From 650c7c243be4bd3b41217ba371e058b5dd925c19 Mon Sep 17 00:00:00 2001 From: Scott Weber Date: Sun, 31 Mar 2024 18:48:43 -0400 Subject: [PATCH 001/580] Remove PNI prekeys and sessions along with ACI --- pkg/signalmeow/store/device.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/pkg/signalmeow/store/device.go b/pkg/signalmeow/store/device.go index 2c8d54a..f487de4 100644 --- a/pkg/signalmeow/store/device.go +++ b/pkg/signalmeow/store/device.go @@ -80,11 +80,11 @@ func (d *Device) ClearDeviceKeys(ctx context.Context) error { zerolog.Ctx(ctx).Warn().Msg("ClearDeviceKeys called with nil device") return nil } - err := d.ACIPreKeyStore.DeleteAllPreKeys(ctx) - if err != nil { - return err - } + var err error + err = d.ACIPreKeyStore.DeleteAllPreKeys(ctx) err = d.ACISessionStore.RemoveAllSessions(ctx) + err = d.PNIPreKeyStore.DeleteAllPreKeys(ctx) + err = d.PNISessionStore.RemoveAllSessions(ctx) return err } From 6ab46691b33c517ddf1e4158f0b65a2d66fae5e8 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Mon, 1 Apr 2024 02:15:31 +0300 Subject: [PATCH 002/580] Log errors when converting prekeys to JSON --- pkg/signalmeow/keys.go | 81 +++++++++++++++++++++++++--------- pkg/signalmeow/provisioning.go | 20 +++++++-- 2 files changed, 76 insertions(+), 25 deletions(-) diff --git a/pkg/signalmeow/keys.go b/pkg/signalmeow/keys.go index 219697f..9b87912 100644 --- a/pkg/signalmeow/keys.go +++ b/pkg/signalmeow/keys.go @@ -272,41 +272,74 @@ func GenerateSignedPreKey(startSignedKeyId uint32, identityKeyPair *libsignalgo. return signedPreKey } -func PreKeyToJSON(preKey *libsignalgo.PreKeyRecord) map[string]interface{} { - id, _ := preKey.GetID() - publicKey, _ := preKey.GetPublicKey() - serializedKey, _ := publicKey.Serialize() +func PreKeyToJSON(preKey *libsignalgo.PreKeyRecord) (map[string]interface{}, error) { + id, err := preKey.GetID() + if err != nil { + return nil, fmt.Errorf("failed to get ID: %w", err) + } + publicKey, err := preKey.GetPublicKey() + if err != nil { + return nil, fmt.Errorf("failed to get public key: %w", err) + } + serializedKey, err := publicKey.Serialize() + if err != nil { + return nil, fmt.Errorf("failed to serialize public key: %w", err) + } preKeyJson := map[string]interface{}{ "keyId": id, "publicKey": base64.StdEncoding.EncodeToString(serializedKey), } - return preKeyJson + return preKeyJson, nil } -func SignedPreKeyToJSON(signedPreKey *libsignalgo.SignedPreKeyRecord) map[string]interface{} { - id, _ := signedPreKey.GetID() - publicKey, _ := signedPreKey.GetPublicKey() - serializedKey, _ := publicKey.Serialize() - signature, _ := signedPreKey.GetSignature() +func SignedPreKeyToJSON(signedPreKey *libsignalgo.SignedPreKeyRecord) (map[string]interface{}, error) { + id, err := signedPreKey.GetID() + if err != nil { + return nil, fmt.Errorf("failed to get ID: %w", err) + } + publicKey, err := signedPreKey.GetPublicKey() + if err != nil { + return nil, fmt.Errorf("failed to get public key: %w", err) + } + serializedKey, err := publicKey.Serialize() + if err != nil { + return nil, fmt.Errorf("failed to serialize public key: %w", err) + } + signature, err := signedPreKey.GetSignature() + if err != nil { + return nil, fmt.Errorf("failed to get signature: %w", err) + } signedPreKeyJson := map[string]interface{}{ "keyId": id, "publicKey": base64.StdEncoding.EncodeToString(serializedKey), "signature": base64.StdEncoding.EncodeToString(signature), } - return signedPreKeyJson + return signedPreKeyJson, nil } -func KyberPreKeyToJSON(kyberPreKey *libsignalgo.KyberPreKeyRecord) map[string]interface{} { - id, _ := kyberPreKey.GetID() - publicKey, _ := kyberPreKey.GetPublicKey() - serializedKey, _ := publicKey.Serialize() - signature, _ := kyberPreKey.GetSignature() +func KyberPreKeyToJSON(kyberPreKey *libsignalgo.KyberPreKeyRecord) (map[string]interface{}, error) { + id, err := kyberPreKey.GetID() + if err != nil { + return nil, fmt.Errorf("failed to get ID: %w", err) + } + publicKey, err := kyberPreKey.GetPublicKey() + if err != nil { + return nil, fmt.Errorf("failed to get public key: %w", err) + } + serializedKey, err := publicKey.Serialize() + if err != nil { + return nil, fmt.Errorf("failed to serialize public key: %w", err) + } + signature, err := kyberPreKey.GetSignature() + if err != nil { + return nil, fmt.Errorf("failed to get signature: %w", err) + } kyberPreKeyJson := map[string]interface{}{ "keyId": id, "publicKey": base64.StdEncoding.EncodeToString(serializedKey), "signature": base64.StdEncoding.EncodeToString(signature), } - return kyberPreKeyJson + return kyberPreKeyJson, nil } func RegisterPreKeys(ctx context.Context, generatedPreKeys *GeneratedPreKeys, pni bool, username string, password string) error { @@ -315,11 +348,17 @@ func RegisterPreKeys(ctx context.Context, generatedPreKeys *GeneratedPreKeys, pn preKeysJson := []map[string]interface{}{} kyberPreKeysJson := []map[string]interface{}{} for _, preKey := range generatedPreKeys.PreKeys { - preKeyJson := PreKeyToJSON(preKey) + preKeyJson, err := PreKeyToJSON(preKey) + if err != nil { + return fmt.Errorf("failed to convert prekey to JSON: %w", err) + } preKeysJson = append(preKeysJson, preKeyJson) } for _, kyberPreKey := range generatedPreKeys.KyberPreKeys { - kyberPreKeyJson := KyberPreKeyToJSON(kyberPreKey) + kyberPreKeyJson, err := KyberPreKeyToJSON(kyberPreKey) + if err != nil { + return fmt.Errorf("failed to convert kyber prekey to JSON: %w", err) + } kyberPreKeysJson = append(kyberPreKeysJson, kyberPreKeyJson) } @@ -559,8 +598,8 @@ func (cli *Client) StartKeyCheckLoop(ctx context.Context) { log := zerolog.Ctx(ctx).With().Str("action", "start key check loop").Logger() go func() { // Do the initial check in 5-10 minutes after starting the loop - window_start := 5 - window_size := 5 + window_start := 0 + window_size := 1 for { random_minutes_in_window := rand.Intn(window_size) + window_start check_time := time.Duration(random_minutes_in_window) * time.Minute diff --git a/pkg/signalmeow/provisioning.go b/pkg/signalmeow/provisioning.go index 95d0a77..22a8b52 100644 --- a/pkg/signalmeow/provisioning.go +++ b/pkg/signalmeow/provisioning.go @@ -358,11 +358,23 @@ func confirmDevice( } defer ws.Close(websocket.StatusInternalError, "Websocket StatusInternalError") - aciSignedPreKeyJson := SignedPreKeyToJSON(aciSignedPreKey) - pniSignedPreKeyJson := SignedPreKeyToJSON(pniSignedPreKey) + aciSignedPreKeyJson, err := SignedPreKeyToJSON(aciSignedPreKey) + if err != nil { + return nil, fmt.Errorf("failed to convert signed ACI prekey to JSON: %w", err) + } + pniSignedPreKeyJson, err := SignedPreKeyToJSON(pniSignedPreKey) + if err != nil { + return nil, fmt.Errorf("failed to convert signed PNI prekey to JSON: %w", err) + } - aciPQLastResortPreKeyJson := KyberPreKeyToJSON(aciPQLastResortPreKey) - pniPQLastResortPreKeyJson := KyberPreKeyToJSON(pniPQLastResortPreKey) + aciPQLastResortPreKeyJson, err := KyberPreKeyToJSON(aciPQLastResortPreKey) + if err != nil { + return nil, fmt.Errorf("failed to convert ACI kyber last resort prekey to JSON: %w", err) + } + pniPQLastResortPreKeyJson, err := KyberPreKeyToJSON(pniPQLastResortPreKey) + if err != nil { + return nil, fmt.Errorf("failed to convert PNI kyber last resort prekey to JSON: %w", err) + } data := map[string]any{ "verificationCode": code, From 79d42dd1600f82026aeb111ea42048f7edfca702 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Mon, 1 Apr 2024 02:39:25 +0300 Subject: [PATCH 003/580] Delete session if prekey upload returns 422 --- pkg/signalmeow/keys.go | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/pkg/signalmeow/keys.go b/pkg/signalmeow/keys.go index 9b87912..ad717ac 100644 --- a/pkg/signalmeow/keys.go +++ b/pkg/signalmeow/keys.go @@ -20,6 +20,7 @@ import ( "context" "encoding/base64" "encoding/json" + "errors" "fmt" "math/rand" "net/http" @@ -342,6 +343,8 @@ func KyberPreKeyToJSON(kyberPreKey *libsignalgo.KyberPreKeyRecord) (map[string]i return kyberPreKeyJson, nil } +var errPrekeyUpload422 = errors.New("http 422 while registering prekeys") + func RegisterPreKeys(ctx context.Context, generatedPreKeys *GeneratedPreKeys, pni bool, username string, password string) error { log := zerolog.Ctx(ctx).With().Str("action", "register prekeys").Logger() // Convert generated prekeys to JSON @@ -383,7 +386,9 @@ func RegisterPreKeys(ctx context.Context, generatedPreKeys *GeneratedPreKeys, pn } defer resp.Body.Close() // status code not 2xx - if resp.StatusCode < 200 || resp.StatusCode >= 300 { + if resp.StatusCode == 422 { + return errPrekeyUpload422 + } else if resp.StatusCode < 200 || resp.StatusCode >= 300 { return fmt.Errorf("error registering prekeys: %v", resp.Status) } return err @@ -619,6 +624,14 @@ func (cli *Client) StartKeyCheckLoop(ctx context.Context) { } err = cli.CheckAndUploadNewPreKeys(ctx, cli.Store.PNIPreKeyStore) if err != nil { + if errors.Is(err, errPrekeyUpload422) { + log.Err(err).Msg("Got 422 error while uploading PNI prekeys, deleting session") + disconnectErr := cli.ClearKeysAndDisconnect(ctx) + if disconnectErr != nil { + log.Err(disconnectErr).Msg("ClearKeysAndDisconnect error") + } + return + } log.Err(err).Msg("Error checking and uploading new prekeys for PNI identity") // Retry within half an hour window_start = 5 From f6e698281a7acff83cbae8c9d85141cea1da79eb Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Mon, 1 Apr 2024 13:23:37 +0300 Subject: [PATCH 004/580] Fix latest signalmeow db revision number --- pkg/signalmeow/store/upgrades/00-latest.sql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/signalmeow/store/upgrades/00-latest.sql b/pkg/signalmeow/store/upgrades/00-latest.sql index bd376bb..40afbfb 100644 --- a/pkg/signalmeow/store/upgrades/00-latest.sql +++ b/pkg/signalmeow/store/upgrades/00-latest.sql @@ -1,4 +1,4 @@ --- v0 -> v15 (compatible with v13+): Latest revision +-- v0 -> v16 (compatible with v13+): Latest revision CREATE TABLE signalmeow_device ( aci_uuid TEXT PRIMARY KEY, From efc22ef158e6b82632c24357f840f6a0937e32f0 Mon Sep 17 00:00:00 2001 From: Malte E <97891689+maltee1@users.noreply.github.com> Date: Tue, 2 Apr 2024 10:09:31 +0200 Subject: [PATCH 005/580] Send correct event to other users when creating group (#491) Use empty message with GroupV2Context instead of an empty group change --- commands.go | 13 +++++-------- pkg/signalmeow/groups.go | 21 +++++++++++++++++++-- pkg/signalmeow/sending.go | 14 ++++++++------ 3 files changed, 32 insertions(+), 16 deletions(-) diff --git a/commands.go b/commands.go index 68a0f9f..8e605ba 100644 --- a/commands.go +++ b/commands.go @@ -771,6 +771,7 @@ func fnCreate(ce *WrappedCommandEvent) { var avatarHash string var avatarURL id.ContentURI var avatarBytes []byte + avatarSet := false if ok { roomAvatarEvent.Content.ParseRaw(event.StateRoomAvatar) avatarURL = roomAvatarEvent.Content.AsRoomAvatar().URL @@ -783,6 +784,7 @@ func fnCreate(ce *WrappedCommandEvent) { hash := sha256.Sum256(avatarBytes) avatarHash = hex.EncodeToString(hash[:]) ce.ZLog.Debug().Stringers("%s set the group avatar to %s", []fmt.Stringer{ce.User.MXID, avatarURL}) + avatarSet = true } } var encryptionEvent *event.EncryptionEventContent @@ -856,7 +858,7 @@ func fnCreate(ce *WrappedCommandEvent) { Str("room_name", roomName). Any("participants", participants). Msg("Creating Signal group for Matrix room") - group, err := ce.User.Client.CreateGroupOnServer(ce.Ctx, &signalmeow.Group{ + group, err := ce.User.Client.CreateGroup(ce.Ctx, &signalmeow.Group{ Title: roomName, Description: roomTopic, Members: participants, @@ -899,16 +901,11 @@ func fnCreate(ce *WrappedCommandEvent) { } portal.Encrypted = true } - revision, err := ce.User.Client.UpdateGroup(ce.Ctx, &signalmeow.GroupChange{}, gid) - if err != nil { - ce.Reply("Failed to update Group") - return - } - portal.Revision = revision + portal.Revision = group.Revision portal.AvatarHash = avatarHash portal.AvatarURL = avatarURL portal.AvatarPath = group.AvatarPath - portal.AvatarSet = true + portal.AvatarSet = avatarSet err = portal.Update(ce.Ctx) if err != nil { ce.ZLog.Err(err).Msg("Failed to save portal after creating group") diff --git a/pkg/signalmeow/groups.go b/pkg/signalmeow/groups.go index 38cd290..e789ff4 100644 --- a/pkg/signalmeow/groups.go +++ b/pkg/signalmeow/groups.go @@ -1564,7 +1564,7 @@ func (cli *Client) UpdateGroup(ctx context.Context, groupChange *GroupChange, gi return 0, err } groupContext := &signalpb.GroupContextV2{Revision: &groupChange.Revision, GroupChange: groupChangeBytes, MasterKey: masterKeyBytes[:]} - _, err = cli.SendGroupChange(ctx, group, groupContext, groupChange) + _, err = cli.SendGroupUpdate(ctx, group, groupContext, groupChange) if err != nil { log.Err(err).Msg("Error sending GroupChange to group members") } @@ -1622,7 +1622,7 @@ func (cli *Client) EncryptGroup(ctx context.Context, decryptedGroup *Group, grou return encryptedGroup, nil } -func (cli *Client) CreateGroupOnServer(ctx context.Context, decryptedGroup *Group, avatarBytes []byte) (*Group, error) { +func (cli *Client) createGroupOnServer(ctx context.Context, decryptedGroup *Group, avatarBytes []byte) (*Group, error) { log := zerolog.Ctx(ctx).With().Str("action", "CreateGroupOnServer").Logger() masterKeyByteArray := make([]byte, 32) rand.Read(masterKeyByteArray) @@ -1708,3 +1708,20 @@ func GenerateInviteLinkPassword() types.SerializedInviteLinkPassword { rand.Read(inviteLinkPasswordBytes) return InviteLinkPasswordFromBytes(inviteLinkPasswordBytes) } + +func (cli *Client) CreateGroup(ctx context.Context, decryptedGroup *Group, avatarBytes []byte) (*Group, error) { + log := zerolog.Ctx(ctx).With().Str("action", "CreateGroup").Logger() + group, err := cli.createGroupOnServer(ctx, decryptedGroup, avatarBytes) + if err != nil { + log.Err(err).Msg("Error creating group on server") + return nil, err + } + masterKeyBytes := masterKeyToBytes(group.groupMasterKey) + groupContext := &signalpb.GroupContextV2{Revision: &group.Revision, MasterKey: masterKeyBytes[:]} + _, err = cli.SendGroupUpdate(ctx, group, groupContext, nil) + if err != nil { + log.Err(err).Msg("Error sending GroupUpdate to group members") + return nil, err + } + return group, nil +} diff --git a/pkg/signalmeow/sending.go b/pkg/signalmeow/sending.go index ea1eeb4..473dd3e 100644 --- a/pkg/signalmeow/sending.go +++ b/pkg/signalmeow/sending.go @@ -532,7 +532,7 @@ func wrapDataMessageInContent(dm *signalpb.DataMessage) *signalpb.Content { } } -func (cli *Client) SendGroupChange(ctx context.Context, group *Group, groupContext *signalpb.GroupContextV2, groupChange *GroupChange) (*GroupMessageSendResult, error) { +func (cli *Client) SendGroupUpdate(ctx context.Context, group *Group, groupContext *signalpb.GroupContextV2, groupChange *GroupChange) (*GroupMessageSendResult, error) { log := zerolog.Ctx(ctx).With(). Str("action", "send group change message"). Stringer("group_id", group.GroupIdentifier). @@ -548,11 +548,13 @@ func (cli *Client) SendGroupChange(ctx context.Context, group *Group, groupConte for _, member := range group.PendingMembers { recipients = append(recipients, &member.GroupMember) } - for _, member := range groupChange.AddPendingMembers { - recipients = append(recipients, &member.GroupMember) - } - for _, member := range groupChange.AddMembers { - recipients = append(recipients, &member.GroupMember) + if groupChange != nil { + for _, member := range groupChange.AddPendingMembers { + recipients = append(recipients, &member.GroupMember) + } + for _, member := range groupChange.AddMembers { + recipients = append(recipients, &member.GroupMember) + } } return cli.sendToGroup(ctx, recipients, content, timestamp) } From f24a76186d64c15b3135c75b820adee584f8a171 Mon Sep 17 00:00:00 2001 From: Malte E Date: Mon, 1 Apr 2024 12:59:04 +0200 Subject: [PATCH 006/580] UUID->ACI & invite command --- commands.go | 83 +++++++- pkg/libsignalgo/groupsecretparams.go | 26 +-- pkg/signalmeow/groups.go | 297 +++++++++++++++++---------- pkg/signalmeow/sending.go | 34 +-- portal.go | 125 ++++++----- 5 files changed, 370 insertions(+), 195 deletions(-) diff --git a/commands.go b/commands.go index 8e605ba..1b4fbea 100644 --- a/commands.go +++ b/commands.go @@ -71,6 +71,7 @@ func (br *SignalBridge) RegisterCommands() { cmdInviteLink, cmdResetInviteLink, cmdCreate, + cmdInvite, ) } @@ -284,6 +285,82 @@ func fnPM(ce *WrappedCommandEvent) { } } +var cmdInvite = &commands.FullHandler{ + Func: wrapCommand(fnInvite), + Name: "invite", + Help: commands.HelpMeta{ + Section: HelpSectionPortalManagement, + Description: "Invite a user by phone number.", + Args: "<_international phone number_>", + }, + RequiresLogin: true, + RequiresPortal: true, +} + +func fnInvite(ce *WrappedCommandEvent) { + if len(ce.Args) == 0 { + ce.Reply("**Usage:** `invite `") + return + } + number, err := strconv.ParseUint(numberCleaner.Replace(strings.Join(ce.Args, "")), 10, 64) + if err != nil { + ce.Reply("Failed to parse number") + return + } + + user := ce.User + var aci, pni uuid.UUID + e164 := fmt.Sprintf("+%d", number) + var recipient *types.Recipient + + if recipient, err = user.Client.ContactByE164(ce.Ctx, e164); err != nil { + ce.Reply("Error looking up number in local contact list: %v", err) + return + } else if recipient != nil && (recipient.ACI != uuid.Nil || recipient.PNI != uuid.Nil) { + // TODO maybe lookup PNI if there's only ACI and E164 stored? + aci = recipient.ACI + pni = recipient.PNI + } else if resp, err := user.Client.LookupPhone(ce.Ctx, number); err != nil { + ce.ZLog.Err(err).Uint64("e164", number).Msg("Failed to lookup number on server") + ce.Reply("Error looking up number on server: %v", err) + return + } else { + aci = resp[number].ACI + pni = resp[number].PNI + if aci == uuid.Nil && pni == uuid.Nil { + ce.Reply("+%d doesn't seem to be on Signal", number) + return + } + recipient, err = user.Client.Store.RecipientStore.UpdateRecipientE164(ce.Ctx, aci, pni, e164) + if err != nil { + ce.ZLog.Err(err).Msg("Failed to save recipient entry after looking up phone") + } + aci, pni = recipient.ACI, recipient.PNI + } + ce.ZLog.Debug(). + Uint64("e164", number). + Stringer("aci", aci). + Stringer("pni", pni). + Msg("Found Invite target user") + + var groupChange signalmeow.GroupChange + if aci != uuid.Nil { + groupChange.AddMembers = append(groupChange.AddMembers, &signalmeow.AddMember{ + GroupMember: signalmeow.GroupMember{ + ACI: aci, + Role: signalmeow.GroupMember_DEFAULT, + }, + }) + } else { + groupChange.AddPendingMembers = append(groupChange.AddPendingMembers, &signalmeow.PendingMember{ + ServiceID: libsignalgo.NewPNIServiceID(pni), + AddedByUserID: ce.User.SignalID, + Role: signalmeow.GroupMember_DEFAULT, + }) + } + ce.User.Client.UpdateGroup(ce.Ctx, &groupChange, ce.Portal.GroupID()) +} + var cmdResolvePhone = &commands.FullHandler{ Func: wrapCommand(fnResolvePhone), Name: "resolve-phone", @@ -822,12 +899,12 @@ func fnCreate(ce *WrappedCommandEvent) { // joined members that need to be pending-Members should have their signal invite auto-accepted if membership == event.MembershipJoin || membership == event.MembershipInvite { participants = append(participants, &signalmeow.GroupMember{ - UserID: uuid, - Role: role, + ACI: uuid, + Role: role, }) } else if membership == event.MembershipBan { bannedMembers = append(bannedMembers, &signalmeow.BannedMember{ - UserID: uuid, + ServiceID: libsignalgo.NewACIServiceID(uuid), }) } } diff --git a/pkg/libsignalgo/groupsecretparams.go b/pkg/libsignalgo/groupsecretparams.go index fed5477..76a28f7 100644 --- a/pkg/libsignalgo/groupsecretparams.go +++ b/pkg/libsignalgo/groupsecretparams.go @@ -23,7 +23,6 @@ package libsignalgo import "C" import ( "crypto/rand" - "fmt" "runtime" "unsafe" @@ -139,41 +138,36 @@ func (gsp *GroupSecretParams) EncryptBlobWithPaddingDeterministic(randomness Ran return CopySignalOwnedBufferToBytes(ciphertext), nil } -func (gsp *GroupSecretParams) DecryptUUID(ciphertextUUID UUIDCiphertext) (uuid.UUID, error) { - // TODO this should probably be DecryptServiceID - +func (gsp *GroupSecretParams) DecryptServiceID(ciphertextServiceID UUIDCiphertext) (ServiceID, error) { u := C.SignalServiceIdFixedWidthBinaryBytes{} signalFfiError := C.signal_group_secret_params_decrypt_service_id( &u, (*[C.SignalGROUP_SECRET_PARAMS_LEN]C.uint8_t)(unsafe.Pointer(gsp)), - (*[C.SignalUUID_CIPHERTEXT_LEN]C.uint8_t)(unsafe.Pointer(&ciphertextUUID)), + (*[C.SignalUUID_CIPHERTEXT_LEN]C.uint8_t)(unsafe.Pointer(&ciphertextServiceID)), ) runtime.KeepAlive(gsp) - runtime.KeepAlive(ciphertextUUID) + runtime.KeepAlive(ciphertextServiceID) if signalFfiError != nil { - return uuid.Nil, wrapError(signalFfiError) + return EmptyServiceID, wrapError(signalFfiError) } serviceID := ServiceIDFromCFixedBytes(&u) - if serviceID.Type != ServiceIDTypeACI { - return uuid.Nil, fmt.Errorf("unexpected service ID type %d", serviceID.Type) - } - return serviceID.UUID, nil + return serviceID, nil } -func (gsp *GroupSecretParams) EncryptUUID(uuid uuid.UUID) (*UUIDCiphertext, error) { - var cipherTextUUID [C.SignalUUID_CIPHERTEXT_LEN]C.uchar +func (gsp *GroupSecretParams) EncryptServiceID(serviceID ServiceID) (*UUIDCiphertext, error) { + var cipherTextServiceID [C.SignalUUID_CIPHERTEXT_LEN]C.uchar signalFfiError := C.signal_group_secret_params_encrypt_service_id( - &cipherTextUUID, + &cipherTextServiceID, (*[C.SignalGROUP_SECRET_PARAMS_LEN]C.uint8_t)(unsafe.Pointer(gsp)), - NewACIServiceID(uuid).CFixedBytes(), + serviceID.CFixedBytes(), ) runtime.KeepAlive(gsp) if signalFfiError != nil { return nil, wrapError(signalFfiError) } var result UUIDCiphertext - copy(result[:], C.GoBytes(unsafe.Pointer(&cipherTextUUID), C.int(C.SignalUUID_CIPHERTEXT_LEN))) + copy(result[:], C.GoBytes(unsafe.Pointer(&cipherTextServiceID), C.int(C.SignalUUID_CIPHERTEXT_LEN))) return &result, nil } diff --git a/pkg/signalmeow/groups.go b/pkg/signalmeow/groups.go index e789ff4..0e647d0 100644 --- a/pkg/signalmeow/groups.go +++ b/pkg/signalmeow/groups.go @@ -65,15 +65,14 @@ const ( ) type GroupMember struct { - UserID uuid.UUID + ACI uuid.UUID Role GroupMemberRole ProfileKey libsignalgo.ProfileKey JoinedAtRevision uint32 - //Presentation []byte } func (gm *GroupMember) UserServiceID() libsignalgo.ServiceID { - return libsignalgo.NewACIServiceID(gm.UserID) + return libsignalgo.NewACIServiceID(gm.ACI) } type Group struct { @@ -138,38 +137,41 @@ type AddMember struct { } type PendingMember struct { - GroupMember + ServiceID libsignalgo.ServiceID + Role GroupMemberRole AddedByUserID uuid.UUID Timestamp uint64 } type ProfileKeyMember struct { - UserID uuid.UUID + ACI uuid.UUID ProfileKey libsignalgo.ProfileKey - //Presentation []byte } type RequestingMember struct { - UserID uuid.UUID + ACI uuid.UUID ProfileKey libsignalgo.ProfileKey Timestamp uint64 - //Presentation []byte } -// type PromotePniAciMember struct { -// UserID uuid.UUID -// ProfileKey libsignalgo.ProfileKey -// PNI uuid.UUID -// Presentation []byte -// } +type PromotePendingMembers struct { + ACI uuid.UUID + ProfileKey libsignalgo.ProfileKey +} + +type PromotePendingPniAciMember struct { + ACI uuid.UUID + ProfileKey libsignalgo.ProfileKey + PNI uuid.UUID +} type RoleMember struct { - UserID uuid.UUID - Role GroupMemberRole + ACI uuid.UUID + Role GroupMemberRole } type BannedMember struct { - UserID uuid.UUID + ServiceID libsignalgo.ServiceID Timestamp uint64 } @@ -182,8 +184,8 @@ type GroupChange struct { ModifyMemberRoles []*RoleMember ModifyMemberProfileKeys []*ProfileKeyMember AddPendingMembers []*PendingMember - DeletePendingMembers []*uuid.UUID - PromotePendingMembers []*ProfileKeyMember + DeletePendingMembers []*libsignalgo.ServiceID + PromotePendingMembers []*GroupMember ModifyTitle *string ModifyAvatar *string ModifyDisappearingMessagesDuration *uint32 @@ -196,8 +198,8 @@ type GroupChange struct { ModifyDescription *string ModifyAnnouncementsOnly *bool AddBannedMembers []*BannedMember - DeleteBannedMembers []*uuid.UUID - PromotePendingPniAciMembers []*ProfileKeyMember + DeleteBannedMembers []*libsignalgo.ServiceID + PromotePendingPniAciMembers []*PromotePendingPniAciMember ModifyInviteLinkPassword *types.SerializedInviteLinkPassword } @@ -250,38 +252,38 @@ func (groupChange *GroupChange) resolveConflict(group *Group) { } members := make(map[uuid.UUID]GroupMemberRole) for _, member := range group.Members { - members[member.UserID] = member.Role + members[member.ACI] = member.Role } - pendingMembers := make(map[uuid.UUID]bool) + pendingMembers := make(map[libsignalgo.ServiceID]bool) for _, pendingMember := range group.PendingMembers { - pendingMembers[pendingMember.UserID] = true + pendingMembers[pendingMember.ServiceID] = true } requestingMembers := make(map[uuid.UUID]bool) for _, requestingMember := range group.RequestingMembers { - requestingMembers[requestingMember.UserID] = true + requestingMembers[requestingMember.ACI] = true } for i, member := range groupChange.AddMembers { - if _, ok := members[member.GroupMember.UserID]; ok { + if _, ok := members[member.GroupMember.ACI]; ok { groupChange.AddMembers = append(groupChange.AddMembers[:i], groupChange.AddMembers[i+1:]...) } } for i, promotePendingMember := range groupChange.PromotePendingMembers { - if _, ok := members[promotePendingMember.UserID]; ok { + if _, ok := members[promotePendingMember.ACI]; ok { groupChange.PromotePendingMembers = append(groupChange.PromotePendingMembers[:i], groupChange.PromotePendingMembers[i+1:]...) } } for i, promoteRequestingMember := range groupChange.PromotePendingMembers { - if _, ok := members[promoteRequestingMember.UserID]; ok { + if _, ok := members[promoteRequestingMember.ACI]; ok { groupChange.PromoteRequestingMembers = append(groupChange.PromoteRequestingMembers[:i], groupChange.PromoteRequestingMembers[i+1:]...) } } for i, pendingMember := range groupChange.AddPendingMembers { - if pendingMembers[pendingMember.GroupMember.UserID] { + if pendingMembers[pendingMember.ServiceID] { groupChange.AddPendingMembers = append(groupChange.AddPendingMembers[:i], groupChange.AddPendingMembers[i+1:]...) } } for i, requestingMember := range groupChange.AddRequestingMembers { - if pendingMembers[requestingMember.UserID] { + if requestingMembers[requestingMember.ACI] { groupChange.AddRequestingMembers = append(groupChange.AddRequestingMembers[:i], groupChange.AddRequestingMembers[i+1:]...) } } @@ -291,7 +293,7 @@ func (groupChange *GroupChange) resolveConflict(group *Group) { } } for i, deleteRequestingMember := range groupChange.DeleteRequestingMembers { - if !pendingMembers[*deleteRequestingMember] { + if !requestingMembers[*deleteRequestingMember] { groupChange.DeleteRequestingMembers = append(groupChange.DeleteRequestingMembers[:i], groupChange.DeleteRequestingMembers[i+1:]...) } } @@ -301,7 +303,7 @@ func (groupChange *GroupChange) resolveConflict(group *Group) { } } for i, modifyMemberRole := range groupChange.ModifyMemberRoles { - if members[modifyMemberRole.UserID] == modifyMemberRole.Role { + if members[modifyMemberRole.ACI] == modifyMemberRole.Role { groupChange.ModifyMemberRoles = append(groupChange.ModifyMemberRoles[:i], groupChange.ModifyMemberRoles[i+1:]...) } } @@ -563,13 +565,13 @@ func decryptGroup(ctx context.Context, encryptedGroup *signalpb.Group, groupMast continue } encryptedUserID := libsignalgo.UUIDCiphertext(bannedMember.UserId) - userID, err := groupSecretParams.DecryptUUID(encryptedUserID) + serviceID, err := groupSecretParams.DecryptServiceID(encryptedUserID) if err != nil { log.Err(err).Msg("DecryptUUID UserId error") return nil, err } decryptedGroup.BannedMembers = append(decryptedGroup.BannedMembers, &BannedMember{ - UserID: userID, + ServiceID: serviceID, Timestamp: bannedMember.Timestamp, }) } @@ -697,19 +699,13 @@ func (cli *Client) fetchGroupWithMasterKey(ctx context.Context, groupMasterKey t // Store the profile keys in case they're new for _, member := range group.Members { - err = cli.Store.RecipientStore.StoreProfileKey(ctx, member.UserID, member.ProfileKey) - if err != nil { - return nil, fmt.Errorf("failed to store profile key: %w", err) - } - } - for _, pendingMember := range group.PendingMembers { - err = cli.Store.RecipientStore.StoreProfileKey(ctx, pendingMember.UserID, pendingMember.ProfileKey) + err = cli.Store.RecipientStore.StoreProfileKey(ctx, member.ACI, member.ProfileKey) if err != nil { return nil, fmt.Errorf("failed to store profile key: %w", err) } } for _, requestingMember := range group.RequestingMembers { - err = cli.Store.RecipientStore.StoreProfileKey(ctx, requestingMember.UserID, requestingMember.ProfileKey) + err = cli.Store.RecipientStore.StoreProfileKey(ctx, requestingMember.ACI, requestingMember.ProfileKey) if err != nil { return nil, fmt.Errorf("failed to store profile key: %w", err) } @@ -884,7 +880,7 @@ func (cli *Client) DecryptGroupChange(ctx context.Context, groupContext *signalp GroupMember: *decryptedMember, JoinFromInviteLink: addMember.JoinFromInviteLink, }) - err = cli.Store.RecipientStore.StoreProfileKey(ctx, decryptedMember.UserID, decryptedMember.ProfileKey) + err = cli.Store.RecipientStore.StoreProfileKey(ctx, decryptedMember.ACI, decryptedMember.ProfileKey) if err != nil { log.Err(err).Msg("failed to store profile key") return nil, err @@ -896,24 +892,30 @@ func (cli *Client) DecryptGroupChange(ctx context.Context, groupContext *signalp continue } encryptedUserID := libsignalgo.UUIDCiphertext(deleteMember.DeletedUserId) - userID, err := groupSecretParams.DecryptUUID(encryptedUserID) + serviceID, err := groupSecretParams.DecryptServiceID(encryptedUserID) if err != nil { log.Err(err).Msg("DecryptUUID UserId error for deleteMember") return nil, err } - decryptedGroupChange.DeleteMembers = append(decryptedGroupChange.DeleteMembers, &userID) + if serviceID.Type != libsignalgo.ServiceIDTypeACI { + return nil, fmt.Errorf("Wrong ServiceID kind: expected ACI, got PNI") + } + decryptedGroupChange.DeleteMembers = append(decryptedGroupChange.DeleteMembers, &serviceID.UUID) } for _, modifyMemberRole := range encryptedActions.ModifyMemberRoles { encryptedUserID := libsignalgo.UUIDCiphertext(modifyMemberRole.UserId) - userID, err := groupSecretParams.DecryptUUID(encryptedUserID) + serviceID, err := groupSecretParams.DecryptServiceID(encryptedUserID) if err != nil { log.Err(err).Msg("DecryptUUID UserId error for modifyMemberRole") return nil, err } + if serviceID.Type != libsignalgo.ServiceIDTypeACI { + return nil, fmt.Errorf("Wrong ServiceID kind: expected ACI, got PNI") + } decryptedGroupChange.ModifyMemberRoles = append(decryptedGroupChange.ModifyMemberRoles, &RoleMember{ - UserID: userID, - Role: GroupMemberRole(modifyMemberRole.Role), + ACI: serviceID.UUID, + Role: GroupMemberRole(modifyMemberRole.Role), }) } @@ -922,22 +924,25 @@ func (cli *Client) DecryptGroupChange(ctx context.Context, groupContext *signalp continue } encryptedUserID := libsignalgo.UUIDCiphertext(modifyProfileKey.UserId) - userID, err := groupSecretParams.DecryptUUID(encryptedUserID) + serviceID, err := groupSecretParams.DecryptServiceID(encryptedUserID) if err != nil { log.Err(err).Msg("DecryptUUID UserId error for modifyProfileKey") return nil, err } + if serviceID.Type != libsignalgo.ServiceIDTypeACI { + return nil, fmt.Errorf("Wrong ServiceID kind: expected ACI, got PNI") + } encryptedProfileKey := libsignalgo.ProfileKeyCiphertext(modifyProfileKey.ProfileKey) - profileKey, err := groupSecretParams.DecryptProfileKey(encryptedProfileKey, userID) + profileKey, err := groupSecretParams.DecryptProfileKey(encryptedProfileKey, serviceID.UUID) if err != nil { log.Err(err).Msg("DecryptProfileKey ProfileKey error for modifyProfileKey") return nil, err } decryptedGroupChange.ModifyMemberProfileKeys = append(decryptedGroupChange.ModifyMemberProfileKeys, &ProfileKeyMember{ - UserID: userID, + ACI: serviceID.UUID, ProfileKey: *profileKey, }) - err = cli.Store.RecipientStore.StoreProfileKey(ctx, userID, *profileKey) + err = cli.Store.RecipientStore.StoreProfileKey(ctx, serviceID.UUID, *profileKey) if err != nil { log.Err(err).Msg("failed to store profile key") return nil, err @@ -962,7 +967,7 @@ func (cli *Client) DecryptGroupChange(ctx context.Context, groupContext *signalp continue } encryptedUserID := libsignalgo.UUIDCiphertext(deletePendingMember.DeletedUserId) - userID, err := groupSecretParams.DecryptUUID(encryptedUserID) + userID, err := groupSecretParams.DecryptServiceID(encryptedUserID) if err != nil { log.Err(err).Msg("DecryptUUID UserId error for deletePendingMember") return nil, err @@ -975,50 +980,63 @@ func (cli *Client) DecryptGroupChange(ctx context.Context, groupContext *signalp continue } encryptedUserID := libsignalgo.UUIDCiphertext(promotePendingMember.UserId) - userID, err := groupSecretParams.DecryptUUID(encryptedUserID) + serviceID, err := groupSecretParams.DecryptServiceID(encryptedUserID) if err != nil { log.Err(err).Msg("DecryptUUID UserId error for promotePendingMember") return nil, err } encryptedProfileKey := libsignalgo.ProfileKeyCiphertext(promotePendingMember.ProfileKey) - profileKey, err := groupSecretParams.DecryptProfileKey(encryptedProfileKey, userID) + profileKey, err := groupSecretParams.DecryptProfileKey(encryptedProfileKey, serviceID.UUID) if err != nil { log.Err(err).Msg("DecryptProfileKey ProfileKey error for promotePendingMember") return nil, err } - decryptedGroupChange.PromotePendingMembers = append(decryptedGroupChange.PromotePendingMembers, &ProfileKeyMember{ - UserID: userID, + decryptedGroupChange.PromotePendingMembers = append(decryptedGroupChange.PromotePendingMembers, &GroupMember{ + ACI: serviceID.UUID, ProfileKey: *profileKey, }) - err = cli.Store.RecipientStore.StoreProfileKey(ctx, userID, *profileKey) + err = cli.Store.RecipientStore.StoreProfileKey(ctx, serviceID.UUID, *profileKey) if err != nil { log.Err(err).Msg("failed to store profile key") return nil, err } } - for _, promotePendingMember := range encryptedActions.PromotePendingPniAciMembers { + for _, promotePendingPniAciMember := range encryptedActions.PromotePendingPniAciMembers { // TODO: pretending this is a PendingMember should do for mautrix-signal, but we probably want to treat them separately at some point - if promotePendingMember == nil { + if promotePendingPniAciMember == nil { continue } - encryptedUserID := libsignalgo.UUIDCiphertext(promotePendingMember.UserId) - userID, err := groupSecretParams.DecryptUUID(encryptedUserID) + encryptedUserID := libsignalgo.UUIDCiphertext(promotePendingPniAciMember.UserId) + aciServiceID, err := groupSecretParams.DecryptServiceID(encryptedUserID) if err != nil { log.Err(err).Msg("DecryptUUID UserId error for promotePendingPniAciMember") return nil, err } - encryptedProfileKey := libsignalgo.ProfileKeyCiphertext(promotePendingMember.ProfileKey) - profileKey, err := groupSecretParams.DecryptProfileKey(encryptedProfileKey, userID) + if aciServiceID.Type != libsignalgo.ServiceIDTypeACI { + return nil, fmt.Errorf("Wrong ServiceID kind: expected ACI, got PNI") + } + encryptedUserID = libsignalgo.UUIDCiphertext(promotePendingPniAciMember.Pni) + pniServiceID, err := groupSecretParams.DecryptServiceID(encryptedUserID) + if err != nil { + log.Err(err).Msg("DecryptUUID Pni error for promotePendingPniAciMember") + return nil, err + } + if pniServiceID.Type != libsignalgo.ServiceIDTypeACI { + return nil, fmt.Errorf("Wrong ServiceID kind: expected PNI, got ACI") + } + encryptedProfileKey := libsignalgo.ProfileKeyCiphertext(promotePendingPniAciMember.ProfileKey) + profileKey, err := groupSecretParams.DecryptProfileKey(encryptedProfileKey, aciServiceID.UUID) if err != nil { log.Err(err).Msg("DecryptProfileKey ProfileKey error for promotePendingPniAciMember") return nil, err } - decryptedGroupChange.PromotePendingMembers = append(decryptedGroupChange.PromotePendingMembers, &ProfileKeyMember{ - UserID: userID, + decryptedGroupChange.PromotePendingPniAciMembers = append(decryptedGroupChange.PromotePendingPniAciMembers, &PromotePendingPniAciMember{ + ACI: aciServiceID.UUID, ProfileKey: *profileKey, + PNI: pniServiceID.UUID, }) - err = cli.Store.RecipientStore.StoreProfileKey(ctx, userID, *profileKey) + err = cli.Store.RecipientStore.StoreProfileKey(ctx, aciServiceID.UUID, *profileKey) if err != nil { log.Err(err).Msg("failed to store profile key") return nil, err @@ -1034,7 +1052,7 @@ func (cli *Client) DecryptGroupChange(ctx context.Context, groupContext *signalp return nil, err } decryptedGroupChange.AddRequestingMembers = append(decryptedGroupChange.AddRequestingMembers, decryptedRequestingMember) - err = cli.Store.RecipientStore.StoreProfileKey(ctx, decryptedRequestingMember.UserID, decryptedRequestingMember.ProfileKey) + err = cli.Store.RecipientStore.StoreProfileKey(ctx, decryptedRequestingMember.ACI, decryptedRequestingMember.ProfileKey) if err != nil { log.Err(err).Msg("failed to store profile key") return nil, err @@ -1046,12 +1064,12 @@ func (cli *Client) DecryptGroupChange(ctx context.Context, groupContext *signalp continue } encryptedUserID := libsignalgo.UUIDCiphertext(deleteRequestingMember.DeletedUserId) - userID, err := groupSecretParams.DecryptUUID(encryptedUserID) + serviceID, err := groupSecretParams.DecryptServiceID(encryptedUserID) if err != nil { log.Err(err).Msg("DecryptUUID UserId error for deleteRequestingMember") return nil, err } - decryptedGroupChange.DeleteRequestingMembers = append(decryptedGroupChange.DeleteRequestingMembers, &userID) + decryptedGroupChange.DeleteRequestingMembers = append(decryptedGroupChange.DeleteRequestingMembers, &serviceID.UUID) } for _, promoteRequestingMember := range encryptedActions.PromoteRequestingMembers { @@ -1059,14 +1077,14 @@ func (cli *Client) DecryptGroupChange(ctx context.Context, groupContext *signalp continue } encryptedUserID := libsignalgo.UUIDCiphertext(promoteRequestingMember.UserId) - userID, err := groupSecretParams.DecryptUUID(encryptedUserID) + serviceID, err := groupSecretParams.DecryptServiceID(encryptedUserID) if err != nil { log.Err(err).Msg("DecryptUUID UserId error for promoteRequestingMember") return nil, err } decryptedGroupChange.PromoteRequestingMembers = append(decryptedGroupChange.PromoteRequestingMembers, &RoleMember{ - UserID: userID, - Role: GroupMemberRole(promoteRequestingMember.Role), + ACI: serviceID.UUID, + Role: GroupMemberRole(promoteRequestingMember.Role), }) } @@ -1076,13 +1094,13 @@ func (cli *Client) DecryptGroupChange(ctx context.Context, groupContext *signalp } bannedMember := addBannedMember.Added encryptedUserID := libsignalgo.UUIDCiphertext(bannedMember.UserId) - userID, err := groupSecretParams.DecryptUUID(encryptedUserID) + serviceID, err := groupSecretParams.DecryptServiceID(encryptedUserID) if err != nil { log.Err(err).Msg("DecryptUUID UserId error for addBannedMember") return nil, err } decryptedGroupChange.AddBannedMembers = append(decryptedGroupChange.AddBannedMembers, &BannedMember{ - UserID: userID, + ServiceID: serviceID, Timestamp: bannedMember.Timestamp, }) } @@ -1092,7 +1110,7 @@ func (cli *Client) DecryptGroupChange(ctx context.Context, groupContext *signalp continue } encryptedUserID := libsignalgo.UUIDCiphertext(deleteBannedMember.DeletedUserId) - userID, err := groupSecretParams.DecryptUUID(encryptedUserID) + userID, err := groupSecretParams.DecryptServiceID(encryptedUserID) if err != nil { log.Err(err).Msg("DecryptUUID UserId error for deleteBannedMember") return nil, err @@ -1134,19 +1152,19 @@ func (cli *Client) DecryptGroupChange(ctx context.Context, groupContext *signalp func decryptMember(ctx context.Context, member *signalpb.Member, groupSecretParams libsignalgo.GroupSecretParams) (*GroupMember, error) { log := zerolog.Ctx(ctx) encryptedUserID := libsignalgo.UUIDCiphertext(member.UserId) - userID, err := groupSecretParams.DecryptUUID(encryptedUserID) + serviceID, err := groupSecretParams.DecryptServiceID(encryptedUserID) if err != nil { log.Err(err).Msg("DecryptUUID UserId error") return nil, err } encryptedProfileKey := libsignalgo.ProfileKeyCiphertext(member.ProfileKey) - profileKey, err := groupSecretParams.DecryptProfileKey(encryptedProfileKey, userID) + profileKey, err := groupSecretParams.DecryptProfileKey(encryptedProfileKey, serviceID.UUID) if err != nil { log.Err(err).Msg("DecryptProfileKey ProfileKey error") return nil, err } return &GroupMember{ - UserID: userID, + ACI: serviceID.UUID, ProfileKey: *profileKey, Role: GroupMemberRole(member.Role), JoinedAtRevision: member.JoinedAtRevision, @@ -1156,25 +1174,22 @@ func decryptMember(ctx context.Context, member *signalpb.Member, groupSecretPara func decryptPendingMember(ctx context.Context, pendingMember *signalpb.PendingMember, groupSecretParams libsignalgo.GroupSecretParams) (*PendingMember, error) { log := zerolog.Ctx(ctx) encryptedUserID := libsignalgo.UUIDCiphertext(pendingMember.Member.UserId) - userID, err := groupSecretParams.DecryptUUID(encryptedUserID) + userID, err := groupSecretParams.DecryptServiceID(encryptedUserID) if err != nil { log.Err(err).Msg("DecryptUUID UserId error for pendingMember") return nil, err } // pendingMembers don't have profile keys encryptedAddedByUserID := pendingMember.AddedByUserId - addedByUserId, err := groupSecretParams.DecryptUUID(libsignalgo.UUIDCiphertext(encryptedAddedByUserID)) + addedByServiceId, err := groupSecretParams.DecryptServiceID(libsignalgo.UUIDCiphertext(encryptedAddedByUserID)) if err != nil { log.Err(err).Msg("DecryptUUID addedByUserId error for pendingMember") return nil, err } return &PendingMember{ - GroupMember: GroupMember{ - UserID: userID, - Role: GroupMemberRole(pendingMember.Member.Role), - JoinedAtRevision: pendingMember.Member.JoinedAtRevision, - }, - AddedByUserID: addedByUserId, + ServiceID: userID, + Role: GroupMemberRole(pendingMember.Member.Role), + AddedByUserID: addedByServiceId.UUID, Timestamp: pendingMember.Timestamp, }, nil } @@ -1182,19 +1197,19 @@ func decryptPendingMember(ctx context.Context, pendingMember *signalpb.PendingMe func decryptRequestingMember(ctx context.Context, requestingMember *signalpb.RequestingMember, groupSecretParams libsignalgo.GroupSecretParams) (*RequestingMember, error) { log := zerolog.Ctx(ctx) encryptedUserID := libsignalgo.UUIDCiphertext(requestingMember.UserId) - userID, err := groupSecretParams.DecryptUUID(encryptedUserID) + serviceID, err := groupSecretParams.DecryptServiceID(encryptedUserID) if err != nil { log.Err(err).Msg("DecryptUUID UserId error for requestingMember") return nil, err } encryptedProfileKey := libsignalgo.ProfileKeyCiphertext(requestingMember.ProfileKey) - profileKey, err := groupSecretParams.DecryptProfileKey(encryptedProfileKey, userID) + profileKey, err := groupSecretParams.DecryptProfileKey(encryptedProfileKey, serviceID.UUID) if err != nil { log.Err(err).Msg("DecryptProfileKey ProfileKey error for requestingMember") return nil, err } return &RequestingMember{ - UserID: userID, + ACI: serviceID.UUID, ProfileKey: *profileKey, Timestamp: requestingMember.Timestamp, }, nil @@ -1232,17 +1247,23 @@ func (cli *Client) EncryptAndSignGroupChange(ctx context.Context, decryptedGroup groupChangeActions.ModifyAvatar = &signalpb.GroupChange_Actions_ModifyAvatarAction{Avatar: *decryptedGroupChange.ModifyAvatar} } for _, addMember := range decryptedGroupChange.AddMembers { - encryptedMember, err := cli.encryptMember(ctx, &addMember.GroupMember, &groupSecretParams) + encryptedMember, encryptedPendingMember, err := cli.encryptMember(ctx, &addMember.GroupMember, &groupSecretParams) if err != nil { log.Err(err).Msg("Failed to encrypt GroupMember") } - groupChangeActions.AddMembers = append(groupChangeActions.AddMembers, &signalpb.GroupChange_Actions_AddMemberAction{ - Added: encryptedMember, - JoinFromInviteLink: addMember.JoinFromInviteLink, - }) + if encryptedMember != nil { + groupChangeActions.AddMembers = append(groupChangeActions.AddMembers, &signalpb.GroupChange_Actions_AddMemberAction{ + Added: encryptedMember, + JoinFromInviteLink: addMember.JoinFromInviteLink, + }) + } else { + groupChangeActions.AddPendingMembers = append(groupChangeActions.AddPendingMembers, &signalpb.GroupChange_Actions_AddPendingMemberAction{ + Added: encryptedPendingMember, + }) + } } for _, deleteMember := range decryptedGroupChange.DeleteMembers { - encryptedUserID, err := groupSecretParams.EncryptUUID(*deleteMember) + encryptedUserID, err := groupSecretParams.EncryptServiceID(libsignalgo.NewACIServiceID(*deleteMember)) if err != nil { log.Err(err).Msg("Encrypt UserId error for deleteMember") return nil, err @@ -1252,7 +1273,7 @@ func (cli *Client) EncryptAndSignGroupChange(ctx context.Context, decryptedGroup }) } for _, modifyMemberRoles := range decryptedGroupChange.ModifyMemberRoles { - encryptedUserID, err := groupSecretParams.EncryptUUID(modifyMemberRoles.UserID) + encryptedUserID, err := groupSecretParams.EncryptServiceID(libsignalgo.NewACIServiceID(modifyMemberRoles.ACI)) if err != nil { log.Err(err).Msg("Encrypt UserId error for modifyMemberRoles") return nil, err @@ -1262,10 +1283,18 @@ func (cli *Client) EncryptAndSignGroupChange(ctx context.Context, decryptedGroup Role: signalpb.Member_Role(modifyMemberRoles.Role), }) } - // for _, addPendingMember := range decryptedGroupChange.AddPendingMembers { - // } + for _, addPendingMember := range decryptedGroupChange.AddPendingMembers { + encryptedPendingMember, err := cli.encryptPendingMember(ctx, addPendingMember, &groupSecretParams) + if err != nil { + log.Err(err).Msg("Failed to encrypt pendingMember") + return nil, err + } + groupChangeActions.AddPendingMembers = append(groupChangeActions.AddPendingMembers, &signalpb.GroupChange_Actions_AddPendingMemberAction{ + Added: encryptedPendingMember, + }) + } for _, deletePendingMember := range decryptedGroupChange.DeletePendingMembers { - encryptedUserID, err := groupSecretParams.EncryptUUID(*deletePendingMember) + encryptedUserID, err := groupSecretParams.EncryptServiceID(libsignalgo.NewACIServiceID(deletePendingMember.UUID)) if err != nil { log.Err(err).Msg("Encrypt UserId error for deletePendingMember") return nil, err @@ -1275,7 +1304,7 @@ func (cli *Client) EncryptAndSignGroupChange(ctx context.Context, decryptedGroup }) } for _, promotePendingMember := range decryptedGroupChange.PromotePendingMembers { - expiringProfileKeyCredential, err := cli.FetchExpiringProfileKeyCredentialById(ctx, promotePendingMember.UserID) + expiringProfileKeyCredential, err := cli.FetchExpiringProfileKeyCredentialById(ctx, promotePendingMember.ACI) if err != nil { log.Err(err).Msg("failed getting expiring profile key credential for addMember") return nil, err @@ -1293,7 +1322,7 @@ func (cli *Client) EncryptAndSignGroupChange(ctx context.Context, decryptedGroup }) } for _, addRequestingMember := range decryptedGroupChange.AddRequestingMembers { - expiringProfileKeyCredential, err := cli.FetchExpiringProfileKeyCredentialById(ctx, addRequestingMember.UserID) + expiringProfileKeyCredential, err := cli.FetchExpiringProfileKeyCredentialById(ctx, addRequestingMember.ACI) if err != nil { log.Err(err).Msg("failed getting expiring profile key credential for addMember") return nil, err @@ -1313,7 +1342,7 @@ func (cli *Client) EncryptAndSignGroupChange(ctx context.Context, decryptedGroup }) } for _, deleteRequestingMember := range decryptedGroupChange.DeleteRequestingMembers { - encryptedUserID, err := groupSecretParams.EncryptUUID(*deleteRequestingMember) + encryptedUserID, err := groupSecretParams.EncryptServiceID(libsignalgo.NewACIServiceID(*deleteRequestingMember)) if err != nil { log.Err(err).Msg("Encrypt UserId error for promotePendingMember") return nil, err @@ -1323,7 +1352,7 @@ func (cli *Client) EncryptAndSignGroupChange(ctx context.Context, decryptedGroup }) } for _, promoteRequestingMember := range decryptedGroupChange.PromoteRequestingMembers { - encryptedUserID, err := groupSecretParams.EncryptUUID(promoteRequestingMember.UserID) + encryptedUserID, err := groupSecretParams.EncryptServiceID(libsignalgo.NewACIServiceID(promoteRequestingMember.ACI)) if err != nil { log.Err(err).Msg("Encrypt UserId error for promoteRequestingMember") return nil, err @@ -1335,7 +1364,7 @@ func (cli *Client) EncryptAndSignGroupChange(ctx context.Context, decryptedGroup }) } for _, addBannedMember := range decryptedGroupChange.AddBannedMembers { - encryptedUserID, err := groupSecretParams.EncryptUUID(addBannedMember.UserID) + encryptedUserID, err := groupSecretParams.EncryptServiceID(addBannedMember.ServiceID) if err != nil { log.Err(err).Msg("Encrypt UserId error for promoteRequestingMember") return nil, err @@ -1348,7 +1377,7 @@ func (cli *Client) EncryptAndSignGroupChange(ctx context.Context, decryptedGroup }) } for _, deleteBannedMember := range decryptedGroupChange.DeleteBannedMembers { - encryptedUserID, err := groupSecretParams.EncryptUUID(*deleteBannedMember) + encryptedUserID, err := groupSecretParams.EncryptServiceID(*deleteBannedMember) if err != nil { log.Err(err).Msg("Encrypt UserId error for promoteRequestingMember") return nil, err @@ -1399,12 +1428,18 @@ func (cli *Client) EncryptAndSignGroupChange(ctx context.Context, decryptedGroup return cli.patchGroup(ctx, groupChangeActions, groupMasterKey, nil) } -func (cli *Client) encryptMember(ctx context.Context, member *GroupMember, groupSecretParams *libsignalgo.GroupSecretParams) (*signalpb.Member, error) { +func (cli *Client) encryptMember(ctx context.Context, member *GroupMember, groupSecretParams *libsignalgo.GroupSecretParams) (*signalpb.Member, *signalpb.PendingMember, error) { log := zerolog.Ctx(ctx) - expiringProfileKeyCredential, err := cli.FetchExpiringProfileKeyCredentialById(ctx, member.UserID) + expiringProfileKeyCredential, err := cli.FetchExpiringProfileKeyCredentialById(ctx, member.ACI) if err != nil { - log.Err(err).Msg("failed getting expiring profile key credential for addMember") - return nil, err + log.Err(err).Msg("failed getting expiring profile key credential for member, trying to encrypt as PendingMember") + pendingMember := PendingMember{ + ServiceID: member.UserServiceID(), + Role: member.Role, + AddedByUserID: cli.Store.ACI, + } + encryptedPendingMember, err := cli.encryptPendingMember(ctx, &pendingMember, groupSecretParams) + return nil, encryptedPendingMember, err } presentation, err := groupSecretParams.CreateExpiringProfileKeyCredentialPresentation( prodServerPublicParams, @@ -1412,13 +1447,35 @@ func (cli *Client) encryptMember(ctx context.Context, member *GroupMember, group ) if err != nil { log.Err(err).Msg("failed creating expiring profile key credential presentation for addMember") - return nil, err + return nil, nil, err } encryptedMember := signalpb.Member{ Presentation: *presentation, Role: signalpb.Member_Role(member.Role), } - return &encryptedMember, nil + return &encryptedMember, nil, nil +} + +func (cli *Client) encryptPendingMember(ctx context.Context, pendingMember *PendingMember, groupSecretParams *libsignalgo.GroupSecretParams) (*signalpb.PendingMember, error) { + log := zerolog.Ctx(ctx) + encryptedUserID, err := groupSecretParams.EncryptServiceID(pendingMember.ServiceID) + if err != nil { + log.Err(err).Msg("Encrypt UserId error for addPendingMember") + return nil, err + } + encryptedAddedByUserID, err := groupSecretParams.EncryptServiceID(libsignalgo.NewACIServiceID(pendingMember.AddedByUserID)) + if err != nil { + log.Err(err).Msg("Encrypt AddedByUserId error for addPendingMember") + return nil, err + } + encryptedPendingMember := signalpb.PendingMember{ + AddedByUserId: encryptedAddedByUserID[:], + Member: &signalpb.Member{ + UserId: encryptedUserID[:], + Role: signalpb.Member_Role(pendingMember.Role), + }, + } + return &encryptedPendingMember, nil } var ( @@ -1613,11 +1670,23 @@ func (cli *Client) EncryptGroup(ctx context.Context, decryptedGroup *Group, grou } } for _, member := range decryptedGroup.Members { - encryptedMember, err := cli.encryptMember(ctx, member, &groupSecretParams) + encryptedMember, encryptedPendingMember, err := cli.encryptMember(ctx, member, &groupSecretParams) if err != nil { log.Err(err).Msg("Failed to encrypt GroupMember") } - encryptedGroup.Members = append(encryptedGroup.Members, encryptedMember) + if encryptedMember != nil { + encryptedGroup.Members = append(encryptedGroup.Members, encryptedMember) + } else { + encryptedGroup.PendingMembers = append(encryptedGroup.PendingMembers, encryptedPendingMember) + } + } + for _, pendingMember := range decryptedGroup.PendingMembers { + encryptedPendingMember, err := cli.encryptPendingMember(ctx, pendingMember, &groupSecretParams) + if err != nil { + log.Err(err).Msg("Failed to encrypt pendingMember") + return nil, err + } + encryptedGroup.PendingMembers = append(encryptedGroup.PendingMembers, encryptedPendingMember) } return encryptedGroup, nil } diff --git a/pkg/signalmeow/sending.go b/pkg/signalmeow/sending.go index 473dd3e..11211e0 100644 --- a/pkg/signalmeow/sending.go +++ b/pkg/signalmeow/sending.go @@ -544,16 +544,21 @@ func (cli *Client) SendGroupUpdate(ctx context.Context, group *Group, groupConte GroupV2: groupContext, } content := wrapDataMessageInContent(dm) - recipients := group.Members + var recipients []*libsignalgo.ServiceID + for _, member := range group.Members { + serviceID := member.UserServiceID() + recipients = append(recipients, &serviceID) + } for _, member := range group.PendingMembers { - recipients = append(recipients, &member.GroupMember) + recipients = append(recipients, &member.ServiceID) } if groupChange != nil { for _, member := range groupChange.AddPendingMembers { - recipients = append(recipients, &member.GroupMember) + recipients = append(recipients, &member.ServiceID) } for _, member := range groupChange.AddMembers { - recipients = append(recipients, &member.GroupMember) + serviceID := member.UserServiceID() + recipients = append(recipients, &serviceID) } } return cli.sendToGroup(ctx, recipients, content, timestamp) @@ -578,32 +583,37 @@ func (cli *Client) SendGroupMessage(ctx context.Context, gid types.GroupIdentifi messageTimestamp = content.EditMessage.DataMessage.GetTimestamp() content.EditMessage.DataMessage.GroupV2 = groupMetadataForDataMessage(*group) } - return cli.sendToGroup(ctx, group.Members, content, messageTimestamp) + var recipients []*libsignalgo.ServiceID + for _, member := range group.Members { + serviceID := member.UserServiceID() + recipients = append(recipients, &serviceID) + } + return cli.sendToGroup(ctx, recipients, content, messageTimestamp) } -func (cli *Client) sendToGroup(ctx context.Context, recipients []*GroupMember, content *signalpb.Content, messageTimestamp uint64) (*GroupMessageSendResult, error) { +func (cli *Client) sendToGroup(ctx context.Context, recipients []*libsignalgo.ServiceID, content *signalpb.Content, messageTimestamp uint64) (*GroupMessageSendResult, error) { // Send to each member of the group result := &GroupMessageSendResult{ SuccessfullySentTo: []SuccessfulSendResult{}, FailedToSendTo: []FailedSendResult{}, } - for _, member := range recipients { - if member.UserID == cli.Store.ACI { + for _, recipient := range recipients { + if recipient.Type == libsignalgo.ServiceIDTypeACI && recipient.UUID == cli.Store.ACI { // Don't send normal DataMessages to ourselves continue } - log := zerolog.Ctx(ctx).With().Stringer("member", member.UserID).Logger() + log := zerolog.Ctx(ctx).With().Stringer("member", *recipient).Logger() ctx := log.WithContext(ctx) - sentUnidentified, err := cli.sendContent(ctx, member.UserServiceID(), messageTimestamp, content, 0, true) + sentUnidentified, err := cli.sendContent(ctx, *recipient, messageTimestamp, content, 0, true) if err != nil { result.FailedToSendTo = append(result.FailedToSendTo, FailedSendResult{ - Recipient: member.UserServiceID(), + Recipient: *recipient, Error: err, }) log.Err(err).Msg("Failed to send to user") } else { result.SuccessfullySentTo = append(result.SuccessfullySentTo, SuccessfulSendResult{ - Recipient: member.UserServiceID(), + Recipient: *recipient, Unidentified: sentUnidentified, }) log.Trace().Msg("Successfully sent to user") diff --git a/portal.go b/portal.go index b5be7f3..0624b89 100644 --- a/portal.go +++ b/portal.go @@ -953,19 +953,19 @@ func (portal *Portal) handleSignalGroupChange(source *User, sender *Puppet, grou intent := sender.IntentFor(portal) modifyRoles := groupChange.ModifyMemberRoles for _, deleteBannedMember := range groupChange.DeleteBannedMembers { - _, err := portal.sendMembershipForPuppetAndUser(ctx, sender, *deleteBannedMember, event.MembershipLeave, "unbanned") + _, err := portal.sendMembershipForPuppetAndUser(ctx, sender, *&deleteBannedMember.UUID, event.MembershipLeave, "unbanned") if err != nil { log.Warn().Stringer("signal_user_id", deleteBannedMember).Msg("Couldn't get puppet for unban") } } for _, addMember := range groupChange.AddMembers { - modifyRoles = append(modifyRoles, &signalmeow.RoleMember{UserID: addMember.UserID, Role: addMember.Role}) + modifyRoles = append(modifyRoles, &signalmeow.RoleMember{ACI: addMember.ACI, Role: addMember.Role}) var puppet *Puppet if addMember.JoinFromInviteLink { - puppet = portal.bridge.GetPuppetBySignalID(addMember.UserID) + puppet = portal.bridge.GetPuppetBySignalID(addMember.ACI) if puppet != nil { if puppet.customIntent == nil { - user := portal.bridge.GetUserBySignalID(addMember.UserID) + user := portal.bridge.GetUserBySignalID(addMember.ACI) if user != nil { portal.MainIntent().SendCustomMembershipEvent(ctx, portal.MXID, user.MXID, event.MembershipInvite, "Joined via invite Link") } @@ -978,20 +978,23 @@ func (portal *Portal) handleSignalGroupChange(source *User, sender *Puppet, grou } } } else { - puppet, _ = portal.sendMembershipForPuppetAndUser(ctx, sender, addMember.UserID, event.MembershipInvite, "added") + puppet, _ = portal.sendMembershipForPuppetAndUser(ctx, sender, addMember.ACI, event.MembershipInvite, "added") } if puppet != nil { puppet.IntentFor(portal).SendCustomMembershipEvent(ctx, portal.MXID, puppet.IntentFor(portal).UserID, event.MembershipJoin, "") } else { - log.Warn().Stringer("signal_user_id", addMember.UserID).Msg("Couldn't get puppet for invite") + log.Warn().Stringer("signal_user_id", addMember.ACI).Msg("Couldn't get puppet for invite") } } bannedMembers := make(map[uuid.UUID]bool) for _, addBannedMember := range groupChange.AddBannedMembers { - bannedMembers[addBannedMember.UserID] = true - _, err := portal.sendMembershipForPuppetAndUser(ctx, sender, addBannedMember.UserID, event.MembershipBan, "banned") + if addBannedMember.ServiceID.Type == libsignalgo.ServiceIDTypePNI { + continue + } + bannedMembers[addBannedMember.ServiceID.UUID] = true + _, err := portal.sendMembershipForPuppetAndUser(ctx, sender, addBannedMember.ServiceID.UUID, event.MembershipBan, "banned") if err != nil { - log.Warn().Stringer("signal_user_id", addBannedMember.UserID).Msg("Couldn't get puppet for ban") + log.Warn().Stringer("signal_user_id", addBannedMember.ServiceID.UUID).Msg("Couldn't get puppet for ban") } } for _, deleteMember := range groupChange.DeleteMembers { @@ -1004,10 +1007,13 @@ func (portal *Portal) handleSignalGroupChange(source *User, sender *Puppet, grou } } for _, deletePendingMember := range groupChange.DeletePendingMembers { - if bannedMembers[*deletePendingMember] { + if deletePendingMember.Type == libsignalgo.ServiceIDTypePNI { continue } - _, err := portal.sendMembershipForPuppetAndUser(ctx, sender, *deletePendingMember, event.MembershipLeave, "invite withdrawn") + if bannedMembers[deletePendingMember.UUID] { + continue + } + _, err := portal.sendMembershipForPuppetAndUser(ctx, sender, deletePendingMember.UUID, event.MembershipLeave, "invite withdrawn") if err != nil { log.Warn().Stringer("signal_user_id", deletePendingMember).Msg("Couldn't get puppet for removal") } @@ -1022,35 +1028,46 @@ func (portal *Portal) handleSignalGroupChange(source *User, sender *Puppet, grou } } for _, promotePendingMember := range groupChange.PromotePendingMembers { - puppet, err := portal.sendMembershipForPuppetAndUser(ctx, sender, promotePendingMember.UserID, event.MembershipInvite, "request accepted") - if err == nil { - puppet.IntentFor(portal).EnsureJoined(ctx, portal.MXID) - } else { - log.Warn().Stringer("signal_user_id", promotePendingMember.UserID).Msg("Couldn't get puppet for invite") + puppet := portal.bridge.GetPuppetBySignalID(promotePendingMember.ACI) + if puppet == nil { + log.Warn().Stringer("signal_user_id", promotePendingMember.ACI).Msg("Couldn't get puppet for invite") + continue } + puppet.IntentFor(portal).EnsureJoined(ctx, portal.MXID) + } + for _, promotePendingPniAciMember := range groupChange.PromotePendingPniAciMembers { + puppet := portal.bridge.GetPuppetBySignalID(promotePendingPniAciMember.ACI) + if puppet == nil { + log.Warn().Stringer("signal_user_id", promotePendingPniAciMember.ACI).Msg("Couldn't get puppet for invite") + continue + } + puppet.IntentFor(portal).EnsureJoined(ctx, portal.MXID) } for _, addPendingMember := range groupChange.AddPendingMembers { - _, err := portal.sendMembershipForPuppetAndUser(ctx, sender, addPendingMember.UserID, event.MembershipInvite, "invited") - if err != nil { - log.Warn().Stringer("signal_user_id", addPendingMember.UserID).Msg("Couldn't get puppet for invite") + if addPendingMember.ServiceID.Type == libsignalgo.ServiceIDTypePNI { + continue } - modifyRoles = append(modifyRoles, &signalmeow.RoleMember{UserID: addPendingMember.UserID, Role: addPendingMember.Role}) + _, err := portal.sendMembershipForPuppetAndUser(ctx, sender, addPendingMember.ServiceID.UUID, event.MembershipInvite, "invited") + if err != nil { + log.Warn().Stringer("signal_user_id", addPendingMember.ServiceID).Msg("Couldn't get puppet for invite") + } + modifyRoles = append(modifyRoles, &signalmeow.RoleMember{ACI: addPendingMember.ServiceID.UUID, Role: addPendingMember.Role}) } for _, promoteRequestingMember := range groupChange.PromoteRequestingMembers { - puppet, err := portal.sendMembershipForPuppetAndUser(ctx, sender, promoteRequestingMember.UserID, event.MembershipInvite, "accepted") + puppet, err := portal.sendMembershipForPuppetAndUser(ctx, sender, promoteRequestingMember.ACI, event.MembershipInvite, "accepted") if err == nil { err = puppet.IntentFor(portal).EnsureJoined(ctx, portal.MXID) if err != nil { - log.Warn().Stringer("signal_user_id", promoteRequestingMember.UserID).Msg("failed to join puppet") + log.Warn().Stringer("signal_user_id", promoteRequestingMember.ACI).Msg("failed to join puppet") } } else { - log.Warn().Stringer("signal_user_id", promoteRequestingMember.UserID).Msg("Couldn't get puppet for join") + log.Warn().Stringer("signal_user_id", promoteRequestingMember.ACI).Msg("Couldn't get puppet for join") } - modifyRoles = append(modifyRoles, &signalmeow.RoleMember{UserID: promoteRequestingMember.UserID, Role: promoteRequestingMember.Role}) + modifyRoles = append(modifyRoles, &signalmeow.RoleMember{ACI: promoteRequestingMember.ACI, Role: promoteRequestingMember.Role}) } for _, addRequestingMember := range groupChange.AddRequestingMembers { // sender and target should be the same SignalID - puppet := portal.bridge.GetPuppetBySignalID(addRequestingMember.UserID) + puppet := portal.bridge.GetPuppetBySignalID(addRequestingMember.ACI) if puppet != nil { portal.sendMembershipWithPuppet(ctx, sender, puppet.IntentFor(portal).UserID, event.MembershipKnock, "knocked") } @@ -1062,9 +1079,9 @@ func (portal *Portal) handleSignalGroupChange(source *User, sender *Puppet, grou log.Err(err).Msg("Couldn't get power levels") } else { for _, modifyRole := range modifyRoles { - puppet := portal.bridge.GetPuppetBySignalID(modifyRole.UserID) + puppet := portal.bridge.GetPuppetBySignalID(modifyRole.ACI) if puppet == nil { - log.Warn().Stringer("signal_user_id", modifyRole.UserID).Msg("Couldn't get puppet for power level change") + log.Warn().Stringer("signal_user_id", modifyRole.ACI).Msg("Couldn't get puppet for power level change") continue } powerLevel := 0 @@ -1073,7 +1090,7 @@ func (portal *Portal) handleSignalGroupChange(source *User, sender *Puppet, grou } levels.EnsureUserLevel(puppet.IntentFor(portal).UserID, powerLevel) if puppet.customIntent == nil { - user := portal.bridge.GetUserBySignalID(modifyRole.UserID) + user := portal.bridge.GetUserBySignalID(modifyRole.ACI) if user != nil { levels.EnsureUserLevel(user.MXID, powerLevel) } @@ -2237,14 +2254,14 @@ func (portal *Portal) SyncParticipants(ctx context.Context, source *User, info * } } for _, member := range info.Members { - puppet := portal.bridge.GetPuppetBySignalID(member.UserID) + puppet := portal.bridge.GetPuppetBySignalID(member.ACI) if puppet == nil { - log.Warn().Stringer("signal_user_id", member.UserID).Msg("Couldn't get puppet for group member") + log.Warn().Stringer("signal_user_id", member.ACI).Msg("Couldn't get puppet for group member") continue } puppet.UpdateInfo(ctx, source) intent := puppet.IntentFor(portal) - if member.UserID != source.SignalID && portal.MXID != "" { + if member.ACI != source.SignalID && portal.MXID != "" { userIDs[intent.UserID] = ((int)(member.Role) >> 1) * 50 } delete(currentMembers, intent.UserID) @@ -2252,11 +2269,11 @@ func (portal *Portal) SyncParticipants(ctx context.Context, source *User, info * if currentMembers[intent.UserID] != event.MembershipJoin { err := intent.EnsureJoined(ctx, portal.MXID) if err != nil { - log.Err(err).Stringer("signal_user_id", member.UserID).Msg("Failed to ensure user is joined to portal") + log.Err(err).Stringer("signal_user_id", member.ACI).Msg("Failed to ensure user is joined to portal") } } if puppet.customIntent == nil { - user := portal.bridge.GetUserBySignalID(member.UserID) + user := portal.bridge.GetUserBySignalID(member.ACI) if user != nil { delete(currentMembers, user.MXID) userIDs[user.MXID] = ((int)(member.Role) >> 1) * 50 @@ -2273,9 +2290,12 @@ func (portal *Portal) SyncParticipants(ctx context.Context, source *User, info * return userIDs } for _, pendingMember := range info.PendingMembers { - puppet := portal.bridge.GetPuppetBySignalID(pendingMember.UserID) + if pendingMember.ServiceID.Type == libsignalgo.ServiceIDTypePNI { + continue + } + puppet := portal.bridge.GetPuppetBySignalID(pendingMember.ServiceID.UUID) if puppet == nil { - log.Warn().Stringer("signal_user_id", pendingMember.UserID).Msg("Couldn't get puppet for group member") + log.Warn().Stringer("signal_user_id", pendingMember.ServiceID.UUID).Msg("Couldn't get puppet for group member") continue } mxid := puppet.IntentFor(portal).UserID @@ -2295,7 +2315,7 @@ func (portal *Portal) SyncParticipants(ctx context.Context, source *User, info * userIDs[mxid] = ((int)(pendingMember.Role) >> 1) * 50 delete(currentMembers, mxid) if puppet.customIntent == nil { - user := portal.bridge.GetUserBySignalID(pendingMember.UserID) + user := portal.bridge.GetUserBySignalID(pendingMember.ServiceID.UUID) if user == nil { continue } @@ -2319,9 +2339,9 @@ func (portal *Portal) SyncParticipants(ctx context.Context, source *User, info * } } for _, requestingMember := range info.RequestingMembers { - puppet := portal.bridge.GetPuppetBySignalID(requestingMember.UserID) + puppet := portal.bridge.GetPuppetBySignalID(requestingMember.ACI) if puppet == nil { - log.Warn().Stringer("signal_user_id", requestingMember.UserID).Msg("Couldn't get puppet for group member") + log.Warn().Stringer("signal_user_id", requestingMember.ACI).Msg("Couldn't get puppet for group member") continue } mxid := puppet.IntentFor(portal).UserID @@ -2341,9 +2361,12 @@ func (portal *Portal) SyncParticipants(ctx context.Context, source *User, info * delete(currentMembers, mxid) } for _, bannedMember := range info.BannedMembers { - puppet := portal.bridge.GetPuppetBySignalID(bannedMember.UserID) + if bannedMember.ServiceID.Type == libsignalgo.ServiceIDTypePNI { + continue + } + puppet := portal.bridge.GetPuppetBySignalID(bannedMember.ServiceID.UUID) if puppet == nil { - log.Warn().Stringer("signal_user_id", bannedMember.UserID).Msg("Couldn't get puppet for group member") + log.Warn().Stringer("signal_user_id", bannedMember.ServiceID.UUID).Msg("Couldn't get puppet for group member") continue } mxid := puppet.IntentFor(portal).UserID @@ -2355,7 +2378,7 @@ func (portal *Portal) SyncParticipants(ctx context.Context, source *User, info * } delete(currentMembers, mxid) if puppet.customIntent == nil { - user := portal.bridge.GetUserBySignalID(bannedMember.UserID) + user := portal.bridge.GetUserBySignalID(bannedMember.ServiceID.UUID) if user == nil { continue } @@ -2590,8 +2613,8 @@ func (portal *Portal) HandleMatrixInvite(brSender bridge.User, brGhost bridge.Gh } groupChange := &signalmeow.GroupChange{AddMembers: []*signalmeow.AddMember{{ GroupMember: signalmeow.GroupMember{ - UserID: puppet.SignalID, - Role: role, + ACI: puppet.SignalID, + Role: role, }, }}} revision, err := sender.Client.UpdateGroup(ctx, groupChange, portal.GroupID()) @@ -2621,8 +2644,8 @@ func (portal *Portal) HandleMatrixAcceptKnock(brSender bridge.User, brGhost brid } } groupChange := &signalmeow.GroupChange{PromoteRequestingMembers: []*signalmeow.RoleMember{{ - UserID: puppet.SignalID, - Role: role, + ACI: puppet.SignalID, + Role: role, }}} revision, err := sender.Client.UpdateGroup(ctx, groupChange, portal.GroupID()) if err != nil { @@ -2675,7 +2698,7 @@ func (portal *Portal) HandleMatrixBan(brSender bridge.User, brGhost bridge.Ghost sender := brSender.(*User) puppet := brGhost.(*Puppet) groupChange := &signalmeow.GroupChange{AddBannedMembers: []*signalmeow.BannedMember{{ - UserID: puppet.SignalID, + ServiceID: libsignalgo.NewACIServiceID(puppet.SignalID), Timestamp: uint64(time.Now().UnixMilli()), }}} switch prevMembership := evt.Unsigned.PrevContent.AsMember().Membership; prevMembership { @@ -2684,7 +2707,8 @@ func (portal *Portal) HandleMatrixBan(brSender bridge.User, brGhost bridge.Ghost case event.MembershipKnock: groupChange.DeleteRequestingMembers = []*uuid.UUID{&puppet.SignalID} case event.MembershipInvite: - groupChange.DeletePendingMembers = []*uuid.UUID{&puppet.SignalID} + serviceID := libsignalgo.NewACIServiceID(puppet.SignalID) + groupChange.DeletePendingMembers = []*libsignalgo.ServiceID{&serviceID} } revision, err := sender.Client.UpdateGroup(ctx, groupChange, portal.GroupID()) if err != nil { @@ -2703,7 +2727,8 @@ func (portal *Portal) HandleMatrixUnban(brSender bridge.User, brGhost bridge.Gho ctx := log.WithContext(context.TODO()) sender := brSender.(*User) puppet := brGhost.(*Puppet) - groupChange := &signalmeow.GroupChange{DeleteBannedMembers: []*uuid.UUID{&puppet.SignalID}} + serviceID := libsignalgo.NewACIServiceID(puppet.SignalID) + groupChange := &signalmeow.GroupChange{DeleteBannedMembers: []*libsignalgo.ServiceID{&serviceID}} revision, err := sender.Client.UpdateGroup(ctx, groupChange, portal.GroupID()) if err != nil { log.Err(err).Msg("Error unbanning on Signal") @@ -2748,8 +2773,8 @@ func (portal *Portal) HandleMatrixPowerLevels(brSender bridge.User, evt *event.E role = signalmeow.GroupMember_ADMINISTRATOR } groupChange.ModifyMemberRoles = append(groupChange.ModifyMemberRoles, &signalmeow.RoleMember{ - UserID: puppet.SignalID, - Role: role, + ACI: puppet.SignalID, + Role: role, }) } } From fd7c3cd1b5d3b037aa396780cace411dbd2d33eb Mon Sep 17 00:00:00 2001 From: Malte E Date: Thu, 4 Apr 2024 21:40:05 +0200 Subject: [PATCH 007/580] add list-invited and revoke-invite commands, some fixes --- commands.go | 160 ++++++++++++++++++++++++++++++++++++--- pkg/signalmeow/groups.go | 2 +- 2 files changed, 150 insertions(+), 12 deletions(-) diff --git a/commands.go b/commands.go index 1b4fbea..2f224bc 100644 --- a/commands.go +++ b/commands.go @@ -72,6 +72,8 @@ func (br *SignalBridge) RegisterCommands() { cmdResetInviteLink, cmdCreate, cmdInvite, + cmdListInvited, + cmdRevokeInvite, ) } @@ -345,20 +347,156 @@ func fnInvite(ce *WrappedCommandEvent) { var groupChange signalmeow.GroupChange if aci != uuid.Nil { - groupChange.AddMembers = append(groupChange.AddMembers, &signalmeow.AddMember{ - GroupMember: signalmeow.GroupMember{ - ACI: aci, - Role: signalmeow.GroupMember_DEFAULT, + groupChange.AddMembers = []*signalmeow.AddMember{ + { + GroupMember: signalmeow.GroupMember{ + ACI: aci, + Role: signalmeow.GroupMember_DEFAULT, + }, }, - }) + } } else { - groupChange.AddPendingMembers = append(groupChange.AddPendingMembers, &signalmeow.PendingMember{ - ServiceID: libsignalgo.NewPNIServiceID(pni), - AddedByUserID: ce.User.SignalID, - Role: signalmeow.GroupMember_DEFAULT, - }) + groupChange.AddPendingMembers = []*signalmeow.PendingMember{ + { + ServiceID: libsignalgo.NewPNIServiceID(pni), + AddedByUserID: ce.User.SignalID, + Role: signalmeow.GroupMember_DEFAULT, + }, + } } - ce.User.Client.UpdateGroup(ce.Ctx, &groupChange, ce.Portal.GroupID()) + revision, err := ce.User.Client.UpdateGroup(ce.Ctx, &groupChange, ce.Portal.GroupID()) + if err != nil { + ce.Reply("Failed to update group: %w", err) + return + } + ce.Portal.Revision = revision + if aci != uuid.Nil { + group, err := ce.User.Client.RetrieveGroupByID(ce.Ctx, ce.Portal.GroupID(), revision) + if err != nil { + ce.Reply("Failed to fetch group after invite: %w", err) + } + ce.Portal.SyncParticipants(ce.Ctx, user, group) + ce.Portal.Update(ce.Ctx) + return + } + ce.Portal.Update(ce.Ctx) + ce.Reply("Invited " + e164) +} + +var cmdListInvited = &commands.FullHandler{ + Func: wrapCommand(fnListInvited), + Name: "list-invited", + Help: commands.HelpMeta{ + Section: HelpSectionPortalManagement, + Description: "list pending invites", + Args: "<_international phone number_>", + }, + RequiresLogin: true, + RequiresPortal: true, +} + +func fnListInvited(ce *WrappedCommandEvent) { + group, err := ce.User.Client.RetrieveGroupByID(ce.Ctx, ce.Portal.GroupID(), ce.Portal.Revision) + if err != nil { + ce.Reply("Failed to fetch group info: %w", err) + return + } + var memberList []string + for _, pendingMember := range group.PendingMembers { + recipientString, err := pendingMemberToString(ce.Ctx, ce.User, pendingMember) + if err != nil { + ce.Reply("Failed to fetch recipient for %s: %w", pendingMember.ServiceID, err) + continue + } + memberList = append(memberList, recipientString) + } + if len(memberList) == 0 { + ce.Reply("No pending Invites") + } else { + ce.Reply(strings.Join(memberList, "\n")) + } +} + +func pendingMemberToString(ctx context.Context, user *User, pendingMember *signalmeow.PendingMember) (string, error) { + var pni, aci uuid.UUID + if pendingMember.ServiceID.Type == libsignalgo.ServiceIDTypeACI { + aci = pendingMember.ServiceID.UUID + } else { + pni = pendingMember.ServiceID.UUID + } + recipient, err := user.Client.Store.RecipientStore.LoadAndUpdateRecipient(ctx, aci, pni, nil) + if err != nil { + return "", err + } + if recipient.E164 != "" { + return recipient.E164, nil + } else { + return "Unidentified User", nil + } +} + +var cmdRevokeInvite = &commands.FullHandler{ + Func: wrapCommand(fnRevokeInvite), + Name: "revoke-invite", + Help: commands.HelpMeta{ + Section: HelpSectionPortalManagement, + Description: "Revoke an invite by phone number.", + Args: "<_international phone number_>", + }, + RequiresLogin: true, + RequiresPortal: true, +} + +func fnRevokeInvite(ce *WrappedCommandEvent) { + if len(ce.Args) == 0 { + ce.Reply("**Usage:** `RevokeInvite `") + return + } + e164 := "+" + numberCleaner.Replace(strings.Join(ce.Args, "")) + + user := ce.User + var serviceID libsignalgo.ServiceID + group, err := ce.User.Client.RetrieveGroupByID(ce.Ctx, ce.Portal.GroupID(), ce.Portal.Revision) + if err != nil { + ce.Reply("Failed to fetch group info: %w", err) + return + } + var pni, aci uuid.UUID + for _, pendingMember := range group.PendingMembers { + if pendingMember.ServiceID.Type == libsignalgo.ServiceIDTypeACI { + aci = pendingMember.ServiceID.UUID + } else { + pni = pendingMember.ServiceID.UUID + } + recipient, err := user.Client.Store.RecipientStore.LoadAndUpdateRecipient(ce.Ctx, aci, pni, nil) + if err != nil { + continue + } + if recipient.E164 == e164 { + serviceID = pendingMember.ServiceID + break + } + } + if serviceID.UUID == uuid.Nil { + ce.Reply("User not in Group") + return + } + var groupChange signalmeow.GroupChange + groupChange.DeletePendingMembers = []*libsignalgo.ServiceID{&serviceID} + revision, err := ce.User.Client.UpdateGroup(ce.Ctx, &groupChange, ce.Portal.GroupID()) + if err != nil { + ce.Reply("Failed to update group: %w", err) + return + } + if aci != uuid.Nil { + target := ce.Bridge.GetPuppetBySignalID(aci) + if target != nil { + ce.Bot.SendCustomMembershipEvent(ce.Ctx, ce.Portal.MXID, target.IntentFor(ce.Portal).UserID, event.MembershipLeave, "removed by "+user.MXID.String()) + } + } + ce.Portal.Revision = revision + ce.Portal.Update(ce.Ctx) + ce.Reply("Revoked the invitation for " + e164) } var cmdResolvePhone = &commands.FullHandler{ diff --git a/pkg/signalmeow/groups.go b/pkg/signalmeow/groups.go index 0e647d0..e4857bf 100644 --- a/pkg/signalmeow/groups.go +++ b/pkg/signalmeow/groups.go @@ -1294,7 +1294,7 @@ func (cli *Client) EncryptAndSignGroupChange(ctx context.Context, decryptedGroup }) } for _, deletePendingMember := range decryptedGroupChange.DeletePendingMembers { - encryptedUserID, err := groupSecretParams.EncryptServiceID(libsignalgo.NewACIServiceID(deletePendingMember.UUID)) + encryptedUserID, err := groupSecretParams.EncryptServiceID(*deletePendingMember) if err != nil { log.Err(err).Msg("Encrypt UserId error for deletePendingMember") return nil, err From 9bf99ebe0eeb2e33467290ec7989c82078f02756 Mon Sep 17 00:00:00 2001 From: Malte E <97891689+maltee1@users.noreply.github.com> Date: Fri, 5 Apr 2024 11:22:49 +0200 Subject: [PATCH 008/580] Fix comparison in promotePendingPniAciMembers --- pkg/signalmeow/groups.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/signalmeow/groups.go b/pkg/signalmeow/groups.go index e4857bf..829fc03 100644 --- a/pkg/signalmeow/groups.go +++ b/pkg/signalmeow/groups.go @@ -1022,7 +1022,7 @@ func (cli *Client) DecryptGroupChange(ctx context.Context, groupContext *signalp log.Err(err).Msg("DecryptUUID Pni error for promotePendingPniAciMember") return nil, err } - if pniServiceID.Type != libsignalgo.ServiceIDTypeACI { + if pniServiceID.Type != libsignalgo.ServiceIDTypePNI { return nil, fmt.Errorf("Wrong ServiceID kind: expected PNI, got ACI") } encryptedProfileKey := libsignalgo.ProfileKeyCiphertext(promotePendingPniAciMember.ProfileKey) From 680e0b8c52a36267844e2bf71e522d2c1c1c0cef Mon Sep 17 00:00:00 2001 From: Malte E <97891689+maltee1@users.noreply.github.com> Date: Mon, 8 Apr 2024 21:24:49 +0200 Subject: [PATCH 009/580] Handle missed GroupChanges using group history (#488) --- pkg/signalmeow/groups.go | 111 ++++++++++++++++++++++++++++++++++++--- portal.go | 45 ++++++++++++++-- 2 files changed, 147 insertions(+), 9 deletions(-) diff --git a/pkg/signalmeow/groups.go b/pkg/signalmeow/groups.go index 829fc03..1214088 100644 --- a/pkg/signalmeow/groups.go +++ b/pkg/signalmeow/groups.go @@ -178,6 +178,7 @@ type BannedMember struct { type GroupChange struct { groupMasterKey types.SerializedGroupMasterKey + SourceACI uuid.UUID Revision uint32 AddMembers []*AddMember DeleteMembers []*uuid.UUID @@ -317,6 +318,11 @@ func (groupChange *GroupChange) GetAvatarPath() *string { return groupChange.ModifyAvatar } +type GroupChangeState struct { + GroupState *Group + GroupChange *GroupChange +} + type GroupAuth struct { Username string Password string @@ -812,21 +818,26 @@ type GroupCache struct { func (cli *Client) DecryptGroupChange(ctx context.Context, groupContext *signalpb.GroupContextV2) (*GroupChange, error) { masterKeyBytes := libsignalgo.GroupMasterKey(groupContext.MasterKey) groupMasterKey := masterKeyFromBytes(masterKeyBytes) - log := zerolog.Ctx(ctx).With().Str("action", "decrypt group change").Logger() - - encryptedGroupChange := &signalpb.GroupChange{} groupChangeBytes := groupContext.GroupChange + encryptedGroupChange := &signalpb.GroupChange{} err := proto.Unmarshal(groupChangeBytes, encryptedGroupChange) if err != nil { return nil, fmt.Errorf("Error unmarshalling group change: %w", err) } + return cli.decryptGroupChange(ctx, encryptedGroupChange, groupMasterKey, true) +} +func (cli *Client) decryptGroupChange(ctx context.Context, encryptedGroupChange *signalpb.GroupChange, groupMasterKey types.SerializedGroupMasterKey, verifySignature bool) (*GroupChange, error) { + log := zerolog.Ctx(ctx).With().Str("action", "decrypt group change").Logger() serverSignature := encryptedGroupChange.ServerSignature encryptedActionsBytes := encryptedGroupChange.Actions - err = libsignalgo.ServerPublicParamsVerifySignature(prodServerPublicParams, encryptedActionsBytes, libsignalgo.NotarySignature(serverSignature)) - if err != nil { - return nil, fmt.Errorf("Failed to verify Server Signature: %w", err) + var err error + if verifySignature { + err = libsignalgo.ServerPublicParamsVerifySignature(prodServerPublicParams, encryptedActionsBytes, libsignalgo.NotarySignature(serverSignature)) + if err != nil { + return nil, fmt.Errorf("Failed to verify Server Signature: %w", err) + } } encryptedActions := signalpb.GroupChange_Actions{} @@ -842,9 +853,18 @@ func (cli *Client) DecryptGroupChange(ctx context.Context, groupContext *signalp return nil, err } + sourceServiceID, err := groupSecretParams.DecryptServiceID(libsignalgo.UUIDCiphertext(encryptedActions.SourceServiceId)) + if err != nil { + log.Err(err).Msg("Couldn't decrypt source serviceID") + return nil, err + } + if sourceServiceID.Type != libsignalgo.ServiceIDTypeACI { + return nil, fmt.Errorf("wrong serviceid kind: expected aci, got pni") + } decryptedGroupChange := &GroupChange{ groupMasterKey: groupMasterKey, Revision: encryptedActions.Revision, + SourceACI: sourceServiceID.UUID, } if encryptedActions.ModifyTitle != nil { @@ -1794,3 +1814,82 @@ func (cli *Client) CreateGroup(ctx context.Context, decryptedGroup *Group, avata } return group, nil } + +func (cli *Client) GetGroupHistoryPage(ctx context.Context, gid types.GroupIdentifier, fromRevision uint32, includeFirstState bool) ([]*GroupChangeState, error) { + log := zerolog.Ctx(ctx).With().Str("action", "GetGroupHistoryPage").Logger() + groupMasterKey, err := cli.Store.GroupStore.MasterKeyFromGroupIdentifier(ctx, gid) + if err != nil { + log.Err(err).Msg("Failed to get group master key") + return nil, err + } + if groupMasterKey == "" { + return nil, fmt.Errorf("No group master key found for group identifier %s", gid) + } + masterKeyBytes := masterKeyToBytes(groupMasterKey) + groupAuth, err := cli.GetAuthorizationForToday(ctx, masterKeyBytes) + if err != nil { + return nil, err + } + opts := &web.HTTPReqOpt{ + Username: &groupAuth.Username, + Password: &groupAuth.Password, + ContentType: web.ContentTypeProtobuf, + Host: web.StorageHostname, + } + // highest known epoch seems to always be 5, but that may change in the future. includeLastState is always false + path := fmt.Sprintf("/v1/groups/logs/%d?maxSupportedChangeEpoch=%d&includeFirstState=%t&includeLastState=false", fromRevision, 5, includeFirstState) + response, err := web.SendHTTPRequest(ctx, http.MethodGet, path, opts) + if err != nil { + return nil, err + } + if response.StatusCode != 200 { + return nil, fmt.Errorf("fetchGroupByID SendHTTPRequest bad status: %d", response.StatusCode) + } + var encryptedGroupChanges signalpb.GroupChanges + groupChangesBytes, err := io.ReadAll(response.Body) + if err != nil { + return nil, err + } + err = proto.Unmarshal(groupChangesBytes, &encryptedGroupChanges) + if err != nil { + return nil, fmt.Errorf("failed to unmarshal group: %w", err) + } + + groupChanges, err := cli.decryptGroupChanges(ctx, &encryptedGroupChanges, groupMasterKey) + if err != nil { + return nil, fmt.Errorf("failed to decrypt group: %w", err) + } + return groupChanges, nil +} + +func (cli *Client) decryptGroupChanges(ctx context.Context, encryptedGroupChanges *signalpb.GroupChanges, groupMasterKey types.SerializedGroupMasterKey) ([]*GroupChangeState, error) { + log := zerolog.Ctx(ctx).With().Str("action", "decryptGroupChanges").Logger() + var groupChanges []*GroupChangeState + for _, groupChangeState := range encryptedGroupChanges.GroupChanges { + var group *Group + var err error + // GroupState == nil is normal, except for first and last, depending on the parameters it was fetched with + if groupChangeState.GroupState != nil { + group, err = decryptGroup(ctx, groupChangeState.GroupState, groupMasterKey) + if err != nil { + log.Err(err).Msg("Failed to decrypt Group") + return nil, err + } + } + var groupChange *GroupChange + // GroupChange shouldn't be nil - if it is, something will probably go wrong + if groupChangeState.GroupChange == nil { + return nil, fmt.Errorf("received group change state without group change") + } + groupChange, err = cli.decryptGroupChange(ctx, groupChangeState.GroupChange, groupMasterKey, false) + if err != nil { + log.Err(err).Msg("Failed to decrypt GroupChange") + return nil, err + } + groupChanges = append(groupChanges, &GroupChangeState{ + GroupState: group, + GroupChange: groupChange, + }) + } + return groupChanges, nil +} diff --git a/portal.go b/portal.go index 0624b89..5a4ae72 100644 --- a/portal.go +++ b/portal.go @@ -893,9 +893,18 @@ func (portal *Portal) handleSignalDataMessage(source *User, sender *Puppet, msg // Always update sender info when we receive a message from them, there's caching inside the function sender.UpdateInfo(genericCtx, source) // Handle earlier missed group changes here. - // If this message is a group change, don't handle it here, it's handled below. - if msg.GetGroupV2().GetGroupChange() == nil && portal.Revision < msg.GetGroupV2().GetRevision() { - portal.UpdateInfo(genericCtx, source, nil, msg.GetGroupV2().GetRevision()) + if msg.GetGroupV2() != nil { + requiredRevision := msg.GetGroupV2().GetRevision() + if msg.GetGroupV2().GetGroupChange() != nil { + requiredRevision = requiredRevision - 1 + } + if portal.Revision < requiredRevision { + err := portal.catchUpHistory(source, portal.Revision+1, requiredRevision, msg.GetTimestamp()) + if err != nil { + portal.log.Err(err).Msg("Failed to catch up group history, trying regular update") + portal.UpdateInfo(genericCtx, source, nil, msg.GetGroupV2().GetRevision()) + } + } } else if portal.IsPrivateChat() && portal.UserID().UUID == portal.Receiver && portal.Name != NoteToSelfName { // Slightly hacky way to make note to self names backfill portal.UpdateDMInfo(genericCtx, false) @@ -921,6 +930,30 @@ func (portal *Portal) handleSignalDataMessage(source *User, sender *Puppet, msg } } +func (portal *Portal) catchUpHistory(source *User, fromRevision uint32, toRevision uint32, ts uint64) error { + log := portal.log.With(). + Str("action", "catchUpHistory"). + Stringer("source", source.MXID). + Uint32("from_revision", fromRevision). + Uint32("to_revision", toRevision). + Logger() + ctx := log.WithContext(context.TODO()) + groupChanges, err := source.Client.GetGroupHistoryPage(ctx, portal.GroupID(), fromRevision, false) + if err != nil { + log.Err(err).Msg("Failed to get GroupChanges") + return err + } + for _, groupChangeState := range groupChanges { + sender := portal.bridge.GetPuppetBySignalID(groupChangeState.GroupChange.SourceACI) + portal.applySignalGroupChange(ctx, source, sender, groupChangeState.GroupChange, ts) + // for revision > toRevision, we should have received a group change already + if groupChangeState.GroupChange.Revision == toRevision { + break + } + } + return nil +} + func (portal *Portal) handleSignalGroupChange(source *User, sender *Puppet, groupMeta *signalpb.GroupContextV2, ts uint64) { log := portal.log.With(). Str("action", "handle signal group change"). @@ -934,6 +967,11 @@ func (portal *Portal) handleSignalGroupChange(source *User, sender *Puppet, grou log.Err(err).Msg("Handling GroupChange failed") return } + portal.applySignalGroupChange(ctx, source, sender, groupChange, ts) +} + +func (portal *Portal) applySignalGroupChange(ctx context.Context, source *User, sender *Puppet, groupChange *signalmeow.GroupChange, ts uint64) { + log := zerolog.Ctx(ctx) if groupChange.Revision <= portal.Revision { return } @@ -952,6 +990,7 @@ func (portal *Portal) handleSignalGroupChange(source *User, sender *Puppet, grou } intent := sender.IntentFor(portal) modifyRoles := groupChange.ModifyMemberRoles + var err error for _, deleteBannedMember := range groupChange.DeleteBannedMembers { _, err := portal.sendMembershipForPuppetAndUser(ctx, sender, *&deleteBannedMember.UUID, event.MembershipLeave, "unbanned") if err != nil { From 57348d094386d31e3ab9ca7fcc63f80cf21d02c2 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Wed, 10 Apr 2024 12:30:38 +0300 Subject: [PATCH 010/580] Update to libsignal 0.44.0 --- pkg/libsignalgo/authcredential.go | 16 +- pkg/libsignalgo/libsignal | 2 +- pkg/libsignalgo/libsignal-ffi.h | 248 ++++++++++++++----- pkg/libsignalgo/version.go | 2 +- pkg/signalmeow/prod-server-public-params.dat | Bin 641 -> 673 bytes 5 files changed, 197 insertions(+), 71 deletions(-) diff --git a/pkg/libsignalgo/authcredential.go b/pkg/libsignalgo/authcredential.go index 193f5b8..57396ef 100644 --- a/pkg/libsignalgo/authcredential.go +++ b/pkg/libsignalgo/authcredential.go @@ -23,6 +23,7 @@ package libsignalgo */ import "C" import ( + "fmt" "unsafe" "github.com/google/uuid" @@ -45,9 +46,8 @@ func ReceiveAuthCredentialWithPni( redemptionTime uint64, authCredResponse AuthCredentialWithPniResponse, ) (*AuthCredentialWithPni, error) { - c_result := [C.SignalAUTH_CREDENTIAL_WITH_PNI_LEN]C.uchar{} + var c_result C.SignalOwnedBuffer = C.SignalOwnedBuffer{} c_serverPublicParams := (*[C.SignalSERVER_PUBLIC_PARAMS_LEN]C.uchar)(unsafe.Pointer(&serverPublicParams[0])) - c_authCredResponse := (*[C.SignalAUTH_CREDENTIAL_WITH_PNI_RESPONSE_LEN]C.uchar)(unsafe.Pointer(&authCredResponse[0])) signalFfiError := C.signal_server_public_params_receive_auth_credential_with_pni_as_service_id( &c_result, @@ -55,13 +55,16 @@ func ReceiveAuthCredentialWithPni( NewACIServiceID(aci).CFixedBytes(), NewPNIServiceID(pni).CFixedBytes(), C.uint64_t(redemptionTime), - c_authCredResponse, + BytesToBuffer(authCredResponse[:]), ) if signalFfiError != nil { return nil, wrapError(signalFfiError) } - result := AuthCredentialWithPni(C.GoBytes(unsafe.Pointer(&c_result), C.int(C.SignalAUTH_CREDENTIAL_WITH_PNI_LEN))) - return &result, nil + resultBytes := CopySignalOwnedBufferToBytes(c_result) + if len(resultBytes) != C.SignalAUTH_CREDENTIAL_WITH_PNI_LEN { + return nil, fmt.Errorf("invalid response length %d (expected %d)", len(resultBytes), C.SignalAUTH_CREDENTIAL_WITH_PNI_LEN) + } + return (*AuthCredentialWithPni)(resultBytes), nil } func NewAuthCredentialWithPniResponse(b []byte) (*AuthCredentialWithPniResponse, error) { @@ -84,14 +87,13 @@ func CreateAuthCredentialWithPniPresentation( c_serverPublicParams := (*[C.SignalSERVER_PUBLIC_PARAMS_LEN]C.uchar)(unsafe.Pointer(&serverPublicParams[0])) c_randomness := (*[C.SignalRANDOMNESS_LEN]C.uchar)(unsafe.Pointer(&randomness[0])) c_groupSecretParams := (*[C.SignalGROUP_SECRET_PARAMS_LEN]C.uchar)(unsafe.Pointer(&groupSecretParams[0])) - c_authCredWithPni := (*[C.SignalAUTH_CREDENTIAL_WITH_PNI_LEN]C.uchar)(unsafe.Pointer(&authCredWithPni[0])) signalFfiError := C.signal_server_public_params_create_auth_credential_with_pni_presentation_deterministic( &c_result, c_serverPublicParams, c_randomness, c_groupSecretParams, - c_authCredWithPni, + BytesToBuffer(authCredWithPni[:]), ) if signalFfiError != nil { return nil, wrapError(signalFfiError) diff --git a/pkg/libsignalgo/libsignal b/pkg/libsignalgo/libsignal index ce37388..02e03ee 160000 --- a/pkg/libsignalgo/libsignal +++ b/pkg/libsignalgo/libsignal @@ -1 +1 @@ -Subproject commit ce3738855295cdafd04f377810ace289a6172d11 +Subproject commit 02e03ee05742079694d643fbc64fa737b275e9f8 diff --git a/pkg/libsignalgo/libsignal-ffi.h b/pkg/libsignalgo/libsignal-ffi.h index 3fdfdd7..b8bfab8 100644 --- a/pkg/libsignalgo/libsignal-ffi.h +++ b/pkg/libsignalgo/libsignal-ffi.h @@ -34,6 +34,8 @@ SPDX-License-Identifier: AGPL-3.0-only #define SignalPRESENTATION_VERSION_3 2 +#define SignalPRESENTATION_VERSION_4 3 + #define SignalAES_KEY_LEN 32 #define SignalAESGCM_NONCE_LEN 12 @@ -92,9 +94,9 @@ SPDX-License-Identifier: AGPL-3.0-only #define SignalRESERVED_LEN 1 -#define SignalSERVER_SECRET_PARAMS_LEN 2689 +#define SignalSERVER_SECRET_PARAMS_LEN 2721 -#define SignalSERVER_PUBLIC_PARAMS_LEN 641 +#define SignalSERVER_PUBLIC_PARAMS_LEN 673 #define SignalUUID_CIPHERTEXT_LEN 65 @@ -182,9 +184,13 @@ typedef enum { SignalErrorCodeIoError = 130, SignalErrorCodeInvalidMediaInput = 131, SignalErrorCodeUnsupportedMediaInput = 132, - SignalErrorCodeNetwork = 133, + SignalErrorCodeConnectionTimedOut = 133, SignalErrorCodeNetworkProtocol = 134, SignalErrorCodeRateLimited = 135, + SignalErrorCodeWebSocket = 136, + SignalErrorCodeCdsiInvalidToken = 137, + SignalErrorCodeConnectionFailed = 138, + SignalErrorCodeChatServiceInactive = 139, SignalErrorCodeSvrDataMissing = 150, SignalErrorCodeSvrRestoreFailed = 151, } SignalErrorCode; @@ -289,6 +295,23 @@ typedef struct SignalUnidentifiedSenderMessageContent SignalUnidentifiedSenderMe typedef struct SignalValidatingMac SignalValidatingMac; +/** + * A type alias to be used with [`OwnedBufferOf`], so that `OwnedBufferOf` and + * `OwnedBufferOf<*const c_char>` get distinct names. + */ +typedef const char *SignalCStringPtr; + +/** + * A representation of a array allocated on the Rust heap for use in C code. + */ +typedef struct { + SignalCStringPtr *base; + /** + * The number of elements in the buffer (not necessarily the number of bytes). + */ + size_t length; +} SignalOwnedBufferOfCStringPtr; + typedef struct { /** * Telephone number, as an unformatted e164. @@ -334,7 +357,7 @@ typedef struct { typedef struct { SignalOwnedBuffer bytes; SignalOwnedBufferOfusize lengths; -} SignalStringArray; +} SignalBytestringArray; typedef struct { const unsigned char *base; @@ -461,6 +484,71 @@ typedef struct { SignalStoreSenderKey store_sender_key; } SignalSenderKeyStore; +typedef struct { + const SignalBorrowedBuffer *base; + size_t length; +} SignalBorrowedSliceOfBuffers; + +/** + * A C callback used to report the results of Rust futures. + * + * cbindgen will produce independent C types like `SignalCPromisei32` and + * `SignalCPromiseProtocolAddress`. + */ +typedef void (*SignalCPromiseOwnedBufferOfc_uchar)(SignalFfiError *error, const SignalOwnedBuffer *result, const void *context); + +/** + * A C callback used to report the results of Rust futures. + * + * cbindgen will produce independent C types like `SignalCPromisei32` and + * `SignalCPromiseProtocolAddress`. + */ +typedef void (*SignalCPromisebool)(SignalFfiError *error, const bool *result, const void *context); + +typedef struct { + bool connection_reused; + uint32_t reconnect_count; + uint8_t raw_ip_type; + double duration_secs; + const char *connection_info; +} SignalFfiChatServiceDebugInfo; + +/** + * A C callback used to report the results of Rust futures. + * + * cbindgen will produce independent C types like `SignalCPromisei32` and + * `SignalCPromiseProtocolAddress`. + */ +typedef void (*SignalCPromiseFfiChatServiceDebugInfo)(SignalFfiError *error, const SignalFfiChatServiceDebugInfo *result, const void *context); + +typedef struct { + uint16_t status; + const char *message; + SignalOwnedBufferOfCStringPtr headers; + SignalOwnedBuffer body; +} SignalFfiChatResponse; + +/** + * A C callback used to report the results of Rust futures. + * + * cbindgen will produce independent C types like `SignalCPromisei32` and + * `SignalCPromiseProtocolAddress`. + */ +typedef void (*SignalCPromiseFfiChatResponse)(SignalFfiError *error, const SignalFfiChatResponse *result, const void *context); + +typedef struct { + SignalFfiChatResponse response; + SignalFfiChatServiceDebugInfo debug_info; +} SignalFfiResponseAndDebugInfo; + +/** + * A C callback used to report the results of Rust futures. + * + * cbindgen will produce independent C types like `SignalCPromisei32` and + * `SignalCPromiseProtocolAddress`. + */ +typedef void (*SignalCPromiseFfiResponseAndDebugInfo)(SignalFfiError *error, const SignalFfiResponseAndDebugInfo *result, const void *context); + /** * A C callback used to report the results of Rust futures. * @@ -482,13 +570,7 @@ typedef struct { */ typedef void (*SignalCPromiseFfiCdsiLookupResponse)(SignalFfiError *error, const SignalFfiCdsiLookupResponse *result, const void *context); -/** - * A C callback used to report the results of Rust futures. - * - * cbindgen will produce independent C types like `SignalCPromisei32` and - * `SignalCPromiseProtocolAddress`. - */ -typedef void (*SignalCPromiseOwnedBufferOfc_uchar)(SignalFfiError *error, const SignalOwnedBuffer *result, const void *context); +typedef SignalBytestringArray SignalStringArray; typedef int (*SignalRead)(void *ctx, uint8_t *buf, size_t buf_len, size_t *amount_read); @@ -526,14 +608,6 @@ typedef void (*SignalCPromiseTestingHandleType)(SignalFfiError *error, SignalTes */ typedef void (*SignalCPromiseOtherTestingHandleType)(SignalFfiError *error, SignalOtherTestingHandleType *const *result, const void *context); -/** - * A C callback used to report the results of Rust futures. - * - * cbindgen will produce independent C types like `SignalCPromisei32` and - * `SignalCPromiseProtocolAddress`. - */ -typedef void (*SignalCPromisebool)(SignalFfiError *error, const bool *result, const void *context); - /** * A C callback used to report the results of Rust futures. * @@ -550,9 +624,11 @@ void signal_free_string(const char *buf); void signal_free_buffer(const unsigned char *buf, size_t buf_len); +void signal_free_list_of_strings(SignalOwnedBufferOfCStringPtr buffer); + void signal_free_lookup_response_entry_list(SignalOwnedBufferOfFfiCdsiLookupResponseEntry buffer); -void signal_free_string_array(SignalStringArray array); +void signal_free_bytestring_array(SignalBytestringArray array); SignalFfiError *signal_error_get_message(const SignalFfiError *err, const char **out); @@ -1052,14 +1128,6 @@ SignalFfiError *signal_hsm_enclave_client_established_send(SignalOwnedBuffer *ou SignalFfiError *signal_hsm_enclave_client_established_recv(SignalOwnedBuffer *out, SignalHsmEnclaveClient *cli, SignalBorrowedBuffer received_ciphertext); -SignalFfiError *signal_auth_credential_check_valid_contents(SignalBorrowedBuffer buffer); - -SignalFfiError *signal_auth_credential_response_check_valid_contents(SignalBorrowedBuffer buffer); - -SignalFfiError *signal_auth_credential_with_pni_check_valid_contents(SignalBorrowedBuffer buffer); - -SignalFfiError *signal_auth_credential_with_pni_response_check_valid_contents(SignalBorrowedBuffer buffer); - SignalFfiError *signal_expiring_profile_key_credential_check_valid_contents(SignalBorrowedBuffer buffer); SignalFfiError *signal_expiring_profile_key_credential_response_check_valid_contents(SignalBorrowedBuffer buffer); @@ -1128,15 +1196,11 @@ SignalFfiError *signal_server_secret_params_get_public_params(unsigned char (*ou SignalFfiError *signal_server_secret_params_sign_deterministic(uint8_t (*out)[SignalSIGNATURE_LEN], const unsigned char (*params)[SignalSERVER_SECRET_PARAMS_LEN], const uint8_t (*randomness)[SignalRANDOMNESS_LEN], SignalBorrowedBuffer message); -SignalFfiError *signal_server_public_params_receive_auth_credential(unsigned char (*out)[SignalAUTH_CREDENTIAL_LEN], const unsigned char (*params)[SignalSERVER_PUBLIC_PARAMS_LEN], const SignalServiceIdFixedWidthBinaryBytes *aci, uint32_t redemption_time, const unsigned char (*response)[SignalAUTH_CREDENTIAL_RESPONSE_LEN]); +SignalFfiError *signal_server_public_params_receive_auth_credential_with_pni_as_service_id(SignalOwnedBuffer *out, const unsigned char (*params)[SignalSERVER_PUBLIC_PARAMS_LEN], const SignalServiceIdFixedWidthBinaryBytes *aci, const SignalServiceIdFixedWidthBinaryBytes *pni, uint64_t redemption_time, SignalBorrowedBuffer auth_credential_with_pni_response_bytes); -SignalFfiError *signal_server_public_params_receive_auth_credential_with_pni_as_service_id(unsigned char (*out)[SignalAUTH_CREDENTIAL_WITH_PNI_LEN], const unsigned char (*params)[SignalSERVER_PUBLIC_PARAMS_LEN], const SignalServiceIdFixedWidthBinaryBytes *aci, const SignalServiceIdFixedWidthBinaryBytes *pni, uint64_t redemption_time, const unsigned char (*response)[SignalAUTH_CREDENTIAL_WITH_PNI_RESPONSE_LEN]); +SignalFfiError *signal_server_public_params_receive_auth_credential_with_pni_as_aci(SignalOwnedBuffer *out, const unsigned char (*params)[SignalSERVER_PUBLIC_PARAMS_LEN], const SignalServiceIdFixedWidthBinaryBytes *aci, const SignalServiceIdFixedWidthBinaryBytes *pni, uint64_t redemption_time, SignalBorrowedBuffer auth_credential_with_pni_response_bytes); -SignalFfiError *signal_server_public_params_receive_auth_credential_with_pni_as_aci(unsigned char (*out)[SignalAUTH_CREDENTIAL_WITH_PNI_LEN], const unsigned char (*params)[SignalSERVER_PUBLIC_PARAMS_LEN], const SignalServiceIdFixedWidthBinaryBytes *aci, const SignalServiceIdFixedWidthBinaryBytes *pni, uint64_t redemption_time, const unsigned char (*response)[SignalAUTH_CREDENTIAL_WITH_PNI_RESPONSE_LEN]); - -SignalFfiError *signal_server_public_params_create_auth_credential_presentation_deterministic(SignalOwnedBuffer *out, const unsigned char (*server_public_params)[SignalSERVER_PUBLIC_PARAMS_LEN], const uint8_t (*randomness)[SignalRANDOMNESS_LEN], const unsigned char (*group_secret_params)[SignalGROUP_SECRET_PARAMS_LEN], const unsigned char (*auth_credential)[SignalAUTH_CREDENTIAL_LEN]); - -SignalFfiError *signal_server_public_params_create_auth_credential_with_pni_presentation_deterministic(SignalOwnedBuffer *out, const unsigned char (*server_public_params)[SignalSERVER_PUBLIC_PARAMS_LEN], const uint8_t (*randomness)[SignalRANDOMNESS_LEN], const unsigned char (*group_secret_params)[SignalGROUP_SECRET_PARAMS_LEN], const unsigned char (*auth_credential)[SignalAUTH_CREDENTIAL_WITH_PNI_LEN]); +SignalFfiError *signal_server_public_params_create_auth_credential_with_pni_presentation_deterministic(SignalOwnedBuffer *out, const unsigned char (*server_public_params)[SignalSERVER_PUBLIC_PARAMS_LEN], const uint8_t (*randomness)[SignalRANDOMNESS_LEN], const unsigned char (*group_secret_params)[SignalGROUP_SECRET_PARAMS_LEN], SignalBorrowedBuffer auth_credential_with_pni_bytes); SignalFfiError *signal_server_public_params_create_profile_key_credential_request_context_deterministic(unsigned char (*out)[SignalPROFILE_KEY_CREDENTIAL_REQUEST_CONTEXT_LEN], const unsigned char (*server_public_params)[SignalSERVER_PUBLIC_PARAMS_LEN], const uint8_t (*randomness)[SignalRANDOMNESS_LEN], const SignalServiceIdFixedWidthBinaryBytes *user_id, const unsigned char (*profile_key)[SignalPROFILE_KEY_LEN]); @@ -1150,11 +1214,15 @@ SignalFfiError *signal_server_public_params_receive_receipt_credential(unsigned SignalFfiError *signal_server_public_params_create_receipt_credential_presentation_deterministic(unsigned char (*out)[SignalRECEIPT_CREDENTIAL_PRESENTATION_LEN], const unsigned char (*server_public_params)[SignalSERVER_PUBLIC_PARAMS_LEN], const uint8_t (*randomness)[SignalRANDOMNESS_LEN], const unsigned char (*receipt_credential)[SignalRECEIPT_CREDENTIAL_LEN]); -SignalFfiError *signal_server_secret_params_issue_auth_credential_deterministic(unsigned char (*out)[SignalAUTH_CREDENTIAL_RESPONSE_LEN], const unsigned char (*server_secret_params)[SignalSERVER_SECRET_PARAMS_LEN], const uint8_t (*randomness)[SignalRANDOMNESS_LEN], const SignalServiceIdFixedWidthBinaryBytes *aci, uint32_t redemption_time); +SignalFfiError *signal_server_secret_params_issue_auth_credential_with_pni_as_service_id_deterministic(SignalOwnedBuffer *out, const unsigned char (*server_secret_params)[SignalSERVER_SECRET_PARAMS_LEN], const uint8_t (*randomness)[SignalRANDOMNESS_LEN], const SignalServiceIdFixedWidthBinaryBytes *aci, const SignalServiceIdFixedWidthBinaryBytes *pni, uint64_t redemption_time); -SignalFfiError *signal_server_secret_params_issue_auth_credential_with_pni_as_service_id_deterministic(unsigned char (*out)[SignalAUTH_CREDENTIAL_WITH_PNI_RESPONSE_LEN], const unsigned char (*server_secret_params)[SignalSERVER_SECRET_PARAMS_LEN], const uint8_t (*randomness)[SignalRANDOMNESS_LEN], const SignalServiceIdFixedWidthBinaryBytes *aci, const SignalServiceIdFixedWidthBinaryBytes *pni, uint64_t redemption_time); +SignalFfiError *signal_server_secret_params_issue_auth_credential_with_pni_as_aci_deterministic(SignalOwnedBuffer *out, const unsigned char (*server_secret_params)[SignalSERVER_SECRET_PARAMS_LEN], const uint8_t (*randomness)[SignalRANDOMNESS_LEN], const SignalServiceIdFixedWidthBinaryBytes *aci, const SignalServiceIdFixedWidthBinaryBytes *pni, uint64_t redemption_time); -SignalFfiError *signal_server_secret_params_issue_auth_credential_with_pni_as_aci_deterministic(unsigned char (*out)[SignalAUTH_CREDENTIAL_WITH_PNI_RESPONSE_LEN], const unsigned char (*server_secret_params)[SignalSERVER_SECRET_PARAMS_LEN], const uint8_t (*randomness)[SignalRANDOMNESS_LEN], const SignalServiceIdFixedWidthBinaryBytes *aci, const SignalServiceIdFixedWidthBinaryBytes *pni, uint64_t redemption_time); +SignalFfiError *signal_server_secret_params_issue_auth_credential_with_pni_zkc_deterministic(SignalOwnedBuffer *out, const unsigned char (*server_secret_params)[SignalSERVER_SECRET_PARAMS_LEN], const uint8_t (*randomness)[SignalRANDOMNESS_LEN], const SignalServiceIdFixedWidthBinaryBytes *aci, const SignalServiceIdFixedWidthBinaryBytes *pni, uint64_t redemption_time); + +SignalFfiError *signal_auth_credential_with_pni_check_valid_contents(SignalBorrowedBuffer bytes); + +SignalFfiError *signal_auth_credential_with_pni_response_check_valid_contents(SignalBorrowedBuffer bytes); SignalFfiError *signal_server_secret_params_verify_auth_credential_presentation(const unsigned char (*server_secret_params)[SignalSERVER_SECRET_PARAMS_LEN], const unsigned char (*group_public_params)[SignalGROUP_PUBLIC_PARAMS_LEN], SignalBorrowedBuffer presentation_bytes, uint64_t current_time_in_seconds); @@ -1280,23 +1348,37 @@ SignalFfiError *signal_backup_auth_credential_presentation_check_valid_contents( SignalFfiError *signal_backup_auth_credential_presentation_verify(SignalBorrowedBuffer presentation_bytes, uint64_t now, SignalBorrowedBuffer server_params_bytes); -SignalFfiError *signal_group_send_credential_response_default_expiration_based_on_current_time(uint64_t *out); +SignalFfiError *signal_group_send_derived_key_pair_check_valid_contents(SignalBorrowedBuffer bytes); -SignalFfiError *signal_group_send_credential_response_issue_deterministic(SignalOwnedBuffer *out, SignalBorrowedBuffer concatenated_group_member_ciphertexts, const unsigned char (*requester)[SignalUUID_CIPHERTEXT_LEN], uint64_t expiration, const unsigned char (*server_params)[SignalSERVER_SECRET_PARAMS_LEN], const uint8_t (*randomness)[SignalRANDOMNESS_LEN]); +SignalFfiError *signal_group_send_derived_key_pair_for_expiration(SignalOwnedBuffer *out, uint64_t expiration, const unsigned char (*server_params)[SignalSERVER_SECRET_PARAMS_LEN]); -SignalFfiError *signal_group_send_credential_response_check_valid_contents(SignalBorrowedBuffer response_bytes); +SignalFfiError *signal_group_send_endorsements_response_check_valid_contents(SignalBorrowedBuffer bytes); -SignalFfiError *signal_group_send_credential_response_receive(SignalOwnedBuffer *out, SignalBorrowedBuffer response_bytes, SignalBorrowedBuffer group_members, const SignalServiceIdFixedWidthBinaryBytes *local_aci, uint64_t now, const unsigned char (*server_params)[SignalSERVER_PUBLIC_PARAMS_LEN], const unsigned char (*group_params)[SignalGROUP_SECRET_PARAMS_LEN]); +SignalFfiError *signal_group_send_endorsements_response_issue_deterministic(SignalOwnedBuffer *out, SignalBorrowedBuffer concatenated_group_member_ciphertexts, SignalBorrowedBuffer key_pair, const uint8_t (*randomness)[SignalRANDOMNESS_LEN]); -SignalFfiError *signal_group_send_credential_response_receive_with_ciphertexts(SignalOwnedBuffer *out, SignalBorrowedBuffer response_bytes, SignalBorrowedBuffer concatenated_group_member_ciphertexts, const unsigned char (*requester)[SignalUUID_CIPHERTEXT_LEN], uint64_t now, const unsigned char (*server_params)[SignalSERVER_PUBLIC_PARAMS_LEN], const unsigned char (*group_params)[SignalGROUP_SECRET_PARAMS_LEN]); +SignalFfiError *signal_group_send_endorsements_response_get_expiration(uint64_t *out, SignalBorrowedBuffer response_bytes); -SignalFfiError *signal_group_send_credential_check_valid_contents(SignalBorrowedBuffer params_bytes); +SignalFfiError *signal_group_send_endorsements_response_receive_and_combine_with_service_ids(SignalBytestringArray *out, SignalBorrowedBuffer response_bytes, SignalBorrowedBuffer group_members, const SignalServiceIdFixedWidthBinaryBytes *local_user, uint64_t now, const unsigned char (*group_params)[SignalGROUP_SECRET_PARAMS_LEN], const unsigned char (*server_params)[SignalSERVER_PUBLIC_PARAMS_LEN]); -SignalFfiError *signal_group_send_credential_present_deterministic(SignalOwnedBuffer *out, SignalBorrowedBuffer credential_bytes, const unsigned char (*server_params)[SignalSERVER_PUBLIC_PARAMS_LEN], const uint8_t (*randomness)[SignalRANDOMNESS_LEN]); +SignalFfiError *signal_group_send_endorsements_response_receive_and_combine_with_ciphertexts(SignalBytestringArray *out, SignalBorrowedBuffer response_bytes, SignalBorrowedBuffer concatenated_group_member_ciphertexts, SignalBorrowedBuffer local_user_ciphertext, uint64_t now, const unsigned char (*server_params)[SignalSERVER_PUBLIC_PARAMS_LEN]); -SignalFfiError *signal_group_send_credential_presentation_check_valid_contents(SignalBorrowedBuffer presentation_bytes); +SignalFfiError *signal_group_send_endorsement_check_valid_contents(SignalBorrowedBuffer bytes); -SignalFfiError *signal_group_send_credential_presentation_verify(SignalBorrowedBuffer presentation_bytes, SignalBorrowedBuffer group_members, uint64_t now, const unsigned char (*server_params)[SignalSERVER_SECRET_PARAMS_LEN]); +SignalFfiError *signal_group_send_endorsement_combine(SignalOwnedBuffer *out, SignalBorrowedSliceOfBuffers endorsements); + +SignalFfiError *signal_group_send_endorsement_remove(SignalOwnedBuffer *out, SignalBorrowedBuffer endorsement, SignalBorrowedBuffer to_remove); + +SignalFfiError *signal_group_send_endorsement_to_token(SignalOwnedBuffer *out, SignalBorrowedBuffer endorsement, const unsigned char (*group_params)[SignalGROUP_SECRET_PARAMS_LEN]); + +SignalFfiError *signal_group_send_token_check_valid_contents(SignalBorrowedBuffer bytes); + +SignalFfiError *signal_group_send_token_to_full_token(SignalOwnedBuffer *out, SignalBorrowedBuffer token, uint64_t expiration); + +SignalFfiError *signal_group_send_full_token_check_valid_contents(SignalBorrowedBuffer bytes); + +SignalFfiError *signal_group_send_full_token_get_expiration(uint64_t *out, SignalBorrowedBuffer token); + +SignalFfiError *signal_group_send_full_token_verify(SignalBorrowedBuffer token, SignalBorrowedBuffer user_ids, uint64_t now, SignalBorrowedBuffer key_pair); SignalFfiError *signal_verify_signature(bool *out, SignalBorrowedBuffer cert_pem, SignalBorrowedBuffer body, SignalBorrowedBuffer signature, uint64_t current_timestamp); @@ -1306,8 +1388,42 @@ SignalFfiError *signal_tokio_async_context_destroy(SignalTokioAsyncContext *p); SignalFfiError *signal_connection_manager_new(SignalConnectionManager **out, uint8_t environment); +SignalFfiError *signal_connection_manager_set_proxy(const SignalConnectionManager *connection_manager, const char *host, uint16_t port); + +SignalFfiError *signal_connection_manager_clear_proxy(const SignalConnectionManager *connection_manager); + SignalFfiError *signal_connection_manager_destroy(SignalConnectionManager *p); +SignalFfiError *signal_create_otp(const char **out, const char *username, SignalBorrowedBuffer secret); + +SignalFfiError *signal_create_otp_from_base64(const char **out, const char *username, const char *secret); + +SignalFfiError *signal_svr3_backup(SignalCPromiseOwnedBufferOfc_uchar promise, const void *promise_context, const SignalTokioAsyncContext *async_runtime, const SignalConnectionManager *connection_manager, SignalBorrowedBuffer secret, const char *password, uint32_t max_tries, const char *username, const char *enclave_password); + +SignalFfiError *signal_svr3_restore(SignalCPromiseOwnedBufferOfc_uchar promise, const void *promise_context, const SignalTokioAsyncContext *async_runtime, const SignalConnectionManager *connection_manager, const char *password, SignalBorrowedBuffer share_set, const char *username, const char *enclave_password); + +SignalFfiError *signal_chat_destroy(SignalChat *p); + +SignalFfiError *signal_http_request_destroy(SignalHttpRequest *p); + +SignalFfiError *signal_http_request_new_with_body(SignalHttpRequest **out, const char *method, const char *path, SignalBorrowedBuffer body_as_slice); + +SignalFfiError *signal_http_request_new_without_body(SignalHttpRequest **out, const char *method, const char *path); + +SignalFfiError *signal_http_request_add_header(const SignalHttpRequest *request, const char *name, const char *value); + +SignalFfiError *signal_chat_service_new(SignalChat **out, const SignalConnectionManager *connection_manager, const char *username, const char *password); + +SignalFfiError *signal_chat_service_disconnect(SignalCPromisebool promise, const void *promise_context, const SignalTokioAsyncContext *async_runtime, const SignalChat *chat); + +SignalFfiError *signal_chat_service_connect_unauth(SignalCPromiseFfiChatServiceDebugInfo promise, const void *promise_context, const SignalTokioAsyncContext *async_runtime, const SignalChat *chat); + +SignalFfiError *signal_chat_service_connect_auth(SignalCPromiseFfiChatServiceDebugInfo promise, const void *promise_context, const SignalTokioAsyncContext *async_runtime, const SignalChat *chat); + +SignalFfiError *signal_chat_service_unauth_send(SignalCPromiseFfiChatResponse promise, const void *promise_context, const SignalTokioAsyncContext *async_runtime, const SignalChat *chat, const SignalHttpRequest *http_request, uint32_t timeout_millis); + +SignalFfiError *signal_chat_service_unauth_send_and_debug(SignalCPromiseFfiResponseAndDebugInfo promise, const void *promise_context, const SignalTokioAsyncContext *async_runtime, const SignalChat *chat, const SignalHttpRequest *http_request, uint32_t timeout_millis); + SignalFfiError *signal_lookup_request_new(SignalLookupRequest **out); SignalFfiError *signal_lookup_request_add_e164(const SignalLookupRequest *request, const char *e164); @@ -1324,24 +1440,12 @@ SignalFfiError *signal_lookup_request_destroy(SignalLookupRequest *p); SignalFfiError *signal_cdsi_lookup_destroy(SignalCdsiLookup *p); -SignalFfiError *signal_cdsi_lookup_new(SignalCPromiseCdsiLookup promise, const void *promise_context, const SignalTokioAsyncContext *async_runtime, const SignalConnectionManager *connection_manager, const char *username, const char *password, const SignalLookupRequest *request, uint32_t timeout_millis); +SignalFfiError *signal_cdsi_lookup_new(SignalCPromiseCdsiLookup promise, const void *promise_context, const SignalTokioAsyncContext *async_runtime, const SignalConnectionManager *connection_manager, const char *username, const char *password, const SignalLookupRequest *request); SignalFfiError *signal_cdsi_lookup_token(SignalOwnedBuffer *out, const SignalCdsiLookup *lookup); SignalFfiError *signal_cdsi_lookup_complete(SignalCPromiseFfiCdsiLookupResponse promise, const void *promise_context, const SignalTokioAsyncContext *async_runtime, const SignalCdsiLookup *lookup); -SignalFfiError *signal_create_otp(const char **out, const char *username, SignalBorrowedBuffer secret); - -SignalFfiError *signal_create_otp_from_base64(const char **out, const char *username, const char *secret); - -SignalFfiError *signal_svr3_backup(SignalCPromiseOwnedBufferOfc_uchar promise, const void *promise_context, const SignalTokioAsyncContext *async_runtime, const SignalConnectionManager *connection_manager, SignalBorrowedBuffer secret, const char *password, uint32_t max_tries, const char *username, const char *enclave_password, uint32_t op_timeout_ms); - -SignalFfiError *signal_svr3_restore(SignalCPromiseOwnedBufferOfc_uchar promise, const void *promise_context, const SignalTokioAsyncContext *async_runtime, const SignalConnectionManager *connection_manager, const char *password, SignalBorrowedBuffer share_set, const char *username, const char *enclave_password, uint32_t op_timeout_ms); - -SignalFfiError *signal_chat_destroy(SignalChat *p); - -SignalFfiError *signal_http_request_destroy(SignalHttpRequest *p); - SignalFfiError *signal_pin_hash_destroy(SignalPinHash *p); SignalFfiError *signal_pin_hash_clone(SignalPinHash **new_obj, const SignalPinHash *obj); @@ -1413,7 +1517,7 @@ SignalFfiError *signal_mp4_sanitizer_sanitize(SignalSanitizedMetadata **out, con #endif #if defined(SIGNAL_MEDIA_SUPPORTED) -SignalFfiError *signal_webp_sanitizer_sanitize(bool *out, const SignalSyncInputStream *input); +SignalFfiError *signal_webp_sanitizer_sanitize(const SignalSyncInputStream *input); #endif #if defined(SIGNAL_MEDIA_SUPPORTED) @@ -1496,8 +1600,28 @@ SignalFfiError *signal_testing_error_on_return_io(SignalCPromiseRawPointer promi SignalFfiError *signal_testing_return_string_array(SignalStringArray *out); +SignalFfiError *signal_testing_process_bytestring_array(SignalBytestringArray *out, SignalBorrowedSliceOfBuffers input); + SignalFfiError *signal_testing_cdsi_lookup_response_convert(SignalCPromiseFfiCdsiLookupResponse promise, const void *promise_context, const SignalTokioAsyncContext *async_runtime); -SignalFfiError *signal_testing_cdsi_lookup_error_convert(bool *out); +SignalFfiError *signal_testing_cdsi_lookup_error_convert(const char *error_description); + +SignalFfiError *signal_testing_chat_service_error_convert(void); + +SignalFfiError *signal_testing_chat_service_inactive_error_convert(void); + +SignalFfiError *signal_testing_chat_service_response_convert(SignalFfiChatResponse *out, bool body_present); + +SignalFfiError *signal_testing_chat_service_debug_info_convert(SignalFfiChatServiceDebugInfo *out); + +SignalFfiError *signal_testing_chat_service_response_and_debug_info_convert(SignalFfiResponseAndDebugInfo *out); + +SignalFfiError *signal_testing_chat_request_get_method(const char **out, const SignalHttpRequest *request); + +SignalFfiError *signal_testing_chat_request_get_path(const char **out, const SignalHttpRequest *request); + +SignalFfiError *signal_testing_chat_request_get_header_value(const char **out, const SignalHttpRequest *request, const char *header_name); + +SignalFfiError *signal_testing_chat_request_get_body(SignalOwnedBuffer *out, const SignalHttpRequest *request); #endif /* SIGNAL_FFI_H_ */ diff --git a/pkg/libsignalgo/version.go b/pkg/libsignalgo/version.go index b977e45..ac15575 100644 --- a/pkg/libsignalgo/version.go +++ b/pkg/libsignalgo/version.go @@ -2,4 +2,4 @@ package libsignalgo -const Version = "v0.41.0" +const Version = "v0.44.0" diff --git a/pkg/signalmeow/prod-server-public-params.dat b/pkg/signalmeow/prod-server-public-params.dat index bffaafb69f63ec1990647e3554867add48655a69..9391895914908b47e6bdfeb9aa108754b3acd5a3 100644 GIT binary patch delta 40 ycmV+@0N4M41)&A7fdU}Zl|OF)xFP-hgFRD@nH>>Zrr<{RI}IUr(O>AA510p7oDnYo delta 7 OcmZ3;+Q_=0kqH0_IRan+ From d946571c5af1221d8e4cb0b1d0093d35fa715a5c Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Wed, 10 Apr 2024 19:37:50 +0300 Subject: [PATCH 011/580] Remove invalid cleanup calls --- portal.go | 2 -- 1 file changed, 2 deletions(-) diff --git a/portal.go b/portal.go index 5a4ae72..44f67bb 100644 --- a/portal.go +++ b/portal.go @@ -1184,7 +1184,6 @@ func (portal *Portal) applySignalGroupChange(ctx context.Context, source *User, log.Err(err).Msg("Failed to save portal in database after processing group change") } portal.UpdateBridgeInfo(ctx) - portal.CleanupIfEmpty(ctx) } func (portal *Portal) sendMembershipForPuppetAndUser(ctx context.Context, sender *Puppet, target uuid.UUID, membership event.Membership, action string) (puppet *Puppet, err error) { @@ -2453,7 +2452,6 @@ func (portal *Portal) SyncParticipants(ctx context.Context, source *User, info * } } } - portal.CleanupIfEmpty(ctx) return userIDs } From e369a56c314a62bbdd08cf0bf671ef09397285ac Mon Sep 17 00:00:00 2001 From: Scott Weber Date: Thu, 11 Apr 2024 14:31:27 -0400 Subject: [PATCH 012/580] Minor incoming messages refactor and send m.notice on decryption errors (#496) We were falling through without propagating errors anywhere. I caught most decryption errors and send them along in the new Err field in DecryptionResult, to be then passed along to the bridge as a new type of chat event. I'm going to do another pass to catch any last decryption errors, but this should be a big improvement over what we currently do. --- pkg/signalmeow/events/message.go | 18 +- pkg/signalmeow/receiving.go | 835 +++++++++++++++++-------------- user.go | 13 + 3 files changed, 481 insertions(+), 385 deletions(-) diff --git a/pkg/signalmeow/events/message.go b/pkg/signalmeow/events/message.go index e8ba1cb..0db0f24 100644 --- a/pkg/signalmeow/events/message.go +++ b/pkg/signalmeow/events/message.go @@ -28,12 +28,13 @@ type SignalEvent interface { isSignalEvent() } -func (*ChatEvent) isSignalEvent() {} -func (*Receipt) isSignalEvent() {} -func (*ReadSelf) isSignalEvent() {} -func (*Call) isSignalEvent() {} -func (*ContactList) isSignalEvent() {} -func (*ACIFound) isSignalEvent() {} +func (*ChatEvent) isSignalEvent() {} +func (*DecryptionError) isSignalEvent() {} +func (*Receipt) isSignalEvent() {} +func (*ReadSelf) isSignalEvent() {} +func (*Call) isSignalEvent() {} +func (*ContactList) isSignalEvent() {} +func (*ACIFound) isSignalEvent() {} type MessageInfo struct { Sender uuid.UUID @@ -47,6 +48,11 @@ type ChatEvent struct { Event signalpb.ChatEventContent } +type DecryptionError struct { + Sender uuid.UUID + Err error +} + type Receipt struct { Sender uuid.UUID Content *signalpb.ReceiptMessage diff --git a/pkg/signalmeow/receiving.go b/pkg/signalmeow/receiving.go index 55a44e8..ba29914 100644 --- a/pkg/signalmeow/receiving.go +++ b/pkg/signalmeow/receiving.go @@ -263,10 +263,8 @@ func (cli *Client) incomingRequestHandler(ctx context.Context, req *signalpb.Web }, nil } -// TODO: we should split this up into multiple functions func (cli *Client) incomingAPIMessageHandler(ctx context.Context, req *signalpb.WebSocketRequestMessage) (*web.SimpleResponse, error) { log := *zerolog.Ctx(ctx) - responseCode := 200 envelope := &signalpb.Envelope{} err := proto.Unmarshal(req.Body, envelope) if err != nil { @@ -274,11 +272,6 @@ func (cli *Client) incomingAPIMessageHandler(ctx context.Context, req *signalpb. return nil, err } destinationServiceID, err := libsignalgo.ServiceIDFromString(envelope.GetDestinationServiceId()) - if err != nil { - log.Err(err).Str("destination_service_id", envelope.GetDestinationServiceId()).Msg("Failed to parse destination service ID") - return nil, err - } - var result *DecryptionResult log.Trace(). Uint64("timestamp", envelope.GetTimestamp()). Str("destination_service_id", envelope.GetDestinationServiceId()). @@ -289,184 +282,38 @@ func (cli *Client) incomingAPIMessageHandler(ctx context.Context, req *signalpb. Str("envelope_type", signalpb.Envelope_Type_name[int32(envelope.GetType())]). Msg("Received envelope") + result := cli.decryptEnvelope(ctx, envelope) + + err = cli.handleDecryptedResult(ctx, result, destinationServiceID) + if err != nil { + log.Err(err).Msg("handleDecryptedResult error") + return nil, err + } + + return &web.SimpleResponse{ + Status: 200, + }, nil +} + +func (cli *Client) decryptEnvelope( + ctx context.Context, + envelope *signalpb.Envelope, +) DecryptionResult { + log := zerolog.Ctx(ctx) + + destinationServiceID, err := libsignalgo.ServiceIDFromString(envelope.GetDestinationServiceId()) + if err != nil { + log.Err(err).Str("destination_service_id", envelope.GetDestinationServiceId()).Msg("Failed to parse destination service ID") + return DecryptionResult{Err: err, Urgent: envelope.GetUrgent()} + } + var result *DecryptionResult + switch *envelope.Type { case signalpb.Envelope_UNIDENTIFIED_SENDER: - if destinationServiceID != cli.Store.ACIServiceID() { - log.Warn().Stringer("destination_service_id", destinationServiceID). - Msg("Received UNIDENTIFIED_SENDER envelope for non-ACI destination") - break - } - usmc, err := libsignalgo.SealedSenderDecryptToUSMC( - ctx, - envelope.GetContent(), - cli.Store.ACIIdentityStore, - ) - if err != nil || usmc == nil { - if err == nil { - err = fmt.Errorf("usmc is nil") - } - log.Err(err).Msg("SealedSenderDecryptToUSMC error") - return nil, err - } - - messageType, err := usmc.GetMessageType() + result, err = cli.decryptUnidentifiedSenderEnvelope(ctx, destinationServiceID, envelope) if err != nil { - log.Err(err).Msg("GetMessageType error") - } - senderCertificate, err := usmc.GetSenderCertificate() - if err != nil { - log.Err(err).Msg("GetSenderCertificate error") - } - senderUUID, err := senderCertificate.GetSenderUUID() - if err != nil { - log.Err(err).Msg("GetSenderUUID error") - } - senderDeviceID, err := senderCertificate.GetDeviceID() - if err != nil { - log.Err(err).Msg("GetDeviceID error") - } - senderAddress, err := libsignalgo.NewACIServiceID(senderUUID).Address(uint(senderDeviceID)) - if err != nil { - log.Err(err).Msg("NewAddress error") - } - senderE164, err := senderCertificate.GetSenderE164() - if err != nil { - log.Err(err).Msg("GetSenderE164 error") - } - usmcContents, err := usmc.GetContents() - if err != nil { - log.Err(err).Msg("GetContents error") - } - log = log.With(). - Stringer("sender_uuid", senderUUID). - Uint32("sender_device_id", senderDeviceID). - Str("sender_e164", senderE164). - Logger() - ctx = log.WithContext(ctx) - log.Trace().Msg("Received SealedSender message") - - cli.Store.RecipientStore.UpdateRecipientE164(ctx, senderUUID, uuid.Nil, senderE164) - - switch messageType { - case libsignalgo.CiphertextMessageTypeSenderKey: - log.Trace().Msg("SealedSender messageType is CiphertextMessageTypeSenderKey") - decryptedText, err := libsignalgo.GroupDecrypt( - ctx, - usmcContents, - senderAddress, - cli.Store.SenderKeyStore, - ) - if err != nil { - if strings.Contains(err.Error(), "message with old counter") { - log.Warn().Msg("Duplicate message, ignoring") - } else { - log.Err(err).Msg("GroupDecrypt error") - } - } else { - err = stripPadding(&decryptedText) - if err != nil { - return nil, fmt.Errorf("stripPadding error: %v", err) - } - content := signalpb.Content{} - err = proto.Unmarshal(decryptedText, &content) - if err != nil { - log.Err(err).Msg("Unmarshal error") - } - result = &DecryptionResult{ - SenderAddress: senderAddress, - Content: &content, - SealedSender: true, - } - } - - case libsignalgo.CiphertextMessageTypePreKey: - log.Trace().Msg("SealedSender messageType is CiphertextMessageTypePreKey") - result, err = cli.prekeyDecrypt(ctx, destinationServiceID, senderAddress, usmcContents) - if err != nil { - log.Err(err).Msg("Sealed sender prekey ciphertext decryption error") - } - - case libsignalgo.CiphertextMessageTypeWhisper: - log.Trace().Msg("SealedSender messageType is CiphertextMessageTypeWhisper") - message, err := libsignalgo.DeserializeMessage(usmcContents) - if err != nil { - log.Err(err).Msg("Sealed sender whisper deserialize error") - } - decryptedText, err := libsignalgo.Decrypt( - ctx, - message, - senderAddress, - cli.Store.ACISessionStore, - cli.Store.ACIIdentityStore, - ) - if err != nil { - log.Err(err).Msg("Sealed sender whisper decryption error") - } else { - err = stripPadding(&decryptedText) - if err != nil { - return nil, fmt.Errorf("stripPadding error: %v", err) - } - content := signalpb.Content{} - err = proto.Unmarshal(decryptedText, &content) - if err != nil { - log.Err(err).Msg("Unmarshal error") - } - result = &DecryptionResult{ - SenderAddress: senderAddress, - Content: &content, - SealedSender: true, - } - } - - case libsignalgo.CiphertextMessageTypePlaintext: - log.Debug().Msg("SealedSender messageType is CiphertextMessageTypePlaintext") - // TODO: handle plaintext (usually DecryptionErrorMessage) and retries - // when implementing SenderKey groups - - //plaintextContent, err := libsignalgo.DeserializePlaintextContent(usmcContents) - //if err != nil { - // log.Err(err).Msg("DeserializePlaintextContent error") - //} - //body, err := plaintextContent.GetBody() - //if err != nil { - // log.Err(err).Msg("PlaintextContent GetBody error") - //} - //content := signalpb.Content{} - //err = proto.Unmarshal(body, &content) - //if err != nil { - // log.Err(err).Msg("PlaintextContent Unmarshal error") - //} - //result = &DecryptionResult{ - // SenderAddress: *senderAddress, - // Content: &content, - // SealedSender: true, - //} - - return &web.SimpleResponse{ - Status: responseCode, - }, nil - - default: - log.Warn().Msg("SealedSender messageType is unknown") - } - - // If we couldn't decrypt with specific decryption methods, try sealedSenderDecrypt - if result == nil || responseCode != 200 { - log.Debug().Msg("Didn't decrypt with specific methods, trying sealedSenderDecrypt") - var err error - result, err = cli.sealedSenderDecrypt(ctx, envelope) - if err != nil { - if strings.Contains(err.Error(), "self send of a sealed sender message") { - log.Debug().Msg("Message sent by us, ignoring") - } else { - log.Err(err).Msg("sealedSenderDecrypt error") - } - } else { - log.Trace(). - Any("sender_address", result.SenderAddress). - Any("content", result.Content). - Msg("SealedSender decrypt result") - } + log.Err(err).Msg("decryptUnidentifiedSenderEnvelope error") + return DecryptionResult{Err: err, Urgent: envelope.GetUrgent()} } case signalpb.Envelope_PREKEY_BUNDLE: @@ -475,7 +322,7 @@ func (cli *Client) incomingAPIMessageHandler(ctx context.Context, req *signalpb. uint(*envelope.SourceDevice), ) if err != nil { - return nil, fmt.Errorf("NewAddress error: %v", err) + return DecryptionResult{Err: fmt.Errorf("NewAddress error: %v", err), Urgent: envelope.GetUrgent()} } result, err = cli.prekeyDecrypt(ctx, destinationServiceID, sender, envelope.Content) if err != nil { @@ -499,15 +346,21 @@ func (cli *Client) incomingAPIMessageHandler(ctx context.Context, req *signalpb. uint(*envelope.SourceDevice), ) if err != nil { - return nil, fmt.Errorf("NewAddress error: %w", err) + return DecryptionResult{Err: fmt.Errorf("NewAddress error: %v", err), Urgent: envelope.GetUrgent()} } sessionStore := cli.Store.SessionStore(destinationServiceID) if sessionStore == nil { - return nil, fmt.Errorf("no session store for destination service ID %s", destinationServiceID) + return DecryptionResult{ + Err: fmt.Errorf("no session store for destination service ID %s", destinationServiceID), + Urgent: envelope.GetUrgent(), + } } identityStore := cli.Store.IdentityStore(destinationServiceID) if identityStore == nil { - return nil, fmt.Errorf("no identity store for destination service ID %s", destinationServiceID) + return DecryptionResult{ + Err: fmt.Errorf("no identity store for destination service ID %s", destinationServiceID), + Urgent: envelope.GetUrgent(), + } } decryptedText, err := libsignalgo.Decrypt( ctx, @@ -525,7 +378,7 @@ func (cli *Client) incomingAPIMessageHandler(ctx context.Context, req *signalpb. } else { err = stripPadding(&decryptedText) if err != nil { - return nil, fmt.Errorf("stripPadding error: %v", err) + return DecryptionResult{Err: fmt.Errorf("stripPadding error: %v", err), Urgent: envelope.GetUrgent()} } content := signalpb.Content{} err = proto.Unmarshal(decryptedText, &content) @@ -539,226 +392,448 @@ func (cli *Client) incomingAPIMessageHandler(ctx context.Context, req *signalpb. } case signalpb.Envelope_RECEIPT: + log.Warn().Msg("Received RECEIPT envelope, not yet implemented") // TODO: handle receipt case signalpb.Envelope_KEY_EXCHANGE: - responseCode = 400 + log.Warn().Msg("Received KEY_EXCHANGE envelope, not supported") case signalpb.Envelope_UNKNOWN: - responseCode = 400 + log.Warn().Msg("Received UNKNOWN envelope, not supported") default: log.Warn().Msg("Received actual unknown envelope type") - responseCode = 400 + } + if result == nil { + log.Warn().Msg("Decryption result is nil") + return DecryptionResult{ + Err: fmt.Errorf("decryption result is nil"), + Urgent: envelope.GetUrgent(), + } + } + result.Urgent = envelope.GetUrgent() + return *result +} + +func (cli *Client) decryptUnidentifiedSenderEnvelope(ctx context.Context, destinationServiceID libsignalgo.ServiceID, envelope *signalpb.Envelope) (*DecryptionResult, error) { + log := zerolog.Ctx(ctx) + var result *DecryptionResult + + if destinationServiceID != cli.Store.ACIServiceID() { + log.Warn().Stringer("destination_service_id", destinationServiceID). + Msg("Received UNIDENTIFIED_SENDER envelope for non-ACI destination") + // Return nil, nil to skip the rest of the handling and return 200 OK to the server + return nil, nil + } + usmc, err := libsignalgo.SealedSenderDecryptToUSMC( + ctx, + envelope.GetContent(), + cli.Store.ACIIdentityStore, + ) + if err != nil || usmc == nil { + if err == nil { + err = fmt.Errorf("usmc is nil") + } + log.Err(err).Msg("SealedSenderDecryptToUSMC error") + return nil, err } - // Handle content that is now decrypted - if result != nil && result.Content != nil { - content := result.Content - log.Trace().Any("raw_data", content).Msg("Raw event data") + messageType, err := usmc.GetMessageType() + if err != nil { + log.Err(err).Msg("GetMessageType error") + } + senderCertificate, err := usmc.GetSenderCertificate() + if err != nil { + log.Err(err).Msg("GetSenderCertificate error") + } + senderUUID, err := senderCertificate.GetSenderUUID() + if err != nil { + log.Err(err).Msg("GetSenderUUID error") + } + senderDeviceID, err := senderCertificate.GetDeviceID() + if err != nil { + log.Err(err).Msg("GetDeviceID error") + } + senderAddress, err := libsignalgo.NewACIServiceID(senderUUID).Address(uint(senderDeviceID)) + if err != nil { + log.Err(err).Msg("NewAddress error") + } + senderE164, err := senderCertificate.GetSenderE164() + if err != nil { + log.Err(err).Msg("GetSenderE164 error") + } + usmcContents, err := usmc.GetContents() + if err != nil { + log.Err(err).Msg("GetContents error") + } + newLog := log.With(). + Stringer("sender_uuid", senderUUID). + Uint32("sender_device_id", senderDeviceID). + Str("sender_e164", senderE164). + Logger() + log = &newLog + ctx = log.WithContext(ctx) + log.Trace().Msg("Received SealedSender message") - name, _ := result.SenderAddress.Name() - deviceId, _ := result.SenderAddress.DeviceID() - log = log.With(). - Str("sender_name", name). - Uint("sender_device_id", deviceId). - Str("destination_service_id", destinationServiceID.String()). - Logger() - ctx = log.WithContext(ctx) - log.Debug().Msg("Decrypted message") - printContentFieldString(ctx, content, "Decrypted content fields") + cli.Store.RecipientStore.UpdateRecipientE164(ctx, senderUUID, uuid.Nil, senderE164) - // If there's a sender key distribution message, process it - if content.GetSenderKeyDistributionMessage() != nil { - log.Debug().Msg("content includes sender key distribution message") - skdm, err := libsignalgo.DeserializeSenderKeyDistributionMessage(content.GetSenderKeyDistributionMessage()) - if err != nil { - log.Err(err).Msg("DeserializeSenderKeyDistributionMessage error") - return nil, err + switch messageType { + case libsignalgo.CiphertextMessageTypeSenderKey: + log.Trace().Msg("SealedSender messageType is CiphertextMessageTypeSenderKey") + decryptedText, err := libsignalgo.GroupDecrypt( + ctx, + usmcContents, + senderAddress, + cli.Store.SenderKeyStore, + ) + if err != nil { + if strings.Contains(err.Error(), "message with old counter") { + log.Warn().Msg("Duplicate message, ignoring") + } else { + log.Err(err).Msg("GroupDecrypt error") } - err = libsignalgo.ProcessSenderKeyDistributionMessage( - ctx, - skdm, - result.SenderAddress, - cli.Store.SenderKeyStore, - ) + } else { + err = stripPadding(&decryptedText) if err != nil { - log.Err(err).Msg("ProcessSenderKeyDistributionMessage error") - return nil, err + return nil, fmt.Errorf("stripPadding error: %v", err) + } + content := signalpb.Content{} + err = proto.Unmarshal(decryptedText, &content) + if err != nil { + log.Err(err).Msg("Unmarshal error") + } + result = &DecryptionResult{ + SenderAddress: senderAddress, + Content: &content, + SealedSender: true, } } + case libsignalgo.CiphertextMessageTypePreKey: + log.Trace().Msg("SealedSender messageType is CiphertextMessageTypePreKey") + result, err = cli.prekeyDecrypt(ctx, destinationServiceID, senderAddress, usmcContents) + if err != nil { + log.Err(err).Msg("Sealed sender prekey ciphertext decryption error") + } + + case libsignalgo.CiphertextMessageTypeWhisper: + log.Trace().Msg("SealedSender messageType is CiphertextMessageTypeWhisper") + message, err := libsignalgo.DeserializeMessage(usmcContents) + if err != nil { + log.Err(err).Msg("Sealed sender whisper deserialize error") + } + decryptedText, err := libsignalgo.Decrypt( + ctx, + message, + senderAddress, + cli.Store.ACISessionStore, + cli.Store.ACIIdentityStore, + ) + if err != nil { + log.Err(err).Msg("Sealed sender whisper decryption error") + } else { + err = stripPadding(&decryptedText) + if err != nil { + return nil, fmt.Errorf("stripPadding error: %v", err) + } + content := signalpb.Content{} + err = proto.Unmarshal(decryptedText, &content) + if err != nil { + log.Err(err).Msg("Unmarshal error") + } + result = &DecryptionResult{ + SenderAddress: senderAddress, + Content: &content, + SealedSender: true, + } + } + + case libsignalgo.CiphertextMessageTypePlaintext: + log.Debug().Msg("SealedSender messageType is CiphertextMessageTypePlaintext") + // TODO: handle plaintext (usually DecryptionErrorMessage) and retries + // when implementing SenderKey groups + + //plaintextContent, err := libsignalgo.DeserializePlaintextContent(usmcContents) + //if err != nil { + // log.Err(err).Msg("DeserializePlaintextContent error") + //} + //body, err := plaintextContent.GetBody() + //if err != nil { + // log.Err(err).Msg("PlaintextContent GetBody error") + //} + //content := signalpb.Content{} + //err = proto.Unmarshal(body, &content) + //if err != nil { + // log.Err(err).Msg("PlaintextContent Unmarshal error") + //} + //result = &DecryptionResult{ + // SenderAddress: *senderAddress, + // Content: &content, + // SealedSender: true, + //} + + return nil, nil + + default: + log.Warn().Msg("SealedSender messageType is unknown") + } + + // If we couldn't decrypt with specific decryption methods, try sealedSenderDecrypt + if result == nil { + log.Debug().Msg("Didn't decrypt with specific methods, trying sealedSenderDecrypt") + var err error + result, err = cli.sealedSenderDecrypt(ctx, envelope) + if err != nil { + if strings.Contains(err.Error(), "self send of a sealed sender message") { + log.Debug().Msg("Message sent by us, ignoring") + } else if strings.Contains(err.Error(), "message with old counter") { + log.Info().Msg("Duplicate message, ignoring (sealedSenderDecrypt)") + } else { + log.Err(err).Msg("sealedSenderDecrypt error") + } + } else { + log.Trace(). + Any("sender_address", result.SenderAddress). + Any("content", result.Content). + Msg("SealedSender decrypt result") + } + } + return result, nil +} + +// TODO: we should split this up into multiple functions +func (cli *Client) handleDecryptedResult( + ctx context.Context, + result DecryptionResult, + destinationServiceID libsignalgo.ServiceID, +) error { + log := zerolog.Ctx(ctx) + if result.Content == nil { + log.Warn().Msg("Decrypted content is nil") + return nil + } + + // result.Err is set if there was an error during decryption and we + // should notifiy the user that the message could not be decrypted + if result.Err != nil { + log.Err(result.Err).Bool("urgent", result.Urgent).Msg("Decryption error") theirServiceID, err := result.SenderAddress.NameServiceID() if err != nil { - log.Err(err).Msg("Name error") - return nil, err + log.Err(err).Msg("Name error handling decryption error") } else if theirServiceID.Type != libsignalgo.ServiceIDTypeACI { log.Warn().Any("their_service_id", theirServiceID).Msg("Sender ServiceID is not an ACI") - return &web.SimpleResponse{ - Status: responseCode, - }, nil } - - if destinationServiceID == cli.Store.PNIServiceID() { - _, err = cli.Store.RecipientStore.LoadAndUpdateRecipient(ctx, theirServiceID.UUID, uuid.Nil, func(recipient *types.Recipient) (changed bool, err error) { - if !recipient.NeedsPNISignature { - log.Debug().Msg("Marking recipient as needing PNI signature") - recipient.NeedsPNISignature = true - return true, nil - } - return false, nil - }) - if err != nil { - log.Err(err).Msg("Failed to set needs_pni_signature flag after receiving message to PNI service ID") - } - } - - if content.GetPniSignatureMessage() != nil { - log.Debug().Msg("Content includes PNI signature message") - err = cli.handlePNISignatureMessage(ctx, theirServiceID, content.GetPniSignatureMessage()) - if err != nil { - log.Err(err). - Hex("pni_raw", content.GetPniSignatureMessage().GetPni()). - Stringer("aci", theirServiceID.UUID). - Msg("Failed to verify ACI-PNI mapping") - } - } - - // TODO: handle more sync messages - if content.SyncMessage != nil { - if content.SyncMessage.Keys != nil { - cli.Store.MasterKey = content.SyncMessage.Keys.GetMaster() - err = cli.Store.DeviceStore.PutDevice(ctx, &cli.Store.DeviceData) - if err != nil { - log.Err(err).Msg("Failed to save device after receiving master key") - } else { - log.Info().Msg("Received master key") - go cli.SyncStorage(ctx) - } - } else if content.SyncMessage.GetFetchLatest().GetType() == signalpb.SyncMessage_FetchLatest_STORAGE_MANIFEST { - log.Debug().Msg("Received storage manifest fetch latest notice") - go cli.SyncStorage(ctx) - } - syncSent := content.SyncMessage.GetSent() - if syncSent.GetMessage() != nil || syncSent.GetEditMessage() != nil { - destination := syncSent.DestinationServiceId - var syncDestinationServiceID libsignalgo.ServiceID - if destination != nil { - syncDestinationServiceID, err = libsignalgo.ServiceIDFromString(*destination) - if err != nil { - log.Err(err).Msg("Sync message destination parse error") - return nil, err - } - } - if destination == nil && syncSent.GetMessage().GetGroupV2() == nil && syncSent.GetEditMessage().GetDataMessage().GetGroupV2() == nil { - log.Warn().Msg("sync message sent destination is nil") - } else if content.SyncMessage.Sent.Message != nil { - // TODO handle expiration start ts, and maybe the sync message ts? - cli.incomingDataMessage(ctx, content.SyncMessage.Sent.Message, cli.Store.ACI, syncDestinationServiceID) - } else if content.SyncMessage.Sent.EditMessage != nil { - cli.incomingEditMessage(ctx, content.SyncMessage.Sent.EditMessage, cli.Store.ACI, syncDestinationServiceID) - } - } - if content.SyncMessage.Contacts != nil { - log.Debug().Msg("Recieved sync message contacts") - blob := content.SyncMessage.Contacts.Blob - if blob != nil { - contactsBytes, err := DownloadAttachment(ctx, blob) - if err != nil { - log.Err(err).Msg("Contacts Sync DownloadAttachment error") - } - // unmarshall contacts - contacts, avatars, err := unmarshalContactDetailsMessages(contactsBytes) - if err != nil { - log.Err(err).Msg("Contacts Sync unmarshalContactDetailsMessages error") - } - log.Debug().Int("contact_count", len(contacts)).Msg("Contacts Sync received contacts") - convertedContacts := make([]*types.Recipient, 0, len(contacts)) - for i, signalContact := range contacts { - if signalContact.Aci == nil || *signalContact.Aci == "" { - // TODO lookup PNI via CDSI and store that when ACI is missing? - log.Info(). - Any("contact", signalContact). - Msg("Signal Contact UUID is nil, skipping") - continue - } - contact, err := cli.StoreContactDetailsAsContact(ctx, signalContact, &avatars[i]) - if err != nil { - log.Err(err).Msg("StoreContactDetailsAsContact error") - continue - } - convertedContacts = append(convertedContacts, contact) - } - cli.handleEvent(&events.ContactList{ - Contacts: convertedContacts, - }) - } - } - if content.SyncMessage.Read != nil { - cli.handleEvent(&events.ReadSelf{ - Messages: content.SyncMessage.GetRead(), - }) - } - - } - - var sendDeliveryReceipt bool - if content.DataMessage != nil { - sendDeliveryReceipt = cli.incomingDataMessage(ctx, content.DataMessage, theirServiceID.UUID, theirServiceID) - } else if content.EditMessage != nil { - sendDeliveryReceipt = cli.incomingEditMessage(ctx, content.EditMessage, theirServiceID.UUID, theirServiceID) - } - if sendDeliveryReceipt { - // TODO send delivery receipts after actually bridging instead of here - err = cli.sendDeliveryReceipts(ctx, []uint64{content.DataMessage.GetTimestamp()}, theirServiceID.UUID) - if err != nil { - log.Err(err).Msg("sendDeliveryReceipts error") - } - } - - if content.TypingMessage != nil { - var groupID types.GroupIdentifier - if content.TypingMessage.GetGroupId() != nil { - gidBytes := content.TypingMessage.GetGroupId() - groupID = types.GroupIdentifier(base64.StdEncoding.EncodeToString(gidBytes)) - } - cli.handleEvent(&events.ChatEvent{ - Info: events.MessageInfo{ - Sender: theirServiceID.UUID, - ChatID: groupOrUserID(groupID, theirServiceID), - }, - Event: content.TypingMessage, + // Only send decryption error event if the message was urgent, + // to prevent spamming errors for typing notifications and whatnot + if result.Urgent { + cli.handleEvent(&events.DecryptionError{ + Sender: theirServiceID.UUID, + Err: result.Err, }) } + // Intentionally not returning here. In most cases there's nothing besides the error so + // nothing else will happen, but if there is content we still want to do what we can with it + } - // DM call message (group call is an opaque callMessage and a groupCallUpdate in a dataMessage) - if content.CallMessage != nil && (content.CallMessage.Offer != nil || content.CallMessage.Hangup != nil) { - cli.handleEvent(&events.Call{ - Info: events.MessageInfo{ - Sender: theirServiceID.UUID, - ChatID: theirServiceID.String(), - }, - IsRinging: content.CallMessage.Offer != nil, - }) + content := result.Content + log.Trace().Any("raw_data", content).Msg("Raw event data") + + name, _ := result.SenderAddress.Name() + deviceId, _ := result.SenderAddress.DeviceID() + newLog := log.With(). + Str("sender_name", name). + Uint("sender_device_id", deviceId). + Str("destination_service_id", destinationServiceID.String()). + Logger() + log = &newLog + ctx = log.WithContext(ctx) + log.Debug().Msg("Decrypted message") + printContentFieldString(ctx, content, "Decrypted content fields") + + // If there's a sender key distribution message, process it + if content.GetSenderKeyDistributionMessage() != nil { + log.Debug().Msg("content includes sender key distribution message") + skdm, err := libsignalgo.DeserializeSenderKeyDistributionMessage(content.GetSenderKeyDistributionMessage()) + if err != nil { + log.Err(err).Msg("DeserializeSenderKeyDistributionMessage error") + return err } - - // Read and delivery receipts - if content.ReceiptMessage != nil { - if content.GetReceiptMessage().GetType() == signalpb.ReceiptMessage_DELIVERY && theirServiceID == cli.Store.ACIServiceID() { - // Ignore delivery receipts from other own devices - return &web.SimpleResponse{ - Status: responseCode, - }, nil - } - cli.handleEvent(&events.Receipt{ - Sender: theirServiceID.UUID, - Content: content.ReceiptMessage, - }) + err = libsignalgo.ProcessSenderKeyDistributionMessage( + ctx, + skdm, + result.SenderAddress, + cli.Store.SenderKeyStore, + ) + if err != nil { + log.Err(err).Msg("ProcessSenderKeyDistributionMessage error") + return err } } - return &web.SimpleResponse{ - Status: responseCode, - }, nil + + theirServiceID, err := result.SenderAddress.NameServiceID() + if err != nil { + log.Err(err).Msg("Name error") + return err + } else if theirServiceID.Type != libsignalgo.ServiceIDTypeACI { + log.Warn().Any("their_service_id", theirServiceID).Msg("Sender ServiceID is not an ACI") + return nil + } + + if destinationServiceID == cli.Store.PNIServiceID() { + _, err = cli.Store.RecipientStore.LoadAndUpdateRecipient(ctx, theirServiceID.UUID, uuid.Nil, func(recipient *types.Recipient) (changed bool, err error) { + if !recipient.NeedsPNISignature { + log.Debug().Msg("Marking recipient as needing PNI signature") + recipient.NeedsPNISignature = true + return true, nil + } + return false, nil + }) + if err != nil { + log.Err(err).Msg("Failed to set needs_pni_signature flag after receiving message to PNI service ID") + } + } + + if content.GetPniSignatureMessage() != nil { + log.Debug().Msg("Content includes PNI signature message") + err = cli.handlePNISignatureMessage(ctx, theirServiceID, content.GetPniSignatureMessage()) + if err != nil { + log.Err(err). + Hex("pni_raw", content.GetPniSignatureMessage().GetPni()). + Stringer("aci", theirServiceID.UUID). + Msg("Failed to verify ACI-PNI mapping") + } + } + + // TODO: handle more sync messages + if content.SyncMessage != nil { + if content.SyncMessage.Keys != nil { + cli.Store.MasterKey = content.SyncMessage.Keys.GetMaster() + err = cli.Store.DeviceStore.PutDevice(ctx, &cli.Store.DeviceData) + if err != nil { + log.Err(err).Msg("Failed to save device after receiving master key") + } else { + log.Info().Msg("Received master key") + go cli.SyncStorage(ctx) + } + } else if content.SyncMessage.GetFetchLatest().GetType() == signalpb.SyncMessage_FetchLatest_STORAGE_MANIFEST { + log.Debug().Msg("Received storage manifest fetch latest notice") + go cli.SyncStorage(ctx) + } + syncSent := content.SyncMessage.GetSent() + if syncSent.GetMessage() != nil || syncSent.GetEditMessage() != nil { + destination := syncSent.DestinationServiceId + var syncDestinationServiceID libsignalgo.ServiceID + if destination != nil { + syncDestinationServiceID, err = libsignalgo.ServiceIDFromString(*destination) + if err != nil { + log.Err(err).Msg("Sync message destination parse error") + return err + } + } + if destination == nil && syncSent.GetMessage().GetGroupV2() == nil && syncSent.GetEditMessage().GetDataMessage().GetGroupV2() == nil { + log.Warn().Msg("sync message sent destination is nil") + } else if content.SyncMessage.Sent.Message != nil { + // TODO handle expiration start ts, and maybe the sync message ts? + cli.incomingDataMessage(ctx, content.SyncMessage.Sent.Message, cli.Store.ACI, syncDestinationServiceID) + } else if content.SyncMessage.Sent.EditMessage != nil { + cli.incomingEditMessage(ctx, content.SyncMessage.Sent.EditMessage, cli.Store.ACI, syncDestinationServiceID) + } + } + if content.SyncMessage.Contacts != nil { + log.Debug().Msg("Recieved sync message contacts") + blob := content.SyncMessage.Contacts.Blob + if blob != nil { + contactsBytes, err := DownloadAttachment(ctx, blob) + if err != nil { + log.Err(err).Msg("Contacts Sync DownloadAttachment error") + } + // unmarshall contacts + contacts, avatars, err := unmarshalContactDetailsMessages(contactsBytes) + if err != nil { + log.Err(err).Msg("Contacts Sync unmarshalContactDetailsMessages error") + } + log.Debug().Int("contact_count", len(contacts)).Msg("Contacts Sync received contacts") + convertedContacts := make([]*types.Recipient, 0, len(contacts)) + for i, signalContact := range contacts { + if signalContact.Aci == nil || *signalContact.Aci == "" { + // TODO lookup PNI via CDSI and store that when ACI is missing? + log.Info(). + Any("contact", signalContact). + Msg("Signal Contact UUID is nil, skipping") + continue + } + contact, err := cli.StoreContactDetailsAsContact(ctx, signalContact, &avatars[i]) + if err != nil { + log.Err(err).Msg("StoreContactDetailsAsContact error") + continue + } + convertedContacts = append(convertedContacts, contact) + } + cli.handleEvent(&events.ContactList{ + Contacts: convertedContacts, + }) + } + } + if content.SyncMessage.Read != nil { + cli.handleEvent(&events.ReadSelf{ + Messages: content.SyncMessage.GetRead(), + }) + } + + } + + var sendDeliveryReceipt bool + if content.DataMessage != nil { + sendDeliveryReceipt = cli.incomingDataMessage(ctx, content.DataMessage, theirServiceID.UUID, theirServiceID) + } else if content.EditMessage != nil { + sendDeliveryReceipt = cli.incomingEditMessage(ctx, content.EditMessage, theirServiceID.UUID, theirServiceID) + } + if sendDeliveryReceipt { + // TODO send delivery receipts after actually bridging instead of here + err = cli.sendDeliveryReceipts(ctx, []uint64{content.DataMessage.GetTimestamp()}, theirServiceID.UUID) + if err != nil { + log.Err(err).Msg("sendDeliveryReceipts error") + } + } + + if content.TypingMessage != nil { + var groupID types.GroupIdentifier + if content.TypingMessage.GetGroupId() != nil { + gidBytes := content.TypingMessage.GetGroupId() + groupID = types.GroupIdentifier(base64.StdEncoding.EncodeToString(gidBytes)) + } + cli.handleEvent(&events.ChatEvent{ + Info: events.MessageInfo{ + Sender: theirServiceID.UUID, + ChatID: groupOrUserID(groupID, theirServiceID), + }, + Event: content.TypingMessage, + }) + } + + // DM call message (group call is an opaque callMessage and a groupCallUpdate in a dataMessage) + if content.CallMessage != nil && (content.CallMessage.Offer != nil || content.CallMessage.Hangup != nil) { + cli.handleEvent(&events.Call{ + Info: events.MessageInfo{ + Sender: theirServiceID.UUID, + ChatID: theirServiceID.String(), + }, + IsRinging: content.CallMessage.Offer != nil, + }) + } + + // Read and delivery receipts + if content.ReceiptMessage != nil { + if content.GetReceiptMessage().GetType() == signalpb.ReceiptMessage_DELIVERY && theirServiceID == cli.Store.ACIServiceID() { + // Ignore delivery receipts from other own devices + return nil + } + cli.handleEvent(&events.Receipt{ + Sender: theirServiceID.UUID, + Content: content.ReceiptMessage, + }) + } + return nil } func printStructFields(message protoreflect.Message, parent string, builder *strings.Builder) { @@ -951,6 +1026,8 @@ type DecryptionResult struct { SenderAddress *libsignalgo.Address Content *signalpb.Content SealedSender bool + Err error + Urgent bool } const prodServerTrustRootStr = "BXu6QIKVz5MA8gstzfOgRQGqyLqOwNKHL6INkv3IHWMF" diff --git a/user.go b/user.go index db5bd4c..a579e8b 100644 --- a/user.go +++ b/user.go @@ -858,6 +858,19 @@ func (user *User) eventHandler(rawEvt events.SignalEvent) { } else { user.log.Warn().Str("chat_id", evt.Info.ChatID).Msg("Couldn't get portal, dropping message") } + case *events.DecryptionError: + portal := user.GetPortalByChatID(evt.Sender.String()) + if portal == nil { + user.log.Warn().Stringer("chat_id", evt.Sender).Msg("Couldn't get portal for decryption error") + return + } + content := &event.MessageEventContent{MsgType: event.MsgNotice} + name := user.bridge.GetPuppetBySignalID(evt.Sender).Name + if name == "" { + name = "This user" + } + content.Body = fmt.Sprintf("%s sent a message that couldn't be decrypted. It may have been in this chat or a group chat. Please check your Signal app", name) + portal.sendMainIntentMessage(context.TODO(), content) case *events.Receipt: user.handleReceipt(evt) case *events.ReadSelf: From e7b62ee93b9388540d77c4beecc50c264c7fb390 Mon Sep 17 00:00:00 2001 From: Malte E <97891689+maltee1@users.noreply.github.com> Date: Sat, 13 Apr 2024 23:06:32 +0200 Subject: [PATCH 013/580] Try fix zero length user ID error (#498) --- pkg/libsignalgo/profilekey.go | 53 ++++++++-------- pkg/signalmeow/groups.go | 111 ++++++++++++++++------------------ 2 files changed, 81 insertions(+), 83 deletions(-) diff --git a/pkg/libsignalgo/profilekey.go b/pkg/libsignalgo/profilekey.go index 8d4ba8f..5d5f157 100644 --- a/pkg/libsignalgo/profilekey.go +++ b/pkg/libsignalgo/profilekey.go @@ -214,27 +214,32 @@ func ReceiveExpiringProfileKeyCredential(spp ServerPublicParams, requestContext return &credential, nil } -//func NewProfileKeyCredentialPresentation(b []byte) (ProfileKeyCredentialPresentation, error) { -// C.signal_profile_key_credential_presentation_check_valid_contents(cBytes(b), cLen(b)) -// if res := C.FFI_ProfileKeyCredentialPresentation_checkValidContents(cBytes(b), cLen(b)); res != C.FFI_RETURN_OK { -// return nil, errFromCode(res) -// } -// return ProfileKeyCredentialPresentation(b), nil -//} -// -//func (a ProfileKeyCredentialPresentation) UUIDCiphertext() ([]byte, error) { -// out := make([]byte, C.UUID_CIPHERTEXT_LEN) -// if res := C.FFI_ProfileKeyCredentialPresentation_getUuidCiphertext(cBytes(a), cLen(a), cBytes(out), cLen(out)); res != C.FFI_RETURN_OK { -// return nil, errFromCode(res) -// } -// return out, nil -//} -// -//func (a ProfileKeyCredentialPresentation) ProfileKeyCiphertext() ([]byte, error) { -// out := make([]byte, C.PROFILE_KEY_CIPHERTEXT_LEN) -// if res := C.FFI_ProfileKeyCredentialPresentation_getProfileKeyCiphertext(cBytes(a), cLen(a), cBytes(out), cLen(out)); res != C.FFI_RETURN_OK { -// return nil, errFromCode(res) -// } -// return out, nil -//} -// +func (a ProfileKeyCredentialPresentation) CheckValidContents() error { + signalFfiError := C.signal_profile_key_credential_presentation_check_valid_contents(BytesToBuffer(a)) + runtime.KeepAlive(a) + return wrapError(signalFfiError) +} + +func (a ProfileKeyCredentialPresentation) UUIDCiphertext() (UUIDCiphertext, error) { + out := [C.SignalUUID_CIPHERTEXT_LEN]C.uchar{} + signalFfiError := C.signal_profile_key_credential_presentation_get_uuid_ciphertext(&out, BytesToBuffer(a)) + runtime.KeepAlive(a) + if signalFfiError != nil { + return UUIDCiphertext{}, wrapError(signalFfiError) + } + var result UUIDCiphertext + copy(result[:], C.GoBytes(unsafe.Pointer(&out), C.int(C.SignalUUID_CIPHERTEXT_LEN))) + return result, nil +} + +func (a ProfileKeyCredentialPresentation) ProfileKeyCiphertext() (ProfileKeyCiphertext, error) { + out := [C.SignalPROFILE_KEY_CIPHERTEXT_LEN]C.uchar{} + signalFfiError := C.signal_profile_key_credential_presentation_get_profile_key_ciphertext(&out, BytesToBuffer(a)) + runtime.KeepAlive(a) + if signalFfiError != nil { + return ProfileKeyCiphertext{}, wrapError(signalFfiError) + } + var result ProfileKeyCiphertext + copy(result[:], C.GoBytes(unsafe.Pointer(&out), C.int(C.SignalPROFILE_KEY_CIPHERTEXT_LEN))) + return result, nil +} diff --git a/pkg/signalmeow/groups.go b/pkg/signalmeow/groups.go index 1214088..0a67ef6 100644 --- a/pkg/signalmeow/groups.go +++ b/pkg/signalmeow/groups.go @@ -943,26 +943,15 @@ func (cli *Client) decryptGroupChange(ctx context.Context, encryptedGroupChange if modifyProfileKey == nil { continue } - encryptedUserID := libsignalgo.UUIDCiphertext(modifyProfileKey.UserId) - serviceID, err := groupSecretParams.DecryptServiceID(encryptedUserID) + aci, profileKey, err := decryptPKeyAndIDorPresentation(ctx, modifyProfileKey.UserId, modifyProfileKey.ProfileKey, modifyProfileKey.Presentation, groupSecretParams) if err != nil { - log.Err(err).Msg("DecryptUUID UserId error for modifyProfileKey") - return nil, err - } - if serviceID.Type != libsignalgo.ServiceIDTypeACI { - return nil, fmt.Errorf("Wrong ServiceID kind: expected ACI, got PNI") - } - encryptedProfileKey := libsignalgo.ProfileKeyCiphertext(modifyProfileKey.ProfileKey) - profileKey, err := groupSecretParams.DecryptProfileKey(encryptedProfileKey, serviceID.UUID) - if err != nil { - log.Err(err).Msg("DecryptProfileKey ProfileKey error for modifyProfileKey") return nil, err } decryptedGroupChange.ModifyMemberProfileKeys = append(decryptedGroupChange.ModifyMemberProfileKeys, &ProfileKeyMember{ - ACI: serviceID.UUID, + ACI: *aci, ProfileKey: *profileKey, }) - err = cli.Store.RecipientStore.StoreProfileKey(ctx, serviceID.UUID, *profileKey) + err = cli.Store.RecipientStore.StoreProfileKey(ctx, *aci, *profileKey) if err != nil { log.Err(err).Msg("failed to store profile key") return nil, err @@ -999,23 +988,15 @@ func (cli *Client) decryptGroupChange(ctx context.Context, encryptedGroupChange if promotePendingMember == nil { continue } - encryptedUserID := libsignalgo.UUIDCiphertext(promotePendingMember.UserId) - serviceID, err := groupSecretParams.DecryptServiceID(encryptedUserID) + aci, profileKey, err := decryptPKeyAndIDorPresentation(ctx, promotePendingMember.UserId, promotePendingMember.ProfileKey, promotePendingMember.Presentation, groupSecretParams) if err != nil { - log.Err(err).Msg("DecryptUUID UserId error for promotePendingMember") - return nil, err - } - encryptedProfileKey := libsignalgo.ProfileKeyCiphertext(promotePendingMember.ProfileKey) - profileKey, err := groupSecretParams.DecryptProfileKey(encryptedProfileKey, serviceID.UUID) - if err != nil { - log.Err(err).Msg("DecryptProfileKey ProfileKey error for promotePendingMember") return nil, err } decryptedGroupChange.PromotePendingMembers = append(decryptedGroupChange.PromotePendingMembers, &GroupMember{ - ACI: serviceID.UUID, + ACI: *aci, ProfileKey: *profileKey, }) - err = cli.Store.RecipientStore.StoreProfileKey(ctx, serviceID.UUID, *profileKey) + err = cli.Store.RecipientStore.StoreProfileKey(ctx, *aci, *profileKey) if err != nil { log.Err(err).Msg("failed to store profile key") return nil, err @@ -1027,16 +1008,11 @@ func (cli *Client) decryptGroupChange(ctx context.Context, encryptedGroupChange if promotePendingPniAciMember == nil { continue } - encryptedUserID := libsignalgo.UUIDCiphertext(promotePendingPniAciMember.UserId) - aciServiceID, err := groupSecretParams.DecryptServiceID(encryptedUserID) + aci, profileKey, err := decryptPKeyAndIDorPresentation(ctx, promotePendingPniAciMember.UserId, promotePendingPniAciMember.ProfileKey, promotePendingPniAciMember.Presentation, groupSecretParams) if err != nil { - log.Err(err).Msg("DecryptUUID UserId error for promotePendingPniAciMember") return nil, err } - if aciServiceID.Type != libsignalgo.ServiceIDTypeACI { - return nil, fmt.Errorf("Wrong ServiceID kind: expected ACI, got PNI") - } - encryptedUserID = libsignalgo.UUIDCiphertext(promotePendingPniAciMember.Pni) + encryptedUserID := libsignalgo.UUIDCiphertext(promotePendingPniAciMember.Pni) pniServiceID, err := groupSecretParams.DecryptServiceID(encryptedUserID) if err != nil { log.Err(err).Msg("DecryptUUID Pni error for promotePendingPniAciMember") @@ -1045,18 +1021,12 @@ func (cli *Client) decryptGroupChange(ctx context.Context, encryptedGroupChange if pniServiceID.Type != libsignalgo.ServiceIDTypePNI { return nil, fmt.Errorf("Wrong ServiceID kind: expected PNI, got ACI") } - encryptedProfileKey := libsignalgo.ProfileKeyCiphertext(promotePendingPniAciMember.ProfileKey) - profileKey, err := groupSecretParams.DecryptProfileKey(encryptedProfileKey, aciServiceID.UUID) - if err != nil { - log.Err(err).Msg("DecryptProfileKey ProfileKey error for promotePendingPniAciMember") - return nil, err - } decryptedGroupChange.PromotePendingPniAciMembers = append(decryptedGroupChange.PromotePendingPniAciMembers, &PromotePendingPniAciMember{ - ACI: aciServiceID.UUID, + ACI: *aci, ProfileKey: *profileKey, PNI: pniServiceID.UUID, }) - err = cli.Store.RecipientStore.StoreProfileKey(ctx, aciServiceID.UUID, *profileKey) + err = cli.Store.RecipientStore.StoreProfileKey(ctx, *aci, *profileKey) if err != nil { log.Err(err).Msg("failed to store profile key") return nil, err @@ -1169,22 +1139,54 @@ func (cli *Client) decryptGroupChange(ctx context.Context, encryptedGroupChange return decryptedGroupChange, nil } -func decryptMember(ctx context.Context, member *signalpb.Member, groupSecretParams libsignalgo.GroupSecretParams) (*GroupMember, error) { +func decryptPKeyAndIDorPresentation(ctx context.Context, userID []byte, profileKeyBytes []byte, presentationBytes []byte, groupSecretParams libsignalgo.GroupSecretParams) (*uuid.UUID, *libsignalgo.ProfileKey, error) { log := zerolog.Ctx(ctx) - encryptedUserID := libsignalgo.UUIDCiphertext(member.UserId) + var encryptedUserID libsignalgo.UUIDCiphertext + var encryptedProfileKey libsignalgo.ProfileKeyCiphertext + if len(userID) == 0 || len(profileKeyBytes) == 0 { + presentation := libsignalgo.ProfileKeyCredentialPresentation(presentationBytes) + err := presentation.CheckValidContents() + if err != nil { + log.Err(err).Msg("Invalid presentation contents") + return nil, nil, err + } + encryptedUserID, err = presentation.UUIDCiphertext() + if err != nil { + log.Err(err).Msg("unable to get UUID from presentation") + return nil, nil, err + } + encryptedProfileKey, err = presentation.ProfileKeyCiphertext() + if err != nil { + log.Err(err).Msg("unable to get ProfileKey from presentation") + return nil, nil, err + } + } else { + encryptedUserID = libsignalgo.UUIDCiphertext(userID) + encryptedProfileKey = libsignalgo.ProfileKeyCiphertext(profileKeyBytes) + } serviceID, err := groupSecretParams.DecryptServiceID(encryptedUserID) if err != nil { - log.Err(err).Msg("DecryptUUID UserId error") - return nil, err + log.Err(err).Msg("Failed to decrypt ServiceID") + return nil, nil, err } - encryptedProfileKey := libsignalgo.ProfileKeyCiphertext(member.ProfileKey) profileKey, err := groupSecretParams.DecryptProfileKey(encryptedProfileKey, serviceID.UUID) if err != nil { - log.Err(err).Msg("DecryptProfileKey ProfileKey error") + return nil, nil, err + } + if serviceID.Type == libsignalgo.ServiceIDTypePNI { + return nil, nil, fmt.Errorf("wrong serviceid kind, expected ACI, got PNI") + } + return &serviceID.UUID, profileKey, nil + +} + +func decryptMember(ctx context.Context, member *signalpb.Member, groupSecretParams libsignalgo.GroupSecretParams) (*GroupMember, error) { + aci, profileKey, err := decryptPKeyAndIDorPresentation(ctx, member.UserId, member.ProfileKey, member.Presentation, groupSecretParams) + if err != nil { return nil, err } return &GroupMember{ - ACI: serviceID.UUID, + ACI: *aci, ProfileKey: *profileKey, Role: GroupMemberRole(member.Role), JoinedAtRevision: member.JoinedAtRevision, @@ -1215,21 +1217,12 @@ func decryptPendingMember(ctx context.Context, pendingMember *signalpb.PendingMe } func decryptRequestingMember(ctx context.Context, requestingMember *signalpb.RequestingMember, groupSecretParams libsignalgo.GroupSecretParams) (*RequestingMember, error) { - log := zerolog.Ctx(ctx) - encryptedUserID := libsignalgo.UUIDCiphertext(requestingMember.UserId) - serviceID, err := groupSecretParams.DecryptServiceID(encryptedUserID) + aci, profileKey, err := decryptPKeyAndIDorPresentation(ctx, requestingMember.UserId, requestingMember.ProfileKey, requestingMember.Presentation, groupSecretParams) if err != nil { - log.Err(err).Msg("DecryptUUID UserId error for requestingMember") - return nil, err - } - encryptedProfileKey := libsignalgo.ProfileKeyCiphertext(requestingMember.ProfileKey) - profileKey, err := groupSecretParams.DecryptProfileKey(encryptedProfileKey, serviceID.UUID) - if err != nil { - log.Err(err).Msg("DecryptProfileKey ProfileKey error for requestingMember") return nil, err } return &RequestingMember{ - ACI: serviceID.UUID, + ACI: *aci, ProfileKey: *profileKey, Timestamp: requestingMember.Timestamp, }, nil @@ -1364,7 +1357,7 @@ func (cli *Client) EncryptAndSignGroupChange(ctx context.Context, decryptedGroup for _, deleteRequestingMember := range decryptedGroupChange.DeleteRequestingMembers { encryptedUserID, err := groupSecretParams.EncryptServiceID(libsignalgo.NewACIServiceID(*deleteRequestingMember)) if err != nil { - log.Err(err).Msg("Encrypt UserId error for promotePendingMember") + log.Err(err).Msg("Encrypt UserId error for deleteRequestingMember") return nil, err } groupChangeActions.DeleteRequestingMembers = append(groupChangeActions.DeleteRequestingMembers, &signalpb.GroupChange_Actions_DeleteRequestingMemberAction{ From c8f2f7892968795925cacbe7386c63e5dd250e9b Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Mon, 15 Apr 2024 12:41:38 +0300 Subject: [PATCH 014/580] Update dependencies --- go.mod | 14 +++++++------- go.sum | 28 ++++++++++++++-------------- 2 files changed, 21 insertions(+), 21 deletions(-) diff --git a/go.mod b/go.mod index 949f87e..d7eff9a 100644 --- a/go.mod +++ b/go.mod @@ -15,13 +15,13 @@ require ( github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e github.com/stretchr/testify v1.9.0 github.com/tidwall/gjson v1.17.1 - go.mau.fi/util v0.4.1 - golang.org/x/crypto v0.21.0 - golang.org/x/exp v0.0.0-20240314144324-c7f7c6466f7f - golang.org/x/net v0.22.0 + go.mau.fi/util v0.4.2-0.20240318211948-d27d5a4cda9e + golang.org/x/crypto v0.22.0 + golang.org/x/exp v0.0.0-20240409090435-93d18d7e34b8 + golang.org/x/net v0.24.0 google.golang.org/protobuf v1.33.0 - maunium.net/go/mautrix v0.18.1-0.20240322180408-ade00e8603f9 - nhooyr.io/websocket v1.8.10 + maunium.net/go/mautrix v0.18.1-0.20240413105730-423d32ddf6d6 + nhooyr.io/websocket v1.8.11 ) require ( @@ -43,7 +43,7 @@ require ( github.com/tidwall/sjson v1.2.5 // indirect github.com/yuin/goldmark v1.7.0 // indirect go.mau.fi/zeroconfig v0.1.2 // indirect - golang.org/x/sys v0.18.0 // indirect + golang.org/x/sys v0.19.0 // indirect gopkg.in/natefinch/lumberjack.v2 v2.2.1 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect maunium.net/go/mauflag v1.0.0 // indirect diff --git a/go.sum b/go.sum index 3916c4d..3fd72f0 100644 --- a/go.sum +++ b/go.sum @@ -69,21 +69,21 @@ github.com/tidwall/sjson v1.2.5 h1:kLy8mja+1c9jlljvWTlSazM7cKDRfJuR/bOJhcY5NcY= github.com/tidwall/sjson v1.2.5/go.mod h1:Fvgq9kS/6ociJEDnK0Fk1cpYF4FIW6ZF7LAe+6jwd28= github.com/yuin/goldmark v1.7.0 h1:EfOIvIMZIzHdB/R/zVrikYLPPwJlfMcNczJFMs1m6sA= github.com/yuin/goldmark v1.7.0/go.mod h1:uzxRWxtg69N339t3louHJ7+O03ezfj6PlliRlaOzY1E= -go.mau.fi/util v0.4.1 h1:3EC9KxIXo5+h869zDGf5OOZklRd/FjeVnimTwtm3owg= -go.mau.fi/util v0.4.1/go.mod h1:GjkTEBsehYZbSh2LlE6cWEn+6ZIZTGrTMM/5DMNlmFY= +go.mau.fi/util v0.4.2-0.20240318211948-d27d5a4cda9e h1:2jdYsZTTIwSo4TGmVrqLgeCqaxexJ9nY2Tuj1MzDIwc= +go.mau.fi/util v0.4.2-0.20240318211948-d27d5a4cda9e/go.mod h1:GjkTEBsehYZbSh2LlE6cWEn+6ZIZTGrTMM/5DMNlmFY= go.mau.fi/zeroconfig v0.1.2 h1:DKOydWnhPMn65GbXZOafgkPm11BvFashZWLct0dGFto= go.mau.fi/zeroconfig v0.1.2/go.mod h1:NcSJkf180JT+1IId76PcMuLTNa1CzsFFZ0nBygIQM70= -golang.org/x/crypto v0.21.0 h1:X31++rzVUdKhX5sWmSOFZxx8UW/ldWx55cbf08iNAMA= -golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs= -golang.org/x/exp v0.0.0-20240314144324-c7f7c6466f7f h1:3CW0unweImhOzd5FmYuRsD4Y4oQFKZIjAnKbjV4WIrw= -golang.org/x/exp v0.0.0-20240314144324-c7f7c6466f7f/go.mod h1:CxmFvTBINI24O/j8iY7H1xHzx2i4OsyguNBmN/uPtqc= -golang.org/x/net v0.22.0 h1:9sGLhx7iRIHEiX0oAJ3MRZMUCElJgy7Br1nO+AMN3Tc= -golang.org/x/net v0.22.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg= +golang.org/x/crypto v0.22.0 h1:g1v0xeRhjcugydODzvb3mEM9SQ0HGp9s/nh3COQ/C30= +golang.org/x/crypto v0.22.0/go.mod h1:vr6Su+7cTlO45qkww3VDJlzDn0ctJvRgYbC2NvXHt+M= +golang.org/x/exp v0.0.0-20240409090435-93d18d7e34b8 h1:ESSUROHIBHg7USnszlcdmjBEwdMj9VUvU+OPk4yl2mc= +golang.org/x/exp v0.0.0-20240409090435-93d18d7e34b8/go.mod h1:/lliqkxwWAhPjf5oSOIJup2XcqJaw8RGS6k3TGEc7GI= +golang.org/x/net v0.24.0 h1:1PcaxkF854Fu3+lvBIx5SYn9wRlBzzcnHZSiaFFAb0w= +golang.org/x/net v0.24.0/go.mod h1:2Q7sJY5mzlzWjKtYUEXSlBWCdyaioyXzRB2RtU8KVE8= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.18.0 h1:DBdB3niSjOA/O0blCZBqDefyWNYveAYMNF1Wum0DYQ4= -golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.19.0 h1:q5f1RH2jigJ1MoAWp2KTp3gm5zAGFUTarQZ5U386+4o= +golang.org/x/sys v0.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI= google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= @@ -95,7 +95,7 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= maunium.net/go/mauflag v1.0.0 h1:YiaRc0tEI3toYtJMRIfjP+jklH45uDHtT80nUamyD4M= maunium.net/go/mauflag v1.0.0/go.mod h1:nLivPOpTpHnpzEh8jEdSL9UqO9+/KBJFmNRlwKfkPeA= -maunium.net/go/mautrix v0.18.1-0.20240322180408-ade00e8603f9 h1:Xl741d8hAFdBPJPT/ydc6zTQM4R4L+5/d1X+AevLdXY= -maunium.net/go/mautrix v0.18.1-0.20240322180408-ade00e8603f9/go.mod h1:STwJZ+6CAeiEQs7fYCkd5aC12XR5DXANE6Swy/PBKGo= -nhooyr.io/websocket v1.8.10 h1:mv4p+MnGrLDcPlBoWsvPP7XCzTYMXP9F9eIGoKbgx7Q= -nhooyr.io/websocket v1.8.10/go.mod h1:rN9OFWIUwuxg4fR5tELlYC04bXYowCP9GX47ivo2l+c= +maunium.net/go/mautrix v0.18.1-0.20240413105730-423d32ddf6d6 h1:zSGNGm31EzKYDmKJG2VS5wYqYDAT5pJhFfGauR6r4yU= +maunium.net/go/mautrix v0.18.1-0.20240413105730-423d32ddf6d6/go.mod h1:STwJZ+6CAeiEQs7fYCkd5aC12XR5DXANE6Swy/PBKGo= +nhooyr.io/websocket v1.8.11 h1:f/qXNc2/3DpoSZkHt1DQu6rj4zGC8JmkkLkWss0MgN0= +nhooyr.io/websocket v1.8.11/go.mod h1:rN9OFWIUwuxg4fR5tELlYC04bXYowCP9GX47ivo2l+c= From cd13814b3d87ee38fd59f4b0eca09fc98519f334 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Mon, 15 Apr 2024 13:06:38 +0300 Subject: [PATCH 015/580] Add missing check to create command --- commands.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/commands.go b/commands.go index 2f224bc..728f2d6 100644 --- a/commands.go +++ b/commands.go @@ -1103,7 +1103,7 @@ func fnCreate(ce *WrappedCommandEvent) { } portal.MXID = ce.RoomID portal.Name = roomName - portal.Encrypted = encryptionEvent.Algorithm == id.AlgorithmMegolmV1 + portal.Encrypted = encryptionEvent != nil && encryptionEvent.Algorithm == id.AlgorithmMegolmV1 if !portal.Encrypted && ce.Bridge.Config.Bridge.Encryption.Default { _, err = portal.MainIntent().SendStateEvent(ce.Ctx, portal.MXID, event.StateEncryption, "", portal.GetEncryptionEventContent()) if err != nil { From 703becae6de32e0f89611d492536883102814452 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Tue, 16 Apr 2024 14:05:16 +0300 Subject: [PATCH 016/580] Bump version to v0.6.0 --- CHANGELOG.md | 26 ++++++++++++++++++++++++++ go.mod | 6 +++--- go.sum | 12 ++++++------ main.go | 2 +- 4 files changed, 36 insertions(+), 10 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5a63f40..ec053c8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,29 @@ +# v0.6.0 (2024-04-16) + +* Updated to libsignal v0.44.0. +* Refactored bridge to support Signal's new phone number identifier (PNI) + system in order to fix starting new chats and receiving messages from new + users. + * When starting a chat with a user you haven't talked to before, the portal + room will not have a ghost user for the recipient until they accept the + message request. +* Added support for syncing existing groups on login instead of having to wait + for new messages. +* Added notices if decrypting incoming message from Signal fails. +* Added bridging of group metadata from Matrix to Signal + (thanks to [@maltee1] in [#461]). +* Added command to create new Signal group for Matrix room + (thanks to [@maltee1] in [#461] and [#491]). +* Added commands for inviting users to Signal groups by phone number + (thanks to [@maltee1] in [#495]). +* Improved handling of missed Signal group metadata changes + (thanks to [@maltee1] in [#488]). + +[#461]: https://github.com/mautrix/signal/pull/461 +[#488]: https://github.com/mautrix/signal/pull/488 +[#491]: https://github.com/mautrix/signal/pull/491 +[#495]: https://github.com/mautrix/signal/pull/495 + # v0.5.1 (2024-03-16) * Updated to libsignal v0.41.0. diff --git a/go.mod b/go.mod index d7eff9a..ac97321 100644 --- a/go.mod +++ b/go.mod @@ -15,12 +15,12 @@ require ( github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e github.com/stretchr/testify v1.9.0 github.com/tidwall/gjson v1.17.1 - go.mau.fi/util v0.4.2-0.20240318211948-d27d5a4cda9e + go.mau.fi/util v0.4.2 golang.org/x/crypto v0.22.0 golang.org/x/exp v0.0.0-20240409090435-93d18d7e34b8 golang.org/x/net v0.24.0 google.golang.org/protobuf v1.33.0 - maunium.net/go/mautrix v0.18.1-0.20240413105730-423d32ddf6d6 + maunium.net/go/mautrix v0.18.1 nhooyr.io/websocket v1.8.11 ) @@ -41,7 +41,7 @@ require ( github.com/tidwall/match v1.1.1 // indirect github.com/tidwall/pretty v1.2.0 // indirect github.com/tidwall/sjson v1.2.5 // indirect - github.com/yuin/goldmark v1.7.0 // indirect + github.com/yuin/goldmark v1.7.1 // indirect go.mau.fi/zeroconfig v0.1.2 // indirect golang.org/x/sys v0.19.0 // indirect gopkg.in/natefinch/lumberjack.v2 v2.2.1 // indirect diff --git a/go.sum b/go.sum index 3fd72f0..aaf41a7 100644 --- a/go.sum +++ b/go.sum @@ -67,10 +67,10 @@ github.com/tidwall/pretty v1.2.0 h1:RWIZEg2iJ8/g6fDDYzMpobmaoGh5OLl4AXtGUGPcqCs= github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU= github.com/tidwall/sjson v1.2.5 h1:kLy8mja+1c9jlljvWTlSazM7cKDRfJuR/bOJhcY5NcY= github.com/tidwall/sjson v1.2.5/go.mod h1:Fvgq9kS/6ociJEDnK0Fk1cpYF4FIW6ZF7LAe+6jwd28= -github.com/yuin/goldmark v1.7.0 h1:EfOIvIMZIzHdB/R/zVrikYLPPwJlfMcNczJFMs1m6sA= -github.com/yuin/goldmark v1.7.0/go.mod h1:uzxRWxtg69N339t3louHJ7+O03ezfj6PlliRlaOzY1E= -go.mau.fi/util v0.4.2-0.20240318211948-d27d5a4cda9e h1:2jdYsZTTIwSo4TGmVrqLgeCqaxexJ9nY2Tuj1MzDIwc= -go.mau.fi/util v0.4.2-0.20240318211948-d27d5a4cda9e/go.mod h1:GjkTEBsehYZbSh2LlE6cWEn+6ZIZTGrTMM/5DMNlmFY= +github.com/yuin/goldmark v1.7.1 h1:3bajkSilaCbjdKVsKdZjZCLBNPL9pYzrCakKaf4U49U= +github.com/yuin/goldmark v1.7.1/go.mod h1:uzxRWxtg69N339t3louHJ7+O03ezfj6PlliRlaOzY1E= +go.mau.fi/util v0.4.2 h1:RR3TOcRHmCF9Bx/3YG4S65MYfa+nV6/rn8qBWW4Mi30= +go.mau.fi/util v0.4.2/go.mod h1:PlAVfUUcPyHPrwnvjkJM9UFcPE7qGPDJqk+Oufa1Gtw= go.mau.fi/zeroconfig v0.1.2 h1:DKOydWnhPMn65GbXZOafgkPm11BvFashZWLct0dGFto= go.mau.fi/zeroconfig v0.1.2/go.mod h1:NcSJkf180JT+1IId76PcMuLTNa1CzsFFZ0nBygIQM70= golang.org/x/crypto v0.22.0 h1:g1v0xeRhjcugydODzvb3mEM9SQ0HGp9s/nh3COQ/C30= @@ -95,7 +95,7 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= maunium.net/go/mauflag v1.0.0 h1:YiaRc0tEI3toYtJMRIfjP+jklH45uDHtT80nUamyD4M= maunium.net/go/mauflag v1.0.0/go.mod h1:nLivPOpTpHnpzEh8jEdSL9UqO9+/KBJFmNRlwKfkPeA= -maunium.net/go/mautrix v0.18.1-0.20240413105730-423d32ddf6d6 h1:zSGNGm31EzKYDmKJG2VS5wYqYDAT5pJhFfGauR6r4yU= -maunium.net/go/mautrix v0.18.1-0.20240413105730-423d32ddf6d6/go.mod h1:STwJZ+6CAeiEQs7fYCkd5aC12XR5DXANE6Swy/PBKGo= +maunium.net/go/mautrix v0.18.1 h1:a6mUsJixegBNTXUoqC5RQ9gsumIPzKvCubKwF+zmCt4= +maunium.net/go/mautrix v0.18.1/go.mod h1:2oHaq792cSXFGvxLvYw3Gf1L4WVVP4KZcYys5HVk/h8= nhooyr.io/websocket v1.8.11 h1:f/qXNc2/3DpoSZkHt1DQu6rj4zGC8JmkkLkWss0MgN0= nhooyr.io/websocket v1.8.11/go.mod h1:rN9OFWIUwuxg4fR5tELlYC04bXYowCP9GX47ivo2l+c= diff --git a/main.go b/main.go index cd9e156..c09bc3d 100644 --- a/main.go +++ b/main.go @@ -331,7 +331,7 @@ func main() { Name: "mautrix-signal", URL: "https://github.com/mautrix/signal", Description: "A Matrix-Signal puppeting bridge.", - Version: "0.5.1", + Version: "0.6.0", ProtocolName: "Signal", BeeperServiceName: "signal", BeeperNetworkName: "signal", From 2a4b58e04ac3b3b45be89e39d5535cc4e5e5c9d7 Mon Sep 17 00:00:00 2001 From: Malte E <97891689+maltee1@users.noreply.github.com> Date: Wed, 1 May 2024 10:16:54 +0200 Subject: [PATCH 017/580] Add support for Matrix -> Signal location messages (#504) Fixes #424 --- config/bridge.go | 23 ++++++++++++----------- config/upgrade.go | 1 + example-config.yaml | 4 ++++ msgconv/from-matrix.go | 28 ++++++++++++++++++++++++++-- msgconv/msgconv.go | 2 ++ portal.go | 1 + 6 files changed, 46 insertions(+), 13 deletions(-) diff --git a/config/bridge.go b/config/bridge.go index 2ce4bb9..e3e756c 100644 --- a/config/bridge.go +++ b/config/bridge.go @@ -42,17 +42,18 @@ type BridgeConfig struct { PortalMessageBuffer int `yaml:"portal_message_buffer"` - PersonalFilteringSpaces bool `yaml:"personal_filtering_spaces"` - BridgeNotices bool `yaml:"bridge_notices"` - DeliveryReceipts bool `yaml:"delivery_receipts"` - MessageStatusEvents bool `yaml:"message_status_events"` - MessageErrorNotices bool `yaml:"message_error_notices"` - SyncDirectChatList bool `yaml:"sync_direct_chat_list"` - ResendBridgeInfo bool `yaml:"resend_bridge_info"` - PublicPortals bool `yaml:"public_portals"` - CaptionInMessage bool `yaml:"caption_in_message"` - FederateRooms bool `yaml:"federate_rooms"` - BridgeMatrixLeave bool `yaml:"bridge_matrix_leave"` + PersonalFilteringSpaces bool `yaml:"personal_filtering_spaces"` + BridgeNotices bool `yaml:"bridge_notices"` + DeliveryReceipts bool `yaml:"delivery_receipts"` + MessageStatusEvents bool `yaml:"message_status_events"` + MessageErrorNotices bool `yaml:"message_error_notices"` + SyncDirectChatList bool `yaml:"sync_direct_chat_list"` + ResendBridgeInfo bool `yaml:"resend_bridge_info"` + PublicPortals bool `yaml:"public_portals"` + CaptionInMessage bool `yaml:"caption_in_message"` + LocationFormat string `yaml:"location_format"` + FederateRooms bool `yaml:"federate_rooms"` + BridgeMatrixLeave bool `yaml:"bridge_matrix_leave"` DoublePuppetConfig bridgeconfig.DoublePuppetConfig `yaml:",inline"` diff --git a/config/upgrade.go b/config/upgrade.go index 0d943d6..114eb1d 100644 --- a/config/upgrade.go +++ b/config/upgrade.go @@ -96,6 +96,7 @@ func DoUpgrade(helper *up.Helper) { helper.Copy(up.Bool, "bridge", "resend_bridge_info") helper.Copy(up.Bool, "bridge", "public_portals") helper.Copy(up.Bool, "bridge", "caption_in_message") + helper.Copy(up.Str, "bridge", "location_format") helper.Copy(up.Bool, "bridge", "federate_rooms") helper.Copy(up.Map, "bridge", "double_puppet_server_map") helper.Copy(up.Bool, "bridge", "double_puppet_allow_discovery") diff --git a/example-config.yaml b/example-config.yaml index b61c355..71caa9c 100644 --- a/example-config.yaml +++ b/example-config.yaml @@ -139,6 +139,10 @@ bridge: # Send captions in the same message as images. This will send data compatible with both MSC2530. # This is currently not supported in most clients. caption_in_message: false + # Format for generating URLs from location messages for sending to Signal + # Google Maps: 'https://www.google.com/maps/place/%[1]s,%[2]s' + # OpenStreetMap: 'https://www.openstreetmap.org/?mlat=%[1]s&mlon=%[2]' + location_format: 'https://www.google.com/maps/place/%[1]s,%[2]s' # Whether or not created rooms should have federation enabled. # If false, created portal rooms will never be federated. federate_rooms: true diff --git a/msgconv/from-matrix.go b/msgconv/from-matrix.go index 791ea9e..9a14ead 100644 --- a/msgconv/from-matrix.go +++ b/msgconv/from-matrix.go @@ -20,9 +20,11 @@ import ( "context" "errors" "fmt" + "strings" "time" "github.com/rs/zerolog" + "github.com/rs/zerolog/log" "go.mau.fi/util/exerrors" "go.mau.fi/util/exmime" "go.mau.fi/util/ffmpeg" @@ -109,8 +111,13 @@ func (mc *MessageConverter) ToSignal(ctx context.Context, evt *event.Event, cont Emoji: emoji, } case event.MsgLocation: - // TODO implement - fallthrough + lat, lon, err := parseGeoURI(content.GeoURI) + if err != nil { + log.Err(err).Msg("Invalid geo URI") + return nil, err + } + locationString := fmt.Sprintf(mc.LocationFormat, lat, lon) + dm.Body = &locationString default: return nil, fmt.Errorf("%w %s", ErrUnsupportedMsgType, content.MsgType) } @@ -190,3 +197,20 @@ func (mc *MessageConverter) convertFileToSignal(ctx context.Context, evt *event. } return att, nil } + +func parseGeoURI(uri string) (lat, long string, err error) { + if !strings.HasPrefix(uri, "geo:") { + err = fmt.Errorf("uri doesn't have geo: prefix") + return + } + // Remove geo: prefix and anything after ; + coordinates := strings.Split(strings.TrimPrefix(uri, "geo:"), ";")[0] + splitCoordinates := strings.Split(coordinates, ",") + if len(splitCoordinates) != 2 { + err = fmt.Errorf("didn't find exactly two numbers separated by a comma") + } else { + lat = splitCoordinates[0] + long = splitCoordinates[1] + } + return +} diff --git a/msgconv/msgconv.go b/msgconv/msgconv.go index b7f9771..0e29157 100644 --- a/msgconv/msgconv.go +++ b/msgconv/msgconv.go @@ -54,6 +54,8 @@ type MessageConverter struct { ConvertGIFToAPNG bool MaxFileSize int64 AsyncFiles bool + + LocationFormat string } func (mc *MessageConverter) IsPrivateChat(ctx context.Context) bool { diff --git a/portal.go b/portal.go index 44f67bb..2e90ac7 100644 --- a/portal.go +++ b/portal.go @@ -236,6 +236,7 @@ func (br *SignalBridge) NewPortal(dbPortal *database.Portal) *Portal { MatrixFmtParams: matrixFormatParams, ConvertVoiceMessages: true, MaxFileSize: br.MediaConfig.UploadSize, + LocationFormat: br.Config.Bridge.LocationFormat, } go portal.messageLoop() From 73e7619312248c0abc2a64a058d1221152f6a8dc Mon Sep 17 00:00:00 2001 From: Malte E <97891689+maltee1@users.noreply.github.com> Date: Wed, 1 May 2024 10:17:07 +0200 Subject: [PATCH 018/580] Properly convert long text messages from Signal (#506) Fixes #479 --- msgconv/from-signal.go | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/msgconv/from-signal.go b/msgconv/from-signal.go index 9b47cca..a5c0174 100644 --- a/msgconv/from-signal.go +++ b/msgconv/from-signal.go @@ -115,7 +115,16 @@ func (mc *MessageConverter) ToMatrix(ctx context.Context, dm *signalpb.DataMessa return cm } for i, att := range dm.GetAttachments() { - cm.Parts = append(cm.Parts, mc.convertAttachmentToMatrix(ctx, i, att)) + if att.GetContentType() != "text/x-signal-plain" { + cm.Parts = append(cm.Parts, mc.convertAttachmentToMatrix(ctx, i, att)) + } else { + longBody, err := mc.downloadSignalLongText(ctx, att) + if err == nil { + dm.Body = longBody + } else { + zerolog.Ctx(ctx).Err(err).Msg("Failed to download Signal long text") + } + } } for _, contact := range dm.GetContact() { cm.Parts = append(cm.Parts, mc.convertContactToMatrix(ctx, contact)) @@ -415,6 +424,15 @@ func (mc *MessageConverter) convertStickerToMatrix(ctx context.Context, sticker return converted } +func (mc *MessageConverter) downloadSignalLongText(ctx context.Context, att *signalpb.AttachmentPointer) (*string, error) { + data, err := signalmeow.DownloadAttachment(ctx, att) + if err != nil { + return nil, fmt.Errorf("failed to download attachment: %w", err) + } + longBody := string(data) + return &longBody, nil +} + func (mc *MessageConverter) reuploadAttachment(ctx context.Context, att *signalpb.AttachmentPointer) (*ConvertedMessagePart, error) { data, err := signalmeow.DownloadAttachment(ctx, att) if err != nil { From b602e9472b9d7cc6d9915b8c133c727e003bf8b6 Mon Sep 17 00:00:00 2001 From: Scott Weber Date: Wed, 1 May 2024 09:17:15 +0100 Subject: [PATCH 019/580] Make Signal ping kill and rebuild websocket if it takes more than 20s (#507) --- pkg/signalmeow/web/signalwebsocket.go | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/pkg/signalmeow/web/signalwebsocket.go b/pkg/signalmeow/web/signalwebsocket.go index 40e43e4..0b97b8a 100644 --- a/pkg/signalmeow/web/signalwebsocket.go +++ b/pkg/signalmeow/web/signalwebsocket.go @@ -292,9 +292,12 @@ func (s *SignalWebsocket) connectLoop( for { select { case <-ticker.C: - err := ws.Ping(loopCtx) + pingCtx, cancel := context.WithTimeout(loopCtx, 20*time.Second) + err := ws.Ping(pingCtx) + cancel() if err != nil { - loopCancel(fmt.Errorf("error sending keepalive: %w", err)) + log.Err(err).Msg("Error pinging") + loopCancel(err) return } log.Debug().Msg("Sent keepalive") From 7ea4cdfce8981b05fd2862ec6aa0dee54e9aaa0a Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Thu, 16 May 2024 16:08:51 +0300 Subject: [PATCH 020/580] Bump version to v0.6.1 --- CHANGELOG.md | 10 ++++++++++ go.mod | 12 ++++++------ go.sum | 24 ++++++++++++------------ main.go | 2 +- 4 files changed, 29 insertions(+), 19 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ec053c8..df01490 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,13 @@ +# v0.6.1 (2024-05-16) + +* Added support for bridging location messages from Matrix to Signal + (thanks to [@maltee1] in [#504]). + * Note that Signal doesn't support real location messages, so they're just + bridged as links. The link template is configurable. +* Fixed bridging long text messages from Signal + (thanks to [@maltee1] in [#509]). +* Improved handling of ping timeouts in Signal websocket. + # v0.6.0 (2024-04-16) * Updated to libsignal v0.44.0. diff --git a/go.mod b/go.mod index ac97321..bf3fd25 100644 --- a/go.mod +++ b/go.mod @@ -10,16 +10,16 @@ require ( github.com/lib/pq v1.10.9 github.com/mattn/go-pointer v0.0.1 github.com/mattn/go-sqlite3 v1.14.22 - github.com/prometheus/client_golang v1.19.0 + github.com/prometheus/client_golang v1.19.1 github.com/rs/zerolog v1.32.0 github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e github.com/stretchr/testify v1.9.0 github.com/tidwall/gjson v1.17.1 go.mau.fi/util v0.4.2 - golang.org/x/crypto v0.22.0 - golang.org/x/exp v0.0.0-20240409090435-93d18d7e34b8 - golang.org/x/net v0.24.0 - google.golang.org/protobuf v1.33.0 + golang.org/x/crypto v0.23.0 + golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842 + golang.org/x/net v0.25.0 + google.golang.org/protobuf v1.34.1 maunium.net/go/mautrix v0.18.1 nhooyr.io/websocket v1.8.11 ) @@ -43,7 +43,7 @@ require ( github.com/tidwall/sjson v1.2.5 // indirect github.com/yuin/goldmark v1.7.1 // indirect go.mau.fi/zeroconfig v0.1.2 // indirect - golang.org/x/sys v0.19.0 // indirect + golang.org/x/sys v0.20.0 // indirect gopkg.in/natefinch/lumberjack.v2 v2.2.1 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect maunium.net/go/mauflag v1.0.0 // indirect diff --git a/go.sum b/go.sum index aaf41a7..30dea68 100644 --- a/go.sum +++ b/go.sum @@ -40,8 +40,8 @@ github.com/mattn/go-sqlite3 v1.14.22/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxU github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/prometheus/client_golang v1.19.0 h1:ygXvpU1AoN1MhdzckN+PyD9QJOSD4x7kmXYlnfbA6JU= -github.com/prometheus/client_golang v1.19.0/go.mod h1:ZRM9uEAypZakd+q/x7+gmsvXdURP+DABIEIjnmDdp+k= +github.com/prometheus/client_golang v1.19.1 h1:wZWJDwK+NameRJuPGDhlnFgx8e8HN3XHQeLaYJFJBOE= +github.com/prometheus/client_golang v1.19.1/go.mod h1:mP78NwGzrVks5S2H6ab8+ZZGJLZUq1hoULYBAYBw1Ho= github.com/prometheus/client_model v0.5.0 h1:VQw1hfvPvk3Uv6Qf29VrPF32JB6rtbgI6cYPYQjL0Qw= github.com/prometheus/client_model v0.5.0/go.mod h1:dTiFglRmd66nLR9Pv9f0mZi7B7fk5Pm3gvsjB5tr+kI= github.com/prometheus/common v0.48.0 h1:QO8U2CdOzSn1BBsmXJXduaaW+dY/5QLjfB8svtSzKKE= @@ -73,19 +73,19 @@ go.mau.fi/util v0.4.2 h1:RR3TOcRHmCF9Bx/3YG4S65MYfa+nV6/rn8qBWW4Mi30= go.mau.fi/util v0.4.2/go.mod h1:PlAVfUUcPyHPrwnvjkJM9UFcPE7qGPDJqk+Oufa1Gtw= go.mau.fi/zeroconfig v0.1.2 h1:DKOydWnhPMn65GbXZOafgkPm11BvFashZWLct0dGFto= go.mau.fi/zeroconfig v0.1.2/go.mod h1:NcSJkf180JT+1IId76PcMuLTNa1CzsFFZ0nBygIQM70= -golang.org/x/crypto v0.22.0 h1:g1v0xeRhjcugydODzvb3mEM9SQ0HGp9s/nh3COQ/C30= -golang.org/x/crypto v0.22.0/go.mod h1:vr6Su+7cTlO45qkww3VDJlzDn0ctJvRgYbC2NvXHt+M= -golang.org/x/exp v0.0.0-20240409090435-93d18d7e34b8 h1:ESSUROHIBHg7USnszlcdmjBEwdMj9VUvU+OPk4yl2mc= -golang.org/x/exp v0.0.0-20240409090435-93d18d7e34b8/go.mod h1:/lliqkxwWAhPjf5oSOIJup2XcqJaw8RGS6k3TGEc7GI= -golang.org/x/net v0.24.0 h1:1PcaxkF854Fu3+lvBIx5SYn9wRlBzzcnHZSiaFFAb0w= -golang.org/x/net v0.24.0/go.mod h1:2Q7sJY5mzlzWjKtYUEXSlBWCdyaioyXzRB2RtU8KVE8= +golang.org/x/crypto v0.23.0 h1:dIJU/v2J8Mdglj/8rJ6UUOM3Zc9zLZxVZwwxMooUSAI= +golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8= +golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842 h1:vr/HnozRka3pE4EsMEg1lgkXJkTFJCVUX+S/ZT6wYzM= +golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842/go.mod h1:XtvwrStGgqGPLc4cjQfWqZHG1YFdYs6swckp8vpsjnc= +golang.org/x/net v0.25.0 h1:d/OCCoBEUq33pjydKrGQhw7IlUPI2Oylr+8qLx49kac= +golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.19.0 h1:q5f1RH2jigJ1MoAWp2KTp3gm5zAGFUTarQZ5U386+4o= -golang.org/x/sys v0.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI= -google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= +golang.org/x/sys v0.20.0 h1:Od9JTbYCk261bKm4M/mw7AklTlFYIa0bIp9BgSm1S8Y= +golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +google.golang.org/protobuf v1.34.1 h1:9ddQBjfCyZPOHPUiPxpYESBLc+T8P3E+Vo4IbKZgFWg= +google.golang.org/protobuf v1.34.1/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= diff --git a/main.go b/main.go index c09bc3d..0a92c52 100644 --- a/main.go +++ b/main.go @@ -331,7 +331,7 @@ func main() { Name: "mautrix-signal", URL: "https://github.com/mautrix/signal", Description: "A Matrix-Signal puppeting bridge.", - Version: "0.6.0", + Version: "0.6.1", ProtocolName: "Signal", BeeperServiceName: "signal", BeeperNetworkName: "signal", From 585397a736d800939d500573b1e7e621bb93d05b Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Thu, 16 May 2024 16:25:00 +0300 Subject: [PATCH 021/580] Fix PR links in changelog --- CHANGELOG.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index df01490..9c6bc06 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,9 +5,12 @@ * Note that Signal doesn't support real location messages, so they're just bridged as links. The link template is configurable. * Fixed bridging long text messages from Signal - (thanks to [@maltee1] in [#509]). + (thanks to [@maltee1] in [#506]). * Improved handling of ping timeouts in Signal websocket. +[#504]: https://github.com/mautrix/signal/pull/504 +[#506]: https://github.com/mautrix/signal/pull/506 + # v0.6.0 (2024-04-16) * Updated to libsignal v0.44.0. From 6304b6b8c3eb935733c44de2ef120ce56bfbacdb Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Fri, 17 May 2024 17:47:16 +0300 Subject: [PATCH 022/580] Remove msc1767 audio field. Fixes #513 --- msgconv/from-signal.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/msgconv/from-signal.go b/msgconv/from-signal.go index a5c0174..9caecd6 100644 --- a/msgconv/from-signal.go +++ b/msgconv/from-signal.go @@ -452,7 +452,8 @@ func (mc *MessageConverter) reuploadAttachment(ctx context.Context, att *signalp fileName += ".ogg" mimeType = "audio/ogg" extra["org.matrix.msc3245.voice"] = map[string]any{} - extra["org.matrix.msc1767.audio"] = map[string]any{} + // TODO include duration here (and in info) if there's some easy way to extract it with ffmpeg + //extra["org.matrix.msc1767.audio"] = map[string]any{"duration": ???} } var file *event.EncryptedFileInfo uploadMime := mimeType From 874712c0f2dac17bc439e6f0a634f2affbb21156 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Fri, 3 May 2024 11:45:59 +0200 Subject: [PATCH 023/580] Initial draft bridge with v2 architecture --- connector/connector.go | 440 ++++++++++++++++++++++++++++ connector/mautrix-signal-v2/main.go | 207 +++++++++++++ connector/mautrix-signal-v2/start | 6 + go.mod | 8 +- go.sum | 12 +- 5 files changed, 663 insertions(+), 10 deletions(-) create mode 100644 connector/connector.go create mode 100644 connector/mautrix-signal-v2/main.go create mode 100755 connector/mautrix-signal-v2/start diff --git a/connector/connector.go b/connector/connector.go new file mode 100644 index 0000000..9667ae5 --- /dev/null +++ b/connector/connector.go @@ -0,0 +1,440 @@ +// mautrix-signal - A Matrix-Signal puppeting bridge. +// Copyright (C) 2024 Tulir Asokan +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +package connector + +import ( + "context" + "fmt" + "strconv" + "strings" + "time" + + "github.com/google/uuid" + "github.com/rs/zerolog" + "go.mau.fi/util/dbutil" + "golang.org/x/exp/slices" + "google.golang.org/protobuf/proto" + + "maunium.net/go/mautrix/bridgev2" + "maunium.net/go/mautrix/bridgev2/database" + "maunium.net/go/mautrix/bridgev2/networkid" + "maunium.net/go/mautrix/event" + "maunium.net/go/mautrix/id" + + legacydb "go.mau.fi/mautrix-signal/database" + "go.mau.fi/mautrix-signal/msgconv" + "go.mau.fi/mautrix-signal/msgconv/matrixfmt" + "go.mau.fi/mautrix-signal/msgconv/signalfmt" + "go.mau.fi/mautrix-signal/pkg/libsignalgo" + "go.mau.fi/mautrix-signal/pkg/signalmeow" + "go.mau.fi/mautrix-signal/pkg/signalmeow/events" + signalpb "go.mau.fi/mautrix-signal/pkg/signalmeow/protobuf" + "go.mau.fi/mautrix-signal/pkg/signalmeow/store" + "go.mau.fi/mautrix-signal/pkg/signalmeow/types" +) + +type SignalConnector struct { + MsgConv *msgconv.MessageConverter + Store *store.Container + Bridge *bridgev2.Bridge +} + +func NewConnector() *SignalConnector { + return &SignalConnector{} +} + +func (s *SignalConnector) Init(bridge *bridgev2.Bridge) { + s.Store = store.NewStore(bridge.DB.Database, dbutil.ZeroLogger(bridge.Log.With().Str("db_section", "signalmeow").Logger())) + s.Bridge = bridge + s.MsgConv = &msgconv.MessageConverter{ + PortalMethods: &msgconvPortalMethods{}, + SignalFmtParams: &signalfmt.FormatParams{ + GetUserInfo: func(ctx context.Context, uuid uuid.UUID) signalfmt.UserInfo { + ghost, err := s.Bridge.GetGhostByID(ctx, makeUserID(uuid)) + if err != nil { + // TODO log? + return signalfmt.UserInfo{} + } + userInfo := signalfmt.UserInfo{ + MXID: ghost.MXID, + Name: ghost.Name, + } + userLogin := s.Bridge.GetCachedUserLoginByID(networkid.UserLoginID(uuid.String())) + if userLogin != nil { + userInfo.MXID = userLogin.UserMXID + // TODO find matrix user displayname? + } + return userInfo + }, + }, + MatrixFmtParams: &matrixfmt.HTMLParser{ + GetUUIDFromMXID: func(ctx context.Context, userID id.UserID) uuid.UUID { + parsed, ok := s.Bridge.Matrix.ParseGhostMXID(userID) + if ok { + u, _ := uuid.Parse(string(parsed)) + return u + } + user, _ := s.Bridge.GetExistingUserByMXID(ctx, userID) + // TODO log errors? + if user != nil { + preferredLogin, _ := ctx.Value(msgconvContextKey).(*msgconvContext).Portal.FindPreferredLogin(ctx, user) + if preferredLogin != nil { + u, _ := uuid.Parse(string(preferredLogin.ID)) + return u + } + } + return uuid.Nil + }, + }, + ConvertVoiceMessages: true, + ConvertGIFToAPNG: true, + MaxFileSize: 100 * 1024 * 1024, + AsyncFiles: true, + LocationFormat: "", + } +} + +func (s *SignalConnector) Start(ctx context.Context) error { + return s.Store.Upgrade(ctx) +} + +var _ bridgev2.NetworkConnector = (*SignalConnector)(nil) +var _ bridgev2.NetworkAPI = (*SignalClient)(nil) +var _ msgconv.PortalMethods = (*msgconvPortalMethods)(nil) + +func (s *SignalConnector) PrepareLogin(ctx context.Context, login *bridgev2.UserLogin) error { + aci, err := uuid.Parse(string(login.ID)) + if err != nil { + return fmt.Errorf("failed to parse user login ID: %w", err) + } + device, err := s.Store.DeviceByACI(ctx, aci) + if err != nil { + return fmt.Errorf("failed to get device from store: %w", err) + } else if device == nil { + return fmt.Errorf("%w: device not found in store", bridgev2.ErrNotLoggedIn) + } + sc := &SignalClient{ + Main: s, + UserLogin: login, + Client: &signalmeow.Client{ + Store: device, + }, + } + sc.Client.EventHandler = sc.handleSignalEvent + login.Client = sc + return nil +} + +type SignalClient struct { + Main *SignalConnector + UserLogin *bridgev2.UserLogin + Client *signalmeow.Client +} + +func (s *SignalClient) GetChatInfo(ctx context.Context, portal *bridgev2.Portal) (*bridgev2.PortalInfo, error) { + return &bridgev2.PortalInfo{}, nil +} + +func (s *SignalClient) Connect(ctx context.Context) error { + _, err := s.Client.StartReceiveLoops(ctx) + if err != nil { + return err + } + // TODO status + return nil +} + +func (s *SignalClient) IsLoggedIn() bool { + return s.Client.IsLoggedIn() +} + +func (s *SignalClient) parsePortalID(portalID networkid.PortalID) (string, error) { + parts := strings.Split(string(portalID), "|") + if len(parts) == 1 { + if len(parts[0]) == 44 { + return parts[0], nil + } + return "", fmt.Errorf("invalid portal ID: expected group ID to be 44 characters") + } else if len(parts) == 2 { + ourACI := s.Client.Store.ACI.String() + if parts[0] == ourACI { + return parts[1], nil + } else if parts[1] == ourACI { + return parts[0], nil + } else { + return "", fmt.Errorf("invalid portal ID: expected one side to be our ACI") + } + } + return "", fmt.Errorf("invalid portal ID: unexpected number of pipe-separated parts") +} + +func (s *SignalClient) getPortalID(chatID string) networkid.PortalID { + if len(chatID) == 44 { + // Group ID + return networkid.PortalID(chatID) + } else if strings.HasPrefix(chatID, "PNI:") { + // Temporary new DM ID: always put our own ACI first, the portal will never be shared anyway + return networkid.PortalID(fmt.Sprintf("%s|%s", s.Client.Store.ACI, chatID)) + } else { + // DM ID: sort the two parts so the ID is always the same regardless of which side is receiving the message + parts := []string{s.Client.Store.ACI.String(), chatID} + slices.Sort(parts) + return networkid.PortalID(strings.Join(parts, "|")) + } +} + +func makeMessageID(sender uuid.UUID, timestamp uint64) networkid.MessageID { + return networkid.MessageID(fmt.Sprintf("%s|%d", sender, timestamp)) +} + +func makeUserID(user uuid.UUID) networkid.UserID { + return networkid.UserID(user.String()) +} + +func makeUserLoginID(user uuid.UUID) networkid.UserLoginID { + return networkid.UserLoginID(user.String()) +} + +func (s *SignalClient) makeEventSender(sender uuid.UUID) bridgev2.EventSender { + return bridgev2.EventSender{ + IsFromMe: sender == s.Client.Store.ACI, + SenderLogin: makeUserLoginID(sender), + Sender: makeUserID(sender), + } +} + +func makeMessagePartID(index int) networkid.PartID { + if index == 0 { + return "" + } + return networkid.PartID(strconv.Itoa(index)) +} + +type contextKey int + +var msgconvContextKey contextKey + +type msgconvContext struct { + Connector *SignalConnector + Intent bridgev2.MatrixAPI + Client *SignalClient + Portal *bridgev2.Portal + ReplyTo *database.Message +} + +func (s *SignalClient) convertMessage(ctx context.Context, portal *bridgev2.Portal, data *events.ChatEvent) (*bridgev2.ConvertedMessage, error) { + dataMsg := data.Event.(*signalpb.DataMessage) + converted := s.Main.MsgConv.ToMatrix(ctx, dataMsg) + var replyTo *networkid.MessageOptionalPartID + if dataMsg.GetQuote() != nil { + quoteAuthor, _ := uuid.Parse(dataMsg.Quote.GetAuthorAci()) + replyTo = &networkid.MessageOptionalPartID{ + MessageID: makeMessageID(quoteAuthor, dataMsg.Quote.GetId()), + } + } + convertedParts := make([]*bridgev2.ConvertedMessagePart, len(converted.Parts)) + for i, part := range converted.Parts { + convertedParts[i] = &bridgev2.ConvertedMessagePart{ + ID: makeMessagePartID(i), + Type: part.Type, + Content: part.Content, + Extra: part.Extra, + } + + } + return &bridgev2.ConvertedMessage{ + ID: makeMessageID(data.Info.Sender, dataMsg.GetTimestamp()), + EventSender: s.makeEventSender(data.Info.Sender), + Timestamp: time.UnixMilli(int64(converted.Timestamp)), + ReplyTo: replyTo, + Parts: convertedParts, + }, nil +} + +func (s *SignalClient) handleSignalEvent(rawEvt events.SignalEvent) { + switch evt := rawEvt.(type) { + case *events.ChatEvent: + switch innerEvt := evt.Event.(type) { + case *signalpb.DataMessage: + s.Main.Bridge.QueueRemoteEvent(s.UserLogin, &bridgev2.SimpleRemoteEvent[*events.ChatEvent]{ + Type: bridgev2.RemoteEventMessage, + LogContext: func(c zerolog.Context) zerolog.Context { + return c. + Uint64("message_id", innerEvt.GetTimestamp()). + Stringer("sender_id", evt.Info.Sender) + }, + PortalID: s.getPortalID(evt.Info.ChatID), + Data: evt, + CreatePortal: true, + + ConvertMessageFunc: s.convertMessage, + }) + case *signalpb.EditMessage: + case *signalpb.TypingMessage: + } + case *events.DecryptionError: + case *events.Receipt: + case *events.ReadSelf: + case *events.Call: + case *events.ContactList: + case *events.ACIFound: + } +} + +func (s *SignalClient) HandleMatrixMessage(ctx context.Context, msg *bridgev2.MatrixMessage) (message *database.Message, err error) { + mcCtx := &msgconvContext{ + Connector: s.Main, + Intent: nil, + Client: s, + Portal: msg.Portal, + ReplyTo: msg.ReplyTo, + } + ctx = context.WithValue(ctx, msgconvContextKey, mcCtx) + chatID, err := s.parsePortalID(msg.Portal.ID) + if err != nil { + return nil, err + } + var userID libsignalgo.ServiceID + var groupID types.GroupIdentifier + if len(chatID) == 44 { + groupID = types.GroupIdentifier(chatID) + } else { + userID, err = libsignalgo.ServiceIDFromString(chatID) + if err != nil { + return nil, err + } + } + converted, err := s.Main.MsgConv.ToSignal(ctx, msg.Event, msg.Content, msg.OrigSender != nil) + if err != nil { + return nil, err + } + wrappedContent := &signalpb.Content{ + DataMessage: converted, + } + if groupID != "" { + res, err := s.Client.SendGroupMessage(ctx, groupID, wrappedContent) + if err != nil { + return nil, err + } + // TODO check result + fmt.Println(res) + } else { + res := s.Client.SendMessage(ctx, userID, wrappedContent) + // TODO check result + fmt.Println(res) + } + meta := map[string]any{ + "reply_to_file": len(converted.Attachments) > 0, + } + dbMsg := &database.Message{ + ID: makeMessageID(s.Client.Store.ACI, converted.GetTimestamp()), + MXID: msg.Event.ID, + RoomID: msg.Portal.ID, + SenderID: makeUserID(s.Client.Store.ACI), + Timestamp: time.UnixMilli(int64(converted.GetTimestamp())), + Metadata: meta, + } + if msg.ReplyTo != nil { + dbMsg.RelatesToRowID = msg.ReplyTo.RowID + } + return dbMsg, nil +} + +func (s *SignalClient) HandleMatrixEdit(ctx context.Context, msg *bridgev2.MatrixEdit) error { + //TODO implement me + panic("implement me") +} + +func (s *SignalClient) HandleMatrixReaction(ctx context.Context, msg *bridgev2.MatrixReaction) (emojiID networkid.EmojiID, err error) { + //TODO implement me + panic("implement me") +} + +func (s *SignalClient) HandleMatrixReactionRemove(ctx context.Context, msg *bridgev2.MatrixReactionRemove) error { + //TODO implement me + panic("implement me") +} + +func (s *SignalClient) HandleMatrixMessageRemove(ctx context.Context, msg *bridgev2.MatrixMessageRemove) error { + //TODO implement me + panic("implement me") +} + +type msgconvPortalMethods struct{} + +func (mpm *msgconvPortalMethods) UploadMatrixMedia(ctx context.Context, data []byte, fileName, contentType string) (id.ContentURIString, error) { + mcCtx := ctx.Value(msgconvContextKey).(*msgconvContext) + uri, _, err := mcCtx.Intent.UploadMedia(ctx, "", data, fileName, contentType) + return uri, err +} + +func (mpm *msgconvPortalMethods) DownloadMatrixMedia(ctx context.Context, uri id.ContentURIString) ([]byte, error) { + return ctx.Value(msgconvContextKey).(*msgconvContext).Connector.Bridge.Bot.DownloadMedia(ctx, uri, nil) +} + +func (mpm *msgconvPortalMethods) GetMatrixReply(ctx context.Context, msg *signalpb.DataMessage_Quote) (replyTo id.EventID, replyTargetSender id.UserID) { + // Matrix replies are handled in bridgev2 code + return "", "" +} + +func (mpm *msgconvPortalMethods) GetSignalReply(ctx context.Context, content *event.MessageEventContent) *signalpb.DataMessage_Quote { + mcCtx := ctx.Value(msgconvContextKey).(*msgconvContext) + if mcCtx.ReplyTo == nil { + return nil + } + quote := &signalpb.DataMessage_Quote{ + Id: proto.Uint64(uint64(mcCtx.ReplyTo.Timestamp.UnixMilli())), + AuthorAci: proto.String(string(mcCtx.ReplyTo.SenderID)), + Type: signalpb.DataMessage_Quote_NORMAL.Enum(), + } + if mcCtx.ReplyTo.Metadata["reply_to_file"] != false { + quote.Attachments = make([]*signalpb.DataMessage_Quote_QuotedAttachment, 1) + } + return quote +} + +func (mpm *msgconvPortalMethods) GetClient(ctx context.Context) *signalmeow.Client { + return ctx.Value(msgconvContextKey).(*msgconvContext).Client.Client +} + +func (mpm *msgconvPortalMethods) GetData(ctx context.Context) *legacydb.Portal { + mcCtx := ctx.Value(msgconvContextKey).(*msgconvContext) + portal := mcCtx.Portal + chatID, _ := mcCtx.Client.parsePortalID(portal.ID) + pk := legacydb.PortalKey{ + ChatID: chatID, + } + if len(chatID) != 44 { + pk.Receiver = mcCtx.Client.Client.Store.ACI + } + return &legacydb.Portal{ + PortalKey: pk, + MXID: portal.MXID, + Name: portal.Name, + Topic: portal.Topic, + //AvatarPath: "", + //AvatarHash: "", + //AvatarURL: id.ContentURI{}, + NameSet: portal.NameSet, + AvatarSet: portal.AvatarSet, + TopicSet: portal.TopicSet, + //Revision: portal.Metadata["revision"].(uint32), + Encrypted: true, + //RelayUserID: portal.Relay.UserMXID, + //ExpirationTime: portal.Metadata["expiration_timer"].(uint32), + } +} diff --git a/connector/mautrix-signal-v2/main.go b/connector/mautrix-signal-v2/main.go new file mode 100644 index 0000000..929a9c1 --- /dev/null +++ b/connector/mautrix-signal-v2/main.go @@ -0,0 +1,207 @@ +// mautrix-signal - A Matrix-Signal puppeting bridge. +// Copyright (C) 2024 Tulir Asokan +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +package main + +import ( + "fmt" + "os" + "strings" + "time" + + "github.com/google/uuid" + "github.com/skip2/go-qrcode" + "go.mau.fi/util/dbutil" + "go.mau.fi/util/exerrors" + "go.mau.fi/util/exzerolog" + "gopkg.in/yaml.v3" + + "go.mau.fi/mautrix-signal/pkg/signalmeow" + "maunium.net/go/mautrix/bridgev2" + "maunium.net/go/mautrix/bridgev2/bridgeconfig" + "maunium.net/go/mautrix/bridgev2/database" + "maunium.net/go/mautrix/bridgev2/matrix" + "maunium.net/go/mautrix/bridgev2/networkid" + "maunium.net/go/mautrix/event" + "maunium.net/go/mautrix/id" + + "go.mau.fi/mautrix-signal/connector" +) + +func main() { + var cfg bridgeconfig.Config + config := exerrors.Must(os.ReadFile("config.yaml")) + exerrors.PanicIfNotNil(yaml.Unmarshal(config, &cfg)) + log := exerrors.Must(cfg.Logging.Compile()) + exzerolog.SetupDefaults(log) + db := exerrors.Must(dbutil.NewFromConfig("mautrix-signal", cfg.Database, dbutil.ZeroLogger(log.With().Str("db_section", "main").Logger()))) + bridge := bridgev2.NewBridge("", db, *log, matrix.NewConnector(&cfg), connector.NewConnector()) + bridge.CommandPrefix = "!signal" + bridge.Commands.AddHandlers(&bridgev2.FullHandler{ + Func: fnLogin, + Name: "login", + Help: bridgev2.HelpMeta{ + Section: bridgev2.HelpSectionAuth, + Description: "Log into Signal", + }, + }) + bridge.Start() +} + +func sendQR(ce *bridgev2.CommandEvent, code string, prevQR, prevMsg id.EventID) (qr, msg id.EventID) { + content, ok := uploadQR(ce, code) + if !ok { + return prevQR, prevMsg + } + if len(prevQR) != 0 { + content.SetEdit(prevQR) + } + resp, err := ce.Bot.SendMessage(ce.Ctx, ce.RoomID, event.EventMessage, &event.Content{Parsed: &content}, time.Now()) + if err != nil { + ce.Log.Err(err).Msg("Failed to send QR code to user") + } else if len(prevQR) == 0 { + prevQR = resp.EventID + } + content = event.MessageEventContent{ + MsgType: event.MsgNotice, + Body: fmt.Sprintf("Raw linking URI: %s", code), + Format: event.FormatHTML, + FormattedBody: fmt.Sprintf("Raw linking URI: %s", code), + } + if len(prevMsg) != 0 { + content.SetEdit(prevMsg) + } + resp, err = ce.Bot.SendMessage(ce.Ctx, ce.RoomID, event.EventMessage, &event.Content{Parsed: &content}, time.Now()) + if err != nil { + ce.Log.Err(err).Msg("Failed to send raw code to user") + } else if len(prevMsg) == 0 { + prevMsg = resp.EventID + } + return prevQR, prevMsg +} + +func uploadQR(ce *bridgev2.CommandEvent, code string) (event.MessageEventContent, bool) { + const size = 512 + qrCode, err := qrcode.Encode(code, qrcode.Low, size) + if err != nil { + ce.Log.Err(err).Msg("Failed to encode QR code") + ce.Reply("Failed to encode QR code: %v", err) + return event.MessageEventContent{}, false + } + + uri, file, err := ce.Bot.UploadMedia(ce.Ctx, ce.RoomID, qrCode, "qr.png", "image/png") + if err != nil { + ce.Log.Err(err).Msg("Failed to upload QR code") + ce.Reply("Failed to upload QR code: %v", err) + return event.MessageEventContent{}, false + } + return event.MessageEventContent{ + MsgType: event.MsgImage, + Info: &event.FileInfo{ + MimeType: "image/png", + Width: size, + Height: size, + Size: len(qrCode), + }, + Body: "qr.png", + URL: uri, + File: file, + }, true +} +func fnLogin(ce *bridgev2.CommandEvent) { + signal := ce.Bridge.Network.(*connector.SignalConnector) + // TODO configurable device name + provChan := signalmeow.PerformProvisioning(ce.Ctx, signal.Store, "Mautrix-Signal Megabridge") + + resp := <-provChan + if resp.Err != nil || resp.State == signalmeow.StateProvisioningError { + ce.Reply("Error getting provisioning URL: %v", resp.Err) + return + } + var qrEventID, msgEventID id.EventID + if resp.State == signalmeow.StateProvisioningURLReceived { + qrEventID, msgEventID = sendQR(ce, resp.ProvisioningURL, qrEventID, msgEventID) + } else { + ce.Reply("Unexpected state: %v", resp.State) + return + } + + // Next, get the results of finishing registration + resp = <-provChan + _, _ = ce.Bot.SendMessage(ce.Ctx, ce.RoomID, event.EventRedaction, &event.Content{ + Parsed: &event.RedactionEventContent{ + Redacts: qrEventID, + }, + }, time.Now()) + _, _ = ce.Bot.SendMessage(ce.Ctx, ce.RoomID, event.EventRedaction, &event.Content{ + Parsed: &event.RedactionEventContent{ + Redacts: msgEventID, + }, + }, time.Now()) + if resp.Err != nil || resp.State == signalmeow.StateProvisioningError { + if resp.Err != nil && strings.HasSuffix(resp.Err.Error(), " EOF") { + ce.Reply("Logging in timed out, please try again.") + } else { + ce.Reply("Error finishing registration: %v", resp.Err) + } + return + } + var signalID uuid.UUID + var signalPhone string + if resp.State == signalmeow.StateProvisioningDataReceived { + signalID = resp.ProvisioningData.ACI + signalPhone = resp.ProvisioningData.Number + } else { + ce.Reply("Unexpected state: %v", resp.State) + return + } + + // Finally, get the results of generating and registering prekeys + resp = <-provChan + if resp.Err != nil || resp.State == signalmeow.StateProvisioningError { + ce.Reply("Error with prekeys: %v", resp.Err) + return + } else if resp.State != signalmeow.StateProvisioningPreKeysRegistered { + ce.Reply("Unexpected state: %v", resp.State) + return + } + + if signalID == uuid.Nil { + ce.Reply("Problem logging in - No SignalID received") + return + } + ul, err := ce.User.NewLogin(ce.Ctx, &database.UserLogin{ + ID: networkid.UserLoginID(signalID.String()), + Metadata: map[string]any{ + "phone": signalPhone, + }, + }, nil) + if err != nil { + ce.Reply("Failed to save new login: %v", err) + return + } + err = ce.Bridge.Network.PrepareLogin(ce.Ctx, ul) + if err != nil { + ce.Reply("Failed to prepare connection after login: %v", err) + return + } + err = ul.Client.Connect(ce.Ctx) + if err != nil { + ce.Reply("Failed to connect after login: %v", err) + return + } + ce.Reply("Successfully logged in as %s (UUID: %s)", signalPhone, signalID) +} diff --git a/connector/mautrix-signal-v2/start b/connector/mautrix-signal-v2/start new file mode 100755 index 0000000..85c97d1 --- /dev/null +++ b/connector/mautrix-signal-v2/start @@ -0,0 +1,6 @@ +#!/bin/bash +export LIBRARY_PATH=$(dirname $(dirname $(pwd))):$LIBRARY_PATH +export MAUTRIX_VERSION=$(cat ../../go.mod | grep 'maunium.net/go/mautrix ' | head -n1 | awk '{ print $2 }') +go install -ldflags "-X main.Tag=$(git describe --exact-match --tags 2>/dev/null) -X main.Commit=$(git rev-parse HEAD) -X 'main.BuildTime=`date '+%b %_d %Y, %H:%M:%S'`' -X 'maunium.net/go/mautrix.GoModVersion=$MAUTRIX_VERSION'" || exit 2 +mkdir -p logs +mautrix-signal-v2 "$@" diff --git a/go.mod b/go.mod index bf3fd25..8743805 100644 --- a/go.mod +++ b/go.mod @@ -15,12 +15,13 @@ require ( github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e github.com/stretchr/testify v1.9.0 github.com/tidwall/gjson v1.17.1 - go.mau.fi/util v0.4.2 + go.mau.fi/util v0.4.3-0.20240516141139-2ebe792cd8f7 golang.org/x/crypto v0.23.0 - golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842 + golang.org/x/exp v0.0.0-20240525044651-4c93da0ed11d golang.org/x/net v0.25.0 google.golang.org/protobuf v1.34.1 - maunium.net/go/mautrix v0.18.1 + gopkg.in/yaml.v3 v3.0.1 + maunium.net/go/mautrix v0.18.2-0.20240527105318-9254a5d6c1d9 nhooyr.io/websocket v1.8.11 ) @@ -45,6 +46,5 @@ require ( go.mau.fi/zeroconfig v0.1.2 // indirect golang.org/x/sys v0.20.0 // indirect gopkg.in/natefinch/lumberjack.v2 v2.2.1 // indirect - gopkg.in/yaml.v3 v3.0.1 // indirect maunium.net/go/mauflag v1.0.0 // indirect ) diff --git a/go.sum b/go.sum index 30dea68..f68078a 100644 --- a/go.sum +++ b/go.sum @@ -69,14 +69,14 @@ github.com/tidwall/sjson v1.2.5 h1:kLy8mja+1c9jlljvWTlSazM7cKDRfJuR/bOJhcY5NcY= github.com/tidwall/sjson v1.2.5/go.mod h1:Fvgq9kS/6ociJEDnK0Fk1cpYF4FIW6ZF7LAe+6jwd28= github.com/yuin/goldmark v1.7.1 h1:3bajkSilaCbjdKVsKdZjZCLBNPL9pYzrCakKaf4U49U= github.com/yuin/goldmark v1.7.1/go.mod h1:uzxRWxtg69N339t3louHJ7+O03ezfj6PlliRlaOzY1E= -go.mau.fi/util v0.4.2 h1:RR3TOcRHmCF9Bx/3YG4S65MYfa+nV6/rn8qBWW4Mi30= -go.mau.fi/util v0.4.2/go.mod h1:PlAVfUUcPyHPrwnvjkJM9UFcPE7qGPDJqk+Oufa1Gtw= +go.mau.fi/util v0.4.3-0.20240516141139-2ebe792cd8f7 h1:2hnc2iS7usHT3aqIQ8HVtKtPgic+13EVSdZ1m8UBL/E= +go.mau.fi/util v0.4.3-0.20240516141139-2ebe792cd8f7/go.mod h1:m+PJpPMadAW6cj3ldyuO5bLhFreWdwcu+3QTwYNGlGk= go.mau.fi/zeroconfig v0.1.2 h1:DKOydWnhPMn65GbXZOafgkPm11BvFashZWLct0dGFto= go.mau.fi/zeroconfig v0.1.2/go.mod h1:NcSJkf180JT+1IId76PcMuLTNa1CzsFFZ0nBygIQM70= golang.org/x/crypto v0.23.0 h1:dIJU/v2J8Mdglj/8rJ6UUOM3Zc9zLZxVZwwxMooUSAI= golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8= -golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842 h1:vr/HnozRka3pE4EsMEg1lgkXJkTFJCVUX+S/ZT6wYzM= -golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842/go.mod h1:XtvwrStGgqGPLc4cjQfWqZHG1YFdYs6swckp8vpsjnc= +golang.org/x/exp v0.0.0-20240525044651-4c93da0ed11d h1:N0hmiNbwsSNwHBAvR3QB5w25pUwH4tK0Y/RltD1j1h4= +golang.org/x/exp v0.0.0-20240525044651-4c93da0ed11d/go.mod h1:XtvwrStGgqGPLc4cjQfWqZHG1YFdYs6swckp8vpsjnc= golang.org/x/net v0.25.0 h1:d/OCCoBEUq33pjydKrGQhw7IlUPI2Oylr+8qLx49kac= golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -95,7 +95,7 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= maunium.net/go/mauflag v1.0.0 h1:YiaRc0tEI3toYtJMRIfjP+jklH45uDHtT80nUamyD4M= maunium.net/go/mauflag v1.0.0/go.mod h1:nLivPOpTpHnpzEh8jEdSL9UqO9+/KBJFmNRlwKfkPeA= -maunium.net/go/mautrix v0.18.1 h1:a6mUsJixegBNTXUoqC5RQ9gsumIPzKvCubKwF+zmCt4= -maunium.net/go/mautrix v0.18.1/go.mod h1:2oHaq792cSXFGvxLvYw3Gf1L4WVVP4KZcYys5HVk/h8= +maunium.net/go/mautrix v0.18.2-0.20240527105318-9254a5d6c1d9 h1:pRnJkxSjLsJSWON0yWzHNDyQqeebvgCeRXzozntEj/0= +maunium.net/go/mautrix v0.18.2-0.20240527105318-9254a5d6c1d9/go.mod h1:Ln4XquIKL5MttTUGNUSbiEGX3XYC0P6jzT9XjLFFPdY= nhooyr.io/websocket v1.8.11 h1:f/qXNc2/3DpoSZkHt1DQu6rj4zGC8JmkkLkWss0MgN0= nhooyr.io/websocket v1.8.11/go.mod h1:rN9OFWIUwuxg4fR5tELlYC04bXYowCP9GX47ivo2l+c= From e5e3dd1abcee154bce3bafa63903ac0d8f6a595b Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Tue, 28 May 2024 20:52:07 +0300 Subject: [PATCH 024/580] Add initial user and room metadata support --- commands.go | 2 +- connector/connector.go | 155 +++++++++++++++++++++++++++++++++++------ go.mod | 2 +- go.sum | 4 +- portal.go | 15 ++-- user.go | 2 +- 6 files changed, 148 insertions(+), 32 deletions(-) diff --git a/commands.go b/commands.go index 728f2d6..e3021c0 100644 --- a/commands.go +++ b/commands.go @@ -989,7 +989,7 @@ func fnCreate(ce *WrappedCommandEvent) { avatarSet := false if ok { roomAvatarEvent.Content.ParseRaw(event.StateRoomAvatar) - avatarURL = roomAvatarEvent.Content.AsRoomAvatar().URL + avatarURL = roomAvatarEvent.Content.AsRoomAvatar().URL.ParseOrIgnore() if !avatarURL.IsEmpty() { avatarBytes, err = ce.Bot.DownloadBytes(ce.Ctx, avatarURL) if err != nil { diff --git a/connector/connector.go b/connector/connector.go index 9667ae5..770259c 100644 --- a/connector/connector.go +++ b/connector/connector.go @@ -145,8 +145,115 @@ type SignalClient struct { Client *signalmeow.Client } +func (s *SignalClient) contactToUserInfo(contact *types.Recipient) *bridgev2.UserInfo { + isBot := false + ui := &bridgev2.UserInfo{ + IsBot: &isBot, + } + // TODO use template for name + if contact.ContactName != "" { + ui.Name = &contact.ContactName + } else if contact.Profile.Name != "" { + ui.Name = &contact.Profile.Name + } else if contact.E164 != "" { + ui.Name = &contact.E164 + } + // TODO only use this if contact avatars are allowed + if contact.ContactAvatar.Hash != "" { + ui.Avatar = &bridgev2.Avatar{ + ID: networkid.AvatarID("hash:" + contact.ContactAvatar.Hash), + Get: func(ctx context.Context) ([]byte, error) { + if contact.ContactAvatar.Image == nil { + return nil, fmt.Errorf("contact avatar not available") + } + return contact.ContactAvatar.Image, nil + }, + } + } else if contact.Profile.AvatarPath != "" { + ui.Avatar = &bridgev2.Avatar{ + ID: makeAvatarPathID(contact.Profile.AvatarPath), + Get: func(ctx context.Context) ([]byte, error) { + return s.Client.DownloadUserAvatar(ctx, contact.Profile.AvatarPath, contact.Profile.Key) + }, + } + } else { + ui.Avatar = &bridgev2.Avatar{ + ID: "", + Remove: true, + } + } + return ui +} + +func (s *SignalClient) GetUserInfo(ctx context.Context, ghost *bridgev2.Ghost) (*bridgev2.UserInfo, error) { + userID, err := parseUserID(ghost.ID) + if err != nil { + return nil, err + } + contact, err := s.Client.ContactByACI(ctx, userID) + if err != nil { + return nil, err + } + return s.contactToUserInfo(contact), nil +} + +func makeAvatarPathID(avatarPath string) networkid.AvatarID { + if avatarPath == "" { + return "" + } + return networkid.AvatarID("path:" + avatarPath) +} + func (s *SignalClient) GetChatInfo(ctx context.Context, portal *bridgev2.Portal) (*bridgev2.PortalInfo, error) { - return &bridgev2.PortalInfo{}, nil + userID, groupID, err := s.parsePortalID(portal.ID) + if err != nil { + return nil, err + } + isSpace := false + if groupID != "" { + groupInfo, err := s.Client.RetrieveGroupByID(ctx, groupID, 0) + if err != nil { + return nil, err + } + isDM := false + members := make([]networkid.UserID, len(groupInfo.Members)) + for i, member := range groupInfo.Members { + members[i] = makeUserID(member.ACI) + } + return &bridgev2.PortalInfo{ + Name: &groupInfo.Title, + Topic: &groupInfo.Description, + Avatar: &bridgev2.Avatar{ + ID: makeAvatarPathID(groupInfo.AvatarPath), + Get: func(ctx context.Context) ([]byte, error) { + return s.Client.DownloadGroupAvatar(ctx, groupInfo) + }, + Remove: groupInfo.AvatarPath == "", + }, + Members: members, + IsDirectChat: &isDM, + IsSpace: &isSpace, + }, nil + } else if userID.Type == libsignalgo.ServiceIDTypePNI { + isDM := true + // TODO set name/avatar because we don't have the recipient user ID + return &bridgev2.PortalInfo{ + Members: []networkid.UserID{makeUserID(s.Client.Store.ACI)}, + IsDirectChat: &isDM, + IsSpace: &isSpace, + }, nil + } else { + isDM := true + return &bridgev2.PortalInfo{ + Members: []networkid.UserID{makeUserID(userID.UUID), makeUserID(s.Client.Store.ACI)}, + IsDirectChat: &isDM, + IsSpace: &isSpace, + }, nil + } +} + +func (s *SignalClient) IsThisUser(_ context.Context, userID networkid.UserID) bool { + return userID == makeUserID(s.Client.Store.ACI) } func (s *SignalClient) Connect(ctx context.Context) error { @@ -162,24 +269,31 @@ func (s *SignalClient) IsLoggedIn() bool { return s.Client.IsLoggedIn() } -func (s *SignalClient) parsePortalID(portalID networkid.PortalID) (string, error) { +func parseUserID(userID networkid.UserID) (uuid.UUID, error) { + return uuid.Parse(string(userID)) +} + +func (s *SignalClient) parsePortalID(portalID networkid.PortalID) (userID libsignalgo.ServiceID, groupID types.GroupIdentifier, err error) { parts := strings.Split(string(portalID), "|") if len(parts) == 1 { if len(parts[0]) == 44 { - return parts[0], nil + groupID = types.GroupIdentifier(parts[0]) + } else { + err = fmt.Errorf("invalid portal ID: expected group ID to be 44 characters") } - return "", fmt.Errorf("invalid portal ID: expected group ID to be 44 characters") } else if len(parts) == 2 { ourACI := s.Client.Store.ACI.String() if parts[0] == ourACI { - return parts[1], nil + userID, err = libsignalgo.ServiceIDFromString(parts[1]) } else if parts[1] == ourACI { - return parts[0], nil + userID, err = libsignalgo.ServiceIDFromString(parts[0]) } else { - return "", fmt.Errorf("invalid portal ID: expected one side to be our ACI") + err = fmt.Errorf("invalid portal ID: expected one side to be our ACI") } + } else { + err = fmt.Errorf("invalid portal ID: unexpected number of pipe-separated parts") } - return "", fmt.Errorf("invalid portal ID: unexpected number of pipe-separated parts") + return } func (s *SignalClient) getPortalID(chatID string) networkid.PortalID { @@ -237,6 +351,13 @@ type msgconvContext struct { } func (s *SignalClient) convertMessage(ctx context.Context, portal *bridgev2.Portal, data *events.ChatEvent) (*bridgev2.ConvertedMessage, error) { + mcCtx := &msgconvContext{ + Connector: s.Main, + Intent: s.Main.Bridge.Bot, // TODO get correct intent? + Client: s, + Portal: portal, + } + ctx = context.WithValue(ctx, msgconvContextKey, mcCtx) dataMsg := data.Event.(*signalpb.DataMessage) converted := s.Main.MsgConv.ToMatrix(ctx, dataMsg) var replyTo *networkid.MessageOptionalPartID @@ -304,20 +425,10 @@ func (s *SignalClient) HandleMatrixMessage(ctx context.Context, msg *bridgev2.Ma ReplyTo: msg.ReplyTo, } ctx = context.WithValue(ctx, msgconvContextKey, mcCtx) - chatID, err := s.parsePortalID(msg.Portal.ID) + userID, groupID, err := s.parsePortalID(msg.Portal.ID) if err != nil { return nil, err } - var userID libsignalgo.ServiceID - var groupID types.GroupIdentifier - if len(chatID) == 44 { - groupID = types.GroupIdentifier(chatID) - } else { - userID, err = libsignalgo.ServiceIDFromString(chatID) - if err != nil { - return nil, err - } - } converted, err := s.Main.MsgConv.ToSignal(ctx, msg.Event, msg.Content, msg.OrigSender != nil) if err != nil { return nil, err @@ -414,7 +525,11 @@ func (mpm *msgconvPortalMethods) GetClient(ctx context.Context) *signalmeow.Clie func (mpm *msgconvPortalMethods) GetData(ctx context.Context) *legacydb.Portal { mcCtx := ctx.Value(msgconvContextKey).(*msgconvContext) portal := mcCtx.Portal - chatID, _ := mcCtx.Client.parsePortalID(portal.ID) + userID, groupID, _ := mcCtx.Client.parsePortalID(portal.ID) + chatID := string(groupID) + if chatID == "" { + chatID = userID.String() + } pk := legacydb.PortalKey{ ChatID: chatID, } diff --git a/go.mod b/go.mod index 8743805..22b07b3 100644 --- a/go.mod +++ b/go.mod @@ -21,7 +21,7 @@ require ( golang.org/x/net v0.25.0 google.golang.org/protobuf v1.34.1 gopkg.in/yaml.v3 v3.0.1 - maunium.net/go/mautrix v0.18.2-0.20240527105318-9254a5d6c1d9 + maunium.net/go/mautrix v0.18.2-0.20240528174923-3c7b3e13efe4 nhooyr.io/websocket v1.8.11 ) diff --git a/go.sum b/go.sum index f68078a..4d6c887 100644 --- a/go.sum +++ b/go.sum @@ -95,7 +95,7 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= maunium.net/go/mauflag v1.0.0 h1:YiaRc0tEI3toYtJMRIfjP+jklH45uDHtT80nUamyD4M= maunium.net/go/mauflag v1.0.0/go.mod h1:nLivPOpTpHnpzEh8jEdSL9UqO9+/KBJFmNRlwKfkPeA= -maunium.net/go/mautrix v0.18.2-0.20240527105318-9254a5d6c1d9 h1:pRnJkxSjLsJSWON0yWzHNDyQqeebvgCeRXzozntEj/0= -maunium.net/go/mautrix v0.18.2-0.20240527105318-9254a5d6c1d9/go.mod h1:Ln4XquIKL5MttTUGNUSbiEGX3XYC0P6jzT9XjLFFPdY= +maunium.net/go/mautrix v0.18.2-0.20240528174923-3c7b3e13efe4 h1:b+pK+EJL2XsweSKlwhd8eeqD4v395dKrcJZmCFTBmBY= +maunium.net/go/mautrix v0.18.2-0.20240528174923-3c7b3e13efe4/go.mod h1:Ln4XquIKL5MttTUGNUSbiEGX3XYC0P6jzT9XjLFFPdY= nhooyr.io/websocket v1.8.11 h1:f/qXNc2/3DpoSZkHt1DQu6rj4zGC8JmkkLkWss0MgN0= nhooyr.io/websocket v1.8.11/go.mod h1:rN9OFWIUwuxg4fR5tELlYC04bXYowCP9GX47ivo2l+c= diff --git a/portal.go b/portal.go index 2e90ac7..b0ba635 100644 --- a/portal.go +++ b/portal.go @@ -1765,7 +1765,7 @@ func (portal *Portal) CreateMatrixRoom(ctx context.Context, user *User, groupRev initialState = append(initialState, &event.Event{ Type: event.StateRoomAvatar, Content: event.Content{Parsed: &event.RoomAvatarEventContent{ - URL: portal.AvatarURL, + URL: portal.AvatarURL.CUString(), }}, }) } @@ -2910,17 +2910,18 @@ func (portal *Portal) HandleMatrixMeta(brSender bridge.User, evt *event.Event) { portal.Topic = content.Topic groupChange.ModifyDescription = &content.Topic case *event.RoomAvatarEventContent: - if content.URL == portal.AvatarURL { + url := content.URL.ParseOrIgnore() + if url == portal.AvatarURL { return } var data []byte - if !content.URL.IsEmpty() { - data, err = portal.MainIntent().DownloadBytes(ctx, content.URL) + if !url.IsEmpty() { + data, err = portal.MainIntent().DownloadBytes(ctx, url) if err != nil { - log.Err(err).Stringer("Failed to download updated avatar %s", content.URL) + log.Err(err).Stringer("Failed to download updated avatar %s", url) return } - log.Debug().Stringers("%s set the group avatar to %s", []fmt.Stringer{sender.MXID, content.URL}) + log.Debug().Stringers("%s set the group avatar to %s", []fmt.Stringer{sender.MXID, url}) } else { log.Debug().Stringer("%s removed the group avatar", sender.MXID) } @@ -2933,7 +2934,7 @@ func (portal *Portal) HandleMatrixMeta(brSender bridge.User, evt *event.Event) { hash := sha256.Sum256(data) avatarHash = hex.EncodeToString(hash[:]) avatarChanged = true - avatarURL = content.URL + avatarURL = url } revision, err := sender.Client.UpdateGroup(ctx, groupChange, portal.GroupID()) if err != nil { diff --git a/user.go b/user.go index a579e8b..0a72b05 100644 --- a/user.go +++ b/user.go @@ -292,7 +292,7 @@ func (user *User) GetSpaceRoom(ctx context.Context) id.RoomID { Type: event.StateRoomAvatar, Content: event.Content{ Parsed: &event.RoomAvatarEventContent{ - URL: user.bridge.Config.AppService.Bot.ParsedAvatar, + URL: user.bridge.Config.AppService.Bot.ParsedAvatar.CUString(), }, }, }}, From b3e881ce471c7b7d8d3b9a605e4296f265331390 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Wed, 29 May 2024 15:09:06 +0300 Subject: [PATCH 025/580] Fix contact avatars --- connector/connector.go | 22 ++++++++++++++++++++++ portal.go | 8 ++++---- puppet.go | 5 ++++- user.go | 2 +- 4 files changed, 31 insertions(+), 6 deletions(-) diff --git a/connector/connector.go b/connector/connector.go index 770259c..f332dc5 100644 --- a/connector/connector.go +++ b/connector/connector.go @@ -412,10 +412,32 @@ func (s *SignalClient) handleSignalEvent(rawEvt events.SignalEvent) { case *events.ReadSelf: case *events.Call: case *events.ContactList: + s.handleSignalContactList(evt) case *events.ACIFound: } } +func (s *SignalClient) handleSignalContactList(evt *events.ContactList) { + log := s.UserLogin.Log.With().Str("action", "handle contact list").Logger() + ctx := log.WithContext(context.TODO()) + for _, contact := range evt.Contacts { + if contact.ACI != uuid.Nil { + fullContact, err := s.Client.ContactByACI(ctx, contact.ACI) + if err != nil { + log.Err(err).Msg("Failed to get full contact info from store") + continue + } + fullContact.ContactAvatar = contact.ContactAvatar + ghost, err := s.Main.Bridge.GetGhostByID(ctx, makeUserID(contact.ACI)) + if err != nil { + log.Err(err).Msg("Failed to get ghost to update contact info") + continue + } + ghost.UpdateInfo(ctx, s.contactToUserInfo(contact)) + } + } +} + func (s *SignalClient) HandleMatrixMessage(ctx context.Context, msg *bridgev2.MatrixMessage) (message *database.Message, err error) { mcCtx := &msgconvContext{ Connector: s.Main, diff --git a/portal.go b/portal.go index b0ba635..0369c04 100644 --- a/portal.go +++ b/portal.go @@ -892,7 +892,7 @@ func (portal *Portal) handleSignalDataMessage(source *User, sender *Puppet, msg Uint64("msg_ts", msg.GetTimestamp()). Logger().WithContext(context.TODO()) // Always update sender info when we receive a message from them, there's caching inside the function - sender.UpdateInfo(genericCtx, source) + sender.UpdateInfo(genericCtx, source, nil) // Handle earlier missed group changes here. if msg.GetGroupV2() != nil { requiredRevision := msg.GetGroupV2().GetRevision() @@ -1800,7 +1800,7 @@ func (portal *Portal) CreateMatrixRoom(ctx context.Context, user *User, groupRev if portal.IsPrivateChat() { dmPuppet = portal.GetDMPuppet() if dmPuppet != nil { - dmPuppet.UpdateInfo(ctx, user) + dmPuppet.UpdateInfo(ctx, user, nil) portal.UpdateDMInfo(ctx, false) } else { portal.UpdatePNIDMInfo(ctx, user) @@ -1900,7 +1900,7 @@ func (portal *Portal) PostReIDUpdate(ctx context.Context, user *User) { if err != nil { zerolog.Ctx(ctx).Err(err).Msg("Failed to update ghost power level after portal re-ID") } - portal.GetDMPuppet().UpdateInfo(ctx, user) + portal.GetDMPuppet().UpdateInfo(ctx, user, nil) portal.UpdateDMInfo(ctx, true) if !portal.Encrypted { _, _ = portal.bridge.Bot.LeaveRoom(ctx, portal.MXID) @@ -2298,7 +2298,7 @@ func (portal *Portal) SyncParticipants(ctx context.Context, source *User, info * log.Warn().Stringer("signal_user_id", member.ACI).Msg("Couldn't get puppet for group member") continue } - puppet.UpdateInfo(ctx, source) + puppet.UpdateInfo(ctx, source, nil) intent := puppet.IntentFor(portal) if member.ACI != source.SignalID && portal.MXID != "" { userIDs[intent.UserID] = ((int)(member.Role) >> 1) * 50 diff --git a/puppet.go b/puppet.go index f58befa..857312e 100644 --- a/puppet.go +++ b/puppet.go @@ -232,7 +232,7 @@ func (puppet *Puppet) GetAvatarURL() id.ContentURI { return puppet.AvatarURL } -func (puppet *Puppet) UpdateInfo(ctx context.Context, source *User) { +func (puppet *Puppet) UpdateInfo(ctx context.Context, source *User, contactAvatar *types.ContactAvatar) { log := zerolog.Ctx(ctx).With(). Str("function", "Puppet.UpdateInfo"). Stringer("signal_user_id", puppet.SignalID). @@ -252,6 +252,9 @@ func (puppet *Puppet) UpdateInfo(ctx context.Context, source *User) { Msg("Ignoring outdated contact info") return } + if contactAvatar != nil { + info.ContactAvatar = *contactAvatar + } log.Trace().Msg("Updating puppet info") diff --git a/user.go b/user.go index 0a72b05..dc16f98 100644 --- a/user.go +++ b/user.go @@ -755,7 +755,7 @@ func (user *User) handleContactList(evt *events.ContactList) { if puppet == nil { continue } - puppet.UpdateInfo(ctx, user) + puppet.UpdateInfo(ctx, user, &contact.ContactAvatar) } } From 954da8480caa7b4c29364634cb3e307b0d815ee1 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Wed, 29 May 2024 20:46:28 +0300 Subject: [PATCH 026/580] Add connector config --- connector/connector.go | 83 ++++++++++++++++++++++++----- connector/mautrix-signal-v2/main.go | 4 +- go.mod | 2 +- go.sum | 4 +- 4 files changed, 77 insertions(+), 16 deletions(-) diff --git a/connector/connector.go b/connector/connector.go index f332dc5..7e24be6 100644 --- a/connector/connector.go +++ b/connector/connector.go @@ -21,6 +21,7 @@ import ( "fmt" "strconv" "strings" + "text/template" "time" "github.com/google/uuid" @@ -47,17 +48,65 @@ import ( "go.mau.fi/mautrix-signal/pkg/signalmeow/types" ) +type SignalConfig struct { + DisplaynameTemplate string `yaml:"displayname_template"` + UseContactAvatars bool `yaml:"use_contact_avatars"` + UseOutdatedProfiles bool `yaml:"use_outdated_profiles"` + NumberInTopic bool `yaml:"number_in_topic"` + DeviceName string `yaml:"device_name"` + + displaynameTemplate *template.Template `yaml:"-"` +} + +type DisplaynameParams struct { + ProfileName string + ContactName string + Username string + PhoneNumber string + UUID string + ACI string + PNI string + AboutEmoji string +} + +func (c *SignalConfig) FormatDisplayname(contact *types.Recipient) string { + var nameBuf strings.Builder + err := c.displaynameTemplate.Execute(&nameBuf, &DisplaynameParams{ + ProfileName: contact.Profile.Name, + ContactName: contact.ContactName, + Username: "", + PhoneNumber: contact.E164, + UUID: contact.ACI.String(), + ACI: contact.ACI.String(), + PNI: contact.PNI.String(), + AboutEmoji: contact.Profile.AboutEmoji, + }) + if err != nil { + panic(err) + } + return nameBuf.String() +} + type SignalConnector struct { MsgConv *msgconv.MessageConverter Store *store.Container Bridge *bridgev2.Bridge + Config *SignalConfig } func NewConnector() *SignalConnector { - return &SignalConnector{} + return &SignalConnector{ + Config: &SignalConfig{}, + } } func (s *SignalConnector) Init(bridge *bridgev2.Bridge) { + var err error + s.Config.displaynameTemplate, err = template.New("displayname").Parse(s.Config.DisplaynameTemplate) + if err != nil { + // TODO return error or do this later? + panic(err) + } s.Store = store.NewStore(bridge.DB.Database, dbutil.ZeroLogger(bridge.Log.With().Str("db_section", "signalmeow").Logger())) s.Bridge = bridge s.MsgConv = &msgconv.MessageConverter{ @@ -150,16 +199,9 @@ func (s *SignalClient) contactToUserInfo(contact *types.Recipient) *bridgev2.Use ui := &bridgev2.UserInfo{ IsBot: &isBot, } - // TODO use template for name - if contact.ContactName != "" { - ui.Name = &contact.ContactName - } else if contact.Profile.Name != "" { - ui.Name = &contact.Profile.Name - } else if contact.E164 != "" { - ui.Name = &contact.E164 - } - // TODO only use this if contact avatars are allowed - if contact.ContactAvatar.Hash != "" { + name := s.Main.Config.FormatDisplayname(contact) + ui.Name = &name + if s.Main.Config.UseContactAvatars && contact.ContactAvatar.Hash != "" { ui.Avatar = &bridgev2.Avatar{ ID: networkid.AvatarID("hash:" + contact.ContactAvatar.Hash), Get: func(ctx context.Context) ([]byte, error) { @@ -235,17 +277,34 @@ func (s *SignalClient) GetChatInfo(ctx context.Context, portal *bridgev2.Portal) IsSpace: &isSpace, }, nil } else if userID.Type == libsignalgo.ServiceIDTypePNI { + contact, err := s.Client.Store.RecipientStore.LoadAndUpdateRecipient(ctx, uuid.Nil, userID.UUID, nil) + if err != nil { + return nil, err + } + var topic, name string + name = s.Main.Config.FormatDisplayname(contact) + if s.Main.Config.NumberInTopic && contact.E164 != "" { + topic = fmt.Sprintf("") + // TODO set topic + } isDM := true - // TODO set name/avatar because we don't have the recipient user ID return &bridgev2.PortalInfo{ Members: []networkid.UserID{makeUserID(s.Client.Store.ACI)}, + Name: &name, + Topic: &topic, IsDirectChat: &isDM, IsSpace: &isSpace, }, nil } else { + var topic, name string + if s.Main.Config.NumberInTopic { + // TODO set topic + } isDM := true return &bridgev2.PortalInfo{ Members: []networkid.UserID{makeUserID(userID.UUID), makeUserID(s.Client.Store.ACI)}, + Name: &name, + Topic: &topic, IsDirectChat: &isDM, IsSpace: &isSpace, }, nil diff --git a/connector/mautrix-signal-v2/main.go b/connector/mautrix-signal-v2/main.go index 929a9c1..1ea34d9 100644 --- a/connector/mautrix-signal-v2/main.go +++ b/connector/mautrix-signal-v2/main.go @@ -48,7 +48,9 @@ func main() { log := exerrors.Must(cfg.Logging.Compile()) exzerolog.SetupDefaults(log) db := exerrors.Must(dbutil.NewFromConfig("mautrix-signal", cfg.Database, dbutil.ZeroLogger(log.With().Str("db_section", "main").Logger()))) - bridge := bridgev2.NewBridge("", db, *log, matrix.NewConnector(&cfg), connector.NewConnector()) + signalConnector := connector.NewConnector() + exerrors.PanicIfNotNil(cfg.Network.Decode(signalConnector.Config)) + bridge := bridgev2.NewBridge("", db, *log, matrix.NewConnector(&cfg), signalConnector) bridge.CommandPrefix = "!signal" bridge.Commands.AddHandlers(&bridgev2.FullHandler{ Func: fnLogin, diff --git a/go.mod b/go.mod index 22b07b3..913d3c1 100644 --- a/go.mod +++ b/go.mod @@ -21,7 +21,7 @@ require ( golang.org/x/net v0.25.0 google.golang.org/protobuf v1.34.1 gopkg.in/yaml.v3 v3.0.1 - maunium.net/go/mautrix v0.18.2-0.20240528174923-3c7b3e13efe4 + maunium.net/go/mautrix v0.18.2-0.20240529135554-248de0e6adb2 nhooyr.io/websocket v1.8.11 ) diff --git a/go.sum b/go.sum index 4d6c887..641b71f 100644 --- a/go.sum +++ b/go.sum @@ -95,7 +95,7 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= maunium.net/go/mauflag v1.0.0 h1:YiaRc0tEI3toYtJMRIfjP+jklH45uDHtT80nUamyD4M= maunium.net/go/mauflag v1.0.0/go.mod h1:nLivPOpTpHnpzEh8jEdSL9UqO9+/KBJFmNRlwKfkPeA= -maunium.net/go/mautrix v0.18.2-0.20240528174923-3c7b3e13efe4 h1:b+pK+EJL2XsweSKlwhd8eeqD4v395dKrcJZmCFTBmBY= -maunium.net/go/mautrix v0.18.2-0.20240528174923-3c7b3e13efe4/go.mod h1:Ln4XquIKL5MttTUGNUSbiEGX3XYC0P6jzT9XjLFFPdY= +maunium.net/go/mautrix v0.18.2-0.20240529135554-248de0e6adb2 h1:AUKv3tqpdFerCw2X8m05BGfhtP3vH8cDuEtAGxwuUl0= +maunium.net/go/mautrix v0.18.2-0.20240529135554-248de0e6adb2/go.mod h1:Ln4XquIKL5MttTUGNUSbiEGX3XYC0P6jzT9XjLFFPdY= nhooyr.io/websocket v1.8.11 h1:f/qXNc2/3DpoSZkHt1DQu6rj4zGC8JmkkLkWss0MgN0= nhooyr.io/websocket v1.8.11/go.mod h1:rN9OFWIUwuxg4fR5tELlYC04bXYowCP9GX47ivo2l+c= From c5a7ccaf89167ffc63187da7383c919aa45054fc Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Fri, 31 May 2024 15:47:27 +0300 Subject: [PATCH 027/580] Fix contact avatars --- portal.go | 8 ++++---- puppet.go | 5 ++++- user.go | 2 +- 3 files changed, 9 insertions(+), 6 deletions(-) diff --git a/portal.go b/portal.go index 2e90ac7..6922311 100644 --- a/portal.go +++ b/portal.go @@ -892,7 +892,7 @@ func (portal *Portal) handleSignalDataMessage(source *User, sender *Puppet, msg Uint64("msg_ts", msg.GetTimestamp()). Logger().WithContext(context.TODO()) // Always update sender info when we receive a message from them, there's caching inside the function - sender.UpdateInfo(genericCtx, source) + sender.UpdateInfo(genericCtx, source, nil) // Handle earlier missed group changes here. if msg.GetGroupV2() != nil { requiredRevision := msg.GetGroupV2().GetRevision() @@ -1800,7 +1800,7 @@ func (portal *Portal) CreateMatrixRoom(ctx context.Context, user *User, groupRev if portal.IsPrivateChat() { dmPuppet = portal.GetDMPuppet() if dmPuppet != nil { - dmPuppet.UpdateInfo(ctx, user) + dmPuppet.UpdateInfo(ctx, user, nil) portal.UpdateDMInfo(ctx, false) } else { portal.UpdatePNIDMInfo(ctx, user) @@ -1900,7 +1900,7 @@ func (portal *Portal) PostReIDUpdate(ctx context.Context, user *User) { if err != nil { zerolog.Ctx(ctx).Err(err).Msg("Failed to update ghost power level after portal re-ID") } - portal.GetDMPuppet().UpdateInfo(ctx, user) + portal.GetDMPuppet().UpdateInfo(ctx, user, nil) portal.UpdateDMInfo(ctx, true) if !portal.Encrypted { _, _ = portal.bridge.Bot.LeaveRoom(ctx, portal.MXID) @@ -2298,7 +2298,7 @@ func (portal *Portal) SyncParticipants(ctx context.Context, source *User, info * log.Warn().Stringer("signal_user_id", member.ACI).Msg("Couldn't get puppet for group member") continue } - puppet.UpdateInfo(ctx, source) + puppet.UpdateInfo(ctx, source, nil) intent := puppet.IntentFor(portal) if member.ACI != source.SignalID && portal.MXID != "" { userIDs[intent.UserID] = ((int)(member.Role) >> 1) * 50 diff --git a/puppet.go b/puppet.go index f58befa..857312e 100644 --- a/puppet.go +++ b/puppet.go @@ -232,7 +232,7 @@ func (puppet *Puppet) GetAvatarURL() id.ContentURI { return puppet.AvatarURL } -func (puppet *Puppet) UpdateInfo(ctx context.Context, source *User) { +func (puppet *Puppet) UpdateInfo(ctx context.Context, source *User, contactAvatar *types.ContactAvatar) { log := zerolog.Ctx(ctx).With(). Str("function", "Puppet.UpdateInfo"). Stringer("signal_user_id", puppet.SignalID). @@ -252,6 +252,9 @@ func (puppet *Puppet) UpdateInfo(ctx context.Context, source *User) { Msg("Ignoring outdated contact info") return } + if contactAvatar != nil { + info.ContactAvatar = *contactAvatar + } log.Trace().Msg("Updating puppet info") diff --git a/user.go b/user.go index a579e8b..0814c3e 100644 --- a/user.go +++ b/user.go @@ -755,7 +755,7 @@ func (user *User) handleContactList(evt *events.ContactList) { if puppet == nil { continue } - puppet.UpdateInfo(ctx, user) + puppet.UpdateInfo(ctx, user, &contact.ContactAvatar) } } From 3e6561054ef7fd1eb123faf9d8fba7a6b3a41891 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Mon, 3 Jun 2024 16:57:45 +0300 Subject: [PATCH 028/580] Update to libsignal 0.49.0 --- pkg/libsignalgo/authcredential.go | 10 +- pkg/libsignalgo/groupsecretparams.go | 5 +- pkg/libsignalgo/libsignal | 2 +- pkg/libsignalgo/libsignal-ffi.h | 364 ++++++++++++------ pkg/libsignalgo/logging.go | 11 +- pkg/libsignalgo/profilekey.go | 12 +- ...rifysignature.go => serverpublicparams.go} | 21 +- pkg/libsignalgo/version.go | 2 +- pkg/signalmeow/misc.go | 7 +- 9 files changed, 284 insertions(+), 150 deletions(-) rename pkg/libsignalgo/{verifysignature.go => serverpublicparams.go} (68%) diff --git a/pkg/libsignalgo/authcredential.go b/pkg/libsignalgo/authcredential.go index 57396ef..0c7354f 100644 --- a/pkg/libsignalgo/authcredential.go +++ b/pkg/libsignalgo/authcredential.go @@ -40,18 +40,17 @@ func (ac *AuthCredentialWithPni) Slice() []byte { } func ReceiveAuthCredentialWithPni( - serverPublicParams ServerPublicParams, + serverPublicParams *ServerPublicParams, aci uuid.UUID, pni uuid.UUID, redemptionTime uint64, authCredResponse AuthCredentialWithPniResponse, ) (*AuthCredentialWithPni, error) { var c_result C.SignalOwnedBuffer = C.SignalOwnedBuffer{} - c_serverPublicParams := (*[C.SignalSERVER_PUBLIC_PARAMS_LEN]C.uchar)(unsafe.Pointer(&serverPublicParams[0])) signalFfiError := C.signal_server_public_params_receive_auth_credential_with_pni_as_service_id( &c_result, - c_serverPublicParams, + serverPublicParams, NewACIServiceID(aci).CFixedBytes(), NewPNIServiceID(pni).CFixedBytes(), C.uint64_t(redemptionTime), @@ -78,19 +77,18 @@ func NewAuthCredentialWithPniResponse(b []byte) (*AuthCredentialWithPniResponse, } func CreateAuthCredentialWithPniPresentation( - serverPublicParams ServerPublicParams, + serverPublicParams *ServerPublicParams, randomness Randomness, groupSecretParams GroupSecretParams, authCredWithPni AuthCredentialWithPni, ) (*AuthCredentialPresentation, error) { var c_result C.SignalOwnedBuffer = C.SignalOwnedBuffer{} - c_serverPublicParams := (*[C.SignalSERVER_PUBLIC_PARAMS_LEN]C.uchar)(unsafe.Pointer(&serverPublicParams[0])) c_randomness := (*[C.SignalRANDOMNESS_LEN]C.uchar)(unsafe.Pointer(&randomness[0])) c_groupSecretParams := (*[C.SignalGROUP_SECRET_PARAMS_LEN]C.uchar)(unsafe.Pointer(&groupSecretParams[0])) signalFfiError := C.signal_server_public_params_create_auth_credential_with_pni_presentation_deterministic( &c_result, - c_serverPublicParams, + serverPublicParams, c_randomness, c_groupSecretParams, BytesToBuffer(authCredWithPni[:]), diff --git a/pkg/libsignalgo/groupsecretparams.go b/pkg/libsignalgo/groupsecretparams.go index 76a28f7..0df5ec8 100644 --- a/pkg/libsignalgo/groupsecretparams.go +++ b/pkg/libsignalgo/groupsecretparams.go @@ -208,18 +208,17 @@ func (gsp *GroupSecretParams) EncryptProfileKey(profileKey ProfileKey, u uuid.UU return &result, nil } -func (gsp *GroupSecretParams) CreateExpiringProfileKeyCredentialPresentation(spp ServerPublicParams, credential ExpiringProfileKeyCredential) (*ProfileKeyCredentialPresentation, error) { +func (gsp *GroupSecretParams) CreateExpiringProfileKeyCredentialPresentation(spp *ServerPublicParams, credential ExpiringProfileKeyCredential) (*ProfileKeyCredentialPresentation, error) { var out C.SignalOwnedBuffer = C.SignalOwnedBuffer{} randomness := GenerateRandomness() signalFfiError := C.signal_server_public_params_create_expiring_profile_key_credential_presentation_deterministic( &out, - (*[C.SignalSERVER_PUBLIC_PARAMS_LEN]C.uchar)(unsafe.Pointer(&spp)), + spp, (*[C.SignalRANDOMNESS_LEN]C.uint8_t)(unsafe.Pointer(&randomness)), (*[C.SignalGROUP_SECRET_PARAMS_LEN]C.uchar)(unsafe.Pointer(gsp)), (*[C.SignalEXPIRING_PROFILE_KEY_CREDENTIAL_LEN]C.uchar)(unsafe.Pointer(&credential)), ) runtime.KeepAlive(gsp) - runtime.KeepAlive(spp) runtime.KeepAlive(credential) runtime.KeepAlive(randomness) if signalFfiError != nil { diff --git a/pkg/libsignalgo/libsignal b/pkg/libsignalgo/libsignal index 02e03ee..347791c 160000 --- a/pkg/libsignalgo/libsignal +++ b/pkg/libsignalgo/libsignal @@ -1 +1 @@ -Subproject commit 02e03ee05742079694d643fbc64fa737b275e9f8 +Subproject commit 347791c88cdfdb765534b5e2be149f588b75bf49 diff --git a/pkg/libsignalgo/libsignal-ffi.h b/pkg/libsignalgo/libsignal-ffi.h index b8bfab8..c349c2c 100644 --- a/pkg/libsignalgo/libsignal-ffi.h +++ b/pkg/libsignalgo/libsignal-ffi.h @@ -147,6 +147,7 @@ typedef enum { SignalErrorCodeInvalidArgument = 5, SignalErrorCodeInvalidType = 6, SignalErrorCodeInvalidUtf8String = 7, + SignalErrorCodeCancelled = 8, SignalErrorCodeProtobufError = 10, SignalErrorCodeLegacyCiphertextVersion = 21, SignalErrorCodeUnknownCiphertextVersion = 22, @@ -193,6 +194,8 @@ typedef enum { SignalErrorCodeChatServiceInactive = 139, SignalErrorCodeSvrDataMissing = 150, SignalErrorCodeSvrRestoreFailed = 151, + SignalErrorCodeAppExpired = 160, + SignalErrorCodeDeviceDeregistered = 161, } SignalErrorCode; /** @@ -274,6 +277,15 @@ typedef struct SignalSenderKeyRecord SignalSenderKeyRecord; typedef struct SignalServerCertificate SignalServerCertificate; +/** + * Wraps a named type and a single-use guard around [`chat::server_requests::AckEnvelopeFuture`]. + */ +typedef struct SignalServerMessageAck SignalServerMessageAck; + +typedef struct SignalServerPublicParams SignalServerPublicParams; + +typedef struct SignalServerSecretParams SignalServerSecretParams; + typedef struct SignalSessionRecord SignalSessionRecord; typedef struct SignalSgxClientState SignalSgxClientState; @@ -416,14 +428,12 @@ typedef struct { SignalStoreSignedPreKey store_signed_pre_key; } SignalSignedPreKeyStore; -typedef bool (*SignalLogEnabledCallback)(const char *target, SignalLogLevel level); +typedef void (*SignalLogCallback)(void *ctx, const char *target, SignalLogLevel level, const char *file, uint32_t line, const char *message); -typedef void (*SignalLogCallback)(const char *target, SignalLogLevel level, const char *file, uint32_t line, const char *message); - -typedef void (*SignalLogFlushCallback)(void); +typedef void (*SignalLogFlushCallback)(void *ctx); typedef struct { - SignalLogEnabledCallback enabled; + void *ctx; SignalLogCallback log; SignalLogFlushCallback flush; } SignalFfiLogger; @@ -489,24 +499,74 @@ typedef struct { size_t length; } SignalBorrowedSliceOfBuffers; -/** - * A C callback used to report the results of Rust futures. - * - * cbindgen will produce independent C types like `SignalCPromisei32` and - * `SignalCPromiseProtocolAddress`. - */ -typedef void (*SignalCPromiseOwnedBufferOfc_uchar)(SignalFfiError *error, const SignalOwnedBuffer *result, const void *context); +typedef uint64_t SignalCancellationId; /** * A C callback used to report the results of Rust futures. * * cbindgen will produce independent C types like `SignalCPromisei32` and * `SignalCPromiseProtocolAddress`. + * + * This derives Copy because it behaves like a C type; nevertheless, a promise should still only be + * completed once. */ -typedef void (*SignalCPromisebool)(SignalFfiError *error, const bool *result, const void *context); +typedef struct { + void (*complete)(SignalFfiError *error, const SignalOwnedBuffer *result, const void *context); + const void *context; + SignalCancellationId cancellation_id; +} SignalCPromiseOwnedBufferOfc_uchar; + +/** + * A C callback used to report the results of Rust futures. + * + * cbindgen will produce independent C types like `SignalCPromisei32` and + * `SignalCPromiseProtocolAddress`. + * + * This derives Copy because it behaves like a C type; nevertheless, a promise should still only be + * completed once. + */ +typedef struct { + void (*complete)(SignalFfiError *error, const bool *result, const void *context); + const void *context; + SignalCancellationId cancellation_id; +} SignalCPromisebool; + +/** + * A C callback used to report the results of Rust futures. + * + * cbindgen will produce independent C types like `SignalCPromisei32` and + * `SignalCPromiseProtocolAddress`. + * + * This derives Copy because it behaves like a C type; nevertheless, a promise should still only be + * completed once. + */ +typedef struct { + void (*complete)(SignalFfiError *error, SignalCdsiLookup *const *result, const void *context); + const void *context; + SignalCancellationId cancellation_id; +} SignalCPromiseCdsiLookup; + +typedef struct { + SignalOwnedBufferOfFfiCdsiLookupResponseEntry entries; + int32_t debug_permits_used; +} SignalFfiCdsiLookupResponse; + +/** + * A C callback used to report the results of Rust futures. + * + * cbindgen will produce independent C types like `SignalCPromisei32` and + * `SignalCPromiseProtocolAddress`. + * + * This derives Copy because it behaves like a C type; nevertheless, a promise should still only be + * completed once. + */ +typedef struct { + void (*complete)(SignalFfiError *error, const SignalFfiCdsiLookupResponse *result, const void *context); + const void *context; + SignalCancellationId cancellation_id; +} SignalCPromiseFfiCdsiLookupResponse; typedef struct { - bool connection_reused; uint32_t reconnect_count; uint8_t raw_ip_type; double duration_secs; @@ -518,8 +578,15 @@ typedef struct { * * cbindgen will produce independent C types like `SignalCPromisei32` and * `SignalCPromiseProtocolAddress`. + * + * This derives Copy because it behaves like a C type; nevertheless, a promise should still only be + * completed once. */ -typedef void (*SignalCPromiseFfiChatServiceDebugInfo)(SignalFfiError *error, const SignalFfiChatServiceDebugInfo *result, const void *context); +typedef struct { + void (*complete)(SignalFfiError *error, const SignalFfiChatServiceDebugInfo *result, const void *context); + const void *context; + SignalCancellationId cancellation_id; +} SignalCPromiseFfiChatServiceDebugInfo; typedef struct { uint16_t status; @@ -533,8 +600,15 @@ typedef struct { * * cbindgen will produce independent C types like `SignalCPromisei32` and * `SignalCPromiseProtocolAddress`. + * + * This derives Copy because it behaves like a C type; nevertheless, a promise should still only be + * completed once. */ -typedef void (*SignalCPromiseFfiChatResponse)(SignalFfiError *error, const SignalFfiChatResponse *result, const void *context); +typedef struct { + void (*complete)(SignalFfiError *error, const SignalFfiChatResponse *result, const void *context); + const void *context; + SignalCancellationId cancellation_id; +} SignalCPromiseFfiChatResponse; typedef struct { SignalFfiChatResponse response; @@ -546,29 +620,37 @@ typedef struct { * * cbindgen will produce independent C types like `SignalCPromisei32` and * `SignalCPromiseProtocolAddress`. - */ -typedef void (*SignalCPromiseFfiResponseAndDebugInfo)(SignalFfiError *error, const SignalFfiResponseAndDebugInfo *result, const void *context); - -/** - * A C callback used to report the results of Rust futures. * - * cbindgen will produce independent C types like `SignalCPromisei32` and - * `SignalCPromiseProtocolAddress`. + * This derives Copy because it behaves like a C type; nevertheless, a promise should still only be + * completed once. */ -typedef void (*SignalCPromiseCdsiLookup)(SignalFfiError *error, SignalCdsiLookup *const *result, const void *context); - typedef struct { - SignalOwnedBufferOfFfiCdsiLookupResponseEntry entries; - int32_t debug_permits_used; -} SignalFfiCdsiLookupResponse; + void (*complete)(SignalFfiError *error, const SignalFfiResponseAndDebugInfo *result, const void *context); + const void *context; + SignalCancellationId cancellation_id; +} SignalCPromiseFfiResponseAndDebugInfo; + +typedef void (*SignalReceivedIncomingMessage)(void *ctx, SignalOwnedBuffer envelope, uint64_t timestamp_millis, SignalServerMessageAck *cleanup); + +typedef void (*SignalReceivedQueueEmpty)(void *ctx); + +typedef void (*SignalDestroyChatListener)(void *ctx); /** - * A C callback used to report the results of Rust futures. + * Callbacks for [`ChatListener`]. * - * cbindgen will produce independent C types like `SignalCPromisei32` and - * `SignalCPromiseProtocolAddress`. + * Callbacks will be serialized (i.e. two calls will not come in at the same time), but may not + * always happen on the same thread. Calls should be responded to promptly to avoid blocking later + * messages. */ -typedef void (*SignalCPromiseFfiCdsiLookupResponse)(SignalFfiError *error, const SignalFfiCdsiLookupResponse *result, const void *context); +typedef struct { + void *ctx; + SignalReceivedIncomingMessage received_incoming_message; + SignalReceivedQueueEmpty received_queue_empty; + SignalDestroyChatListener destroy; +} SignalFfiChatListenerStruct; + +typedef SignalFfiChatListenerStruct SignalFfiMakeChatListenerStruct; typedef SignalBytestringArray SignalStringArray; @@ -589,32 +671,60 @@ typedef SignalInputStream SignalSyncInputStream; * * cbindgen will produce independent C types like `SignalCPromisei32` and * `SignalCPromiseProtocolAddress`. + * + * This derives Copy because it behaves like a C type; nevertheless, a promise should still only be + * completed once. */ -typedef void (*SignalCPromisei32)(SignalFfiError *error, const int32_t *result, const void *context); +typedef struct { + void (*complete)(SignalFfiError *error, const int32_t *result, const void *context); + const void *context; + SignalCancellationId cancellation_id; +} SignalCPromisei32; /** * A C callback used to report the results of Rust futures. * * cbindgen will produce independent C types like `SignalCPromisei32` and * `SignalCPromiseProtocolAddress`. + * + * This derives Copy because it behaves like a C type; nevertheless, a promise should still only be + * completed once. */ -typedef void (*SignalCPromiseTestingHandleType)(SignalFfiError *error, SignalTestingHandleType *const *result, const void *context); +typedef struct { + void (*complete)(SignalFfiError *error, SignalTestingHandleType *const *result, const void *context); + const void *context; + SignalCancellationId cancellation_id; +} SignalCPromiseTestingHandleType; /** * A C callback used to report the results of Rust futures. * * cbindgen will produce independent C types like `SignalCPromisei32` and * `SignalCPromiseProtocolAddress`. + * + * This derives Copy because it behaves like a C type; nevertheless, a promise should still only be + * completed once. */ -typedef void (*SignalCPromiseOtherTestingHandleType)(SignalFfiError *error, SignalOtherTestingHandleType *const *result, const void *context); +typedef struct { + void (*complete)(SignalFfiError *error, SignalOtherTestingHandleType *const *result, const void *context); + const void *context; + SignalCancellationId cancellation_id; +} SignalCPromiseOtherTestingHandleType; /** * A C callback used to report the results of Rust futures. * * cbindgen will produce independent C types like `SignalCPromisei32` and * `SignalCPromiseProtocolAddress`. + * + * This derives Copy because it behaves like a C type; nevertheless, a promise should still only be + * completed once. */ -typedef void (*SignalCPromiseRawPointer)(SignalFfiError *error, const void *const *result, const void *context); +typedef struct { + void (*complete)(SignalFfiError *error, const void *const *result, const void *context); + const void *context; + SignalCancellationId cancellation_id; +} SignalCPromiseRawPointer; typedef uint8_t SignalRandomnessBytes[SignalRANDOMNESS_LEN]; @@ -640,13 +750,15 @@ uint32_t signal_error_get_type(const SignalFfiError *err); SignalFfiError *signal_error_get_retry_after_seconds(const SignalFfiError *err, uint32_t *out); +SignalFfiError *signal_error_get_tries_remaining(const SignalFfiError *err, uint32_t *out); + void signal_error_free(SignalFfiError *err); SignalFfiError *signal_identitykeypair_deserialize(SignalPrivateKey **private_key, SignalPublicKey **public_key, SignalBorrowedBuffer input); SignalFfiError *signal_sealed_session_cipher_decrypt(SignalOwnedBuffer *out, const char **sender_e164, const char **sender_uuid, uint32_t *sender_device_id, SignalBorrowedBuffer ctext, const SignalPublicKey *trust_root, uint64_t timestamp, const char *local_e164, const char *local_uuid, unsigned int local_device_id, const SignalSessionStore *session_store, const SignalIdentityKeyStore *identity_store, const SignalPreKeyStore *prekey_store, const SignalSignedPreKeyStore *signed_prekey_store); -void signal_init_logger(SignalLogLevel max_level, SignalFfiLogger logger); +bool signal_init_logger(SignalLogLevel max_level, SignalFfiLogger logger); SignalFfiError *signal_aes256_gcm_siv_destroy(SignalAes256GcmSiv *p); @@ -946,6 +1058,8 @@ SignalFfiError *signal_pre_key_bundle_get_pre_key_public(SignalPublicKey **out, SignalFfiError *signal_pre_key_bundle_get_signed_pre_key_public(SignalPublicKey **out, const SignalPreKeyBundle *obj); +SignalFfiError *signal_pre_key_bundle_get_kyber_pre_key_id(uint32_t *out, const SignalPreKeyBundle *obj); + SignalFfiError *signal_pre_key_bundle_get_kyber_pre_key_public(SignalKyberPublicKey **out, const SignalPreKeyBundle *bundle); SignalFfiError *signal_pre_key_bundle_get_kyber_pre_key_signature(SignalOwnedBuffer *out, const SignalPreKeyBundle *bundle); @@ -1158,12 +1272,20 @@ SignalFfiError *signal_receipt_credential_request_context_check_valid_contents(S SignalFfiError *signal_receipt_credential_response_check_valid_contents(SignalBorrowedBuffer buffer); -SignalFfiError *signal_server_public_params_check_valid_contents(SignalBorrowedBuffer buffer); - -SignalFfiError *signal_server_secret_params_check_valid_contents(SignalBorrowedBuffer buffer); - SignalFfiError *signal_uuid_ciphertext_check_valid_contents(SignalBorrowedBuffer buffer); +SignalFfiError *signal_server_public_params_destroy(SignalServerPublicParams *p); + +SignalFfiError *signal_server_public_params_deserialize(SignalServerPublicParams **out, SignalBorrowedBuffer buffer); + +SignalFfiError *signal_server_public_params_serialize(SignalOwnedBuffer *out, const SignalServerPublicParams *handle); + +SignalFfiError *signal_server_secret_params_destroy(SignalServerSecretParams *p); + +SignalFfiError *signal_server_secret_params_deserialize(SignalServerSecretParams **out, SignalBorrowedBuffer buffer); + +SignalFfiError *signal_server_secret_params_serialize(SignalOwnedBuffer *out, const SignalServerSecretParams *handle); + SignalFfiError *signal_profile_key_get_commitment(unsigned char (*out)[SignalPROFILE_KEY_COMMITMENT_LEN], const unsigned char (*profile_key)[SignalPROFILE_KEY_LEN], const SignalServiceIdFixedWidthBinaryBytes *user_id); SignalFfiError *signal_profile_key_get_profile_key_version(uint8_t (*out)[SignalPROFILE_KEY_VERSION_ENCODED_LEN], const unsigned char (*profile_key)[SignalPROFILE_KEY_LEN], const SignalServiceIdFixedWidthBinaryBytes *user_id); @@ -1190,53 +1312,49 @@ SignalFfiError *signal_group_secret_params_encrypt_blob_with_padding_determinist SignalFfiError *signal_group_secret_params_decrypt_blob_with_padding(SignalOwnedBuffer *out, const unsigned char (*params)[SignalGROUP_SECRET_PARAMS_LEN], SignalBorrowedBuffer ciphertext); -SignalFfiError *signal_server_secret_params_generate_deterministic(unsigned char (*out)[SignalSERVER_SECRET_PARAMS_LEN], const uint8_t (*randomness)[SignalRANDOMNESS_LEN]); +SignalFfiError *signal_server_secret_params_generate_deterministic(SignalServerSecretParams **out, const uint8_t (*randomness)[SignalRANDOMNESS_LEN]); -SignalFfiError *signal_server_secret_params_get_public_params(unsigned char (*out)[SignalSERVER_PUBLIC_PARAMS_LEN], const unsigned char (*params)[SignalSERVER_SECRET_PARAMS_LEN]); +SignalFfiError *signal_server_secret_params_get_public_params(SignalServerPublicParams **out, const SignalServerSecretParams *params); -SignalFfiError *signal_server_secret_params_sign_deterministic(uint8_t (*out)[SignalSIGNATURE_LEN], const unsigned char (*params)[SignalSERVER_SECRET_PARAMS_LEN], const uint8_t (*randomness)[SignalRANDOMNESS_LEN], SignalBorrowedBuffer message); +SignalFfiError *signal_server_secret_params_sign_deterministic(uint8_t (*out)[SignalSIGNATURE_LEN], const SignalServerSecretParams *params, const uint8_t (*randomness)[SignalRANDOMNESS_LEN], SignalBorrowedBuffer message); -SignalFfiError *signal_server_public_params_receive_auth_credential_with_pni_as_service_id(SignalOwnedBuffer *out, const unsigned char (*params)[SignalSERVER_PUBLIC_PARAMS_LEN], const SignalServiceIdFixedWidthBinaryBytes *aci, const SignalServiceIdFixedWidthBinaryBytes *pni, uint64_t redemption_time, SignalBorrowedBuffer auth_credential_with_pni_response_bytes); +SignalFfiError *signal_server_public_params_receive_auth_credential_with_pni_as_service_id(SignalOwnedBuffer *out, const SignalServerPublicParams *params, const SignalServiceIdFixedWidthBinaryBytes *aci, const SignalServiceIdFixedWidthBinaryBytes *pni, uint64_t redemption_time, SignalBorrowedBuffer auth_credential_with_pni_response_bytes); -SignalFfiError *signal_server_public_params_receive_auth_credential_with_pni_as_aci(SignalOwnedBuffer *out, const unsigned char (*params)[SignalSERVER_PUBLIC_PARAMS_LEN], const SignalServiceIdFixedWidthBinaryBytes *aci, const SignalServiceIdFixedWidthBinaryBytes *pni, uint64_t redemption_time, SignalBorrowedBuffer auth_credential_with_pni_response_bytes); +SignalFfiError *signal_server_public_params_create_auth_credential_with_pni_presentation_deterministic(SignalOwnedBuffer *out, const SignalServerPublicParams *server_public_params, const uint8_t (*randomness)[SignalRANDOMNESS_LEN], const unsigned char (*group_secret_params)[SignalGROUP_SECRET_PARAMS_LEN], SignalBorrowedBuffer auth_credential_with_pni_bytes); -SignalFfiError *signal_server_public_params_create_auth_credential_with_pni_presentation_deterministic(SignalOwnedBuffer *out, const unsigned char (*server_public_params)[SignalSERVER_PUBLIC_PARAMS_LEN], const uint8_t (*randomness)[SignalRANDOMNESS_LEN], const unsigned char (*group_secret_params)[SignalGROUP_SECRET_PARAMS_LEN], SignalBorrowedBuffer auth_credential_with_pni_bytes); +SignalFfiError *signal_server_public_params_create_profile_key_credential_request_context_deterministic(unsigned char (*out)[SignalPROFILE_KEY_CREDENTIAL_REQUEST_CONTEXT_LEN], const SignalServerPublicParams *server_public_params, const uint8_t (*randomness)[SignalRANDOMNESS_LEN], const SignalServiceIdFixedWidthBinaryBytes *user_id, const unsigned char (*profile_key)[SignalPROFILE_KEY_LEN]); -SignalFfiError *signal_server_public_params_create_profile_key_credential_request_context_deterministic(unsigned char (*out)[SignalPROFILE_KEY_CREDENTIAL_REQUEST_CONTEXT_LEN], const unsigned char (*server_public_params)[SignalSERVER_PUBLIC_PARAMS_LEN], const uint8_t (*randomness)[SignalRANDOMNESS_LEN], const SignalServiceIdFixedWidthBinaryBytes *user_id, const unsigned char (*profile_key)[SignalPROFILE_KEY_LEN]); +SignalFfiError *signal_server_public_params_receive_expiring_profile_key_credential(unsigned char (*out)[SignalEXPIRING_PROFILE_KEY_CREDENTIAL_LEN], const SignalServerPublicParams *server_public_params, const unsigned char (*request_context)[SignalPROFILE_KEY_CREDENTIAL_REQUEST_CONTEXT_LEN], const unsigned char (*response)[SignalEXPIRING_PROFILE_KEY_CREDENTIAL_RESPONSE_LEN], uint64_t current_time_in_seconds); -SignalFfiError *signal_server_public_params_receive_expiring_profile_key_credential(unsigned char (*out)[SignalEXPIRING_PROFILE_KEY_CREDENTIAL_LEN], const unsigned char (*server_public_params)[SignalSERVER_PUBLIC_PARAMS_LEN], const unsigned char (*request_context)[SignalPROFILE_KEY_CREDENTIAL_REQUEST_CONTEXT_LEN], const unsigned char (*response)[SignalEXPIRING_PROFILE_KEY_CREDENTIAL_RESPONSE_LEN], uint64_t current_time_in_seconds); +SignalFfiError *signal_server_public_params_create_expiring_profile_key_credential_presentation_deterministic(SignalOwnedBuffer *out, const SignalServerPublicParams *server_public_params, const uint8_t (*randomness)[SignalRANDOMNESS_LEN], const unsigned char (*group_secret_params)[SignalGROUP_SECRET_PARAMS_LEN], const unsigned char (*profile_key_credential)[SignalEXPIRING_PROFILE_KEY_CREDENTIAL_LEN]); -SignalFfiError *signal_server_public_params_create_expiring_profile_key_credential_presentation_deterministic(SignalOwnedBuffer *out, const unsigned char (*server_public_params)[SignalSERVER_PUBLIC_PARAMS_LEN], const uint8_t (*randomness)[SignalRANDOMNESS_LEN], const unsigned char (*group_secret_params)[SignalGROUP_SECRET_PARAMS_LEN], const unsigned char (*profile_key_credential)[SignalEXPIRING_PROFILE_KEY_CREDENTIAL_LEN]); +SignalFfiError *signal_server_public_params_create_receipt_credential_request_context_deterministic(unsigned char (*out)[SignalRECEIPT_CREDENTIAL_REQUEST_CONTEXT_LEN], const SignalServerPublicParams *server_public_params, const uint8_t (*randomness)[SignalRANDOMNESS_LEN], const uint8_t (*receipt_serial)[SignalRECEIPT_SERIAL_LEN]); -SignalFfiError *signal_server_public_params_create_receipt_credential_request_context_deterministic(unsigned char (*out)[SignalRECEIPT_CREDENTIAL_REQUEST_CONTEXT_LEN], const unsigned char (*server_public_params)[SignalSERVER_PUBLIC_PARAMS_LEN], const uint8_t (*randomness)[SignalRANDOMNESS_LEN], const uint8_t (*receipt_serial)[SignalRECEIPT_SERIAL_LEN]); +SignalFfiError *signal_server_public_params_receive_receipt_credential(unsigned char (*out)[SignalRECEIPT_CREDENTIAL_LEN], const SignalServerPublicParams *server_public_params, const unsigned char (*request_context)[SignalRECEIPT_CREDENTIAL_REQUEST_CONTEXT_LEN], const unsigned char (*response)[SignalRECEIPT_CREDENTIAL_RESPONSE_LEN]); -SignalFfiError *signal_server_public_params_receive_receipt_credential(unsigned char (*out)[SignalRECEIPT_CREDENTIAL_LEN], const unsigned char (*server_public_params)[SignalSERVER_PUBLIC_PARAMS_LEN], const unsigned char (*request_context)[SignalRECEIPT_CREDENTIAL_REQUEST_CONTEXT_LEN], const unsigned char (*response)[SignalRECEIPT_CREDENTIAL_RESPONSE_LEN]); +SignalFfiError *signal_server_public_params_create_receipt_credential_presentation_deterministic(unsigned char (*out)[SignalRECEIPT_CREDENTIAL_PRESENTATION_LEN], const SignalServerPublicParams *server_public_params, const uint8_t (*randomness)[SignalRANDOMNESS_LEN], const unsigned char (*receipt_credential)[SignalRECEIPT_CREDENTIAL_LEN]); -SignalFfiError *signal_server_public_params_create_receipt_credential_presentation_deterministic(unsigned char (*out)[SignalRECEIPT_CREDENTIAL_PRESENTATION_LEN], const unsigned char (*server_public_params)[SignalSERVER_PUBLIC_PARAMS_LEN], const uint8_t (*randomness)[SignalRANDOMNESS_LEN], const unsigned char (*receipt_credential)[SignalRECEIPT_CREDENTIAL_LEN]); +SignalFfiError *signal_server_secret_params_issue_auth_credential_with_pni_as_service_id_deterministic(SignalOwnedBuffer *out, const SignalServerSecretParams *server_secret_params, const uint8_t (*randomness)[SignalRANDOMNESS_LEN], const SignalServiceIdFixedWidthBinaryBytes *aci, const SignalServiceIdFixedWidthBinaryBytes *pni, uint64_t redemption_time); -SignalFfiError *signal_server_secret_params_issue_auth_credential_with_pni_as_service_id_deterministic(SignalOwnedBuffer *out, const unsigned char (*server_secret_params)[SignalSERVER_SECRET_PARAMS_LEN], const uint8_t (*randomness)[SignalRANDOMNESS_LEN], const SignalServiceIdFixedWidthBinaryBytes *aci, const SignalServiceIdFixedWidthBinaryBytes *pni, uint64_t redemption_time); - -SignalFfiError *signal_server_secret_params_issue_auth_credential_with_pni_as_aci_deterministic(SignalOwnedBuffer *out, const unsigned char (*server_secret_params)[SignalSERVER_SECRET_PARAMS_LEN], const uint8_t (*randomness)[SignalRANDOMNESS_LEN], const SignalServiceIdFixedWidthBinaryBytes *aci, const SignalServiceIdFixedWidthBinaryBytes *pni, uint64_t redemption_time); - -SignalFfiError *signal_server_secret_params_issue_auth_credential_with_pni_zkc_deterministic(SignalOwnedBuffer *out, const unsigned char (*server_secret_params)[SignalSERVER_SECRET_PARAMS_LEN], const uint8_t (*randomness)[SignalRANDOMNESS_LEN], const SignalServiceIdFixedWidthBinaryBytes *aci, const SignalServiceIdFixedWidthBinaryBytes *pni, uint64_t redemption_time); +SignalFfiError *signal_server_secret_params_issue_auth_credential_with_pni_zkc_deterministic(SignalOwnedBuffer *out, const SignalServerSecretParams *server_secret_params, const uint8_t (*randomness)[SignalRANDOMNESS_LEN], const SignalServiceIdFixedWidthBinaryBytes *aci, const SignalServiceIdFixedWidthBinaryBytes *pni, uint64_t redemption_time); SignalFfiError *signal_auth_credential_with_pni_check_valid_contents(SignalBorrowedBuffer bytes); SignalFfiError *signal_auth_credential_with_pni_response_check_valid_contents(SignalBorrowedBuffer bytes); -SignalFfiError *signal_server_secret_params_verify_auth_credential_presentation(const unsigned char (*server_secret_params)[SignalSERVER_SECRET_PARAMS_LEN], const unsigned char (*group_public_params)[SignalGROUP_PUBLIC_PARAMS_LEN], SignalBorrowedBuffer presentation_bytes, uint64_t current_time_in_seconds); +SignalFfiError *signal_server_secret_params_verify_auth_credential_presentation(const SignalServerSecretParams *server_secret_params, const unsigned char (*group_public_params)[SignalGROUP_PUBLIC_PARAMS_LEN], SignalBorrowedBuffer presentation_bytes, uint64_t current_time_in_seconds); -SignalFfiError *signal_server_secret_params_issue_expiring_profile_key_credential_deterministic(unsigned char (*out)[SignalEXPIRING_PROFILE_KEY_CREDENTIAL_RESPONSE_LEN], const unsigned char (*server_secret_params)[SignalSERVER_SECRET_PARAMS_LEN], const uint8_t (*randomness)[SignalRANDOMNESS_LEN], const unsigned char (*request)[SignalPROFILE_KEY_CREDENTIAL_REQUEST_LEN], const SignalServiceIdFixedWidthBinaryBytes *user_id, const unsigned char (*commitment)[SignalPROFILE_KEY_COMMITMENT_LEN], uint64_t expiration_in_seconds); +SignalFfiError *signal_server_secret_params_issue_expiring_profile_key_credential_deterministic(unsigned char (*out)[SignalEXPIRING_PROFILE_KEY_CREDENTIAL_RESPONSE_LEN], const SignalServerSecretParams *server_secret_params, const uint8_t (*randomness)[SignalRANDOMNESS_LEN], const unsigned char (*request)[SignalPROFILE_KEY_CREDENTIAL_REQUEST_LEN], const SignalServiceIdFixedWidthBinaryBytes *user_id, const unsigned char (*commitment)[SignalPROFILE_KEY_COMMITMENT_LEN], uint64_t expiration_in_seconds); -SignalFfiError *signal_server_secret_params_verify_profile_key_credential_presentation(const unsigned char (*server_secret_params)[SignalSERVER_SECRET_PARAMS_LEN], const unsigned char (*group_public_params)[SignalGROUP_PUBLIC_PARAMS_LEN], SignalBorrowedBuffer presentation_bytes, uint64_t current_time_in_seconds); +SignalFfiError *signal_server_secret_params_verify_profile_key_credential_presentation(const SignalServerSecretParams *server_secret_params, const unsigned char (*group_public_params)[SignalGROUP_PUBLIC_PARAMS_LEN], SignalBorrowedBuffer presentation_bytes, uint64_t current_time_in_seconds); -SignalFfiError *signal_server_secret_params_issue_receipt_credential_deterministic(unsigned char (*out)[SignalRECEIPT_CREDENTIAL_RESPONSE_LEN], const unsigned char (*server_secret_params)[SignalSERVER_SECRET_PARAMS_LEN], const uint8_t (*randomness)[SignalRANDOMNESS_LEN], const unsigned char (*request)[SignalRECEIPT_CREDENTIAL_REQUEST_LEN], uint64_t receipt_expiration_time, uint64_t receipt_level); +SignalFfiError *signal_server_secret_params_issue_receipt_credential_deterministic(unsigned char (*out)[SignalRECEIPT_CREDENTIAL_RESPONSE_LEN], const SignalServerSecretParams *server_secret_params, const uint8_t (*randomness)[SignalRANDOMNESS_LEN], const unsigned char (*request)[SignalRECEIPT_CREDENTIAL_REQUEST_LEN], uint64_t receipt_expiration_time, uint64_t receipt_level); -SignalFfiError *signal_server_secret_params_verify_receipt_credential_presentation(const unsigned char (*server_secret_params)[SignalSERVER_SECRET_PARAMS_LEN], const unsigned char (*presentation)[SignalRECEIPT_CREDENTIAL_PRESENTATION_LEN]); +SignalFfiError *signal_server_secret_params_verify_receipt_credential_presentation(const SignalServerSecretParams *server_secret_params, const unsigned char (*presentation)[SignalRECEIPT_CREDENTIAL_PRESENTATION_LEN]); SignalFfiError *signal_group_public_params_get_group_identifier(uint8_t (*out)[SignalGROUP_IDENTIFIER_LEN], const unsigned char (*group_public_params)[SignalGROUP_PUBLIC_PARAMS_LEN]); -SignalFfiError *signal_server_public_params_verify_signature(const unsigned char (*server_public_params)[SignalSERVER_PUBLIC_PARAMS_LEN], SignalBorrowedBuffer message, const uint8_t (*notary_signature)[SignalSIGNATURE_LEN]); +SignalFfiError *signal_server_public_params_verify_signature(const SignalServerPublicParams *server_public_params, SignalBorrowedBuffer message, const uint8_t (*notary_signature)[SignalSIGNATURE_LEN]); SignalFfiError *signal_auth_credential_presentation_check_valid_contents(SignalBorrowedBuffer presentation_bytes); @@ -1332,16 +1450,18 @@ SignalFfiError *signal_backup_auth_credential_request_context_get_request(Signal SignalFfiError *signal_backup_auth_credential_request_check_valid_contents(SignalBorrowedBuffer request_bytes); -SignalFfiError *signal_backup_auth_credential_request_issue_deterministic(SignalOwnedBuffer *out, SignalBorrowedBuffer request_bytes, uint64_t redemption_time, uint64_t receipt_level, SignalBorrowedBuffer params_bytes, const uint8_t (*randomness)[SignalRANDOMNESS_LEN]); +SignalFfiError *signal_backup_auth_credential_request_issue_deterministic(SignalOwnedBuffer *out, SignalBorrowedBuffer request_bytes, uint64_t redemption_time, uint8_t backup_level, SignalBorrowedBuffer params_bytes, const uint8_t (*randomness)[SignalRANDOMNESS_LEN]); SignalFfiError *signal_backup_auth_credential_response_check_valid_contents(SignalBorrowedBuffer response_bytes); -SignalFfiError *signal_backup_auth_credential_request_context_receive_response(SignalOwnedBuffer *out, SignalBorrowedBuffer context_bytes, SignalBorrowedBuffer response_bytes, SignalBorrowedBuffer params_bytes, uint64_t expected_receipt_level); +SignalFfiError *signal_backup_auth_credential_request_context_receive_response(SignalOwnedBuffer *out, SignalBorrowedBuffer context_bytes, SignalBorrowedBuffer response_bytes, uint64_t expected_redemption_time, SignalBorrowedBuffer params_bytes); SignalFfiError *signal_backup_auth_credential_check_valid_contents(SignalBorrowedBuffer params_bytes); SignalFfiError *signal_backup_auth_credential_get_backup_id(uint8_t (*out)[16], SignalBorrowedBuffer credential_bytes); +SignalFfiError *signal_backup_auth_credential_get_backup_level(uint8_t *out, SignalBorrowedBuffer credential_bytes); + SignalFfiError *signal_backup_auth_credential_present_deterministic(SignalOwnedBuffer *out, SignalBorrowedBuffer credential_bytes, SignalBorrowedBuffer server_params_bytes, const uint8_t (*randomness)[SignalRANDOMNESS_LEN]); SignalFfiError *signal_backup_auth_credential_presentation_check_valid_contents(SignalBorrowedBuffer presentation_bytes); @@ -1350,7 +1470,7 @@ SignalFfiError *signal_backup_auth_credential_presentation_verify(SignalBorrowed SignalFfiError *signal_group_send_derived_key_pair_check_valid_contents(SignalBorrowedBuffer bytes); -SignalFfiError *signal_group_send_derived_key_pair_for_expiration(SignalOwnedBuffer *out, uint64_t expiration, const unsigned char (*server_params)[SignalSERVER_SECRET_PARAMS_LEN]); +SignalFfiError *signal_group_send_derived_key_pair_for_expiration(SignalOwnedBuffer *out, uint64_t expiration, const SignalServerSecretParams *server_params); SignalFfiError *signal_group_send_endorsements_response_check_valid_contents(SignalBorrowedBuffer bytes); @@ -1358,9 +1478,9 @@ SignalFfiError *signal_group_send_endorsements_response_issue_deterministic(Sign SignalFfiError *signal_group_send_endorsements_response_get_expiration(uint64_t *out, SignalBorrowedBuffer response_bytes); -SignalFfiError *signal_group_send_endorsements_response_receive_and_combine_with_service_ids(SignalBytestringArray *out, SignalBorrowedBuffer response_bytes, SignalBorrowedBuffer group_members, const SignalServiceIdFixedWidthBinaryBytes *local_user, uint64_t now, const unsigned char (*group_params)[SignalGROUP_SECRET_PARAMS_LEN], const unsigned char (*server_params)[SignalSERVER_PUBLIC_PARAMS_LEN]); +SignalFfiError *signal_group_send_endorsements_response_receive_and_combine_with_service_ids(SignalBytestringArray *out, SignalBorrowedBuffer response_bytes, SignalBorrowedBuffer group_members, const SignalServiceIdFixedWidthBinaryBytes *local_user, uint64_t now, const unsigned char (*group_params)[SignalGROUP_SECRET_PARAMS_LEN], const SignalServerPublicParams *server_params); -SignalFfiError *signal_group_send_endorsements_response_receive_and_combine_with_ciphertexts(SignalBytestringArray *out, SignalBorrowedBuffer response_bytes, SignalBorrowedBuffer concatenated_group_member_ciphertexts, SignalBorrowedBuffer local_user_ciphertext, uint64_t now, const unsigned char (*server_params)[SignalSERVER_PUBLIC_PARAMS_LEN]); +SignalFfiError *signal_group_send_endorsements_response_receive_and_combine_with_ciphertexts(SignalBytestringArray *out, SignalBorrowedBuffer response_bytes, SignalBorrowedBuffer concatenated_group_member_ciphertexts, SignalBorrowedBuffer local_user_ciphertext, uint64_t now, const SignalServerPublicParams *server_params); SignalFfiError *signal_group_send_endorsement_check_valid_contents(SignalBorrowedBuffer bytes); @@ -1382,13 +1502,9 @@ SignalFfiError *signal_group_send_full_token_verify(SignalBorrowedBuffer token, SignalFfiError *signal_verify_signature(bool *out, SignalBorrowedBuffer cert_pem, SignalBorrowedBuffer body, SignalBorrowedBuffer signature, uint64_t current_timestamp); -SignalFfiError *signal_tokio_async_context_new(SignalTokioAsyncContext **out); +SignalFfiError *signal_connection_manager_new(SignalConnectionManager **out, uint8_t environment, const char *user_agent); -SignalFfiError *signal_tokio_async_context_destroy(SignalTokioAsyncContext *p); - -SignalFfiError *signal_connection_manager_new(SignalConnectionManager **out, uint8_t environment); - -SignalFfiError *signal_connection_manager_set_proxy(const SignalConnectionManager *connection_manager, const char *host, uint16_t port); +SignalFfiError *signal_connection_manager_set_proxy(const SignalConnectionManager *connection_manager, const char *host, int32_t port); SignalFfiError *signal_connection_manager_clear_proxy(const SignalConnectionManager *connection_manager); @@ -1398,31 +1514,11 @@ SignalFfiError *signal_create_otp(const char **out, const char *username, Signal SignalFfiError *signal_create_otp_from_base64(const char **out, const char *username, const char *secret); -SignalFfiError *signal_svr3_backup(SignalCPromiseOwnedBufferOfc_uchar promise, const void *promise_context, const SignalTokioAsyncContext *async_runtime, const SignalConnectionManager *connection_manager, SignalBorrowedBuffer secret, const char *password, uint32_t max_tries, const char *username, const char *enclave_password); +SignalFfiError *signal_svr3_backup(SignalCPromiseOwnedBufferOfc_uchar *promise, const SignalTokioAsyncContext *async_runtime, const SignalConnectionManager *connection_manager, SignalBorrowedBuffer secret, const char *password, uint32_t max_tries, const char *username, const char *enclave_password); -SignalFfiError *signal_svr3_restore(SignalCPromiseOwnedBufferOfc_uchar promise, const void *promise_context, const SignalTokioAsyncContext *async_runtime, const SignalConnectionManager *connection_manager, const char *password, SignalBorrowedBuffer share_set, const char *username, const char *enclave_password); +SignalFfiError *signal_svr3_restore(SignalCPromiseOwnedBufferOfc_uchar *promise, const SignalTokioAsyncContext *async_runtime, const SignalConnectionManager *connection_manager, const char *password, SignalBorrowedBuffer share_set, const char *username, const char *enclave_password); -SignalFfiError *signal_chat_destroy(SignalChat *p); - -SignalFfiError *signal_http_request_destroy(SignalHttpRequest *p); - -SignalFfiError *signal_http_request_new_with_body(SignalHttpRequest **out, const char *method, const char *path, SignalBorrowedBuffer body_as_slice); - -SignalFfiError *signal_http_request_new_without_body(SignalHttpRequest **out, const char *method, const char *path); - -SignalFfiError *signal_http_request_add_header(const SignalHttpRequest *request, const char *name, const char *value); - -SignalFfiError *signal_chat_service_new(SignalChat **out, const SignalConnectionManager *connection_manager, const char *username, const char *password); - -SignalFfiError *signal_chat_service_disconnect(SignalCPromisebool promise, const void *promise_context, const SignalTokioAsyncContext *async_runtime, const SignalChat *chat); - -SignalFfiError *signal_chat_service_connect_unauth(SignalCPromiseFfiChatServiceDebugInfo promise, const void *promise_context, const SignalTokioAsyncContext *async_runtime, const SignalChat *chat); - -SignalFfiError *signal_chat_service_connect_auth(SignalCPromiseFfiChatServiceDebugInfo promise, const void *promise_context, const SignalTokioAsyncContext *async_runtime, const SignalChat *chat); - -SignalFfiError *signal_chat_service_unauth_send(SignalCPromiseFfiChatResponse promise, const void *promise_context, const SignalTokioAsyncContext *async_runtime, const SignalChat *chat, const SignalHttpRequest *http_request, uint32_t timeout_millis); - -SignalFfiError *signal_chat_service_unauth_send_and_debug(SignalCPromiseFfiResponseAndDebugInfo promise, const void *promise_context, const SignalTokioAsyncContext *async_runtime, const SignalChat *chat, const SignalHttpRequest *http_request, uint32_t timeout_millis); +SignalFfiError *signal_svr3_remove(SignalCPromisebool *promise, const SignalTokioAsyncContext *async_runtime, const SignalConnectionManager *connection_manager, const char *username, const char *enclave_password); SignalFfiError *signal_lookup_request_new(SignalLookupRequest **out); @@ -1440,11 +1536,51 @@ SignalFfiError *signal_lookup_request_destroy(SignalLookupRequest *p); SignalFfiError *signal_cdsi_lookup_destroy(SignalCdsiLookup *p); -SignalFfiError *signal_cdsi_lookup_new(SignalCPromiseCdsiLookup promise, const void *promise_context, const SignalTokioAsyncContext *async_runtime, const SignalConnectionManager *connection_manager, const char *username, const char *password, const SignalLookupRequest *request); +SignalFfiError *signal_cdsi_lookup_new(SignalCPromiseCdsiLookup *promise, const SignalTokioAsyncContext *async_runtime, const SignalConnectionManager *connection_manager, const char *username, const char *password, const SignalLookupRequest *request); SignalFfiError *signal_cdsi_lookup_token(SignalOwnedBuffer *out, const SignalCdsiLookup *lookup); -SignalFfiError *signal_cdsi_lookup_complete(SignalCPromiseFfiCdsiLookupResponse promise, const void *promise_context, const SignalTokioAsyncContext *async_runtime, const SignalCdsiLookup *lookup); +SignalFfiError *signal_cdsi_lookup_complete(SignalCPromiseFfiCdsiLookupResponse *promise, const SignalTokioAsyncContext *async_runtime, const SignalCdsiLookup *lookup); + +SignalFfiError *signal_chat_destroy(SignalChat *p); + +SignalFfiError *signal_http_request_destroy(SignalHttpRequest *p); + +SignalFfiError *signal_http_request_new_with_body(SignalHttpRequest **out, const char *method, const char *path, SignalBorrowedBuffer body_as_slice); + +SignalFfiError *signal_http_request_new_without_body(SignalHttpRequest **out, const char *method, const char *path); + +SignalFfiError *signal_http_request_add_header(const SignalHttpRequest *request, const char *name, const char *value); + +SignalFfiError *signal_chat_service_new(SignalChat **out, const SignalConnectionManager *connection_manager, const char *username, const char *password); + +SignalFfiError *signal_chat_service_disconnect(SignalCPromisebool *promise, const SignalTokioAsyncContext *async_runtime, const SignalChat *chat); + +SignalFfiError *signal_chat_service_connect_unauth(SignalCPromiseFfiChatServiceDebugInfo *promise, const SignalTokioAsyncContext *async_runtime, const SignalChat *chat); + +SignalFfiError *signal_chat_service_connect_auth(SignalCPromiseFfiChatServiceDebugInfo *promise, const SignalTokioAsyncContext *async_runtime, const SignalChat *chat); + +SignalFfiError *signal_chat_service_unauth_send(SignalCPromiseFfiChatResponse *promise, const SignalTokioAsyncContext *async_runtime, const SignalChat *chat, const SignalHttpRequest *http_request, uint32_t timeout_millis); + +SignalFfiError *signal_chat_service_unauth_send_and_debug(SignalCPromiseFfiResponseAndDebugInfo *promise, const SignalTokioAsyncContext *async_runtime, const SignalChat *chat, const SignalHttpRequest *http_request, uint32_t timeout_millis); + +SignalFfiError *signal_chat_service_auth_send(SignalCPromiseFfiChatResponse *promise, const SignalTokioAsyncContext *async_runtime, const SignalChat *chat, const SignalHttpRequest *http_request, uint32_t timeout_millis); + +SignalFfiError *signal_chat_service_auth_send_and_debug(SignalCPromiseFfiResponseAndDebugInfo *promise, const SignalTokioAsyncContext *async_runtime, const SignalChat *chat, const SignalHttpRequest *http_request, uint32_t timeout_millis); + +SignalFfiError *signal_chat_server_set_listener(const SignalTokioAsyncContext *runtime, const SignalChat *chat, const SignalFfiMakeChatListenerStruct *make_listener); + +SignalFfiError *signal_testing_chat_service_inject_raw_server_request(const SignalChat *chat, SignalBorrowedBuffer bytes); + +SignalFfiError *signal_server_message_ack_destroy(SignalServerMessageAck *p); + +SignalFfiError *signal_server_message_ack_send(SignalCPromisebool *promise, const SignalTokioAsyncContext *async_runtime, const SignalServerMessageAck *ack); + +SignalFfiError *signal_tokio_async_context_destroy(SignalTokioAsyncContext *p); + +SignalFfiError *signal_tokio_async_context_new(SignalTokioAsyncContext **out); + +SignalFfiError *signal_tokio_async_context_cancel(const SignalTokioAsyncContext *context, uint64_t raw_cancellation_id); SignalFfiError *signal_pin_hash_destroy(SignalPinHash *p); @@ -1542,9 +1678,9 @@ SignalFfiError *signal_sanitized_metadata_get_data_len(uint64_t *out, const Sign SignalFfiError *signal_testing_NonSuspendingBackgroundThreadRuntime_destroy(SignalNonSuspendingBackgroundThreadRuntime *p); -SignalFfiError *signal_testing_future_success(SignalCPromisei32 promise, const void *promise_context, const SignalNonSuspendingBackgroundThreadRuntime *async_runtime, uint8_t input); +SignalFfiError *signal_testing_future_success(SignalCPromisei32 *promise, const SignalNonSuspendingBackgroundThreadRuntime *async_runtime, uint8_t input); -SignalFfiError *signal_testing_future_failure(SignalCPromisei32 promise, const void *promise_context, const SignalNonSuspendingBackgroundThreadRuntime *async_runtime, uint8_t _input); +SignalFfiError *signal_testing_future_failure(SignalCPromisei32 *promise, const SignalNonSuspendingBackgroundThreadRuntime *async_runtime, uint8_t _input); SignalFfiError *signal_testing_handle_type_destroy(SignalTestingHandleType *p); @@ -1552,7 +1688,7 @@ SignalFfiError *signal_testing_handle_type_clone(SignalTestingHandleType **new_o SignalFfiError *signal_testing_testing_handle_type_get_value(uint8_t *out, const SignalTestingHandleType *handle); -SignalFfiError *signal_testing_future_produces_pointer_type(SignalCPromiseTestingHandleType promise, const void *promise_context, const SignalNonSuspendingBackgroundThreadRuntime *async_runtime, uint8_t input); +SignalFfiError *signal_testing_future_produces_pointer_type(SignalCPromiseTestingHandleType *promise, const SignalNonSuspendingBackgroundThreadRuntime *async_runtime, uint8_t input); SignalFfiError *signal_other_testing_handle_type_destroy(SignalOtherTestingHandleType *p); @@ -1560,55 +1696,55 @@ SignalFfiError *signal_other_testing_handle_type_clone(SignalOtherTestingHandleT SignalFfiError *signal_testing_other_testing_handle_type_get_value(const char **out, const SignalOtherTestingHandleType *handle); -SignalFfiError *signal_testing_future_produces_other_pointer_type(SignalCPromiseOtherTestingHandleType promise, const void *promise_context, const SignalNonSuspendingBackgroundThreadRuntime *async_runtime, const char *input); +SignalFfiError *signal_testing_future_produces_other_pointer_type(SignalCPromiseOtherTestingHandleType *promise, const SignalNonSuspendingBackgroundThreadRuntime *async_runtime, const char *input); SignalFfiError *signal_testing_panic_on_borrow_sync(const void *_input); SignalFfiError *signal_testing_panic_on_borrow_async(const void *_input); -SignalFfiError *signal_testing_panic_on_borrow_io(SignalCPromisebool promise, const void *promise_context, const SignalNonSuspendingBackgroundThreadRuntime *async_runtime, const void *_input); +SignalFfiError *signal_testing_panic_on_borrow_io(SignalCPromisebool *promise, const SignalNonSuspendingBackgroundThreadRuntime *async_runtime, const void *_input); SignalFfiError *signal_testing_error_on_borrow_sync(const void *_input); SignalFfiError *signal_testing_error_on_borrow_async(const void *_input); -SignalFfiError *signal_testing_error_on_borrow_io(SignalCPromisebool promise, const void *promise_context, const SignalNonSuspendingBackgroundThreadRuntime *async_runtime, const void *_input); +SignalFfiError *signal_testing_error_on_borrow_io(SignalCPromisebool *promise, const SignalNonSuspendingBackgroundThreadRuntime *async_runtime, const void *_input); SignalFfiError *signal_testing_panic_on_load_sync(const void *_needs_cleanup, const void *_input); SignalFfiError *signal_testing_panic_on_load_async(const void *_needs_cleanup, const void *_input); -SignalFfiError *signal_testing_panic_on_load_io(SignalCPromisebool promise, const void *promise_context, const SignalNonSuspendingBackgroundThreadRuntime *async_runtime, const void *_needs_cleanup, const void *_input); +SignalFfiError *signal_testing_panic_on_load_io(SignalCPromisebool *promise, const SignalNonSuspendingBackgroundThreadRuntime *async_runtime, const void *_needs_cleanup, const void *_input); SignalFfiError *signal_testing_panic_in_body_sync(const void *_input); SignalFfiError *signal_testing_panic_in_body_async(const void *_input); -SignalFfiError *signal_testing_panic_in_body_io(SignalCPromisebool promise, const void *promise_context, const SignalNonSuspendingBackgroundThreadRuntime *async_runtime, const void *_input); +SignalFfiError *signal_testing_panic_in_body_io(SignalCPromisebool *promise, const SignalNonSuspendingBackgroundThreadRuntime *async_runtime, const void *_input); SignalFfiError *signal_testing_panic_on_return_sync(const void **out, const void *_needs_cleanup); SignalFfiError *signal_testing_panic_on_return_async(const void **out, const void *_needs_cleanup); -SignalFfiError *signal_testing_panic_on_return_io(SignalCPromiseRawPointer promise, const void *promise_context, const SignalNonSuspendingBackgroundThreadRuntime *async_runtime, const void *_needs_cleanup); +SignalFfiError *signal_testing_panic_on_return_io(SignalCPromiseRawPointer *promise, const SignalNonSuspendingBackgroundThreadRuntime *async_runtime, const void *_needs_cleanup); SignalFfiError *signal_testing_error_on_return_sync(const void **out, const void *_needs_cleanup); SignalFfiError *signal_testing_error_on_return_async(const void **out, const void *_needs_cleanup); -SignalFfiError *signal_testing_error_on_return_io(SignalCPromiseRawPointer promise, const void *promise_context, const SignalNonSuspendingBackgroundThreadRuntime *async_runtime, const void *_needs_cleanup); +SignalFfiError *signal_testing_error_on_return_io(SignalCPromiseRawPointer *promise, const SignalNonSuspendingBackgroundThreadRuntime *async_runtime, const void *_needs_cleanup); SignalFfiError *signal_testing_return_string_array(SignalStringArray *out); SignalFfiError *signal_testing_process_bytestring_array(SignalBytestringArray *out, SignalBorrowedSliceOfBuffers input); -SignalFfiError *signal_testing_cdsi_lookup_response_convert(SignalCPromiseFfiCdsiLookupResponse promise, const void *promise_context, const SignalTokioAsyncContext *async_runtime); +SignalFfiError *signal_testing_cdsi_lookup_response_convert(SignalCPromiseFfiCdsiLookupResponse *promise, const SignalTokioAsyncContext *async_runtime); + +SignalFfiError *signal_testing_only_completes_by_cancellation(SignalCPromisebool *promise, const SignalTokioAsyncContext *async_runtime); SignalFfiError *signal_testing_cdsi_lookup_error_convert(const char *error_description); -SignalFfiError *signal_testing_chat_service_error_convert(void); - -SignalFfiError *signal_testing_chat_service_inactive_error_convert(void); +SignalFfiError *signal_testing_chat_service_error_convert(const char *error_description); SignalFfiError *signal_testing_chat_service_response_convert(SignalFfiChatResponse *out, bool body_present); diff --git a/pkg/libsignalgo/logging.go b/pkg/libsignalgo/logging.go index 2fcf8ba..a467b57 100644 --- a/pkg/libsignalgo/logging.go +++ b/pkg/libsignalgo/logging.go @@ -29,11 +29,6 @@ import "C" // ffiLogger is the global logger object. var ffiLogger Logger -//export signal_log_enabled_callback -func signal_log_enabled_callback(target *C.char, level C.SignalLogLevel) C.bool { - return C.bool(ffiLogger.Enabled(C.GoString(target), LogLevel(int(level)))) -} - //export signal_log_callback func signal_log_callback(target *C.char, level C.SignalLogLevel, file *C.char, line C.uint32_t, message *C.char) { ffiLogger.Log(C.GoString(target), LogLevel(int(level)), C.GoString(file), uint(line), C.GoString(message)) @@ -55,7 +50,6 @@ const ( ) type Logger interface { - Enabled(target string, level LogLevel) bool Log(target string, level LogLevel, file string, line uint, message string) Flush() } @@ -63,8 +57,7 @@ type Logger interface { func InitLogger(level LogLevel, logger Logger) { ffiLogger = logger C.signal_init_logger(C.SignalLogLevel(level), C.SignalFfiLogger{ - enabled: C.SignalLogEnabledCallback(C.signal_log_enabled_callback), - log: C.SignalLogCallback(C.signal_log_callback), - flush: C.SignalLogFlushCallback(C.signal_log_flush_callback), + log: C.SignalLogCallback(C.signal_log_callback), + flush: C.SignalLogFlushCallback(C.signal_log_flush_callback), }) } diff --git a/pkg/libsignalgo/profilekey.go b/pkg/libsignalgo/profilekey.go index 5d5f157..82e3036 100644 --- a/pkg/libsignalgo/profilekey.go +++ b/pkg/libsignalgo/profilekey.go @@ -136,13 +136,11 @@ type ProfileKeyCredentialRequestContext [C.SignalPROFILE_KEY_CREDENTIAL_REQUEST_ type ProfileKeyCredentialRequest [C.SignalPROFILE_KEY_CREDENTIAL_REQUEST_LEN]byte type ProfileKeyCredentialResponse []byte type ProfileKeyCredentialPresentation []byte -type ServerPublicParams [C.SignalSERVER_PUBLIC_PARAMS_LEN]byte type ExpiringProfileKeyCredential [C.SignalEXPIRING_PROFILE_KEY_CREDENTIAL_LEN]byte type ExpiringProfileKeyCredentialResponse [C.SignalEXPIRING_PROFILE_KEY_CREDENTIAL_RESPONSE_LEN]byte -func CreateProfileKeyCredentialRequestContext(serverPublicParams ServerPublicParams, u uuid.UUID, profileKey ProfileKey) (*ProfileKeyCredentialRequestContext, error) { +func CreateProfileKeyCredentialRequestContext(serverPublicParams *ServerPublicParams, u uuid.UUID, profileKey ProfileKey) (*ProfileKeyCredentialRequestContext, error) { c_result := [C.SignalPROFILE_KEY_CREDENTIAL_REQUEST_CONTEXT_LEN]C.uchar{} - c_serverPublicParams := (*[C.SignalSERVER_PUBLIC_PARAMS_LEN]C.uchar)(unsafe.Pointer(&serverPublicParams[0])) randBytes := [32]byte(random.Bytes(32)) c_random := (*[32]C.uchar)(unsafe.Pointer(&randBytes[0])) c_profileKey := (*[C.SignalPROFILE_KEY_LEN]C.uchar)(unsafe.Pointer(&profileKey[0])) @@ -150,12 +148,11 @@ func CreateProfileKeyCredentialRequestContext(serverPublicParams ServerPublicPar signalFfiError := C.signal_server_public_params_create_profile_key_credential_request_context_deterministic( &c_result, - c_serverPublicParams, + serverPublicParams, c_random, c_uuid, c_profileKey, ) - runtime.KeepAlive(serverPublicParams) runtime.KeepAlive(u) runtime.KeepAlive(profileKey) runtime.KeepAlive(randBytes) @@ -193,16 +190,15 @@ func NewExpiringProfileKeyCredentialResponse(b []byte) (*ExpiringProfileKeyCrede return &response, nil } -func ReceiveExpiringProfileKeyCredential(spp ServerPublicParams, requestContext *ProfileKeyCredentialRequestContext, response *ExpiringProfileKeyCredentialResponse, currentTimeInSeconds uint64) (*ExpiringProfileKeyCredential, error) { +func ReceiveExpiringProfileKeyCredential(spp *ServerPublicParams, requestContext *ProfileKeyCredentialRequestContext, response *ExpiringProfileKeyCredentialResponse, currentTimeInSeconds uint64) (*ExpiringProfileKeyCredential, error) { c_credential := [C.SignalEXPIRING_PROFILE_KEY_CREDENTIAL_LEN]C.uchar{} signalFfiError := C.signal_server_public_params_receive_expiring_profile_key_credential( &c_credential, - (*[C.SignalSERVER_PUBLIC_PARAMS_LEN]C.uchar)(unsafe.Pointer(&spp[0])), + spp, (*[C.SignalPROFILE_KEY_CREDENTIAL_REQUEST_CONTEXT_LEN]C.uchar)(unsafe.Pointer(requestContext)), (*[C.SignalEXPIRING_PROFILE_KEY_CREDENTIAL_RESPONSE_LEN]C.uchar)(unsafe.Pointer(response)), (C.uint64_t)(currentTimeInSeconds), ) - runtime.KeepAlive(spp) runtime.KeepAlive(requestContext) runtime.KeepAlive(response) runtime.KeepAlive(currentTimeInSeconds) diff --git a/pkg/libsignalgo/verifysignature.go b/pkg/libsignalgo/serverpublicparams.go similarity index 68% rename from pkg/libsignalgo/verifysignature.go rename to pkg/libsignalgo/serverpublicparams.go index 69d354e..6e99471 100644 --- a/pkg/libsignalgo/verifysignature.go +++ b/pkg/libsignalgo/serverpublicparams.go @@ -1,5 +1,5 @@ // mautrix-signal - A Matrix-signal puppeting bridge. -// Copyright (C) 2023 Scott Weber +// Copyright (C) 2024 Tulir Asokan // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU Affero General Public License as published by @@ -23,21 +23,34 @@ package libsignalgo */ import "C" import ( + "fmt" "runtime" "unsafe" ) +type ServerPublicParams = C.SignalServerPublicParams type NotarySignature [C.SignalSIGNATURE_LEN]byte +func DeserializeServerPublicParams(params []byte) (out *ServerPublicParams, err error) { + if len(params) != C.SignalSERVER_PUBLIC_PARAMS_LEN { + err = fmt.Errorf("invalid server public params length: %d (expected %d)", len(params), int(C.SignalSERVER_PUBLIC_PARAMS_LEN)) + return + } + signalFfiError := C.signal_server_public_params_deserialize(&out, BytesToBuffer(params[:])) + if signalFfiError != nil { + err = wrapError(signalFfiError) + } + return +} + func ServerPublicParamsVerifySignature( - serverPublicParams ServerPublicParams, + serverPublicParams *ServerPublicParams, messageBytes []byte, NotarySignature NotarySignature, ) error { c_notarySignature := (*[C.SignalSIGNATURE_LEN]C.uint8_t)(unsafe.Pointer(&NotarySignature[0])) - c_serverPublicParams := (*[C.SignalSERVER_PUBLIC_PARAMS_LEN]C.uchar)(unsafe.Pointer(&serverPublicParams[0])) signalFfiError := C.signal_server_public_params_verify_signature( - c_serverPublicParams, + serverPublicParams, BytesToBuffer(messageBytes), c_notarySignature, ) diff --git a/pkg/libsignalgo/version.go b/pkg/libsignalgo/version.go index ac15575..0bc1cb7 100644 --- a/pkg/libsignalgo/version.go +++ b/pkg/libsignalgo/version.go @@ -2,4 +2,4 @@ package libsignalgo -const Version = "v0.44.0" +const Version = "v0.49.0" diff --git a/pkg/signalmeow/misc.go b/pkg/signalmeow/misc.go index 0c305ee..1062dcb 100644 --- a/pkg/signalmeow/misc.go +++ b/pkg/signalmeow/misc.go @@ -20,6 +20,7 @@ import ( _ "embed" "github.com/rs/zerolog" + "go.mau.fi/util/exerrors" "go.mau.fi/mautrix-signal/pkg/libsignalgo" ) @@ -40,8 +41,6 @@ type FFILogger struct { logger zerolog.Logger } -func (FFILogger) Enabled(target string, level libsignalgo.LogLevel) bool { return true } - func (l FFILogger) Log(target string, level libsignalgo.LogLevel, file string, line uint, message string) { var evt *zerolog.Event switch level { @@ -73,8 +72,8 @@ var _ libsignalgo.Logger = FFILogger{} //go:embed prod-server-public-params.dat var prodServerPublicParamsSlice []byte -var prodServerPublicParams libsignalgo.ServerPublicParams +var prodServerPublicParams *libsignalgo.ServerPublicParams func init() { - prodServerPublicParams = libsignalgo.ServerPublicParams(prodServerPublicParamsSlice) + prodServerPublicParams = exerrors.Must(libsignalgo.DeserializeServerPublicParams(prodServerPublicParamsSlice)) } From 088badafa35320c40e8816b152a0fee2a0ef58fe Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Mon, 3 Jun 2024 18:37:08 +0300 Subject: [PATCH 029/580] Fix libsignal log interface --- pkg/libsignalgo/logging.go | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/pkg/libsignalgo/logging.go b/pkg/libsignalgo/logging.go index a467b57..132cc8a 100644 --- a/pkg/libsignalgo/logging.go +++ b/pkg/libsignalgo/logging.go @@ -20,22 +20,25 @@ package libsignalgo #cgo LDFLAGS: -lsignal_ffi -ldl -lm #include <./libsignal-ffi.h> -extern bool signal_log_enabled_callback(char *target, SignalLogLevel level); -extern void signal_log_callback(char *target, SignalLogLevel level, char *file, uint32_t line, char *message); +extern bool signal_log_enabled_callback(void *ctx, char *target, SignalLogLevel level); +extern void signal_log_callback(void *ctx, char *target, SignalLogLevel level, char *file, uint32_t line, char *message); extern void signal_log_flush_callback(); */ import "C" +import ( + "unsafe" +) // ffiLogger is the global logger object. var ffiLogger Logger //export signal_log_callback -func signal_log_callback(target *C.char, level C.SignalLogLevel, file *C.char, line C.uint32_t, message *C.char) { +func signal_log_callback(ctx unsafe.Pointer, target *C.char, level C.SignalLogLevel, file *C.char, line C.uint32_t, message *C.char) { ffiLogger.Log(C.GoString(target), LogLevel(int(level)), C.GoString(file), uint(line), C.GoString(message)) } //export signal_log_flush_callback -func signal_log_flush_callback() { +func signal_log_flush_callback(ctx unsafe.Pointer) { ffiLogger.Flush() } From 860fad4d5c26a3f236b3f43923bac3785183d55a Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Mon, 3 Jun 2024 19:10:09 +0300 Subject: [PATCH 030/580] Fix signal_log_flush_callback signature too --- pkg/libsignalgo/logging.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/pkg/libsignalgo/logging.go b/pkg/libsignalgo/logging.go index 132cc8a..2cbee01 100644 --- a/pkg/libsignalgo/logging.go +++ b/pkg/libsignalgo/logging.go @@ -20,9 +20,8 @@ package libsignalgo #cgo LDFLAGS: -lsignal_ffi -ldl -lm #include <./libsignal-ffi.h> -extern bool signal_log_enabled_callback(void *ctx, char *target, SignalLogLevel level); extern void signal_log_callback(void *ctx, char *target, SignalLogLevel level, char *file, uint32_t line, char *message); -extern void signal_log_flush_callback(); +extern void signal_log_flush_callback(void *ctx); */ import "C" import ( From 18116ea9f4ffab560613ff1a90d684af48801b1d Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Mon, 3 Jun 2024 22:34:33 +0300 Subject: [PATCH 031/580] Move login command to mautrix-go --- connector/connector.go | 2 +- connector/login.go | 155 ++++++++++++++++++++++++++ connector/mautrix-signal-v2/main.go | 166 +--------------------------- go.mod | 2 +- go.sum | 4 +- pkg/signalmeow/provisioning.go | 2 +- 6 files changed, 162 insertions(+), 169 deletions(-) create mode 100644 connector/login.go diff --git a/connector/connector.go b/connector/connector.go index 7e24be6..6c08eee 100644 --- a/connector/connector.go +++ b/connector/connector.go @@ -165,7 +165,7 @@ var _ bridgev2.NetworkConnector = (*SignalConnector)(nil) var _ bridgev2.NetworkAPI = (*SignalClient)(nil) var _ msgconv.PortalMethods = (*msgconvPortalMethods)(nil) -func (s *SignalConnector) PrepareLogin(ctx context.Context, login *bridgev2.UserLogin) error { +func (s *SignalConnector) LoadUserLogin(ctx context.Context, login *bridgev2.UserLogin) error { aci, err := uuid.Parse(string(login.ID)) if err != nil { return fmt.Errorf("failed to parse user login ID: %w", err) diff --git a/connector/login.go b/connector/login.go new file mode 100644 index 0000000..0265ae5 --- /dev/null +++ b/connector/login.go @@ -0,0 +1,155 @@ +// mautrix-signal - A Matrix-Signal puppeting bridge. +// Copyright (C) 2024 Tulir Asokan +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +package connector + +import ( + "context" + "fmt" + + "github.com/google/uuid" + + "go.mau.fi/mautrix-signal/pkg/signalmeow" + "maunium.net/go/mautrix/bridgev2" + "maunium.net/go/mautrix/bridgev2/database" +) + +func (s *SignalConnector) GetLoginFlows() []bridgev2.LoginFlow { + return []bridgev2.LoginFlow{{ + Name: "QR", + Description: "Scan a QR code to pair the bridge to your Signal app", + ID: "qr", + }} +} + +func (s *SignalConnector) CreateLogin(ctx context.Context, user *bridgev2.User, flowID string) (bridgev2.LoginProcess, error) { + if flowID != "qr" { + return nil, fmt.Errorf("invalid login flow ID") + } + return &QRLogin{User: user, Main: s}, nil +} + +type QRLogin struct { + User *bridgev2.User + Main *SignalConnector + cancelChan context.CancelFunc + ProvChan chan signalmeow.ProvisioningResponse +} + +var _ bridgev2.LoginProcessDisplayAndWait = (*QRLogin)(nil) + +func (qr *QRLogin) Cancel() { + qr.cancelChan() + go func() { + for range qr.ProvChan { + } + }() +} + +func (qr *QRLogin) Start(ctx context.Context) (*bridgev2.LoginStep, error) { + log := qr.Main.Bridge.Log.With(). + Str("action", "login"). + Stringer("user_id", qr.User.MXID). + Logger() + provCtx, cancel := context.WithCancel(log.WithContext(context.Background())) + qr.cancelChan = cancel + // Don't use the start context here: the channel will outlive the start request. + qr.ProvChan = signalmeow.PerformProvisioning(provCtx, qr.Main.Store, qr.Main.Config.DeviceName) + var resp signalmeow.ProvisioningResponse + select { + case resp = <-qr.ProvChan: + if resp.Err != nil || resp.State == signalmeow.StateProvisioningError { + return nil, resp.Err + } else if resp.State != signalmeow.StateProvisioningURLReceived { + return nil, fmt.Errorf("unexpected state %v", resp.State) + } + case <-ctx.Done(): + cancel() + return nil, ctx.Err() + // TODO separate timeout here? + } + return &bridgev2.LoginStep{ + Type: bridgev2.LoginStepTypeDisplayAndWait, + StepID: "fi.mau.signal.login.qr", + Instructions: "Scan the QR code on your Signal app to log in", + DisplayAndWaitParams: &bridgev2.LoginDisplayAndWaitParams{ + Type: bridgev2.LoginDisplayTypeQR, + Data: resp.ProvisioningURL, + }, + }, nil +} + +func (qr *QRLogin) Wait(ctx context.Context) (*bridgev2.LoginStep, error) { + if qr.ProvChan == nil { + return nil, fmt.Errorf("login not started") + } + defer qr.cancelChan() + + var signalID uuid.UUID + var signalPhone string + select { + case resp := <-qr.ProvChan: + if resp.Err != nil || resp.State == signalmeow.StateProvisioningError { + return nil, resp.Err + } else if resp.State != signalmeow.StateProvisioningDataReceived { + return nil, fmt.Errorf("unexpected state %v", resp.State) + } else if resp.ProvisioningData.ACI == uuid.Nil { + return nil, fmt.Errorf("no signal account ID received") + } + signalID = resp.ProvisioningData.ACI + signalPhone = resp.ProvisioningData.Number + case <-ctx.Done(): + return nil, ctx.Err() + } + + select { + case resp := <-qr.ProvChan: + if resp.Err != nil || resp.State == signalmeow.StateProvisioningError { + return nil, resp.Err + } else if resp.State != signalmeow.StateProvisioningPreKeysRegistered { + return nil, fmt.Errorf("unexpected state %v", resp.State) + } + case <-ctx.Done(): + return nil, ctx.Err() + } + + ul, err := qr.User.NewLogin(ctx, &database.UserLogin{ + ID: makeUserLoginID(signalID), + Metadata: map[string]any{ + "phone": signalPhone, + }, + }, nil) + if err != nil { + return nil, fmt.Errorf("failed to save new login: %w", err) + } + backgroundCtx := ul.Log.WithContext(context.Background()) + err = qr.Main.LoadUserLogin(backgroundCtx, ul) + if err != nil { + return nil, fmt.Errorf("failed to prepare connection after login: %w", err) + } + err = ul.Client.Connect(backgroundCtx) + if err != nil { + return nil, fmt.Errorf("failed to connect after login: %w", err) + } + return &bridgev2.LoginStep{ + Type: bridgev2.LoginStepTypeComplete, + StepID: "fi.mau.signal.login.complete", + Instructions: fmt.Sprintf("Successfully logged in as %s / %s", signalPhone, signalID), + CompleteParams: &bridgev2.LoginCompleteParams{ + UserLoginID: ul.ID, + }, + }, nil +} diff --git a/connector/mautrix-signal-v2/main.go b/connector/mautrix-signal-v2/main.go index 1ea34d9..42ebfa9 100644 --- a/connector/mautrix-signal-v2/main.go +++ b/connector/mautrix-signal-v2/main.go @@ -17,28 +17,18 @@ package main import ( - "fmt" "os" - "strings" - "time" - "github.com/google/uuid" - "github.com/skip2/go-qrcode" "go.mau.fi/util/dbutil" "go.mau.fi/util/exerrors" "go.mau.fi/util/exzerolog" "gopkg.in/yaml.v3" + "go.mau.fi/mautrix-signal/connector" "go.mau.fi/mautrix-signal/pkg/signalmeow" "maunium.net/go/mautrix/bridgev2" "maunium.net/go/mautrix/bridgev2/bridgeconfig" - "maunium.net/go/mautrix/bridgev2/database" "maunium.net/go/mautrix/bridgev2/matrix" - "maunium.net/go/mautrix/bridgev2/networkid" - "maunium.net/go/mautrix/event" - "maunium.net/go/mautrix/id" - - "go.mau.fi/mautrix-signal/connector" ) func main() { @@ -47,163 +37,11 @@ func main() { exerrors.PanicIfNotNil(yaml.Unmarshal(config, &cfg)) log := exerrors.Must(cfg.Logging.Compile()) exzerolog.SetupDefaults(log) + signalmeow.SetLogger(log.With().Str("component", "signalmeow").Logger()) db := exerrors.Must(dbutil.NewFromConfig("mautrix-signal", cfg.Database, dbutil.ZeroLogger(log.With().Str("db_section", "main").Logger()))) signalConnector := connector.NewConnector() exerrors.PanicIfNotNil(cfg.Network.Decode(signalConnector.Config)) bridge := bridgev2.NewBridge("", db, *log, matrix.NewConnector(&cfg), signalConnector) bridge.CommandPrefix = "!signal" - bridge.Commands.AddHandlers(&bridgev2.FullHandler{ - Func: fnLogin, - Name: "login", - Help: bridgev2.HelpMeta{ - Section: bridgev2.HelpSectionAuth, - Description: "Log into Signal", - }, - }) bridge.Start() } - -func sendQR(ce *bridgev2.CommandEvent, code string, prevQR, prevMsg id.EventID) (qr, msg id.EventID) { - content, ok := uploadQR(ce, code) - if !ok { - return prevQR, prevMsg - } - if len(prevQR) != 0 { - content.SetEdit(prevQR) - } - resp, err := ce.Bot.SendMessage(ce.Ctx, ce.RoomID, event.EventMessage, &event.Content{Parsed: &content}, time.Now()) - if err != nil { - ce.Log.Err(err).Msg("Failed to send QR code to user") - } else if len(prevQR) == 0 { - prevQR = resp.EventID - } - content = event.MessageEventContent{ - MsgType: event.MsgNotice, - Body: fmt.Sprintf("Raw linking URI: %s", code), - Format: event.FormatHTML, - FormattedBody: fmt.Sprintf("Raw linking URI: %s", code), - } - if len(prevMsg) != 0 { - content.SetEdit(prevMsg) - } - resp, err = ce.Bot.SendMessage(ce.Ctx, ce.RoomID, event.EventMessage, &event.Content{Parsed: &content}, time.Now()) - if err != nil { - ce.Log.Err(err).Msg("Failed to send raw code to user") - } else if len(prevMsg) == 0 { - prevMsg = resp.EventID - } - return prevQR, prevMsg -} - -func uploadQR(ce *bridgev2.CommandEvent, code string) (event.MessageEventContent, bool) { - const size = 512 - qrCode, err := qrcode.Encode(code, qrcode.Low, size) - if err != nil { - ce.Log.Err(err).Msg("Failed to encode QR code") - ce.Reply("Failed to encode QR code: %v", err) - return event.MessageEventContent{}, false - } - - uri, file, err := ce.Bot.UploadMedia(ce.Ctx, ce.RoomID, qrCode, "qr.png", "image/png") - if err != nil { - ce.Log.Err(err).Msg("Failed to upload QR code") - ce.Reply("Failed to upload QR code: %v", err) - return event.MessageEventContent{}, false - } - return event.MessageEventContent{ - MsgType: event.MsgImage, - Info: &event.FileInfo{ - MimeType: "image/png", - Width: size, - Height: size, - Size: len(qrCode), - }, - Body: "qr.png", - URL: uri, - File: file, - }, true -} -func fnLogin(ce *bridgev2.CommandEvent) { - signal := ce.Bridge.Network.(*connector.SignalConnector) - // TODO configurable device name - provChan := signalmeow.PerformProvisioning(ce.Ctx, signal.Store, "Mautrix-Signal Megabridge") - - resp := <-provChan - if resp.Err != nil || resp.State == signalmeow.StateProvisioningError { - ce.Reply("Error getting provisioning URL: %v", resp.Err) - return - } - var qrEventID, msgEventID id.EventID - if resp.State == signalmeow.StateProvisioningURLReceived { - qrEventID, msgEventID = sendQR(ce, resp.ProvisioningURL, qrEventID, msgEventID) - } else { - ce.Reply("Unexpected state: %v", resp.State) - return - } - - // Next, get the results of finishing registration - resp = <-provChan - _, _ = ce.Bot.SendMessage(ce.Ctx, ce.RoomID, event.EventRedaction, &event.Content{ - Parsed: &event.RedactionEventContent{ - Redacts: qrEventID, - }, - }, time.Now()) - _, _ = ce.Bot.SendMessage(ce.Ctx, ce.RoomID, event.EventRedaction, &event.Content{ - Parsed: &event.RedactionEventContent{ - Redacts: msgEventID, - }, - }, time.Now()) - if resp.Err != nil || resp.State == signalmeow.StateProvisioningError { - if resp.Err != nil && strings.HasSuffix(resp.Err.Error(), " EOF") { - ce.Reply("Logging in timed out, please try again.") - } else { - ce.Reply("Error finishing registration: %v", resp.Err) - } - return - } - var signalID uuid.UUID - var signalPhone string - if resp.State == signalmeow.StateProvisioningDataReceived { - signalID = resp.ProvisioningData.ACI - signalPhone = resp.ProvisioningData.Number - } else { - ce.Reply("Unexpected state: %v", resp.State) - return - } - - // Finally, get the results of generating and registering prekeys - resp = <-provChan - if resp.Err != nil || resp.State == signalmeow.StateProvisioningError { - ce.Reply("Error with prekeys: %v", resp.Err) - return - } else if resp.State != signalmeow.StateProvisioningPreKeysRegistered { - ce.Reply("Unexpected state: %v", resp.State) - return - } - - if signalID == uuid.Nil { - ce.Reply("Problem logging in - No SignalID received") - return - } - ul, err := ce.User.NewLogin(ce.Ctx, &database.UserLogin{ - ID: networkid.UserLoginID(signalID.String()), - Metadata: map[string]any{ - "phone": signalPhone, - }, - }, nil) - if err != nil { - ce.Reply("Failed to save new login: %v", err) - return - } - err = ce.Bridge.Network.PrepareLogin(ce.Ctx, ul) - if err != nil { - ce.Reply("Failed to prepare connection after login: %v", err) - return - } - err = ul.Client.Connect(ce.Ctx) - if err != nil { - ce.Reply("Failed to connect after login: %v", err) - return - } - ce.Reply("Successfully logged in as %s (UUID: %s)", signalPhone, signalID) -} diff --git a/go.mod b/go.mod index 913d3c1..42f5fbd 100644 --- a/go.mod +++ b/go.mod @@ -21,7 +21,7 @@ require ( golang.org/x/net v0.25.0 google.golang.org/protobuf v1.34.1 gopkg.in/yaml.v3 v3.0.1 - maunium.net/go/mautrix v0.18.2-0.20240529135554-248de0e6adb2 + maunium.net/go/mautrix v0.18.2-0.20240603193336-a599b15466ae nhooyr.io/websocket v1.8.11 ) diff --git a/go.sum b/go.sum index 641b71f..309bce5 100644 --- a/go.sum +++ b/go.sum @@ -95,7 +95,7 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= maunium.net/go/mauflag v1.0.0 h1:YiaRc0tEI3toYtJMRIfjP+jklH45uDHtT80nUamyD4M= maunium.net/go/mauflag v1.0.0/go.mod h1:nLivPOpTpHnpzEh8jEdSL9UqO9+/KBJFmNRlwKfkPeA= -maunium.net/go/mautrix v0.18.2-0.20240529135554-248de0e6adb2 h1:AUKv3tqpdFerCw2X8m05BGfhtP3vH8cDuEtAGxwuUl0= -maunium.net/go/mautrix v0.18.2-0.20240529135554-248de0e6adb2/go.mod h1:Ln4XquIKL5MttTUGNUSbiEGX3XYC0P6jzT9XjLFFPdY= +maunium.net/go/mautrix v0.18.2-0.20240603193336-a599b15466ae h1:PlT6saNJNjRT3i04LNLsFAC5ewZU1HrxBSM4V/Aze7k= +maunium.net/go/mautrix v0.18.2-0.20240603193336-a599b15466ae/go.mod h1:P/FV8cXY262MezYX7ViuhfzeJ0nK4+M8K6ZmxEC/aEA= nhooyr.io/websocket v1.8.11 h1:f/qXNc2/3DpoSZkHt1DQu6rj4zGC8JmkkLkWss0MgN0= nhooyr.io/websocket v1.8.11/go.mod h1:rN9OFWIUwuxg4fR5tELlYC04bXYowCP9GX47ivo2l+c= diff --git a/pkg/signalmeow/provisioning.go b/pkg/signalmeow/provisioning.go index 22a8b52..88f8485 100644 --- a/pkg/signalmeow/provisioning.go +++ b/pkg/signalmeow/provisioning.go @@ -81,7 +81,7 @@ type ProvisioningResponse struct { func PerformProvisioning(ctx context.Context, deviceStore store.DeviceStore, deviceName string) chan ProvisioningResponse { log := zerolog.Ctx(ctx).With().Str("action", "perform provisioning").Logger() - c := make(chan ProvisioningResponse) + c := make(chan ProvisioningResponse, 4) go func() { defer close(c) From 69de6afae21f858517ad669e67b18e10b7adcb72 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Tue, 4 Jun 2024 14:36:28 +0300 Subject: [PATCH 032/580] Reorganize v2 packages --- {connector => cmd}/mautrix-signal-v2/main.go | 6 +++--- {connector => cmd}/mautrix-signal-v2/start | 0 {connector => pkg/connector}/connector.go | 0 {connector => pkg/connector}/login.go | 4 ++-- 4 files changed, 5 insertions(+), 5 deletions(-) rename {connector => cmd}/mautrix-signal-v2/main.go (97%) rename {connector => cmd}/mautrix-signal-v2/start (100%) rename {connector => pkg/connector}/connector.go (100%) rename {connector => pkg/connector}/login.go (100%) diff --git a/connector/mautrix-signal-v2/main.go b/cmd/mautrix-signal-v2/main.go similarity index 97% rename from connector/mautrix-signal-v2/main.go rename to cmd/mautrix-signal-v2/main.go index 42ebfa9..4e02361 100644 --- a/connector/mautrix-signal-v2/main.go +++ b/cmd/mautrix-signal-v2/main.go @@ -23,12 +23,12 @@ import ( "go.mau.fi/util/exerrors" "go.mau.fi/util/exzerolog" "gopkg.in/yaml.v3" - - "go.mau.fi/mautrix-signal/connector" - "go.mau.fi/mautrix-signal/pkg/signalmeow" "maunium.net/go/mautrix/bridgev2" "maunium.net/go/mautrix/bridgev2/bridgeconfig" "maunium.net/go/mautrix/bridgev2/matrix" + + "go.mau.fi/mautrix-signal/pkg/connector" + "go.mau.fi/mautrix-signal/pkg/signalmeow" ) func main() { diff --git a/connector/mautrix-signal-v2/start b/cmd/mautrix-signal-v2/start similarity index 100% rename from connector/mautrix-signal-v2/start rename to cmd/mautrix-signal-v2/start diff --git a/connector/connector.go b/pkg/connector/connector.go similarity index 100% rename from connector/connector.go rename to pkg/connector/connector.go diff --git a/connector/login.go b/pkg/connector/login.go similarity index 100% rename from connector/login.go rename to pkg/connector/login.go index 0265ae5..34ac514 100644 --- a/connector/login.go +++ b/pkg/connector/login.go @@ -21,10 +21,10 @@ import ( "fmt" "github.com/google/uuid" - - "go.mau.fi/mautrix-signal/pkg/signalmeow" "maunium.net/go/mautrix/bridgev2" "maunium.net/go/mautrix/bridgev2/database" + + "go.mau.fi/mautrix-signal/pkg/signalmeow" ) func (s *SignalConnector) GetLoginFlows() []bridgev2.LoginFlow { From 204824bbaeda570f55c7509beff733b229917a29 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Wed, 5 Jun 2024 13:52:51 +0300 Subject: [PATCH 033/580] Add logout method and update message interface --- go.mod | 2 +- go.sum | 4 ++-- pkg/connector/connector.go | 27 ++++++++++++++++++++------- pkg/connector/login.go | 32 ++++++++++++++++++++++++-------- 4 files changed, 47 insertions(+), 18 deletions(-) diff --git a/go.mod b/go.mod index 42f5fbd..848b912 100644 --- a/go.mod +++ b/go.mod @@ -21,7 +21,7 @@ require ( golang.org/x/net v0.25.0 google.golang.org/protobuf v1.34.1 gopkg.in/yaml.v3 v3.0.1 - maunium.net/go/mautrix v0.18.2-0.20240603193336-a599b15466ae + maunium.net/go/mautrix v0.18.2-0.20240605105031-218ed06e73f6 nhooyr.io/websocket v1.8.11 ) diff --git a/go.sum b/go.sum index 309bce5..dfce129 100644 --- a/go.sum +++ b/go.sum @@ -95,7 +95,7 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= maunium.net/go/mauflag v1.0.0 h1:YiaRc0tEI3toYtJMRIfjP+jklH45uDHtT80nUamyD4M= maunium.net/go/mauflag v1.0.0/go.mod h1:nLivPOpTpHnpzEh8jEdSL9UqO9+/KBJFmNRlwKfkPeA= -maunium.net/go/mautrix v0.18.2-0.20240603193336-a599b15466ae h1:PlT6saNJNjRT3i04LNLsFAC5ewZU1HrxBSM4V/Aze7k= -maunium.net/go/mautrix v0.18.2-0.20240603193336-a599b15466ae/go.mod h1:P/FV8cXY262MezYX7ViuhfzeJ0nK4+M8K6ZmxEC/aEA= +maunium.net/go/mautrix v0.18.2-0.20240605105031-218ed06e73f6 h1:JkMk5Urz1niqsqOVWhoHculon2FSVrITM1g1iVMcxhU= +maunium.net/go/mautrix v0.18.2-0.20240605105031-218ed06e73f6/go.mod h1:P/FV8cXY262MezYX7ViuhfzeJ0nK4+M8K6ZmxEC/aEA= nhooyr.io/websocket v1.8.11 h1:f/qXNc2/3DpoSZkHt1DQu6rj4zGC8JmkkLkWss0MgN0= nhooyr.io/websocket v1.8.11/go.mod h1:rN9OFWIUwuxg4fR5tELlYC04bXYowCP9GX47ivo2l+c= diff --git a/pkg/connector/connector.go b/pkg/connector/connector.go index 6c08eee..a0fc4ee 100644 --- a/pkg/connector/connector.go +++ b/pkg/connector/connector.go @@ -194,6 +194,17 @@ type SignalClient struct { Client *signalmeow.Client } +func (s *SignalClient) LogoutRemote(ctx context.Context) { + err := s.Client.StopReceiveLoops() + if err != nil { + zerolog.Ctx(ctx).Err(err).Msg("Failed to stop receive loops for logout") + } + err = s.Main.Store.DeleteDevice(context.TODO(), &s.Client.Store.DeviceData) + if err != nil { + zerolog.Ctx(ctx).Err(err).Msg("Failed to delete device from store") + } +} + func (s *SignalClient) contactToUserInfo(contact *types.Recipient) *bridgev2.UserInfo { isBot := false ui := &bridgev2.UserInfo{ @@ -409,10 +420,10 @@ type msgconvContext struct { ReplyTo *database.Message } -func (s *SignalClient) convertMessage(ctx context.Context, portal *bridgev2.Portal, data *events.ChatEvent) (*bridgev2.ConvertedMessage, error) { +func (s *SignalClient) convertMessage(ctx context.Context, portal *bridgev2.Portal, intent bridgev2.MatrixAPI, data *events.ChatEvent) (*bridgev2.ConvertedMessage, error) { mcCtx := &msgconvContext{ Connector: s.Main, - Intent: s.Main.Bridge.Bot, // TODO get correct intent? + Intent: intent, Client: s, Portal: portal, } @@ -437,11 +448,11 @@ func (s *SignalClient) convertMessage(ctx context.Context, portal *bridgev2.Port } return &bridgev2.ConvertedMessage{ - ID: makeMessageID(data.Info.Sender, dataMsg.GetTimestamp()), - EventSender: s.makeEventSender(data.Info.Sender), - Timestamp: time.UnixMilli(int64(converted.Timestamp)), - ReplyTo: replyTo, - Parts: convertedParts, + //ID: makeMessageID(data.Info.Sender, dataMsg.GetTimestamp()), + //EventSender: s.makeEventSender(data.Info.Sender), + Timestamp: time.UnixMilli(int64(converted.Timestamp)), + ReplyTo: replyTo, + Parts: convertedParts, }, nil } @@ -457,6 +468,8 @@ func (s *SignalClient) handleSignalEvent(rawEvt events.SignalEvent) { Uint64("message_id", innerEvt.GetTimestamp()). Stringer("sender_id", evt.Info.Sender) }, + ID: makeMessageID(evt.Info.Sender, innerEvt.GetTimestamp()), + Sender: s.makeEventSender(evt.Info.Sender), PortalID: s.getPortalID(evt.Info.ChatID), Data: evt, CreatePortal: true, diff --git a/pkg/connector/login.go b/pkg/connector/login.go index 34ac514..cd25e60 100644 --- a/pkg/connector/login.go +++ b/pkg/connector/login.go @@ -44,6 +44,7 @@ func (s *SignalConnector) CreateLogin(ctx context.Context, user *bridgev2.User, type QRLogin struct { User *bridgev2.User + Existing *bridgev2.UserLogin Main *SignalConnector cancelChan context.CancelFunc ProvChan chan signalmeow.ProvisioningResponse @@ -114,6 +115,10 @@ func (qr *QRLogin) Wait(ctx context.Context) (*bridgev2.LoginStep, error) { case <-ctx.Done(): return nil, ctx.Err() } + newLoginID := makeUserLoginID(signalID) + if qr.Existing != nil && qr.Existing.ID != newLoginID { + return nil, fmt.Errorf("user ID mismatch for re-auth") + } select { case resp := <-qr.ProvChan: @@ -126,14 +131,25 @@ func (qr *QRLogin) Wait(ctx context.Context) (*bridgev2.LoginStep, error) { return nil, ctx.Err() } - ul, err := qr.User.NewLogin(ctx, &database.UserLogin{ - ID: makeUserLoginID(signalID), - Metadata: map[string]any{ - "phone": signalPhone, - }, - }, nil) - if err != nil { - return nil, fmt.Errorf("failed to save new login: %w", err) + var ul *bridgev2.UserLogin + var err error + if qr.Existing == nil { + ul, err = qr.User.NewLogin(ctx, &database.UserLogin{ + ID: newLoginID, + Metadata: map[string]any{ + "phone": signalPhone, + }, + }, nil) + if err != nil { + return nil, fmt.Errorf("failed to save new login: %w", err) + } + } else { + ul = qr.Existing + ul.Metadata["phone"] = signalPhone + err = ul.Save(ctx) + if err != nil { + return nil, fmt.Errorf("failed to update existing login: %w", err) + } } backgroundCtx := ul.Log.WithContext(context.Background()) err = qr.Main.LoadUserLogin(backgroundCtx, ul) From 7e74d98371b564ce9125c2ed72e9f780f80c7496 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Thu, 6 Jun 2024 16:11:58 +0300 Subject: [PATCH 034/580] Implement Matrix reactions, edits and redactions --- go.mod | 2 +- go.sum | 4 +- pkg/connector/connector.go | 193 +++++++++++++++++++++++++++++++------ pkg/signalmeow/sending.go | 7 ++ 4 files changed, 174 insertions(+), 32 deletions(-) diff --git a/go.mod b/go.mod index 848b912..fee3d52 100644 --- a/go.mod +++ b/go.mod @@ -21,7 +21,7 @@ require ( golang.org/x/net v0.25.0 google.golang.org/protobuf v1.34.1 gopkg.in/yaml.v3 v3.0.1 - maunium.net/go/mautrix v0.18.2-0.20240605105031-218ed06e73f6 + maunium.net/go/mautrix v0.18.2-0.20240606131110-a0e309fa55ab nhooyr.io/websocket v1.8.11 ) diff --git a/go.sum b/go.sum index dfce129..b80546d 100644 --- a/go.sum +++ b/go.sum @@ -95,7 +95,7 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= maunium.net/go/mauflag v1.0.0 h1:YiaRc0tEI3toYtJMRIfjP+jklH45uDHtT80nUamyD4M= maunium.net/go/mauflag v1.0.0/go.mod h1:nLivPOpTpHnpzEh8jEdSL9UqO9+/KBJFmNRlwKfkPeA= -maunium.net/go/mautrix v0.18.2-0.20240605105031-218ed06e73f6 h1:JkMk5Urz1niqsqOVWhoHculon2FSVrITM1g1iVMcxhU= -maunium.net/go/mautrix v0.18.2-0.20240605105031-218ed06e73f6/go.mod h1:P/FV8cXY262MezYX7ViuhfzeJ0nK4+M8K6ZmxEC/aEA= +maunium.net/go/mautrix v0.18.2-0.20240606131110-a0e309fa55ab h1:e0Zo3/K+quT6p+U2Gsmw8R1kinzZ0wOkPbVPwoMkrBY= +maunium.net/go/mautrix v0.18.2-0.20240606131110-a0e309fa55ab/go.mod h1:P/FV8cXY262MezYX7ViuhfzeJ0nK4+M8K6ZmxEC/aEA= nhooyr.io/websocket v1.8.11 h1:f/qXNc2/3DpoSZkHt1DQu6rj4zGC8JmkkLkWss0MgN0= nhooyr.io/websocket v1.8.11/go.mod h1:rN9OFWIUwuxg4fR5tELlYC04bXYowCP9GX47ivo2l+c= diff --git a/pkg/connector/connector.go b/pkg/connector/connector.go index a0fc4ee..9075567 100644 --- a/pkg/connector/connector.go +++ b/pkg/connector/connector.go @@ -27,6 +27,7 @@ import ( "github.com/google/uuid" "github.com/rs/zerolog" "go.mau.fi/util/dbutil" + "go.mau.fi/util/variationselector" "golang.org/x/exp/slices" "google.golang.org/protobuf/proto" @@ -381,6 +382,20 @@ func (s *SignalClient) getPortalID(chatID string) networkid.PortalID { } } +func parseMessageID(messageID networkid.MessageID) (sender uuid.UUID, timestamp uint64, err error) { + parts := strings.Split(string(messageID), "|") + if len(parts) != 2 { + err = fmt.Errorf("invalid message ID: expected two pipe-separated parts") + return + } + sender, err = uuid.Parse(parts[0]) + if err != nil { + return + } + timestamp, err = strconv.ParseUint(parts[1], 10, 64) + return +} + func makeMessageID(sender uuid.UUID, timestamp uint64) networkid.MessageID { return networkid.MessageID(fmt.Sprintf("%s|%d", sender, timestamp)) } @@ -519,31 +534,18 @@ func (s *SignalClient) HandleMatrixMessage(ctx context.Context, msg *bridgev2.Ma ReplyTo: msg.ReplyTo, } ctx = context.WithValue(ctx, msgconvContextKey, mcCtx) - userID, groupID, err := s.parsePortalID(msg.Portal.ID) - if err != nil { - return nil, err - } converted, err := s.Main.MsgConv.ToSignal(ctx, msg.Event, msg.Content, msg.OrigSender != nil) if err != nil { return nil, err } - wrappedContent := &signalpb.Content{ - DataMessage: converted, - } - if groupID != "" { - res, err := s.Client.SendGroupMessage(ctx, groupID, wrappedContent) - if err != nil { - return nil, err - } - // TODO check result - fmt.Println(res) - } else { - res := s.Client.SendMessage(ctx, userID, wrappedContent) - // TODO check result - fmt.Println(res) + res, err := s.sendMessage(ctx, msg.Portal.ID, &signalpb.Content{DataMessage: converted}) + if err != nil { + return nil, err } + // TODO check result + fmt.Println(res) meta := map[string]any{ - "reply_to_file": len(converted.Attachments) > 0, + "contains_attachments": len(converted.Attachments) > 0, } dbMsg := &database.Message{ ID: makeMessageID(s.Client.Store.ACI, converted.GetTimestamp()), @@ -560,23 +562,156 @@ func (s *SignalClient) HandleMatrixMessage(ctx context.Context, msg *bridgev2.Ma } func (s *SignalClient) HandleMatrixEdit(ctx context.Context, msg *bridgev2.MatrixEdit) error { - //TODO implement me - panic("implement me") + _, targetSentTimestamp, err := parseMessageID(msg.EditTarget.ID) + if err != nil { + return fmt.Errorf("failed to parse target message ID: %w", err) + } else if msg.EditTarget.SenderID != makeUserID(s.Client.Store.ACI) { + return fmt.Errorf("cannot edit other people's messages") + } + mcCtx := &msgconvContext{ + Connector: s.Main, + Intent: nil, + Client: s, + Portal: msg.Portal, + } + if msg.EditTarget.RelatesToRowID != 0 { + var err error + mcCtx.ReplyTo, err = s.Main.Bridge.DB.Message.GetByRowID(ctx, msg.EditTarget.RelatesToRowID) + if err != nil { + return fmt.Errorf("failed to get message reply target: %w", err) + } + } + ctx = context.WithValue(ctx, msgconvContextKey, mcCtx) + converted, err := s.Main.MsgConv.ToSignal(ctx, msg.Event, msg.Content, msg.OrigSender != nil) + if err != nil { + return err + } + res, err := s.sendMessage(ctx, msg.Portal.ID, &signalpb.Content{EditMessage: &signalpb.EditMessage{ + TargetSentTimestamp: proto.Uint64(targetSentTimestamp), + DataMessage: converted, + }}) + if err != nil { + return err + } + // TODO check result + fmt.Println(res) + msg.EditTarget.ID = makeMessageID(s.Client.Store.ACI, converted.GetTimestamp()) + msg.EditTarget.Metadata["contains_attachments"] = len(converted.Attachments) > 0 + return nil } -func (s *SignalClient) HandleMatrixReaction(ctx context.Context, msg *bridgev2.MatrixReaction) (emojiID networkid.EmojiID, err error) { - //TODO implement me - panic("implement me") +func (s *SignalClient) sendMessage(ctx context.Context, portalID networkid.PortalID, content *signalpb.Content) (signalmeow.SendResult, error) { + userID, groupID, err := s.parsePortalID(portalID) + if err != nil { + return nil, err + } + if groupID != "" { + res, err := s.Client.SendGroupMessage(ctx, groupID, content) + if err != nil { + return nil, err + } + return res, nil + } else { + res := s.Client.SendMessage(ctx, userID, content) + return &res, nil + } +} + +func (s *SignalClient) HandleMatrixReaction(ctx context.Context, msg *bridgev2.MatrixReaction) (reaction *database.Reaction, err error) { + senderID := makeUserID(s.Client.Store.ACI) + // emojiID is always empty because only one reaction is allowed per message+user + var emojiID networkid.EmojiID + signalEmoji := variationselector.FullyQualify(msg.Content.RelatesTo.Key) + if existing, err := msg.GetExisting(ctx, senderID, emojiID); err != nil { + return nil, fmt.Errorf("failed to check for duplicate reaction: %w", err) + } else if existing != nil && existing.Metadata["emoji"] == signalEmoji { + return nil, nil + } + targetAuthorACI, targetSentTimestamp, err := parseMessageID(msg.TargetMessage.ID) + if err != nil { + return nil, fmt.Errorf("failed to parse target message ID: %w", err) + } + wrappedContent := &signalpb.Content{ + DataMessage: &signalpb.DataMessage{ + Timestamp: proto.Uint64(uint64(msg.Event.Timestamp)), + RequiredProtocolVersion: proto.Uint32(uint32(signalpb.DataMessage_REACTIONS)), + Reaction: &signalpb.DataMessage_Reaction{ + Emoji: proto.String(signalEmoji), + Remove: proto.Bool(false), + TargetAuthorAci: proto.String(targetAuthorACI.String()), + TargetSentTimestamp: proto.Uint64(targetSentTimestamp), + }, + }, + } + res, err := s.sendMessage(ctx, msg.Portal.ID, wrappedContent) + if err != nil { + return nil, err + } + // TODO check result + fmt.Println(res) + return &database.Reaction{ + RoomID: msg.Portal.ID, + MessageID: msg.TargetMessage.ID, + MessagePartID: msg.TargetMessage.PartID, + SenderID: senderID, + EmojiID: emojiID, + MXID: msg.Event.ID, + Timestamp: time.UnixMilli(msg.Event.Timestamp), + Metadata: map[string]any{ + "emoji": signalEmoji, + }, + }, nil } func (s *SignalClient) HandleMatrixReactionRemove(ctx context.Context, msg *bridgev2.MatrixReactionRemove) error { - //TODO implement me - panic("implement me") + emoji, _ := msg.TargetReaction.Metadata["emoji"].(string) + targetAuthorACI, targetSentTimestamp, err := parseMessageID(msg.TargetReaction.MessageID) + if err != nil { + return fmt.Errorf("failed to parse target message ID: %w", err) + } + wrappedContent := &signalpb.Content{ + DataMessage: &signalpb.DataMessage{ + Timestamp: proto.Uint64(uint64(msg.Event.Timestamp)), + RequiredProtocolVersion: proto.Uint32(uint32(signalpb.DataMessage_REACTIONS)), + Reaction: &signalpb.DataMessage_Reaction{ + Emoji: proto.String(emoji), + Remove: proto.Bool(true), + TargetAuthorAci: proto.String(targetAuthorACI.String()), + TargetSentTimestamp: proto.Uint64(targetSentTimestamp), + }, + }, + } + res, err := s.sendMessage(ctx, msg.Portal.ID, wrappedContent) + if err != nil { + return err + } + // TODO check result + fmt.Println(res) + return nil } func (s *SignalClient) HandleMatrixMessageRemove(ctx context.Context, msg *bridgev2.MatrixMessageRemove) error { - //TODO implement me - panic("implement me") + _, targetSentTimestamp, err := parseMessageID(msg.TargetMessage.ID) + if err != nil { + return fmt.Errorf("failed to parse target message ID: %w", err) + } else if msg.TargetMessage.SenderID != makeUserID(s.Client.Store.ACI) { + return fmt.Errorf("cannot delete other people's messages") + } + wrappedContent := &signalpb.Content{ + DataMessage: &signalpb.DataMessage{ + Timestamp: proto.Uint64(uint64(msg.Event.Timestamp)), + Delete: &signalpb.DataMessage_Delete{ + TargetSentTimestamp: proto.Uint64(targetSentTimestamp), + }, + }, + } + res, err := s.sendMessage(ctx, msg.Portal.ID, wrappedContent) + if err != nil { + return err + } + // TODO check result + fmt.Println(res) + return nil } type msgconvPortalMethods struct{} @@ -606,7 +741,7 @@ func (mpm *msgconvPortalMethods) GetSignalReply(ctx context.Context, content *ev AuthorAci: proto.String(string(mcCtx.ReplyTo.SenderID)), Type: signalpb.DataMessage_Quote_NORMAL.Enum(), } - if mcCtx.ReplyTo.Metadata["reply_to_file"] != false { + if mcCtx.ReplyTo.Metadata["contains_attachments"] != false { quote.Attachments = make([]*signalpb.DataMessage_Quote_QuotedAttachment, 1) } return quote diff --git a/pkg/signalmeow/sending.go b/pkg/signalmeow/sending.go index 11211e0..053e335 100644 --- a/pkg/signalmeow/sending.go +++ b/pkg/signalmeow/sending.go @@ -304,6 +304,13 @@ type GroupMessageSendResult struct { FailedToSendTo []FailedSendResult } +type SendResult interface { + isSendResult() +} + +func (gmsr *GroupMessageSendResult) isSendResult() {} +func (smsr *SendMessageResult) isSendResult() {} + func contentFromDataMessage(dataMessage *signalpb.DataMessage) *signalpb.Content { return &signalpb.Content{ DataMessage: dataMessage, From 851aac5f45aa768f7871538d6c17976471a612ea Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Thu, 6 Jun 2024 21:01:49 +0300 Subject: [PATCH 035/580] Stop using SimpleRemoteEvent --- go.mod | 2 +- go.sum | 4 +- pkg/connector/connector.go | 206 +++++++++++++++++++++++++++++++------ 3 files changed, 179 insertions(+), 33 deletions(-) diff --git a/go.mod b/go.mod index fee3d52..726ed5a 100644 --- a/go.mod +++ b/go.mod @@ -21,7 +21,7 @@ require ( golang.org/x/net v0.25.0 google.golang.org/protobuf v1.34.1 gopkg.in/yaml.v3 v3.0.1 - maunium.net/go/mautrix v0.18.2-0.20240606131110-a0e309fa55ab + maunium.net/go/mautrix v0.18.2-0.20240606175822-a150a4760419 nhooyr.io/websocket v1.8.11 ) diff --git a/go.sum b/go.sum index b80546d..d6720a8 100644 --- a/go.sum +++ b/go.sum @@ -95,7 +95,7 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= maunium.net/go/mauflag v1.0.0 h1:YiaRc0tEI3toYtJMRIfjP+jklH45uDHtT80nUamyD4M= maunium.net/go/mauflag v1.0.0/go.mod h1:nLivPOpTpHnpzEh8jEdSL9UqO9+/KBJFmNRlwKfkPeA= -maunium.net/go/mautrix v0.18.2-0.20240606131110-a0e309fa55ab h1:e0Zo3/K+quT6p+U2Gsmw8R1kinzZ0wOkPbVPwoMkrBY= -maunium.net/go/mautrix v0.18.2-0.20240606131110-a0e309fa55ab/go.mod h1:P/FV8cXY262MezYX7ViuhfzeJ0nK4+M8K6ZmxEC/aEA= +maunium.net/go/mautrix v0.18.2-0.20240606175822-a150a4760419 h1:6JOCYkxS/nfhK/J3o+kkJgUDRaPRGgQXaxZj5HX5jys= +maunium.net/go/mautrix v0.18.2-0.20240606175822-a150a4760419/go.mod h1:P/FV8cXY262MezYX7ViuhfzeJ0nK4+M8K6ZmxEC/aEA= nhooyr.io/websocket v1.8.11 h1:f/qXNc2/3DpoSZkHt1DQu6rj4zGC8JmkkLkWss0MgN0= nhooyr.io/websocket v1.8.11/go.mod h1:rN9OFWIUwuxg4fR5tELlYC04bXYowCP9GX47ivo2l+c= diff --git a/pkg/connector/connector.go b/pkg/connector/connector.go index 9075567..f46270e 100644 --- a/pkg/connector/connector.go +++ b/pkg/connector/connector.go @@ -435,16 +435,157 @@ type msgconvContext struct { ReplyTo *database.Message } -func (s *SignalClient) convertMessage(ctx context.Context, portal *bridgev2.Portal, intent bridgev2.MatrixAPI, data *events.ChatEvent) (*bridgev2.ConvertedMessage, error) { +type Bv2ChatEvent struct { + *events.ChatEvent + s *SignalClient +} + +var ( + _ bridgev2.RemoteMessage = (*Bv2ChatEvent)(nil) + _ bridgev2.RemoteEdit = (*Bv2ChatEvent)(nil) + _ bridgev2.RemoteEventWithTimestamp = (*Bv2ChatEvent)(nil) + _ bridgev2.RemoteReactionWithMeta = (*Bv2ChatEvent)(nil) + _ bridgev2.RemoteMessageRemove = (*Bv2ChatEvent)(nil) +) + +func (evt *Bv2ChatEvent) GetType() bridgev2.RemoteEventType { + switch innerEvt := evt.Event.(type) { + case *signalpb.DataMessage: + switch { + case innerEvt.Body != nil, innerEvt.Attachments != nil, innerEvt.Contact != nil, innerEvt.Sticker != nil: + return bridgev2.RemoteEventMessage + case innerEvt.Reaction != nil: + if innerEvt.Reaction.GetRemove() { + return bridgev2.RemoteEventReactionRemove + } + return bridgev2.RemoteEventReaction + case innerEvt.Delete != nil: + return bridgev2.RemoteEventMessageRemove + } + case *signalpb.EditMessage: + return bridgev2.RemoteEventEdit + case *signalpb.TypingMessage: + //return bridgev2.RemoteEventTyping + } + return bridgev2.RemoteEventUnknown +} + +func (evt *Bv2ChatEvent) GetPortalID() networkid.PortalID { + return evt.s.getPortalID(evt.Info.ChatID) +} + +func (evt *Bv2ChatEvent) ShouldCreatePortal() bool { + return evt.GetType() == bridgev2.RemoteEventMessage +} + +func (evt *Bv2ChatEvent) AddLogContext(c zerolog.Context) zerolog.Context { + c = c.Stringer("sender_id", evt.Info.Sender) + switch innerEvt := evt.Event.(type) { + case *signalpb.DataMessage: + c = c.Uint64("message_ts", innerEvt.GetTimestamp()) + switch { + case innerEvt.Reaction != nil: + c = c.Uint64("reaction_target_ts", innerEvt.Reaction.GetTargetSentTimestamp()) + case innerEvt.Delete != nil: + c = c.Uint64("delete_target_ts", innerEvt.Delete.GetTargetSentTimestamp()) + } + case *signalpb.EditMessage: + c = c. + Uint64("edit_target_ts", innerEvt.GetTargetSentTimestamp()). + Uint64("edit_ts", innerEvt.GetDataMessage().GetTimestamp()) + } + return c +} + +func (evt *Bv2ChatEvent) GetSender() bridgev2.EventSender { + return evt.s.makeEventSender(evt.Info.Sender) +} + +func (evt *Bv2ChatEvent) GetID() networkid.MessageID { + ts := evt.getDataMsgTimestamp() + if ts == 0 { + panic(fmt.Errorf("GetID() called for non-DataMessage event")) + } + return makeMessageID(evt.Info.Sender, ts) +} + +func (evt *Bv2ChatEvent) getDataMsgTimestamp() uint64 { + switch innerEvt := evt.Event.(type) { + case *signalpb.DataMessage: + return innerEvt.GetTimestamp() + case *signalpb.EditMessage: + return innerEvt.GetDataMessage().GetTimestamp() + default: + return 0 + } +} + +func (evt *Bv2ChatEvent) GetTimestamp() time.Time { + ts := evt.getDataMsgTimestamp() + if ts == 0 { + return time.Now() + } + return time.UnixMilli(int64(ts)) +} + +func (evt *Bv2ChatEvent) GetTargetMessage() networkid.MessageID { + var targetAuthorACI string + var targetSentTS uint64 + switch innerEvt := evt.Event.(type) { + case *signalpb.DataMessage: + switch { + case innerEvt.Reaction != nil: + targetAuthorACI = innerEvt.Reaction.GetTargetAuthorAci() + targetSentTS = innerEvt.Reaction.GetTargetSentTimestamp() + case innerEvt.Delete != nil: + targetSentTS = innerEvt.Delete.GetTargetSentTimestamp() + default: + panic(fmt.Errorf("GetTargetMessage() called for message type without target")) + } + case *signalpb.EditMessage: + targetSentTS = innerEvt.GetTargetSentTimestamp() + default: + panic(fmt.Errorf("GetTargetMessage() called for message type without target")) + } + targetAuthorUUID := evt.Info.Sender + if targetAuthorACI != "" { + targetAuthorUUID, _ = uuid.Parse(targetAuthorACI) + } + return makeMessageID(targetAuthorUUID, targetSentTS) +} + +func (evt *Bv2ChatEvent) GetReactionEmoji() (string, networkid.EmojiID) { + dataMsg, ok := evt.Event.(*signalpb.DataMessage) + if !ok || dataMsg.Reaction == nil { + panic(fmt.Errorf("GetReactionEmoji() called for non-reaction event")) + } + return dataMsg.GetReaction().GetEmoji(), "" +} + +func (evt *Bv2ChatEvent) GetReactionDBMetadata() map[string]any { + dataMsg, ok := evt.Event.(*signalpb.DataMessage) + if !ok || dataMsg.Reaction == nil { + return map[string]any{} + } + return map[string]any{ + "emoji": dataMsg.GetReaction().GetEmoji(), + } +} + +func (evt *Bv2ChatEvent) ConvertMessage(ctx context.Context, portal *bridgev2.Portal, intent bridgev2.MatrixAPI) (*bridgev2.ConvertedMessage, error) { mcCtx := &msgconvContext{ - Connector: s.Main, + Connector: evt.s.Main, Intent: intent, - Client: s, + Client: evt.s, Portal: portal, } ctx = context.WithValue(ctx, msgconvContextKey, mcCtx) - dataMsg := data.Event.(*signalpb.DataMessage) - converted := s.Main.MsgConv.ToMatrix(ctx, dataMsg) + dataMsg, ok := evt.Event.(*signalpb.DataMessage) + if !ok { + return nil, fmt.Errorf("ConvertMessage() called for non-DataMessage event") + } + converted := evt.s.Main.MsgConv.ToMatrix(ctx, dataMsg) + converted.MergeCaption() var replyTo *networkid.MessageOptionalPartID if dataMsg.GetQuote() != nil { quoteAuthor, _ := uuid.Parse(dataMsg.Quote.GetAuthorAci()) @@ -463,37 +604,42 @@ func (s *SignalClient) convertMessage(ctx context.Context, portal *bridgev2.Port } return &bridgev2.ConvertedMessage{ - //ID: makeMessageID(data.Info.Sender, dataMsg.GetTimestamp()), - //EventSender: s.makeEventSender(data.Info.Sender), - Timestamp: time.UnixMilli(int64(converted.Timestamp)), - ReplyTo: replyTo, - Parts: convertedParts, + ReplyTo: replyTo, + Parts: convertedParts, }, nil } +func (evt *Bv2ChatEvent) ConvertEdit(ctx context.Context, portal *bridgev2.Portal, intent bridgev2.MatrixAPI, existing []*database.Message) (*bridgev2.ConvertedEdit, error) { + mcCtx := &msgconvContext{ + Connector: evt.s.Main, + Intent: intent, + Client: evt.s, + Portal: portal, + } + ctx = context.WithValue(ctx, msgconvContextKey, mcCtx) + editMsg, ok := evt.Event.(*signalpb.EditMessage) + if !ok { + return nil, fmt.Errorf("ConvertEdit() called for non-EditMessage event") + } + // TODO tell converter about existing parts to avoid reupload? + converted := evt.s.Main.MsgConv.ToMatrix(ctx, editMsg.GetDataMessage()) + converted.MergeCaption() + convertedEdit := &bridgev2.ConvertedEdit{} + // TODO can anything other than the text be edited? + lastPart := converted.Parts[len(converted.Parts)-1] + convertedEdit.ModifiedParts = append(convertedEdit.ModifiedParts, &bridgev2.ConvertedEditPart{ + Part: existing[len(existing)-1], + Type: lastPart.Type, + Content: lastPart.Content, + Extra: lastPart.Extra, + }) + return convertedEdit, nil +} + func (s *SignalClient) handleSignalEvent(rawEvt events.SignalEvent) { switch evt := rawEvt.(type) { case *events.ChatEvent: - switch innerEvt := evt.Event.(type) { - case *signalpb.DataMessage: - s.Main.Bridge.QueueRemoteEvent(s.UserLogin, &bridgev2.SimpleRemoteEvent[*events.ChatEvent]{ - Type: bridgev2.RemoteEventMessage, - LogContext: func(c zerolog.Context) zerolog.Context { - return c. - Uint64("message_id", innerEvt.GetTimestamp()). - Stringer("sender_id", evt.Info.Sender) - }, - ID: makeMessageID(evt.Info.Sender, innerEvt.GetTimestamp()), - Sender: s.makeEventSender(evt.Info.Sender), - PortalID: s.getPortalID(evt.Info.ChatID), - Data: evt, - CreatePortal: true, - - ConvertMessageFunc: s.convertMessage, - }) - case *signalpb.EditMessage: - case *signalpb.TypingMessage: - } + s.Main.Bridge.QueueRemoteEvent(s.UserLogin, &Bv2ChatEvent{ChatEvent: evt, s: s}) case *events.DecryptionError: case *events.Receipt: case *events.ReadSelf: From 64a364d97de77cf707e3960a7f992c924a5f9728 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Fri, 7 Jun 2024 12:57:36 +0300 Subject: [PATCH 036/580] Update reaction deduplication --- go.mod | 2 +- go.sum | 4 ++-- pkg/connector/connector.go | 47 ++++++++++++-------------------------- 3 files changed, 17 insertions(+), 36 deletions(-) diff --git a/go.mod b/go.mod index 726ed5a..7d766d8 100644 --- a/go.mod +++ b/go.mod @@ -21,7 +21,7 @@ require ( golang.org/x/net v0.25.0 google.golang.org/protobuf v1.34.1 gopkg.in/yaml.v3 v3.0.1 - maunium.net/go/mautrix v0.18.2-0.20240606175822-a150a4760419 + maunium.net/go/mautrix v0.18.2-0.20240607095501-6466bf945260 nhooyr.io/websocket v1.8.11 ) diff --git a/go.sum b/go.sum index d6720a8..78957fa 100644 --- a/go.sum +++ b/go.sum @@ -95,7 +95,7 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= maunium.net/go/mauflag v1.0.0 h1:YiaRc0tEI3toYtJMRIfjP+jklH45uDHtT80nUamyD4M= maunium.net/go/mauflag v1.0.0/go.mod h1:nLivPOpTpHnpzEh8jEdSL9UqO9+/KBJFmNRlwKfkPeA= -maunium.net/go/mautrix v0.18.2-0.20240606175822-a150a4760419 h1:6JOCYkxS/nfhK/J3o+kkJgUDRaPRGgQXaxZj5HX5jys= -maunium.net/go/mautrix v0.18.2-0.20240606175822-a150a4760419/go.mod h1:P/FV8cXY262MezYX7ViuhfzeJ0nK4+M8K6ZmxEC/aEA= +maunium.net/go/mautrix v0.18.2-0.20240607095501-6466bf945260 h1:PRjq8wEtssdiUhwVpo9h2LAlVEB04r3y/YR2XZsdlbg= +maunium.net/go/mautrix v0.18.2-0.20240607095501-6466bf945260/go.mod h1:P/FV8cXY262MezYX7ViuhfzeJ0nK4+M8K6ZmxEC/aEA= nhooyr.io/websocket v1.8.11 h1:f/qXNc2/3DpoSZkHt1DQu6rj4zGC8JmkkLkWss0MgN0= nhooyr.io/websocket v1.8.11/go.mod h1:rN9OFWIUwuxg4fR5tELlYC04bXYowCP9GX47ivo2l+c= diff --git a/pkg/connector/connector.go b/pkg/connector/connector.go index f46270e..69ec6b3 100644 --- a/pkg/connector/connector.go +++ b/pkg/connector/connector.go @@ -444,7 +444,8 @@ var ( _ bridgev2.RemoteMessage = (*Bv2ChatEvent)(nil) _ bridgev2.RemoteEdit = (*Bv2ChatEvent)(nil) _ bridgev2.RemoteEventWithTimestamp = (*Bv2ChatEvent)(nil) - _ bridgev2.RemoteReactionWithMeta = (*Bv2ChatEvent)(nil) + _ bridgev2.RemoteReaction = (*Bv2ChatEvent)(nil) + _ bridgev2.RemoteReactionRemove = (*Bv2ChatEvent)(nil) _ bridgev2.RemoteMessageRemove = (*Bv2ChatEvent)(nil) ) @@ -562,14 +563,8 @@ func (evt *Bv2ChatEvent) GetReactionEmoji() (string, networkid.EmojiID) { return dataMsg.GetReaction().GetEmoji(), "" } -func (evt *Bv2ChatEvent) GetReactionDBMetadata() map[string]any { - dataMsg, ok := evt.Event.(*signalpb.DataMessage) - if !ok || dataMsg.Reaction == nil { - return map[string]any{} - } - return map[string]any{ - "emoji": dataMsg.GetReaction().GetEmoji(), - } +func (evt *Bv2ChatEvent) GetRemovedEmojiID() networkid.EmojiID { + return "" } func (evt *Bv2ChatEvent) ConvertMessage(ctx context.Context, portal *bridgev2.Portal, intent bridgev2.MatrixAPI) (*bridgev2.ConvertedMessage, error) { @@ -695,8 +690,6 @@ func (s *SignalClient) HandleMatrixMessage(ctx context.Context, msg *bridgev2.Ma } dbMsg := &database.Message{ ID: makeMessageID(s.Client.Store.ACI, converted.GetTimestamp()), - MXID: msg.Event.ID, - RoomID: msg.Portal.ID, SenderID: makeUserID(s.Client.Store.ACI), Timestamp: time.UnixMilli(int64(converted.GetTimestamp())), Metadata: meta, @@ -763,16 +756,15 @@ func (s *SignalClient) sendMessage(ctx context.Context, portalID networkid.Porta } } +func (s *SignalClient) PreHandleMatrixReaction(ctx context.Context, msg *bridgev2.MatrixReaction) (bridgev2.MatrixReactionPreResponse, error) { + return bridgev2.MatrixReactionPreResponse{ + SenderID: makeUserID(s.Client.Store.ACI), + EmojiID: "", + Emoji: variationselector.FullyQualify(msg.Content.RelatesTo.Key), + }, nil +} + func (s *SignalClient) HandleMatrixReaction(ctx context.Context, msg *bridgev2.MatrixReaction) (reaction *database.Reaction, err error) { - senderID := makeUserID(s.Client.Store.ACI) - // emojiID is always empty because only one reaction is allowed per message+user - var emojiID networkid.EmojiID - signalEmoji := variationselector.FullyQualify(msg.Content.RelatesTo.Key) - if existing, err := msg.GetExisting(ctx, senderID, emojiID); err != nil { - return nil, fmt.Errorf("failed to check for duplicate reaction: %w", err) - } else if existing != nil && existing.Metadata["emoji"] == signalEmoji { - return nil, nil - } targetAuthorACI, targetSentTimestamp, err := parseMessageID(msg.TargetMessage.ID) if err != nil { return nil, fmt.Errorf("failed to parse target message ID: %w", err) @@ -782,7 +774,7 @@ func (s *SignalClient) HandleMatrixReaction(ctx context.Context, msg *bridgev2.M Timestamp: proto.Uint64(uint64(msg.Event.Timestamp)), RequiredProtocolVersion: proto.Uint32(uint32(signalpb.DataMessage_REACTIONS)), Reaction: &signalpb.DataMessage_Reaction{ - Emoji: proto.String(signalEmoji), + Emoji: proto.String(msg.PreHandleResp.Emoji), Remove: proto.Bool(false), TargetAuthorAci: proto.String(targetAuthorACI.String()), TargetSentTimestamp: proto.Uint64(targetSentTimestamp), @@ -795,18 +787,7 @@ func (s *SignalClient) HandleMatrixReaction(ctx context.Context, msg *bridgev2.M } // TODO check result fmt.Println(res) - return &database.Reaction{ - RoomID: msg.Portal.ID, - MessageID: msg.TargetMessage.ID, - MessagePartID: msg.TargetMessage.PartID, - SenderID: senderID, - EmojiID: emojiID, - MXID: msg.Event.ID, - Timestamp: time.UnixMilli(msg.Event.Timestamp), - Metadata: map[string]any{ - "emoji": signalEmoji, - }, - }, nil + return &database.Reaction{}, nil } func (s *SignalClient) HandleMatrixReactionRemove(ctx context.Context, msg *bridgev2.MatrixReactionRemove) error { From d501ce0578dec93cc3f5bcb6826f0bdc2ba7c930 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Mon, 10 Jun 2024 22:15:10 +0300 Subject: [PATCH 037/580] Add portal receiver to DMs --- go.mod | 2 +- go.sum | 4 ++-- pkg/connector/connector.go | 45 +++++++++----------------------------- 3 files changed, 13 insertions(+), 38 deletions(-) diff --git a/go.mod b/go.mod index 7d766d8..c602f49 100644 --- a/go.mod +++ b/go.mod @@ -21,7 +21,7 @@ require ( golang.org/x/net v0.25.0 google.golang.org/protobuf v1.34.1 gopkg.in/yaml.v3 v3.0.1 - maunium.net/go/mautrix v0.18.2-0.20240607095501-6466bf945260 + maunium.net/go/mautrix v0.18.2-0.20240610191402-39ce0103d40b nhooyr.io/websocket v1.8.11 ) diff --git a/go.sum b/go.sum index 78957fa..f67f9ad 100644 --- a/go.sum +++ b/go.sum @@ -95,7 +95,7 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= maunium.net/go/mauflag v1.0.0 h1:YiaRc0tEI3toYtJMRIfjP+jklH45uDHtT80nUamyD4M= maunium.net/go/mauflag v1.0.0/go.mod h1:nLivPOpTpHnpzEh8jEdSL9UqO9+/KBJFmNRlwKfkPeA= -maunium.net/go/mautrix v0.18.2-0.20240607095501-6466bf945260 h1:PRjq8wEtssdiUhwVpo9h2LAlVEB04r3y/YR2XZsdlbg= -maunium.net/go/mautrix v0.18.2-0.20240607095501-6466bf945260/go.mod h1:P/FV8cXY262MezYX7ViuhfzeJ0nK4+M8K6ZmxEC/aEA= +maunium.net/go/mautrix v0.18.2-0.20240610191402-39ce0103d40b h1:sEwWJqdshbCZFGlvj6j3IPxBDznQLHG79GZdrMCEZvk= +maunium.net/go/mautrix v0.18.2-0.20240610191402-39ce0103d40b/go.mod h1:P/FV8cXY262MezYX7ViuhfzeJ0nK4+M8K6ZmxEC/aEA= nhooyr.io/websocket v1.8.11 h1:f/qXNc2/3DpoSZkHt1DQu6rj4zGC8JmkkLkWss0MgN0= nhooyr.io/websocket v1.8.11/go.mod h1:rN9OFWIUwuxg4fR5tELlYC04bXYowCP9GX47ivo2l+c= diff --git a/pkg/connector/connector.go b/pkg/connector/connector.go index 69ec6b3..180a30e 100644 --- a/pkg/connector/connector.go +++ b/pkg/connector/connector.go @@ -28,7 +28,6 @@ import ( "github.com/rs/zerolog" "go.mau.fi/util/dbutil" "go.mau.fi/util/variationselector" - "golang.org/x/exp/slices" "google.golang.org/protobuf/proto" "maunium.net/go/mautrix/bridgev2" @@ -345,43 +344,14 @@ func parseUserID(userID networkid.UserID) (uuid.UUID, error) { } func (s *SignalClient) parsePortalID(portalID networkid.PortalID) (userID libsignalgo.ServiceID, groupID types.GroupIdentifier, err error) { - parts := strings.Split(string(portalID), "|") - if len(parts) == 1 { - if len(parts[0]) == 44 { - groupID = types.GroupIdentifier(parts[0]) - } else { - err = fmt.Errorf("invalid portal ID: expected group ID to be 44 characters") - } - } else if len(parts) == 2 { - ourACI := s.Client.Store.ACI.String() - if parts[0] == ourACI { - userID, err = libsignalgo.ServiceIDFromString(parts[1]) - } else if parts[1] == ourACI { - userID, err = libsignalgo.ServiceIDFromString(parts[0]) - } else { - err = fmt.Errorf("invalid portal ID: expected one side to be our ACI") - } + if len(portalID) == 44 { + groupID = types.GroupIdentifier(portalID) } else { - err = fmt.Errorf("invalid portal ID: unexpected number of pipe-separated parts") + userID, err = libsignalgo.ServiceIDFromString(string(portalID)) } return } -func (s *SignalClient) getPortalID(chatID string) networkid.PortalID { - if len(chatID) == 44 { - // Group ID - return networkid.PortalID(chatID) - } else if strings.HasPrefix(chatID, "PNI:") { - // Temporary new DM ID: always put our own ACI first, the portal will never be shared anyway - return networkid.PortalID(fmt.Sprintf("%s|%s", s.Client.Store.ACI, chatID)) - } else { - // DM ID: sort the two parts so the ID is always the same regardless of which side is receiving the message - parts := []string{s.Client.Store.ACI.String(), chatID} - slices.Sort(parts) - return networkid.PortalID(strings.Join(parts, "|")) - } -} - func parseMessageID(messageID networkid.MessageID) (sender uuid.UUID, timestamp uint64, err error) { parts := strings.Split(string(messageID), "|") if len(parts) != 2 { @@ -471,8 +441,13 @@ func (evt *Bv2ChatEvent) GetType() bridgev2.RemoteEventType { return bridgev2.RemoteEventUnknown } -func (evt *Bv2ChatEvent) GetPortalID() networkid.PortalID { - return evt.s.getPortalID(evt.Info.ChatID) +func (evt *Bv2ChatEvent) GetPortalKey() networkid.PortalKey { + key := networkid.PortalKey{ID: networkid.PortalID(evt.Info.ChatID)} + // For non-group chats, add receiver + if len(evt.Info.ChatID) != 44 { + key.Receiver = makeUserLoginID(evt.s.Client.Store.ACI) + } + return key } func (evt *Bv2ChatEvent) ShouldCreatePortal() bool { From ecd4f055ae312c61f363659962a5f3b1bb843af7 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Tue, 11 Jun 2024 15:06:04 +0300 Subject: [PATCH 038/580] Use new main function for v2 bridge --- cmd/mautrix-signal-v2/main.go | 43 ++++++++++++++++--------------- config/upgrade.go | 2 +- go.mod | 16 ++++++------ go.sum | 28 ++++++++++---------- pkg/connector/connector.go | 39 ++++++++++++++++++++++++---- pkg/connector/example-config.yaml | 21 +++++++++++++++ 6 files changed, 100 insertions(+), 49 deletions(-) create mode 100644 pkg/connector/example-config.yaml diff --git a/cmd/mautrix-signal-v2/main.go b/cmd/mautrix-signal-v2/main.go index 4e02361..e397e14 100644 --- a/cmd/mautrix-signal-v2/main.go +++ b/cmd/mautrix-signal-v2/main.go @@ -17,31 +17,32 @@ package main import ( - "os" - - "go.mau.fi/util/dbutil" - "go.mau.fi/util/exerrors" - "go.mau.fi/util/exzerolog" - "gopkg.in/yaml.v3" - "maunium.net/go/mautrix/bridgev2" - "maunium.net/go/mautrix/bridgev2/bridgeconfig" - "maunium.net/go/mautrix/bridgev2/matrix" + "maunium.net/go/mautrix/bridgev2/matrix/mxmain" "go.mau.fi/mautrix-signal/pkg/connector" "go.mau.fi/mautrix-signal/pkg/signalmeow" ) +// Information to find out exactly which commit the bridge was built from. +// These are filled at build time with the -X linker flag. +var ( + Tag = "unknown" + Commit = "unknown" + BuildTime = "unknown" +) + func main() { - var cfg bridgeconfig.Config - config := exerrors.Must(os.ReadFile("config.yaml")) - exerrors.PanicIfNotNil(yaml.Unmarshal(config, &cfg)) - log := exerrors.Must(cfg.Logging.Compile()) - exzerolog.SetupDefaults(log) - signalmeow.SetLogger(log.With().Str("component", "signalmeow").Logger()) - db := exerrors.Must(dbutil.NewFromConfig("mautrix-signal", cfg.Database, dbutil.ZeroLogger(log.With().Str("db_section", "main").Logger()))) - signalConnector := connector.NewConnector() - exerrors.PanicIfNotNil(cfg.Network.Decode(signalConnector.Config)) - bridge := bridgev2.NewBridge("", db, *log, matrix.NewConnector(&cfg), signalConnector) - bridge.CommandPrefix = "!signal" - bridge.Start() + m := mxmain.BridgeMain{ + Name: "mautrix-signal", + URL: "https://github.com/mautrix/signal", + Description: "A Matrix-Signal puppeting bridge.", + Version: "0.7.0", + + Connector: connector.NewConnector(), + } + m.PostInit = func() { + signalmeow.SetLogger(m.Log.With().Str("component", "signalmeow").Logger()) + } + m.InitVersion(Tag, Commit, BuildTime) + m.Run() } diff --git a/config/upgrade.go b/config/upgrade.go index 114eb1d..219b7fc 100644 --- a/config/upgrade.go +++ b/config/upgrade.go @@ -25,7 +25,7 @@ import ( "maunium.net/go/mautrix/bridge/bridgeconfig" ) -func DoUpgrade(helper *up.Helper) { +func DoUpgrade(helper up.Helper) { bridgeconfig.Upgrader.DoUpgrade(helper) legacyDB, ok := helper.Get(up.Str, "appservice", "database") diff --git a/go.mod b/go.mod index 4d44c1d..e328525 100644 --- a/go.mod +++ b/go.mod @@ -11,17 +11,16 @@ require ( github.com/mattn/go-pointer v0.0.1 github.com/mattn/go-sqlite3 v1.14.22 github.com/prometheus/client_golang v1.19.1 - github.com/rs/zerolog v1.32.0 + github.com/rs/zerolog v1.33.0 github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e github.com/stretchr/testify v1.9.0 github.com/tidwall/gjson v1.17.1 - go.mau.fi/util v0.4.3-0.20240516141139-2ebe792cd8f7 - golang.org/x/crypto v0.23.0 - golang.org/x/exp v0.0.0-20240525044651-4c93da0ed11d - golang.org/x/net v0.25.0 + go.mau.fi/util v0.4.3-0.20240611114927-6ef09885dd97 + golang.org/x/crypto v0.24.0 + golang.org/x/exp v0.0.0-20240604190554-fc45aab8b7f8 + golang.org/x/net v0.26.0 google.golang.org/protobuf v1.34.1 - gopkg.in/yaml.v3 v3.0.1 - maunium.net/go/mautrix v0.18.2-0.20240610192549-f9dccaaea049 + maunium.net/go/mautrix v0.18.2-0.20240611120402-f97d365ea9eb nhooyr.io/websocket v1.8.11 ) @@ -44,7 +43,8 @@ require ( github.com/tidwall/sjson v1.2.5 // indirect github.com/yuin/goldmark v1.7.1 // indirect go.mau.fi/zeroconfig v0.1.2 // indirect - golang.org/x/sys v0.20.0 // indirect + golang.org/x/sys v0.21.0 // indirect gopkg.in/natefinch/lumberjack.v2 v2.2.1 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect maunium.net/go/mauflag v1.0.0 // indirect ) diff --git a/go.sum b/go.sum index edf5156..98c7001 100644 --- a/go.sum +++ b/go.sum @@ -52,8 +52,8 @@ github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjR github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog= github.com/rs/xid v1.5.0 h1:mKX4bl4iPYJtEIxp6CYiUuLQ/8DYMoz0PUdtGgMFRVc= github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= -github.com/rs/zerolog v1.32.0 h1:keLypqrlIjaFsbmJOBdB/qvyF8KEtCWHwobLp5l/mQ0= -github.com/rs/zerolog v1.32.0/go.mod h1:/7mN4D5sKwJLZQ2b/znpjC3/GQWY/xaDXUM0kKWRHss= +github.com/rs/zerolog v1.33.0 h1:1cU2KZkvPxNyfgEmhHAz/1A9Bz+llsdYzklWFzgp0r8= +github.com/rs/zerolog v1.33.0/go.mod h1:/7mN4D5sKwJLZQ2b/znpjC3/GQWY/xaDXUM0kKWRHss= github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e h1:MRM5ITcdelLK2j1vwZ3Je0FKVCfqOLp5zO6trqMLYs0= github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e/go.mod h1:XV66xRDqSt+GTGFMVlhk3ULuV0y9ZmzeVGR4mloJI3M= github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= @@ -69,21 +69,21 @@ github.com/tidwall/sjson v1.2.5 h1:kLy8mja+1c9jlljvWTlSazM7cKDRfJuR/bOJhcY5NcY= github.com/tidwall/sjson v1.2.5/go.mod h1:Fvgq9kS/6ociJEDnK0Fk1cpYF4FIW6ZF7LAe+6jwd28= github.com/yuin/goldmark v1.7.1 h1:3bajkSilaCbjdKVsKdZjZCLBNPL9pYzrCakKaf4U49U= github.com/yuin/goldmark v1.7.1/go.mod h1:uzxRWxtg69N339t3louHJ7+O03ezfj6PlliRlaOzY1E= -go.mau.fi/util v0.4.3-0.20240516141139-2ebe792cd8f7 h1:2hnc2iS7usHT3aqIQ8HVtKtPgic+13EVSdZ1m8UBL/E= -go.mau.fi/util v0.4.3-0.20240516141139-2ebe792cd8f7/go.mod h1:m+PJpPMadAW6cj3ldyuO5bLhFreWdwcu+3QTwYNGlGk= +go.mau.fi/util v0.4.3-0.20240611114927-6ef09885dd97 h1:btYXIv4Iqnboc9FQS99dh8XwMF2QftOhfTeh02K2b4o= +go.mau.fi/util v0.4.3-0.20240611114927-6ef09885dd97/go.mod h1:4etkIWotzgsWICu/1I34Y2LFFekINhFsyWYHXEsxXdY= go.mau.fi/zeroconfig v0.1.2 h1:DKOydWnhPMn65GbXZOafgkPm11BvFashZWLct0dGFto= go.mau.fi/zeroconfig v0.1.2/go.mod h1:NcSJkf180JT+1IId76PcMuLTNa1CzsFFZ0nBygIQM70= -golang.org/x/crypto v0.23.0 h1:dIJU/v2J8Mdglj/8rJ6UUOM3Zc9zLZxVZwwxMooUSAI= -golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8= -golang.org/x/exp v0.0.0-20240525044651-4c93da0ed11d h1:N0hmiNbwsSNwHBAvR3QB5w25pUwH4tK0Y/RltD1j1h4= -golang.org/x/exp v0.0.0-20240525044651-4c93da0ed11d/go.mod h1:XtvwrStGgqGPLc4cjQfWqZHG1YFdYs6swckp8vpsjnc= -golang.org/x/net v0.25.0 h1:d/OCCoBEUq33pjydKrGQhw7IlUPI2Oylr+8qLx49kac= -golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM= +golang.org/x/crypto v0.24.0 h1:mnl8DM0o513X8fdIkmyFE/5hTYxbwYOjDS/+rK6qpRI= +golang.org/x/crypto v0.24.0/go.mod h1:Z1PMYSOR5nyMcyAVAIQSKCDwalqy85Aqn1x3Ws4L5DM= +golang.org/x/exp v0.0.0-20240604190554-fc45aab8b7f8 h1:LoYXNGAShUG3m/ehNk4iFctuhGX/+R1ZpfJ4/ia80JM= +golang.org/x/exp v0.0.0-20240604190554-fc45aab8b7f8/go.mod h1:jj3sYF3dwk5D+ghuXyeI3r5MFf+NT2An6/9dOA95KSI= +golang.org/x/net v0.26.0 h1:soB7SVo0PWrY4vPW/+ay0jKDNScG2X9wFeYlXIvJsOQ= +golang.org/x/net v0.26.0/go.mod h1:5YKkiSynbBIh3p6iOc/vibscux0x38BZDkn8sCUPxHE= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.20.0 h1:Od9JTbYCk261bKm4M/mw7AklTlFYIa0bIp9BgSm1S8Y= -golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.21.0 h1:rF+pYz3DAGSQAxAu1CbC7catZg4ebC4UIeIhKxBZvws= +golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= google.golang.org/protobuf v1.34.1 h1:9ddQBjfCyZPOHPUiPxpYESBLc+T8P3E+Vo4IbKZgFWg= google.golang.org/protobuf v1.34.1/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= @@ -95,7 +95,7 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= maunium.net/go/mauflag v1.0.0 h1:YiaRc0tEI3toYtJMRIfjP+jklH45uDHtT80nUamyD4M= maunium.net/go/mauflag v1.0.0/go.mod h1:nLivPOpTpHnpzEh8jEdSL9UqO9+/KBJFmNRlwKfkPeA= -maunium.net/go/mautrix v0.18.2-0.20240610192549-f9dccaaea049 h1:keFLN2tVrt5UmNSm7Mjweue4r4t+WUKk0kmPcWfXUpQ= -maunium.net/go/mautrix v0.18.2-0.20240610192549-f9dccaaea049/go.mod h1:P/FV8cXY262MezYX7ViuhfzeJ0nK4+M8K6ZmxEC/aEA= +maunium.net/go/mautrix v0.18.2-0.20240611120402-f97d365ea9eb h1:PcUevUW1w5PCeqXha1fPIlk25XcdXrogpBsBLB/HbXo= +maunium.net/go/mautrix v0.18.2-0.20240611120402-f97d365ea9eb/go.mod h1:HLNcNm0J4ZDgaoMjoHv5Hc/GkA2FfVUR6KbW7A3Iwv0= nhooyr.io/websocket v1.8.11 h1:f/qXNc2/3DpoSZkHt1DQu6rj4zGC8JmkkLkWss0MgN0= nhooyr.io/websocket v1.8.11/go.mod h1:rN9OFWIUwuxg4fR5tELlYC04bXYowCP9GX47ivo2l+c= diff --git a/pkg/connector/connector.go b/pkg/connector/connector.go index 180a30e..d663657 100644 --- a/pkg/connector/connector.go +++ b/pkg/connector/connector.go @@ -18,6 +18,7 @@ package connector import ( "context" + _ "embed" "fmt" "strconv" "strings" @@ -26,10 +27,10 @@ import ( "github.com/google/uuid" "github.com/rs/zerolog" + up "go.mau.fi/util/configupgrade" "go.mau.fi/util/dbutil" "go.mau.fi/util/variationselector" "google.golang.org/protobuf/proto" - "maunium.net/go/mautrix/bridgev2" "maunium.net/go/mautrix/bridgev2/database" "maunium.net/go/mautrix/bridgev2/networkid" @@ -94,12 +95,44 @@ type SignalConnector struct { Config *SignalConfig } +var _ bridgev2.NetworkConnector = (*SignalConnector)(nil) +var _ bridgev2.NetworkAPI = (*SignalClient)(nil) +var _ msgconv.PortalMethods = (*msgconvPortalMethods)(nil) + func NewConnector() *SignalConnector { return &SignalConnector{ Config: &SignalConfig{}, } } +//go:embed example-config.yaml +var ExampleConfig string + +func (s *SignalConnector) GetName() bridgev2.BridgeName { + return bridgev2.BridgeName{ + DisplayName: "Signal", + NetworkURL: "https://signal.org", + NetworkIcon: "mxc://maunium.net/wPJgTQbZOtpBFmDNkiNEMDUp", + NetworkID: "signal", + BeeperBridgeType: "signal", + DefaultPort: 29328, + } +} + +func upgradeConfig(helper up.Helper) { + helper.Copy(up.Str, "displayname_template") + helper.Copy(up.Bool, "use_contact_avatars") + helper.Copy(up.Bool, "use_outdated_profiles") + helper.Copy(up.Bool, "number_in_topic") + helper.Copy(up.Str, "device_name") + helper.Copy(up.Str, "note_to_self_avatar") + helper.Copy(up.Str, "location_format") +} + +func (s *SignalConnector) GetConfig() (string, any, up.Upgrader) { + return ExampleConfig, s.Config, up.SimpleUpgrader(upgradeConfig) +} + func (s *SignalConnector) Init(bridge *bridgev2.Bridge) { var err error s.Config.displaynameTemplate, err = template.New("displayname").Parse(s.Config.DisplaynameTemplate) @@ -161,10 +194,6 @@ func (s *SignalConnector) Start(ctx context.Context) error { return s.Store.Upgrade(ctx) } -var _ bridgev2.NetworkConnector = (*SignalConnector)(nil) -var _ bridgev2.NetworkAPI = (*SignalClient)(nil) -var _ msgconv.PortalMethods = (*msgconvPortalMethods)(nil) - func (s *SignalConnector) LoadUserLogin(ctx context.Context, login *bridgev2.UserLogin) error { aci, err := uuid.Parse(string(login.ID)) if err != nil { diff --git a/pkg/connector/example-config.yaml b/pkg/connector/example-config.yaml new file mode 100644 index 0000000..4c399b3 --- /dev/null +++ b/pkg/connector/example-config.yaml @@ -0,0 +1,21 @@ +# Displayname template for Signal users. +# {{.ProfileName}} - The Signal profile name set by the user. +# {{.ContactName}} - The name for the user from your phone's contact list. This is not safe on multi-user instances. +# {{.PhoneNumber}} - The phone number of the user. +# {{.UUID}} - The UUID of the Signal user. +# {{.AboutEmoji}} - The emoji set by the user in their profile. +displayname_template: '{{or .ProfileName .PhoneNumber "Unknown user"}}' +# Should avatars from the user's contact list be used? This is not safe on multi-user instances. +use_contact_avatars: false +# Should the bridge sync ghost user info even if profile fetching fails? This is not safe on multi-user instances. +use_outdated_profiles: false +# Should the Signal user's phone number be included in the room topic in private chat portal rooms? +number_in_topic: true +# Default device name that shows up in the Signal app. +device_name: mautrix-signal +# Avatar image for the Note to Self room. +note_to_self_avatar: mxc://maunium.net/REBIVrqjZwmaWpssCZpBlmlL +# Format for generating URLs from location messages for sending to Signal. +# Google Maps: 'https://www.google.com/maps/place/%[1]s,%[2]s' +# OpenStreetMap: 'https://www.openstreetmap.org/?mlat=%[1]s&mlon=%[2]s' +location_format: 'https://www.google.com/maps/place/%[1]s,%[2]s' From e637cdfac728306c74b0ec2503b24a681af66151 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Tue, 11 Jun 2024 20:29:04 +0300 Subject: [PATCH 039/580] v2: Add bridge states --- go.mod | 4 +- go.sum | 8 +-- pkg/connector/connector.go | 108 ++++++++++++++++++++++++++++++++++++- pkg/connector/login.go | 4 +- 4 files changed, 115 insertions(+), 9 deletions(-) diff --git a/go.mod b/go.mod index e328525..9d49663 100644 --- a/go.mod +++ b/go.mod @@ -15,12 +15,12 @@ require ( github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e github.com/stretchr/testify v1.9.0 github.com/tidwall/gjson v1.17.1 - go.mau.fi/util v0.4.3-0.20240611114927-6ef09885dd97 + go.mau.fi/util v0.4.3-0.20240611132549-e72a5f4745e7 golang.org/x/crypto v0.24.0 golang.org/x/exp v0.0.0-20240604190554-fc45aab8b7f8 golang.org/x/net v0.26.0 google.golang.org/protobuf v1.34.1 - maunium.net/go/mautrix v0.18.2-0.20240611120402-f97d365ea9eb + maunium.net/go/mautrix v0.18.2-0.20240611172604-d58e8f88173b nhooyr.io/websocket v1.8.11 ) diff --git a/go.sum b/go.sum index 98c7001..58227d6 100644 --- a/go.sum +++ b/go.sum @@ -69,8 +69,8 @@ github.com/tidwall/sjson v1.2.5 h1:kLy8mja+1c9jlljvWTlSazM7cKDRfJuR/bOJhcY5NcY= github.com/tidwall/sjson v1.2.5/go.mod h1:Fvgq9kS/6ociJEDnK0Fk1cpYF4FIW6ZF7LAe+6jwd28= github.com/yuin/goldmark v1.7.1 h1:3bajkSilaCbjdKVsKdZjZCLBNPL9pYzrCakKaf4U49U= github.com/yuin/goldmark v1.7.1/go.mod h1:uzxRWxtg69N339t3louHJ7+O03ezfj6PlliRlaOzY1E= -go.mau.fi/util v0.4.3-0.20240611114927-6ef09885dd97 h1:btYXIv4Iqnboc9FQS99dh8XwMF2QftOhfTeh02K2b4o= -go.mau.fi/util v0.4.3-0.20240611114927-6ef09885dd97/go.mod h1:4etkIWotzgsWICu/1I34Y2LFFekINhFsyWYHXEsxXdY= +go.mau.fi/util v0.4.3-0.20240611132549-e72a5f4745e7 h1:DviEWXBpeOlFrqIf5s/iBDp1ewZx8fe6imMJ78kq3tA= +go.mau.fi/util v0.4.3-0.20240611132549-e72a5f4745e7/go.mod h1:Eaj7jl37ehkA7S6vE/vfPs5PsY8e91FKZ2BqA3OM/NU= go.mau.fi/zeroconfig v0.1.2 h1:DKOydWnhPMn65GbXZOafgkPm11BvFashZWLct0dGFto= go.mau.fi/zeroconfig v0.1.2/go.mod h1:NcSJkf180JT+1IId76PcMuLTNa1CzsFFZ0nBygIQM70= golang.org/x/crypto v0.24.0 h1:mnl8DM0o513X8fdIkmyFE/5hTYxbwYOjDS/+rK6qpRI= @@ -95,7 +95,7 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= maunium.net/go/mauflag v1.0.0 h1:YiaRc0tEI3toYtJMRIfjP+jklH45uDHtT80nUamyD4M= maunium.net/go/mauflag v1.0.0/go.mod h1:nLivPOpTpHnpzEh8jEdSL9UqO9+/KBJFmNRlwKfkPeA= -maunium.net/go/mautrix v0.18.2-0.20240611120402-f97d365ea9eb h1:PcUevUW1w5PCeqXha1fPIlk25XcdXrogpBsBLB/HbXo= -maunium.net/go/mautrix v0.18.2-0.20240611120402-f97d365ea9eb/go.mod h1:HLNcNm0J4ZDgaoMjoHv5Hc/GkA2FfVUR6KbW7A3Iwv0= +maunium.net/go/mautrix v0.18.2-0.20240611172604-d58e8f88173b h1:pcehRMwc0JrVokKa6Paucq6JyAvzZBaDt9x7QCeNWlQ= +maunium.net/go/mautrix v0.18.2-0.20240611172604-d58e8f88173b/go.mod h1:qdyAG5Uvdz3kdw3wCCz/FGnnwjoXK+/b6Iy3fRXnKM0= nhooyr.io/websocket v1.8.11 h1:f/qXNc2/3DpoSZkHt1DQu6rj4zGC8JmkkLkWss0MgN0= nhooyr.io/websocket v1.8.11/go.mod h1:rN9OFWIUwuxg4fR5tELlYC04bXYowCP9GX47ivo2l+c= diff --git a/pkg/connector/connector.go b/pkg/connector/connector.go index d663657..534dbf5 100644 --- a/pkg/connector/connector.go +++ b/pkg/connector/connector.go @@ -31,6 +31,7 @@ import ( "go.mau.fi/util/dbutil" "go.mau.fi/util/variationselector" "google.golang.org/protobuf/proto" + "maunium.net/go/mautrix/bridge/status" "maunium.net/go/mautrix/bridgev2" "maunium.net/go/mautrix/bridgev2/database" "maunium.net/go/mautrix/bridgev2/networkid" @@ -355,12 +356,115 @@ func (s *SignalClient) IsThisUser(_ context.Context, userID networkid.UserID) bo return userID == makeUserID(s.Client.Store.ACI) } +func (s *SignalClient) bridgeStateLoop(statusChan <-chan signalmeow.SignalConnectionStatus) { + var peekedConnectionStatus signalmeow.SignalConnectionStatus + for { + var connectionStatus signalmeow.SignalConnectionStatus + if peekedConnectionStatus.Event != signalmeow.SignalConnectionEventNone { + s.UserLogin.Log.Debug(). + Stringer("peeked_connection_status_event", peekedConnectionStatus.Event). + Msg("Using peeked connectionStatus event") + connectionStatus = peekedConnectionStatus + peekedConnectionStatus = signalmeow.SignalConnectionStatus{} + } else { + var ok bool + connectionStatus, ok = <-statusChan + if !ok { + s.UserLogin.Log.Debug().Msg("statusChan channel closed") + return + } + } + + err := connectionStatus.Err + switch connectionStatus.Event { + case signalmeow.SignalConnectionEventConnected: + s.UserLogin.Log.Debug().Msg("Sending Connected BridgeState") + s.UserLogin.BridgeState.Send(status.BridgeState{StateEvent: status.StateConnected}) + + case signalmeow.SignalConnectionEventDisconnected: + s.UserLogin.Log.Debug().Msg("Received SignalConnectionEventDisconnected") + + // Debounce: wait 7s before sending TransientDisconnect, in case we get a reconnect + // We should wait until the next message comes in, or 7 seconds has passed. + // - If a disconnected event comes in, just loop again, unless it's been more than 7 seconds. + // - If a non-disconnected event comes in, store it in peekedConnectionStatus, + // break out of this loop and go back to the top of the goroutine to handle it in the switch. + // - If 7 seconds passes without any non-disconnect messages, send the TransientDisconnect. + // (Why 7 seconds? It was 5 at first, but websockets min retry is 5 seconds, + // so it would send TransientDisconnect right before reconnecting. 7 seems to work well.) + debounceTimer := time.NewTimer(7 * time.Second) + PeekLoop: + for { + var ok bool + select { + case peekedConnectionStatus, ok = <-statusChan: + // Handle channel closing + if !ok { + s.UserLogin.Log.Debug().Msg("connectionStatus channel closed") + return + } + // If it's another Disconnected event, just keep looping + if peekedConnectionStatus.Event == signalmeow.SignalConnectionEventDisconnected { + peekedConnectionStatus = signalmeow.SignalConnectionStatus{} + continue + } + // If it's a non-disconnect event, break out of the PeekLoop and handle it in the switch + break PeekLoop + case <-debounceTimer.C: + // Time is up, so break out of the loop and send the TransientDisconnect + break PeekLoop + } + } + // We're out of the PeekLoop, so either we got a non-disconnect event, or it's been 7 seconds (or both). + // We want to send TransientDisconnect if it's been 7 seconds, but not if the latest event was something + // other than Disconnected + if !debounceTimer.Stop() { // If the timer has already expired + // Send TransientDisconnect only if the latest event is a disconnect or no event + // (peekedConnectionStatus could be something else if the timer and the event race) + if peekedConnectionStatus.Event == signalmeow.SignalConnectionEventDisconnected || + peekedConnectionStatus.Event == signalmeow.SignalConnectionEventNone { + s.UserLogin.Log.Debug().Msg("Sending TransientDisconnect BridgeState") + if err == nil { + s.UserLogin.BridgeState.Send(status.BridgeState{StateEvent: status.StateTransientDisconnect}) + } else { + s.UserLogin.BridgeState.Send(status.BridgeState{StateEvent: status.StateTransientDisconnect, Error: "unknown-websocket-error", Message: err.Error()}) + } + } + } + + case signalmeow.SignalConnectionEventLoggedOut: + s.UserLogin.Log.Debug().Msg("Sending BadCredentials BridgeState") + if err == nil { + s.UserLogin.BridgeState.Send(status.BridgeState{StateEvent: status.StateBadCredentials, Message: "You have been logged out of Signal, please reconnect"}) + } else { + s.UserLogin.BridgeState.Send(status.BridgeState{StateEvent: status.StateBadCredentials, Message: err.Error()}) + } + err = s.Client.ClearKeysAndDisconnect(context.TODO()) + if err != nil { + s.UserLogin.Log.Error().Err(err).Msg("Failed to clear keys and disconnect") + } + + case signalmeow.SignalConnectionEventError: + s.UserLogin.Log.Debug().Msg("Sending UnknownError BridgeState") + s.UserLogin.BridgeState.Send(status.BridgeState{StateEvent: status.StateUnknownError, Error: "unknown-websocket-error", Message: err.Error()}) + + case signalmeow.SignalConnectionCleanShutdown: + if s.Client.IsLoggedIn() { + s.UserLogin.Log.Debug().Msg("Clean Shutdown - sending no BridgeState") + } else { + s.UserLogin.Log.Debug().Msg("Clean Shutdown, but logged out - Sending BadCredentials BridgeState") + s.UserLogin.BridgeState.Send(status.BridgeState{StateEvent: status.StateBadCredentials, Message: "You have been logged out of Signal, please reconnect"}) + } + } + } +} + func (s *SignalClient) Connect(ctx context.Context) error { - _, err := s.Client.StartReceiveLoops(ctx) + ch, err := s.Client.StartReceiveLoops(ctx) if err != nil { return err } - // TODO status + go s.bridgeStateLoop(ch) return nil } diff --git a/pkg/connector/login.go b/pkg/connector/login.go index cd25e60..4771b65 100644 --- a/pkg/connector/login.go +++ b/pkg/connector/login.go @@ -137,7 +137,8 @@ func (qr *QRLogin) Wait(ctx context.Context) (*bridgev2.LoginStep, error) { ul, err = qr.User.NewLogin(ctx, &database.UserLogin{ ID: newLoginID, Metadata: map[string]any{ - "phone": signalPhone, + "phone": signalPhone, + "remote_name": signalPhone, }, }, nil) if err != nil { @@ -146,6 +147,7 @@ func (qr *QRLogin) Wait(ctx context.Context) (*bridgev2.LoginStep, error) { } else { ul = qr.Existing ul.Metadata["phone"] = signalPhone + ul.Metadata["remote_name"] = signalPhone err = ul.Save(ctx) if err != nil { return nil, fmt.Errorf("failed to update existing login: %w", err) From ecd444fbf30543ea24b6b3bbfd5ae32986525e45 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Wed, 12 Jun 2024 14:58:35 +0300 Subject: [PATCH 040/580] v2: add retry loop in initial connect --- pkg/connector/connector.go | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/pkg/connector/connector.go b/pkg/connector/connector.go index 534dbf5..c67cfed 100644 --- a/pkg/connector/connector.go +++ b/pkg/connector/connector.go @@ -458,14 +458,27 @@ func (s *SignalClient) bridgeStateLoop(statusChan <-chan signalmeow.SignalConnec } } } - func (s *SignalClient) Connect(ctx context.Context) error { + s.tryConnect(ctx, 0) + return nil +} + +func (s *SignalClient) tryConnect(ctx context.Context, retryCount int) { ch, err := s.Client.StartReceiveLoops(ctx) if err != nil { - return err + zerolog.Ctx(ctx).Err(err).Msg("Failed to start receive loops") + if retryCount < 6 { + s.UserLogin.BridgeState.Send(status.BridgeState{StateEvent: status.StateTransientDisconnect, Error: "unknown-websocket-error", Message: err.Error()}) + retryInSeconds := 2 << retryCount + zerolog.Ctx(ctx).Debug().Int("retry_in_seconds", retryInSeconds).Msg("Sleeping and retrying connection") + time.Sleep(time.Duration(retryInSeconds) * time.Second) + s.tryConnect(ctx, retryCount+1) + } else { + s.UserLogin.BridgeState.Send(status.BridgeState{StateEvent: status.StateUnknownError, Error: "unknown-websocket-error", Message: err.Error()}) + } + } else { + go s.bridgeStateLoop(ch) } - go s.bridgeStateLoop(ch) - return nil } func (s *SignalClient) IsLoggedIn() bool { From 6964a0d175a7506953caf21d7492520c67038112 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Wed, 12 Jun 2024 19:45:21 +0300 Subject: [PATCH 041/580] v2: add read receipts and other things --- go.mod | 2 +- go.sum | 4 +- pkg/connector/connector.go | 189 +++++++++++++++++++++++++++++++++++-- 3 files changed, 183 insertions(+), 12 deletions(-) diff --git a/go.mod b/go.mod index 9d49663..0cef984 100644 --- a/go.mod +++ b/go.mod @@ -20,7 +20,7 @@ require ( golang.org/x/exp v0.0.0-20240604190554-fc45aab8b7f8 golang.org/x/net v0.26.0 google.golang.org/protobuf v1.34.1 - maunium.net/go/mautrix v0.18.2-0.20240611172604-d58e8f88173b + maunium.net/go/mautrix v0.18.2-0.20240612164408-cf6b0e71f0a0 nhooyr.io/websocket v1.8.11 ) diff --git a/go.sum b/go.sum index 58227d6..ba5d33d 100644 --- a/go.sum +++ b/go.sum @@ -95,7 +95,7 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= maunium.net/go/mauflag v1.0.0 h1:YiaRc0tEI3toYtJMRIfjP+jklH45uDHtT80nUamyD4M= maunium.net/go/mauflag v1.0.0/go.mod h1:nLivPOpTpHnpzEh8jEdSL9UqO9+/KBJFmNRlwKfkPeA= -maunium.net/go/mautrix v0.18.2-0.20240611172604-d58e8f88173b h1:pcehRMwc0JrVokKa6Paucq6JyAvzZBaDt9x7QCeNWlQ= -maunium.net/go/mautrix v0.18.2-0.20240611172604-d58e8f88173b/go.mod h1:qdyAG5Uvdz3kdw3wCCz/FGnnwjoXK+/b6Iy3fRXnKM0= +maunium.net/go/mautrix v0.18.2-0.20240612164408-cf6b0e71f0a0 h1:e+7glrQSSUm5GROTBYq/ENwhefRFmEXfGwRdP2FllAw= +maunium.net/go/mautrix v0.18.2-0.20240612164408-cf6b0e71f0a0/go.mod h1:qdyAG5Uvdz3kdw3wCCz/FGnnwjoXK+/b6Iy3fRXnKM0= nhooyr.io/websocket v1.8.11 h1:f/qXNc2/3DpoSZkHt1DQu6rj4zGC8JmkkLkWss0MgN0= nhooyr.io/websocket v1.8.11/go.mod h1:rN9OFWIUwuxg4fR5tELlYC04bXYowCP9GX47ivo2l+c= diff --git a/pkg/connector/connector.go b/pkg/connector/connector.go index c67cfed..864e3d8 100644 --- a/pkg/connector/connector.go +++ b/pkg/connector/connector.go @@ -29,6 +29,7 @@ import ( "github.com/rs/zerolog" up "go.mau.fi/util/configupgrade" "go.mau.fi/util/dbutil" + "go.mau.fi/util/exzerolog" "go.mau.fi/util/variationselector" "google.golang.org/protobuf/proto" "maunium.net/go/mautrix/bridge/status" @@ -51,11 +52,13 @@ import ( ) type SignalConfig struct { - DisplaynameTemplate string `yaml:"displayname_template"` - UseContactAvatars bool `yaml:"use_contact_avatars"` - UseOutdatedProfiles bool `yaml:"use_outdated_profiles"` - NumberInTopic bool `yaml:"number_in_topic"` - DeviceName string `yaml:"device_name"` + DisplaynameTemplate string `yaml:"displayname_template"` + UseContactAvatars bool `yaml:"use_contact_avatars"` + UseOutdatedProfiles bool `yaml:"use_outdated_profiles"` + NumberInTopic bool `yaml:"number_in_topic"` + DeviceName string `yaml:"device_name"` + NoteToSelfAvatar id.ContentURIString `yaml:"note_to_self_avatar"` + LocationFormat string `yaml:"location_format"` displaynameTemplate *template.Template `yaml:"-"` } @@ -97,6 +100,7 @@ type SignalConnector struct { } var _ bridgev2.NetworkConnector = (*SignalConnector)(nil) +var _ bridgev2.MaxFileSizeingNetwork = (*SignalConnector)(nil) var _ bridgev2.NetworkAPI = (*SignalClient)(nil) var _ msgconv.PortalMethods = (*msgconvPortalMethods)(nil) @@ -174,7 +178,7 @@ func (s *SignalConnector) Init(bridge *bridgev2.Bridge) { user, _ := s.Bridge.GetExistingUserByMXID(ctx, userID) // TODO log errors? if user != nil { - preferredLogin, _ := ctx.Value(msgconvContextKey).(*msgconvContext).Portal.FindPreferredLogin(ctx, user) + preferredLogin, _, _ := ctx.Value(msgconvContextKey).(*msgconvContext).Portal.FindPreferredLogin(ctx, user, true) if preferredLogin != nil { u, _ := uuid.Parse(string(preferredLogin.ID)) return u @@ -185,12 +189,16 @@ func (s *SignalConnector) Init(bridge *bridgev2.Bridge) { }, ConvertVoiceMessages: true, ConvertGIFToAPNG: true, - MaxFileSize: 100 * 1024 * 1024, + MaxFileSize: 50 * 1024 * 1024, AsyncFiles: true, - LocationFormat: "", + LocationFormat: s.Config.LocationFormat, } } +func (s *SignalConnector) SetMaxFileSize(maxSize int64) { + s.MsgConv.MaxFileSize = maxSize +} + func (s *SignalConnector) Start(ctx context.Context) error { return s.Store.Upgrade(ctx) } @@ -582,7 +590,7 @@ func (evt *Bv2ChatEvent) GetType() bridgev2.RemoteEventType { case *signalpb.EditMessage: return bridgev2.RemoteEventEdit case *signalpb.TypingMessage: - //return bridgev2.RemoteEventTyping + return bridgev2.RemoteEventTyping } return bridgev2.RemoteEventUnknown } @@ -752,13 +760,124 @@ func (evt *Bv2ChatEvent) ConvertEdit(ctx context.Context, portal *bridgev2.Porta return convertedEdit, nil } +type Bv2Receipt struct { + Type signalpb.ReceiptMessage_Type + Chat networkid.PortalKey + Sender bridgev2.EventSender + + LastTS time.Time + LastID networkid.MessageID + IDs []networkid.MessageID +} + +func (b *Bv2Receipt) GetType() bridgev2.RemoteEventType { + switch b.Type { + case signalpb.ReceiptMessage_READ: + return bridgev2.RemoteEventReadReceipt + case signalpb.ReceiptMessage_DELIVERY: + return bridgev2.RemoteEventDeliveryReceipt + default: + return bridgev2.RemoteEventUnknown + } +} + +func (b *Bv2Receipt) GetPortalKey() networkid.PortalKey { + return b.Chat +} + +func (b *Bv2Receipt) AddLogContext(c zerolog.Context) zerolog.Context { + return c. + Str("sender_id", string(b.Sender.Sender)). + Stringer("receipt_type", b.Type). + Array("message_ids", exzerolog.ArrayOfStrs(b.IDs)) +} + +func (b *Bv2Receipt) GetSender() bridgev2.EventSender { + return b.Sender +} + +func (b *Bv2Receipt) GetLastReceiptTarget() networkid.MessageID { + return b.LastID +} + +func (b *Bv2Receipt) GetReceiptTargets() []networkid.MessageID { + return b.IDs +} + +var _ bridgev2.RemoteReceipt = (*Bv2Receipt)(nil) + +func convertReceipts[T any](ctx context.Context, input []T, getMessageFunc func(ctx context.Context, msgID T) (*database.Message, error)) map[networkid.PortalKey]*Bv2Receipt { + log := zerolog.Ctx(ctx) + receipts := make(map[networkid.PortalKey]*Bv2Receipt) + for _, msgID := range input { + msg, err := getMessageFunc(ctx, msgID) + if err != nil { + log.Err(err).Any("message_id", msgID).Msg("Failed to get target message for receipt") + } else if msg == nil { + log.Debug().Any("message_id", msgID).Msg("Got receipt for unknown message") + } else { + receiptEvt, ok := receipts[msg.Room] + if !ok { + receiptEvt = &Bv2Receipt{Chat: msg.Room} + receipts[msg.Room] = receiptEvt + } + receiptEvt.IDs = append(receiptEvt.IDs, msg.ID) + if receiptEvt.LastTS.Before(msg.Timestamp) { + receiptEvt.LastTS = msg.Timestamp + receiptEvt.LastID = msg.ID + } + } + } + return receipts +} + +func (s *SignalClient) dispatchReceipts(sender uuid.UUID, receiptType signalpb.ReceiptMessage_Type, receipts map[networkid.PortalKey]*Bv2Receipt) { + evtSender := s.makeEventSender(sender) + for chat, receiptEvt := range receipts { + receiptEvt.Chat = chat + receiptEvt.Sender = evtSender + receiptEvt.Type = receiptType + s.Main.Bridge.QueueRemoteEvent(s.UserLogin, receiptEvt) + } +} + +func (s *SignalClient) handleSignalReceipt(evt *events.Receipt) { + log := s.UserLogin.Log.With(). + Str("action", "handle signal receipt"). + Stringer("sender_id", evt.Sender). + Stringer("receipt_type", evt.Content.GetType()). + Logger() + ctx := log.WithContext(context.TODO()) + receipts := convertReceipts(ctx, evt.Content.Timestamp, func(ctx context.Context, msgTS uint64) (*database.Message, error) { + return s.Main.Bridge.DB.Message.GetFirstPartByID(ctx, makeMessageID(s.Client.Store.ACI, msgTS)) + }) + s.dispatchReceipts(evt.Sender, evt.Content.GetType(), receipts) +} + +func (s *SignalClient) handleSignalReadSelf(evt *events.ReadSelf) { + log := s.UserLogin.Log.With(). + Str("action", "handle signal read self"). + Logger() + ctx := log.WithContext(context.TODO()) + receipts := convertReceipts(ctx, evt.Messages, func(ctx context.Context, msgInfo *signalpb.SyncMessage_Read) (*database.Message, error) { + aciUUID, err := uuid.Parse(msgInfo.GetSenderAci()) + if err != nil { + return nil, err + } + return s.Main.Bridge.DB.Message.GetFirstPartByID(ctx, makeMessageID(aciUUID, msgInfo.GetTimestamp())) + }) + s.dispatchReceipts(s.Client.Store.ACI, signalpb.ReceiptMessage_READ, receipts) +} + func (s *SignalClient) handleSignalEvent(rawEvt events.SignalEvent) { switch evt := rawEvt.(type) { case *events.ChatEvent: s.Main.Bridge.QueueRemoteEvent(s.UserLogin, &Bv2ChatEvent{ChatEvent: evt, s: s}) case *events.DecryptionError: case *events.Receipt: + s.handleSignalReceipt(evt) case *events.ReadSelf: + s.handleSignalReadSelf(evt) case *events.Call: case *events.ContactList: s.handleSignalContactList(evt) @@ -962,6 +1081,58 @@ func (s *SignalClient) HandleMatrixMessageRemove(ctx context.Context, msg *bridg return nil } +func (s *SignalClient) HandleMatrixReadReceipt(ctx context.Context, receipt *bridgev2.MatrixReadReceipt) error { + if !receipt.ReadUpTo.After(receipt.LastRead) { + return nil + } + if receipt.LastRead.IsZero() { + receipt.LastRead = receipt.ReadUpTo.Add(-5 * time.Second) + } + dbMessages, err := s.Main.Bridge.DB.Message.GetMessagesBetweenTimeQuery(ctx, receipt.Portal.PortalKey, receipt.LastRead, receipt.ReadUpTo) + if err != nil { + return fmt.Errorf("failed to get messages to mark as read: %w", err) + } else if len(dbMessages) == 0 { + return nil + } + messagesToRead := map[uuid.UUID][]uint64{} + for _, msg := range dbMessages { + userID, timestamp, err := parseMessageID(msg.ID) + if err != nil { + return fmt.Errorf("failed to parse message ID %q: %w", msg.ID, err) + } + messagesToRead[userID] = append(messagesToRead[userID], timestamp) + } + zerolog.Ctx(ctx).Debug(). + Any("targets", messagesToRead). + Msg("Collected read receipt target messages") + + // TODO send sync message manually containing all read receipts instead of a separate message for each recipient + + for destination, messages := range messagesToRead { + // Don't send read receipts for own messages + if destination == s.Client.Store.ACI { + continue + } + // Don't use portal.sendSignalMessage because we're sending this straight to + // who sent the original message, not the portal's ChatID + ctx, cancel := context.WithTimeout(ctx, 10*time.Second) + result := s.Client.SendMessage(ctx, libsignalgo.NewACIServiceID(destination), signalmeow.ReadReceptMessageForTimestamps(messages)) + cancel() + if !result.WasSuccessful { + zerolog.Ctx(ctx).Err(result.FailedSendResult.Error). + Stringer("destination", destination). + Uints64("message_ids", messages). + Msg("Failed to send read receipt to Signal") + } else { + zerolog.Ctx(ctx).Debug(). + Stringer("destination", destination). + Uints64("message_ids", messages). + Msg("Sent read receipt to Signal") + } + } + return nil +} + type msgconvPortalMethods struct{} func (mpm *msgconvPortalMethods) UploadMatrixMedia(ctx context.Context, data []byte, fileName, contentType string) (id.ContentURIString, error) { From 84999d499385ec84254f466ae1a30f7e331be68b Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Thu, 13 Jun 2024 17:27:19 +0300 Subject: [PATCH 042/580] ci: build binaries and docker images for v2 (#518) --- .gitlab-ci.yml | 7 ++++++- Dockerfile.v2.ci | 15 +++++++++++++++ docker-run.sh | 18 +++++++++++++----- 3 files changed, 34 insertions(+), 6 deletions(-) create mode 100644 Dockerfile.v2.ci diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 6c694eb..03bd8f5 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1,12 +1,17 @@ include: - project: 'mautrix/ci' file: '/go.yml' +- project: 'mautrix/ci' + file: '/gov2.yml' variables: BUILDER_IMAGE: dock.mau.dev/tulir/gomuks-build-docker/signal - BINARY_NAME: mautrix-signal # 32-bit arm builds aren't supported build arm: rules: - when: never + +build arm v2: + rules: + - when: never diff --git a/Dockerfile.v2.ci b/Dockerfile.v2.ci new file mode 100644 index 0000000..d5868a7 --- /dev/null +++ b/Dockerfile.v2.ci @@ -0,0 +1,15 @@ +FROM alpine:3.20 + +ENV UID=1337 \ + GID=1337 + +RUN apk add --no-cache ffmpeg su-exec ca-certificates bash jq curl yq-go + +ARG EXECUTABLE=./mautrix-signal-v2 +COPY $EXECUTABLE /usr/bin/mautrix-signal-v2 +COPY ./docker-run.sh /docker-run.sh +ENV BRIDGEV2=1 +VOLUME /data +WORKDIR /data + +CMD ["/docker-run.sh"] diff --git a/docker-run.sh b/docker-run.sh index c760f6b..6d6f3a7 100755 --- a/docker-run.sh +++ b/docker-run.sh @@ -4,6 +4,11 @@ if [[ -z "$GID" ]]; then GID="$UID" fi +BINARY_NAME=/usr/bin/mautrix-signal +if [[ "$BRIDGEV2" == "1" ]]; then + BINARY_NAME=/usr/bin/mautrix-signal-v2 +fi + # Define functions. function fixperms { chown -R $UID:$GID /data @@ -15,7 +20,11 @@ function fixperms { } if [[ ! -f /data/config.yaml ]]; then - cp /opt/mautrix-signal/example-config.yaml /data/config.yaml + if [[ "$BRIDGEV2" == "1" ]]; then + $BINARY_NAME -c /data/config -e + else + cp /opt/mautrix-signal/example-config.yaml /data/config.yaml + fi echo "Didn't find a config file." echo "Copied default config file to /data/config.yaml" echo "Modify that config file to your liking." @@ -24,7 +33,7 @@ if [[ ! -f /data/config.yaml ]]; then fi if [[ ! -f /data/registration.yaml ]]; then - /usr/bin/mautrix-signal -g -c /data/config.yaml -r /data/registration.yaml || exit $? + $BINARY_NAME -g -c /data/config.yaml -r /data/registration.yaml || exit $? echo "Didn't find a registration file." echo "Generated one for you." echo "See https://docs.mau.fi/bridges/general/registering-appservices.html on how to use it." @@ -34,13 +43,12 @@ fi cd /data fixperms -EXE=/usr/bin/mautrix-signal DLV=/usr/bin/dlv if [ -x "$DLV" ]; then if [ "$DBGWAIT" != 1 ]; then NOWAIT=1 fi - EXE="${DLV} exec ${EXE} ${NOWAIT:+--continue --accept-multiclient} --api-version 2 --headless -l :4040" + BINARY_NAME="${DLV} exec ${BINARY_NAME} ${NOWAIT:+--continue --accept-multiclient} --api-version 2 --headless -l :4040" fi -exec su-exec $UID:$GID $EXE +exec su-exec $UID:$GID $BINARY_NAME From fabe2657074fd17b9b8e519b7988fe1e9ced7a6b Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Thu, 13 Jun 2024 21:41:56 +0300 Subject: [PATCH 043/580] v2: update mautrix-go --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 0cef984..bd780c3 100644 --- a/go.mod +++ b/go.mod @@ -20,7 +20,7 @@ require ( golang.org/x/exp v0.0.0-20240604190554-fc45aab8b7f8 golang.org/x/net v0.26.0 google.golang.org/protobuf v1.34.1 - maunium.net/go/mautrix v0.18.2-0.20240612164408-cf6b0e71f0a0 + maunium.net/go/mautrix v0.18.2-0.20240613184127-2863a1323b60 nhooyr.io/websocket v1.8.11 ) diff --git a/go.sum b/go.sum index ba5d33d..e03e111 100644 --- a/go.sum +++ b/go.sum @@ -95,7 +95,7 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= maunium.net/go/mauflag v1.0.0 h1:YiaRc0tEI3toYtJMRIfjP+jklH45uDHtT80nUamyD4M= maunium.net/go/mauflag v1.0.0/go.mod h1:nLivPOpTpHnpzEh8jEdSL9UqO9+/KBJFmNRlwKfkPeA= -maunium.net/go/mautrix v0.18.2-0.20240612164408-cf6b0e71f0a0 h1:e+7glrQSSUm5GROTBYq/ENwhefRFmEXfGwRdP2FllAw= -maunium.net/go/mautrix v0.18.2-0.20240612164408-cf6b0e71f0a0/go.mod h1:qdyAG5Uvdz3kdw3wCCz/FGnnwjoXK+/b6Iy3fRXnKM0= +maunium.net/go/mautrix v0.18.2-0.20240613184127-2863a1323b60 h1:JqRWNajY57PTvSrMY3wx46u8pT2eAzmTh4kVJ7Wblhc= +maunium.net/go/mautrix v0.18.2-0.20240613184127-2863a1323b60/go.mod h1:qdyAG5Uvdz3kdw3wCCz/FGnnwjoXK+/b6Iy3fRXnKM0= nhooyr.io/websocket v1.8.11 h1:f/qXNc2/3DpoSZkHt1DQu6rj4zGC8JmkkLkWss0MgN0= nhooyr.io/websocket v1.8.11/go.mod h1:rN9OFWIUwuxg4fR5tELlYC04bXYowCP9GX47ivo2l+c= From d1e76ad973d5d987c74ae8e0468d9eac834d3a86 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Fri, 14 Jun 2024 12:47:36 +0300 Subject: [PATCH 044/580] v2: update mautrix-go --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index bd780c3..258845e 100644 --- a/go.mod +++ b/go.mod @@ -20,7 +20,7 @@ require ( golang.org/x/exp v0.0.0-20240604190554-fc45aab8b7f8 golang.org/x/net v0.26.0 google.golang.org/protobuf v1.34.1 - maunium.net/go/mautrix v0.18.2-0.20240613184127-2863a1323b60 + maunium.net/go/mautrix v0.18.2-0.20240614094708-b456fb6e0a6b nhooyr.io/websocket v1.8.11 ) diff --git a/go.sum b/go.sum index e03e111..61c4295 100644 --- a/go.sum +++ b/go.sum @@ -95,7 +95,7 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= maunium.net/go/mauflag v1.0.0 h1:YiaRc0tEI3toYtJMRIfjP+jklH45uDHtT80nUamyD4M= maunium.net/go/mauflag v1.0.0/go.mod h1:nLivPOpTpHnpzEh8jEdSL9UqO9+/KBJFmNRlwKfkPeA= -maunium.net/go/mautrix v0.18.2-0.20240613184127-2863a1323b60 h1:JqRWNajY57PTvSrMY3wx46u8pT2eAzmTh4kVJ7Wblhc= -maunium.net/go/mautrix v0.18.2-0.20240613184127-2863a1323b60/go.mod h1:qdyAG5Uvdz3kdw3wCCz/FGnnwjoXK+/b6Iy3fRXnKM0= +maunium.net/go/mautrix v0.18.2-0.20240614094708-b456fb6e0a6b h1:/JvXcwT+y9SR0AN0fQIhIOz+9Uy9jhwpqqFEYxuTtTI= +maunium.net/go/mautrix v0.18.2-0.20240614094708-b456fb6e0a6b/go.mod h1:qdyAG5Uvdz3kdw3wCCz/FGnnwjoXK+/b6Iy3fRXnKM0= nhooyr.io/websocket v1.8.11 h1:f/qXNc2/3DpoSZkHt1DQu6rj4zGC8JmkkLkWss0MgN0= nhooyr.io/websocket v1.8.11/go.mod h1:rN9OFWIUwuxg4fR5tELlYC04bXYowCP9GX47ivo2l+c= From 114d478e61b4ce90fecfd922efb0e16bf056c00d Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Fri, 14 Jun 2024 15:43:59 +0300 Subject: [PATCH 045/580] signalmeow: update protobuf schemas --- .../protobuf/ContactDiscovery.pb.go | 2 +- pkg/signalmeow/protobuf/DeviceName.pb.go | 2 +- pkg/signalmeow/protobuf/Groups.pb.go | 2 +- pkg/signalmeow/protobuf/Provisioning.pb.go | 2 +- pkg/signalmeow/protobuf/SignalService.pb.go | 1836 +++++++++++------ pkg/signalmeow/protobuf/SignalService.proto | 56 +- .../protobuf/StickerResources.pb.go | 2 +- pkg/signalmeow/protobuf/StorageService.pb.go | 588 +++--- pkg/signalmeow/protobuf/StorageService.proto | 9 +- .../protobuf/UnidentifiedDelivery.pb.go | 2 +- .../protobuf/WebSocketResources.pb.go | 2 +- pkg/signalmeow/protobuf/update-protos.sh | 4 +- 12 files changed, 1639 insertions(+), 868 deletions(-) diff --git a/pkg/signalmeow/protobuf/ContactDiscovery.pb.go b/pkg/signalmeow/protobuf/ContactDiscovery.pb.go index 282d9a8..b252d37 100644 --- a/pkg/signalmeow/protobuf/ContactDiscovery.pb.go +++ b/pkg/signalmeow/protobuf/ContactDiscovery.pb.go @@ -1,6 +1,6 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.31.0 +// protoc-gen-go v1.34.1 // protoc v3.21.12 // source: ContactDiscovery.proto diff --git a/pkg/signalmeow/protobuf/DeviceName.pb.go b/pkg/signalmeow/protobuf/DeviceName.pb.go index 657dcf5..2cdca84 100644 --- a/pkg/signalmeow/protobuf/DeviceName.pb.go +++ b/pkg/signalmeow/protobuf/DeviceName.pb.go @@ -1,6 +1,6 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.31.0 +// protoc-gen-go v1.34.1 // protoc v3.21.12 // source: DeviceName.proto diff --git a/pkg/signalmeow/protobuf/Groups.pb.go b/pkg/signalmeow/protobuf/Groups.pb.go index a49ea9f..8ec4a97 100644 --- a/pkg/signalmeow/protobuf/Groups.pb.go +++ b/pkg/signalmeow/protobuf/Groups.pb.go @@ -5,7 +5,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.31.0 +// protoc-gen-go v1.34.1 // protoc v3.21.12 // source: Groups.proto diff --git a/pkg/signalmeow/protobuf/Provisioning.pb.go b/pkg/signalmeow/protobuf/Provisioning.pb.go index 446162e..e2ceb1f 100644 --- a/pkg/signalmeow/protobuf/Provisioning.pb.go +++ b/pkg/signalmeow/protobuf/Provisioning.pb.go @@ -5,7 +5,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.31.0 +// protoc-gen-go v1.34.1 // protoc v3.21.12 // source: Provisioning.proto diff --git a/pkg/signalmeow/protobuf/SignalService.pb.go b/pkg/signalmeow/protobuf/SignalService.pb.go index aa5d674..1ff1228 100644 --- a/pkg/signalmeow/protobuf/SignalService.pb.go +++ b/pkg/signalmeow/protobuf/SignalService.pb.go @@ -5,7 +5,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.31.0 +// protoc-gen-go v1.34.1 // protoc v3.21.12 // source: SignalService.proto @@ -1517,8 +1517,9 @@ func (SyncMessage_CallLinkUpdate_Type) EnumDescriptor() ([]byte, []int) { type SyncMessage_CallLogEvent_Type int32 const ( - SyncMessage_CallLogEvent_CLEAR SyncMessage_CallLogEvent_Type = 0 - SyncMessage_CallLogEvent_MARKED_AS_READ SyncMessage_CallLogEvent_Type = 1 + SyncMessage_CallLogEvent_CLEAR SyncMessage_CallLogEvent_Type = 0 + SyncMessage_CallLogEvent_MARKED_AS_READ SyncMessage_CallLogEvent_Type = 1 + SyncMessage_CallLogEvent_MARKED_AS_READ_IN_CONVERSATION SyncMessage_CallLogEvent_Type = 2 ) // Enum value maps for SyncMessage_CallLogEvent_Type. @@ -1526,10 +1527,12 @@ var ( SyncMessage_CallLogEvent_Type_name = map[int32]string{ 0: "CLEAR", 1: "MARKED_AS_READ", + 2: "MARKED_AS_READ_IN_CONVERSATION", } SyncMessage_CallLogEvent_Type_value = map[string]int32{ - "CLEAR": 0, - "MARKED_AS_READ": 1, + "CLEAR": 0, + "MARKED_AS_READ": 1, + "MARKED_AS_READ_IN_CONVERSATION": 2, } ) @@ -2917,6 +2920,7 @@ type SyncMessage struct { CallEvent *SyncMessage_CallEvent `protobuf:"bytes,19,opt,name=callEvent" json:"callEvent,omitempty"` CallLinkUpdate *SyncMessage_CallLinkUpdate `protobuf:"bytes,20,opt,name=callLinkUpdate" json:"callLinkUpdate,omitempty"` CallLogEvent *SyncMessage_CallLogEvent `protobuf:"bytes,21,opt,name=callLogEvent" json:"callLogEvent,omitempty"` + DeleteForMe *SyncMessage_DeleteForMe `protobuf:"bytes,22,opt,name=deleteForMe" json:"deleteForMe,omitempty"` } func (x *SyncMessage) Reset() { @@ -3084,6 +3088,13 @@ func (x *SyncMessage) GetCallLogEvent() *SyncMessage_CallLogEvent { return nil } +func (x *SyncMessage) GetDeleteForMe() *SyncMessage_DeleteForMe { + if x != nil { + return x.DeleteForMe + } + return nil +} + type AttachmentPointer struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -3447,7 +3458,6 @@ type ContactDetails struct { Color *string `protobuf:"bytes,4,opt,name=color" json:"color,omitempty"` Verified *Verified `protobuf:"bytes,5,opt,name=verified" json:"verified,omitempty"` ProfileKey []byte `protobuf:"bytes,6,opt,name=profileKey" json:"profileKey,omitempty"` - Blocked *bool `protobuf:"varint,7,opt,name=blocked" json:"blocked,omitempty"` ExpireTimer *uint32 `protobuf:"varint,8,opt,name=expireTimer" json:"expireTimer,omitempty"` InboxPosition *uint32 `protobuf:"varint,10,opt,name=inboxPosition" json:"inboxPosition,omitempty"` Archived *bool `protobuf:"varint,11,opt,name=archived" json:"archived,omitempty"` @@ -3534,13 +3544,6 @@ func (x *ContactDetails) GetProfileKey() []byte { return nil } -func (x *ContactDetails) GetBlocked() bool { - if x != nil && x.Blocked != nil { - return *x.Blocked - } - return false -} - func (x *ContactDetails) GetExpireTimer() uint32 { if x != nil && x.ExpireTimer != nil { return *x.ExpireTimer @@ -6764,6 +6767,13 @@ type SyncMessage_CallLogEvent struct { Type *SyncMessage_CallLogEvent_Type `protobuf:"varint,1,opt,name=type,enum=signalservice.SyncMessage_CallLogEvent_Type" json:"type,omitempty"` Timestamp *uint64 `protobuf:"varint,2,opt,name=timestamp" json:"timestamp,omitempty"` + // Data identifying a conversation. The service ID for 1:1, the group ID for + // group, or the room ID for an ad-hoc call. See also + // `CallEvent/conversationId`. + ConversationId []byte `protobuf:"bytes,3,opt,name=conversationId" json:"conversationId,omitempty"` + // An identifier for a call. Generated directly for 1:1, or derived from + // the era ID for group and ad-hoc calls. See also `CallEvent/callId`. + CallId *uint64 `protobuf:"varint,4,opt,name=callId" json:"callId,omitempty"` } func (x *SyncMessage_CallLogEvent) Reset() { @@ -6812,6 +6822,83 @@ func (x *SyncMessage_CallLogEvent) GetTimestamp() uint64 { return 0 } +func (x *SyncMessage_CallLogEvent) GetConversationId() []byte { + if x != nil { + return x.ConversationId + } + return nil +} + +func (x *SyncMessage_CallLogEvent) GetCallId() uint64 { + if x != nil && x.CallId != nil { + return *x.CallId + } + return 0 +} + +type SyncMessage_DeleteForMe struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + MessageDeletes []*SyncMessage_DeleteForMe_MessageDeletes `protobuf:"bytes,1,rep,name=messageDeletes" json:"messageDeletes,omitempty"` + ConversationDeletes []*SyncMessage_DeleteForMe_ConversationDelete `protobuf:"bytes,2,rep,name=conversationDeletes" json:"conversationDeletes,omitempty"` + LocalOnlyConversationDeletes []*SyncMessage_DeleteForMe_LocalOnlyConversationDelete `protobuf:"bytes,3,rep,name=localOnlyConversationDeletes" json:"localOnlyConversationDeletes,omitempty"` +} + +func (x *SyncMessage_DeleteForMe) Reset() { + *x = SyncMessage_DeleteForMe{} + if protoimpl.UnsafeEnabled { + mi := &file_SignalService_proto_msgTypes[66] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *SyncMessage_DeleteForMe) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SyncMessage_DeleteForMe) ProtoMessage() {} + +func (x *SyncMessage_DeleteForMe) ProtoReflect() protoreflect.Message { + mi := &file_SignalService_proto_msgTypes[66] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use SyncMessage_DeleteForMe.ProtoReflect.Descriptor instead. +func (*SyncMessage_DeleteForMe) Descriptor() ([]byte, []int) { + return file_SignalService_proto_rawDescGZIP(), []int{12, 17} +} + +func (x *SyncMessage_DeleteForMe) GetMessageDeletes() []*SyncMessage_DeleteForMe_MessageDeletes { + if x != nil { + return x.MessageDeletes + } + return nil +} + +func (x *SyncMessage_DeleteForMe) GetConversationDeletes() []*SyncMessage_DeleteForMe_ConversationDelete { + if x != nil { + return x.ConversationDeletes + } + return nil +} + +func (x *SyncMessage_DeleteForMe) GetLocalOnlyConversationDeletes() []*SyncMessage_DeleteForMe_LocalOnlyConversationDelete { + if x != nil { + return x.LocalOnlyConversationDeletes + } + return nil +} + type SyncMessage_Sent_UnidentifiedDeliveryStatus struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -6825,7 +6912,7 @@ type SyncMessage_Sent_UnidentifiedDeliveryStatus struct { func (x *SyncMessage_Sent_UnidentifiedDeliveryStatus) Reset() { *x = SyncMessage_Sent_UnidentifiedDeliveryStatus{} if protoimpl.UnsafeEnabled { - mi := &file_SignalService_proto_msgTypes[66] + mi := &file_SignalService_proto_msgTypes[67] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6838,7 +6925,7 @@ func (x *SyncMessage_Sent_UnidentifiedDeliveryStatus) String() string { func (*SyncMessage_Sent_UnidentifiedDeliveryStatus) ProtoMessage() {} func (x *SyncMessage_Sent_UnidentifiedDeliveryStatus) ProtoReflect() protoreflect.Message { - mi := &file_SignalService_proto_msgTypes[66] + mi := &file_SignalService_proto_msgTypes[67] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6888,7 +6975,7 @@ type SyncMessage_Sent_StoryMessageRecipient struct { func (x *SyncMessage_Sent_StoryMessageRecipient) Reset() { *x = SyncMessage_Sent_StoryMessageRecipient{} if protoimpl.UnsafeEnabled { - mi := &file_SignalService_proto_msgTypes[67] + mi := &file_SignalService_proto_msgTypes[68] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6901,7 +6988,7 @@ func (x *SyncMessage_Sent_StoryMessageRecipient) String() string { func (*SyncMessage_Sent_StoryMessageRecipient) ProtoMessage() {} func (x *SyncMessage_Sent_StoryMessageRecipient) ProtoReflect() protoreflect.Message { - mi := &file_SignalService_proto_msgTypes[67] + mi := &file_SignalService_proto_msgTypes[68] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6959,7 +7046,7 @@ type SyncMessage_OutgoingPayment_MobileCoin struct { func (x *SyncMessage_OutgoingPayment_MobileCoin) Reset() { *x = SyncMessage_OutgoingPayment_MobileCoin{} if protoimpl.UnsafeEnabled { - mi := &file_SignalService_proto_msgTypes[68] + mi := &file_SignalService_proto_msgTypes[69] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6972,7 +7059,7 @@ func (x *SyncMessage_OutgoingPayment_MobileCoin) String() string { func (*SyncMessage_OutgoingPayment_MobileCoin) ProtoMessage() {} func (x *SyncMessage_OutgoingPayment_MobileCoin) ProtoReflect() protoreflect.Message { - mi := &file_SignalService_proto_msgTypes[68] + mi := &file_SignalService_proto_msgTypes[69] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7044,6 +7131,360 @@ func (x *SyncMessage_OutgoingPayment_MobileCoin) GetOutputPublicKeys() [][]byte return nil } +type SyncMessage_DeleteForMe_ConversationIdentifier struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Types that are assignable to Identifier: + // + // *SyncMessage_DeleteForMe_ConversationIdentifier_ThreadAci + // *SyncMessage_DeleteForMe_ConversationIdentifier_ThreadGroupId + // *SyncMessage_DeleteForMe_ConversationIdentifier_ThreadE164 + Identifier isSyncMessage_DeleteForMe_ConversationIdentifier_Identifier `protobuf_oneof:"identifier"` +} + +func (x *SyncMessage_DeleteForMe_ConversationIdentifier) Reset() { + *x = SyncMessage_DeleteForMe_ConversationIdentifier{} + if protoimpl.UnsafeEnabled { + mi := &file_SignalService_proto_msgTypes[70] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *SyncMessage_DeleteForMe_ConversationIdentifier) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SyncMessage_DeleteForMe_ConversationIdentifier) ProtoMessage() {} + +func (x *SyncMessage_DeleteForMe_ConversationIdentifier) ProtoReflect() protoreflect.Message { + mi := &file_SignalService_proto_msgTypes[70] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use SyncMessage_DeleteForMe_ConversationIdentifier.ProtoReflect.Descriptor instead. +func (*SyncMessage_DeleteForMe_ConversationIdentifier) Descriptor() ([]byte, []int) { + return file_SignalService_proto_rawDescGZIP(), []int{12, 17, 0} +} + +func (m *SyncMessage_DeleteForMe_ConversationIdentifier) GetIdentifier() isSyncMessage_DeleteForMe_ConversationIdentifier_Identifier { + if m != nil { + return m.Identifier + } + return nil +} + +func (x *SyncMessage_DeleteForMe_ConversationIdentifier) GetThreadAci() string { + if x, ok := x.GetIdentifier().(*SyncMessage_DeleteForMe_ConversationIdentifier_ThreadAci); ok { + return x.ThreadAci + } + return "" +} + +func (x *SyncMessage_DeleteForMe_ConversationIdentifier) GetThreadGroupId() []byte { + if x, ok := x.GetIdentifier().(*SyncMessage_DeleteForMe_ConversationIdentifier_ThreadGroupId); ok { + return x.ThreadGroupId + } + return nil +} + +func (x *SyncMessage_DeleteForMe_ConversationIdentifier) GetThreadE164() string { + if x, ok := x.GetIdentifier().(*SyncMessage_DeleteForMe_ConversationIdentifier_ThreadE164); ok { + return x.ThreadE164 + } + return "" +} + +type isSyncMessage_DeleteForMe_ConversationIdentifier_Identifier interface { + isSyncMessage_DeleteForMe_ConversationIdentifier_Identifier() +} + +type SyncMessage_DeleteForMe_ConversationIdentifier_ThreadAci struct { + ThreadAci string `protobuf:"bytes,1,opt,name=threadAci,oneof"` +} + +type SyncMessage_DeleteForMe_ConversationIdentifier_ThreadGroupId struct { + ThreadGroupId []byte `protobuf:"bytes,2,opt,name=threadGroupId,oneof"` +} + +type SyncMessage_DeleteForMe_ConversationIdentifier_ThreadE164 struct { + ThreadE164 string `protobuf:"bytes,3,opt,name=threadE164,oneof"` +} + +func (*SyncMessage_DeleteForMe_ConversationIdentifier_ThreadAci) isSyncMessage_DeleteForMe_ConversationIdentifier_Identifier() { +} + +func (*SyncMessage_DeleteForMe_ConversationIdentifier_ThreadGroupId) isSyncMessage_DeleteForMe_ConversationIdentifier_Identifier() { +} + +func (*SyncMessage_DeleteForMe_ConversationIdentifier_ThreadE164) isSyncMessage_DeleteForMe_ConversationIdentifier_Identifier() { +} + +type SyncMessage_DeleteForMe_AddressableMessage struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Types that are assignable to Author: + // + // *SyncMessage_DeleteForMe_AddressableMessage_AuthorAci + // *SyncMessage_DeleteForMe_AddressableMessage_AuthorE164 + Author isSyncMessage_DeleteForMe_AddressableMessage_Author `protobuf_oneof:"author"` + SentTimestamp *uint64 `protobuf:"varint,3,opt,name=sentTimestamp" json:"sentTimestamp,omitempty"` +} + +func (x *SyncMessage_DeleteForMe_AddressableMessage) Reset() { + *x = SyncMessage_DeleteForMe_AddressableMessage{} + if protoimpl.UnsafeEnabled { + mi := &file_SignalService_proto_msgTypes[71] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *SyncMessage_DeleteForMe_AddressableMessage) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SyncMessage_DeleteForMe_AddressableMessage) ProtoMessage() {} + +func (x *SyncMessage_DeleteForMe_AddressableMessage) ProtoReflect() protoreflect.Message { + mi := &file_SignalService_proto_msgTypes[71] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use SyncMessage_DeleteForMe_AddressableMessage.ProtoReflect.Descriptor instead. +func (*SyncMessage_DeleteForMe_AddressableMessage) Descriptor() ([]byte, []int) { + return file_SignalService_proto_rawDescGZIP(), []int{12, 17, 1} +} + +func (m *SyncMessage_DeleteForMe_AddressableMessage) GetAuthor() isSyncMessage_DeleteForMe_AddressableMessage_Author { + if m != nil { + return m.Author + } + return nil +} + +func (x *SyncMessage_DeleteForMe_AddressableMessage) GetAuthorAci() string { + if x, ok := x.GetAuthor().(*SyncMessage_DeleteForMe_AddressableMessage_AuthorAci); ok { + return x.AuthorAci + } + return "" +} + +func (x *SyncMessage_DeleteForMe_AddressableMessage) GetAuthorE164() string { + if x, ok := x.GetAuthor().(*SyncMessage_DeleteForMe_AddressableMessage_AuthorE164); ok { + return x.AuthorE164 + } + return "" +} + +func (x *SyncMessage_DeleteForMe_AddressableMessage) GetSentTimestamp() uint64 { + if x != nil && x.SentTimestamp != nil { + return *x.SentTimestamp + } + return 0 +} + +type isSyncMessage_DeleteForMe_AddressableMessage_Author interface { + isSyncMessage_DeleteForMe_AddressableMessage_Author() +} + +type SyncMessage_DeleteForMe_AddressableMessage_AuthorAci struct { + AuthorAci string `protobuf:"bytes,1,opt,name=authorAci,oneof"` +} + +type SyncMessage_DeleteForMe_AddressableMessage_AuthorE164 struct { + AuthorE164 string `protobuf:"bytes,2,opt,name=authorE164,oneof"` +} + +func (*SyncMessage_DeleteForMe_AddressableMessage_AuthorAci) isSyncMessage_DeleteForMe_AddressableMessage_Author() { +} + +func (*SyncMessage_DeleteForMe_AddressableMessage_AuthorE164) isSyncMessage_DeleteForMe_AddressableMessage_Author() { +} + +type SyncMessage_DeleteForMe_MessageDeletes struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Conversation *SyncMessage_DeleteForMe_ConversationIdentifier `protobuf:"bytes,1,opt,name=conversation" json:"conversation,omitempty"` + Messages []*SyncMessage_DeleteForMe_AddressableMessage `protobuf:"bytes,2,rep,name=messages" json:"messages,omitempty"` +} + +func (x *SyncMessage_DeleteForMe_MessageDeletes) Reset() { + *x = SyncMessage_DeleteForMe_MessageDeletes{} + if protoimpl.UnsafeEnabled { + mi := &file_SignalService_proto_msgTypes[72] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *SyncMessage_DeleteForMe_MessageDeletes) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SyncMessage_DeleteForMe_MessageDeletes) ProtoMessage() {} + +func (x *SyncMessage_DeleteForMe_MessageDeletes) ProtoReflect() protoreflect.Message { + mi := &file_SignalService_proto_msgTypes[72] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use SyncMessage_DeleteForMe_MessageDeletes.ProtoReflect.Descriptor instead. +func (*SyncMessage_DeleteForMe_MessageDeletes) Descriptor() ([]byte, []int) { + return file_SignalService_proto_rawDescGZIP(), []int{12, 17, 2} +} + +func (x *SyncMessage_DeleteForMe_MessageDeletes) GetConversation() *SyncMessage_DeleteForMe_ConversationIdentifier { + if x != nil { + return x.Conversation + } + return nil +} + +func (x *SyncMessage_DeleteForMe_MessageDeletes) GetMessages() []*SyncMessage_DeleteForMe_AddressableMessage { + if x != nil { + return x.Messages + } + return nil +} + +type SyncMessage_DeleteForMe_ConversationDelete struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Conversation *SyncMessage_DeleteForMe_ConversationIdentifier `protobuf:"bytes,1,opt,name=conversation" json:"conversation,omitempty"` + MostRecentMessages []*SyncMessage_DeleteForMe_AddressableMessage `protobuf:"bytes,2,rep,name=mostRecentMessages" json:"mostRecentMessages,omitempty"` + IsFullDelete *bool `protobuf:"varint,3,opt,name=isFullDelete" json:"isFullDelete,omitempty"` +} + +func (x *SyncMessage_DeleteForMe_ConversationDelete) Reset() { + *x = SyncMessage_DeleteForMe_ConversationDelete{} + if protoimpl.UnsafeEnabled { + mi := &file_SignalService_proto_msgTypes[73] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *SyncMessage_DeleteForMe_ConversationDelete) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SyncMessage_DeleteForMe_ConversationDelete) ProtoMessage() {} + +func (x *SyncMessage_DeleteForMe_ConversationDelete) ProtoReflect() protoreflect.Message { + mi := &file_SignalService_proto_msgTypes[73] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use SyncMessage_DeleteForMe_ConversationDelete.ProtoReflect.Descriptor instead. +func (*SyncMessage_DeleteForMe_ConversationDelete) Descriptor() ([]byte, []int) { + return file_SignalService_proto_rawDescGZIP(), []int{12, 17, 3} +} + +func (x *SyncMessage_DeleteForMe_ConversationDelete) GetConversation() *SyncMessage_DeleteForMe_ConversationIdentifier { + if x != nil { + return x.Conversation + } + return nil +} + +func (x *SyncMessage_DeleteForMe_ConversationDelete) GetMostRecentMessages() []*SyncMessage_DeleteForMe_AddressableMessage { + if x != nil { + return x.MostRecentMessages + } + return nil +} + +func (x *SyncMessage_DeleteForMe_ConversationDelete) GetIsFullDelete() bool { + if x != nil && x.IsFullDelete != nil { + return *x.IsFullDelete + } + return false +} + +type SyncMessage_DeleteForMe_LocalOnlyConversationDelete struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Conversation *SyncMessage_DeleteForMe_ConversationIdentifier `protobuf:"bytes,1,opt,name=conversation" json:"conversation,omitempty"` +} + +func (x *SyncMessage_DeleteForMe_LocalOnlyConversationDelete) Reset() { + *x = SyncMessage_DeleteForMe_LocalOnlyConversationDelete{} + if protoimpl.UnsafeEnabled { + mi := &file_SignalService_proto_msgTypes[74] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *SyncMessage_DeleteForMe_LocalOnlyConversationDelete) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SyncMessage_DeleteForMe_LocalOnlyConversationDelete) ProtoMessage() {} + +func (x *SyncMessage_DeleteForMe_LocalOnlyConversationDelete) ProtoReflect() protoreflect.Message { + mi := &file_SignalService_proto_msgTypes[74] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use SyncMessage_DeleteForMe_LocalOnlyConversationDelete.ProtoReflect.Descriptor instead. +func (*SyncMessage_DeleteForMe_LocalOnlyConversationDelete) Descriptor() ([]byte, []int) { + return file_SignalService_proto_rawDescGZIP(), []int{12, 17, 4} +} + +func (x *SyncMessage_DeleteForMe_LocalOnlyConversationDelete) GetConversation() *SyncMessage_DeleteForMe_ConversationIdentifier { + if x != nil { + return x.Conversation + } + return nil +} + type GroupContext_Member struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -7055,7 +7496,7 @@ type GroupContext_Member struct { func (x *GroupContext_Member) Reset() { *x = GroupContext_Member{} if protoimpl.UnsafeEnabled { - mi := &file_SignalService_proto_msgTypes[69] + mi := &file_SignalService_proto_msgTypes[75] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7068,7 +7509,7 @@ func (x *GroupContext_Member) String() string { func (*GroupContext_Member) ProtoMessage() {} func (x *GroupContext_Member) ProtoReflect() protoreflect.Message { - mi := &file_SignalService_proto_msgTypes[69] + mi := &file_SignalService_proto_msgTypes[75] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7103,7 +7544,7 @@ type ContactDetails_Avatar struct { func (x *ContactDetails_Avatar) Reset() { *x = ContactDetails_Avatar{} if protoimpl.UnsafeEnabled { - mi := &file_SignalService_proto_msgTypes[70] + mi := &file_SignalService_proto_msgTypes[76] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7116,7 +7557,7 @@ func (x *ContactDetails_Avatar) String() string { func (*ContactDetails_Avatar) ProtoMessage() {} func (x *ContactDetails_Avatar) ProtoReflect() protoreflect.Message { - mi := &file_SignalService_proto_msgTypes[70] + mi := &file_SignalService_proto_msgTypes[76] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7158,7 +7599,7 @@ type GroupDetails_Avatar struct { func (x *GroupDetails_Avatar) Reset() { *x = GroupDetails_Avatar{} if protoimpl.UnsafeEnabled { - mi := &file_SignalService_proto_msgTypes[71] + mi := &file_SignalService_proto_msgTypes[77] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7171,7 +7612,7 @@ func (x *GroupDetails_Avatar) String() string { func (*GroupDetails_Avatar) ProtoMessage() {} func (x *GroupDetails_Avatar) ProtoReflect() protoreflect.Message { - mi := &file_SignalService_proto_msgTypes[71] + mi := &file_SignalService_proto_msgTypes[77] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7212,7 +7653,7 @@ type GroupDetails_Member struct { func (x *GroupDetails_Member) Reset() { *x = GroupDetails_Member{} if protoimpl.UnsafeEnabled { - mi := &file_SignalService_proto_msgTypes[72] + mi := &file_SignalService_proto_msgTypes[78] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7225,7 +7666,7 @@ func (x *GroupDetails_Member) String() string { func (*GroupDetails_Member) ProtoMessage() {} func (x *GroupDetails_Member) ProtoReflect() protoreflect.Message { - mi := &file_SignalService_proto_msgTypes[72] + mi := &file_SignalService_proto_msgTypes[78] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7260,7 +7701,7 @@ type PaymentAddress_MobileCoinAddress struct { func (x *PaymentAddress_MobileCoinAddress) Reset() { *x = PaymentAddress_MobileCoinAddress{} if protoimpl.UnsafeEnabled { - mi := &file_SignalService_proto_msgTypes[73] + mi := &file_SignalService_proto_msgTypes[79] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7273,7 +7714,7 @@ func (x *PaymentAddress_MobileCoinAddress) String() string { func (*PaymentAddress_MobileCoinAddress) ProtoMessage() {} func (x *PaymentAddress_MobileCoinAddress) ProtoReflect() protoreflect.Message { - mi := &file_SignalService_proto_msgTypes[73] + mi := &file_SignalService_proto_msgTypes[79] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7860,7 +8301,7 @@ var file_SignalService_proto_rawDesc = []byte{ 0x67, 0x65, 0x22, 0x32, 0x0a, 0x05, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x0b, 0x0a, 0x07, 0x44, 0x45, 0x46, 0x41, 0x55, 0x4c, 0x54, 0x10, 0x00, 0x12, 0x0c, 0x0a, 0x08, 0x56, 0x45, 0x52, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x01, 0x12, 0x0e, 0x0a, 0x0a, 0x55, 0x4e, 0x56, 0x45, 0x52, 0x49, - 0x46, 0x49, 0x45, 0x44, 0x10, 0x02, 0x4a, 0x04, 0x08, 0x01, 0x10, 0x02, 0x22, 0x8f, 0x2b, 0x0a, + 0x46, 0x49, 0x45, 0x44, 0x10, 0x02, 0x4a, 0x04, 0x08, 0x01, 0x10, 0x02, 0x22, 0x97, 0x36, 0x0a, 0x0b, 0x53, 0x79, 0x6e, 0x63, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x33, 0x0a, 0x04, 0x73, 0x65, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x6c, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x53, 0x79, 0x6e, 0x63, 0x4d, @@ -7944,432 +8385,519 @@ var file_SignalService_proto_rawDesc = []byte{ 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x6c, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x53, 0x79, 0x6e, 0x63, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x43, 0x61, 0x6c, 0x6c, 0x4c, 0x6f, 0x67, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x52, 0x0c, 0x63, 0x61, 0x6c, - 0x6c, 0x4c, 0x6f, 0x67, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x1a, 0xf0, 0x07, 0x0a, 0x04, 0x53, 0x65, - 0x6e, 0x74, 0x12, 0x28, 0x0a, 0x0f, 0x64, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x45, 0x31, 0x36, 0x34, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x64, 0x65, 0x73, - 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x31, 0x36, 0x34, 0x12, 0x32, 0x0a, 0x14, - 0x64, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x65, 0x72, 0x76, 0x69, - 0x63, 0x65, 0x49, 0x64, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x14, 0x64, 0x65, 0x73, 0x74, - 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x49, 0x64, - 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x04, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x34, - 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x1a, 0x2e, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x6c, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, - 0x44, 0x61, 0x74, 0x61, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x07, 0x6d, 0x65, 0x73, - 0x73, 0x61, 0x67, 0x65, 0x12, 0x3a, 0x0a, 0x18, 0x65, 0x78, 0x70, 0x69, 0x72, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x72, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, - 0x18, 0x04, 0x20, 0x01, 0x28, 0x04, 0x52, 0x18, 0x65, 0x78, 0x70, 0x69, 0x72, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x72, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, - 0x12, 0x6a, 0x0a, 0x12, 0x75, 0x6e, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x64, - 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x3a, 0x2e, 0x73, + 0x6c, 0x4c, 0x6f, 0x67, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x48, 0x0a, 0x0b, 0x64, 0x65, 0x6c, + 0x65, 0x74, 0x65, 0x46, 0x6f, 0x72, 0x4d, 0x65, 0x18, 0x16, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x26, + 0x2e, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x6c, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x53, + 0x79, 0x6e, 0x63, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, + 0x65, 0x46, 0x6f, 0x72, 0x4d, 0x65, 0x52, 0x0b, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x46, 0x6f, + 0x72, 0x4d, 0x65, 0x1a, 0xf0, 0x07, 0x0a, 0x04, 0x53, 0x65, 0x6e, 0x74, 0x12, 0x28, 0x0a, 0x0f, + 0x64, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x31, 0x36, 0x34, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x64, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x45, 0x31, 0x36, 0x34, 0x12, 0x32, 0x0a, 0x14, 0x64, 0x65, 0x73, 0x74, 0x69, 0x6e, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x49, 0x64, 0x18, 0x07, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x14, 0x64, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x49, 0x64, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x69, + 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x09, 0x74, + 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x34, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, + 0x61, 0x67, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x73, 0x69, 0x67, 0x6e, + 0x61, 0x6c, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x44, 0x61, 0x74, 0x61, 0x4d, 0x65, + 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x3a, + 0x0a, 0x18, 0x65, 0x78, 0x70, 0x69, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x72, + 0x74, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x04, 0x20, 0x01, 0x28, 0x04, + 0x52, 0x18, 0x65, 0x78, 0x70, 0x69, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x72, + 0x74, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x6a, 0x0a, 0x12, 0x75, 0x6e, + 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, + 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x3a, 0x2e, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x6c, 0x73, + 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x53, 0x79, 0x6e, 0x63, 0x4d, 0x65, 0x73, 0x73, 0x61, + 0x67, 0x65, 0x2e, 0x53, 0x65, 0x6e, 0x74, 0x2e, 0x55, 0x6e, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, + 0x66, 0x69, 0x65, 0x64, 0x44, 0x65, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x79, 0x53, 0x74, 0x61, 0x74, + 0x75, 0x73, 0x52, 0x12, 0x75, 0x6e, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x64, + 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x33, 0x0a, 0x11, 0x69, 0x73, 0x52, 0x65, 0x63, 0x69, + 0x70, 0x69, 0x65, 0x6e, 0x74, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, + 0x08, 0x3a, 0x05, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x52, 0x11, 0x69, 0x73, 0x52, 0x65, 0x63, 0x69, + 0x70, 0x69, 0x65, 0x6e, 0x74, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x12, 0x3f, 0x0a, 0x0c, 0x73, + 0x74, 0x6f, 0x72, 0x79, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x08, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x1b, 0x2e, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x6c, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, + 0x65, 0x2e, 0x53, 0x74, 0x6f, 0x72, 0x79, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x0c, + 0x73, 0x74, 0x6f, 0x72, 0x79, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x6d, 0x0a, 0x16, + 0x73, 0x74, 0x6f, 0x72, 0x79, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x65, 0x63, 0x69, + 0x70, 0x69, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x09, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x35, 0x2e, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x6c, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x53, 0x79, 0x6e, - 0x63, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x53, 0x65, 0x6e, 0x74, 0x2e, 0x55, 0x6e, + 0x63, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x53, 0x65, 0x6e, 0x74, 0x2e, 0x53, 0x74, + 0x6f, 0x72, 0x79, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x65, 0x63, 0x69, 0x70, 0x69, + 0x65, 0x6e, 0x74, 0x52, 0x16, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, + 0x65, 0x52, 0x65, 0x63, 0x69, 0x70, 0x69, 0x65, 0x6e, 0x74, 0x73, 0x12, 0x3c, 0x0a, 0x0b, 0x65, + 0x64, 0x69, 0x74, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x1a, 0x2e, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x6c, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, + 0x2e, 0x45, 0x64, 0x69, 0x74, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x0b, 0x65, 0x64, + 0x69, 0x74, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x1a, 0xb8, 0x01, 0x0a, 0x1a, 0x55, 0x6e, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x64, 0x44, 0x65, 0x6c, 0x69, 0x76, 0x65, - 0x72, 0x79, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x12, 0x75, 0x6e, 0x69, 0x64, 0x65, 0x6e, - 0x74, 0x69, 0x66, 0x69, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x33, 0x0a, 0x11, - 0x69, 0x73, 0x52, 0x65, 0x63, 0x69, 0x70, 0x69, 0x65, 0x6e, 0x74, 0x55, 0x70, 0x64, 0x61, 0x74, - 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x3a, 0x05, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x52, 0x11, - 0x69, 0x73, 0x52, 0x65, 0x63, 0x69, 0x70, 0x69, 0x65, 0x6e, 0x74, 0x55, 0x70, 0x64, 0x61, 0x74, - 0x65, 0x12, 0x3f, 0x0a, 0x0c, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, - 0x65, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x6c, - 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x53, 0x74, 0x6f, 0x72, 0x79, 0x4d, 0x65, 0x73, - 0x73, 0x61, 0x67, 0x65, 0x52, 0x0c, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x4d, 0x65, 0x73, 0x73, 0x61, - 0x67, 0x65, 0x12, 0x6d, 0x0a, 0x16, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x4d, 0x65, 0x73, 0x73, 0x61, - 0x67, 0x65, 0x52, 0x65, 0x63, 0x69, 0x70, 0x69, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x09, 0x20, 0x03, - 0x28, 0x0b, 0x32, 0x35, 0x2e, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x6c, 0x73, 0x65, 0x72, 0x76, 0x69, - 0x63, 0x65, 0x2e, 0x53, 0x79, 0x6e, 0x63, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x53, - 0x65, 0x6e, 0x74, 0x2e, 0x53, 0x74, 0x6f, 0x72, 0x79, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, - 0x52, 0x65, 0x63, 0x69, 0x70, 0x69, 0x65, 0x6e, 0x74, 0x52, 0x16, 0x73, 0x74, 0x6f, 0x72, 0x79, - 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x65, 0x63, 0x69, 0x70, 0x69, 0x65, 0x6e, 0x74, - 0x73, 0x12, 0x3c, 0x0a, 0x0b, 0x65, 0x64, 0x69, 0x74, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, - 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x6c, 0x73, - 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x45, 0x64, 0x69, 0x74, 0x4d, 0x65, 0x73, 0x73, 0x61, - 0x67, 0x65, 0x52, 0x0b, 0x65, 0x64, 0x69, 0x74, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x1a, - 0xb8, 0x01, 0x0a, 0x1a, 0x55, 0x6e, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x64, - 0x44, 0x65, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x79, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x32, + 0x72, 0x79, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x32, 0x0a, 0x14, 0x64, 0x65, 0x73, 0x74, + 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x49, 0x64, + 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x14, 0x64, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x49, 0x64, 0x12, 0x22, 0x0a, 0x0c, + 0x75, 0x6e, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x64, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x08, 0x52, 0x0c, 0x75, 0x6e, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x64, + 0x12, 0x36, 0x0a, 0x16, 0x64, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, + 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x4b, 0x65, 0x79, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0c, + 0x52, 0x16, 0x64, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x65, + 0x6e, 0x74, 0x69, 0x74, 0x79, 0x4b, 0x65, 0x79, 0x4a, 0x04, 0x08, 0x01, 0x10, 0x02, 0x4a, 0x04, + 0x08, 0x04, 0x10, 0x05, 0x1a, 0xa9, 0x01, 0x0a, 0x15, 0x53, 0x74, 0x6f, 0x72, 0x79, 0x4d, 0x65, + 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x65, 0x63, 0x69, 0x70, 0x69, 0x65, 0x6e, 0x74, 0x12, 0x32, 0x0a, 0x14, 0x64, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x65, 0x72, - 0x76, 0x69, 0x63, 0x65, 0x49, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x14, 0x64, 0x65, + 0x76, 0x69, 0x63, 0x65, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x14, 0x64, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, - 0x49, 0x64, 0x12, 0x22, 0x0a, 0x0c, 0x75, 0x6e, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, - 0x65, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0c, 0x75, 0x6e, 0x69, 0x64, 0x65, 0x6e, - 0x74, 0x69, 0x66, 0x69, 0x65, 0x64, 0x12, 0x36, 0x0a, 0x16, 0x64, 0x65, 0x73, 0x74, 0x69, 0x6e, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x4b, 0x65, 0x79, - 0x18, 0x05, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x16, 0x64, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x4b, 0x65, 0x79, 0x4a, 0x04, - 0x08, 0x01, 0x10, 0x02, 0x4a, 0x04, 0x08, 0x04, 0x10, 0x05, 0x1a, 0xa9, 0x01, 0x0a, 0x15, 0x53, - 0x74, 0x6f, 0x72, 0x79, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x65, 0x63, 0x69, 0x70, - 0x69, 0x65, 0x6e, 0x74, 0x12, 0x32, 0x0a, 0x14, 0x64, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x14, 0x64, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, - 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x49, 0x64, 0x12, 0x30, 0x0a, 0x13, 0x64, 0x69, 0x73, 0x74, - 0x72, 0x69, 0x62, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x4c, 0x69, 0x73, 0x74, 0x49, 0x64, 0x73, 0x18, - 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x13, 0x64, 0x69, 0x73, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, - 0x69, 0x6f, 0x6e, 0x4c, 0x69, 0x73, 0x74, 0x49, 0x64, 0x73, 0x12, 0x2a, 0x0a, 0x10, 0x69, 0x73, - 0x41, 0x6c, 0x6c, 0x6f, 0x77, 0x65, 0x64, 0x54, 0x6f, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x18, 0x03, - 0x20, 0x01, 0x28, 0x08, 0x52, 0x10, 0x69, 0x73, 0x41, 0x6c, 0x6c, 0x6f, 0x77, 0x65, 0x64, 0x54, - 0x6f, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x4a, 0x04, 0x08, 0x0b, 0x10, 0x0c, 0x1a, 0x63, 0x0a, 0x08, - 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x63, 0x74, 0x73, 0x12, 0x34, 0x0a, 0x04, 0x62, 0x6c, 0x6f, 0x62, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x6c, 0x73, - 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x41, 0x74, 0x74, 0x61, 0x63, 0x68, 0x6d, 0x65, 0x6e, - 0x74, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x52, 0x04, 0x62, 0x6c, 0x6f, 0x62, 0x12, 0x21, - 0x0a, 0x08, 0x63, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, - 0x3a, 0x05, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x52, 0x08, 0x63, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, - 0x65, 0x1a, 0x53, 0x0a, 0x07, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x65, 0x64, 0x12, 0x18, 0x0a, 0x07, - 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x07, 0x6e, - 0x75, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x61, 0x63, 0x69, 0x73, 0x18, 0x03, - 0x20, 0x03, 0x28, 0x09, 0x52, 0x04, 0x61, 0x63, 0x69, 0x73, 0x12, 0x1a, 0x0a, 0x08, 0x67, 0x72, - 0x6f, 0x75, 0x70, 0x49, 0x64, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x08, 0x67, 0x72, - 0x6f, 0x75, 0x70, 0x49, 0x64, 0x73, 0x1a, 0xa5, 0x01, 0x0a, 0x07, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x12, 0x3b, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, - 0x32, 0x27, 0x2e, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x6c, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, - 0x2e, 0x53, 0x79, 0x6e, 0x63, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x2e, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x22, - 0x5d, 0x0a, 0x04, 0x54, 0x79, 0x70, 0x65, 0x12, 0x0b, 0x0a, 0x07, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, - 0x57, 0x4e, 0x10, 0x00, 0x12, 0x0c, 0x0a, 0x08, 0x43, 0x4f, 0x4e, 0x54, 0x41, 0x43, 0x54, 0x53, - 0x10, 0x01, 0x12, 0x0b, 0x0a, 0x07, 0x42, 0x4c, 0x4f, 0x43, 0x4b, 0x45, 0x44, 0x10, 0x03, 0x12, - 0x11, 0x0a, 0x0d, 0x43, 0x4f, 0x4e, 0x46, 0x49, 0x47, 0x55, 0x52, 0x41, 0x54, 0x49, 0x4f, 0x4e, - 0x10, 0x04, 0x12, 0x08, 0x0a, 0x04, 0x4b, 0x45, 0x59, 0x53, 0x10, 0x05, 0x12, 0x10, 0x0a, 0x0c, - 0x50, 0x4e, 0x49, 0x5f, 0x49, 0x44, 0x45, 0x4e, 0x54, 0x49, 0x54, 0x59, 0x10, 0x06, 0x1a, 0x48, - 0x0a, 0x04, 0x52, 0x65, 0x61, 0x64, 0x12, 0x1c, 0x0a, 0x09, 0x73, 0x65, 0x6e, 0x64, 0x65, 0x72, - 0x41, 0x63, 0x69, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x73, 0x65, 0x6e, 0x64, 0x65, - 0x72, 0x41, 0x63, 0x69, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, - 0x70, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, - 0x6d, 0x70, 0x4a, 0x04, 0x08, 0x01, 0x10, 0x02, 0x1a, 0x4a, 0x0a, 0x06, 0x56, 0x69, 0x65, 0x77, - 0x65, 0x64, 0x12, 0x1c, 0x0a, 0x09, 0x73, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x41, 0x63, 0x69, 0x18, - 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x73, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x41, 0x63, 0x69, - 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x04, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x4a, 0x04, - 0x08, 0x01, 0x10, 0x02, 0x1a, 0x83, 0x02, 0x0a, 0x0d, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, - 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x22, 0x0a, 0x0c, 0x72, 0x65, 0x61, 0x64, 0x52, 0x65, - 0x63, 0x65, 0x69, 0x70, 0x74, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0c, 0x72, 0x65, - 0x61, 0x64, 0x52, 0x65, 0x63, 0x65, 0x69, 0x70, 0x74, 0x73, 0x12, 0x46, 0x0a, 0x1e, 0x75, 0x6e, - 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x64, 0x44, 0x65, 0x6c, 0x69, 0x76, 0x65, - 0x72, 0x79, 0x49, 0x6e, 0x64, 0x69, 0x63, 0x61, 0x74, 0x6f, 0x72, 0x73, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x08, 0x52, 0x1e, 0x75, 0x6e, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x64, - 0x44, 0x65, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x79, 0x49, 0x6e, 0x64, 0x69, 0x63, 0x61, 0x74, 0x6f, - 0x72, 0x73, 0x12, 0x2a, 0x0a, 0x10, 0x74, 0x79, 0x70, 0x69, 0x6e, 0x67, 0x49, 0x6e, 0x64, 0x69, - 0x63, 0x61, 0x74, 0x6f, 0x72, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x10, 0x74, 0x79, - 0x70, 0x69, 0x6e, 0x67, 0x49, 0x6e, 0x64, 0x69, 0x63, 0x61, 0x74, 0x6f, 0x72, 0x73, 0x12, 0x30, - 0x0a, 0x13, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x69, 0x6e, 0x67, 0x56, 0x65, - 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x13, 0x70, 0x72, 0x6f, - 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x69, 0x6e, 0x67, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, - 0x12, 0x22, 0x0a, 0x0c, 0x6c, 0x69, 0x6e, 0x6b, 0x50, 0x72, 0x65, 0x76, 0x69, 0x65, 0x77, 0x73, - 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0c, 0x6c, 0x69, 0x6e, 0x6b, 0x50, 0x72, 0x65, 0x76, - 0x69, 0x65, 0x77, 0x73, 0x4a, 0x04, 0x08, 0x04, 0x10, 0x05, 0x1a, 0xb3, 0x01, 0x0a, 0x14, 0x53, - 0x74, 0x69, 0x63, 0x6b, 0x65, 0x72, 0x50, 0x61, 0x63, 0x6b, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x12, 0x16, 0x0a, 0x06, 0x70, 0x61, 0x63, 0x6b, 0x49, 0x64, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x0c, 0x52, 0x06, 0x70, 0x61, 0x63, 0x6b, 0x49, 0x64, 0x12, 0x18, 0x0a, 0x07, 0x70, - 0x61, 0x63, 0x6b, 0x4b, 0x65, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x70, 0x61, - 0x63, 0x6b, 0x4b, 0x65, 0x79, 0x12, 0x48, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x03, 0x20, - 0x01, 0x28, 0x0e, 0x32, 0x34, 0x2e, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x6c, 0x73, 0x65, 0x72, 0x76, - 0x69, 0x63, 0x65, 0x2e, 0x53, 0x79, 0x6e, 0x63, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, - 0x53, 0x74, 0x69, 0x63, 0x6b, 0x65, 0x72, 0x50, 0x61, 0x63, 0x6b, 0x4f, 0x70, 0x65, 0x72, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x22, - 0x1f, 0x0a, 0x04, 0x54, 0x79, 0x70, 0x65, 0x12, 0x0b, 0x0a, 0x07, 0x49, 0x4e, 0x53, 0x54, 0x41, - 0x4c, 0x4c, 0x10, 0x00, 0x12, 0x0a, 0x0a, 0x06, 0x52, 0x45, 0x4d, 0x4f, 0x56, 0x45, 0x10, 0x01, - 0x1a, 0x50, 0x0a, 0x0c, 0x56, 0x69, 0x65, 0x77, 0x4f, 0x6e, 0x63, 0x65, 0x4f, 0x70, 0x65, 0x6e, + 0x49, 0x64, 0x12, 0x30, 0x0a, 0x13, 0x64, 0x69, 0x73, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x69, + 0x6f, 0x6e, 0x4c, 0x69, 0x73, 0x74, 0x49, 0x64, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, + 0x13, 0x64, 0x69, 0x73, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x4c, 0x69, 0x73, + 0x74, 0x49, 0x64, 0x73, 0x12, 0x2a, 0x0a, 0x10, 0x69, 0x73, 0x41, 0x6c, 0x6c, 0x6f, 0x77, 0x65, + 0x64, 0x54, 0x6f, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x10, + 0x69, 0x73, 0x41, 0x6c, 0x6c, 0x6f, 0x77, 0x65, 0x64, 0x54, 0x6f, 0x52, 0x65, 0x70, 0x6c, 0x79, + 0x4a, 0x04, 0x08, 0x0b, 0x10, 0x0c, 0x1a, 0x63, 0x0a, 0x08, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x63, + 0x74, 0x73, 0x12, 0x34, 0x0a, 0x04, 0x62, 0x6c, 0x6f, 0x62, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x20, 0x2e, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x6c, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, + 0x2e, 0x41, 0x74, 0x74, 0x61, 0x63, 0x68, 0x6d, 0x65, 0x6e, 0x74, 0x50, 0x6f, 0x69, 0x6e, 0x74, + 0x65, 0x72, 0x52, 0x04, 0x62, 0x6c, 0x6f, 0x62, 0x12, 0x21, 0x0a, 0x08, 0x63, 0x6f, 0x6d, 0x70, + 0x6c, 0x65, 0x74, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x3a, 0x05, 0x66, 0x61, 0x6c, 0x73, + 0x65, 0x52, 0x08, 0x63, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x1a, 0x53, 0x0a, 0x07, 0x42, + 0x6c, 0x6f, 0x63, 0x6b, 0x65, 0x64, 0x12, 0x18, 0x0a, 0x07, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, + 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x07, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x73, + 0x12, 0x12, 0x0a, 0x04, 0x61, 0x63, 0x69, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x04, + 0x61, 0x63, 0x69, 0x73, 0x12, 0x1a, 0x0a, 0x08, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x49, 0x64, 0x73, + 0x18, 0x02, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x08, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x49, 0x64, 0x73, + 0x1a, 0xa5, 0x01, 0x0a, 0x07, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x3b, 0x0a, 0x04, + 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x27, 0x2e, 0x73, 0x69, 0x67, + 0x6e, 0x61, 0x6c, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x53, 0x79, 0x6e, 0x63, 0x4d, + 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x54, + 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x22, 0x5d, 0x0a, 0x04, 0x54, 0x79, 0x70, + 0x65, 0x12, 0x0b, 0x0a, 0x07, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x00, 0x12, 0x0c, + 0x0a, 0x08, 0x43, 0x4f, 0x4e, 0x54, 0x41, 0x43, 0x54, 0x53, 0x10, 0x01, 0x12, 0x0b, 0x0a, 0x07, + 0x42, 0x4c, 0x4f, 0x43, 0x4b, 0x45, 0x44, 0x10, 0x03, 0x12, 0x11, 0x0a, 0x0d, 0x43, 0x4f, 0x4e, + 0x46, 0x49, 0x47, 0x55, 0x52, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x10, 0x04, 0x12, 0x08, 0x0a, 0x04, + 0x4b, 0x45, 0x59, 0x53, 0x10, 0x05, 0x12, 0x10, 0x0a, 0x0c, 0x50, 0x4e, 0x49, 0x5f, 0x49, 0x44, + 0x45, 0x4e, 0x54, 0x49, 0x54, 0x59, 0x10, 0x06, 0x1a, 0x48, 0x0a, 0x04, 0x52, 0x65, 0x61, 0x64, 0x12, 0x1c, 0x0a, 0x09, 0x73, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x41, 0x63, 0x69, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x73, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x41, 0x63, 0x69, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x4a, 0x04, 0x08, 0x01, - 0x10, 0x02, 0x1a, 0xa5, 0x01, 0x0a, 0x0b, 0x46, 0x65, 0x74, 0x63, 0x68, 0x4c, 0x61, 0x74, 0x65, - 0x73, 0x74, 0x12, 0x3f, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, - 0x32, 0x2b, 0x2e, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x6c, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, - 0x2e, 0x53, 0x79, 0x6e, 0x63, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x46, 0x65, 0x74, - 0x63, 0x68, 0x4c, 0x61, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, - 0x79, 0x70, 0x65, 0x22, 0x55, 0x0a, 0x04, 0x54, 0x79, 0x70, 0x65, 0x12, 0x0b, 0x0a, 0x07, 0x55, - 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x00, 0x12, 0x11, 0x0a, 0x0d, 0x4c, 0x4f, 0x43, 0x41, - 0x4c, 0x5f, 0x50, 0x52, 0x4f, 0x46, 0x49, 0x4c, 0x45, 0x10, 0x01, 0x12, 0x14, 0x0a, 0x10, 0x53, - 0x54, 0x4f, 0x52, 0x41, 0x47, 0x45, 0x5f, 0x4d, 0x41, 0x4e, 0x49, 0x46, 0x45, 0x53, 0x54, 0x10, - 0x02, 0x12, 0x17, 0x0a, 0x13, 0x53, 0x55, 0x42, 0x53, 0x43, 0x52, 0x49, 0x50, 0x54, 0x49, 0x4f, - 0x4e, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x10, 0x03, 0x1a, 0x46, 0x0a, 0x04, 0x4b, 0x65, - 0x79, 0x73, 0x12, 0x26, 0x0a, 0x0e, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x53, 0x65, 0x72, - 0x76, 0x69, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0e, 0x73, 0x74, 0x6f, 0x72, - 0x61, 0x67, 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x6d, 0x61, - 0x73, 0x74, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x6d, 0x61, 0x73, 0x74, - 0x65, 0x72, 0x1a, 0x8e, 0x02, 0x0a, 0x16, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1c, 0x0a, - 0x09, 0x74, 0x68, 0x72, 0x65, 0x61, 0x64, 0x41, 0x63, 0x69, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x09, 0x74, 0x68, 0x72, 0x65, 0x61, 0x64, 0x41, 0x63, 0x69, 0x12, 0x18, 0x0a, 0x07, 0x67, - 0x72, 0x6f, 0x75, 0x70, 0x49, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x67, 0x72, - 0x6f, 0x75, 0x70, 0x49, 0x64, 0x12, 0x4a, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x04, 0x20, - 0x01, 0x28, 0x0e, 0x32, 0x36, 0x2e, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x6c, 0x73, 0x65, 0x72, 0x76, - 0x69, 0x63, 0x65, 0x2e, 0x53, 0x79, 0x6e, 0x63, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, - 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, - 0x65, 0x22, 0x6a, 0x0a, 0x04, 0x54, 0x79, 0x70, 0x65, 0x12, 0x0b, 0x0a, 0x07, 0x55, 0x4e, 0x4b, - 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x00, 0x12, 0x0a, 0x0a, 0x06, 0x41, 0x43, 0x43, 0x45, 0x50, 0x54, - 0x10, 0x01, 0x12, 0x0a, 0x0a, 0x06, 0x44, 0x45, 0x4c, 0x45, 0x54, 0x45, 0x10, 0x02, 0x12, 0x09, - 0x0a, 0x05, 0x42, 0x4c, 0x4f, 0x43, 0x4b, 0x10, 0x03, 0x12, 0x14, 0x0a, 0x10, 0x42, 0x4c, 0x4f, - 0x43, 0x4b, 0x5f, 0x41, 0x4e, 0x44, 0x5f, 0x44, 0x45, 0x4c, 0x45, 0x54, 0x45, 0x10, 0x04, 0x12, - 0x08, 0x0a, 0x04, 0x53, 0x50, 0x41, 0x4d, 0x10, 0x05, 0x12, 0x12, 0x0a, 0x0e, 0x42, 0x4c, 0x4f, - 0x43, 0x4b, 0x5f, 0x41, 0x4e, 0x44, 0x5f, 0x53, 0x50, 0x41, 0x4d, 0x10, 0x06, 0x4a, 0x04, 0x08, - 0x01, 0x10, 0x02, 0x1a, 0x8e, 0x04, 0x0a, 0x0f, 0x4f, 0x75, 0x74, 0x67, 0x6f, 0x69, 0x6e, 0x67, - 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x2e, 0x0a, 0x12, 0x72, 0x65, 0x63, 0x69, 0x70, - 0x69, 0x65, 0x6e, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x49, 0x64, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x12, 0x72, 0x65, 0x63, 0x69, 0x70, 0x69, 0x65, 0x6e, 0x74, 0x53, 0x65, - 0x72, 0x76, 0x69, 0x63, 0x65, 0x49, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x6f, 0x74, 0x65, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x6f, 0x74, 0x65, 0x12, 0x57, 0x0a, 0x0a, 0x6d, - 0x6f, 0x62, 0x69, 0x6c, 0x65, 0x43, 0x6f, 0x69, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x35, 0x2e, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x6c, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, - 0x53, 0x79, 0x6e, 0x63, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x4f, 0x75, 0x74, 0x67, - 0x6f, 0x69, 0x6e, 0x67, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x4d, 0x6f, 0x62, 0x69, - 0x6c, 0x65, 0x43, 0x6f, 0x69, 0x6e, 0x48, 0x00, 0x52, 0x0a, 0x6d, 0x6f, 0x62, 0x69, 0x6c, 0x65, - 0x43, 0x6f, 0x69, 0x6e, 0x1a, 0xcc, 0x02, 0x0a, 0x0a, 0x4d, 0x6f, 0x62, 0x69, 0x6c, 0x65, 0x43, - 0x6f, 0x69, 0x6e, 0x12, 0x2a, 0x0a, 0x10, 0x72, 0x65, 0x63, 0x69, 0x70, 0x69, 0x65, 0x6e, 0x74, - 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x10, 0x72, - 0x65, 0x63, 0x69, 0x70, 0x69, 0x65, 0x6e, 0x74, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, - 0x24, 0x0a, 0x0d, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x50, 0x69, 0x63, 0x6f, 0x4d, 0x6f, 0x62, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0d, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x50, 0x69, - 0x63, 0x6f, 0x4d, 0x6f, 0x62, 0x12, 0x1e, 0x0a, 0x0a, 0x66, 0x65, 0x65, 0x50, 0x69, 0x63, 0x6f, - 0x4d, 0x6f, 0x62, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0a, 0x66, 0x65, 0x65, 0x50, 0x69, - 0x63, 0x6f, 0x4d, 0x6f, 0x62, 0x12, 0x18, 0x0a, 0x07, 0x72, 0x65, 0x63, 0x65, 0x69, 0x70, 0x74, - 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x72, 0x65, 0x63, 0x65, 0x69, 0x70, 0x74, 0x12, - 0x32, 0x0a, 0x14, 0x6c, 0x65, 0x64, 0x67, 0x65, 0x72, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x54, 0x69, - 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x05, 0x20, 0x01, 0x28, 0x04, 0x52, 0x14, 0x6c, - 0x65, 0x64, 0x67, 0x65, 0x72, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, - 0x61, 0x6d, 0x70, 0x12, 0x2a, 0x0a, 0x10, 0x6c, 0x65, 0x64, 0x67, 0x65, 0x72, 0x42, 0x6c, 0x6f, - 0x63, 0x6b, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x06, 0x20, 0x01, 0x28, 0x04, 0x52, 0x10, 0x6c, - 0x65, 0x64, 0x67, 0x65, 0x72, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x12, - 0x26, 0x0a, 0x0e, 0x73, 0x70, 0x65, 0x6e, 0x74, 0x4b, 0x65, 0x79, 0x49, 0x6d, 0x61, 0x67, 0x65, - 0x73, 0x18, 0x07, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x0e, 0x73, 0x70, 0x65, 0x6e, 0x74, 0x4b, 0x65, - 0x79, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x73, 0x12, 0x2a, 0x0a, 0x10, 0x6f, 0x75, 0x74, 0x70, 0x75, - 0x74, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x73, 0x18, 0x08, 0x20, 0x03, 0x28, - 0x0c, 0x52, 0x10, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, - 0x65, 0x79, 0x73, 0x42, 0x0f, 0x0a, 0x0d, 0x70, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x44, 0x65, - 0x74, 0x61, 0x69, 0x6c, 0x1a, 0xd7, 0x01, 0x0a, 0x0f, 0x50, 0x6e, 0x69, 0x43, 0x68, 0x61, 0x6e, - 0x67, 0x65, 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x12, 0x28, 0x0a, 0x0f, 0x69, 0x64, 0x65, 0x6e, - 0x74, 0x69, 0x74, 0x79, 0x4b, 0x65, 0x79, 0x50, 0x61, 0x69, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x0c, 0x52, 0x0f, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x4b, 0x65, 0x79, 0x50, 0x61, - 0x69, 0x72, 0x12, 0x22, 0x0a, 0x0c, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x50, 0x72, 0x65, 0x4b, - 0x65, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0c, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x64, - 0x50, 0x72, 0x65, 0x4b, 0x65, 0x79, 0x12, 0x34, 0x0a, 0x15, 0x6c, 0x61, 0x73, 0x74, 0x52, 0x65, - 0x73, 0x6f, 0x72, 0x74, 0x4b, 0x79, 0x62, 0x65, 0x72, 0x50, 0x72, 0x65, 0x4b, 0x65, 0x79, 0x18, - 0x05, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x15, 0x6c, 0x61, 0x73, 0x74, 0x52, 0x65, 0x73, 0x6f, 0x72, - 0x74, 0x4b, 0x79, 0x62, 0x65, 0x72, 0x50, 0x72, 0x65, 0x4b, 0x65, 0x79, 0x12, 0x26, 0x0a, 0x0e, - 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x18, 0x03, - 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0e, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x18, 0x0a, 0x07, 0x6e, 0x65, 0x77, 0x45, 0x31, 0x36, 0x34, 0x18, - 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6e, 0x65, 0x77, 0x45, 0x31, 0x36, 0x34, 0x1a, 0x94, - 0x04, 0x0a, 0x09, 0x43, 0x61, 0x6c, 0x6c, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x26, 0x0a, 0x0e, - 0x63, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0e, 0x63, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, - 0x52, 0x02, 0x69, 0x64, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, - 0x70, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, - 0x6d, 0x70, 0x12, 0x3d, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0e, - 0x32, 0x29, 0x2e, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x6c, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, - 0x2e, 0x53, 0x79, 0x6e, 0x63, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x43, 0x61, 0x6c, - 0x6c, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x2e, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, - 0x65, 0x12, 0x4c, 0x0a, 0x09, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x05, - 0x20, 0x01, 0x28, 0x0e, 0x32, 0x2e, 0x2e, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x6c, 0x73, 0x65, 0x72, - 0x76, 0x69, 0x63, 0x65, 0x2e, 0x53, 0x79, 0x6e, 0x63, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, - 0x2e, 0x43, 0x61, 0x6c, 0x6c, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x2e, 0x44, 0x69, 0x72, 0x65, 0x63, - 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x09, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, - 0x40, 0x0a, 0x05, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x2a, + 0x10, 0x02, 0x1a, 0x4a, 0x0a, 0x06, 0x56, 0x69, 0x65, 0x77, 0x65, 0x64, 0x12, 0x1c, 0x0a, 0x09, + 0x73, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x41, 0x63, 0x69, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x09, 0x73, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x41, 0x63, 0x69, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x69, + 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x09, 0x74, + 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x4a, 0x04, 0x08, 0x01, 0x10, 0x02, 0x1a, 0x83, + 0x02, 0x0a, 0x0d, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x12, 0x22, 0x0a, 0x0c, 0x72, 0x65, 0x61, 0x64, 0x52, 0x65, 0x63, 0x65, 0x69, 0x70, 0x74, 0x73, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0c, 0x72, 0x65, 0x61, 0x64, 0x52, 0x65, 0x63, 0x65, + 0x69, 0x70, 0x74, 0x73, 0x12, 0x46, 0x0a, 0x1e, 0x75, 0x6e, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, + 0x66, 0x69, 0x65, 0x64, 0x44, 0x65, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x79, 0x49, 0x6e, 0x64, 0x69, + 0x63, 0x61, 0x74, 0x6f, 0x72, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x1e, 0x75, 0x6e, + 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x64, 0x44, 0x65, 0x6c, 0x69, 0x76, 0x65, + 0x72, 0x79, 0x49, 0x6e, 0x64, 0x69, 0x63, 0x61, 0x74, 0x6f, 0x72, 0x73, 0x12, 0x2a, 0x0a, 0x10, + 0x74, 0x79, 0x70, 0x69, 0x6e, 0x67, 0x49, 0x6e, 0x64, 0x69, 0x63, 0x61, 0x74, 0x6f, 0x72, 0x73, + 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x10, 0x74, 0x79, 0x70, 0x69, 0x6e, 0x67, 0x49, 0x6e, + 0x64, 0x69, 0x63, 0x61, 0x74, 0x6f, 0x72, 0x73, 0x12, 0x30, 0x0a, 0x13, 0x70, 0x72, 0x6f, 0x76, + 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x69, 0x6e, 0x67, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, + 0x05, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x13, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, + 0x69, 0x6e, 0x67, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x22, 0x0a, 0x0c, 0x6c, 0x69, + 0x6e, 0x6b, 0x50, 0x72, 0x65, 0x76, 0x69, 0x65, 0x77, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, + 0x52, 0x0c, 0x6c, 0x69, 0x6e, 0x6b, 0x50, 0x72, 0x65, 0x76, 0x69, 0x65, 0x77, 0x73, 0x4a, 0x04, + 0x08, 0x04, 0x10, 0x05, 0x1a, 0xb3, 0x01, 0x0a, 0x14, 0x53, 0x74, 0x69, 0x63, 0x6b, 0x65, 0x72, + 0x50, 0x61, 0x63, 0x6b, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x16, 0x0a, + 0x06, 0x70, 0x61, 0x63, 0x6b, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x70, + 0x61, 0x63, 0x6b, 0x49, 0x64, 0x12, 0x18, 0x0a, 0x07, 0x70, 0x61, 0x63, 0x6b, 0x4b, 0x65, 0x79, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x70, 0x61, 0x63, 0x6b, 0x4b, 0x65, 0x79, 0x12, + 0x48, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x34, 0x2e, + 0x73, 0x69, 0x67, 0x6e, 0x61, 0x6c, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x53, 0x79, + 0x6e, 0x63, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x53, 0x74, 0x69, 0x63, 0x6b, 0x65, + 0x72, 0x50, 0x61, 0x63, 0x6b, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x54, + 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x22, 0x1f, 0x0a, 0x04, 0x54, 0x79, 0x70, + 0x65, 0x12, 0x0b, 0x0a, 0x07, 0x49, 0x4e, 0x53, 0x54, 0x41, 0x4c, 0x4c, 0x10, 0x00, 0x12, 0x0a, + 0x0a, 0x06, 0x52, 0x45, 0x4d, 0x4f, 0x56, 0x45, 0x10, 0x01, 0x1a, 0x50, 0x0a, 0x0c, 0x56, 0x69, + 0x65, 0x77, 0x4f, 0x6e, 0x63, 0x65, 0x4f, 0x70, 0x65, 0x6e, 0x12, 0x1c, 0x0a, 0x09, 0x73, 0x65, + 0x6e, 0x64, 0x65, 0x72, 0x41, 0x63, 0x69, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x73, + 0x65, 0x6e, 0x64, 0x65, 0x72, 0x41, 0x63, 0x69, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, + 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x09, 0x74, 0x69, 0x6d, + 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x4a, 0x04, 0x08, 0x01, 0x10, 0x02, 0x1a, 0xa5, 0x01, 0x0a, + 0x0b, 0x46, 0x65, 0x74, 0x63, 0x68, 0x4c, 0x61, 0x74, 0x65, 0x73, 0x74, 0x12, 0x3f, 0x0a, 0x04, + 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x2b, 0x2e, 0x73, 0x69, 0x67, + 0x6e, 0x61, 0x6c, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x53, 0x79, 0x6e, 0x63, 0x4d, + 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x46, 0x65, 0x74, 0x63, 0x68, 0x4c, 0x61, 0x74, 0x65, + 0x73, 0x74, 0x2e, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x22, 0x55, 0x0a, + 0x04, 0x54, 0x79, 0x70, 0x65, 0x12, 0x0b, 0x0a, 0x07, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, + 0x10, 0x00, 0x12, 0x11, 0x0a, 0x0d, 0x4c, 0x4f, 0x43, 0x41, 0x4c, 0x5f, 0x50, 0x52, 0x4f, 0x46, + 0x49, 0x4c, 0x45, 0x10, 0x01, 0x12, 0x14, 0x0a, 0x10, 0x53, 0x54, 0x4f, 0x52, 0x41, 0x47, 0x45, + 0x5f, 0x4d, 0x41, 0x4e, 0x49, 0x46, 0x45, 0x53, 0x54, 0x10, 0x02, 0x12, 0x17, 0x0a, 0x13, 0x53, + 0x55, 0x42, 0x53, 0x43, 0x52, 0x49, 0x50, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x53, 0x54, 0x41, 0x54, + 0x55, 0x53, 0x10, 0x03, 0x1a, 0x46, 0x0a, 0x04, 0x4b, 0x65, 0x79, 0x73, 0x12, 0x26, 0x0a, 0x0e, + 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0e, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x53, 0x65, 0x72, + 0x76, 0x69, 0x63, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x6d, 0x61, 0x73, 0x74, 0x65, 0x72, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x6d, 0x61, 0x73, 0x74, 0x65, 0x72, 0x1a, 0x8e, 0x02, 0x0a, + 0x16, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x68, 0x72, 0x65, 0x61, + 0x64, 0x41, 0x63, 0x69, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x74, 0x68, 0x72, 0x65, + 0x61, 0x64, 0x41, 0x63, 0x69, 0x12, 0x18, 0x0a, 0x07, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x49, 0x64, + 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x49, 0x64, 0x12, + 0x4a, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x36, 0x2e, + 0x73, 0x69, 0x67, 0x6e, 0x61, 0x6c, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x53, 0x79, + 0x6e, 0x63, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, + 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x2e, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x22, 0x6a, 0x0a, 0x04, 0x54, + 0x79, 0x70, 0x65, 0x12, 0x0b, 0x0a, 0x07, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x00, + 0x12, 0x0a, 0x0a, 0x06, 0x41, 0x43, 0x43, 0x45, 0x50, 0x54, 0x10, 0x01, 0x12, 0x0a, 0x0a, 0x06, + 0x44, 0x45, 0x4c, 0x45, 0x54, 0x45, 0x10, 0x02, 0x12, 0x09, 0x0a, 0x05, 0x42, 0x4c, 0x4f, 0x43, + 0x4b, 0x10, 0x03, 0x12, 0x14, 0x0a, 0x10, 0x42, 0x4c, 0x4f, 0x43, 0x4b, 0x5f, 0x41, 0x4e, 0x44, + 0x5f, 0x44, 0x45, 0x4c, 0x45, 0x54, 0x45, 0x10, 0x04, 0x12, 0x08, 0x0a, 0x04, 0x53, 0x50, 0x41, + 0x4d, 0x10, 0x05, 0x12, 0x12, 0x0a, 0x0e, 0x42, 0x4c, 0x4f, 0x43, 0x4b, 0x5f, 0x41, 0x4e, 0x44, + 0x5f, 0x53, 0x50, 0x41, 0x4d, 0x10, 0x06, 0x4a, 0x04, 0x08, 0x01, 0x10, 0x02, 0x1a, 0x8e, 0x04, + 0x0a, 0x0f, 0x4f, 0x75, 0x74, 0x67, 0x6f, 0x69, 0x6e, 0x67, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, + 0x74, 0x12, 0x2e, 0x0a, 0x12, 0x72, 0x65, 0x63, 0x69, 0x70, 0x69, 0x65, 0x6e, 0x74, 0x53, 0x65, + 0x72, 0x76, 0x69, 0x63, 0x65, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x12, 0x72, + 0x65, 0x63, 0x69, 0x70, 0x69, 0x65, 0x6e, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x49, + 0x64, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x6f, 0x74, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x04, 0x6e, 0x6f, 0x74, 0x65, 0x12, 0x57, 0x0a, 0x0a, 0x6d, 0x6f, 0x62, 0x69, 0x6c, 0x65, 0x43, + 0x6f, 0x69, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x35, 0x2e, 0x73, 0x69, 0x67, 0x6e, + 0x61, 0x6c, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x53, 0x79, 0x6e, 0x63, 0x4d, 0x65, + 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x4f, 0x75, 0x74, 0x67, 0x6f, 0x69, 0x6e, 0x67, 0x50, 0x61, + 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x4d, 0x6f, 0x62, 0x69, 0x6c, 0x65, 0x43, 0x6f, 0x69, 0x6e, + 0x48, 0x00, 0x52, 0x0a, 0x6d, 0x6f, 0x62, 0x69, 0x6c, 0x65, 0x43, 0x6f, 0x69, 0x6e, 0x1a, 0xcc, + 0x02, 0x0a, 0x0a, 0x4d, 0x6f, 0x62, 0x69, 0x6c, 0x65, 0x43, 0x6f, 0x69, 0x6e, 0x12, 0x2a, 0x0a, + 0x10, 0x72, 0x65, 0x63, 0x69, 0x70, 0x69, 0x65, 0x6e, 0x74, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, + 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x10, 0x72, 0x65, 0x63, 0x69, 0x70, 0x69, 0x65, + 0x6e, 0x74, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x24, 0x0a, 0x0d, 0x61, 0x6d, 0x6f, + 0x75, 0x6e, 0x74, 0x50, 0x69, 0x63, 0x6f, 0x4d, 0x6f, 0x62, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, + 0x52, 0x0d, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x50, 0x69, 0x63, 0x6f, 0x4d, 0x6f, 0x62, 0x12, + 0x1e, 0x0a, 0x0a, 0x66, 0x65, 0x65, 0x50, 0x69, 0x63, 0x6f, 0x4d, 0x6f, 0x62, 0x18, 0x03, 0x20, + 0x01, 0x28, 0x04, 0x52, 0x0a, 0x66, 0x65, 0x65, 0x50, 0x69, 0x63, 0x6f, 0x4d, 0x6f, 0x62, 0x12, + 0x18, 0x0a, 0x07, 0x72, 0x65, 0x63, 0x65, 0x69, 0x70, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, + 0x52, 0x07, 0x72, 0x65, 0x63, 0x65, 0x69, 0x70, 0x74, 0x12, 0x32, 0x0a, 0x14, 0x6c, 0x65, 0x64, + 0x67, 0x65, 0x72, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, + 0x70, 0x18, 0x05, 0x20, 0x01, 0x28, 0x04, 0x52, 0x14, 0x6c, 0x65, 0x64, 0x67, 0x65, 0x72, 0x42, + 0x6c, 0x6f, 0x63, 0x6b, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x2a, 0x0a, + 0x10, 0x6c, 0x65, 0x64, 0x67, 0x65, 0x72, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x49, 0x6e, 0x64, 0x65, + 0x78, 0x18, 0x06, 0x20, 0x01, 0x28, 0x04, 0x52, 0x10, 0x6c, 0x65, 0x64, 0x67, 0x65, 0x72, 0x42, + 0x6c, 0x6f, 0x63, 0x6b, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x12, 0x26, 0x0a, 0x0e, 0x73, 0x70, 0x65, + 0x6e, 0x74, 0x4b, 0x65, 0x79, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x73, 0x18, 0x07, 0x20, 0x03, 0x28, + 0x0c, 0x52, 0x0e, 0x73, 0x70, 0x65, 0x6e, 0x74, 0x4b, 0x65, 0x79, 0x49, 0x6d, 0x61, 0x67, 0x65, + 0x73, 0x12, 0x2a, 0x0a, 0x10, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x50, 0x75, 0x62, 0x6c, 0x69, + 0x63, 0x4b, 0x65, 0x79, 0x73, 0x18, 0x08, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x10, 0x6f, 0x75, 0x74, + 0x70, 0x75, 0x74, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x73, 0x42, 0x0f, 0x0a, + 0x0d, 0x70, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x1a, 0xd7, + 0x01, 0x0a, 0x0f, 0x50, 0x6e, 0x69, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x4e, 0x75, 0x6d, 0x62, + 0x65, 0x72, 0x12, 0x28, 0x0a, 0x0f, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x4b, 0x65, + 0x79, 0x50, 0x61, 0x69, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0f, 0x69, 0x64, 0x65, + 0x6e, 0x74, 0x69, 0x74, 0x79, 0x4b, 0x65, 0x79, 0x50, 0x61, 0x69, 0x72, 0x12, 0x22, 0x0a, 0x0c, + 0x73, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x50, 0x72, 0x65, 0x4b, 0x65, 0x79, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x0c, 0x52, 0x0c, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x50, 0x72, 0x65, 0x4b, 0x65, 0x79, + 0x12, 0x34, 0x0a, 0x15, 0x6c, 0x61, 0x73, 0x74, 0x52, 0x65, 0x73, 0x6f, 0x72, 0x74, 0x4b, 0x79, + 0x62, 0x65, 0x72, 0x50, 0x72, 0x65, 0x4b, 0x65, 0x79, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0c, 0x52, + 0x15, 0x6c, 0x61, 0x73, 0x74, 0x52, 0x65, 0x73, 0x6f, 0x72, 0x74, 0x4b, 0x79, 0x62, 0x65, 0x72, + 0x50, 0x72, 0x65, 0x4b, 0x65, 0x79, 0x12, 0x26, 0x0a, 0x0e, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, + 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0e, + 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x18, + 0x0a, 0x07, 0x6e, 0x65, 0x77, 0x45, 0x31, 0x36, 0x34, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x07, 0x6e, 0x65, 0x77, 0x45, 0x31, 0x36, 0x34, 0x1a, 0x94, 0x04, 0x0a, 0x09, 0x43, 0x61, 0x6c, + 0x6c, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x26, 0x0a, 0x0e, 0x63, 0x6f, 0x6e, 0x76, 0x65, 0x72, + 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0e, + 0x63, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x0e, + 0x0a, 0x02, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x02, 0x69, 0x64, 0x12, 0x1c, + 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x03, 0x20, 0x01, 0x28, + 0x04, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x3d, 0x0a, 0x04, + 0x74, 0x79, 0x70, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x29, 0x2e, 0x73, 0x69, 0x67, + 0x6e, 0x61, 0x6c, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x53, 0x79, 0x6e, 0x63, 0x4d, + 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x43, 0x61, 0x6c, 0x6c, 0x45, 0x76, 0x65, 0x6e, 0x74, + 0x2e, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x4c, 0x0a, 0x09, 0x64, + 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x2e, 0x2e, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x6c, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x53, 0x79, 0x6e, 0x63, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x43, 0x61, 0x6c, 0x6c, 0x45, - 0x76, 0x65, 0x6e, 0x74, 0x2e, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x52, 0x05, 0x65, 0x76, 0x65, 0x6e, - 0x74, 0x22, 0x59, 0x0a, 0x04, 0x54, 0x79, 0x70, 0x65, 0x12, 0x10, 0x0a, 0x0c, 0x55, 0x4e, 0x4b, - 0x4e, 0x4f, 0x57, 0x4e, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x10, 0x00, 0x12, 0x0e, 0x0a, 0x0a, 0x41, - 0x55, 0x44, 0x49, 0x4f, 0x5f, 0x43, 0x41, 0x4c, 0x4c, 0x10, 0x01, 0x12, 0x0e, 0x0a, 0x0a, 0x56, - 0x49, 0x44, 0x45, 0x4f, 0x5f, 0x43, 0x41, 0x4c, 0x4c, 0x10, 0x02, 0x12, 0x0e, 0x0a, 0x0a, 0x47, - 0x52, 0x4f, 0x55, 0x50, 0x5f, 0x43, 0x41, 0x4c, 0x4c, 0x10, 0x03, 0x12, 0x0f, 0x0a, 0x0b, 0x41, - 0x44, 0x5f, 0x48, 0x4f, 0x43, 0x5f, 0x43, 0x41, 0x4c, 0x4c, 0x10, 0x04, 0x22, 0x3e, 0x0a, 0x09, - 0x44, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x15, 0x0a, 0x11, 0x55, 0x4e, 0x4b, - 0x4e, 0x4f, 0x57, 0x4e, 0x5f, 0x44, 0x49, 0x52, 0x45, 0x43, 0x54, 0x49, 0x4f, 0x4e, 0x10, 0x00, - 0x12, 0x0c, 0x0a, 0x08, 0x49, 0x4e, 0x43, 0x4f, 0x4d, 0x49, 0x4e, 0x47, 0x10, 0x01, 0x12, 0x0c, - 0x0a, 0x08, 0x4f, 0x55, 0x54, 0x47, 0x4f, 0x49, 0x4e, 0x47, 0x10, 0x02, 0x22, 0x47, 0x0a, 0x05, - 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x12, 0x0a, 0x0e, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, - 0x5f, 0x41, 0x43, 0x54, 0x49, 0x4f, 0x4e, 0x10, 0x00, 0x12, 0x0c, 0x0a, 0x08, 0x41, 0x43, 0x43, - 0x45, 0x50, 0x54, 0x45, 0x44, 0x10, 0x01, 0x12, 0x10, 0x0a, 0x0c, 0x4e, 0x4f, 0x54, 0x5f, 0x41, - 0x43, 0x43, 0x45, 0x50, 0x54, 0x45, 0x44, 0x10, 0x02, 0x12, 0x0a, 0x0a, 0x06, 0x44, 0x45, 0x4c, - 0x45, 0x54, 0x45, 0x10, 0x03, 0x1a, 0xb2, 0x01, 0x0a, 0x0e, 0x43, 0x61, 0x6c, 0x6c, 0x4c, 0x69, - 0x6e, 0x6b, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x72, 0x6f, 0x6f, 0x74, - 0x4b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x72, 0x6f, 0x6f, 0x74, 0x4b, - 0x65, 0x79, 0x12, 0x22, 0x0a, 0x0c, 0x61, 0x64, 0x6d, 0x69, 0x6e, 0x50, 0x61, 0x73, 0x73, 0x4b, - 0x65, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0c, 0x61, 0x64, 0x6d, 0x69, 0x6e, 0x50, - 0x61, 0x73, 0x73, 0x4b, 0x65, 0x79, 0x12, 0x42, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x03, - 0x20, 0x01, 0x28, 0x0e, 0x32, 0x2e, 0x2e, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x6c, 0x73, 0x65, 0x72, - 0x76, 0x69, 0x63, 0x65, 0x2e, 0x53, 0x79, 0x6e, 0x63, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, - 0x2e, 0x43, 0x61, 0x6c, 0x6c, 0x4c, 0x69, 0x6e, 0x6b, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x2e, - 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x22, 0x1e, 0x0a, 0x04, 0x54, 0x79, - 0x70, 0x65, 0x12, 0x0a, 0x0a, 0x06, 0x55, 0x50, 0x44, 0x41, 0x54, 0x45, 0x10, 0x00, 0x12, 0x0a, - 0x0a, 0x06, 0x44, 0x45, 0x4c, 0x45, 0x54, 0x45, 0x10, 0x01, 0x1a, 0x95, 0x01, 0x0a, 0x0c, 0x43, - 0x61, 0x6c, 0x6c, 0x4c, 0x6f, 0x67, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x40, 0x0a, 0x04, 0x74, - 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x2c, 0x2e, 0x73, 0x69, 0x67, 0x6e, + 0x76, 0x65, 0x6e, 0x74, 0x2e, 0x44, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x09, + 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x40, 0x0a, 0x05, 0x65, 0x76, 0x65, + 0x6e, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x2a, 0x2e, 0x73, 0x69, 0x67, 0x6e, 0x61, + 0x6c, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x53, 0x79, 0x6e, 0x63, 0x4d, 0x65, 0x73, + 0x73, 0x61, 0x67, 0x65, 0x2e, 0x43, 0x61, 0x6c, 0x6c, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x2e, 0x45, + 0x76, 0x65, 0x6e, 0x74, 0x52, 0x05, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x22, 0x59, 0x0a, 0x04, 0x54, + 0x79, 0x70, 0x65, 0x12, 0x10, 0x0a, 0x0c, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x5f, 0x54, + 0x59, 0x50, 0x45, 0x10, 0x00, 0x12, 0x0e, 0x0a, 0x0a, 0x41, 0x55, 0x44, 0x49, 0x4f, 0x5f, 0x43, + 0x41, 0x4c, 0x4c, 0x10, 0x01, 0x12, 0x0e, 0x0a, 0x0a, 0x56, 0x49, 0x44, 0x45, 0x4f, 0x5f, 0x43, + 0x41, 0x4c, 0x4c, 0x10, 0x02, 0x12, 0x0e, 0x0a, 0x0a, 0x47, 0x52, 0x4f, 0x55, 0x50, 0x5f, 0x43, + 0x41, 0x4c, 0x4c, 0x10, 0x03, 0x12, 0x0f, 0x0a, 0x0b, 0x41, 0x44, 0x5f, 0x48, 0x4f, 0x43, 0x5f, + 0x43, 0x41, 0x4c, 0x4c, 0x10, 0x04, 0x22, 0x3e, 0x0a, 0x09, 0x44, 0x69, 0x72, 0x65, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x12, 0x15, 0x0a, 0x11, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x5f, 0x44, + 0x49, 0x52, 0x45, 0x43, 0x54, 0x49, 0x4f, 0x4e, 0x10, 0x00, 0x12, 0x0c, 0x0a, 0x08, 0x49, 0x4e, + 0x43, 0x4f, 0x4d, 0x49, 0x4e, 0x47, 0x10, 0x01, 0x12, 0x0c, 0x0a, 0x08, 0x4f, 0x55, 0x54, 0x47, + 0x4f, 0x49, 0x4e, 0x47, 0x10, 0x02, 0x22, 0x47, 0x0a, 0x05, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, + 0x12, 0x0a, 0x0e, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x5f, 0x41, 0x43, 0x54, 0x49, 0x4f, + 0x4e, 0x10, 0x00, 0x12, 0x0c, 0x0a, 0x08, 0x41, 0x43, 0x43, 0x45, 0x50, 0x54, 0x45, 0x44, 0x10, + 0x01, 0x12, 0x10, 0x0a, 0x0c, 0x4e, 0x4f, 0x54, 0x5f, 0x41, 0x43, 0x43, 0x45, 0x50, 0x54, 0x45, + 0x44, 0x10, 0x02, 0x12, 0x0a, 0x0a, 0x06, 0x44, 0x45, 0x4c, 0x45, 0x54, 0x45, 0x10, 0x03, 0x1a, + 0xb2, 0x01, 0x0a, 0x0e, 0x43, 0x61, 0x6c, 0x6c, 0x4c, 0x69, 0x6e, 0x6b, 0x55, 0x70, 0x64, 0x61, + 0x74, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x72, 0x6f, 0x6f, 0x74, 0x4b, 0x65, 0x79, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x0c, 0x52, 0x07, 0x72, 0x6f, 0x6f, 0x74, 0x4b, 0x65, 0x79, 0x12, 0x22, 0x0a, 0x0c, + 0x61, 0x64, 0x6d, 0x69, 0x6e, 0x50, 0x61, 0x73, 0x73, 0x4b, 0x65, 0x79, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x0c, 0x52, 0x0c, 0x61, 0x64, 0x6d, 0x69, 0x6e, 0x50, 0x61, 0x73, 0x73, 0x4b, 0x65, 0x79, + 0x12, 0x42, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x2e, + 0x2e, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x6c, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x53, + 0x79, 0x6e, 0x63, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x43, 0x61, 0x6c, 0x6c, 0x4c, + 0x69, 0x6e, 0x6b, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x2e, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, + 0x74, 0x79, 0x70, 0x65, 0x22, 0x1e, 0x0a, 0x04, 0x54, 0x79, 0x70, 0x65, 0x12, 0x0a, 0x0a, 0x06, + 0x55, 0x50, 0x44, 0x41, 0x54, 0x45, 0x10, 0x00, 0x12, 0x0a, 0x0a, 0x06, 0x44, 0x45, 0x4c, 0x45, + 0x54, 0x45, 0x10, 0x01, 0x1a, 0xf9, 0x01, 0x0a, 0x0c, 0x43, 0x61, 0x6c, 0x6c, 0x4c, 0x6f, 0x67, + 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x40, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x0e, 0x32, 0x2c, 0x2e, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x6c, 0x73, 0x65, 0x72, 0x76, + 0x69, 0x63, 0x65, 0x2e, 0x53, 0x79, 0x6e, 0x63, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, + 0x43, 0x61, 0x6c, 0x6c, 0x4c, 0x6f, 0x67, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x2e, 0x54, 0x79, 0x70, + 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, + 0x74, 0x61, 0x6d, 0x70, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, + 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x26, 0x0a, 0x0e, 0x63, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0e, 0x63, + 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x16, 0x0a, + 0x06, 0x63, 0x61, 0x6c, 0x6c, 0x49, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x04, 0x52, 0x06, 0x63, + 0x61, 0x6c, 0x6c, 0x49, 0x64, 0x22, 0x49, 0x0a, 0x04, 0x54, 0x79, 0x70, 0x65, 0x12, 0x09, 0x0a, + 0x05, 0x43, 0x4c, 0x45, 0x41, 0x52, 0x10, 0x00, 0x12, 0x12, 0x0a, 0x0e, 0x4d, 0x41, 0x52, 0x4b, + 0x45, 0x44, 0x5f, 0x41, 0x53, 0x5f, 0x52, 0x45, 0x41, 0x44, 0x10, 0x01, 0x12, 0x22, 0x0a, 0x1e, + 0x4d, 0x41, 0x52, 0x4b, 0x45, 0x44, 0x5f, 0x41, 0x53, 0x5f, 0x52, 0x45, 0x41, 0x44, 0x5f, 0x49, + 0x4e, 0x5f, 0x43, 0x4f, 0x4e, 0x56, 0x45, 0x52, 0x53, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x10, 0x02, + 0x1a, 0xd7, 0x09, 0x0a, 0x0b, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x46, 0x6f, 0x72, 0x4d, 0x65, + 0x12, 0x5d, 0x0a, 0x0e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x44, 0x65, 0x6c, 0x65, 0x74, + 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x35, 0x2e, 0x73, 0x69, 0x67, 0x6e, 0x61, + 0x6c, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x53, 0x79, 0x6e, 0x63, 0x4d, 0x65, 0x73, + 0x73, 0x61, 0x67, 0x65, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x46, 0x6f, 0x72, 0x4d, 0x65, + 0x2e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x73, 0x52, + 0x0e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x73, 0x12, + 0x6b, 0x0a, 0x13, 0x63, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x44, + 0x65, 0x6c, 0x65, 0x74, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x39, 0x2e, 0x73, + 0x69, 0x67, 0x6e, 0x61, 0x6c, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x53, 0x79, 0x6e, + 0x63, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x46, + 0x6f, 0x72, 0x4d, 0x65, 0x2e, 0x43, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x13, 0x63, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x73, 0x12, 0x86, 0x01, 0x0a, + 0x1c, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x4f, 0x6e, 0x6c, 0x79, 0x43, 0x6f, 0x6e, 0x76, 0x65, 0x72, + 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x73, 0x18, 0x03, 0x20, + 0x03, 0x28, 0x0b, 0x32, 0x42, 0x2e, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x6c, 0x73, 0x65, 0x72, 0x76, + 0x69, 0x63, 0x65, 0x2e, 0x53, 0x79, 0x6e, 0x63, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, + 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x46, 0x6f, 0x72, 0x4d, 0x65, 0x2e, 0x4c, 0x6f, 0x63, 0x61, + 0x6c, 0x4f, 0x6e, 0x6c, 0x79, 0x43, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x1c, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x4f, 0x6e, + 0x6c, 0x79, 0x43, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x44, 0x65, + 0x6c, 0x65, 0x74, 0x65, 0x73, 0x1a, 0x90, 0x01, 0x0a, 0x16, 0x43, 0x6f, 0x6e, 0x76, 0x65, 0x72, + 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, + 0x12, 0x1e, 0x0a, 0x09, 0x74, 0x68, 0x72, 0x65, 0x61, 0x64, 0x41, 0x63, 0x69, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x09, 0x74, 0x68, 0x72, 0x65, 0x61, 0x64, 0x41, 0x63, 0x69, + 0x12, 0x26, 0x0a, 0x0d, 0x74, 0x68, 0x72, 0x65, 0x61, 0x64, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x49, + 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x48, 0x00, 0x52, 0x0d, 0x74, 0x68, 0x72, 0x65, 0x61, + 0x64, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x49, 0x64, 0x12, 0x20, 0x0a, 0x0a, 0x74, 0x68, 0x72, 0x65, + 0x61, 0x64, 0x45, 0x31, 0x36, 0x34, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x0a, + 0x74, 0x68, 0x72, 0x65, 0x61, 0x64, 0x45, 0x31, 0x36, 0x34, 0x42, 0x0c, 0x0a, 0x0a, 0x69, 0x64, + 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x1a, 0x86, 0x01, 0x0a, 0x12, 0x41, 0x64, 0x64, + 0x72, 0x65, 0x73, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, + 0x1e, 0x0a, 0x09, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x41, 0x63, 0x69, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x48, 0x00, 0x52, 0x09, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x41, 0x63, 0x69, 0x12, + 0x20, 0x0a, 0x0a, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x45, 0x31, 0x36, 0x34, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x0a, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x45, 0x31, 0x36, + 0x34, 0x12, 0x24, 0x0a, 0x0d, 0x73, 0x65, 0x6e, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, + 0x6d, 0x70, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0d, 0x73, 0x65, 0x6e, 0x74, 0x54, 0x69, + 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x42, 0x08, 0x0a, 0x06, 0x61, 0x75, 0x74, 0x68, 0x6f, + 0x72, 0x1a, 0xca, 0x01, 0x0a, 0x0e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x44, 0x65, 0x6c, + 0x65, 0x74, 0x65, 0x73, 0x12, 0x61, 0x0a, 0x0c, 0x63, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x3d, 0x2e, 0x73, 0x69, 0x67, + 0x6e, 0x61, 0x6c, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x53, 0x79, 0x6e, 0x63, 0x4d, + 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x46, 0x6f, 0x72, + 0x4d, 0x65, 0x2e, 0x43, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, + 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x52, 0x0c, 0x63, 0x6f, 0x6e, 0x76, 0x65, + 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x55, 0x0a, 0x08, 0x6d, 0x65, 0x73, 0x73, 0x61, + 0x67, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x39, 0x2e, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x6c, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x53, 0x79, 0x6e, 0x63, 0x4d, 0x65, - 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x43, 0x61, 0x6c, 0x6c, 0x4c, 0x6f, 0x67, 0x45, 0x76, 0x65, - 0x6e, 0x74, 0x2e, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x1c, 0x0a, - 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, - 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x22, 0x25, 0x0a, 0x04, 0x54, - 0x79, 0x70, 0x65, 0x12, 0x09, 0x0a, 0x05, 0x43, 0x4c, 0x45, 0x41, 0x52, 0x10, 0x00, 0x12, 0x12, - 0x0a, 0x0e, 0x4d, 0x41, 0x52, 0x4b, 0x45, 0x44, 0x5f, 0x41, 0x53, 0x5f, 0x52, 0x45, 0x41, 0x44, - 0x10, 0x01, 0x4a, 0x04, 0x08, 0x03, 0x10, 0x04, 0x4a, 0x04, 0x08, 0x11, 0x10, 0x12, 0x22, 0xe3, - 0x04, 0x0a, 0x11, 0x41, 0x74, 0x74, 0x61, 0x63, 0x68, 0x6d, 0x65, 0x6e, 0x74, 0x50, 0x6f, 0x69, - 0x6e, 0x74, 0x65, 0x72, 0x12, 0x16, 0x0a, 0x05, 0x63, 0x64, 0x6e, 0x49, 0x64, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x06, 0x48, 0x00, 0x52, 0x05, 0x63, 0x64, 0x6e, 0x49, 0x64, 0x12, 0x18, 0x0a, 0x06, - 0x63, 0x64, 0x6e, 0x4b, 0x65, 0x79, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x06, - 0x63, 0x64, 0x6e, 0x4b, 0x65, 0x79, 0x12, 0x20, 0x0a, 0x0b, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, - 0x74, 0x54, 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x63, 0x6f, 0x6e, - 0x74, 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, - 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x12, 0x0a, 0x04, 0x73, 0x69, - 0x7a, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x04, 0x73, 0x69, 0x7a, 0x65, 0x12, 0x1c, - 0x0a, 0x09, 0x74, 0x68, 0x75, 0x6d, 0x62, 0x6e, 0x61, 0x69, 0x6c, 0x18, 0x05, 0x20, 0x01, 0x28, - 0x0c, 0x52, 0x09, 0x74, 0x68, 0x75, 0x6d, 0x62, 0x6e, 0x61, 0x69, 0x6c, 0x12, 0x16, 0x0a, 0x06, - 0x64, 0x69, 0x67, 0x65, 0x73, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x64, 0x69, - 0x67, 0x65, 0x73, 0x74, 0x12, 0x26, 0x0a, 0x0e, 0x69, 0x6e, 0x63, 0x72, 0x65, 0x6d, 0x65, 0x6e, - 0x74, 0x61, 0x6c, 0x4d, 0x61, 0x63, 0x18, 0x13, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0e, 0x69, 0x6e, - 0x63, 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x61, 0x6c, 0x4d, 0x61, 0x63, 0x12, 0x38, 0x0a, 0x17, - 0x69, 0x6e, 0x63, 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x61, 0x6c, 0x4d, 0x61, 0x63, 0x43, 0x68, - 0x75, 0x6e, 0x6b, 0x53, 0x69, 0x7a, 0x65, 0x18, 0x11, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x17, 0x69, - 0x6e, 0x63, 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x61, 0x6c, 0x4d, 0x61, 0x63, 0x43, 0x68, 0x75, - 0x6e, 0x6b, 0x53, 0x69, 0x7a, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x66, 0x69, 0x6c, 0x65, 0x4e, 0x61, - 0x6d, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x66, 0x69, 0x6c, 0x65, 0x4e, 0x61, - 0x6d, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x66, 0x6c, 0x61, 0x67, 0x73, 0x18, 0x08, 0x20, 0x01, 0x28, - 0x0d, 0x52, 0x05, 0x66, 0x6c, 0x61, 0x67, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x77, 0x69, 0x64, 0x74, - 0x68, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x05, 0x77, 0x69, 0x64, 0x74, 0x68, 0x12, 0x16, - 0x0a, 0x06, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x06, - 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x61, 0x70, 0x74, 0x69, 0x6f, - 0x6e, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x63, 0x61, 0x70, 0x74, 0x69, 0x6f, 0x6e, - 0x12, 0x1a, 0x0a, 0x08, 0x62, 0x6c, 0x75, 0x72, 0x48, 0x61, 0x73, 0x68, 0x18, 0x0c, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x08, 0x62, 0x6c, 0x75, 0x72, 0x48, 0x61, 0x73, 0x68, 0x12, 0x28, 0x0a, 0x0f, - 0x75, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, - 0x0d, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0f, 0x75, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x54, 0x69, 0x6d, - 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x1c, 0x0a, 0x09, 0x63, 0x64, 0x6e, 0x4e, 0x75, 0x6d, - 0x62, 0x65, 0x72, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x63, 0x64, 0x6e, 0x4e, 0x75, - 0x6d, 0x62, 0x65, 0x72, 0x22, 0x39, 0x0a, 0x05, 0x46, 0x6c, 0x61, 0x67, 0x73, 0x12, 0x11, 0x0a, - 0x0d, 0x56, 0x4f, 0x49, 0x43, 0x45, 0x5f, 0x4d, 0x45, 0x53, 0x53, 0x41, 0x47, 0x45, 0x10, 0x01, - 0x12, 0x0e, 0x0a, 0x0a, 0x42, 0x4f, 0x52, 0x44, 0x45, 0x52, 0x4c, 0x45, 0x53, 0x53, 0x10, 0x02, - 0x12, 0x07, 0x0a, 0x03, 0x47, 0x49, 0x46, 0x10, 0x04, 0x22, 0x04, 0x08, 0x03, 0x10, 0x03, 0x42, - 0x17, 0x0a, 0x15, 0x61, 0x74, 0x74, 0x61, 0x63, 0x68, 0x6d, 0x65, 0x6e, 0x74, 0x5f, 0x69, 0x64, - 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x4a, 0x04, 0x08, 0x10, 0x10, 0x11, 0x4a, 0x04, - 0x08, 0x12, 0x10, 0x13, 0x22, 0xf0, 0x02, 0x0a, 0x0c, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x43, 0x6f, - 0x6e, 0x74, 0x65, 0x78, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x0c, 0x52, 0x02, 0x69, 0x64, 0x12, 0x34, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x0e, 0x32, 0x20, 0x2e, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x6c, 0x73, 0x65, 0x72, 0x76, - 0x69, 0x63, 0x65, 0x2e, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, - 0x2e, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, - 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, - 0x20, 0x0a, 0x0b, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x45, 0x31, 0x36, 0x34, 0x18, 0x04, - 0x20, 0x03, 0x28, 0x09, 0x52, 0x0b, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x45, 0x31, 0x36, - 0x34, 0x12, 0x3c, 0x0a, 0x07, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x18, 0x06, 0x20, 0x03, - 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x6c, 0x73, 0x65, 0x72, 0x76, 0x69, - 0x63, 0x65, 0x2e, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x2e, - 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x52, 0x07, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x12, - 0x38, 0x0a, 0x06, 0x61, 0x76, 0x61, 0x74, 0x61, 0x72, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x20, 0x2e, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x6c, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, - 0x41, 0x74, 0x74, 0x61, 0x63, 0x68, 0x6d, 0x65, 0x6e, 0x74, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x65, - 0x72, 0x52, 0x06, 0x61, 0x76, 0x61, 0x74, 0x61, 0x72, 0x1a, 0x22, 0x0a, 0x06, 0x4d, 0x65, 0x6d, - 0x62, 0x65, 0x72, 0x12, 0x12, 0x0a, 0x04, 0x65, 0x31, 0x36, 0x34, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x04, 0x65, 0x31, 0x36, 0x34, 0x4a, 0x04, 0x08, 0x01, 0x10, 0x02, 0x22, 0x48, 0x0a, - 0x04, 0x54, 0x79, 0x70, 0x65, 0x12, 0x0b, 0x0a, 0x07, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, - 0x10, 0x00, 0x12, 0x0a, 0x0a, 0x06, 0x55, 0x50, 0x44, 0x41, 0x54, 0x45, 0x10, 0x01, 0x12, 0x0b, - 0x0a, 0x07, 0x44, 0x45, 0x4c, 0x49, 0x56, 0x45, 0x52, 0x10, 0x02, 0x12, 0x08, 0x0a, 0x04, 0x51, - 0x55, 0x49, 0x54, 0x10, 0x03, 0x12, 0x10, 0x0a, 0x0c, 0x52, 0x45, 0x51, 0x55, 0x45, 0x53, 0x54, - 0x5f, 0x49, 0x4e, 0x46, 0x4f, 0x10, 0x04, 0x22, 0x6c, 0x0a, 0x0e, 0x47, 0x72, 0x6f, 0x75, 0x70, - 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x56, 0x32, 0x12, 0x1c, 0x0a, 0x09, 0x6d, 0x61, 0x73, - 0x74, 0x65, 0x72, 0x4b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x6d, 0x61, - 0x73, 0x74, 0x65, 0x72, 0x4b, 0x65, 0x79, 0x12, 0x1a, 0x0a, 0x08, 0x72, 0x65, 0x76, 0x69, 0x73, - 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x08, 0x72, 0x65, 0x76, 0x69, 0x73, - 0x69, 0x6f, 0x6e, 0x12, 0x20, 0x0a, 0x0b, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x43, 0x68, 0x61, 0x6e, - 0x67, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0b, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x43, - 0x68, 0x61, 0x6e, 0x67, 0x65, 0x22, 0xb9, 0x03, 0x0a, 0x0e, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x63, - 0x74, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x12, 0x16, 0x0a, 0x06, 0x6e, 0x75, 0x6d, 0x62, - 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, - 0x12, 0x10, 0x0a, 0x03, 0x61, 0x63, 0x69, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x61, - 0x63, 0x69, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x3c, 0x0a, 0x06, 0x61, 0x76, 0x61, 0x74, 0x61, 0x72, - 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x6c, 0x73, - 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x63, 0x74, 0x44, 0x65, - 0x74, 0x61, 0x69, 0x6c, 0x73, 0x2e, 0x41, 0x76, 0x61, 0x74, 0x61, 0x72, 0x52, 0x06, 0x61, 0x76, - 0x61, 0x74, 0x61, 0x72, 0x12, 0x14, 0x0a, 0x05, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x18, 0x04, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x05, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x12, 0x33, 0x0a, 0x08, 0x76, 0x65, - 0x72, 0x69, 0x66, 0x69, 0x65, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x73, - 0x69, 0x67, 0x6e, 0x61, 0x6c, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x56, 0x65, 0x72, - 0x69, 0x66, 0x69, 0x65, 0x64, 0x52, 0x08, 0x76, 0x65, 0x72, 0x69, 0x66, 0x69, 0x65, 0x64, 0x12, - 0x1e, 0x0a, 0x0a, 0x70, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x4b, 0x65, 0x79, 0x18, 0x06, 0x20, - 0x01, 0x28, 0x0c, 0x52, 0x0a, 0x70, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x4b, 0x65, 0x79, 0x12, - 0x18, 0x0a, 0x07, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x65, 0x64, 0x18, 0x07, 0x20, 0x01, 0x28, 0x08, - 0x52, 0x07, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x65, 0x64, 0x12, 0x20, 0x0a, 0x0b, 0x65, 0x78, 0x70, - 0x69, 0x72, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x72, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0b, - 0x65, 0x78, 0x70, 0x69, 0x72, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x72, 0x12, 0x24, 0x0a, 0x0d, 0x69, - 0x6e, 0x62, 0x6f, 0x78, 0x50, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x0a, 0x20, 0x01, - 0x28, 0x0d, 0x52, 0x0d, 0x69, 0x6e, 0x62, 0x6f, 0x78, 0x50, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, - 0x6e, 0x12, 0x1a, 0x0a, 0x08, 0x61, 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, 0x64, 0x18, 0x0b, 0x20, - 0x01, 0x28, 0x08, 0x52, 0x08, 0x61, 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, 0x64, 0x1a, 0x42, 0x0a, - 0x06, 0x41, 0x76, 0x61, 0x74, 0x61, 0x72, 0x12, 0x20, 0x0a, 0x0b, 0x63, 0x6f, 0x6e, 0x74, 0x65, - 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x63, 0x6f, - 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x6c, 0x65, 0x6e, - 0x67, 0x74, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x06, 0x6c, 0x65, 0x6e, 0x67, 0x74, - 0x68, 0x22, 0xe8, 0x03, 0x0a, 0x0c, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x44, 0x65, 0x74, 0x61, 0x69, - 0x6c, 0x73, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x02, - 0x69, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, - 0x73, 0x45, 0x31, 0x36, 0x34, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0b, 0x6d, 0x65, 0x6d, - 0x62, 0x65, 0x72, 0x73, 0x45, 0x31, 0x36, 0x34, 0x12, 0x3c, 0x0a, 0x07, 0x6d, 0x65, 0x6d, 0x62, - 0x65, 0x72, 0x73, 0x18, 0x09, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x73, 0x69, 0x67, 0x6e, - 0x61, 0x6c, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x44, - 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x2e, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x52, 0x07, 0x6d, - 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x12, 0x3a, 0x0a, 0x06, 0x61, 0x76, 0x61, 0x74, 0x61, 0x72, - 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x6c, 0x73, - 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x44, 0x65, 0x74, 0x61, - 0x69, 0x6c, 0x73, 0x2e, 0x41, 0x76, 0x61, 0x74, 0x61, 0x72, 0x52, 0x06, 0x61, 0x76, 0x61, 0x74, - 0x61, 0x72, 0x12, 0x1c, 0x0a, 0x06, 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x18, 0x05, 0x20, 0x01, - 0x28, 0x08, 0x3a, 0x04, 0x74, 0x72, 0x75, 0x65, 0x52, 0x06, 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, - 0x12, 0x20, 0x0a, 0x0b, 0x65, 0x78, 0x70, 0x69, 0x72, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x72, 0x18, - 0x06, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0b, 0x65, 0x78, 0x70, 0x69, 0x72, 0x65, 0x54, 0x69, 0x6d, - 0x65, 0x72, 0x12, 0x14, 0x0a, 0x05, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x18, 0x07, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x05, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x12, 0x18, 0x0a, 0x07, 0x62, 0x6c, 0x6f, 0x63, - 0x6b, 0x65, 0x64, 0x18, 0x08, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x62, 0x6c, 0x6f, 0x63, 0x6b, - 0x65, 0x64, 0x12, 0x24, 0x0a, 0x0d, 0x69, 0x6e, 0x62, 0x6f, 0x78, 0x50, 0x6f, 0x73, 0x69, 0x74, - 0x69, 0x6f, 0x6e, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0d, 0x69, 0x6e, 0x62, 0x6f, 0x78, - 0x50, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1a, 0x0a, 0x08, 0x61, 0x72, 0x63, 0x68, - 0x69, 0x76, 0x65, 0x64, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x61, 0x72, 0x63, 0x68, - 0x69, 0x76, 0x65, 0x64, 0x1a, 0x42, 0x0a, 0x06, 0x41, 0x76, 0x61, 0x74, 0x61, 0x72, 0x12, 0x20, - 0x0a, 0x0b, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, + 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x46, 0x6f, 0x72, 0x4d, + 0x65, 0x2e, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x4d, 0x65, 0x73, + 0x73, 0x61, 0x67, 0x65, 0x52, 0x08, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x1a, 0x86, + 0x02, 0x0a, 0x12, 0x43, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x44, + 0x65, 0x6c, 0x65, 0x74, 0x65, 0x12, 0x61, 0x0a, 0x0c, 0x63, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x3d, 0x2e, 0x73, 0x69, + 0x67, 0x6e, 0x61, 0x6c, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x53, 0x79, 0x6e, 0x63, + 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x46, 0x6f, + 0x72, 0x4d, 0x65, 0x2e, 0x43, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x52, 0x0c, 0x63, 0x6f, 0x6e, 0x76, + 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x69, 0x0a, 0x12, 0x6d, 0x6f, 0x73, 0x74, + 0x52, 0x65, 0x63, 0x65, 0x6e, 0x74, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x18, 0x02, + 0x20, 0x03, 0x28, 0x0b, 0x32, 0x39, 0x2e, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x6c, 0x73, 0x65, 0x72, + 0x76, 0x69, 0x63, 0x65, 0x2e, 0x53, 0x79, 0x6e, 0x63, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, + 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x46, 0x6f, 0x72, 0x4d, 0x65, 0x2e, 0x41, 0x64, 0x64, + 0x72, 0x65, 0x73, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, + 0x12, 0x6d, 0x6f, 0x73, 0x74, 0x52, 0x65, 0x63, 0x65, 0x6e, 0x74, 0x4d, 0x65, 0x73, 0x73, 0x61, + 0x67, 0x65, 0x73, 0x12, 0x22, 0x0a, 0x0c, 0x69, 0x73, 0x46, 0x75, 0x6c, 0x6c, 0x44, 0x65, 0x6c, + 0x65, 0x74, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0c, 0x69, 0x73, 0x46, 0x75, 0x6c, + 0x6c, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x1a, 0x80, 0x01, 0x0a, 0x1b, 0x4c, 0x6f, 0x63, 0x61, + 0x6c, 0x4f, 0x6e, 0x6c, 0x79, 0x43, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x12, 0x61, 0x0a, 0x0c, 0x63, 0x6f, 0x6e, 0x76, 0x65, + 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x3d, 0x2e, + 0x73, 0x69, 0x67, 0x6e, 0x61, 0x6c, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x53, 0x79, + 0x6e, 0x63, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, + 0x46, 0x6f, 0x72, 0x4d, 0x65, 0x2e, 0x43, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x52, 0x0c, 0x63, 0x6f, + 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4a, 0x04, 0x08, 0x03, 0x10, 0x04, + 0x4a, 0x04, 0x08, 0x11, 0x10, 0x12, 0x22, 0xe3, 0x04, 0x0a, 0x11, 0x41, 0x74, 0x74, 0x61, 0x63, + 0x68, 0x6d, 0x65, 0x6e, 0x74, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x12, 0x16, 0x0a, 0x05, + 0x63, 0x64, 0x6e, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x06, 0x48, 0x00, 0x52, 0x05, 0x63, + 0x64, 0x6e, 0x49, 0x64, 0x12, 0x18, 0x0a, 0x06, 0x63, 0x64, 0x6e, 0x4b, 0x65, 0x79, 0x18, 0x0f, + 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x06, 0x63, 0x64, 0x6e, 0x4b, 0x65, 0x79, 0x12, 0x20, + 0x0a, 0x0b, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, - 0x12, 0x16, 0x0a, 0x06, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, - 0x52, 0x06, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x1a, 0x22, 0x0a, 0x06, 0x4d, 0x65, 0x6d, 0x62, - 0x65, 0x72, 0x12, 0x12, 0x0a, 0x04, 0x65, 0x31, 0x36, 0x34, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x04, 0x65, 0x31, 0x36, 0x34, 0x4a, 0x04, 0x08, 0x01, 0x10, 0x02, 0x22, 0xc9, 0x01, 0x0a, - 0x0e, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, - 0x5f, 0x0a, 0x11, 0x6d, 0x6f, 0x62, 0x69, 0x6c, 0x65, 0x43, 0x6f, 0x69, 0x6e, 0x41, 0x64, 0x64, - 0x72, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2f, 0x2e, 0x73, 0x69, 0x67, - 0x6e, 0x61, 0x6c, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x50, 0x61, 0x79, 0x6d, 0x65, - 0x6e, 0x74, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x2e, 0x4d, 0x6f, 0x62, 0x69, 0x6c, 0x65, - 0x43, 0x6f, 0x69, 0x6e, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x48, 0x00, 0x52, 0x11, 0x6d, - 0x6f, 0x62, 0x69, 0x6c, 0x65, 0x43, 0x6f, 0x69, 0x6e, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, - 0x1a, 0x4b, 0x0a, 0x11, 0x4d, 0x6f, 0x62, 0x69, 0x6c, 0x65, 0x43, 0x6f, 0x69, 0x6e, 0x41, 0x64, - 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, - 0x1c, 0x0a, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x0c, 0x52, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x42, 0x09, 0x0a, - 0x07, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x22, 0x72, 0x0a, 0x16, 0x44, 0x65, 0x63, 0x72, - 0x79, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x4d, 0x65, 0x73, 0x73, 0x61, - 0x67, 0x65, 0x12, 0x1e, 0x0a, 0x0a, 0x72, 0x61, 0x74, 0x63, 0x68, 0x65, 0x74, 0x4b, 0x65, 0x79, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0a, 0x72, 0x61, 0x74, 0x63, 0x68, 0x65, 0x74, 0x4b, - 0x65, 0x79, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, - 0x12, 0x1a, 0x0a, 0x08, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x49, 0x64, 0x18, 0x03, 0x20, 0x01, - 0x28, 0x0d, 0x52, 0x08, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x49, 0x64, 0x22, 0x45, 0x0a, 0x13, - 0x50, 0x6e, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x4d, 0x65, 0x73, 0x73, - 0x61, 0x67, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x70, 0x6e, 0x69, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, - 0x52, 0x03, 0x70, 0x6e, 0x69, 0x12, 0x1c, 0x0a, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, - 0x72, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, - 0x75, 0x72, 0x65, 0x22, 0x7d, 0x0a, 0x0b, 0x45, 0x64, 0x69, 0x74, 0x4d, 0x65, 0x73, 0x73, 0x61, - 0x67, 0x65, 0x12, 0x30, 0x0a, 0x13, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x53, 0x65, 0x6e, 0x74, - 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, - 0x13, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x53, 0x65, 0x6e, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x73, - 0x74, 0x61, 0x6d, 0x70, 0x12, 0x3c, 0x0a, 0x0b, 0x64, 0x61, 0x74, 0x61, 0x4d, 0x65, 0x73, 0x73, - 0x61, 0x67, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x73, 0x69, 0x67, 0x6e, - 0x61, 0x6c, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x44, 0x61, 0x74, 0x61, 0x4d, 0x65, - 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x0b, 0x64, 0x61, 0x74, 0x61, 0x4d, 0x65, 0x73, 0x73, 0x61, - 0x67, 0x65, 0x42, 0x45, 0x0a, 0x2e, 0x6f, 0x72, 0x67, 0x2e, 0x77, 0x68, 0x69, 0x73, 0x70, 0x65, - 0x72, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x73, 0x2e, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x6c, 0x73, - 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, - 0x70, 0x75, 0x73, 0x68, 0x42, 0x13, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x6c, 0x53, 0x65, 0x72, 0x76, - 0x69, 0x63, 0x65, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x73, + 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x03, 0x6b, + 0x65, 0x79, 0x12, 0x12, 0x0a, 0x04, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0d, + 0x52, 0x04, 0x73, 0x69, 0x7a, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x68, 0x75, 0x6d, 0x62, 0x6e, + 0x61, 0x69, 0x6c, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x74, 0x68, 0x75, 0x6d, 0x62, + 0x6e, 0x61, 0x69, 0x6c, 0x12, 0x16, 0x0a, 0x06, 0x64, 0x69, 0x67, 0x65, 0x73, 0x74, 0x18, 0x06, + 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x64, 0x69, 0x67, 0x65, 0x73, 0x74, 0x12, 0x26, 0x0a, 0x0e, + 0x69, 0x6e, 0x63, 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x61, 0x6c, 0x4d, 0x61, 0x63, 0x18, 0x13, + 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0e, 0x69, 0x6e, 0x63, 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x61, + 0x6c, 0x4d, 0x61, 0x63, 0x12, 0x38, 0x0a, 0x17, 0x69, 0x6e, 0x63, 0x72, 0x65, 0x6d, 0x65, 0x6e, + 0x74, 0x61, 0x6c, 0x4d, 0x61, 0x63, 0x43, 0x68, 0x75, 0x6e, 0x6b, 0x53, 0x69, 0x7a, 0x65, 0x18, + 0x11, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x17, 0x69, 0x6e, 0x63, 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, + 0x61, 0x6c, 0x4d, 0x61, 0x63, 0x43, 0x68, 0x75, 0x6e, 0x6b, 0x53, 0x69, 0x7a, 0x65, 0x12, 0x1a, + 0x0a, 0x08, 0x66, 0x69, 0x6c, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x08, 0x66, 0x69, 0x6c, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x66, 0x6c, + 0x61, 0x67, 0x73, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x05, 0x66, 0x6c, 0x61, 0x67, 0x73, + 0x12, 0x14, 0x0a, 0x05, 0x77, 0x69, 0x64, 0x74, 0x68, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0d, 0x52, + 0x05, 0x77, 0x69, 0x64, 0x74, 0x68, 0x12, 0x16, 0x0a, 0x06, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, + 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x06, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x12, 0x18, + 0x0a, 0x07, 0x63, 0x61, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x07, 0x63, 0x61, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1a, 0x0a, 0x08, 0x62, 0x6c, 0x75, 0x72, + 0x48, 0x61, 0x73, 0x68, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x62, 0x6c, 0x75, 0x72, + 0x48, 0x61, 0x73, 0x68, 0x12, 0x28, 0x0a, 0x0f, 0x75, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x54, 0x69, + 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0f, 0x75, + 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x1c, + 0x0a, 0x09, 0x63, 0x64, 0x6e, 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x18, 0x0e, 0x20, 0x01, 0x28, + 0x0d, 0x52, 0x09, 0x63, 0x64, 0x6e, 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x22, 0x39, 0x0a, 0x05, + 0x46, 0x6c, 0x61, 0x67, 0x73, 0x12, 0x11, 0x0a, 0x0d, 0x56, 0x4f, 0x49, 0x43, 0x45, 0x5f, 0x4d, + 0x45, 0x53, 0x53, 0x41, 0x47, 0x45, 0x10, 0x01, 0x12, 0x0e, 0x0a, 0x0a, 0x42, 0x4f, 0x52, 0x44, + 0x45, 0x52, 0x4c, 0x45, 0x53, 0x53, 0x10, 0x02, 0x12, 0x07, 0x0a, 0x03, 0x47, 0x49, 0x46, 0x10, + 0x04, 0x22, 0x04, 0x08, 0x03, 0x10, 0x03, 0x42, 0x17, 0x0a, 0x15, 0x61, 0x74, 0x74, 0x61, 0x63, + 0x68, 0x6d, 0x65, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, + 0x4a, 0x04, 0x08, 0x10, 0x10, 0x11, 0x4a, 0x04, 0x08, 0x12, 0x10, 0x13, 0x22, 0xf0, 0x02, 0x0a, + 0x0c, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x12, 0x0e, 0x0a, + 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x02, 0x69, 0x64, 0x12, 0x34, 0x0a, + 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x20, 0x2e, 0x73, 0x69, + 0x67, 0x6e, 0x61, 0x6c, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x47, 0x72, 0x6f, 0x75, + 0x70, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x2e, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, + 0x79, 0x70, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x6d, 0x65, 0x6d, 0x62, 0x65, + 0x72, 0x73, 0x45, 0x31, 0x36, 0x34, 0x18, 0x04, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0b, 0x6d, 0x65, + 0x6d, 0x62, 0x65, 0x72, 0x73, 0x45, 0x31, 0x36, 0x34, 0x12, 0x3c, 0x0a, 0x07, 0x6d, 0x65, 0x6d, + 0x62, 0x65, 0x72, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x73, 0x69, 0x67, + 0x6e, 0x61, 0x6c, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x47, 0x72, 0x6f, 0x75, 0x70, + 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x2e, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x52, 0x07, + 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x12, 0x38, 0x0a, 0x06, 0x61, 0x76, 0x61, 0x74, 0x61, + 0x72, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x6c, + 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x41, 0x74, 0x74, 0x61, 0x63, 0x68, 0x6d, 0x65, + 0x6e, 0x74, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x52, 0x06, 0x61, 0x76, 0x61, 0x74, 0x61, + 0x72, 0x1a, 0x22, 0x0a, 0x06, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x12, 0x12, 0x0a, 0x04, 0x65, + 0x31, 0x36, 0x34, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x65, 0x31, 0x36, 0x34, 0x4a, + 0x04, 0x08, 0x01, 0x10, 0x02, 0x22, 0x48, 0x0a, 0x04, 0x54, 0x79, 0x70, 0x65, 0x12, 0x0b, 0x0a, + 0x07, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x00, 0x12, 0x0a, 0x0a, 0x06, 0x55, 0x50, + 0x44, 0x41, 0x54, 0x45, 0x10, 0x01, 0x12, 0x0b, 0x0a, 0x07, 0x44, 0x45, 0x4c, 0x49, 0x56, 0x45, + 0x52, 0x10, 0x02, 0x12, 0x08, 0x0a, 0x04, 0x51, 0x55, 0x49, 0x54, 0x10, 0x03, 0x12, 0x10, 0x0a, + 0x0c, 0x52, 0x45, 0x51, 0x55, 0x45, 0x53, 0x54, 0x5f, 0x49, 0x4e, 0x46, 0x4f, 0x10, 0x04, 0x22, + 0x6c, 0x0a, 0x0e, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x56, + 0x32, 0x12, 0x1c, 0x0a, 0x09, 0x6d, 0x61, 0x73, 0x74, 0x65, 0x72, 0x4b, 0x65, 0x79, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x6d, 0x61, 0x73, 0x74, 0x65, 0x72, 0x4b, 0x65, 0x79, 0x12, + 0x1a, 0x0a, 0x08, 0x72, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x0d, 0x52, 0x08, 0x72, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x20, 0x0a, 0x0b, 0x67, + 0x72, 0x6f, 0x75, 0x70, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, + 0x52, 0x0b, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x22, 0xa5, 0x03, + 0x0a, 0x0e, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x63, 0x74, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, + 0x12, 0x16, 0x0a, 0x06, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x06, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x12, 0x10, 0x0a, 0x03, 0x61, 0x63, 0x69, 0x18, + 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x61, 0x63, 0x69, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, + 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x3c, + 0x0a, 0x06, 0x61, 0x76, 0x61, 0x74, 0x61, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x24, + 0x2e, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x6c, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x43, + 0x6f, 0x6e, 0x74, 0x61, 0x63, 0x74, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x2e, 0x41, 0x76, + 0x61, 0x74, 0x61, 0x72, 0x52, 0x06, 0x61, 0x76, 0x61, 0x74, 0x61, 0x72, 0x12, 0x14, 0x0a, 0x05, + 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x63, 0x6f, 0x6c, + 0x6f, 0x72, 0x12, 0x33, 0x0a, 0x08, 0x76, 0x65, 0x72, 0x69, 0x66, 0x69, 0x65, 0x64, 0x18, 0x05, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x6c, 0x73, 0x65, 0x72, + 0x76, 0x69, 0x63, 0x65, 0x2e, 0x56, 0x65, 0x72, 0x69, 0x66, 0x69, 0x65, 0x64, 0x52, 0x08, 0x76, + 0x65, 0x72, 0x69, 0x66, 0x69, 0x65, 0x64, 0x12, 0x1e, 0x0a, 0x0a, 0x70, 0x72, 0x6f, 0x66, 0x69, + 0x6c, 0x65, 0x4b, 0x65, 0x79, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0a, 0x70, 0x72, 0x6f, + 0x66, 0x69, 0x6c, 0x65, 0x4b, 0x65, 0x79, 0x12, 0x20, 0x0a, 0x0b, 0x65, 0x78, 0x70, 0x69, 0x72, + 0x65, 0x54, 0x69, 0x6d, 0x65, 0x72, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0b, 0x65, 0x78, + 0x70, 0x69, 0x72, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x72, 0x12, 0x24, 0x0a, 0x0d, 0x69, 0x6e, 0x62, + 0x6f, 0x78, 0x50, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0d, + 0x52, 0x0d, 0x69, 0x6e, 0x62, 0x6f, 0x78, 0x50, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x12, + 0x1a, 0x0a, 0x08, 0x61, 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, 0x64, 0x18, 0x0b, 0x20, 0x01, 0x28, + 0x08, 0x52, 0x08, 0x61, 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, 0x64, 0x1a, 0x42, 0x0a, 0x06, 0x41, + 0x76, 0x61, 0x74, 0x61, 0x72, 0x12, 0x20, 0x0a, 0x0b, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, + 0x54, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x63, 0x6f, 0x6e, 0x74, + 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x6c, 0x65, 0x6e, 0x67, 0x74, + 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x06, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x4a, + 0x04, 0x08, 0x07, 0x10, 0x08, 0x22, 0xe8, 0x03, 0x0a, 0x0c, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x44, + 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x0c, 0x52, 0x02, 0x69, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x6d, 0x65, + 0x6d, 0x62, 0x65, 0x72, 0x73, 0x45, 0x31, 0x36, 0x34, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, + 0x0b, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x45, 0x31, 0x36, 0x34, 0x12, 0x3c, 0x0a, 0x07, + 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x18, 0x09, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x22, 0x2e, + 0x73, 0x69, 0x67, 0x6e, 0x61, 0x6c, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x47, 0x72, + 0x6f, 0x75, 0x70, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x2e, 0x4d, 0x65, 0x6d, 0x62, 0x65, + 0x72, 0x52, 0x07, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x12, 0x3a, 0x0a, 0x06, 0x61, 0x76, + 0x61, 0x74, 0x61, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x73, 0x69, 0x67, + 0x6e, 0x61, 0x6c, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x47, 0x72, 0x6f, 0x75, 0x70, + 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x2e, 0x41, 0x76, 0x61, 0x74, 0x61, 0x72, 0x52, 0x06, + 0x61, 0x76, 0x61, 0x74, 0x61, 0x72, 0x12, 0x1c, 0x0a, 0x06, 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, + 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x3a, 0x04, 0x74, 0x72, 0x75, 0x65, 0x52, 0x06, 0x61, 0x63, + 0x74, 0x69, 0x76, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x65, 0x78, 0x70, 0x69, 0x72, 0x65, 0x54, 0x69, + 0x6d, 0x65, 0x72, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0b, 0x65, 0x78, 0x70, 0x69, 0x72, + 0x65, 0x54, 0x69, 0x6d, 0x65, 0x72, 0x12, 0x14, 0x0a, 0x05, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x18, + 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x12, 0x18, 0x0a, 0x07, + 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x65, 0x64, 0x18, 0x08, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x62, + 0x6c, 0x6f, 0x63, 0x6b, 0x65, 0x64, 0x12, 0x24, 0x0a, 0x0d, 0x69, 0x6e, 0x62, 0x6f, 0x78, 0x50, + 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0d, 0x69, + 0x6e, 0x62, 0x6f, 0x78, 0x50, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1a, 0x0a, 0x08, + 0x61, 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, 0x64, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, + 0x61, 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, 0x64, 0x1a, 0x42, 0x0a, 0x06, 0x41, 0x76, 0x61, 0x74, + 0x61, 0x72, 0x12, 0x20, 0x0a, 0x0b, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70, + 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, + 0x54, 0x79, 0x70, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x0d, 0x52, 0x06, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x1a, 0x22, 0x0a, 0x06, + 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x12, 0x12, 0x0a, 0x04, 0x65, 0x31, 0x36, 0x34, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x65, 0x31, 0x36, 0x34, 0x4a, 0x04, 0x08, 0x01, 0x10, 0x02, + 0x22, 0xc9, 0x01, 0x0a, 0x0e, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x41, 0x64, 0x64, 0x72, + 0x65, 0x73, 0x73, 0x12, 0x5f, 0x0a, 0x11, 0x6d, 0x6f, 0x62, 0x69, 0x6c, 0x65, 0x43, 0x6f, 0x69, + 0x6e, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2f, + 0x2e, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x6c, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x50, + 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x2e, 0x4d, 0x6f, + 0x62, 0x69, 0x6c, 0x65, 0x43, 0x6f, 0x69, 0x6e, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x48, + 0x00, 0x52, 0x11, 0x6d, 0x6f, 0x62, 0x69, 0x6c, 0x65, 0x43, 0x6f, 0x69, 0x6e, 0x41, 0x64, 0x64, + 0x72, 0x65, 0x73, 0x73, 0x1a, 0x4b, 0x0a, 0x11, 0x4d, 0x6f, 0x62, 0x69, 0x6c, 0x65, 0x43, 0x6f, + 0x69, 0x6e, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x61, 0x64, 0x64, + 0x72, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x61, 0x64, 0x64, 0x72, + 0x65, 0x73, 0x73, 0x12, 0x1c, 0x0a, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, + 0x65, 0x42, 0x09, 0x0a, 0x07, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x22, 0x72, 0x0a, 0x16, + 0x44, 0x65, 0x63, 0x72, 0x79, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x4d, + 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x1e, 0x0a, 0x0a, 0x72, 0x61, 0x74, 0x63, 0x68, 0x65, + 0x74, 0x4b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0a, 0x72, 0x61, 0x74, 0x63, + 0x68, 0x65, 0x74, 0x4b, 0x65, 0x79, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, + 0x61, 0x6d, 0x70, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, + 0x74, 0x61, 0x6d, 0x70, 0x12, 0x1a, 0x0a, 0x08, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x49, 0x64, + 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x08, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x49, 0x64, + 0x22, 0x45, 0x0a, 0x13, 0x50, 0x6e, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, + 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x70, 0x6e, 0x69, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x0c, 0x52, 0x03, 0x70, 0x6e, 0x69, 0x12, 0x1c, 0x0a, 0x09, 0x73, 0x69, 0x67, + 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x73, 0x69, + 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x22, 0x7d, 0x0a, 0x0b, 0x45, 0x64, 0x69, 0x74, 0x4d, + 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x30, 0x0a, 0x13, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, + 0x53, 0x65, 0x6e, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x04, 0x52, 0x13, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x53, 0x65, 0x6e, 0x74, 0x54, + 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x3c, 0x0a, 0x0b, 0x64, 0x61, 0x74, 0x61, + 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, + 0x73, 0x69, 0x67, 0x6e, 0x61, 0x6c, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x44, 0x61, + 0x74, 0x61, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x0b, 0x64, 0x61, 0x74, 0x61, 0x4d, + 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x42, 0x45, 0x0a, 0x2e, 0x6f, 0x72, 0x67, 0x2e, 0x77, 0x68, + 0x69, 0x73, 0x70, 0x65, 0x72, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x73, 0x2e, 0x73, 0x69, 0x67, + 0x6e, 0x61, 0x6c, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, + 0x6e, 0x61, 0x6c, 0x2e, 0x70, 0x75, 0x73, 0x68, 0x42, 0x13, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x6c, + 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x73, } var ( @@ -8385,109 +8913,115 @@ func file_SignalService_proto_rawDescGZIP() []byte { } var file_SignalService_proto_enumTypes = make([]protoimpl.EnumInfo, 27) -var file_SignalService_proto_msgTypes = make([]protoimpl.MessageInfo, 74) +var file_SignalService_proto_msgTypes = make([]protoimpl.MessageInfo, 80) var file_SignalService_proto_goTypes = []interface{}{ - (Envelope_Type)(0), // 0: signalservice.Envelope.Type - (CallMessage_Offer_Type)(0), // 1: signalservice.CallMessage.Offer.Type - (CallMessage_Hangup_Type)(0), // 2: signalservice.CallMessage.Hangup.Type - (CallMessage_Opaque_Urgency)(0), // 3: signalservice.CallMessage.Opaque.Urgency - (BodyRange_Style)(0), // 4: signalservice.BodyRange.Style - (DataMessage_Flags)(0), // 5: signalservice.DataMessage.Flags - (DataMessage_ProtocolVersion)(0), // 6: signalservice.DataMessage.ProtocolVersion - (DataMessage_Quote_Type)(0), // 7: signalservice.DataMessage.Quote.Type - (DataMessage_Contact_Phone_Type)(0), // 8: signalservice.DataMessage.Contact.Phone.Type - (DataMessage_Contact_Email_Type)(0), // 9: signalservice.DataMessage.Contact.Email.Type - (DataMessage_Contact_PostalAddress_Type)(0), // 10: signalservice.DataMessage.Contact.PostalAddress.Type - (DataMessage_Payment_Activation_Type)(0), // 11: signalservice.DataMessage.Payment.Activation.Type - (ReceiptMessage_Type)(0), // 12: signalservice.ReceiptMessage.Type - (TypingMessage_Action)(0), // 13: signalservice.TypingMessage.Action - (TextAttachment_Style)(0), // 14: signalservice.TextAttachment.Style - (Verified_State)(0), // 15: signalservice.Verified.State - (SyncMessage_Request_Type)(0), // 16: signalservice.SyncMessage.Request.Type - (SyncMessage_StickerPackOperation_Type)(0), // 17: signalservice.SyncMessage.StickerPackOperation.Type - (SyncMessage_FetchLatest_Type)(0), // 18: signalservice.SyncMessage.FetchLatest.Type - (SyncMessage_MessageRequestResponse_Type)(0), // 19: signalservice.SyncMessage.MessageRequestResponse.Type - (SyncMessage_CallEvent_Type)(0), // 20: signalservice.SyncMessage.CallEvent.Type - (SyncMessage_CallEvent_Direction)(0), // 21: signalservice.SyncMessage.CallEvent.Direction - (SyncMessage_CallEvent_Event)(0), // 22: signalservice.SyncMessage.CallEvent.Event - (SyncMessage_CallLinkUpdate_Type)(0), // 23: signalservice.SyncMessage.CallLinkUpdate.Type - (SyncMessage_CallLogEvent_Type)(0), // 24: signalservice.SyncMessage.CallLogEvent.Type - (AttachmentPointer_Flags)(0), // 25: signalservice.AttachmentPointer.Flags - (GroupContext_Type)(0), // 26: signalservice.GroupContext.Type - (*Envelope)(nil), // 27: signalservice.Envelope - (*Content)(nil), // 28: signalservice.Content - (*CallMessage)(nil), // 29: signalservice.CallMessage - (*BodyRange)(nil), // 30: signalservice.BodyRange - (*DataMessage)(nil), // 31: signalservice.DataMessage - (*NullMessage)(nil), // 32: signalservice.NullMessage - (*ReceiptMessage)(nil), // 33: signalservice.ReceiptMessage - (*TypingMessage)(nil), // 34: signalservice.TypingMessage - (*StoryMessage)(nil), // 35: signalservice.StoryMessage - (*Preview)(nil), // 36: signalservice.Preview - (*TextAttachment)(nil), // 37: signalservice.TextAttachment - (*Verified)(nil), // 38: signalservice.Verified - (*SyncMessage)(nil), // 39: signalservice.SyncMessage - (*AttachmentPointer)(nil), // 40: signalservice.AttachmentPointer - (*GroupContext)(nil), // 41: signalservice.GroupContext - (*GroupContextV2)(nil), // 42: signalservice.GroupContextV2 - (*ContactDetails)(nil), // 43: signalservice.ContactDetails - (*GroupDetails)(nil), // 44: signalservice.GroupDetails - (*PaymentAddress)(nil), // 45: signalservice.PaymentAddress - (*DecryptionErrorMessage)(nil), // 46: signalservice.DecryptionErrorMessage - (*PniSignatureMessage)(nil), // 47: signalservice.PniSignatureMessage - (*EditMessage)(nil), // 48: signalservice.EditMessage - (*CallMessage_Offer)(nil), // 49: signalservice.CallMessage.Offer - (*CallMessage_Answer)(nil), // 50: signalservice.CallMessage.Answer - (*CallMessage_IceUpdate)(nil), // 51: signalservice.CallMessage.IceUpdate - (*CallMessage_Busy)(nil), // 52: signalservice.CallMessage.Busy - (*CallMessage_Hangup)(nil), // 53: signalservice.CallMessage.Hangup - (*CallMessage_Opaque)(nil), // 54: signalservice.CallMessage.Opaque - (*DataMessage_Quote)(nil), // 55: signalservice.DataMessage.Quote - (*DataMessage_Contact)(nil), // 56: signalservice.DataMessage.Contact - (*DataMessage_Sticker)(nil), // 57: signalservice.DataMessage.Sticker - (*DataMessage_Reaction)(nil), // 58: signalservice.DataMessage.Reaction - (*DataMessage_Delete)(nil), // 59: signalservice.DataMessage.Delete - (*DataMessage_GroupCallUpdate)(nil), // 60: signalservice.DataMessage.GroupCallUpdate - (*DataMessage_StoryContext)(nil), // 61: signalservice.DataMessage.StoryContext - (*DataMessage_Payment)(nil), // 62: signalservice.DataMessage.Payment - (*DataMessage_GiftBadge)(nil), // 63: signalservice.DataMessage.GiftBadge - (*DataMessage_Quote_QuotedAttachment)(nil), // 64: signalservice.DataMessage.Quote.QuotedAttachment - (*DataMessage_Contact_Name)(nil), // 65: signalservice.DataMessage.Contact.Name - (*DataMessage_Contact_Phone)(nil), // 66: signalservice.DataMessage.Contact.Phone - (*DataMessage_Contact_Email)(nil), // 67: signalservice.DataMessage.Contact.Email - (*DataMessage_Contact_PostalAddress)(nil), // 68: signalservice.DataMessage.Contact.PostalAddress - (*DataMessage_Contact_Avatar)(nil), // 69: signalservice.DataMessage.Contact.Avatar - (*DataMessage_Payment_Amount)(nil), // 70: signalservice.DataMessage.Payment.Amount - (*DataMessage_Payment_Notification)(nil), // 71: signalservice.DataMessage.Payment.Notification - (*DataMessage_Payment_Activation)(nil), // 72: signalservice.DataMessage.Payment.Activation - (*DataMessage_Payment_Amount_MobileCoin)(nil), // 73: signalservice.DataMessage.Payment.Amount.MobileCoin - (*DataMessage_Payment_Notification_MobileCoin)(nil), // 74: signalservice.DataMessage.Payment.Notification.MobileCoin - (*TextAttachment_Gradient)(nil), // 75: signalservice.TextAttachment.Gradient - (*SyncMessage_Sent)(nil), // 76: signalservice.SyncMessage.Sent - (*SyncMessage_Contacts)(nil), // 77: signalservice.SyncMessage.Contacts - (*SyncMessage_Blocked)(nil), // 78: signalservice.SyncMessage.Blocked - (*SyncMessage_Request)(nil), // 79: signalservice.SyncMessage.Request - (*SyncMessage_Read)(nil), // 80: signalservice.SyncMessage.Read - (*SyncMessage_Viewed)(nil), // 81: signalservice.SyncMessage.Viewed - (*SyncMessage_Configuration)(nil), // 82: signalservice.SyncMessage.Configuration - (*SyncMessage_StickerPackOperation)(nil), // 83: signalservice.SyncMessage.StickerPackOperation - (*SyncMessage_ViewOnceOpen)(nil), // 84: signalservice.SyncMessage.ViewOnceOpen - (*SyncMessage_FetchLatest)(nil), // 85: signalservice.SyncMessage.FetchLatest - (*SyncMessage_Keys)(nil), // 86: signalservice.SyncMessage.Keys - (*SyncMessage_MessageRequestResponse)(nil), // 87: signalservice.SyncMessage.MessageRequestResponse - (*SyncMessage_OutgoingPayment)(nil), // 88: signalservice.SyncMessage.OutgoingPayment - (*SyncMessage_PniChangeNumber)(nil), // 89: signalservice.SyncMessage.PniChangeNumber - (*SyncMessage_CallEvent)(nil), // 90: signalservice.SyncMessage.CallEvent - (*SyncMessage_CallLinkUpdate)(nil), // 91: signalservice.SyncMessage.CallLinkUpdate - (*SyncMessage_CallLogEvent)(nil), // 92: signalservice.SyncMessage.CallLogEvent - (*SyncMessage_Sent_UnidentifiedDeliveryStatus)(nil), // 93: signalservice.SyncMessage.Sent.UnidentifiedDeliveryStatus - (*SyncMessage_Sent_StoryMessageRecipient)(nil), // 94: signalservice.SyncMessage.Sent.StoryMessageRecipient - (*SyncMessage_OutgoingPayment_MobileCoin)(nil), // 95: signalservice.SyncMessage.OutgoingPayment.MobileCoin - (*GroupContext_Member)(nil), // 96: signalservice.GroupContext.Member - (*ContactDetails_Avatar)(nil), // 97: signalservice.ContactDetails.Avatar - (*GroupDetails_Avatar)(nil), // 98: signalservice.GroupDetails.Avatar - (*GroupDetails_Member)(nil), // 99: signalservice.GroupDetails.Member - (*PaymentAddress_MobileCoinAddress)(nil), // 100: signalservice.PaymentAddress.MobileCoinAddress + (Envelope_Type)(0), // 0: signalservice.Envelope.Type + (CallMessage_Offer_Type)(0), // 1: signalservice.CallMessage.Offer.Type + (CallMessage_Hangup_Type)(0), // 2: signalservice.CallMessage.Hangup.Type + (CallMessage_Opaque_Urgency)(0), // 3: signalservice.CallMessage.Opaque.Urgency + (BodyRange_Style)(0), // 4: signalservice.BodyRange.Style + (DataMessage_Flags)(0), // 5: signalservice.DataMessage.Flags + (DataMessage_ProtocolVersion)(0), // 6: signalservice.DataMessage.ProtocolVersion + (DataMessage_Quote_Type)(0), // 7: signalservice.DataMessage.Quote.Type + (DataMessage_Contact_Phone_Type)(0), // 8: signalservice.DataMessage.Contact.Phone.Type + (DataMessage_Contact_Email_Type)(0), // 9: signalservice.DataMessage.Contact.Email.Type + (DataMessage_Contact_PostalAddress_Type)(0), // 10: signalservice.DataMessage.Contact.PostalAddress.Type + (DataMessage_Payment_Activation_Type)(0), // 11: signalservice.DataMessage.Payment.Activation.Type + (ReceiptMessage_Type)(0), // 12: signalservice.ReceiptMessage.Type + (TypingMessage_Action)(0), // 13: signalservice.TypingMessage.Action + (TextAttachment_Style)(0), // 14: signalservice.TextAttachment.Style + (Verified_State)(0), // 15: signalservice.Verified.State + (SyncMessage_Request_Type)(0), // 16: signalservice.SyncMessage.Request.Type + (SyncMessage_StickerPackOperation_Type)(0), // 17: signalservice.SyncMessage.StickerPackOperation.Type + (SyncMessage_FetchLatest_Type)(0), // 18: signalservice.SyncMessage.FetchLatest.Type + (SyncMessage_MessageRequestResponse_Type)(0), // 19: signalservice.SyncMessage.MessageRequestResponse.Type + (SyncMessage_CallEvent_Type)(0), // 20: signalservice.SyncMessage.CallEvent.Type + (SyncMessage_CallEvent_Direction)(0), // 21: signalservice.SyncMessage.CallEvent.Direction + (SyncMessage_CallEvent_Event)(0), // 22: signalservice.SyncMessage.CallEvent.Event + (SyncMessage_CallLinkUpdate_Type)(0), // 23: signalservice.SyncMessage.CallLinkUpdate.Type + (SyncMessage_CallLogEvent_Type)(0), // 24: signalservice.SyncMessage.CallLogEvent.Type + (AttachmentPointer_Flags)(0), // 25: signalservice.AttachmentPointer.Flags + (GroupContext_Type)(0), // 26: signalservice.GroupContext.Type + (*Envelope)(nil), // 27: signalservice.Envelope + (*Content)(nil), // 28: signalservice.Content + (*CallMessage)(nil), // 29: signalservice.CallMessage + (*BodyRange)(nil), // 30: signalservice.BodyRange + (*DataMessage)(nil), // 31: signalservice.DataMessage + (*NullMessage)(nil), // 32: signalservice.NullMessage + (*ReceiptMessage)(nil), // 33: signalservice.ReceiptMessage + (*TypingMessage)(nil), // 34: signalservice.TypingMessage + (*StoryMessage)(nil), // 35: signalservice.StoryMessage + (*Preview)(nil), // 36: signalservice.Preview + (*TextAttachment)(nil), // 37: signalservice.TextAttachment + (*Verified)(nil), // 38: signalservice.Verified + (*SyncMessage)(nil), // 39: signalservice.SyncMessage + (*AttachmentPointer)(nil), // 40: signalservice.AttachmentPointer + (*GroupContext)(nil), // 41: signalservice.GroupContext + (*GroupContextV2)(nil), // 42: signalservice.GroupContextV2 + (*ContactDetails)(nil), // 43: signalservice.ContactDetails + (*GroupDetails)(nil), // 44: signalservice.GroupDetails + (*PaymentAddress)(nil), // 45: signalservice.PaymentAddress + (*DecryptionErrorMessage)(nil), // 46: signalservice.DecryptionErrorMessage + (*PniSignatureMessage)(nil), // 47: signalservice.PniSignatureMessage + (*EditMessage)(nil), // 48: signalservice.EditMessage + (*CallMessage_Offer)(nil), // 49: signalservice.CallMessage.Offer + (*CallMessage_Answer)(nil), // 50: signalservice.CallMessage.Answer + (*CallMessage_IceUpdate)(nil), // 51: signalservice.CallMessage.IceUpdate + (*CallMessage_Busy)(nil), // 52: signalservice.CallMessage.Busy + (*CallMessage_Hangup)(nil), // 53: signalservice.CallMessage.Hangup + (*CallMessage_Opaque)(nil), // 54: signalservice.CallMessage.Opaque + (*DataMessage_Quote)(nil), // 55: signalservice.DataMessage.Quote + (*DataMessage_Contact)(nil), // 56: signalservice.DataMessage.Contact + (*DataMessage_Sticker)(nil), // 57: signalservice.DataMessage.Sticker + (*DataMessage_Reaction)(nil), // 58: signalservice.DataMessage.Reaction + (*DataMessage_Delete)(nil), // 59: signalservice.DataMessage.Delete + (*DataMessage_GroupCallUpdate)(nil), // 60: signalservice.DataMessage.GroupCallUpdate + (*DataMessage_StoryContext)(nil), // 61: signalservice.DataMessage.StoryContext + (*DataMessage_Payment)(nil), // 62: signalservice.DataMessage.Payment + (*DataMessage_GiftBadge)(nil), // 63: signalservice.DataMessage.GiftBadge + (*DataMessage_Quote_QuotedAttachment)(nil), // 64: signalservice.DataMessage.Quote.QuotedAttachment + (*DataMessage_Contact_Name)(nil), // 65: signalservice.DataMessage.Contact.Name + (*DataMessage_Contact_Phone)(nil), // 66: signalservice.DataMessage.Contact.Phone + (*DataMessage_Contact_Email)(nil), // 67: signalservice.DataMessage.Contact.Email + (*DataMessage_Contact_PostalAddress)(nil), // 68: signalservice.DataMessage.Contact.PostalAddress + (*DataMessage_Contact_Avatar)(nil), // 69: signalservice.DataMessage.Contact.Avatar + (*DataMessage_Payment_Amount)(nil), // 70: signalservice.DataMessage.Payment.Amount + (*DataMessage_Payment_Notification)(nil), // 71: signalservice.DataMessage.Payment.Notification + (*DataMessage_Payment_Activation)(nil), // 72: signalservice.DataMessage.Payment.Activation + (*DataMessage_Payment_Amount_MobileCoin)(nil), // 73: signalservice.DataMessage.Payment.Amount.MobileCoin + (*DataMessage_Payment_Notification_MobileCoin)(nil), // 74: signalservice.DataMessage.Payment.Notification.MobileCoin + (*TextAttachment_Gradient)(nil), // 75: signalservice.TextAttachment.Gradient + (*SyncMessage_Sent)(nil), // 76: signalservice.SyncMessage.Sent + (*SyncMessage_Contacts)(nil), // 77: signalservice.SyncMessage.Contacts + (*SyncMessage_Blocked)(nil), // 78: signalservice.SyncMessage.Blocked + (*SyncMessage_Request)(nil), // 79: signalservice.SyncMessage.Request + (*SyncMessage_Read)(nil), // 80: signalservice.SyncMessage.Read + (*SyncMessage_Viewed)(nil), // 81: signalservice.SyncMessage.Viewed + (*SyncMessage_Configuration)(nil), // 82: signalservice.SyncMessage.Configuration + (*SyncMessage_StickerPackOperation)(nil), // 83: signalservice.SyncMessage.StickerPackOperation + (*SyncMessage_ViewOnceOpen)(nil), // 84: signalservice.SyncMessage.ViewOnceOpen + (*SyncMessage_FetchLatest)(nil), // 85: signalservice.SyncMessage.FetchLatest + (*SyncMessage_Keys)(nil), // 86: signalservice.SyncMessage.Keys + (*SyncMessage_MessageRequestResponse)(nil), // 87: signalservice.SyncMessage.MessageRequestResponse + (*SyncMessage_OutgoingPayment)(nil), // 88: signalservice.SyncMessage.OutgoingPayment + (*SyncMessage_PniChangeNumber)(nil), // 89: signalservice.SyncMessage.PniChangeNumber + (*SyncMessage_CallEvent)(nil), // 90: signalservice.SyncMessage.CallEvent + (*SyncMessage_CallLinkUpdate)(nil), // 91: signalservice.SyncMessage.CallLinkUpdate + (*SyncMessage_CallLogEvent)(nil), // 92: signalservice.SyncMessage.CallLogEvent + (*SyncMessage_DeleteForMe)(nil), // 93: signalservice.SyncMessage.DeleteForMe + (*SyncMessage_Sent_UnidentifiedDeliveryStatus)(nil), // 94: signalservice.SyncMessage.Sent.UnidentifiedDeliveryStatus + (*SyncMessage_Sent_StoryMessageRecipient)(nil), // 95: signalservice.SyncMessage.Sent.StoryMessageRecipient + (*SyncMessage_OutgoingPayment_MobileCoin)(nil), // 96: signalservice.SyncMessage.OutgoingPayment.MobileCoin + (*SyncMessage_DeleteForMe_ConversationIdentifier)(nil), // 97: signalservice.SyncMessage.DeleteForMe.ConversationIdentifier + (*SyncMessage_DeleteForMe_AddressableMessage)(nil), // 98: signalservice.SyncMessage.DeleteForMe.AddressableMessage + (*SyncMessage_DeleteForMe_MessageDeletes)(nil), // 99: signalservice.SyncMessage.DeleteForMe.MessageDeletes + (*SyncMessage_DeleteForMe_ConversationDelete)(nil), // 100: signalservice.SyncMessage.DeleteForMe.ConversationDelete + (*SyncMessage_DeleteForMe_LocalOnlyConversationDelete)(nil), // 101: signalservice.SyncMessage.DeleteForMe.LocalOnlyConversationDelete + (*GroupContext_Member)(nil), // 102: signalservice.GroupContext.Member + (*ContactDetails_Avatar)(nil), // 103: signalservice.ContactDetails.Avatar + (*GroupDetails_Avatar)(nil), // 104: signalservice.GroupDetails.Avatar + (*GroupDetails_Member)(nil), // 105: signalservice.GroupDetails.Member + (*PaymentAddress_MobileCoinAddress)(nil), // 106: signalservice.PaymentAddress.MobileCoinAddress } var file_SignalService_proto_depIdxs = []int32{ 0, // 0: signalservice.Envelope.type:type_name -> signalservice.Envelope.Type @@ -8549,58 +9083,67 @@ var file_SignalService_proto_depIdxs = []int32{ 90, // 56: signalservice.SyncMessage.callEvent:type_name -> signalservice.SyncMessage.CallEvent 91, // 57: signalservice.SyncMessage.callLinkUpdate:type_name -> signalservice.SyncMessage.CallLinkUpdate 92, // 58: signalservice.SyncMessage.callLogEvent:type_name -> signalservice.SyncMessage.CallLogEvent - 26, // 59: signalservice.GroupContext.type:type_name -> signalservice.GroupContext.Type - 96, // 60: signalservice.GroupContext.members:type_name -> signalservice.GroupContext.Member - 40, // 61: signalservice.GroupContext.avatar:type_name -> signalservice.AttachmentPointer - 97, // 62: signalservice.ContactDetails.avatar:type_name -> signalservice.ContactDetails.Avatar - 38, // 63: signalservice.ContactDetails.verified:type_name -> signalservice.Verified - 99, // 64: signalservice.GroupDetails.members:type_name -> signalservice.GroupDetails.Member - 98, // 65: signalservice.GroupDetails.avatar:type_name -> signalservice.GroupDetails.Avatar - 100, // 66: signalservice.PaymentAddress.mobileCoinAddress:type_name -> signalservice.PaymentAddress.MobileCoinAddress - 31, // 67: signalservice.EditMessage.dataMessage:type_name -> signalservice.DataMessage - 1, // 68: signalservice.CallMessage.Offer.type:type_name -> signalservice.CallMessage.Offer.Type - 2, // 69: signalservice.CallMessage.Hangup.type:type_name -> signalservice.CallMessage.Hangup.Type - 3, // 70: signalservice.CallMessage.Opaque.urgency:type_name -> signalservice.CallMessage.Opaque.Urgency - 64, // 71: signalservice.DataMessage.Quote.attachments:type_name -> signalservice.DataMessage.Quote.QuotedAttachment - 30, // 72: signalservice.DataMessage.Quote.bodyRanges:type_name -> signalservice.BodyRange - 7, // 73: signalservice.DataMessage.Quote.type:type_name -> signalservice.DataMessage.Quote.Type - 65, // 74: signalservice.DataMessage.Contact.name:type_name -> signalservice.DataMessage.Contact.Name - 66, // 75: signalservice.DataMessage.Contact.number:type_name -> signalservice.DataMessage.Contact.Phone - 67, // 76: signalservice.DataMessage.Contact.email:type_name -> signalservice.DataMessage.Contact.Email - 68, // 77: signalservice.DataMessage.Contact.address:type_name -> signalservice.DataMessage.Contact.PostalAddress - 69, // 78: signalservice.DataMessage.Contact.avatar:type_name -> signalservice.DataMessage.Contact.Avatar - 40, // 79: signalservice.DataMessage.Sticker.data:type_name -> signalservice.AttachmentPointer - 71, // 80: signalservice.DataMessage.Payment.notification:type_name -> signalservice.DataMessage.Payment.Notification - 72, // 81: signalservice.DataMessage.Payment.activation:type_name -> signalservice.DataMessage.Payment.Activation - 40, // 82: signalservice.DataMessage.Quote.QuotedAttachment.thumbnail:type_name -> signalservice.AttachmentPointer - 8, // 83: signalservice.DataMessage.Contact.Phone.type:type_name -> signalservice.DataMessage.Contact.Phone.Type - 9, // 84: signalservice.DataMessage.Contact.Email.type:type_name -> signalservice.DataMessage.Contact.Email.Type - 10, // 85: signalservice.DataMessage.Contact.PostalAddress.type:type_name -> signalservice.DataMessage.Contact.PostalAddress.Type - 40, // 86: signalservice.DataMessage.Contact.Avatar.avatar:type_name -> signalservice.AttachmentPointer - 73, // 87: signalservice.DataMessage.Payment.Amount.mobileCoin:type_name -> signalservice.DataMessage.Payment.Amount.MobileCoin - 74, // 88: signalservice.DataMessage.Payment.Notification.mobileCoin:type_name -> signalservice.DataMessage.Payment.Notification.MobileCoin - 11, // 89: signalservice.DataMessage.Payment.Activation.type:type_name -> signalservice.DataMessage.Payment.Activation.Type - 31, // 90: signalservice.SyncMessage.Sent.message:type_name -> signalservice.DataMessage - 93, // 91: signalservice.SyncMessage.Sent.unidentifiedStatus:type_name -> signalservice.SyncMessage.Sent.UnidentifiedDeliveryStatus - 35, // 92: signalservice.SyncMessage.Sent.storyMessage:type_name -> signalservice.StoryMessage - 94, // 93: signalservice.SyncMessage.Sent.storyMessageRecipients:type_name -> signalservice.SyncMessage.Sent.StoryMessageRecipient - 48, // 94: signalservice.SyncMessage.Sent.editMessage:type_name -> signalservice.EditMessage - 40, // 95: signalservice.SyncMessage.Contacts.blob:type_name -> signalservice.AttachmentPointer - 16, // 96: signalservice.SyncMessage.Request.type:type_name -> signalservice.SyncMessage.Request.Type - 17, // 97: signalservice.SyncMessage.StickerPackOperation.type:type_name -> signalservice.SyncMessage.StickerPackOperation.Type - 18, // 98: signalservice.SyncMessage.FetchLatest.type:type_name -> signalservice.SyncMessage.FetchLatest.Type - 19, // 99: signalservice.SyncMessage.MessageRequestResponse.type:type_name -> signalservice.SyncMessage.MessageRequestResponse.Type - 95, // 100: signalservice.SyncMessage.OutgoingPayment.mobileCoin:type_name -> signalservice.SyncMessage.OutgoingPayment.MobileCoin - 20, // 101: signalservice.SyncMessage.CallEvent.type:type_name -> signalservice.SyncMessage.CallEvent.Type - 21, // 102: signalservice.SyncMessage.CallEvent.direction:type_name -> signalservice.SyncMessage.CallEvent.Direction - 22, // 103: signalservice.SyncMessage.CallEvent.event:type_name -> signalservice.SyncMessage.CallEvent.Event - 23, // 104: signalservice.SyncMessage.CallLinkUpdate.type:type_name -> signalservice.SyncMessage.CallLinkUpdate.Type - 24, // 105: signalservice.SyncMessage.CallLogEvent.type:type_name -> signalservice.SyncMessage.CallLogEvent.Type - 106, // [106:106] is the sub-list for method output_type - 106, // [106:106] is the sub-list for method input_type - 106, // [106:106] is the sub-list for extension type_name - 106, // [106:106] is the sub-list for extension extendee - 0, // [0:106] is the sub-list for field type_name + 93, // 59: signalservice.SyncMessage.deleteForMe:type_name -> signalservice.SyncMessage.DeleteForMe + 26, // 60: signalservice.GroupContext.type:type_name -> signalservice.GroupContext.Type + 102, // 61: signalservice.GroupContext.members:type_name -> signalservice.GroupContext.Member + 40, // 62: signalservice.GroupContext.avatar:type_name -> signalservice.AttachmentPointer + 103, // 63: signalservice.ContactDetails.avatar:type_name -> signalservice.ContactDetails.Avatar + 38, // 64: signalservice.ContactDetails.verified:type_name -> signalservice.Verified + 105, // 65: signalservice.GroupDetails.members:type_name -> signalservice.GroupDetails.Member + 104, // 66: signalservice.GroupDetails.avatar:type_name -> signalservice.GroupDetails.Avatar + 106, // 67: signalservice.PaymentAddress.mobileCoinAddress:type_name -> signalservice.PaymentAddress.MobileCoinAddress + 31, // 68: signalservice.EditMessage.dataMessage:type_name -> signalservice.DataMessage + 1, // 69: signalservice.CallMessage.Offer.type:type_name -> signalservice.CallMessage.Offer.Type + 2, // 70: signalservice.CallMessage.Hangup.type:type_name -> signalservice.CallMessage.Hangup.Type + 3, // 71: signalservice.CallMessage.Opaque.urgency:type_name -> signalservice.CallMessage.Opaque.Urgency + 64, // 72: signalservice.DataMessage.Quote.attachments:type_name -> signalservice.DataMessage.Quote.QuotedAttachment + 30, // 73: signalservice.DataMessage.Quote.bodyRanges:type_name -> signalservice.BodyRange + 7, // 74: signalservice.DataMessage.Quote.type:type_name -> signalservice.DataMessage.Quote.Type + 65, // 75: signalservice.DataMessage.Contact.name:type_name -> signalservice.DataMessage.Contact.Name + 66, // 76: signalservice.DataMessage.Contact.number:type_name -> signalservice.DataMessage.Contact.Phone + 67, // 77: signalservice.DataMessage.Contact.email:type_name -> signalservice.DataMessage.Contact.Email + 68, // 78: signalservice.DataMessage.Contact.address:type_name -> signalservice.DataMessage.Contact.PostalAddress + 69, // 79: signalservice.DataMessage.Contact.avatar:type_name -> signalservice.DataMessage.Contact.Avatar + 40, // 80: signalservice.DataMessage.Sticker.data:type_name -> signalservice.AttachmentPointer + 71, // 81: signalservice.DataMessage.Payment.notification:type_name -> signalservice.DataMessage.Payment.Notification + 72, // 82: signalservice.DataMessage.Payment.activation:type_name -> signalservice.DataMessage.Payment.Activation + 40, // 83: signalservice.DataMessage.Quote.QuotedAttachment.thumbnail:type_name -> signalservice.AttachmentPointer + 8, // 84: signalservice.DataMessage.Contact.Phone.type:type_name -> signalservice.DataMessage.Contact.Phone.Type + 9, // 85: signalservice.DataMessage.Contact.Email.type:type_name -> signalservice.DataMessage.Contact.Email.Type + 10, // 86: signalservice.DataMessage.Contact.PostalAddress.type:type_name -> signalservice.DataMessage.Contact.PostalAddress.Type + 40, // 87: signalservice.DataMessage.Contact.Avatar.avatar:type_name -> signalservice.AttachmentPointer + 73, // 88: signalservice.DataMessage.Payment.Amount.mobileCoin:type_name -> signalservice.DataMessage.Payment.Amount.MobileCoin + 74, // 89: signalservice.DataMessage.Payment.Notification.mobileCoin:type_name -> signalservice.DataMessage.Payment.Notification.MobileCoin + 11, // 90: signalservice.DataMessage.Payment.Activation.type:type_name -> signalservice.DataMessage.Payment.Activation.Type + 31, // 91: signalservice.SyncMessage.Sent.message:type_name -> signalservice.DataMessage + 94, // 92: signalservice.SyncMessage.Sent.unidentifiedStatus:type_name -> signalservice.SyncMessage.Sent.UnidentifiedDeliveryStatus + 35, // 93: signalservice.SyncMessage.Sent.storyMessage:type_name -> signalservice.StoryMessage + 95, // 94: signalservice.SyncMessage.Sent.storyMessageRecipients:type_name -> signalservice.SyncMessage.Sent.StoryMessageRecipient + 48, // 95: signalservice.SyncMessage.Sent.editMessage:type_name -> signalservice.EditMessage + 40, // 96: signalservice.SyncMessage.Contacts.blob:type_name -> signalservice.AttachmentPointer + 16, // 97: signalservice.SyncMessage.Request.type:type_name -> signalservice.SyncMessage.Request.Type + 17, // 98: signalservice.SyncMessage.StickerPackOperation.type:type_name -> signalservice.SyncMessage.StickerPackOperation.Type + 18, // 99: signalservice.SyncMessage.FetchLatest.type:type_name -> signalservice.SyncMessage.FetchLatest.Type + 19, // 100: signalservice.SyncMessage.MessageRequestResponse.type:type_name -> signalservice.SyncMessage.MessageRequestResponse.Type + 96, // 101: signalservice.SyncMessage.OutgoingPayment.mobileCoin:type_name -> signalservice.SyncMessage.OutgoingPayment.MobileCoin + 20, // 102: signalservice.SyncMessage.CallEvent.type:type_name -> signalservice.SyncMessage.CallEvent.Type + 21, // 103: signalservice.SyncMessage.CallEvent.direction:type_name -> signalservice.SyncMessage.CallEvent.Direction + 22, // 104: signalservice.SyncMessage.CallEvent.event:type_name -> signalservice.SyncMessage.CallEvent.Event + 23, // 105: signalservice.SyncMessage.CallLinkUpdate.type:type_name -> signalservice.SyncMessage.CallLinkUpdate.Type + 24, // 106: signalservice.SyncMessage.CallLogEvent.type:type_name -> signalservice.SyncMessage.CallLogEvent.Type + 99, // 107: signalservice.SyncMessage.DeleteForMe.messageDeletes:type_name -> signalservice.SyncMessage.DeleteForMe.MessageDeletes + 100, // 108: signalservice.SyncMessage.DeleteForMe.conversationDeletes:type_name -> signalservice.SyncMessage.DeleteForMe.ConversationDelete + 101, // 109: signalservice.SyncMessage.DeleteForMe.localOnlyConversationDeletes:type_name -> signalservice.SyncMessage.DeleteForMe.LocalOnlyConversationDelete + 97, // 110: signalservice.SyncMessage.DeleteForMe.MessageDeletes.conversation:type_name -> signalservice.SyncMessage.DeleteForMe.ConversationIdentifier + 98, // 111: signalservice.SyncMessage.DeleteForMe.MessageDeletes.messages:type_name -> signalservice.SyncMessage.DeleteForMe.AddressableMessage + 97, // 112: signalservice.SyncMessage.DeleteForMe.ConversationDelete.conversation:type_name -> signalservice.SyncMessage.DeleteForMe.ConversationIdentifier + 98, // 113: signalservice.SyncMessage.DeleteForMe.ConversationDelete.mostRecentMessages:type_name -> signalservice.SyncMessage.DeleteForMe.AddressableMessage + 97, // 114: signalservice.SyncMessage.DeleteForMe.LocalOnlyConversationDelete.conversation:type_name -> signalservice.SyncMessage.DeleteForMe.ConversationIdentifier + 115, // [115:115] is the sub-list for method output_type + 115, // [115:115] is the sub-list for method input_type + 115, // [115:115] is the sub-list for extension type_name + 115, // [115:115] is the sub-list for extension extendee + 0, // [0:115] is the sub-list for field type_name } func init() { file_SignalService_proto_init() } @@ -9402,7 +9945,7 @@ func file_SignalService_proto_init() { } } file_SignalService_proto_msgTypes[66].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*SyncMessage_Sent_UnidentifiedDeliveryStatus); i { + switch v := v.(*SyncMessage_DeleteForMe); i { case 0: return &v.state case 1: @@ -9414,7 +9957,7 @@ func file_SignalService_proto_init() { } } file_SignalService_proto_msgTypes[67].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*SyncMessage_Sent_StoryMessageRecipient); i { + switch v := v.(*SyncMessage_Sent_UnidentifiedDeliveryStatus); i { case 0: return &v.state case 1: @@ -9426,7 +9969,7 @@ func file_SignalService_proto_init() { } } file_SignalService_proto_msgTypes[68].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*SyncMessage_OutgoingPayment_MobileCoin); i { + switch v := v.(*SyncMessage_Sent_StoryMessageRecipient); i { case 0: return &v.state case 1: @@ -9438,7 +9981,7 @@ func file_SignalService_proto_init() { } } file_SignalService_proto_msgTypes[69].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*GroupContext_Member); i { + switch v := v.(*SyncMessage_OutgoingPayment_MobileCoin); i { case 0: return &v.state case 1: @@ -9450,7 +9993,7 @@ func file_SignalService_proto_init() { } } file_SignalService_proto_msgTypes[70].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ContactDetails_Avatar); i { + switch v := v.(*SyncMessage_DeleteForMe_ConversationIdentifier); i { case 0: return &v.state case 1: @@ -9462,7 +10005,7 @@ func file_SignalService_proto_init() { } } file_SignalService_proto_msgTypes[71].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*GroupDetails_Avatar); i { + switch v := v.(*SyncMessage_DeleteForMe_AddressableMessage); i { case 0: return &v.state case 1: @@ -9474,7 +10017,7 @@ func file_SignalService_proto_init() { } } file_SignalService_proto_msgTypes[72].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*GroupDetails_Member); i { + switch v := v.(*SyncMessage_DeleteForMe_MessageDeletes); i { case 0: return &v.state case 1: @@ -9486,6 +10029,78 @@ func file_SignalService_proto_init() { } } file_SignalService_proto_msgTypes[73].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*SyncMessage_DeleteForMe_ConversationDelete); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_SignalService_proto_msgTypes[74].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*SyncMessage_DeleteForMe_LocalOnlyConversationDelete); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_SignalService_proto_msgTypes[75].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GroupContext_Member); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_SignalService_proto_msgTypes[76].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ContactDetails_Avatar); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_SignalService_proto_msgTypes[77].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GroupDetails_Avatar); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_SignalService_proto_msgTypes[78].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GroupDetails_Member); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_SignalService_proto_msgTypes[79].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*PaymentAddress_MobileCoinAddress); i { case 0: return &v.state @@ -9530,13 +10145,22 @@ func file_SignalService_proto_init() { file_SignalService_proto_msgTypes[61].OneofWrappers = []interface{}{ (*SyncMessage_OutgoingPayment_MobileCoin_)(nil), } + file_SignalService_proto_msgTypes[70].OneofWrappers = []interface{}{ + (*SyncMessage_DeleteForMe_ConversationIdentifier_ThreadAci)(nil), + (*SyncMessage_DeleteForMe_ConversationIdentifier_ThreadGroupId)(nil), + (*SyncMessage_DeleteForMe_ConversationIdentifier_ThreadE164)(nil), + } + file_SignalService_proto_msgTypes[71].OneofWrappers = []interface{}{ + (*SyncMessage_DeleteForMe_AddressableMessage_AuthorAci)(nil), + (*SyncMessage_DeleteForMe_AddressableMessage_AuthorE164)(nil), + } type x struct{} out := protoimpl.TypeBuilder{ File: protoimpl.DescBuilder{ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_SignalService_proto_rawDesc, NumEnums: 27, - NumMessages: 74, + NumMessages: 80, NumExtensions: 0, NumServices: 0, }, diff --git a/pkg/signalmeow/protobuf/SignalService.proto b/pkg/signalmeow/protobuf/SignalService.proto index 2cf83ba..dceaf0a 100644 --- a/pkg/signalmeow/protobuf/SignalService.proto +++ b/pkg/signalmeow/protobuf/SignalService.proto @@ -637,12 +637,57 @@ message SyncMessage { message CallLogEvent { enum Type { - CLEAR = 0; - MARKED_AS_READ = 1; + CLEAR = 0; + MARKED_AS_READ = 1; + MARKED_AS_READ_IN_CONVERSATION = 2; } - optional Type type = 1; - optional uint64 timestamp = 2; + optional Type type = 1; + optional uint64 timestamp = 2; + /* Data identifying a conversation. The service ID for 1:1, the group ID for + * group, or the room ID for an ad-hoc call. See also + * `CallEvent/conversationId`. */ + optional bytes conversationId = 3; + /* An identifier for a call. Generated directly for 1:1, or derived from + * the era ID for group and ad-hoc calls. See also `CallEvent/callId`. */ + optional uint64 callId = 4; + } + + message DeleteForMe { + message ConversationIdentifier { + oneof identifier { + string threadAci = 1; + bytes threadGroupId = 2; + string threadE164 = 3; + } + } + + message AddressableMessage { + oneof author { + string authorAci = 1; + string authorE164 = 2; + } + optional uint64 sentTimestamp = 3; + } + + message MessageDeletes { + optional ConversationIdentifier conversation = 1; + repeated AddressableMessage messages = 2; + } + + message ConversationDelete { + optional ConversationIdentifier conversation = 1; + repeated AddressableMessage mostRecentMessages = 2; + optional bool isFullDelete = 3; + } + + message LocalOnlyConversationDelete { + optional ConversationIdentifier conversation = 1; + } + + repeated MessageDeletes messageDeletes = 1; + repeated ConversationDelete conversationDeletes = 2; + repeated LocalOnlyConversationDelete localOnlyConversationDeletes = 3; } optional Sent sent = 1; @@ -666,6 +711,7 @@ message SyncMessage { optional CallEvent callEvent = 19; optional CallLinkUpdate callLinkUpdate = 20; optional CallLogEvent callLogEvent = 21; + optional DeleteForMe deleteForMe = 22; } message AttachmentPointer { @@ -741,7 +787,7 @@ message ContactDetails { optional string color = 4; optional Verified verified = 5; optional bytes profileKey = 6; - optional bool blocked = 7; + reserved /*blocked*/ 7; optional uint32 expireTimer = 8; optional uint32 inboxPosition = 10; optional bool archived = 11; diff --git a/pkg/signalmeow/protobuf/StickerResources.pb.go b/pkg/signalmeow/protobuf/StickerResources.pb.go index 34f48be..e9c864a 100644 --- a/pkg/signalmeow/protobuf/StickerResources.pb.go +++ b/pkg/signalmeow/protobuf/StickerResources.pb.go @@ -5,7 +5,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.31.0 +// protoc-gen-go v1.34.1 // protoc v3.21.12 // source: StickerResources.proto diff --git a/pkg/signalmeow/protobuf/StorageService.pb.go b/pkg/signalmeow/protobuf/StorageService.pb.go index f4894ec..aeb2cbd 100644 --- a/pkg/signalmeow/protobuf/StorageService.pb.go +++ b/pkg/signalmeow/protobuf/StorageService.pb.go @@ -5,7 +5,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.31.0 +// protoc-gen-go v1.34.1 // protoc v3.21.12 // source: StorageService.proto @@ -832,7 +832,9 @@ type ContactRecord struct { SystemFamilyName string `protobuf:"bytes,18,opt,name=systemFamilyName,proto3" json:"systemFamilyName,omitempty"` SystemNickname string `protobuf:"bytes,19,opt,name=systemNickname,proto3" json:"systemNickname,omitempty"` Hidden bool `protobuf:"varint,20,opt,name=hidden,proto3" json:"hidden,omitempty"` - PniSignatureVerified bool `protobuf:"varint,21,opt,name=pniSignatureVerified,proto3" json:"pniSignatureVerified,omitempty"` // NEXT ID: 22 + PniSignatureVerified bool `protobuf:"varint,21,opt,name=pniSignatureVerified,proto3" json:"pniSignatureVerified,omitempty"` + Nickname *ContactRecord_Name `protobuf:"bytes,22,opt,name=nickname,proto3" json:"nickname,omitempty"` + Note string `protobuf:"bytes,23,opt,name=note,proto3" json:"note,omitempty"` // NEXT ID: 24 } func (x *ContactRecord) Reset() { @@ -1014,6 +1016,20 @@ func (x *ContactRecord) GetPniSignatureVerified() bool { return false } +func (x *ContactRecord) GetNickname() *ContactRecord_Name { + if x != nil { + return x.Nickname + } + return nil +} + +func (x *ContactRecord) GetNote() string { + if x != nil { + return x.Note + } + return "" +} + type GroupV1Record struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -1704,6 +1720,61 @@ func (x *ManifestRecord_Identifier) GetType() ManifestRecord_Identifier_Type { return ManifestRecord_Identifier_UNKNOWN } +type ContactRecord_Name struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Given string `protobuf:"bytes,1,opt,name=given,proto3" json:"given,omitempty"` + Family string `protobuf:"bytes,2,opt,name=family,proto3" json:"family,omitempty"` +} + +func (x *ContactRecord_Name) Reset() { + *x = ContactRecord_Name{} + if protoimpl.UnsafeEnabled { + mi := &file_StorageService_proto_msgTypes[14] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ContactRecord_Name) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ContactRecord_Name) ProtoMessage() {} + +func (x *ContactRecord_Name) ProtoReflect() protoreflect.Message { + mi := &file_StorageService_proto_msgTypes[14] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ContactRecord_Name.ProtoReflect.Descriptor instead. +func (*ContactRecord_Name) Descriptor() ([]byte, []int) { + return file_StorageService_proto_rawDescGZIP(), []int{7, 0} +} + +func (x *ContactRecord_Name) GetGiven() string { + if x != nil { + return x.Given + } + return "" +} + +func (x *ContactRecord_Name) GetFamily() string { + if x != nil { + return x.Family + } + return "" +} + type AccountRecord_PinnedConversation struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -1720,7 +1791,7 @@ type AccountRecord_PinnedConversation struct { func (x *AccountRecord_PinnedConversation) Reset() { *x = AccountRecord_PinnedConversation{} if protoimpl.UnsafeEnabled { - mi := &file_StorageService_proto_msgTypes[14] + mi := &file_StorageService_proto_msgTypes[15] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1733,7 +1804,7 @@ func (x *AccountRecord_PinnedConversation) String() string { func (*AccountRecord_PinnedConversation) ProtoMessage() {} func (x *AccountRecord_PinnedConversation) ProtoReflect() protoreflect.Message { - mi := &file_StorageService_proto_msgTypes[14] + mi := &file_StorageService_proto_msgTypes[15] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1814,7 +1885,7 @@ type AccountRecord_UsernameLink struct { func (x *AccountRecord_UsernameLink) Reset() { *x = AccountRecord_UsernameLink{} if protoimpl.UnsafeEnabled { - mi := &file_StorageService_proto_msgTypes[15] + mi := &file_StorageService_proto_msgTypes[16] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1827,7 +1898,7 @@ func (x *AccountRecord_UsernameLink) String() string { func (*AccountRecord_UsernameLink) ProtoMessage() {} func (x *AccountRecord_UsernameLink) ProtoReflect() protoreflect.Message { - mi := &file_StorageService_proto_msgTypes[15] + mi := &file_StorageService_proto_msgTypes[16] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1876,7 +1947,7 @@ type AccountRecord_PinnedConversation_Contact struct { func (x *AccountRecord_PinnedConversation_Contact) Reset() { *x = AccountRecord_PinnedConversation_Contact{} if protoimpl.UnsafeEnabled { - mi := &file_StorageService_proto_msgTypes[16] + mi := &file_StorageService_proto_msgTypes[17] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1889,7 +1960,7 @@ func (x *AccountRecord_PinnedConversation_Contact) String() string { func (*AccountRecord_PinnedConversation_Contact) ProtoMessage() {} func (x *AccountRecord_PinnedConversation_Contact) ProtoReflect() protoreflect.Message { - mi := &file_StorageService_proto_msgTypes[16] + mi := &file_StorageService_proto_msgTypes[17] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1996,7 +2067,7 @@ var file_StorageService_proto_rawDesc = []byte{ 0x69, 0x6f, 0x6e, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x48, 0x00, 0x52, 0x15, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x44, 0x69, 0x73, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x4c, 0x69, 0x73, 0x74, 0x42, 0x08, 0x0a, 0x06, 0x72, 0x65, 0x63, 0x6f, 0x72, 0x64, - 0x22, 0xc1, 0x06, 0x0a, 0x0d, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x63, 0x74, 0x52, 0x65, 0x63, 0x6f, + 0x22, 0xca, 0x07, 0x0a, 0x0d, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x63, 0x74, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x12, 0x10, 0x0a, 0x03, 0x61, 0x63, 0x69, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x61, 0x63, 0x69, 0x12, 0x12, 0x0a, 0x04, 0x65, 0x31, 0x36, 0x34, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x65, 0x31, 0x36, 0x34, 0x12, 0x10, 0x0a, 0x03, 0x70, 0x6e, 0x69, 0x18, @@ -2044,226 +2115,235 @@ var file_StorageService_proto_rawDesc = []byte{ 0x64, 0x64, 0x65, 0x6e, 0x12, 0x32, 0x0a, 0x14, 0x70, 0x6e, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x56, 0x65, 0x72, 0x69, 0x66, 0x69, 0x65, 0x64, 0x18, 0x15, 0x20, 0x01, 0x28, 0x08, 0x52, 0x14, 0x70, 0x6e, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, - 0x56, 0x65, 0x72, 0x69, 0x66, 0x69, 0x65, 0x64, 0x22, 0x3a, 0x0a, 0x0d, 0x49, 0x64, 0x65, 0x6e, - 0x74, 0x69, 0x74, 0x79, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x0b, 0x0a, 0x07, 0x44, 0x45, 0x46, - 0x41, 0x55, 0x4c, 0x54, 0x10, 0x00, 0x12, 0x0c, 0x0a, 0x08, 0x56, 0x45, 0x52, 0x49, 0x46, 0x49, - 0x45, 0x44, 0x10, 0x01, 0x12, 0x0e, 0x0a, 0x0a, 0x55, 0x4e, 0x56, 0x45, 0x52, 0x49, 0x46, 0x49, - 0x45, 0x44, 0x10, 0x02, 0x22, 0xcd, 0x01, 0x0a, 0x0d, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x56, 0x31, - 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x0c, 0x52, 0x02, 0x69, 0x64, 0x12, 0x18, 0x0a, 0x07, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x65, - 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x65, 0x64, - 0x12, 0x20, 0x0a, 0x0b, 0x77, 0x68, 0x69, 0x74, 0x65, 0x6c, 0x69, 0x73, 0x74, 0x65, 0x64, 0x18, - 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, 0x77, 0x68, 0x69, 0x74, 0x65, 0x6c, 0x69, 0x73, 0x74, - 0x65, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x61, 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, 0x64, 0x18, 0x04, - 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x61, 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, 0x64, 0x12, 0x22, - 0x0a, 0x0c, 0x6d, 0x61, 0x72, 0x6b, 0x65, 0x64, 0x55, 0x6e, 0x72, 0x65, 0x61, 0x64, 0x18, 0x05, - 0x20, 0x01, 0x28, 0x08, 0x52, 0x0c, 0x6d, 0x61, 0x72, 0x6b, 0x65, 0x64, 0x55, 0x6e, 0x72, 0x65, - 0x61, 0x64, 0x12, 0x30, 0x0a, 0x13, 0x6d, 0x75, 0x74, 0x65, 0x64, 0x55, 0x6e, 0x74, 0x69, 0x6c, - 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x06, 0x20, 0x01, 0x28, 0x04, 0x52, - 0x13, 0x6d, 0x75, 0x74, 0x65, 0x64, 0x55, 0x6e, 0x74, 0x69, 0x6c, 0x54, 0x69, 0x6d, 0x65, 0x73, - 0x74, 0x61, 0x6d, 0x70, 0x22, 0xce, 0x03, 0x0a, 0x0d, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x56, 0x32, - 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x12, 0x1c, 0x0a, 0x09, 0x6d, 0x61, 0x73, 0x74, 0x65, 0x72, - 0x4b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x6d, 0x61, 0x73, 0x74, 0x65, - 0x72, 0x4b, 0x65, 0x79, 0x12, 0x18, 0x0a, 0x07, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x65, 0x64, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x65, 0x64, 0x12, 0x20, - 0x0a, 0x0b, 0x77, 0x68, 0x69, 0x74, 0x65, 0x6c, 0x69, 0x73, 0x74, 0x65, 0x64, 0x18, 0x03, 0x20, - 0x01, 0x28, 0x08, 0x52, 0x0b, 0x77, 0x68, 0x69, 0x74, 0x65, 0x6c, 0x69, 0x73, 0x74, 0x65, 0x64, - 0x12, 0x1a, 0x0a, 0x08, 0x61, 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, 0x64, 0x18, 0x04, 0x20, 0x01, - 0x28, 0x08, 0x52, 0x08, 0x61, 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, 0x64, 0x12, 0x22, 0x0a, 0x0c, - 0x6d, 0x61, 0x72, 0x6b, 0x65, 0x64, 0x55, 0x6e, 0x72, 0x65, 0x61, 0x64, 0x18, 0x05, 0x20, 0x01, - 0x28, 0x08, 0x52, 0x0c, 0x6d, 0x61, 0x72, 0x6b, 0x65, 0x64, 0x55, 0x6e, 0x72, 0x65, 0x61, 0x64, - 0x12, 0x30, 0x0a, 0x13, 0x6d, 0x75, 0x74, 0x65, 0x64, 0x55, 0x6e, 0x74, 0x69, 0x6c, 0x54, 0x69, - 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x06, 0x20, 0x01, 0x28, 0x04, 0x52, 0x13, 0x6d, + 0x56, 0x65, 0x72, 0x69, 0x66, 0x69, 0x65, 0x64, 0x12, 0x3d, 0x0a, 0x08, 0x6e, 0x69, 0x63, 0x6b, + 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x16, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x73, 0x69, 0x67, + 0x6e, 0x61, 0x6c, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x61, + 0x63, 0x74, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x2e, 0x4e, 0x61, 0x6d, 0x65, 0x52, 0x08, 0x6e, + 0x69, 0x63, 0x6b, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x6f, 0x74, 0x65, 0x18, + 0x17, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x6f, 0x74, 0x65, 0x1a, 0x34, 0x0a, 0x04, 0x4e, + 0x61, 0x6d, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x67, 0x69, 0x76, 0x65, 0x6e, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x05, 0x67, 0x69, 0x76, 0x65, 0x6e, 0x12, 0x16, 0x0a, 0x06, 0x66, 0x61, 0x6d, + 0x69, 0x6c, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x66, 0x61, 0x6d, 0x69, 0x6c, + 0x79, 0x22, 0x3a, 0x0a, 0x0d, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x53, 0x74, 0x61, + 0x74, 0x65, 0x12, 0x0b, 0x0a, 0x07, 0x44, 0x45, 0x46, 0x41, 0x55, 0x4c, 0x54, 0x10, 0x00, 0x12, + 0x0c, 0x0a, 0x08, 0x56, 0x45, 0x52, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x01, 0x12, 0x0e, 0x0a, + 0x0a, 0x55, 0x4e, 0x56, 0x45, 0x52, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x02, 0x22, 0xcd, 0x01, + 0x0a, 0x0d, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x56, 0x31, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x12, + 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x02, 0x69, 0x64, 0x12, + 0x18, 0x0a, 0x07, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x65, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, + 0x52, 0x07, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x65, 0x64, 0x12, 0x20, 0x0a, 0x0b, 0x77, 0x68, 0x69, + 0x74, 0x65, 0x6c, 0x69, 0x73, 0x74, 0x65, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, + 0x77, 0x68, 0x69, 0x74, 0x65, 0x6c, 0x69, 0x73, 0x74, 0x65, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x61, + 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x61, + 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, 0x64, 0x12, 0x22, 0x0a, 0x0c, 0x6d, 0x61, 0x72, 0x6b, 0x65, + 0x64, 0x55, 0x6e, 0x72, 0x65, 0x61, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0c, 0x6d, + 0x61, 0x72, 0x6b, 0x65, 0x64, 0x55, 0x6e, 0x72, 0x65, 0x61, 0x64, 0x12, 0x30, 0x0a, 0x13, 0x6d, 0x75, 0x74, 0x65, 0x64, 0x55, 0x6e, 0x74, 0x69, 0x6c, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, - 0x6d, 0x70, 0x12, 0x42, 0x0a, 0x1c, 0x64, 0x6f, 0x6e, 0x74, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x79, - 0x46, 0x6f, 0x72, 0x4d, 0x65, 0x6e, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x49, 0x66, 0x4d, 0x75, 0x74, - 0x65, 0x64, 0x18, 0x07, 0x20, 0x01, 0x28, 0x08, 0x52, 0x1c, 0x64, 0x6f, 0x6e, 0x74, 0x4e, 0x6f, - 0x74, 0x69, 0x66, 0x79, 0x46, 0x6f, 0x72, 0x4d, 0x65, 0x6e, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x49, - 0x66, 0x4d, 0x75, 0x74, 0x65, 0x64, 0x12, 0x1c, 0x0a, 0x09, 0x68, 0x69, 0x64, 0x65, 0x53, 0x74, - 0x6f, 0x72, 0x79, 0x18, 0x08, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x68, 0x69, 0x64, 0x65, 0x53, - 0x74, 0x6f, 0x72, 0x79, 0x12, 0x50, 0x0a, 0x0d, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x53, 0x65, 0x6e, - 0x64, 0x4d, 0x6f, 0x64, 0x65, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x2a, 0x2e, 0x73, 0x69, - 0x67, 0x6e, 0x61, 0x6c, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x47, 0x72, 0x6f, 0x75, - 0x70, 0x56, 0x32, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x2e, 0x53, 0x74, 0x6f, 0x72, 0x79, 0x53, - 0x65, 0x6e, 0x64, 0x4d, 0x6f, 0x64, 0x65, 0x52, 0x0d, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x53, 0x65, - 0x6e, 0x64, 0x4d, 0x6f, 0x64, 0x65, 0x22, 0x37, 0x0a, 0x0d, 0x53, 0x74, 0x6f, 0x72, 0x79, 0x53, - 0x65, 0x6e, 0x64, 0x4d, 0x6f, 0x64, 0x65, 0x12, 0x0b, 0x0a, 0x07, 0x44, 0x45, 0x46, 0x41, 0x55, - 0x4c, 0x54, 0x10, 0x00, 0x12, 0x0c, 0x0a, 0x08, 0x44, 0x49, 0x53, 0x41, 0x42, 0x4c, 0x45, 0x44, - 0x10, 0x01, 0x12, 0x0b, 0x0a, 0x07, 0x45, 0x4e, 0x41, 0x42, 0x4c, 0x45, 0x44, 0x10, 0x02, 0x4a, - 0x04, 0x08, 0x09, 0x10, 0x0a, 0x22, 0x3e, 0x0a, 0x08, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, - 0x73, 0x12, 0x18, 0x0a, 0x07, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x08, 0x52, 0x07, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x12, 0x18, 0x0a, 0x07, 0x65, - 0x6e, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x65, 0x6e, - 0x74, 0x72, 0x6f, 0x70, 0x79, 0x22, 0x9a, 0x12, 0x0a, 0x0d, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, - 0x74, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x12, 0x1e, 0x0a, 0x0a, 0x70, 0x72, 0x6f, 0x66, 0x69, - 0x6c, 0x65, 0x4b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0a, 0x70, 0x72, 0x6f, - 0x66, 0x69, 0x6c, 0x65, 0x4b, 0x65, 0x79, 0x12, 0x1c, 0x0a, 0x09, 0x67, 0x69, 0x76, 0x65, 0x6e, - 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x67, 0x69, 0x76, 0x65, - 0x6e, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1e, 0x0a, 0x0a, 0x66, 0x61, 0x6d, 0x69, 0x6c, 0x79, 0x4e, - 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x66, 0x61, 0x6d, 0x69, 0x6c, - 0x79, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x24, 0x0a, 0x0d, 0x61, 0x76, 0x61, 0x74, 0x61, 0x72, 0x55, - 0x72, 0x6c, 0x50, 0x61, 0x74, 0x68, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x61, 0x76, - 0x61, 0x74, 0x61, 0x72, 0x55, 0x72, 0x6c, 0x50, 0x61, 0x74, 0x68, 0x12, 0x2e, 0x0a, 0x12, 0x6e, - 0x6f, 0x74, 0x65, 0x54, 0x6f, 0x53, 0x65, 0x6c, 0x66, 0x41, 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, - 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x12, 0x6e, 0x6f, 0x74, 0x65, 0x54, 0x6f, 0x53, - 0x65, 0x6c, 0x66, 0x41, 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, 0x64, 0x12, 0x22, 0x0a, 0x0c, 0x72, - 0x65, 0x61, 0x64, 0x52, 0x65, 0x63, 0x65, 0x69, 0x70, 0x74, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, - 0x08, 0x52, 0x0c, 0x72, 0x65, 0x61, 0x64, 0x52, 0x65, 0x63, 0x65, 0x69, 0x70, 0x74, 0x73, 0x12, - 0x36, 0x0a, 0x16, 0x73, 0x65, 0x61, 0x6c, 0x65, 0x64, 0x53, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x49, - 0x6e, 0x64, 0x69, 0x63, 0x61, 0x74, 0x6f, 0x72, 0x73, 0x18, 0x07, 0x20, 0x01, 0x28, 0x08, 0x52, - 0x16, 0x73, 0x65, 0x61, 0x6c, 0x65, 0x64, 0x53, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x49, 0x6e, 0x64, - 0x69, 0x63, 0x61, 0x74, 0x6f, 0x72, 0x73, 0x12, 0x2a, 0x0a, 0x10, 0x74, 0x79, 0x70, 0x69, 0x6e, - 0x67, 0x49, 0x6e, 0x64, 0x69, 0x63, 0x61, 0x74, 0x6f, 0x72, 0x73, 0x18, 0x08, 0x20, 0x01, 0x28, - 0x08, 0x52, 0x10, 0x74, 0x79, 0x70, 0x69, 0x6e, 0x67, 0x49, 0x6e, 0x64, 0x69, 0x63, 0x61, 0x74, - 0x6f, 0x72, 0x73, 0x12, 0x36, 0x0a, 0x16, 0x6e, 0x6f, 0x74, 0x65, 0x54, 0x6f, 0x53, 0x65, 0x6c, - 0x66, 0x4d, 0x61, 0x72, 0x6b, 0x65, 0x64, 0x55, 0x6e, 0x72, 0x65, 0x61, 0x64, 0x18, 0x0a, 0x20, - 0x01, 0x28, 0x08, 0x52, 0x16, 0x6e, 0x6f, 0x74, 0x65, 0x54, 0x6f, 0x53, 0x65, 0x6c, 0x66, 0x4d, - 0x61, 0x72, 0x6b, 0x65, 0x64, 0x55, 0x6e, 0x72, 0x65, 0x61, 0x64, 0x12, 0x22, 0x0a, 0x0c, 0x6c, - 0x69, 0x6e, 0x6b, 0x50, 0x72, 0x65, 0x76, 0x69, 0x65, 0x77, 0x73, 0x18, 0x0b, 0x20, 0x01, 0x28, - 0x08, 0x52, 0x0c, 0x6c, 0x69, 0x6e, 0x6b, 0x50, 0x72, 0x65, 0x76, 0x69, 0x65, 0x77, 0x73, 0x12, - 0x6b, 0x0a, 0x16, 0x70, 0x68, 0x6f, 0x6e, 0x65, 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x53, 0x68, - 0x61, 0x72, 0x69, 0x6e, 0x67, 0x4d, 0x6f, 0x64, 0x65, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x0e, 0x32, - 0x33, 0x2e, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x6c, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, - 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x2e, 0x50, 0x68, - 0x6f, 0x6e, 0x65, 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x53, 0x68, 0x61, 0x72, 0x69, 0x6e, 0x67, - 0x4d, 0x6f, 0x64, 0x65, 0x52, 0x16, 0x70, 0x68, 0x6f, 0x6e, 0x65, 0x4e, 0x75, 0x6d, 0x62, 0x65, - 0x72, 0x53, 0x68, 0x61, 0x72, 0x69, 0x6e, 0x67, 0x4d, 0x6f, 0x64, 0x65, 0x12, 0x30, 0x0a, 0x13, - 0x75, 0x6e, 0x6c, 0x69, 0x73, 0x74, 0x65, 0x64, 0x50, 0x68, 0x6f, 0x6e, 0x65, 0x4e, 0x75, 0x6d, - 0x62, 0x65, 0x72, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x08, 0x52, 0x13, 0x75, 0x6e, 0x6c, 0x69, 0x73, - 0x74, 0x65, 0x64, 0x50, 0x68, 0x6f, 0x6e, 0x65, 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x12, 0x61, - 0x0a, 0x13, 0x70, 0x69, 0x6e, 0x6e, 0x65, 0x64, 0x43, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x0e, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2f, 0x2e, 0x73, 0x69, - 0x67, 0x6e, 0x61, 0x6c, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x41, 0x63, 0x63, 0x6f, - 0x75, 0x6e, 0x74, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x2e, 0x50, 0x69, 0x6e, 0x6e, 0x65, 0x64, - 0x43, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x13, 0x70, 0x69, - 0x6e, 0x6e, 0x65, 0x64, 0x43, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x73, 0x12, 0x32, 0x0a, 0x14, 0x70, 0x72, 0x65, 0x66, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x74, 0x61, - 0x63, 0x74, 0x41, 0x76, 0x61, 0x74, 0x61, 0x72, 0x73, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x08, 0x52, - 0x14, 0x70, 0x72, 0x65, 0x66, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x63, 0x74, 0x41, 0x76, - 0x61, 0x74, 0x61, 0x72, 0x73, 0x12, 0x33, 0x0a, 0x08, 0x70, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, - 0x73, 0x18, 0x10, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x6c, - 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x73, - 0x52, 0x08, 0x70, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x12, 0x32, 0x0a, 0x14, 0x75, 0x6e, - 0x69, 0x76, 0x65, 0x72, 0x73, 0x61, 0x6c, 0x45, 0x78, 0x70, 0x69, 0x72, 0x65, 0x54, 0x69, 0x6d, - 0x65, 0x72, 0x18, 0x11, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x14, 0x75, 0x6e, 0x69, 0x76, 0x65, 0x72, - 0x73, 0x61, 0x6c, 0x45, 0x78, 0x70, 0x69, 0x72, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x72, 0x12, 0x28, - 0x0a, 0x0f, 0x70, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x53, 0x65, 0x6e, 0x64, 0x73, 0x53, 0x6d, - 0x73, 0x18, 0x12, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0f, 0x70, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, - 0x53, 0x65, 0x6e, 0x64, 0x73, 0x53, 0x6d, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x65, 0x31, 0x36, 0x34, - 0x18, 0x13, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x65, 0x31, 0x36, 0x34, 0x12, 0x36, 0x0a, 0x16, - 0x70, 0x72, 0x65, 0x66, 0x65, 0x72, 0x72, 0x65, 0x64, 0x52, 0x65, 0x61, 0x63, 0x74, 0x69, 0x6f, - 0x6e, 0x45, 0x6d, 0x6f, 0x6a, 0x69, 0x18, 0x14, 0x20, 0x03, 0x28, 0x09, 0x52, 0x16, 0x70, 0x72, - 0x65, 0x66, 0x65, 0x72, 0x72, 0x65, 0x64, 0x52, 0x65, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x45, - 0x6d, 0x6f, 0x6a, 0x69, 0x12, 0x22, 0x0a, 0x0c, 0x73, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, - 0x65, 0x72, 0x49, 0x64, 0x18, 0x15, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0c, 0x73, 0x75, 0x62, 0x73, - 0x63, 0x72, 0x69, 0x62, 0x65, 0x72, 0x49, 0x64, 0x12, 0x36, 0x0a, 0x16, 0x73, 0x75, 0x62, 0x73, - 0x63, 0x72, 0x69, 0x62, 0x65, 0x72, 0x43, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x63, 0x79, 0x43, 0x6f, - 0x64, 0x65, 0x18, 0x16, 0x20, 0x01, 0x28, 0x09, 0x52, 0x16, 0x73, 0x75, 0x62, 0x73, 0x63, 0x72, - 0x69, 0x62, 0x65, 0x72, 0x43, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x63, 0x79, 0x43, 0x6f, 0x64, 0x65, - 0x12, 0x36, 0x0a, 0x16, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x42, 0x61, 0x64, 0x67, 0x65, - 0x73, 0x4f, 0x6e, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x18, 0x17, 0x20, 0x01, 0x28, 0x08, - 0x52, 0x16, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x42, 0x61, 0x64, 0x67, 0x65, 0x73, 0x4f, - 0x6e, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x12, 0x44, 0x0a, 0x1d, 0x73, 0x75, 0x62, 0x73, - 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x4d, 0x61, 0x6e, 0x75, 0x61, 0x6c, 0x6c, 0x79, - 0x43, 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x6c, 0x65, 0x64, 0x18, 0x18, 0x20, 0x01, 0x28, 0x08, 0x52, - 0x1d, 0x73, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x4d, 0x61, 0x6e, - 0x75, 0x61, 0x6c, 0x6c, 0x79, 0x43, 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x6c, 0x65, 0x64, 0x12, 0x36, - 0x0a, 0x16, 0x6b, 0x65, 0x65, 0x70, 0x4d, 0x75, 0x74, 0x65, 0x64, 0x43, 0x68, 0x61, 0x74, 0x73, - 0x41, 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, 0x64, 0x18, 0x19, 0x20, 0x01, 0x28, 0x08, 0x52, 0x16, - 0x6b, 0x65, 0x65, 0x70, 0x4d, 0x75, 0x74, 0x65, 0x64, 0x43, 0x68, 0x61, 0x74, 0x73, 0x41, 0x72, - 0x63, 0x68, 0x69, 0x76, 0x65, 0x64, 0x12, 0x36, 0x0a, 0x16, 0x68, 0x61, 0x73, 0x53, 0x65, 0x74, - 0x4d, 0x79, 0x53, 0x74, 0x6f, 0x72, 0x69, 0x65, 0x73, 0x50, 0x72, 0x69, 0x76, 0x61, 0x63, 0x79, - 0x18, 0x1a, 0x20, 0x01, 0x28, 0x08, 0x52, 0x16, 0x68, 0x61, 0x73, 0x53, 0x65, 0x74, 0x4d, 0x79, - 0x53, 0x74, 0x6f, 0x72, 0x69, 0x65, 0x73, 0x50, 0x72, 0x69, 0x76, 0x61, 0x63, 0x79, 0x12, 0x3a, - 0x0a, 0x18, 0x68, 0x61, 0x73, 0x56, 0x69, 0x65, 0x77, 0x65, 0x64, 0x4f, 0x6e, 0x62, 0x6f, 0x61, - 0x72, 0x64, 0x69, 0x6e, 0x67, 0x53, 0x74, 0x6f, 0x72, 0x79, 0x18, 0x1b, 0x20, 0x01, 0x28, 0x08, - 0x52, 0x18, 0x68, 0x61, 0x73, 0x56, 0x69, 0x65, 0x77, 0x65, 0x64, 0x4f, 0x6e, 0x62, 0x6f, 0x61, - 0x72, 0x64, 0x69, 0x6e, 0x67, 0x53, 0x74, 0x6f, 0x72, 0x79, 0x12, 0x28, 0x0a, 0x0f, 0x73, 0x74, - 0x6f, 0x72, 0x69, 0x65, 0x73, 0x44, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x18, 0x1d, 0x20, - 0x01, 0x28, 0x08, 0x52, 0x0f, 0x73, 0x74, 0x6f, 0x72, 0x69, 0x65, 0x73, 0x44, 0x69, 0x73, 0x61, - 0x62, 0x6c, 0x65, 0x64, 0x12, 0x57, 0x0a, 0x18, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x56, 0x69, 0x65, - 0x77, 0x52, 0x65, 0x63, 0x65, 0x69, 0x70, 0x74, 0x73, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, - 0x18, 0x1e, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1b, 0x2e, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x6c, 0x73, - 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x42, - 0x6f, 0x6f, 0x6c, 0x52, 0x18, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x56, 0x69, 0x65, 0x77, 0x52, 0x65, - 0x63, 0x65, 0x69, 0x70, 0x74, 0x73, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x12, 0x48, 0x0a, + 0x6d, 0x70, 0x18, 0x06, 0x20, 0x01, 0x28, 0x04, 0x52, 0x13, 0x6d, 0x75, 0x74, 0x65, 0x64, 0x55, + 0x6e, 0x74, 0x69, 0x6c, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x22, 0xce, 0x03, + 0x0a, 0x0d, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x56, 0x32, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x12, + 0x1c, 0x0a, 0x09, 0x6d, 0x61, 0x73, 0x74, 0x65, 0x72, 0x4b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x0c, 0x52, 0x09, 0x6d, 0x61, 0x73, 0x74, 0x65, 0x72, 0x4b, 0x65, 0x79, 0x12, 0x18, 0x0a, + 0x07, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x65, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, + 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x65, 0x64, 0x12, 0x20, 0x0a, 0x0b, 0x77, 0x68, 0x69, 0x74, 0x65, + 0x6c, 0x69, 0x73, 0x74, 0x65, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, 0x77, 0x68, + 0x69, 0x74, 0x65, 0x6c, 0x69, 0x73, 0x74, 0x65, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x61, 0x72, 0x63, + 0x68, 0x69, 0x76, 0x65, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x61, 0x72, 0x63, + 0x68, 0x69, 0x76, 0x65, 0x64, 0x12, 0x22, 0x0a, 0x0c, 0x6d, 0x61, 0x72, 0x6b, 0x65, 0x64, 0x55, + 0x6e, 0x72, 0x65, 0x61, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0c, 0x6d, 0x61, 0x72, + 0x6b, 0x65, 0x64, 0x55, 0x6e, 0x72, 0x65, 0x61, 0x64, 0x12, 0x30, 0x0a, 0x13, 0x6d, 0x75, 0x74, + 0x65, 0x64, 0x55, 0x6e, 0x74, 0x69, 0x6c, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, + 0x18, 0x06, 0x20, 0x01, 0x28, 0x04, 0x52, 0x13, 0x6d, 0x75, 0x74, 0x65, 0x64, 0x55, 0x6e, 0x74, + 0x69, 0x6c, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x42, 0x0a, 0x1c, 0x64, + 0x6f, 0x6e, 0x74, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x79, 0x46, 0x6f, 0x72, 0x4d, 0x65, 0x6e, 0x74, + 0x69, 0x6f, 0x6e, 0x73, 0x49, 0x66, 0x4d, 0x75, 0x74, 0x65, 0x64, 0x18, 0x07, 0x20, 0x01, 0x28, + 0x08, 0x52, 0x1c, 0x64, 0x6f, 0x6e, 0x74, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x79, 0x46, 0x6f, 0x72, + 0x4d, 0x65, 0x6e, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x49, 0x66, 0x4d, 0x75, 0x74, 0x65, 0x64, 0x12, + 0x1c, 0x0a, 0x09, 0x68, 0x69, 0x64, 0x65, 0x53, 0x74, 0x6f, 0x72, 0x79, 0x18, 0x08, 0x20, 0x01, + 0x28, 0x08, 0x52, 0x09, 0x68, 0x69, 0x64, 0x65, 0x53, 0x74, 0x6f, 0x72, 0x79, 0x12, 0x50, 0x0a, + 0x0d, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x53, 0x65, 0x6e, 0x64, 0x4d, 0x6f, 0x64, 0x65, 0x18, 0x0a, + 0x20, 0x01, 0x28, 0x0e, 0x32, 0x2a, 0x2e, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x6c, 0x73, 0x65, 0x72, + 0x76, 0x69, 0x63, 0x65, 0x2e, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x56, 0x32, 0x52, 0x65, 0x63, 0x6f, + 0x72, 0x64, 0x2e, 0x53, 0x74, 0x6f, 0x72, 0x79, 0x53, 0x65, 0x6e, 0x64, 0x4d, 0x6f, 0x64, 0x65, + 0x52, 0x0d, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x53, 0x65, 0x6e, 0x64, 0x4d, 0x6f, 0x64, 0x65, 0x22, + 0x37, 0x0a, 0x0d, 0x53, 0x74, 0x6f, 0x72, 0x79, 0x53, 0x65, 0x6e, 0x64, 0x4d, 0x6f, 0x64, 0x65, + 0x12, 0x0b, 0x0a, 0x07, 0x44, 0x45, 0x46, 0x41, 0x55, 0x4c, 0x54, 0x10, 0x00, 0x12, 0x0c, 0x0a, + 0x08, 0x44, 0x49, 0x53, 0x41, 0x42, 0x4c, 0x45, 0x44, 0x10, 0x01, 0x12, 0x0b, 0x0a, 0x07, 0x45, + 0x4e, 0x41, 0x42, 0x4c, 0x45, 0x44, 0x10, 0x02, 0x4a, 0x04, 0x08, 0x09, 0x10, 0x0a, 0x22, 0x3e, + 0x0a, 0x08, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x65, 0x6e, + 0x61, 0x62, 0x6c, 0x65, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x65, 0x6e, 0x61, + 0x62, 0x6c, 0x65, 0x64, 0x12, 0x18, 0x0a, 0x07, 0x65, 0x6e, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x65, 0x6e, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x22, 0x9a, + 0x12, 0x0a, 0x0d, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, + 0x12, 0x1e, 0x0a, 0x0a, 0x70, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x4b, 0x65, 0x79, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0a, 0x70, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x4b, 0x65, 0x79, + 0x12, 0x1c, 0x0a, 0x09, 0x67, 0x69, 0x76, 0x65, 0x6e, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x09, 0x67, 0x69, 0x76, 0x65, 0x6e, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1e, + 0x0a, 0x0a, 0x66, 0x61, 0x6d, 0x69, 0x6c, 0x79, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x0a, 0x66, 0x61, 0x6d, 0x69, 0x6c, 0x79, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x24, + 0x0a, 0x0d, 0x61, 0x76, 0x61, 0x74, 0x61, 0x72, 0x55, 0x72, 0x6c, 0x50, 0x61, 0x74, 0x68, 0x18, + 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x61, 0x76, 0x61, 0x74, 0x61, 0x72, 0x55, 0x72, 0x6c, + 0x50, 0x61, 0x74, 0x68, 0x12, 0x2e, 0x0a, 0x12, 0x6e, 0x6f, 0x74, 0x65, 0x54, 0x6f, 0x53, 0x65, + 0x6c, 0x66, 0x41, 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, + 0x52, 0x12, 0x6e, 0x6f, 0x74, 0x65, 0x54, 0x6f, 0x53, 0x65, 0x6c, 0x66, 0x41, 0x72, 0x63, 0x68, + 0x69, 0x76, 0x65, 0x64, 0x12, 0x22, 0x0a, 0x0c, 0x72, 0x65, 0x61, 0x64, 0x52, 0x65, 0x63, 0x65, + 0x69, 0x70, 0x74, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0c, 0x72, 0x65, 0x61, 0x64, + 0x52, 0x65, 0x63, 0x65, 0x69, 0x70, 0x74, 0x73, 0x12, 0x36, 0x0a, 0x16, 0x73, 0x65, 0x61, 0x6c, + 0x65, 0x64, 0x53, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x49, 0x6e, 0x64, 0x69, 0x63, 0x61, 0x74, 0x6f, + 0x72, 0x73, 0x18, 0x07, 0x20, 0x01, 0x28, 0x08, 0x52, 0x16, 0x73, 0x65, 0x61, 0x6c, 0x65, 0x64, + 0x53, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x49, 0x6e, 0x64, 0x69, 0x63, 0x61, 0x74, 0x6f, 0x72, 0x73, + 0x12, 0x2a, 0x0a, 0x10, 0x74, 0x79, 0x70, 0x69, 0x6e, 0x67, 0x49, 0x6e, 0x64, 0x69, 0x63, 0x61, + 0x74, 0x6f, 0x72, 0x73, 0x18, 0x08, 0x20, 0x01, 0x28, 0x08, 0x52, 0x10, 0x74, 0x79, 0x70, 0x69, + 0x6e, 0x67, 0x49, 0x6e, 0x64, 0x69, 0x63, 0x61, 0x74, 0x6f, 0x72, 0x73, 0x12, 0x36, 0x0a, 0x16, + 0x6e, 0x6f, 0x74, 0x65, 0x54, 0x6f, 0x53, 0x65, 0x6c, 0x66, 0x4d, 0x61, 0x72, 0x6b, 0x65, 0x64, + 0x55, 0x6e, 0x72, 0x65, 0x61, 0x64, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x08, 0x52, 0x16, 0x6e, 0x6f, + 0x74, 0x65, 0x54, 0x6f, 0x53, 0x65, 0x6c, 0x66, 0x4d, 0x61, 0x72, 0x6b, 0x65, 0x64, 0x55, 0x6e, + 0x72, 0x65, 0x61, 0x64, 0x12, 0x22, 0x0a, 0x0c, 0x6c, 0x69, 0x6e, 0x6b, 0x50, 0x72, 0x65, 0x76, + 0x69, 0x65, 0x77, 0x73, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0c, 0x6c, 0x69, 0x6e, 0x6b, + 0x50, 0x72, 0x65, 0x76, 0x69, 0x65, 0x77, 0x73, 0x12, 0x6b, 0x0a, 0x16, 0x70, 0x68, 0x6f, 0x6e, + 0x65, 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x53, 0x68, 0x61, 0x72, 0x69, 0x6e, 0x67, 0x4d, 0x6f, + 0x64, 0x65, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x33, 0x2e, 0x73, 0x69, 0x67, 0x6e, 0x61, + 0x6c, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, + 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x2e, 0x50, 0x68, 0x6f, 0x6e, 0x65, 0x4e, 0x75, 0x6d, 0x62, + 0x65, 0x72, 0x53, 0x68, 0x61, 0x72, 0x69, 0x6e, 0x67, 0x4d, 0x6f, 0x64, 0x65, 0x52, 0x16, 0x70, + 0x68, 0x6f, 0x6e, 0x65, 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x53, 0x68, 0x61, 0x72, 0x69, 0x6e, + 0x67, 0x4d, 0x6f, 0x64, 0x65, 0x12, 0x30, 0x0a, 0x13, 0x75, 0x6e, 0x6c, 0x69, 0x73, 0x74, 0x65, + 0x64, 0x50, 0x68, 0x6f, 0x6e, 0x65, 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x18, 0x0d, 0x20, 0x01, + 0x28, 0x08, 0x52, 0x13, 0x75, 0x6e, 0x6c, 0x69, 0x73, 0x74, 0x65, 0x64, 0x50, 0x68, 0x6f, 0x6e, + 0x65, 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x12, 0x61, 0x0a, 0x13, 0x70, 0x69, 0x6e, 0x6e, 0x65, + 0x64, 0x43, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x0e, + 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2f, 0x2e, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x6c, 0x73, 0x65, 0x72, + 0x76, 0x69, 0x63, 0x65, 0x2e, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x52, 0x65, 0x63, 0x6f, + 0x72, 0x64, 0x2e, 0x50, 0x69, 0x6e, 0x6e, 0x65, 0x64, 0x43, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x13, 0x70, 0x69, 0x6e, 0x6e, 0x65, 0x64, 0x43, 0x6f, 0x6e, + 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x32, 0x0a, 0x14, 0x70, 0x72, + 0x65, 0x66, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x63, 0x74, 0x41, 0x76, 0x61, 0x74, 0x61, + 0x72, 0x73, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x08, 0x52, 0x14, 0x70, 0x72, 0x65, 0x66, 0x65, 0x72, + 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x63, 0x74, 0x41, 0x76, 0x61, 0x74, 0x61, 0x72, 0x73, 0x12, 0x33, + 0x0a, 0x08, 0x70, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x10, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x17, 0x2e, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x6c, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, + 0x2e, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x08, 0x70, 0x61, 0x79, 0x6d, 0x65, + 0x6e, 0x74, 0x73, 0x12, 0x32, 0x0a, 0x14, 0x75, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x61, 0x6c, + 0x45, 0x78, 0x70, 0x69, 0x72, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x72, 0x18, 0x11, 0x20, 0x01, 0x28, + 0x0d, 0x52, 0x14, 0x75, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x61, 0x6c, 0x45, 0x78, 0x70, 0x69, + 0x72, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x72, 0x12, 0x28, 0x0a, 0x0f, 0x70, 0x72, 0x69, 0x6d, 0x61, + 0x72, 0x79, 0x53, 0x65, 0x6e, 0x64, 0x73, 0x53, 0x6d, 0x73, 0x18, 0x12, 0x20, 0x01, 0x28, 0x08, + 0x52, 0x0f, 0x70, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x53, 0x65, 0x6e, 0x64, 0x73, 0x53, 0x6d, + 0x73, 0x12, 0x12, 0x0a, 0x04, 0x65, 0x31, 0x36, 0x34, 0x18, 0x13, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x04, 0x65, 0x31, 0x36, 0x34, 0x12, 0x36, 0x0a, 0x16, 0x70, 0x72, 0x65, 0x66, 0x65, 0x72, 0x72, + 0x65, 0x64, 0x52, 0x65, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x6d, 0x6f, 0x6a, 0x69, 0x18, + 0x14, 0x20, 0x03, 0x28, 0x09, 0x52, 0x16, 0x70, 0x72, 0x65, 0x66, 0x65, 0x72, 0x72, 0x65, 0x64, + 0x52, 0x65, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x6d, 0x6f, 0x6a, 0x69, 0x12, 0x22, 0x0a, + 0x0c, 0x73, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x72, 0x49, 0x64, 0x18, 0x15, 0x20, + 0x01, 0x28, 0x0c, 0x52, 0x0c, 0x73, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x72, 0x49, + 0x64, 0x12, 0x36, 0x0a, 0x16, 0x73, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x72, 0x43, + 0x75, 0x72, 0x72, 0x65, 0x6e, 0x63, 0x79, 0x43, 0x6f, 0x64, 0x65, 0x18, 0x16, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x16, 0x73, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x72, 0x43, 0x75, 0x72, + 0x72, 0x65, 0x6e, 0x63, 0x79, 0x43, 0x6f, 0x64, 0x65, 0x12, 0x36, 0x0a, 0x16, 0x64, 0x69, 0x73, + 0x70, 0x6c, 0x61, 0x79, 0x42, 0x61, 0x64, 0x67, 0x65, 0x73, 0x4f, 0x6e, 0x50, 0x72, 0x6f, 0x66, + 0x69, 0x6c, 0x65, 0x18, 0x17, 0x20, 0x01, 0x28, 0x08, 0x52, 0x16, 0x64, 0x69, 0x73, 0x70, 0x6c, + 0x61, 0x79, 0x42, 0x61, 0x64, 0x67, 0x65, 0x73, 0x4f, 0x6e, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, + 0x65, 0x12, 0x44, 0x0a, 0x1d, 0x73, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, + 0x6e, 0x4d, 0x61, 0x6e, 0x75, 0x61, 0x6c, 0x6c, 0x79, 0x43, 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x6c, + 0x65, 0x64, 0x18, 0x18, 0x20, 0x01, 0x28, 0x08, 0x52, 0x1d, 0x73, 0x75, 0x62, 0x73, 0x63, 0x72, + 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x4d, 0x61, 0x6e, 0x75, 0x61, 0x6c, 0x6c, 0x79, 0x43, 0x61, + 0x6e, 0x63, 0x65, 0x6c, 0x6c, 0x65, 0x64, 0x12, 0x36, 0x0a, 0x16, 0x6b, 0x65, 0x65, 0x70, 0x4d, + 0x75, 0x74, 0x65, 0x64, 0x43, 0x68, 0x61, 0x74, 0x73, 0x41, 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, + 0x64, 0x18, 0x19, 0x20, 0x01, 0x28, 0x08, 0x52, 0x16, 0x6b, 0x65, 0x65, 0x70, 0x4d, 0x75, 0x74, + 0x65, 0x64, 0x43, 0x68, 0x61, 0x74, 0x73, 0x41, 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, 0x64, 0x12, + 0x36, 0x0a, 0x16, 0x68, 0x61, 0x73, 0x53, 0x65, 0x74, 0x4d, 0x79, 0x53, 0x74, 0x6f, 0x72, 0x69, + 0x65, 0x73, 0x50, 0x72, 0x69, 0x76, 0x61, 0x63, 0x79, 0x18, 0x1a, 0x20, 0x01, 0x28, 0x08, 0x52, + 0x16, 0x68, 0x61, 0x73, 0x53, 0x65, 0x74, 0x4d, 0x79, 0x53, 0x74, 0x6f, 0x72, 0x69, 0x65, 0x73, + 0x50, 0x72, 0x69, 0x76, 0x61, 0x63, 0x79, 0x12, 0x3a, 0x0a, 0x18, 0x68, 0x61, 0x73, 0x56, 0x69, + 0x65, 0x77, 0x65, 0x64, 0x4f, 0x6e, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x69, 0x6e, 0x67, 0x53, 0x74, + 0x6f, 0x72, 0x79, 0x18, 0x1b, 0x20, 0x01, 0x28, 0x08, 0x52, 0x18, 0x68, 0x61, 0x73, 0x56, 0x69, + 0x65, 0x77, 0x65, 0x64, 0x4f, 0x6e, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x69, 0x6e, 0x67, 0x53, 0x74, + 0x6f, 0x72, 0x79, 0x12, 0x28, 0x0a, 0x0f, 0x73, 0x74, 0x6f, 0x72, 0x69, 0x65, 0x73, 0x44, 0x69, + 0x73, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x18, 0x1d, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0f, 0x73, 0x74, + 0x6f, 0x72, 0x69, 0x65, 0x73, 0x44, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x12, 0x57, 0x0a, + 0x18, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x56, 0x69, 0x65, 0x77, 0x52, 0x65, 0x63, 0x65, 0x69, 0x70, + 0x74, 0x73, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x18, 0x1e, 0x20, 0x01, 0x28, 0x0e, 0x32, + 0x1b, 0x2e, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x6c, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, + 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x42, 0x6f, 0x6f, 0x6c, 0x52, 0x18, 0x73, 0x74, + 0x6f, 0x72, 0x79, 0x56, 0x69, 0x65, 0x77, 0x52, 0x65, 0x63, 0x65, 0x69, 0x70, 0x74, 0x73, 0x45, + 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x12, 0x48, 0x0a, 0x1f, 0x68, 0x61, 0x73, 0x53, 0x65, 0x65, + 0x6e, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x53, 0x74, 0x6f, 0x72, 0x79, 0x45, 0x64, 0x75, 0x63, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x68, 0x65, 0x65, 0x74, 0x18, 0x20, 0x20, 0x01, 0x28, 0x08, 0x52, 0x1f, 0x68, 0x61, 0x73, 0x53, 0x65, 0x65, 0x6e, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x53, 0x74, 0x6f, 0x72, 0x79, 0x45, 0x64, 0x75, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x68, 0x65, 0x65, 0x74, - 0x18, 0x20, 0x20, 0x01, 0x28, 0x08, 0x52, 0x1f, 0x68, 0x61, 0x73, 0x53, 0x65, 0x65, 0x6e, 0x47, - 0x72, 0x6f, 0x75, 0x70, 0x53, 0x74, 0x6f, 0x72, 0x79, 0x45, 0x64, 0x75, 0x63, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x53, 0x68, 0x65, 0x65, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, - 0x61, 0x6d, 0x65, 0x18, 0x21, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, - 0x61, 0x6d, 0x65, 0x12, 0x46, 0x0a, 0x1e, 0x68, 0x61, 0x73, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, - 0x74, 0x65, 0x64, 0x55, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x4f, 0x6e, 0x62, 0x6f, 0x61, - 0x72, 0x64, 0x69, 0x6e, 0x67, 0x18, 0x22, 0x20, 0x01, 0x28, 0x08, 0x52, 0x1e, 0x68, 0x61, 0x73, - 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x55, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, - 0x65, 0x4f, 0x6e, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x69, 0x6e, 0x67, 0x12, 0x4d, 0x0a, 0x0c, 0x75, - 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x4c, 0x69, 0x6e, 0x6b, 0x18, 0x23, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x29, 0x2e, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x6c, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, - 0x65, 0x2e, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x2e, - 0x55, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x4c, 0x69, 0x6e, 0x6b, 0x52, 0x0c, 0x75, 0x73, - 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x4c, 0x69, 0x6e, 0x6b, 0x1a, 0x86, 0x02, 0x0a, 0x12, 0x50, - 0x69, 0x6e, 0x6e, 0x65, 0x64, 0x43, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x12, 0x53, 0x0a, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x63, 0x74, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x37, 0x2e, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x6c, 0x73, 0x65, 0x72, 0x76, 0x69, + 0x12, 0x1a, 0x0a, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x21, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x46, 0x0a, 0x1e, + 0x68, 0x61, 0x73, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x55, 0x73, 0x65, 0x72, + 0x6e, 0x61, 0x6d, 0x65, 0x4f, 0x6e, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x69, 0x6e, 0x67, 0x18, 0x22, + 0x20, 0x01, 0x28, 0x08, 0x52, 0x1e, 0x68, 0x61, 0x73, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, + 0x65, 0x64, 0x55, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x4f, 0x6e, 0x62, 0x6f, 0x61, 0x72, + 0x64, 0x69, 0x6e, 0x67, 0x12, 0x4d, 0x0a, 0x0c, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, + 0x4c, 0x69, 0x6e, 0x6b, 0x18, 0x23, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x73, 0x69, 0x67, + 0x6e, 0x61, 0x6c, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x41, 0x63, 0x63, 0x6f, 0x75, + 0x6e, 0x74, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, + 0x65, 0x4c, 0x69, 0x6e, 0x6b, 0x52, 0x0c, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x4c, + 0x69, 0x6e, 0x6b, 0x1a, 0x86, 0x02, 0x0a, 0x12, 0x50, 0x69, 0x6e, 0x6e, 0x65, 0x64, 0x43, 0x6f, + 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x53, 0x0a, 0x07, 0x63, 0x6f, + 0x6e, 0x74, 0x61, 0x63, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x37, 0x2e, 0x73, 0x69, + 0x67, 0x6e, 0x61, 0x6c, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x41, 0x63, 0x63, 0x6f, + 0x75, 0x6e, 0x74, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x2e, 0x50, 0x69, 0x6e, 0x6e, 0x65, 0x64, + 0x43, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x43, 0x6f, 0x6e, + 0x74, 0x61, 0x63, 0x74, 0x48, 0x00, 0x52, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x63, 0x74, 0x12, + 0x26, 0x0a, 0x0d, 0x6c, 0x65, 0x67, 0x61, 0x63, 0x79, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x49, 0x64, + 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x48, 0x00, 0x52, 0x0d, 0x6c, 0x65, 0x67, 0x61, 0x63, 0x79, + 0x47, 0x72, 0x6f, 0x75, 0x70, 0x49, 0x64, 0x12, 0x28, 0x0a, 0x0e, 0x67, 0x72, 0x6f, 0x75, 0x70, + 0x4d, 0x61, 0x73, 0x74, 0x65, 0x72, 0x4b, 0x65, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x48, + 0x00, 0x52, 0x0e, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x4d, 0x61, 0x73, 0x74, 0x65, 0x72, 0x4b, 0x65, + 0x79, 0x1a, 0x3b, 0x0a, 0x07, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x63, 0x74, 0x12, 0x1c, 0x0a, 0x09, + 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x09, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x49, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x65, 0x31, + 0x36, 0x34, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x65, 0x31, 0x36, 0x34, 0x42, 0x0c, + 0x0a, 0x0a, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x1a, 0xf8, 0x01, 0x0a, + 0x0c, 0x55, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x4c, 0x69, 0x6e, 0x6b, 0x12, 0x18, 0x0a, + 0x07, 0x65, 0x6e, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, + 0x65, 0x6e, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x12, 0x1a, 0x0a, 0x08, 0x73, 0x65, 0x72, 0x76, 0x65, + 0x72, 0x49, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, 0x73, 0x65, 0x72, 0x76, 0x65, + 0x72, 0x49, 0x64, 0x12, 0x45, 0x0a, 0x05, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x0e, 0x32, 0x2f, 0x2e, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x6c, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, - 0x2e, 0x50, 0x69, 0x6e, 0x6e, 0x65, 0x64, 0x43, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x63, 0x74, 0x48, 0x00, 0x52, 0x07, 0x63, - 0x6f, 0x6e, 0x74, 0x61, 0x63, 0x74, 0x12, 0x26, 0x0a, 0x0d, 0x6c, 0x65, 0x67, 0x61, 0x63, 0x79, - 0x47, 0x72, 0x6f, 0x75, 0x70, 0x49, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x48, 0x00, 0x52, - 0x0d, 0x6c, 0x65, 0x67, 0x61, 0x63, 0x79, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x49, 0x64, 0x12, 0x28, - 0x0a, 0x0e, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x4d, 0x61, 0x73, 0x74, 0x65, 0x72, 0x4b, 0x65, 0x79, - 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x48, 0x00, 0x52, 0x0e, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x4d, - 0x61, 0x73, 0x74, 0x65, 0x72, 0x4b, 0x65, 0x79, 0x1a, 0x3b, 0x0a, 0x07, 0x43, 0x6f, 0x6e, 0x74, - 0x61, 0x63, 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x49, 0x64, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x49, - 0x64, 0x12, 0x12, 0x0a, 0x04, 0x65, 0x31, 0x36, 0x34, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x04, 0x65, 0x31, 0x36, 0x34, 0x42, 0x0c, 0x0a, 0x0a, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, - 0x69, 0x65, 0x72, 0x1a, 0xf8, 0x01, 0x0a, 0x0c, 0x55, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, - 0x4c, 0x69, 0x6e, 0x6b, 0x12, 0x18, 0x0a, 0x07, 0x65, 0x6e, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x65, 0x6e, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x12, 0x1a, - 0x0a, 0x08, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x49, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, - 0x52, 0x08, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x49, 0x64, 0x12, 0x45, 0x0a, 0x05, 0x63, 0x6f, - 0x6c, 0x6f, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x2f, 0x2e, 0x73, 0x69, 0x67, 0x6e, - 0x61, 0x6c, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, - 0x74, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, - 0x4c, 0x69, 0x6e, 0x6b, 0x2e, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x52, 0x05, 0x63, 0x6f, 0x6c, 0x6f, - 0x72, 0x22, 0x6b, 0x0a, 0x05, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x12, 0x0b, 0x0a, 0x07, 0x55, 0x4e, - 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x00, 0x12, 0x08, 0x0a, 0x04, 0x42, 0x4c, 0x55, 0x45, 0x10, - 0x01, 0x12, 0x09, 0x0a, 0x05, 0x57, 0x48, 0x49, 0x54, 0x45, 0x10, 0x02, 0x12, 0x08, 0x0a, 0x04, - 0x47, 0x52, 0x45, 0x59, 0x10, 0x03, 0x12, 0x09, 0x0a, 0x05, 0x4f, 0x4c, 0x49, 0x56, 0x45, 0x10, - 0x04, 0x12, 0x09, 0x0a, 0x05, 0x47, 0x52, 0x45, 0x45, 0x4e, 0x10, 0x05, 0x12, 0x0a, 0x0a, 0x06, - 0x4f, 0x52, 0x41, 0x4e, 0x47, 0x45, 0x10, 0x06, 0x12, 0x08, 0x0a, 0x04, 0x50, 0x49, 0x4e, 0x4b, - 0x10, 0x07, 0x12, 0x0a, 0x0a, 0x06, 0x50, 0x55, 0x52, 0x50, 0x4c, 0x45, 0x10, 0x08, 0x22, 0x40, - 0x0a, 0x16, 0x50, 0x68, 0x6f, 0x6e, 0x65, 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x53, 0x68, 0x61, - 0x72, 0x69, 0x6e, 0x67, 0x4d, 0x6f, 0x64, 0x65, 0x12, 0x0b, 0x0a, 0x07, 0x55, 0x4e, 0x4b, 0x4e, - 0x4f, 0x57, 0x4e, 0x10, 0x00, 0x12, 0x0d, 0x0a, 0x09, 0x45, 0x56, 0x45, 0x52, 0x59, 0x42, 0x4f, - 0x44, 0x59, 0x10, 0x01, 0x12, 0x0a, 0x0a, 0x06, 0x4e, 0x4f, 0x42, 0x4f, 0x44, 0x59, 0x10, 0x02, - 0x4a, 0x04, 0x08, 0x09, 0x10, 0x0a, 0x4a, 0x04, 0x08, 0x1c, 0x10, 0x1d, 0x4a, 0x04, 0x08, 0x1f, - 0x10, 0x20, 0x22, 0xfb, 0x01, 0x0a, 0x1b, 0x53, 0x74, 0x6f, 0x72, 0x79, 0x44, 0x69, 0x73, 0x74, - 0x72, 0x69, 0x62, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x63, 0x6f, - 0x72, 0x64, 0x12, 0x1e, 0x0a, 0x0a, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0a, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, - 0x65, 0x72, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x30, 0x0a, 0x13, 0x72, 0x65, 0x63, 0x69, 0x70, 0x69, - 0x65, 0x6e, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x49, 0x64, 0x73, 0x18, 0x03, 0x20, - 0x03, 0x28, 0x09, 0x52, 0x13, 0x72, 0x65, 0x63, 0x69, 0x70, 0x69, 0x65, 0x6e, 0x74, 0x53, 0x65, - 0x72, 0x76, 0x69, 0x63, 0x65, 0x49, 0x64, 0x73, 0x12, 0x2e, 0x0a, 0x12, 0x64, 0x65, 0x6c, 0x65, - 0x74, 0x65, 0x64, 0x41, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x04, - 0x20, 0x01, 0x28, 0x04, 0x52, 0x12, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x41, 0x74, 0x54, - 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x24, 0x0a, 0x0d, 0x61, 0x6c, 0x6c, 0x6f, - 0x77, 0x73, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x65, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, - 0x0d, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x73, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x65, 0x73, 0x12, 0x20, - 0x0a, 0x0b, 0x69, 0x73, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x4c, 0x69, 0x73, 0x74, 0x18, 0x06, 0x20, - 0x01, 0x28, 0x08, 0x52, 0x0b, 0x69, 0x73, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x4c, 0x69, 0x73, 0x74, - 0x2a, 0x34, 0x0a, 0x0c, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x42, 0x6f, 0x6f, 0x6c, - 0x12, 0x09, 0x0a, 0x05, 0x55, 0x4e, 0x53, 0x45, 0x54, 0x10, 0x00, 0x12, 0x0b, 0x0a, 0x07, 0x45, - 0x4e, 0x41, 0x42, 0x4c, 0x45, 0x44, 0x10, 0x01, 0x12, 0x0c, 0x0a, 0x08, 0x44, 0x49, 0x53, 0x41, - 0x42, 0x4c, 0x45, 0x44, 0x10, 0x02, 0x42, 0x3c, 0x0a, 0x38, 0x6f, 0x72, 0x67, 0x2e, 0x77, 0x68, - 0x69, 0x73, 0x70, 0x65, 0x72, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x73, 0x2e, 0x73, 0x69, 0x67, - 0x6e, 0x61, 0x6c, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, - 0x6e, 0x61, 0x6c, 0x2e, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x73, 0x50, 0x01, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x2e, 0x55, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x4c, 0x69, 0x6e, 0x6b, 0x2e, 0x43, 0x6f, + 0x6c, 0x6f, 0x72, 0x52, 0x05, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x22, 0x6b, 0x0a, 0x05, 0x43, 0x6f, + 0x6c, 0x6f, 0x72, 0x12, 0x0b, 0x0a, 0x07, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x00, + 0x12, 0x08, 0x0a, 0x04, 0x42, 0x4c, 0x55, 0x45, 0x10, 0x01, 0x12, 0x09, 0x0a, 0x05, 0x57, 0x48, + 0x49, 0x54, 0x45, 0x10, 0x02, 0x12, 0x08, 0x0a, 0x04, 0x47, 0x52, 0x45, 0x59, 0x10, 0x03, 0x12, + 0x09, 0x0a, 0x05, 0x4f, 0x4c, 0x49, 0x56, 0x45, 0x10, 0x04, 0x12, 0x09, 0x0a, 0x05, 0x47, 0x52, + 0x45, 0x45, 0x4e, 0x10, 0x05, 0x12, 0x0a, 0x0a, 0x06, 0x4f, 0x52, 0x41, 0x4e, 0x47, 0x45, 0x10, + 0x06, 0x12, 0x08, 0x0a, 0x04, 0x50, 0x49, 0x4e, 0x4b, 0x10, 0x07, 0x12, 0x0a, 0x0a, 0x06, 0x50, + 0x55, 0x52, 0x50, 0x4c, 0x45, 0x10, 0x08, 0x22, 0x40, 0x0a, 0x16, 0x50, 0x68, 0x6f, 0x6e, 0x65, + 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x53, 0x68, 0x61, 0x72, 0x69, 0x6e, 0x67, 0x4d, 0x6f, 0x64, + 0x65, 0x12, 0x0b, 0x0a, 0x07, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x00, 0x12, 0x0d, + 0x0a, 0x09, 0x45, 0x56, 0x45, 0x52, 0x59, 0x42, 0x4f, 0x44, 0x59, 0x10, 0x01, 0x12, 0x0a, 0x0a, + 0x06, 0x4e, 0x4f, 0x42, 0x4f, 0x44, 0x59, 0x10, 0x02, 0x4a, 0x04, 0x08, 0x09, 0x10, 0x0a, 0x4a, + 0x04, 0x08, 0x1c, 0x10, 0x1d, 0x4a, 0x04, 0x08, 0x1f, 0x10, 0x20, 0x22, 0xfb, 0x01, 0x0a, 0x1b, + 0x53, 0x74, 0x6f, 0x72, 0x79, 0x44, 0x69, 0x73, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x69, 0x6f, + 0x6e, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x12, 0x1e, 0x0a, 0x0a, 0x69, + 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, + 0x0a, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x12, 0x12, 0x0a, 0x04, 0x6e, + 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, + 0x30, 0x0a, 0x13, 0x72, 0x65, 0x63, 0x69, 0x70, 0x69, 0x65, 0x6e, 0x74, 0x53, 0x65, 0x72, 0x76, + 0x69, 0x63, 0x65, 0x49, 0x64, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x13, 0x72, 0x65, + 0x63, 0x69, 0x70, 0x69, 0x65, 0x6e, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x49, 0x64, + 0x73, 0x12, 0x2e, 0x0a, 0x12, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x41, 0x74, 0x54, 0x69, + 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x04, 0x20, 0x01, 0x28, 0x04, 0x52, 0x12, 0x64, + 0x65, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x41, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, + 0x70, 0x12, 0x24, 0x0a, 0x0d, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x73, 0x52, 0x65, 0x70, 0x6c, 0x69, + 0x65, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0d, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x73, + 0x52, 0x65, 0x70, 0x6c, 0x69, 0x65, 0x73, 0x12, 0x20, 0x0a, 0x0b, 0x69, 0x73, 0x42, 0x6c, 0x6f, + 0x63, 0x6b, 0x4c, 0x69, 0x73, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, 0x69, 0x73, + 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x4c, 0x69, 0x73, 0x74, 0x2a, 0x34, 0x0a, 0x0c, 0x4f, 0x70, 0x74, + 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x42, 0x6f, 0x6f, 0x6c, 0x12, 0x09, 0x0a, 0x05, 0x55, 0x4e, 0x53, + 0x45, 0x54, 0x10, 0x00, 0x12, 0x0b, 0x0a, 0x07, 0x45, 0x4e, 0x41, 0x42, 0x4c, 0x45, 0x44, 0x10, + 0x01, 0x12, 0x0c, 0x0a, 0x08, 0x44, 0x49, 0x53, 0x41, 0x42, 0x4c, 0x45, 0x44, 0x10, 0x02, 0x42, + 0x3c, 0x0a, 0x38, 0x6f, 0x72, 0x67, 0x2e, 0x77, 0x68, 0x69, 0x73, 0x70, 0x65, 0x72, 0x73, 0x79, + 0x73, 0x74, 0x65, 0x6d, 0x73, 0x2e, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x6c, 0x73, 0x65, 0x72, 0x76, + 0x69, 0x63, 0x65, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x73, 0x74, 0x6f, + 0x72, 0x61, 0x67, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x50, 0x01, 0x62, 0x06, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -2279,7 +2359,7 @@ func file_StorageService_proto_rawDescGZIP() []byte { } var file_StorageService_proto_enumTypes = make([]protoimpl.EnumInfo, 6) -var file_StorageService_proto_msgTypes = make([]protoimpl.MessageInfo, 17) +var file_StorageService_proto_msgTypes = make([]protoimpl.MessageInfo, 18) var file_StorageService_proto_goTypes = []interface{}{ (OptionalBool)(0), // 0: signalservice.OptionalBool (ManifestRecord_Identifier_Type)(0), // 1: signalservice.ManifestRecord.Identifier.Type @@ -2301,9 +2381,10 @@ var file_StorageService_proto_goTypes = []interface{}{ (*AccountRecord)(nil), // 17: signalservice.AccountRecord (*StoryDistributionListRecord)(nil), // 18: signalservice.StoryDistributionListRecord (*ManifestRecord_Identifier)(nil), // 19: signalservice.ManifestRecord.Identifier - (*AccountRecord_PinnedConversation)(nil), // 20: signalservice.AccountRecord.PinnedConversation - (*AccountRecord_UsernameLink)(nil), // 21: signalservice.AccountRecord.UsernameLink - (*AccountRecord_PinnedConversation_Contact)(nil), // 22: signalservice.AccountRecord.PinnedConversation.Contact + (*ContactRecord_Name)(nil), // 20: signalservice.ContactRecord.Name + (*AccountRecord_PinnedConversation)(nil), // 21: signalservice.AccountRecord.PinnedConversation + (*AccountRecord_UsernameLink)(nil), // 22: signalservice.AccountRecord.UsernameLink + (*AccountRecord_PinnedConversation_Contact)(nil), // 23: signalservice.AccountRecord.PinnedConversation.Contact } var file_StorageService_proto_depIdxs = []int32{ 7, // 0: signalservice.StorageItems.items:type_name -> signalservice.StorageItem @@ -2316,20 +2397,21 @@ var file_StorageService_proto_depIdxs = []int32{ 17, // 7: signalservice.StorageRecord.account:type_name -> signalservice.AccountRecord 18, // 8: signalservice.StorageRecord.storyDistributionList:type_name -> signalservice.StoryDistributionListRecord 2, // 9: signalservice.ContactRecord.identityState:type_name -> signalservice.ContactRecord.IdentityState - 3, // 10: signalservice.GroupV2Record.storySendMode:type_name -> signalservice.GroupV2Record.StorySendMode - 4, // 11: signalservice.AccountRecord.phoneNumberSharingMode:type_name -> signalservice.AccountRecord.PhoneNumberSharingMode - 20, // 12: signalservice.AccountRecord.pinnedConversations:type_name -> signalservice.AccountRecord.PinnedConversation - 16, // 13: signalservice.AccountRecord.payments:type_name -> signalservice.Payments - 0, // 14: signalservice.AccountRecord.storyViewReceiptsEnabled:type_name -> signalservice.OptionalBool - 21, // 15: signalservice.AccountRecord.usernameLink:type_name -> signalservice.AccountRecord.UsernameLink - 1, // 16: signalservice.ManifestRecord.Identifier.type:type_name -> signalservice.ManifestRecord.Identifier.Type - 22, // 17: signalservice.AccountRecord.PinnedConversation.contact:type_name -> signalservice.AccountRecord.PinnedConversation.Contact - 5, // 18: signalservice.AccountRecord.UsernameLink.color:type_name -> signalservice.AccountRecord.UsernameLink.Color - 19, // [19:19] is the sub-list for method output_type - 19, // [19:19] is the sub-list for method input_type - 19, // [19:19] is the sub-list for extension type_name - 19, // [19:19] is the sub-list for extension extendee - 0, // [0:19] is the sub-list for field type_name + 20, // 10: signalservice.ContactRecord.nickname:type_name -> signalservice.ContactRecord.Name + 3, // 11: signalservice.GroupV2Record.storySendMode:type_name -> signalservice.GroupV2Record.StorySendMode + 4, // 12: signalservice.AccountRecord.phoneNumberSharingMode:type_name -> signalservice.AccountRecord.PhoneNumberSharingMode + 21, // 13: signalservice.AccountRecord.pinnedConversations:type_name -> signalservice.AccountRecord.PinnedConversation + 16, // 14: signalservice.AccountRecord.payments:type_name -> signalservice.Payments + 0, // 15: signalservice.AccountRecord.storyViewReceiptsEnabled:type_name -> signalservice.OptionalBool + 22, // 16: signalservice.AccountRecord.usernameLink:type_name -> signalservice.AccountRecord.UsernameLink + 1, // 17: signalservice.ManifestRecord.Identifier.type:type_name -> signalservice.ManifestRecord.Identifier.Type + 23, // 18: signalservice.AccountRecord.PinnedConversation.contact:type_name -> signalservice.AccountRecord.PinnedConversation.Contact + 5, // 19: signalservice.AccountRecord.UsernameLink.color:type_name -> signalservice.AccountRecord.UsernameLink.Color + 20, // [20:20] is the sub-list for method output_type + 20, // [20:20] is the sub-list for method input_type + 20, // [20:20] is the sub-list for extension type_name + 20, // [20:20] is the sub-list for extension extendee + 0, // [0:20] is the sub-list for field type_name } func init() { file_StorageService_proto_init() } @@ -2507,7 +2589,7 @@ func file_StorageService_proto_init() { } } file_StorageService_proto_msgTypes[14].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*AccountRecord_PinnedConversation); i { + switch v := v.(*ContactRecord_Name); i { case 0: return &v.state case 1: @@ -2519,7 +2601,7 @@ func file_StorageService_proto_init() { } } file_StorageService_proto_msgTypes[15].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*AccountRecord_UsernameLink); i { + switch v := v.(*AccountRecord_PinnedConversation); i { case 0: return &v.state case 1: @@ -2531,6 +2613,18 @@ func file_StorageService_proto_init() { } } file_StorageService_proto_msgTypes[16].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*AccountRecord_UsernameLink); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_StorageService_proto_msgTypes[17].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*AccountRecord_PinnedConversation_Contact); i { case 0: return &v.state @@ -2550,7 +2644,7 @@ func file_StorageService_proto_init() { (*StorageRecord_Account)(nil), (*StorageRecord_StoryDistributionList)(nil), } - file_StorageService_proto_msgTypes[14].OneofWrappers = []interface{}{ + file_StorageService_proto_msgTypes[15].OneofWrappers = []interface{}{ (*AccountRecord_PinnedConversation_Contact_)(nil), (*AccountRecord_PinnedConversation_LegacyGroupId)(nil), (*AccountRecord_PinnedConversation_GroupMasterKey)(nil), @@ -2561,7 +2655,7 @@ func file_StorageService_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_StorageService_proto_rawDesc, NumEnums: 6, - NumMessages: 17, + NumMessages: 18, NumExtensions: 0, NumServices: 0, }, diff --git a/pkg/signalmeow/protobuf/StorageService.proto b/pkg/signalmeow/protobuf/StorageService.proto index f9370b0..ac26d38 100644 --- a/pkg/signalmeow/protobuf/StorageService.proto +++ b/pkg/signalmeow/protobuf/StorageService.proto @@ -79,6 +79,11 @@ message ContactRecord { UNVERIFIED = 2; } + message Name { + string given = 1; + string family = 2; + } + string aci = 1; string e164 = 2; string pni = 15; @@ -100,7 +105,9 @@ message ContactRecord { string systemNickname = 19; bool hidden = 20; bool pniSignatureVerified = 21; - // NEXT ID: 22 + Name nickname = 22; + string note = 23; + // NEXT ID: 24 } message GroupV1Record { diff --git a/pkg/signalmeow/protobuf/UnidentifiedDelivery.pb.go b/pkg/signalmeow/protobuf/UnidentifiedDelivery.pb.go index 9f95088..fbfebf5 100644 --- a/pkg/signalmeow/protobuf/UnidentifiedDelivery.pb.go +++ b/pkg/signalmeow/protobuf/UnidentifiedDelivery.pb.go @@ -1,6 +1,6 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.31.0 +// protoc-gen-go v1.34.1 // protoc v3.21.12 // source: UnidentifiedDelivery.proto diff --git a/pkg/signalmeow/protobuf/WebSocketResources.pb.go b/pkg/signalmeow/protobuf/WebSocketResources.pb.go index c3aed6d..df73711 100644 --- a/pkg/signalmeow/protobuf/WebSocketResources.pb.go +++ b/pkg/signalmeow/protobuf/WebSocketResources.pb.go @@ -5,7 +5,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.31.0 +// protoc-gen-go v1.34.1 // protoc v3.21.12 // source: WebSocketResources.proto diff --git a/pkg/signalmeow/protobuf/update-protos.sh b/pkg/signalmeow/protobuf/update-protos.sh index 4aefdb7..dac087b 100755 --- a/pkg/signalmeow/protobuf/update-protos.sh +++ b/pkg/signalmeow/protobuf/update-protos.sh @@ -1,8 +1,8 @@ #!/bin/bash set -euo pipefail -ANDROID_GIT_REVISION=${1:-915b3f0cd32628c6dfddb40934d1c3b47c52e991} -DESKTOP_GIT_REVISION=${1:-3eed6cb350f5e54df09e18a9012f4db74cecb7b6} +ANDROID_GIT_REVISION=${1:-c4805126008977827f8ee08e016568fc9a374b4d} +DESKTOP_GIT_REVISION=${1:-af1c593fef4e485127ea356b3b592f3c781c2a16} update_proto() { case "$1" in From 20e5f43be8818a36b575d0243dbf534b82434025 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Fri, 14 Jun 2024 15:44:43 +0300 Subject: [PATCH 046/580] signalmeow/store: fix master key being non-nil slice when scanned from db --- pkg/signalmeow/store/container.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/pkg/signalmeow/store/container.go b/pkg/signalmeow/store/container.go index d649b92..9edafef 100644 --- a/pkg/signalmeow/store/container.go +++ b/pkg/signalmeow/store/container.go @@ -65,6 +65,9 @@ func (c *Container) scanDevice(row dbutil.Scannable) (*Device, error) { return nil, fmt.Errorf("failed to deserialize PNI identity key pair: %w", err) } + if len(device.MasterKey) == 0 { + device.MasterKey = nil + } baseStore := &sqlStore{Container: c, AccountID: device.ACI} aciStore := &scopedSQLStore{Container: c, AccountID: device.ACI, ServiceID: device.ACIServiceID()} pniStore := &scopedSQLStore{Container: c, AccountID: device.ACI, ServiceID: device.PNIServiceID()} From 790152b38ad4b1717758c44fd498a8f8758ad84f Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Fri, 14 Jun 2024 15:56:17 +0300 Subject: [PATCH 047/580] libsignalgo: update libsignal to v0.51.0 --- pkg/libsignalgo/libsignal | 2 +- pkg/libsignalgo/libsignal-ffi.h | 10 ++++++++++ pkg/libsignalgo/version.go | 2 +- 3 files changed, 12 insertions(+), 2 deletions(-) diff --git a/pkg/libsignalgo/libsignal b/pkg/libsignalgo/libsignal index 347791c..95bf4e7 160000 --- a/pkg/libsignalgo/libsignal +++ b/pkg/libsignalgo/libsignal @@ -1 +1 @@ -Subproject commit 347791c88cdfdb765534b5e2be149f588b75bf49 +Subproject commit 95bf4e77155b5110e80a8d140cce7adaef8aa0ac diff --git a/pkg/libsignalgo/libsignal-ffi.h b/pkg/libsignalgo/libsignal-ffi.h index c349c2c..bd99f60 100644 --- a/pkg/libsignalgo/libsignal-ffi.h +++ b/pkg/libsignalgo/libsignal-ffi.h @@ -292,6 +292,11 @@ typedef struct SignalSgxClientState SignalSgxClientState; /** * The top-level error type (opaquely) returned to C clients when something goes wrong. + * + * Ideally this would use [ThinBox][], and then we wouldn't need an extra level of indirection when + * returning it to C, but unfortunately that isn't stable yet. + * + * [ThinBox]: https://doc.rust-lang.org/std/boxed/struct.ThinBox.html */ typedef struct SignalFfiError SignalFfiError; @@ -634,6 +639,8 @@ typedef void (*SignalReceivedIncomingMessage)(void *ctx, SignalOwnedBuffer envel typedef void (*SignalReceivedQueueEmpty)(void *ctx); +typedef void (*SignalConnectionInterrupted)(void *ctx); + typedef void (*SignalDestroyChatListener)(void *ctx); /** @@ -647,6 +654,7 @@ typedef struct { void *ctx; SignalReceivedIncomingMessage received_incoming_message; SignalReceivedQueueEmpty received_queue_empty; + SignalConnectionInterrupted connection_interrupted; SignalDestroyChatListener destroy; } SignalFfiChatListenerStruct; @@ -1572,6 +1580,8 @@ SignalFfiError *signal_chat_server_set_listener(const SignalTokioAsyncContext *r SignalFfiError *signal_testing_chat_service_inject_raw_server_request(const SignalChat *chat, SignalBorrowedBuffer bytes); +SignalFfiError *signal_testing_chat_service_inject_connection_interrupted(const SignalChat *chat); + SignalFfiError *signal_server_message_ack_destroy(SignalServerMessageAck *p); SignalFfiError *signal_server_message_ack_send(SignalCPromisebool *promise, const SignalTokioAsyncContext *async_runtime, const SignalServerMessageAck *ack); diff --git a/pkg/libsignalgo/version.go b/pkg/libsignalgo/version.go index 0bc1cb7..cf2f348 100644 --- a/pkg/libsignalgo/version.go +++ b/pkg/libsignalgo/version.go @@ -2,4 +2,4 @@ package libsignalgo -const Version = "v0.49.0" +const Version = "v0.51.0" From 65e2b4c9e15e1eb5fa21607c1a4f196f09976ead Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Fri, 14 Jun 2024 15:57:17 +0300 Subject: [PATCH 048/580] v2: update mautrix-go --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 258845e..4d6711e 100644 --- a/go.mod +++ b/go.mod @@ -20,7 +20,7 @@ require ( golang.org/x/exp v0.0.0-20240604190554-fc45aab8b7f8 golang.org/x/net v0.26.0 google.golang.org/protobuf v1.34.1 - maunium.net/go/mautrix v0.18.2-0.20240614094708-b456fb6e0a6b + maunium.net/go/mautrix v0.18.2-0.20240614100125-869a04dadbe4 nhooyr.io/websocket v1.8.11 ) diff --git a/go.sum b/go.sum index 61c4295..18026e7 100644 --- a/go.sum +++ b/go.sum @@ -95,7 +95,7 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= maunium.net/go/mauflag v1.0.0 h1:YiaRc0tEI3toYtJMRIfjP+jklH45uDHtT80nUamyD4M= maunium.net/go/mauflag v1.0.0/go.mod h1:nLivPOpTpHnpzEh8jEdSL9UqO9+/KBJFmNRlwKfkPeA= -maunium.net/go/mautrix v0.18.2-0.20240614094708-b456fb6e0a6b h1:/JvXcwT+y9SR0AN0fQIhIOz+9Uy9jhwpqqFEYxuTtTI= -maunium.net/go/mautrix v0.18.2-0.20240614094708-b456fb6e0a6b/go.mod h1:qdyAG5Uvdz3kdw3wCCz/FGnnwjoXK+/b6Iy3fRXnKM0= +maunium.net/go/mautrix v0.18.2-0.20240614100125-869a04dadbe4 h1:zyTy499oODvoaLBYKEWn7PNsWVmKVGzwNlSh32fR/Js= +maunium.net/go/mautrix v0.18.2-0.20240614100125-869a04dadbe4/go.mod h1:qdyAG5Uvdz3kdw3wCCz/FGnnwjoXK+/b6Iy3fRXnKM0= nhooyr.io/websocket v1.8.11 h1:f/qXNc2/3DpoSZkHt1DQu6rj4zGC8JmkkLkWss0MgN0= nhooyr.io/websocket v1.8.11/go.mod h1:rN9OFWIUwuxg4fR5tELlYC04bXYowCP9GX47ivo2l+c= From 94a2aacce51d163be49792cd08b0c419eda58308 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Sun, 16 Jun 2024 23:51:39 +0300 Subject: [PATCH 049/580] v2: Add GetTimeout for typing events --- pkg/connector/connector.go | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/pkg/connector/connector.go b/pkg/connector/connector.go index 864e3d8..24a2364 100644 --- a/pkg/connector/connector.go +++ b/pkg/connector/connector.go @@ -571,6 +571,7 @@ var ( _ bridgev2.RemoteReaction = (*Bv2ChatEvent)(nil) _ bridgev2.RemoteReactionRemove = (*Bv2ChatEvent)(nil) _ bridgev2.RemoteMessageRemove = (*Bv2ChatEvent)(nil) + _ bridgev2.RemoteTyping = (*Bv2ChatEvent)(nil) ) func (evt *Bv2ChatEvent) GetType() bridgev2.RemoteEventType { @@ -595,6 +596,14 @@ func (evt *Bv2ChatEvent) GetType() bridgev2.RemoteEventType { return bridgev2.RemoteEventUnknown } +func (evt *Bv2ChatEvent) GetTimeout() time.Duration { + if evt.Event.(*signalpb.TypingMessage).GetAction() == signalpb.TypingMessage_STARTED { + return 15 * time.Second + } else { + return 0 + } +} + func (evt *Bv2ChatEvent) GetPortalKey() networkid.PortalKey { key := networkid.PortalKey{ID: networkid.PortalID(evt.Info.ChatID)} // For non-group chats, add receiver From 00abe8099f55f4be9ea630f9e98aeaa91443877f Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Sun, 16 Jun 2024 23:52:05 +0300 Subject: [PATCH 050/580] Bump version to v0.6.2 --- CHANGELOG.md | 7 +++++++ go.mod | 10 +++++----- go.sum | 20 ++++++++++---------- main.go | 2 +- 4 files changed, 23 insertions(+), 16 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9c6bc06..cfad0bd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +# v0.6.2 (2024-06-16) + +* Fixed voice messages not being rendered correctly in Element X. +* Fixed contact avatars not being bridged correctly even when enabled in + the bridge config. +* Implemented connector for the upcoming bridgev2 architecture. + # v0.6.1 (2024-05-16) * Added support for bridging location messages from Matrix to Signal diff --git a/go.mod b/go.mod index 4d6711e..635898b 100644 --- a/go.mod +++ b/go.mod @@ -15,12 +15,12 @@ require ( github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e github.com/stretchr/testify v1.9.0 github.com/tidwall/gjson v1.17.1 - go.mau.fi/util v0.4.3-0.20240611132549-e72a5f4745e7 + go.mau.fi/util v0.5.0 golang.org/x/crypto v0.24.0 - golang.org/x/exp v0.0.0-20240604190554-fc45aab8b7f8 + golang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8 golang.org/x/net v0.26.0 - google.golang.org/protobuf v1.34.1 - maunium.net/go/mautrix v0.18.2-0.20240614100125-869a04dadbe4 + google.golang.org/protobuf v1.34.2 + maunium.net/go/mautrix v0.19.0-beta.1 nhooyr.io/websocket v1.8.11 ) @@ -41,7 +41,7 @@ require ( github.com/tidwall/match v1.1.1 // indirect github.com/tidwall/pretty v1.2.0 // indirect github.com/tidwall/sjson v1.2.5 // indirect - github.com/yuin/goldmark v1.7.1 // indirect + github.com/yuin/goldmark v1.7.2 // indirect go.mau.fi/zeroconfig v0.1.2 // indirect golang.org/x/sys v0.21.0 // indirect gopkg.in/natefinch/lumberjack.v2 v2.2.1 // indirect diff --git a/go.sum b/go.sum index 18026e7..49aba40 100644 --- a/go.sum +++ b/go.sum @@ -67,16 +67,16 @@ github.com/tidwall/pretty v1.2.0 h1:RWIZEg2iJ8/g6fDDYzMpobmaoGh5OLl4AXtGUGPcqCs= github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU= github.com/tidwall/sjson v1.2.5 h1:kLy8mja+1c9jlljvWTlSazM7cKDRfJuR/bOJhcY5NcY= github.com/tidwall/sjson v1.2.5/go.mod h1:Fvgq9kS/6ociJEDnK0Fk1cpYF4FIW6ZF7LAe+6jwd28= -github.com/yuin/goldmark v1.7.1 h1:3bajkSilaCbjdKVsKdZjZCLBNPL9pYzrCakKaf4U49U= -github.com/yuin/goldmark v1.7.1/go.mod h1:uzxRWxtg69N339t3louHJ7+O03ezfj6PlliRlaOzY1E= -go.mau.fi/util v0.4.3-0.20240611132549-e72a5f4745e7 h1:DviEWXBpeOlFrqIf5s/iBDp1ewZx8fe6imMJ78kq3tA= -go.mau.fi/util v0.4.3-0.20240611132549-e72a5f4745e7/go.mod h1:Eaj7jl37ehkA7S6vE/vfPs5PsY8e91FKZ2BqA3OM/NU= +github.com/yuin/goldmark v1.7.2 h1:NjGd7lO7zrUn/A7eKwn5PEOt4ONYGqpxSEeZuduvgxc= +github.com/yuin/goldmark v1.7.2/go.mod h1:uzxRWxtg69N339t3louHJ7+O03ezfj6PlliRlaOzY1E= +go.mau.fi/util v0.5.0 h1:8yELAl+1CDRrwGe9NUmREgVclSs26Z68pTWePHVxuDo= +go.mau.fi/util v0.5.0/go.mod h1:DsJzUrJAG53lCZnnYvq9/mOyLuPScWwYhvETiTrpdP4= go.mau.fi/zeroconfig v0.1.2 h1:DKOydWnhPMn65GbXZOafgkPm11BvFashZWLct0dGFto= go.mau.fi/zeroconfig v0.1.2/go.mod h1:NcSJkf180JT+1IId76PcMuLTNa1CzsFFZ0nBygIQM70= golang.org/x/crypto v0.24.0 h1:mnl8DM0o513X8fdIkmyFE/5hTYxbwYOjDS/+rK6qpRI= golang.org/x/crypto v0.24.0/go.mod h1:Z1PMYSOR5nyMcyAVAIQSKCDwalqy85Aqn1x3Ws4L5DM= -golang.org/x/exp v0.0.0-20240604190554-fc45aab8b7f8 h1:LoYXNGAShUG3m/ehNk4iFctuhGX/+R1ZpfJ4/ia80JM= -golang.org/x/exp v0.0.0-20240604190554-fc45aab8b7f8/go.mod h1:jj3sYF3dwk5D+ghuXyeI3r5MFf+NT2An6/9dOA95KSI= +golang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8 h1:yixxcjnhBmY0nkL253HFVIm0JsFHwrHdT3Yh6szTnfY= +golang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8/go.mod h1:jj3sYF3dwk5D+ghuXyeI3r5MFf+NT2An6/9dOA95KSI= golang.org/x/net v0.26.0 h1:soB7SVo0PWrY4vPW/+ay0jKDNScG2X9wFeYlXIvJsOQ= golang.org/x/net v0.26.0/go.mod h1:5YKkiSynbBIh3p6iOc/vibscux0x38BZDkn8sCUPxHE= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -84,8 +84,8 @@ golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.21.0 h1:rF+pYz3DAGSQAxAu1CbC7catZg4ebC4UIeIhKxBZvws= golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -google.golang.org/protobuf v1.34.1 h1:9ddQBjfCyZPOHPUiPxpYESBLc+T8P3E+Vo4IbKZgFWg= -google.golang.org/protobuf v1.34.1/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= +google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= +google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= @@ -95,7 +95,7 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= maunium.net/go/mauflag v1.0.0 h1:YiaRc0tEI3toYtJMRIfjP+jklH45uDHtT80nUamyD4M= maunium.net/go/mauflag v1.0.0/go.mod h1:nLivPOpTpHnpzEh8jEdSL9UqO9+/KBJFmNRlwKfkPeA= -maunium.net/go/mautrix v0.18.2-0.20240614100125-869a04dadbe4 h1:zyTy499oODvoaLBYKEWn7PNsWVmKVGzwNlSh32fR/Js= -maunium.net/go/mautrix v0.18.2-0.20240614100125-869a04dadbe4/go.mod h1:qdyAG5Uvdz3kdw3wCCz/FGnnwjoXK+/b6Iy3fRXnKM0= +maunium.net/go/mautrix v0.19.0-beta.1 h1:QGqcafucRwnKv/hPc8stGqUuZYZcHJ4PyCki7shMAXA= +maunium.net/go/mautrix v0.19.0-beta.1/go.mod h1:cxv1w6+syudmEpOewHYIQT9yO7TM5UOWmf6xEBVI4H4= nhooyr.io/websocket v1.8.11 h1:f/qXNc2/3DpoSZkHt1DQu6rj4zGC8JmkkLkWss0MgN0= nhooyr.io/websocket v1.8.11/go.mod h1:rN9OFWIUwuxg4fR5tELlYC04bXYowCP9GX47ivo2l+c= diff --git a/main.go b/main.go index 0a92c52..16dbd05 100644 --- a/main.go +++ b/main.go @@ -331,7 +331,7 @@ func main() { Name: "mautrix-signal", URL: "https://github.com/mautrix/signal", Description: "A Matrix-Signal puppeting bridge.", - Version: "0.6.1", + Version: "0.6.2", ProtocolName: "Signal", BeeperServiceName: "signal", BeeperNetworkName: "signal", From 6428e69426a9ecde50568dae31f5065b63ab302b Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Mon, 17 Jun 2024 14:18:13 +0300 Subject: [PATCH 051/580] changelog: add missed row --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index cfad0bd..f31a4c2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,6 @@ # v0.6.2 (2024-06-16) +* Updated to libsignal v0.51.0. * Fixed voice messages not being rendered correctly in Element X. * Fixed contact avatars not being bridged correctly even when enabled in the bridge config. From eb2106dd8f599a090fcf8fa141f7954b93cd673f Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Mon, 17 Jun 2024 14:18:45 +0300 Subject: [PATCH 052/580] provisioning: stop using libserv --- go.mod | 1 - go.sum | 2 -- provisioning.go | 2 +- 3 files changed, 1 insertion(+), 4 deletions(-) diff --git a/go.mod b/go.mod index 635898b..545d155 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,6 @@ module go.mau.fi/mautrix-signal go 1.21 require ( - github.com/beeper/libserv v0.0.0-20231231202820-c7303abfc32c github.com/emersion/go-vcard v0.0.0-20230815062825-8fda7d206ec9 github.com/google/uuid v1.6.0 github.com/gorilla/mux v1.8.0 diff --git a/go.sum b/go.sum index 49aba40..4667517 100644 --- a/go.sum +++ b/go.sum @@ -1,7 +1,5 @@ github.com/DATA-DOG/go-sqlmock v1.5.2 h1:OcvFkGmslmlZibjAjaHm3L//6LiuBgolP7OputlJIzU= github.com/DATA-DOG/go-sqlmock v1.5.2/go.mod h1:88MAG/4G7SMwSE3CeA0ZKzrT5CiOU3OJ+JlNzwDqpNU= -github.com/beeper/libserv v0.0.0-20231231202820-c7303abfc32c h1:WqjRVgUO039eiISCjsZC4F9onOEV93DJAk6v33rsZzY= -github.com/beeper/libserv v0.0.0-20231231202820-c7303abfc32c/go.mod h1:b9FFm9y4mEm36G8ytVmS1vkNzJa0KepmcdVY+qf7qRU= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= diff --git a/provisioning.go b/provisioning.go index 211bd46..3be384b 100644 --- a/provisioning.go +++ b/provisioning.go @@ -28,11 +28,11 @@ import ( "sync" "time" - "github.com/beeper/libserv/pkg/requestlog" "github.com/google/uuid" "github.com/gorilla/mux" "github.com/rs/zerolog" "github.com/rs/zerolog/hlog" + "go.mau.fi/util/requestlog" "maunium.net/go/mautrix" "maunium.net/go/mautrix/id" From a670cc4198b510a9bbceeacec049ae4b9b0702d2 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Mon, 17 Jun 2024 14:23:20 +0300 Subject: [PATCH 053/580] v2: add method for registering for push notifications --- go.mod | 2 +- go.sum | 4 +- pkg/connector/connector.go | 22 ++++++++++ pkg/signalmeow/pushreg.go | 82 ++++++++++++++++++++++++++++++++++++++ 4 files changed, 107 insertions(+), 3 deletions(-) create mode 100644 pkg/signalmeow/pushreg.go diff --git a/go.mod b/go.mod index 545d155..8a124e3 100644 --- a/go.mod +++ b/go.mod @@ -19,7 +19,7 @@ require ( golang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8 golang.org/x/net v0.26.0 google.golang.org/protobuf v1.34.2 - maunium.net/go/mautrix v0.19.0-beta.1 + maunium.net/go/mautrix v0.19.0-beta.1.0.20240617115738-3828c08f27fa nhooyr.io/websocket v1.8.11 ) diff --git a/go.sum b/go.sum index 4667517..436318e 100644 --- a/go.sum +++ b/go.sum @@ -93,7 +93,7 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= maunium.net/go/mauflag v1.0.0 h1:YiaRc0tEI3toYtJMRIfjP+jklH45uDHtT80nUamyD4M= maunium.net/go/mauflag v1.0.0/go.mod h1:nLivPOpTpHnpzEh8jEdSL9UqO9+/KBJFmNRlwKfkPeA= -maunium.net/go/mautrix v0.19.0-beta.1 h1:QGqcafucRwnKv/hPc8stGqUuZYZcHJ4PyCki7shMAXA= -maunium.net/go/mautrix v0.19.0-beta.1/go.mod h1:cxv1w6+syudmEpOewHYIQT9yO7TM5UOWmf6xEBVI4H4= +maunium.net/go/mautrix v0.19.0-beta.1.0.20240617115738-3828c08f27fa h1:9roSXY6+pcSY9jxnUprAi0gbbrUbFYcl5gAQSgNgXVs= +maunium.net/go/mautrix v0.19.0-beta.1.0.20240617115738-3828c08f27fa/go.mod h1:cxv1w6+syudmEpOewHYIQT9yO7TM5UOWmf6xEBVI4H4= nhooyr.io/websocket v1.8.11 h1:f/qXNc2/3DpoSZkHt1DQu6rj4zGC8JmkkLkWss0MgN0= nhooyr.io/websocket v1.8.11/go.mod h1:rN9OFWIUwuxg4fR5tELlYC04bXYowCP9GX47ivo2l+c= diff --git a/pkg/connector/connector.go b/pkg/connector/connector.go index 24a2364..3b0f44a 100644 --- a/pkg/connector/connector.go +++ b/pkg/connector/connector.go @@ -102,6 +102,7 @@ type SignalConnector struct { var _ bridgev2.NetworkConnector = (*SignalConnector)(nil) var _ bridgev2.MaxFileSizeingNetwork = (*SignalConnector)(nil) var _ bridgev2.NetworkAPI = (*SignalClient)(nil) +var _ bridgev2.PushableNetworkAPI = (*SignalClient)(nil) var _ msgconv.PortalMethods = (*msgconvPortalMethods)(nil) func NewConnector() *SignalConnector { @@ -232,6 +233,27 @@ type SignalClient struct { Client *signalmeow.Client } +var pushCfg = &bridgev2.PushConfig{ + FCM: &bridgev2.FCMPushConfig{ + // https://github.com/signalapp/Signal-Android/blob/main/app/src/main/res/values/firebase_messaging.xml#L4 + SenderID: "312334754206", + }, + APNs: &bridgev2.APNsPushConfig{ + BundleID: "org.whispersystems.signal", + }, +} + +func (s *SignalClient) GetPushConfigs() *bridgev2.PushConfig { + return pushCfg +} + +func (s *SignalClient) RegisterPushNotifications(ctx context.Context, pushType bridgev2.PushType, token string) error { + if pushType != bridgev2.PushTypeFCM { + return fmt.Errorf("unsupported push type: %s", pushType) + } + return s.Client.RegisterFCM(ctx, token) +} + func (s *SignalClient) LogoutRemote(ctx context.Context) { err := s.Client.StopReceiveLoops() if err != nil { diff --git a/pkg/signalmeow/pushreg.go b/pkg/signalmeow/pushreg.go new file mode 100644 index 0000000..fe45785 --- /dev/null +++ b/pkg/signalmeow/pushreg.go @@ -0,0 +1,82 @@ +// mautrix-signal - A Matrix-signal puppeting bridge. +// Copyright (C) 2024 Tulir Asokan +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +package signalmeow + +import ( + "context" + "encoding/json" + "fmt" + "net/http" + + "go.mau.fi/mautrix-signal/pkg/signalmeow/web" +) + +type ReqRegisterFCM struct { + GCMRegistrationID string `json:"gcmRegistrationId,omitempty"` + WebSocketChannel bool `json:"webSocketChannel"` +} + +type ReqRegisterAPNs struct { + APNRegistrationID string `json:"apnRegistrationId,omitempty"` + VoIPRegistrationID string `json:"voipRegistrationId,omitempty"` +} + +func (cli *Client) registerPush(ctx context.Context, pushType string, data any) error { + username, password := cli.Store.BasicAuthCreds() + req := &web.HTTPReqOpt{ + Username: &username, + Password: &password, + } + var method string + if data != nil { + method = http.MethodPut + req.ContentType = web.ContentTypeJSON + var err error + req.Body, err = json.Marshal(data) + if err != nil { + return err + } + } else { + method = http.MethodDelete + } + resp, err := web.SendHTTPRequest(ctx, method, "/v1/accounts/"+pushType, req) + if err != nil { + return err + } else if resp.StatusCode >= 300 || resp.StatusCode < 200 { + return fmt.Errorf("unexpected status code %d", resp.StatusCode) + } + return nil +} + +func (cli *Client) RegisterFCM(ctx context.Context, token string) error { + if token == "" { + return cli.registerPush(ctx, "gcm", nil) + } + return cli.registerPush(ctx, "gcm", &ReqRegisterFCM{ + GCMRegistrationID: token, + WebSocketChannel: true, + }) +} + +func (cli *Client) RegisterAPNs(ctx context.Context, token string) error { + if token == "" { + return cli.registerPush(ctx, "apn", nil) + } + return cli.registerPush(ctx, "apn", &ReqRegisterAPNs{ + APNRegistrationID: token, + }) +} From ec7f6db5edf1b842dc9bb20eb90955bbe114ef35 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Mon, 17 Jun 2024 16:44:16 +0300 Subject: [PATCH 054/580] v2: add clean shutdown --- go.mod | 2 +- go.sum | 4 ++-- pkg/connector/connector.go | 8 ++++++++ 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 8a124e3..001f1e6 100644 --- a/go.mod +++ b/go.mod @@ -19,7 +19,7 @@ require ( golang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8 golang.org/x/net v0.26.0 google.golang.org/protobuf v1.34.2 - maunium.net/go/mautrix v0.19.0-beta.1.0.20240617115738-3828c08f27fa + maunium.net/go/mautrix v0.19.0-beta.1.0.20240617130007-833995832be3 nhooyr.io/websocket v1.8.11 ) diff --git a/go.sum b/go.sum index 436318e..339257f 100644 --- a/go.sum +++ b/go.sum @@ -93,7 +93,7 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= maunium.net/go/mauflag v1.0.0 h1:YiaRc0tEI3toYtJMRIfjP+jklH45uDHtT80nUamyD4M= maunium.net/go/mauflag v1.0.0/go.mod h1:nLivPOpTpHnpzEh8jEdSL9UqO9+/KBJFmNRlwKfkPeA= -maunium.net/go/mautrix v0.19.0-beta.1.0.20240617115738-3828c08f27fa h1:9roSXY6+pcSY9jxnUprAi0gbbrUbFYcl5gAQSgNgXVs= -maunium.net/go/mautrix v0.19.0-beta.1.0.20240617115738-3828c08f27fa/go.mod h1:cxv1w6+syudmEpOewHYIQT9yO7TM5UOWmf6xEBVI4H4= +maunium.net/go/mautrix v0.19.0-beta.1.0.20240617130007-833995832be3 h1:FZ6uHxsDt9Z0/z8pgt6Ai+beV9+Te+RJBftgAgV7/r0= +maunium.net/go/mautrix v0.19.0-beta.1.0.20240617130007-833995832be3/go.mod h1:cxv1w6+syudmEpOewHYIQT9yO7TM5UOWmf6xEBVI4H4= nhooyr.io/websocket v1.8.11 h1:f/qXNc2/3DpoSZkHt1DQu6rj4zGC8JmkkLkWss0MgN0= nhooyr.io/websocket v1.8.11/go.mod h1:rN9OFWIUwuxg4fR5tELlYC04bXYowCP9GX47ivo2l+c= diff --git a/pkg/connector/connector.go b/pkg/connector/connector.go index 3b0f44a..dd7f60f 100644 --- a/pkg/connector/connector.go +++ b/pkg/connector/connector.go @@ -488,11 +488,19 @@ func (s *SignalClient) bridgeStateLoop(statusChan <-chan signalmeow.SignalConnec } } } + func (s *SignalClient) Connect(ctx context.Context) error { s.tryConnect(ctx, 0) return nil } +func (s *SignalClient) Disconnect() { + err := s.Client.StopReceiveLoops() + if err != nil { + s.UserLogin.Log.Err(err).Msg("Failed to stop receive loops") + } +} + func (s *SignalClient) tryConnect(ctx context.Context, retryCount int) { ch, err := s.Client.StartReceiveLoops(ctx) if err != nil { From 73fcf0c42c3b118ccb96df14a5765060fa3c1af6 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Mon, 17 Jun 2024 18:18:13 +0300 Subject: [PATCH 055/580] main: update mautrix-go --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 001f1e6..7f48ddb 100644 --- a/go.mod +++ b/go.mod @@ -19,7 +19,7 @@ require ( golang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8 golang.org/x/net v0.26.0 google.golang.org/protobuf v1.34.2 - maunium.net/go/mautrix v0.19.0-beta.1.0.20240617130007-833995832be3 + maunium.net/go/mautrix v0.19.0-beta.1.0.20240617151654-afeadfb15fee nhooyr.io/websocket v1.8.11 ) diff --git a/go.sum b/go.sum index 339257f..98e7437 100644 --- a/go.sum +++ b/go.sum @@ -93,7 +93,7 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= maunium.net/go/mauflag v1.0.0 h1:YiaRc0tEI3toYtJMRIfjP+jklH45uDHtT80nUamyD4M= maunium.net/go/mauflag v1.0.0/go.mod h1:nLivPOpTpHnpzEh8jEdSL9UqO9+/KBJFmNRlwKfkPeA= -maunium.net/go/mautrix v0.19.0-beta.1.0.20240617130007-833995832be3 h1:FZ6uHxsDt9Z0/z8pgt6Ai+beV9+Te+RJBftgAgV7/r0= -maunium.net/go/mautrix v0.19.0-beta.1.0.20240617130007-833995832be3/go.mod h1:cxv1w6+syudmEpOewHYIQT9yO7TM5UOWmf6xEBVI4H4= +maunium.net/go/mautrix v0.19.0-beta.1.0.20240617151654-afeadfb15fee h1:CQyItqakHeYb19uj1FAooHVMK53e45TjoINGmcnKsLc= +maunium.net/go/mautrix v0.19.0-beta.1.0.20240617151654-afeadfb15fee/go.mod h1:cxv1w6+syudmEpOewHYIQT9yO7TM5UOWmf6xEBVI4H4= nhooyr.io/websocket v1.8.11 h1:f/qXNc2/3DpoSZkHt1DQu6rj4zGC8JmkkLkWss0MgN0= nhooyr.io/websocket v1.8.11/go.mod h1:rN9OFWIUwuxg4fR5tELlYC04bXYowCP9GX47ivo2l+c= From ac75fae4e295f0dd94e60c6aa5e9bbf1df469ffe Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Mon, 17 Jun 2024 21:40:06 +0300 Subject: [PATCH 056/580] v2: add build scripts --- .gitignore | 1 + build-go-v2.sh | 9 +++++++++ build-v2.sh | 4 ++++ 3 files changed, 14 insertions(+) create mode 100755 build-go-v2.sh create mode 100755 build-v2.sh diff --git a/.gitignore b/.gitignore index c4d535d..0031287 100644 --- a/.gitignore +++ b/.gitignore @@ -7,5 +7,6 @@ /mautrix-signal /mautrix-signalgo +/mautrix-signal-v2 /start /libsignal_ffi.a diff --git a/build-go-v2.sh b/build-go-v2.sh new file mode 100755 index 0000000..199f474 --- /dev/null +++ b/build-go-v2.sh @@ -0,0 +1,9 @@ +#!/bin/sh +MAUTRIX_VERSION=$(cat go.mod | grep 'maunium.net/go/mautrix ' | awk '{ print $2 }') +GO_LDFLAGS="-X main.Tag=$(git describe --exact-match --tags 2>/dev/null) -X main.Commit=$(git rev-parse HEAD) -X 'main.BuildTime=`date -Iseconds`' -X 'maunium.net/go/mautrix.GoModVersion=$MAUTRIX_VERSION'" +if [ "$DBG" = 1 ]; then + GO_GCFLAGS='all=-N -l' +else + GO_LDFLAGS="-s -w ${GO_LDFLAGS}" +fi +go build -gcflags="$GO_GCFLAGS" -ldflags="$GO_LDFLAGS" -o mautrix-signal-v2 ./cmd/mautrix-signal-v2 "$@" diff --git a/build-v2.sh b/build-v2.sh new file mode 100755 index 0000000..b541932 --- /dev/null +++ b/build-v2.sh @@ -0,0 +1,4 @@ +#!/bin/sh +#./build-rust.sh +#cp -f pkg/libsignalgo/libsignal/target/release/libsignal_ffi.a . +LIBRARY_PATH=.:$LIBRARY_PATH ./build-go-v2.sh From 72cd8a3ca4068f9a83061ae2e402a8cad680f245 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Wed, 19 Jun 2024 15:15:12 +0300 Subject: [PATCH 057/580] v2: add disappearing messages --- go.mod | 2 +- go.sum | 4 +-- msgconv/from-signal.go | 2 +- msgconv/msgconv.go | 1 + pkg/connector/connector.go | 51 +++++++++++++++++++++++++++----------- pkg/connector/login.go | 14 +++++++---- 6 files changed, 51 insertions(+), 23 deletions(-) diff --git a/go.mod b/go.mod index 7f48ddb..fbcc2a0 100644 --- a/go.mod +++ b/go.mod @@ -19,7 +19,7 @@ require ( golang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8 golang.org/x/net v0.26.0 google.golang.org/protobuf v1.34.2 - maunium.net/go/mautrix v0.19.0-beta.1.0.20240617151654-afeadfb15fee + maunium.net/go/mautrix v0.19.0-beta.1.0.20240619092812-451658374280 nhooyr.io/websocket v1.8.11 ) diff --git a/go.sum b/go.sum index 98e7437..915da1a 100644 --- a/go.sum +++ b/go.sum @@ -93,7 +93,7 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= maunium.net/go/mauflag v1.0.0 h1:YiaRc0tEI3toYtJMRIfjP+jklH45uDHtT80nUamyD4M= maunium.net/go/mauflag v1.0.0/go.mod h1:nLivPOpTpHnpzEh8jEdSL9UqO9+/KBJFmNRlwKfkPeA= -maunium.net/go/mautrix v0.19.0-beta.1.0.20240617151654-afeadfb15fee h1:CQyItqakHeYb19uj1FAooHVMK53e45TjoINGmcnKsLc= -maunium.net/go/mautrix v0.19.0-beta.1.0.20240617151654-afeadfb15fee/go.mod h1:cxv1w6+syudmEpOewHYIQT9yO7TM5UOWmf6xEBVI4H4= +maunium.net/go/mautrix v0.19.0-beta.1.0.20240619092812-451658374280 h1:+EHJF8h7obPow7kDnsmGoWN+bTCjHGxCKaH99MldZUI= +maunium.net/go/mautrix v0.19.0-beta.1.0.20240619092812-451658374280/go.mod h1:cxv1w6+syudmEpOewHYIQT9yO7TM5UOWmf6xEBVI4H4= nhooyr.io/websocket v1.8.11 h1:f/qXNc2/3DpoSZkHt1DQu6rj4zGC8JmkkLkWss0MgN0= nhooyr.io/websocket v1.8.11/go.mod h1:rN9OFWIUwuxg4fR5tELlYC04bXYowCP9GX47ivo2l+c= diff --git a/msgconv/from-signal.go b/msgconv/from-signal.go index 9caecd6..8a4b5d1 100644 --- a/msgconv/from-signal.go +++ b/msgconv/from-signal.go @@ -173,7 +173,7 @@ func (mc *MessageConverter) ConvertDisappearingTimerChangeToMatrix(ctx context.C if timer == 0 { part.Content.Body = "Disappearing messages disabled" } - if updatePortal { + if updatePortal && !mc.NoUpdateDisappearing { portal := mc.GetData(ctx) portal.ExpirationTime = timer err := portal.Update(ctx) diff --git a/msgconv/msgconv.go b/msgconv/msgconv.go index 0e29157..33ac4a5 100644 --- a/msgconv/msgconv.go +++ b/msgconv/msgconv.go @@ -54,6 +54,7 @@ type MessageConverter struct { ConvertGIFToAPNG bool MaxFileSize int64 AsyncFiles bool + NoUpdateDisappearing bool LocationFormat string } diff --git a/pkg/connector/connector.go b/pkg/connector/connector.go index dd7f60f..cf6a51f 100644 --- a/pkg/connector/connector.go +++ b/pkg/connector/connector.go @@ -193,6 +193,7 @@ func (s *SignalConnector) Init(bridge *bridgev2.Bridge) { MaxFileSize: 50 * 1024 * 1024, AsyncFiles: true, LocationFormat: s.Config.LocationFormat, + NoUpdateDisappearing: true, } } @@ -764,11 +765,33 @@ func (evt *Bv2ChatEvent) ConvertMessage(ctx context.Context, portal *bridgev2.Po Content: part.Content, Extra: part.Extra, } - + } + var disappear database.DisappearingSetting + if converted.DisappearIn != 0 { + disappear = database.DisappearingSetting{ + Type: database.DisappearingTypeAfterRead, + Timer: time.Duration(converted.DisappearIn) * time.Second, + } + if evt.Info.Sender == evt.s.Client.Store.ACI { + disappear.DisappearAt = time.UnixMilli(int64(dataMsg.GetTimestamp())).Add(disappear.Timer) + } + if portal.Metadata.DisappearTimer != disappear.Timer { + portal.Metadata.DisappearType = disappear.Type + portal.Metadata.DisappearTimer = disappear.Timer + // TODO if the message doesn't have the DataMessage_EXPIRATION_TIMER_UPDATE, + // we should send a message to the portal notifying of the implicit update + err := portal.Save(ctx) + if err != nil { + zerolog.Ctx(ctx).Err(err).Msg("Failed to save portal metadata after updating disappearing timer") + } else { + zerolog.Ctx(ctx).Debug().Dur("new_timer", portal.Metadata.DisappearTimer).Msg("Updated disappearing timer in portal") + } + } } return &bridgev2.ConvertedMessage{ - ReplyTo: replyTo, - Parts: convertedParts, + ReplyTo: replyTo, + Parts: convertedParts, + Disappear: disappear, }, nil } @@ -945,7 +968,7 @@ func (s *SignalClient) handleSignalContactList(evt *events.ContactList) { } } -func (s *SignalClient) HandleMatrixMessage(ctx context.Context, msg *bridgev2.MatrixMessage) (message *database.Message, err error) { +func (s *SignalClient) HandleMatrixMessage(ctx context.Context, msg *bridgev2.MatrixMessage) (message *bridgev2.MatrixMessageResponse, err error) { mcCtx := &msgconvContext{ Connector: s.Main, Intent: nil, @@ -964,19 +987,20 @@ func (s *SignalClient) HandleMatrixMessage(ctx context.Context, msg *bridgev2.Ma } // TODO check result fmt.Println(res) - meta := map[string]any{ - "contains_attachments": len(converted.Attachments) > 0, - } dbMsg := &database.Message{ ID: makeMessageID(s.Client.Store.ACI, converted.GetTimestamp()), SenderID: makeUserID(s.Client.Store.ACI), Timestamp: time.UnixMilli(int64(converted.GetTimestamp())), - Metadata: meta, + } + dbMsg.Metadata.Extra = map[string]any{ + "contains_attachments": len(converted.Attachments) > 0, } if msg.ReplyTo != nil { dbMsg.RelatesToRowID = msg.ReplyTo.RowID } - return dbMsg, nil + return &bridgev2.MatrixMessageResponse{ + DB: dbMsg, + }, nil } func (s *SignalClient) HandleMatrixEdit(ctx context.Context, msg *bridgev2.MatrixEdit) error { @@ -1014,7 +1038,7 @@ func (s *SignalClient) HandleMatrixEdit(ctx context.Context, msg *bridgev2.Matri // TODO check result fmt.Println(res) msg.EditTarget.ID = makeMessageID(s.Client.Store.ACI, converted.GetTimestamp()) - msg.EditTarget.Metadata["contains_attachments"] = len(converted.Attachments) > 0 + msg.EditTarget.Metadata.Extra["contains_attachments"] = len(converted.Attachments) > 0 return nil } @@ -1070,7 +1094,6 @@ func (s *SignalClient) HandleMatrixReaction(ctx context.Context, msg *bridgev2.M } func (s *SignalClient) HandleMatrixReactionRemove(ctx context.Context, msg *bridgev2.MatrixReactionRemove) error { - emoji, _ := msg.TargetReaction.Metadata["emoji"].(string) targetAuthorACI, targetSentTimestamp, err := parseMessageID(msg.TargetReaction.MessageID) if err != nil { return fmt.Errorf("failed to parse target message ID: %w", err) @@ -1080,7 +1103,7 @@ func (s *SignalClient) HandleMatrixReactionRemove(ctx context.Context, msg *brid Timestamp: proto.Uint64(uint64(msg.Event.Timestamp)), RequiredProtocolVersion: proto.Uint32(uint32(signalpb.DataMessage_REACTIONS)), Reaction: &signalpb.DataMessage_Reaction{ - Emoji: proto.String(emoji), + Emoji: proto.String(msg.TargetReaction.Metadata.Emoji), Remove: proto.Bool(true), TargetAuthorAci: proto.String(targetAuthorACI.String()), TargetSentTimestamp: proto.Uint64(targetSentTimestamp), @@ -1199,7 +1222,7 @@ func (mpm *msgconvPortalMethods) GetSignalReply(ctx context.Context, content *ev AuthorAci: proto.String(string(mcCtx.ReplyTo.SenderID)), Type: signalpb.DataMessage_Quote_NORMAL.Enum(), } - if mcCtx.ReplyTo.Metadata["contains_attachments"] != false { + if mcCtx.ReplyTo.Metadata.Extra["contains_attachments"] != false { quote.Attachments = make([]*signalpb.DataMessage_Quote_QuotedAttachment, 1) } return quote @@ -1237,6 +1260,6 @@ func (mpm *msgconvPortalMethods) GetData(ctx context.Context) *legacydb.Portal { //Revision: portal.Metadata["revision"].(uint32), Encrypted: true, //RelayUserID: portal.Relay.UserMXID, - //ExpirationTime: portal.Metadata["expiration_timer"].(uint32), + ExpirationTime: uint32(portal.Metadata.DisappearTimer.Milliseconds()), } } diff --git a/pkg/connector/login.go b/pkg/connector/login.go index 4771b65..ecb12f7 100644 --- a/pkg/connector/login.go +++ b/pkg/connector/login.go @@ -136,9 +136,13 @@ func (qr *QRLogin) Wait(ctx context.Context) (*bridgev2.LoginStep, error) { if qr.Existing == nil { ul, err = qr.User.NewLogin(ctx, &database.UserLogin{ ID: newLoginID, - Metadata: map[string]any{ - "phone": signalPhone, - "remote_name": signalPhone, + Metadata: database.UserLoginMetadata{ + StandardUserLoginMetadata: database.StandardUserLoginMetadata{ + RemoteName: signalPhone, + }, + Extra: map[string]any{ + "phone": signalPhone, + }, }, }, nil) if err != nil { @@ -146,8 +150,8 @@ func (qr *QRLogin) Wait(ctx context.Context) (*bridgev2.LoginStep, error) { } } else { ul = qr.Existing - ul.Metadata["phone"] = signalPhone - ul.Metadata["remote_name"] = signalPhone + ul.Metadata.Extra["phone"] = signalPhone + ul.Metadata.RemoteName = signalPhone err = ul.Save(ctx) if err != nil { return nil, fmt.Errorf("failed to update existing login: %w", err) From 4d601ab465d3c95f380b136d7ec7bc3582326d22 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Wed, 19 Jun 2024 15:44:27 +0300 Subject: [PATCH 058/580] v2: add typing notifications --- go.mod | 2 +- go.sum | 4 ++-- pkg/connector/connector.go | 16 ++++++++++++++++ 3 files changed, 19 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index fbcc2a0..f3becff 100644 --- a/go.mod +++ b/go.mod @@ -19,7 +19,7 @@ require ( golang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8 golang.org/x/net v0.26.0 google.golang.org/protobuf v1.34.2 - maunium.net/go/mautrix v0.19.0-beta.1.0.20240619092812-451658374280 + maunium.net/go/mautrix v0.19.0-beta.1.0.20240619124218-2e23f6372f66 nhooyr.io/websocket v1.8.11 ) diff --git a/go.sum b/go.sum index 915da1a..6c6d36b 100644 --- a/go.sum +++ b/go.sum @@ -93,7 +93,7 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= maunium.net/go/mauflag v1.0.0 h1:YiaRc0tEI3toYtJMRIfjP+jklH45uDHtT80nUamyD4M= maunium.net/go/mauflag v1.0.0/go.mod h1:nLivPOpTpHnpzEh8jEdSL9UqO9+/KBJFmNRlwKfkPeA= -maunium.net/go/mautrix v0.19.0-beta.1.0.20240619092812-451658374280 h1:+EHJF8h7obPow7kDnsmGoWN+bTCjHGxCKaH99MldZUI= -maunium.net/go/mautrix v0.19.0-beta.1.0.20240619092812-451658374280/go.mod h1:cxv1w6+syudmEpOewHYIQT9yO7TM5UOWmf6xEBVI4H4= +maunium.net/go/mautrix v0.19.0-beta.1.0.20240619124218-2e23f6372f66 h1:O7IzqKzbgIPwosfI4nJg97JM1JKP4+KuMCploezxQpI= +maunium.net/go/mautrix v0.19.0-beta.1.0.20240619124218-2e23f6372f66/go.mod h1:cxv1w6+syudmEpOewHYIQT9yO7TM5UOWmf6xEBVI4H4= nhooyr.io/websocket v1.8.11 h1:f/qXNc2/3DpoSZkHt1DQu6rj4zGC8JmkkLkWss0MgN0= nhooyr.io/websocket v1.8.11/go.mod h1:rN9OFWIUwuxg4fR5tELlYC04bXYowCP9GX47ivo2l+c= diff --git a/pkg/connector/connector.go b/pkg/connector/connector.go index cf6a51f..d9e71c1 100644 --- a/pkg/connector/connector.go +++ b/pkg/connector/connector.go @@ -1195,6 +1195,22 @@ func (s *SignalClient) HandleMatrixReadReceipt(ctx context.Context, receipt *bri return nil } +func (s *SignalClient) HandleMatrixTyping(ctx context.Context, typing *bridgev2.MatrixTyping) error { + userID, _, err := s.parsePortalID(typing.Portal.ID) + if err != nil { + return err + } + // Only send typing notifications in DMs for now + // Sending efficiently to groups requires implementing the proper SenderKey stuff first + if !userID.IsEmpty() && userID.Type == libsignalgo.ServiceIDTypeACI { + typingMessage := signalmeow.TypingMessage(typing.IsTyping) + result := s.Client.SendMessage(ctx, userID, typingMessage) + fmt.Println(result) + // TODO check result + } + return nil +} + type msgconvPortalMethods struct{} func (mpm *msgconvPortalMethods) UploadMatrixMedia(ctx context.Context, data []byte, fileName, contentType string) (id.ContentURIString, error) { From e37ad78f55a262284dadb48890c0b67f17910a4f Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Wed, 19 Jun 2024 22:59:44 +0300 Subject: [PATCH 059/580] v2: add support for starting DMs and ACI found events --- go.mod | 2 +- go.sum | 4 +- pkg/connector/connector.go | 188 +++++++++++++++++++++++++++++++------ 3 files changed, 164 insertions(+), 30 deletions(-) diff --git a/go.mod b/go.mod index f3becff..fd1ea3f 100644 --- a/go.mod +++ b/go.mod @@ -19,7 +19,7 @@ require ( golang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8 golang.org/x/net v0.26.0 google.golang.org/protobuf v1.34.2 - maunium.net/go/mautrix v0.19.0-beta.1.0.20240619124218-2e23f6372f66 + maunium.net/go/mautrix v0.19.0-beta.1.0.20240619195836-2a7a5070fb32 nhooyr.io/websocket v1.8.11 ) diff --git a/go.sum b/go.sum index 6c6d36b..a6c0ff3 100644 --- a/go.sum +++ b/go.sum @@ -93,7 +93,7 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= maunium.net/go/mauflag v1.0.0 h1:YiaRc0tEI3toYtJMRIfjP+jklH45uDHtT80nUamyD4M= maunium.net/go/mauflag v1.0.0/go.mod h1:nLivPOpTpHnpzEh8jEdSL9UqO9+/KBJFmNRlwKfkPeA= -maunium.net/go/mautrix v0.19.0-beta.1.0.20240619124218-2e23f6372f66 h1:O7IzqKzbgIPwosfI4nJg97JM1JKP4+KuMCploezxQpI= -maunium.net/go/mautrix v0.19.0-beta.1.0.20240619124218-2e23f6372f66/go.mod h1:cxv1w6+syudmEpOewHYIQT9yO7TM5UOWmf6xEBVI4H4= +maunium.net/go/mautrix v0.19.0-beta.1.0.20240619195836-2a7a5070fb32 h1:BiUVpB1hejeuCivlLOv5jKzU/Y8TTwDlQ0i1qO+JGdI= +maunium.net/go/mautrix v0.19.0-beta.1.0.20240619195836-2a7a5070fb32/go.mod h1:cxv1w6+syudmEpOewHYIQT9yO7TM5UOWmf6xEBVI4H4= nhooyr.io/websocket v1.8.11 h1:f/qXNc2/3DpoSZkHt1DQu6rj4zGC8JmkkLkWss0MgN0= nhooyr.io/websocket v1.8.11/go.mod h1:rN9OFWIUwuxg4fR5tELlYC04bXYowCP9GX47ivo2l+c= diff --git a/pkg/connector/connector.go b/pkg/connector/connector.go index d9e71c1..cb1788d 100644 --- a/pkg/connector/connector.go +++ b/pkg/connector/connector.go @@ -19,6 +19,7 @@ package connector import ( "context" _ "embed" + "errors" "fmt" "strconv" "strings" @@ -103,6 +104,7 @@ var _ bridgev2.NetworkConnector = (*SignalConnector)(nil) var _ bridgev2.MaxFileSizeingNetwork = (*SignalConnector)(nil) var _ bridgev2.NetworkAPI = (*SignalClient)(nil) var _ bridgev2.PushableNetworkAPI = (*SignalClient)(nil) +var _ bridgev2.GroupCreatingNetworkAPI = (*SignalClient)(nil) var _ msgconv.PortalMethods = (*msgconvPortalMethods)(nil) func NewConnector() *SignalConnector { @@ -323,13 +325,13 @@ func (s *SignalClient) GetChatInfo(ctx context.Context, portal *bridgev2.Portal) if err != nil { return nil, err } - isSpace := false if groupID != "" { groupInfo, err := s.Client.RetrieveGroupByID(ctx, groupID, 0) if err != nil { return nil, err } isDM := false + isSpace := false members := make([]networkid.UserID, len(groupInfo.Members)) for i, member := range groupInfo.Members { members[i] = makeUserID(member.ACI) @@ -348,41 +350,127 @@ func (s *SignalClient) GetChatInfo(ctx context.Context, portal *bridgev2.Portal) IsDirectChat: &isDM, IsSpace: &isSpace, }, nil - } else if userID.Type == libsignalgo.ServiceIDTypePNI { - contact, err := s.Client.Store.RecipientStore.LoadAndUpdateRecipient(ctx, uuid.Nil, userID.UUID, nil) + } else { + aci, pni := serviceIDToACIAndPNI(userID) + contact, err := s.Client.Store.RecipientStore.LoadAndUpdateRecipient(ctx, aci, pni, nil) if err != nil { return nil, err } - var topic, name string - name = s.Main.Config.FormatDisplayname(contact) - if s.Main.Config.NumberInTopic && contact.E164 != "" { - topic = fmt.Sprintf("") - // TODO set topic + return s.makeCreateDMResponse(contact).PortalInfo, nil + } +} + +func (s *SignalClient) ResolveIdentifier(ctx context.Context, number string, createChat bool) (*bridgev2.ResolveIdentifierResponse, error) { + number, err := bridgev2.CleanPhoneNumber(number) + if err != nil { + return nil, err + } + e164Number, err := strconv.ParseUint(strings.TrimPrefix(number, "+"), 10, 64) + if err != nil { + return nil, fmt.Errorf("error parsing phone number: %w", err) + } + e164String := fmt.Sprintf("+%d", e164Number) + var aci, pni uuid.UUID + var recipient *types.Recipient + if recipient, err = s.Client.ContactByE164(ctx, e164String); err != nil { + return nil, fmt.Errorf("error looking up number in local contact list: %w", err) + } else if recipient != nil { + aci = recipient.ACI + pni = recipient.PNI + } else if resp, err := s.Client.LookupPhone(ctx, e164Number); err != nil { + return nil, fmt.Errorf("error looking up number on server: %w", err) + } else { + aci = resp[e164Number].ACI + pni = resp[e164Number].PNI + if aci == uuid.Nil && pni == uuid.Nil { + return nil, errors.New("user not found on Signal") } - isDM := true - return &bridgev2.PortalInfo{ - Members: []networkid.UserID{makeUserID(s.Client.Store.ACI)}, - Name: &name, - Topic: &topic, - IsDirectChat: &isDM, - IsSpace: &isSpace, + recipient, err = s.Client.Store.RecipientStore.UpdateRecipientE164(ctx, aci, pni, e164String) + if err != nil { + zerolog.Ctx(ctx).Err(err).Msg("Failed to save recipient entry after looking up phone") + } + aci, pni = recipient.ACI, recipient.PNI + } + zerolog.Ctx(ctx).Debug(). + Uint64("e164", e164Number). + Stringer("aci", aci). + Stringer("pni", pni). + Msg("Found resolve identifier target user") + + // createChat is a no-op: chats don't need to be created, and we always return chat info + if aci != uuid.Nil { + ghost, err := s.Main.Bridge.GetGhostByID(ctx, makeUserID(aci)) + if err != nil { + return nil, fmt.Errorf("failed to get ghost: %w", err) + } + return &bridgev2.ResolveIdentifierResponse{ + UserID: makeUserID(aci), + UserInfo: s.contactToUserInfo(recipient), + Ghost: ghost, + Chat: s.makeCreateDMResponse(recipient), }, nil } else { - var topic, name string - if s.Main.Config.NumberInTopic { - // TODO set topic - } - isDM := true - return &bridgev2.PortalInfo{ - Members: []networkid.UserID{makeUserID(userID.UUID), makeUserID(s.Client.Store.ACI)}, - Name: &name, - Topic: &topic, - IsDirectChat: &isDM, - IsSpace: &isSpace, + return &bridgev2.ResolveIdentifierResponse{ + UserID: makeUserIDFromServiceID(libsignalgo.NewPNIServiceID(pni)), + UserInfo: s.contactToUserInfo(recipient), + Chat: s.makeCreateDMResponse(recipient), }, nil } } +const PrivateChatTopic = "Signal private chat" +const NoteToSelfName = "Signal Note to Self" + +func serviceIDToACIAndPNI(serviceID libsignalgo.ServiceID) (aci, pni uuid.UUID) { + if serviceID.Type == libsignalgo.ServiceIDTypeACI { + return serviceID.UUID, uuid.Nil + } else { + return uuid.Nil, serviceID.UUID + } +} + +func (s *SignalClient) makeCreateDMResponse(recipient *types.Recipient) *bridgev2.CreateChatResponse { + isDirectChat := true + isSpace := false + name := "" + topic := PrivateChatTopic + members := []networkid.UserID{makeUserID(s.Client.Store.ACI)} + if s.Main.Config.NumberInTopic && recipient.E164 != "" { + topic = fmt.Sprintf("%s with %s", PrivateChatTopic, recipient.E164) + } + var serviceID libsignalgo.ServiceID + if recipient.ACI == uuid.Nil { + name = s.Main.Config.FormatDisplayname(recipient) + serviceID = libsignalgo.NewPNIServiceID(recipient.PNI) + } else { + if recipient.ACI == s.Client.Store.ACI { + name = NoteToSelfName + } else { + // The other user is only present if their ACI is known + members = append(members, makeUserID(recipient.ACI)) + } + serviceID = libsignalgo.NewACIServiceID(recipient.ACI) + } + return &bridgev2.CreateChatResponse{ + PortalID: networkid.PortalKey{ + ID: networkid.PortalID(serviceID.String()), + Receiver: s.UserLogin.ID, + }, + PortalInfo: &bridgev2.PortalInfo{ + Name: &name, + Topic: &topic, + Members: members, + IsDirectChat: &isDirectChat, + IsSpace: &isSpace, + }, + } +} + +func (s *SignalClient) CreateGroup(ctx context.Context, name string, users ...networkid.UserID) (*bridgev2.CreateChatResponse, error) { + //TODO implement me + return nil, fmt.Errorf("not implemented") +} + func (s *SignalClient) IsThisUser(_ context.Context, userID networkid.UserID) bool { return userID == makeUserID(s.Client.Store.ACI) } @@ -525,7 +613,18 @@ func (s *SignalClient) IsLoggedIn() bool { } func parseUserID(userID networkid.UserID) (uuid.UUID, error) { - return uuid.Parse(string(userID)) + serviceID, err := parseUserIDAsServiceID(userID) + if err != nil { + return uuid.Nil, err + } else if serviceID.Type != libsignalgo.ServiceIDTypeACI { + return uuid.Nil, fmt.Errorf("invalid user ID: expected ACI type") + } else { + return serviceID.UUID, nil + } +} + +func parseUserIDAsServiceID(userID networkid.UserID) (libsignalgo.ServiceID, error) { + return libsignalgo.ServiceIDFromString(string(userID)) } func (s *SignalClient) parsePortalID(portalID networkid.PortalID) (userID libsignalgo.ServiceID, groupID types.GroupIdentifier, err error) { @@ -559,6 +658,10 @@ func makeUserID(user uuid.UUID) networkid.UserID { return networkid.UserID(user.String()) } +func makeUserIDFromServiceID(user libsignalgo.ServiceID) networkid.UserID { + return networkid.UserID(user.String()) +} + func makeUserLoginID(user uuid.UUID) networkid.UserLoginID { return networkid.UserLoginID(user.String()) } @@ -944,6 +1047,37 @@ func (s *SignalClient) handleSignalEvent(rawEvt events.SignalEvent) { case *events.ContactList: s.handleSignalContactList(evt) case *events.ACIFound: + s.handleSignalACIFound(evt) + } +} + +func (s *SignalClient) handleSignalACIFound(evt *events.ACIFound) { + log := s.UserLogin.Log.With(). + Str("action", "handle aci found"). + Stringer("aci", evt.ACI). + Stringer("pni", evt.PNI). + Logger() + ctx := log.WithContext(context.TODO()) + pniPortalKey := networkid.PortalKey{ + ID: networkid.PortalID(evt.PNI.String()), + Receiver: s.UserLogin.ID, + } + aciPortalKey := networkid.PortalKey{ + ID: networkid.PortalID(evt.ACI.String()), + Receiver: s.UserLogin.ID, + } + result, portal, err := s.Main.Bridge.ReIDPortal(ctx, pniPortalKey, aciPortalKey) + if err != nil { + log.Err(err).Msg("Failed to re-ID portal") + } else if result == bridgev2.ReIDResultSourceReIDd || result == bridgev2.ReIDResultTargetDeletedAndSourceReIDd { + // If the source portal is re-ID'd, we need to sync metadata and participants. + // If the source is deleted, then it doesn't matter, any existing target will already be correct + info, err := s.GetChatInfo(ctx, portal) + if err != nil { + log.Err(err).Msg("Failed to get chat info to update portal after re-ID") + } else { + portal.UpdateInfo(ctx, info, s.UserLogin, nil, time.Time{}) + } } } From d06f4b5aa4b558933a4311ac3e2be7ce095961cb Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Wed, 19 Jun 2024 23:21:52 +0300 Subject: [PATCH 060/580] v2: split connector into multiple files --- pkg/connector/chatinfo.go | 233 ++++++ pkg/connector/client.go | 197 +++++ pkg/connector/config.go | 86 +++ pkg/connector/connector.go | 1264 --------------------------------- pkg/connector/handlematrix.go | 278 ++++++++ pkg/connector/handlesignal.go | 431 +++++++++++ pkg/connector/id.go | 130 ++++ pkg/connector/msgconvproxy.go | 115 +++ 8 files changed, 1470 insertions(+), 1264 deletions(-) create mode 100644 pkg/connector/chatinfo.go create mode 100644 pkg/connector/client.go create mode 100644 pkg/connector/config.go create mode 100644 pkg/connector/handlematrix.go create mode 100644 pkg/connector/handlesignal.go create mode 100644 pkg/connector/id.go create mode 100644 pkg/connector/msgconvproxy.go diff --git a/pkg/connector/chatinfo.go b/pkg/connector/chatinfo.go new file mode 100644 index 0000000..eea4381 --- /dev/null +++ b/pkg/connector/chatinfo.go @@ -0,0 +1,233 @@ +// mautrix-signal - A Matrix-Signal puppeting bridge. +// Copyright (C) 2024 Tulir Asokan +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +package connector + +import ( + "context" + "errors" + "fmt" + "strconv" + "strings" + + "github.com/google/uuid" + "github.com/rs/zerolog" + "maunium.net/go/mautrix/bridgev2" + "maunium.net/go/mautrix/bridgev2/networkid" + + "go.mau.fi/mautrix-signal/pkg/libsignalgo" + "go.mau.fi/mautrix-signal/pkg/signalmeow/types" +) + +const PrivateChatTopic = "Signal private chat" +const NoteToSelfName = "Signal Note to Self" + +func (s *SignalClient) GetUserInfo(ctx context.Context, ghost *bridgev2.Ghost) (*bridgev2.UserInfo, error) { + userID, err := parseUserID(ghost.ID) + if err != nil { + return nil, err + } + contact, err := s.Client.ContactByACI(ctx, userID) + if err != nil { + return nil, err + } + return s.contactToUserInfo(contact), nil +} + +func (s *SignalClient) GetChatInfo(ctx context.Context, portal *bridgev2.Portal) (*bridgev2.PortalInfo, error) { + userID, groupID, err := s.parsePortalID(portal.ID) + if err != nil { + return nil, err + } + if groupID != "" { + groupInfo, err := s.Client.RetrieveGroupByID(ctx, groupID, 0) + if err != nil { + return nil, err + } + isDM := false + isSpace := false + members := make([]networkid.UserID, len(groupInfo.Members)) + for i, member := range groupInfo.Members { + members[i] = makeUserID(member.ACI) + } + return &bridgev2.PortalInfo{ + Name: &groupInfo.Title, + Topic: &groupInfo.Description, + Avatar: &bridgev2.Avatar{ + ID: makeAvatarPathID(groupInfo.AvatarPath), + Get: func(ctx context.Context) ([]byte, error) { + return s.Client.DownloadGroupAvatar(ctx, groupInfo) + }, + Remove: groupInfo.AvatarPath == "", + }, + Members: members, + IsDirectChat: &isDM, + IsSpace: &isSpace, + }, nil + } else { + aci, pni := serviceIDToACIAndPNI(userID) + contact, err := s.Client.Store.RecipientStore.LoadAndUpdateRecipient(ctx, aci, pni, nil) + if err != nil { + return nil, err + } + return s.makeCreateDMResponse(contact).PortalInfo, nil + } +} + +func (s *SignalClient) contactToUserInfo(contact *types.Recipient) *bridgev2.UserInfo { + isBot := false + ui := &bridgev2.UserInfo{ + IsBot: &isBot, + } + name := s.Main.Config.FormatDisplayname(contact) + ui.Name = &name + if s.Main.Config.UseContactAvatars && contact.ContactAvatar.Hash != "" { + ui.Avatar = &bridgev2.Avatar{ + ID: networkid.AvatarID("hash:" + contact.ContactAvatar.Hash), + Get: func(ctx context.Context) ([]byte, error) { + if contact.ContactAvatar.Image == nil { + return nil, fmt.Errorf("contact avatar not available") + } + return contact.ContactAvatar.Image, nil + }, + } + } else if contact.Profile.AvatarPath != "" { + ui.Avatar = &bridgev2.Avatar{ + ID: makeAvatarPathID(contact.Profile.AvatarPath), + Get: func(ctx context.Context) ([]byte, error) { + return s.Client.DownloadUserAvatar(ctx, contact.Profile.AvatarPath, contact.Profile.Key) + }, + } + } else { + ui.Avatar = &bridgev2.Avatar{ + ID: "", + Remove: true, + } + } + return ui +} + +func (s *SignalClient) ResolveIdentifier(ctx context.Context, number string, createChat bool) (*bridgev2.ResolveIdentifierResponse, error) { + number, err := bridgev2.CleanPhoneNumber(number) + if err != nil { + return nil, err + } + e164Number, err := strconv.ParseUint(strings.TrimPrefix(number, "+"), 10, 64) + if err != nil { + return nil, fmt.Errorf("error parsing phone number: %w", err) + } + e164String := fmt.Sprintf("+%d", e164Number) + var aci, pni uuid.UUID + var recipient *types.Recipient + if recipient, err = s.Client.ContactByE164(ctx, e164String); err != nil { + return nil, fmt.Errorf("error looking up number in local contact list: %w", err) + } else if recipient != nil { + aci = recipient.ACI + pni = recipient.PNI + } else if resp, err := s.Client.LookupPhone(ctx, e164Number); err != nil { + return nil, fmt.Errorf("error looking up number on server: %w", err) + } else { + aci = resp[e164Number].ACI + pni = resp[e164Number].PNI + if aci == uuid.Nil && pni == uuid.Nil { + return nil, errors.New("user not found on Signal") + } + recipient, err = s.Client.Store.RecipientStore.UpdateRecipientE164(ctx, aci, pni, e164String) + if err != nil { + zerolog.Ctx(ctx).Err(err).Msg("Failed to save recipient entry after looking up phone") + } + aci, pni = recipient.ACI, recipient.PNI + } + zerolog.Ctx(ctx).Debug(). + Uint64("e164", e164Number). + Stringer("aci", aci). + Stringer("pni", pni). + Msg("Found resolve identifier target user") + + // createChat is a no-op: chats don't need to be created, and we always return chat info + if aci != uuid.Nil { + ghost, err := s.Main.Bridge.GetGhostByID(ctx, makeUserID(aci)) + if err != nil { + return nil, fmt.Errorf("failed to get ghost: %w", err) + } + return &bridgev2.ResolveIdentifierResponse{ + UserID: makeUserID(aci), + UserInfo: s.contactToUserInfo(recipient), + Ghost: ghost, + Chat: s.makeCreateDMResponse(recipient), + }, nil + } else { + return &bridgev2.ResolveIdentifierResponse{ + UserID: makeUserIDFromServiceID(libsignalgo.NewPNIServiceID(pni)), + UserInfo: s.contactToUserInfo(recipient), + Chat: s.makeCreateDMResponse(recipient), + }, nil + } +} + +func (s *SignalClient) CreateGroup(ctx context.Context, name string, users ...networkid.UserID) (*bridgev2.CreateChatResponse, error) { + //TODO implement me + return nil, fmt.Errorf("not implemented") +} + +func (s *SignalClient) makeCreateDMResponse(recipient *types.Recipient) *bridgev2.CreateChatResponse { + isDirectChat := true + isSpace := false + name := "" + topic := PrivateChatTopic + members := []networkid.UserID{makeUserID(s.Client.Store.ACI)} + if s.Main.Config.NumberInTopic && recipient.E164 != "" { + topic = fmt.Sprintf("%s with %s", PrivateChatTopic, recipient.E164) + } + var serviceID libsignalgo.ServiceID + if recipient.ACI == uuid.Nil { + name = s.Main.Config.FormatDisplayname(recipient) + serviceID = libsignalgo.NewPNIServiceID(recipient.PNI) + } else { + if recipient.ACI == s.Client.Store.ACI { + name = NoteToSelfName + } else { + // The other user is only present if their ACI is known + members = append(members, makeUserID(recipient.ACI)) + } + serviceID = libsignalgo.NewACIServiceID(recipient.ACI) + } + return &bridgev2.CreateChatResponse{ + PortalID: s.makeDMPortalKey(serviceID), + PortalInfo: &bridgev2.PortalInfo{ + Name: &name, + Topic: &topic, + Members: members, + IsDirectChat: &isDirectChat, + IsSpace: &isSpace, + }, + } +} + +func makeAvatarPathID(avatarPath string) networkid.AvatarID { + if avatarPath == "" { + return "" + } + return networkid.AvatarID("path:" + avatarPath) +} + +func serviceIDToACIAndPNI(serviceID libsignalgo.ServiceID) (aci, pni uuid.UUID) { + if serviceID.Type == libsignalgo.ServiceIDTypeACI { + return serviceID.UUID, uuid.Nil + } else { + return uuid.Nil, serviceID.UUID + } +} diff --git a/pkg/connector/client.go b/pkg/connector/client.go new file mode 100644 index 0000000..6034a7c --- /dev/null +++ b/pkg/connector/client.go @@ -0,0 +1,197 @@ +package connector + +import ( + "context" + "fmt" + "time" + + "github.com/rs/zerolog" + "maunium.net/go/mautrix/bridge/status" + "maunium.net/go/mautrix/bridgev2" + "maunium.net/go/mautrix/bridgev2/networkid" + + "go.mau.fi/mautrix-signal/pkg/signalmeow" +) + +type SignalClient struct { + Main *SignalConnector + UserLogin *bridgev2.UserLogin + Client *signalmeow.Client +} + +var _ bridgev2.NetworkAPI = (*SignalClient)(nil) +var _ bridgev2.PushableNetworkAPI = (*SignalClient)(nil) +var _ bridgev2.GroupCreatingNetworkAPI = (*SignalClient)(nil) + +var pushCfg = &bridgev2.PushConfig{ + FCM: &bridgev2.FCMPushConfig{ + // https://github.com/signalapp/Signal-Android/blob/main/app/src/main/res/values/firebase_messaging.xml#L4 + SenderID: "312334754206", + }, + APNs: &bridgev2.APNsPushConfig{ + BundleID: "org.whispersystems.signal", + }, +} + +func (s *SignalClient) GetPushConfigs() *bridgev2.PushConfig { + return pushCfg +} + +func (s *SignalClient) RegisterPushNotifications(ctx context.Context, pushType bridgev2.PushType, token string) error { + if pushType != bridgev2.PushTypeFCM { + return fmt.Errorf("unsupported push type: %s", pushType) + } + return s.Client.RegisterFCM(ctx, token) +} + +func (s *SignalClient) LogoutRemote(ctx context.Context) { + err := s.Client.StopReceiveLoops() + if err != nil { + zerolog.Ctx(ctx).Err(err).Msg("Failed to stop receive loops for logout") + } + err = s.Main.Store.DeleteDevice(context.TODO(), &s.Client.Store.DeviceData) + if err != nil { + zerolog.Ctx(ctx).Err(err).Msg("Failed to delete device from store") + } +} + +func (s *SignalClient) IsThisUser(_ context.Context, userID networkid.UserID) bool { + return userID == makeUserID(s.Client.Store.ACI) +} + +func (s *SignalClient) bridgeStateLoop(statusChan <-chan signalmeow.SignalConnectionStatus) { + var peekedConnectionStatus signalmeow.SignalConnectionStatus + for { + var connectionStatus signalmeow.SignalConnectionStatus + if peekedConnectionStatus.Event != signalmeow.SignalConnectionEventNone { + s.UserLogin.Log.Debug(). + Stringer("peeked_connection_status_event", peekedConnectionStatus.Event). + Msg("Using peeked connectionStatus event") + connectionStatus = peekedConnectionStatus + peekedConnectionStatus = signalmeow.SignalConnectionStatus{} + } else { + var ok bool + connectionStatus, ok = <-statusChan + if !ok { + s.UserLogin.Log.Debug().Msg("statusChan channel closed") + return + } + } + + err := connectionStatus.Err + switch connectionStatus.Event { + case signalmeow.SignalConnectionEventConnected: + s.UserLogin.Log.Debug().Msg("Sending Connected BridgeState") + s.UserLogin.BridgeState.Send(status.BridgeState{StateEvent: status.StateConnected}) + + case signalmeow.SignalConnectionEventDisconnected: + s.UserLogin.Log.Debug().Msg("Received SignalConnectionEventDisconnected") + + // Debounce: wait 7s before sending TransientDisconnect, in case we get a reconnect + // We should wait until the next message comes in, or 7 seconds has passed. + // - If a disconnected event comes in, just loop again, unless it's been more than 7 seconds. + // - If a non-disconnected event comes in, store it in peekedConnectionStatus, + // break out of this loop and go back to the top of the goroutine to handle it in the switch. + // - If 7 seconds passes without any non-disconnect messages, send the TransientDisconnect. + // (Why 7 seconds? It was 5 at first, but websockets min retry is 5 seconds, + // so it would send TransientDisconnect right before reconnecting. 7 seems to work well.) + debounceTimer := time.NewTimer(7 * time.Second) + PeekLoop: + for { + var ok bool + select { + case peekedConnectionStatus, ok = <-statusChan: + // Handle channel closing + if !ok { + s.UserLogin.Log.Debug().Msg("connectionStatus channel closed") + return + } + // If it's another Disconnected event, just keep looping + if peekedConnectionStatus.Event == signalmeow.SignalConnectionEventDisconnected { + peekedConnectionStatus = signalmeow.SignalConnectionStatus{} + continue + } + // If it's a non-disconnect event, break out of the PeekLoop and handle it in the switch + break PeekLoop + case <-debounceTimer.C: + // Time is up, so break out of the loop and send the TransientDisconnect + break PeekLoop + } + } + // We're out of the PeekLoop, so either we got a non-disconnect event, or it's been 7 seconds (or both). + // We want to send TransientDisconnect if it's been 7 seconds, but not if the latest event was something + // other than Disconnected + if !debounceTimer.Stop() { // If the timer has already expired + // Send TransientDisconnect only if the latest event is a disconnect or no event + // (peekedConnectionStatus could be something else if the timer and the event race) + if peekedConnectionStatus.Event == signalmeow.SignalConnectionEventDisconnected || + peekedConnectionStatus.Event == signalmeow.SignalConnectionEventNone { + s.UserLogin.Log.Debug().Msg("Sending TransientDisconnect BridgeState") + if err == nil { + s.UserLogin.BridgeState.Send(status.BridgeState{StateEvent: status.StateTransientDisconnect}) + } else { + s.UserLogin.BridgeState.Send(status.BridgeState{StateEvent: status.StateTransientDisconnect, Error: "unknown-websocket-error", Message: err.Error()}) + } + } + } + + case signalmeow.SignalConnectionEventLoggedOut: + s.UserLogin.Log.Debug().Msg("Sending BadCredentials BridgeState") + if err == nil { + s.UserLogin.BridgeState.Send(status.BridgeState{StateEvent: status.StateBadCredentials, Message: "You have been logged out of Signal, please reconnect"}) + } else { + s.UserLogin.BridgeState.Send(status.BridgeState{StateEvent: status.StateBadCredentials, Message: err.Error()}) + } + err = s.Client.ClearKeysAndDisconnect(context.TODO()) + if err != nil { + s.UserLogin.Log.Error().Err(err).Msg("Failed to clear keys and disconnect") + } + + case signalmeow.SignalConnectionEventError: + s.UserLogin.Log.Debug().Msg("Sending UnknownError BridgeState") + s.UserLogin.BridgeState.Send(status.BridgeState{StateEvent: status.StateUnknownError, Error: "unknown-websocket-error", Message: err.Error()}) + + case signalmeow.SignalConnectionCleanShutdown: + if s.Client.IsLoggedIn() { + s.UserLogin.Log.Debug().Msg("Clean Shutdown - sending no BridgeState") + } else { + s.UserLogin.Log.Debug().Msg("Clean Shutdown, but logged out - Sending BadCredentials BridgeState") + s.UserLogin.BridgeState.Send(status.BridgeState{StateEvent: status.StateBadCredentials, Message: "You have been logged out of Signal, please reconnect"}) + } + } + } +} + +func (s *SignalClient) Connect(ctx context.Context) error { + s.tryConnect(ctx, 0) + return nil +} + +func (s *SignalClient) Disconnect() { + err := s.Client.StopReceiveLoops() + if err != nil { + s.UserLogin.Log.Err(err).Msg("Failed to stop receive loops") + } +} + +func (s *SignalClient) tryConnect(ctx context.Context, retryCount int) { + ch, err := s.Client.StartReceiveLoops(ctx) + if err != nil { + zerolog.Ctx(ctx).Err(err).Msg("Failed to start receive loops") + if retryCount < 6 { + s.UserLogin.BridgeState.Send(status.BridgeState{StateEvent: status.StateTransientDisconnect, Error: "unknown-websocket-error", Message: err.Error()}) + retryInSeconds := 2 << retryCount + zerolog.Ctx(ctx).Debug().Int("retry_in_seconds", retryInSeconds).Msg("Sleeping and retrying connection") + time.Sleep(time.Duration(retryInSeconds) * time.Second) + s.tryConnect(ctx, retryCount+1) + } else { + s.UserLogin.BridgeState.Send(status.BridgeState{StateEvent: status.StateUnknownError, Error: "unknown-websocket-error", Message: err.Error()}) + } + } else { + go s.bridgeStateLoop(ch) + } +} + +func (s *SignalClient) IsLoggedIn() bool { + return s.Client.IsLoggedIn() +} diff --git a/pkg/connector/config.go b/pkg/connector/config.go new file mode 100644 index 0000000..20fb6e8 --- /dev/null +++ b/pkg/connector/config.go @@ -0,0 +1,86 @@ +// mautrix-signal - A Matrix-Signal puppeting bridge. +// Copyright (C) 2024 Tulir Asokan +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +package connector + +import ( + _ "embed" + "strings" + "text/template" + + up "go.mau.fi/util/configupgrade" + "maunium.net/go/mautrix/id" + + "go.mau.fi/mautrix-signal/pkg/signalmeow/types" +) + +//go:embed example-config.yaml +var ExampleConfig string + +type SignalConfig struct { + DisplaynameTemplate string `yaml:"displayname_template"` + UseContactAvatars bool `yaml:"use_contact_avatars"` + UseOutdatedProfiles bool `yaml:"use_outdated_profiles"` + NumberInTopic bool `yaml:"number_in_topic"` + DeviceName string `yaml:"device_name"` + NoteToSelfAvatar id.ContentURIString `yaml:"note_to_self_avatar"` + LocationFormat string `yaml:"location_format"` + + displaynameTemplate *template.Template `yaml:"-"` +} + +type DisplaynameParams struct { + ProfileName string + ContactName string + Username string + PhoneNumber string + UUID string + ACI string + PNI string + AboutEmoji string +} + +func (c *SignalConfig) FormatDisplayname(contact *types.Recipient) string { + var nameBuf strings.Builder + err := c.displaynameTemplate.Execute(&nameBuf, &DisplaynameParams{ + ProfileName: contact.Profile.Name, + ContactName: contact.ContactName, + Username: "", + PhoneNumber: contact.E164, + UUID: contact.ACI.String(), + ACI: contact.ACI.String(), + PNI: contact.PNI.String(), + AboutEmoji: contact.Profile.AboutEmoji, + }) + if err != nil { + panic(err) + } + return nameBuf.String() +} + +func upgradeConfig(helper up.Helper) { + helper.Copy(up.Str, "displayname_template") + helper.Copy(up.Bool, "use_contact_avatars") + helper.Copy(up.Bool, "use_outdated_profiles") + helper.Copy(up.Bool, "number_in_topic") + helper.Copy(up.Str, "device_name") + helper.Copy(up.Str, "note_to_self_avatar") + helper.Copy(up.Str, "location_format") +} + +func (s *SignalConnector) GetConfig() (string, any, up.Upgrader) { + return ExampleConfig, s.Config, up.SimpleUpgrader(upgradeConfig) +} diff --git a/pkg/connector/connector.go b/pkg/connector/connector.go index cb1788d..fe594dd 100644 --- a/pkg/connector/connector.go +++ b/pkg/connector/connector.go @@ -18,81 +18,22 @@ package connector import ( "context" - _ "embed" - "errors" "fmt" - "strconv" - "strings" "text/template" - "time" "github.com/google/uuid" - "github.com/rs/zerolog" - up "go.mau.fi/util/configupgrade" "go.mau.fi/util/dbutil" - "go.mau.fi/util/exzerolog" - "go.mau.fi/util/variationselector" - "google.golang.org/protobuf/proto" - "maunium.net/go/mautrix/bridge/status" "maunium.net/go/mautrix/bridgev2" - "maunium.net/go/mautrix/bridgev2/database" "maunium.net/go/mautrix/bridgev2/networkid" - "maunium.net/go/mautrix/event" "maunium.net/go/mautrix/id" - legacydb "go.mau.fi/mautrix-signal/database" "go.mau.fi/mautrix-signal/msgconv" "go.mau.fi/mautrix-signal/msgconv/matrixfmt" "go.mau.fi/mautrix-signal/msgconv/signalfmt" - "go.mau.fi/mautrix-signal/pkg/libsignalgo" "go.mau.fi/mautrix-signal/pkg/signalmeow" - "go.mau.fi/mautrix-signal/pkg/signalmeow/events" - signalpb "go.mau.fi/mautrix-signal/pkg/signalmeow/protobuf" "go.mau.fi/mautrix-signal/pkg/signalmeow/store" - "go.mau.fi/mautrix-signal/pkg/signalmeow/types" ) -type SignalConfig struct { - DisplaynameTemplate string `yaml:"displayname_template"` - UseContactAvatars bool `yaml:"use_contact_avatars"` - UseOutdatedProfiles bool `yaml:"use_outdated_profiles"` - NumberInTopic bool `yaml:"number_in_topic"` - DeviceName string `yaml:"device_name"` - NoteToSelfAvatar id.ContentURIString `yaml:"note_to_self_avatar"` - LocationFormat string `yaml:"location_format"` - - displaynameTemplate *template.Template `yaml:"-"` -} - -type DisplaynameParams struct { - ProfileName string - ContactName string - Username string - PhoneNumber string - UUID string - ACI string - PNI string - AboutEmoji string -} - -func (c *SignalConfig) FormatDisplayname(contact *types.Recipient) string { - var nameBuf strings.Builder - err := c.displaynameTemplate.Execute(&nameBuf, &DisplaynameParams{ - ProfileName: contact.Profile.Name, - ContactName: contact.ContactName, - Username: "", - PhoneNumber: contact.E164, - UUID: contact.ACI.String(), - ACI: contact.ACI.String(), - PNI: contact.PNI.String(), - AboutEmoji: contact.Profile.AboutEmoji, - }) - if err != nil { - panic(err) - } - return nameBuf.String() -} - type SignalConnector struct { MsgConv *msgconv.MessageConverter Store *store.Container @@ -102,10 +43,6 @@ type SignalConnector struct { var _ bridgev2.NetworkConnector = (*SignalConnector)(nil) var _ bridgev2.MaxFileSizeingNetwork = (*SignalConnector)(nil) -var _ bridgev2.NetworkAPI = (*SignalClient)(nil) -var _ bridgev2.PushableNetworkAPI = (*SignalClient)(nil) -var _ bridgev2.GroupCreatingNetworkAPI = (*SignalClient)(nil) -var _ msgconv.PortalMethods = (*msgconvPortalMethods)(nil) func NewConnector() *SignalConnector { return &SignalConnector{ @@ -113,9 +50,6 @@ func NewConnector() *SignalConnector { } } -//go:embed example-config.yaml -var ExampleConfig string - func (s *SignalConnector) GetName() bridgev2.BridgeName { return bridgev2.BridgeName{ DisplayName: "Signal", @@ -127,20 +61,6 @@ func (s *SignalConnector) GetName() bridgev2.BridgeName { } } -func upgradeConfig(helper up.Helper) { - helper.Copy(up.Str, "displayname_template") - helper.Copy(up.Bool, "use_contact_avatars") - helper.Copy(up.Bool, "use_outdated_profiles") - helper.Copy(up.Bool, "number_in_topic") - helper.Copy(up.Str, "device_name") - helper.Copy(up.Str, "note_to_self_avatar") - helper.Copy(up.Str, "location_format") -} - -func (s *SignalConnector) GetConfig() (string, any, up.Upgrader) { - return ExampleConfig, s.Config, up.SimpleUpgrader(upgradeConfig) -} - func (s *SignalConnector) Init(bridge *bridgev2.Bridge) { var err error s.Config.displaynameTemplate, err = template.New("displayname").Parse(s.Config.DisplaynameTemplate) @@ -229,1187 +149,3 @@ func (s *SignalConnector) LoadUserLogin(ctx context.Context, login *bridgev2.Use login.Client = sc return nil } - -type SignalClient struct { - Main *SignalConnector - UserLogin *bridgev2.UserLogin - Client *signalmeow.Client -} - -var pushCfg = &bridgev2.PushConfig{ - FCM: &bridgev2.FCMPushConfig{ - // https://github.com/signalapp/Signal-Android/blob/main/app/src/main/res/values/firebase_messaging.xml#L4 - SenderID: "312334754206", - }, - APNs: &bridgev2.APNsPushConfig{ - BundleID: "org.whispersystems.signal", - }, -} - -func (s *SignalClient) GetPushConfigs() *bridgev2.PushConfig { - return pushCfg -} - -func (s *SignalClient) RegisterPushNotifications(ctx context.Context, pushType bridgev2.PushType, token string) error { - if pushType != bridgev2.PushTypeFCM { - return fmt.Errorf("unsupported push type: %s", pushType) - } - return s.Client.RegisterFCM(ctx, token) -} - -func (s *SignalClient) LogoutRemote(ctx context.Context) { - err := s.Client.StopReceiveLoops() - if err != nil { - zerolog.Ctx(ctx).Err(err).Msg("Failed to stop receive loops for logout") - } - err = s.Main.Store.DeleteDevice(context.TODO(), &s.Client.Store.DeviceData) - if err != nil { - zerolog.Ctx(ctx).Err(err).Msg("Failed to delete device from store") - } -} - -func (s *SignalClient) contactToUserInfo(contact *types.Recipient) *bridgev2.UserInfo { - isBot := false - ui := &bridgev2.UserInfo{ - IsBot: &isBot, - } - name := s.Main.Config.FormatDisplayname(contact) - ui.Name = &name - if s.Main.Config.UseContactAvatars && contact.ContactAvatar.Hash != "" { - ui.Avatar = &bridgev2.Avatar{ - ID: networkid.AvatarID("hash:" + contact.ContactAvatar.Hash), - Get: func(ctx context.Context) ([]byte, error) { - if contact.ContactAvatar.Image == nil { - return nil, fmt.Errorf("contact avatar not available") - } - return contact.ContactAvatar.Image, nil - }, - } - } else if contact.Profile.AvatarPath != "" { - ui.Avatar = &bridgev2.Avatar{ - ID: makeAvatarPathID(contact.Profile.AvatarPath), - Get: func(ctx context.Context) ([]byte, error) { - return s.Client.DownloadUserAvatar(ctx, contact.Profile.AvatarPath, contact.Profile.Key) - }, - } - } else { - ui.Avatar = &bridgev2.Avatar{ - ID: "", - Remove: true, - } - } - return ui -} - -func (s *SignalClient) GetUserInfo(ctx context.Context, ghost *bridgev2.Ghost) (*bridgev2.UserInfo, error) { - userID, err := parseUserID(ghost.ID) - if err != nil { - return nil, err - } - contact, err := s.Client.ContactByACI(ctx, userID) - if err != nil { - return nil, err - } - return s.contactToUserInfo(contact), nil -} - -func makeAvatarPathID(avatarPath string) networkid.AvatarID { - if avatarPath == "" { - return "" - } - return networkid.AvatarID("path:" + avatarPath) -} - -func (s *SignalClient) GetChatInfo(ctx context.Context, portal *bridgev2.Portal) (*bridgev2.PortalInfo, error) { - userID, groupID, err := s.parsePortalID(portal.ID) - if err != nil { - return nil, err - } - if groupID != "" { - groupInfo, err := s.Client.RetrieveGroupByID(ctx, groupID, 0) - if err != nil { - return nil, err - } - isDM := false - isSpace := false - members := make([]networkid.UserID, len(groupInfo.Members)) - for i, member := range groupInfo.Members { - members[i] = makeUserID(member.ACI) - } - return &bridgev2.PortalInfo{ - Name: &groupInfo.Title, - Topic: &groupInfo.Description, - Avatar: &bridgev2.Avatar{ - ID: makeAvatarPathID(groupInfo.AvatarPath), - Get: func(ctx context.Context) ([]byte, error) { - return s.Client.DownloadGroupAvatar(ctx, groupInfo) - }, - Remove: groupInfo.AvatarPath == "", - }, - Members: members, - IsDirectChat: &isDM, - IsSpace: &isSpace, - }, nil - } else { - aci, pni := serviceIDToACIAndPNI(userID) - contact, err := s.Client.Store.RecipientStore.LoadAndUpdateRecipient(ctx, aci, pni, nil) - if err != nil { - return nil, err - } - return s.makeCreateDMResponse(contact).PortalInfo, nil - } -} - -func (s *SignalClient) ResolveIdentifier(ctx context.Context, number string, createChat bool) (*bridgev2.ResolveIdentifierResponse, error) { - number, err := bridgev2.CleanPhoneNumber(number) - if err != nil { - return nil, err - } - e164Number, err := strconv.ParseUint(strings.TrimPrefix(number, "+"), 10, 64) - if err != nil { - return nil, fmt.Errorf("error parsing phone number: %w", err) - } - e164String := fmt.Sprintf("+%d", e164Number) - var aci, pni uuid.UUID - var recipient *types.Recipient - if recipient, err = s.Client.ContactByE164(ctx, e164String); err != nil { - return nil, fmt.Errorf("error looking up number in local contact list: %w", err) - } else if recipient != nil { - aci = recipient.ACI - pni = recipient.PNI - } else if resp, err := s.Client.LookupPhone(ctx, e164Number); err != nil { - return nil, fmt.Errorf("error looking up number on server: %w", err) - } else { - aci = resp[e164Number].ACI - pni = resp[e164Number].PNI - if aci == uuid.Nil && pni == uuid.Nil { - return nil, errors.New("user not found on Signal") - } - recipient, err = s.Client.Store.RecipientStore.UpdateRecipientE164(ctx, aci, pni, e164String) - if err != nil { - zerolog.Ctx(ctx).Err(err).Msg("Failed to save recipient entry after looking up phone") - } - aci, pni = recipient.ACI, recipient.PNI - } - zerolog.Ctx(ctx).Debug(). - Uint64("e164", e164Number). - Stringer("aci", aci). - Stringer("pni", pni). - Msg("Found resolve identifier target user") - - // createChat is a no-op: chats don't need to be created, and we always return chat info - if aci != uuid.Nil { - ghost, err := s.Main.Bridge.GetGhostByID(ctx, makeUserID(aci)) - if err != nil { - return nil, fmt.Errorf("failed to get ghost: %w", err) - } - return &bridgev2.ResolveIdentifierResponse{ - UserID: makeUserID(aci), - UserInfo: s.contactToUserInfo(recipient), - Ghost: ghost, - Chat: s.makeCreateDMResponse(recipient), - }, nil - } else { - return &bridgev2.ResolveIdentifierResponse{ - UserID: makeUserIDFromServiceID(libsignalgo.NewPNIServiceID(pni)), - UserInfo: s.contactToUserInfo(recipient), - Chat: s.makeCreateDMResponse(recipient), - }, nil - } -} - -const PrivateChatTopic = "Signal private chat" -const NoteToSelfName = "Signal Note to Self" - -func serviceIDToACIAndPNI(serviceID libsignalgo.ServiceID) (aci, pni uuid.UUID) { - if serviceID.Type == libsignalgo.ServiceIDTypeACI { - return serviceID.UUID, uuid.Nil - } else { - return uuid.Nil, serviceID.UUID - } -} - -func (s *SignalClient) makeCreateDMResponse(recipient *types.Recipient) *bridgev2.CreateChatResponse { - isDirectChat := true - isSpace := false - name := "" - topic := PrivateChatTopic - members := []networkid.UserID{makeUserID(s.Client.Store.ACI)} - if s.Main.Config.NumberInTopic && recipient.E164 != "" { - topic = fmt.Sprintf("%s with %s", PrivateChatTopic, recipient.E164) - } - var serviceID libsignalgo.ServiceID - if recipient.ACI == uuid.Nil { - name = s.Main.Config.FormatDisplayname(recipient) - serviceID = libsignalgo.NewPNIServiceID(recipient.PNI) - } else { - if recipient.ACI == s.Client.Store.ACI { - name = NoteToSelfName - } else { - // The other user is only present if their ACI is known - members = append(members, makeUserID(recipient.ACI)) - } - serviceID = libsignalgo.NewACIServiceID(recipient.ACI) - } - return &bridgev2.CreateChatResponse{ - PortalID: networkid.PortalKey{ - ID: networkid.PortalID(serviceID.String()), - Receiver: s.UserLogin.ID, - }, - PortalInfo: &bridgev2.PortalInfo{ - Name: &name, - Topic: &topic, - Members: members, - IsDirectChat: &isDirectChat, - IsSpace: &isSpace, - }, - } -} - -func (s *SignalClient) CreateGroup(ctx context.Context, name string, users ...networkid.UserID) (*bridgev2.CreateChatResponse, error) { - //TODO implement me - return nil, fmt.Errorf("not implemented") -} - -func (s *SignalClient) IsThisUser(_ context.Context, userID networkid.UserID) bool { - return userID == makeUserID(s.Client.Store.ACI) -} - -func (s *SignalClient) bridgeStateLoop(statusChan <-chan signalmeow.SignalConnectionStatus) { - var peekedConnectionStatus signalmeow.SignalConnectionStatus - for { - var connectionStatus signalmeow.SignalConnectionStatus - if peekedConnectionStatus.Event != signalmeow.SignalConnectionEventNone { - s.UserLogin.Log.Debug(). - Stringer("peeked_connection_status_event", peekedConnectionStatus.Event). - Msg("Using peeked connectionStatus event") - connectionStatus = peekedConnectionStatus - peekedConnectionStatus = signalmeow.SignalConnectionStatus{} - } else { - var ok bool - connectionStatus, ok = <-statusChan - if !ok { - s.UserLogin.Log.Debug().Msg("statusChan channel closed") - return - } - } - - err := connectionStatus.Err - switch connectionStatus.Event { - case signalmeow.SignalConnectionEventConnected: - s.UserLogin.Log.Debug().Msg("Sending Connected BridgeState") - s.UserLogin.BridgeState.Send(status.BridgeState{StateEvent: status.StateConnected}) - - case signalmeow.SignalConnectionEventDisconnected: - s.UserLogin.Log.Debug().Msg("Received SignalConnectionEventDisconnected") - - // Debounce: wait 7s before sending TransientDisconnect, in case we get a reconnect - // We should wait until the next message comes in, or 7 seconds has passed. - // - If a disconnected event comes in, just loop again, unless it's been more than 7 seconds. - // - If a non-disconnected event comes in, store it in peekedConnectionStatus, - // break out of this loop and go back to the top of the goroutine to handle it in the switch. - // - If 7 seconds passes without any non-disconnect messages, send the TransientDisconnect. - // (Why 7 seconds? It was 5 at first, but websockets min retry is 5 seconds, - // so it would send TransientDisconnect right before reconnecting. 7 seems to work well.) - debounceTimer := time.NewTimer(7 * time.Second) - PeekLoop: - for { - var ok bool - select { - case peekedConnectionStatus, ok = <-statusChan: - // Handle channel closing - if !ok { - s.UserLogin.Log.Debug().Msg("connectionStatus channel closed") - return - } - // If it's another Disconnected event, just keep looping - if peekedConnectionStatus.Event == signalmeow.SignalConnectionEventDisconnected { - peekedConnectionStatus = signalmeow.SignalConnectionStatus{} - continue - } - // If it's a non-disconnect event, break out of the PeekLoop and handle it in the switch - break PeekLoop - case <-debounceTimer.C: - // Time is up, so break out of the loop and send the TransientDisconnect - break PeekLoop - } - } - // We're out of the PeekLoop, so either we got a non-disconnect event, or it's been 7 seconds (or both). - // We want to send TransientDisconnect if it's been 7 seconds, but not if the latest event was something - // other than Disconnected - if !debounceTimer.Stop() { // If the timer has already expired - // Send TransientDisconnect only if the latest event is a disconnect or no event - // (peekedConnectionStatus could be something else if the timer and the event race) - if peekedConnectionStatus.Event == signalmeow.SignalConnectionEventDisconnected || - peekedConnectionStatus.Event == signalmeow.SignalConnectionEventNone { - s.UserLogin.Log.Debug().Msg("Sending TransientDisconnect BridgeState") - if err == nil { - s.UserLogin.BridgeState.Send(status.BridgeState{StateEvent: status.StateTransientDisconnect}) - } else { - s.UserLogin.BridgeState.Send(status.BridgeState{StateEvent: status.StateTransientDisconnect, Error: "unknown-websocket-error", Message: err.Error()}) - } - } - } - - case signalmeow.SignalConnectionEventLoggedOut: - s.UserLogin.Log.Debug().Msg("Sending BadCredentials BridgeState") - if err == nil { - s.UserLogin.BridgeState.Send(status.BridgeState{StateEvent: status.StateBadCredentials, Message: "You have been logged out of Signal, please reconnect"}) - } else { - s.UserLogin.BridgeState.Send(status.BridgeState{StateEvent: status.StateBadCredentials, Message: err.Error()}) - } - err = s.Client.ClearKeysAndDisconnect(context.TODO()) - if err != nil { - s.UserLogin.Log.Error().Err(err).Msg("Failed to clear keys and disconnect") - } - - case signalmeow.SignalConnectionEventError: - s.UserLogin.Log.Debug().Msg("Sending UnknownError BridgeState") - s.UserLogin.BridgeState.Send(status.BridgeState{StateEvent: status.StateUnknownError, Error: "unknown-websocket-error", Message: err.Error()}) - - case signalmeow.SignalConnectionCleanShutdown: - if s.Client.IsLoggedIn() { - s.UserLogin.Log.Debug().Msg("Clean Shutdown - sending no BridgeState") - } else { - s.UserLogin.Log.Debug().Msg("Clean Shutdown, but logged out - Sending BadCredentials BridgeState") - s.UserLogin.BridgeState.Send(status.BridgeState{StateEvent: status.StateBadCredentials, Message: "You have been logged out of Signal, please reconnect"}) - } - } - } -} - -func (s *SignalClient) Connect(ctx context.Context) error { - s.tryConnect(ctx, 0) - return nil -} - -func (s *SignalClient) Disconnect() { - err := s.Client.StopReceiveLoops() - if err != nil { - s.UserLogin.Log.Err(err).Msg("Failed to stop receive loops") - } -} - -func (s *SignalClient) tryConnect(ctx context.Context, retryCount int) { - ch, err := s.Client.StartReceiveLoops(ctx) - if err != nil { - zerolog.Ctx(ctx).Err(err).Msg("Failed to start receive loops") - if retryCount < 6 { - s.UserLogin.BridgeState.Send(status.BridgeState{StateEvent: status.StateTransientDisconnect, Error: "unknown-websocket-error", Message: err.Error()}) - retryInSeconds := 2 << retryCount - zerolog.Ctx(ctx).Debug().Int("retry_in_seconds", retryInSeconds).Msg("Sleeping and retrying connection") - time.Sleep(time.Duration(retryInSeconds) * time.Second) - s.tryConnect(ctx, retryCount+1) - } else { - s.UserLogin.BridgeState.Send(status.BridgeState{StateEvent: status.StateUnknownError, Error: "unknown-websocket-error", Message: err.Error()}) - } - } else { - go s.bridgeStateLoop(ch) - } -} - -func (s *SignalClient) IsLoggedIn() bool { - return s.Client.IsLoggedIn() -} - -func parseUserID(userID networkid.UserID) (uuid.UUID, error) { - serviceID, err := parseUserIDAsServiceID(userID) - if err != nil { - return uuid.Nil, err - } else if serviceID.Type != libsignalgo.ServiceIDTypeACI { - return uuid.Nil, fmt.Errorf("invalid user ID: expected ACI type") - } else { - return serviceID.UUID, nil - } -} - -func parseUserIDAsServiceID(userID networkid.UserID) (libsignalgo.ServiceID, error) { - return libsignalgo.ServiceIDFromString(string(userID)) -} - -func (s *SignalClient) parsePortalID(portalID networkid.PortalID) (userID libsignalgo.ServiceID, groupID types.GroupIdentifier, err error) { - if len(portalID) == 44 { - groupID = types.GroupIdentifier(portalID) - } else { - userID, err = libsignalgo.ServiceIDFromString(string(portalID)) - } - return -} - -func parseMessageID(messageID networkid.MessageID) (sender uuid.UUID, timestamp uint64, err error) { - parts := strings.Split(string(messageID), "|") - if len(parts) != 2 { - err = fmt.Errorf("invalid message ID: expected two pipe-separated parts") - return - } - sender, err = uuid.Parse(parts[0]) - if err != nil { - return - } - timestamp, err = strconv.ParseUint(parts[1], 10, 64) - return -} - -func makeMessageID(sender uuid.UUID, timestamp uint64) networkid.MessageID { - return networkid.MessageID(fmt.Sprintf("%s|%d", sender, timestamp)) -} - -func makeUserID(user uuid.UUID) networkid.UserID { - return networkid.UserID(user.String()) -} - -func makeUserIDFromServiceID(user libsignalgo.ServiceID) networkid.UserID { - return networkid.UserID(user.String()) -} - -func makeUserLoginID(user uuid.UUID) networkid.UserLoginID { - return networkid.UserLoginID(user.String()) -} - -func (s *SignalClient) makeEventSender(sender uuid.UUID) bridgev2.EventSender { - return bridgev2.EventSender{ - IsFromMe: sender == s.Client.Store.ACI, - SenderLogin: makeUserLoginID(sender), - Sender: makeUserID(sender), - } -} - -func makeMessagePartID(index int) networkid.PartID { - if index == 0 { - return "" - } - return networkid.PartID(strconv.Itoa(index)) -} - -type contextKey int - -var msgconvContextKey contextKey - -type msgconvContext struct { - Connector *SignalConnector - Intent bridgev2.MatrixAPI - Client *SignalClient - Portal *bridgev2.Portal - ReplyTo *database.Message -} - -type Bv2ChatEvent struct { - *events.ChatEvent - s *SignalClient -} - -var ( - _ bridgev2.RemoteMessage = (*Bv2ChatEvent)(nil) - _ bridgev2.RemoteEdit = (*Bv2ChatEvent)(nil) - _ bridgev2.RemoteEventWithTimestamp = (*Bv2ChatEvent)(nil) - _ bridgev2.RemoteReaction = (*Bv2ChatEvent)(nil) - _ bridgev2.RemoteReactionRemove = (*Bv2ChatEvent)(nil) - _ bridgev2.RemoteMessageRemove = (*Bv2ChatEvent)(nil) - _ bridgev2.RemoteTyping = (*Bv2ChatEvent)(nil) -) - -func (evt *Bv2ChatEvent) GetType() bridgev2.RemoteEventType { - switch innerEvt := evt.Event.(type) { - case *signalpb.DataMessage: - switch { - case innerEvt.Body != nil, innerEvt.Attachments != nil, innerEvt.Contact != nil, innerEvt.Sticker != nil: - return bridgev2.RemoteEventMessage - case innerEvt.Reaction != nil: - if innerEvt.Reaction.GetRemove() { - return bridgev2.RemoteEventReactionRemove - } - return bridgev2.RemoteEventReaction - case innerEvt.Delete != nil: - return bridgev2.RemoteEventMessageRemove - } - case *signalpb.EditMessage: - return bridgev2.RemoteEventEdit - case *signalpb.TypingMessage: - return bridgev2.RemoteEventTyping - } - return bridgev2.RemoteEventUnknown -} - -func (evt *Bv2ChatEvent) GetTimeout() time.Duration { - if evt.Event.(*signalpb.TypingMessage).GetAction() == signalpb.TypingMessage_STARTED { - return 15 * time.Second - } else { - return 0 - } -} - -func (evt *Bv2ChatEvent) GetPortalKey() networkid.PortalKey { - key := networkid.PortalKey{ID: networkid.PortalID(evt.Info.ChatID)} - // For non-group chats, add receiver - if len(evt.Info.ChatID) != 44 { - key.Receiver = makeUserLoginID(evt.s.Client.Store.ACI) - } - return key -} - -func (evt *Bv2ChatEvent) ShouldCreatePortal() bool { - return evt.GetType() == bridgev2.RemoteEventMessage -} - -func (evt *Bv2ChatEvent) AddLogContext(c zerolog.Context) zerolog.Context { - c = c.Stringer("sender_id", evt.Info.Sender) - switch innerEvt := evt.Event.(type) { - case *signalpb.DataMessage: - c = c.Uint64("message_ts", innerEvt.GetTimestamp()) - switch { - case innerEvt.Reaction != nil: - c = c.Uint64("reaction_target_ts", innerEvt.Reaction.GetTargetSentTimestamp()) - case innerEvt.Delete != nil: - c = c.Uint64("delete_target_ts", innerEvt.Delete.GetTargetSentTimestamp()) - } - case *signalpb.EditMessage: - c = c. - Uint64("edit_target_ts", innerEvt.GetTargetSentTimestamp()). - Uint64("edit_ts", innerEvt.GetDataMessage().GetTimestamp()) - } - return c -} - -func (evt *Bv2ChatEvent) GetSender() bridgev2.EventSender { - return evt.s.makeEventSender(evt.Info.Sender) -} - -func (evt *Bv2ChatEvent) GetID() networkid.MessageID { - ts := evt.getDataMsgTimestamp() - if ts == 0 { - panic(fmt.Errorf("GetID() called for non-DataMessage event")) - } - return makeMessageID(evt.Info.Sender, ts) -} - -func (evt *Bv2ChatEvent) getDataMsgTimestamp() uint64 { - switch innerEvt := evt.Event.(type) { - case *signalpb.DataMessage: - return innerEvt.GetTimestamp() - case *signalpb.EditMessage: - return innerEvt.GetDataMessage().GetTimestamp() - default: - return 0 - } -} - -func (evt *Bv2ChatEvent) GetTimestamp() time.Time { - ts := evt.getDataMsgTimestamp() - if ts == 0 { - return time.Now() - } - return time.UnixMilli(int64(ts)) -} - -func (evt *Bv2ChatEvent) GetTargetMessage() networkid.MessageID { - var targetAuthorACI string - var targetSentTS uint64 - switch innerEvt := evt.Event.(type) { - case *signalpb.DataMessage: - switch { - case innerEvt.Reaction != nil: - targetAuthorACI = innerEvt.Reaction.GetTargetAuthorAci() - targetSentTS = innerEvt.Reaction.GetTargetSentTimestamp() - case innerEvt.Delete != nil: - targetSentTS = innerEvt.Delete.GetTargetSentTimestamp() - default: - panic(fmt.Errorf("GetTargetMessage() called for message type without target")) - } - case *signalpb.EditMessage: - targetSentTS = innerEvt.GetTargetSentTimestamp() - default: - panic(fmt.Errorf("GetTargetMessage() called for message type without target")) - } - targetAuthorUUID := evt.Info.Sender - if targetAuthorACI != "" { - targetAuthorUUID, _ = uuid.Parse(targetAuthorACI) - } - return makeMessageID(targetAuthorUUID, targetSentTS) -} - -func (evt *Bv2ChatEvent) GetReactionEmoji() (string, networkid.EmojiID) { - dataMsg, ok := evt.Event.(*signalpb.DataMessage) - if !ok || dataMsg.Reaction == nil { - panic(fmt.Errorf("GetReactionEmoji() called for non-reaction event")) - } - return dataMsg.GetReaction().GetEmoji(), "" -} - -func (evt *Bv2ChatEvent) GetRemovedEmojiID() networkid.EmojiID { - return "" -} - -func (evt *Bv2ChatEvent) ConvertMessage(ctx context.Context, portal *bridgev2.Portal, intent bridgev2.MatrixAPI) (*bridgev2.ConvertedMessage, error) { - mcCtx := &msgconvContext{ - Connector: evt.s.Main, - Intent: intent, - Client: evt.s, - Portal: portal, - } - ctx = context.WithValue(ctx, msgconvContextKey, mcCtx) - dataMsg, ok := evt.Event.(*signalpb.DataMessage) - if !ok { - return nil, fmt.Errorf("ConvertMessage() called for non-DataMessage event") - } - converted := evt.s.Main.MsgConv.ToMatrix(ctx, dataMsg) - converted.MergeCaption() - var replyTo *networkid.MessageOptionalPartID - if dataMsg.GetQuote() != nil { - quoteAuthor, _ := uuid.Parse(dataMsg.Quote.GetAuthorAci()) - replyTo = &networkid.MessageOptionalPartID{ - MessageID: makeMessageID(quoteAuthor, dataMsg.Quote.GetId()), - } - } - convertedParts := make([]*bridgev2.ConvertedMessagePart, len(converted.Parts)) - for i, part := range converted.Parts { - convertedParts[i] = &bridgev2.ConvertedMessagePart{ - ID: makeMessagePartID(i), - Type: part.Type, - Content: part.Content, - Extra: part.Extra, - } - } - var disappear database.DisappearingSetting - if converted.DisappearIn != 0 { - disappear = database.DisappearingSetting{ - Type: database.DisappearingTypeAfterRead, - Timer: time.Duration(converted.DisappearIn) * time.Second, - } - if evt.Info.Sender == evt.s.Client.Store.ACI { - disappear.DisappearAt = time.UnixMilli(int64(dataMsg.GetTimestamp())).Add(disappear.Timer) - } - if portal.Metadata.DisappearTimer != disappear.Timer { - portal.Metadata.DisappearType = disappear.Type - portal.Metadata.DisappearTimer = disappear.Timer - // TODO if the message doesn't have the DataMessage_EXPIRATION_TIMER_UPDATE, - // we should send a message to the portal notifying of the implicit update - err := portal.Save(ctx) - if err != nil { - zerolog.Ctx(ctx).Err(err).Msg("Failed to save portal metadata after updating disappearing timer") - } else { - zerolog.Ctx(ctx).Debug().Dur("new_timer", portal.Metadata.DisappearTimer).Msg("Updated disappearing timer in portal") - } - } - } - return &bridgev2.ConvertedMessage{ - ReplyTo: replyTo, - Parts: convertedParts, - Disappear: disappear, - }, nil -} - -func (evt *Bv2ChatEvent) ConvertEdit(ctx context.Context, portal *bridgev2.Portal, intent bridgev2.MatrixAPI, existing []*database.Message) (*bridgev2.ConvertedEdit, error) { - mcCtx := &msgconvContext{ - Connector: evt.s.Main, - Intent: intent, - Client: evt.s, - Portal: portal, - } - ctx = context.WithValue(ctx, msgconvContextKey, mcCtx) - editMsg, ok := evt.Event.(*signalpb.EditMessage) - if !ok { - return nil, fmt.Errorf("ConvertEdit() called for non-EditMessage event") - } - // TODO tell converter about existing parts to avoid reupload? - converted := evt.s.Main.MsgConv.ToMatrix(ctx, editMsg.GetDataMessage()) - converted.MergeCaption() - convertedEdit := &bridgev2.ConvertedEdit{} - // TODO can anything other than the text be edited? - lastPart := converted.Parts[len(converted.Parts)-1] - convertedEdit.ModifiedParts = append(convertedEdit.ModifiedParts, &bridgev2.ConvertedEditPart{ - Part: existing[len(existing)-1], - Type: lastPart.Type, - Content: lastPart.Content, - Extra: lastPart.Extra, - }) - return convertedEdit, nil -} - -type Bv2Receipt struct { - Type signalpb.ReceiptMessage_Type - Chat networkid.PortalKey - Sender bridgev2.EventSender - - LastTS time.Time - LastID networkid.MessageID - IDs []networkid.MessageID -} - -func (b *Bv2Receipt) GetType() bridgev2.RemoteEventType { - switch b.Type { - case signalpb.ReceiptMessage_READ: - return bridgev2.RemoteEventReadReceipt - case signalpb.ReceiptMessage_DELIVERY: - return bridgev2.RemoteEventDeliveryReceipt - default: - return bridgev2.RemoteEventUnknown - } -} - -func (b *Bv2Receipt) GetPortalKey() networkid.PortalKey { - return b.Chat -} - -func (b *Bv2Receipt) AddLogContext(c zerolog.Context) zerolog.Context { - return c. - Str("sender_id", string(b.Sender.Sender)). - Stringer("receipt_type", b.Type). - Array("message_ids", exzerolog.ArrayOfStrs(b.IDs)) -} - -func (b *Bv2Receipt) GetSender() bridgev2.EventSender { - return b.Sender -} - -func (b *Bv2Receipt) GetLastReceiptTarget() networkid.MessageID { - return b.LastID -} - -func (b *Bv2Receipt) GetReceiptTargets() []networkid.MessageID { - return b.IDs -} - -var _ bridgev2.RemoteReceipt = (*Bv2Receipt)(nil) - -func convertReceipts[T any](ctx context.Context, input []T, getMessageFunc func(ctx context.Context, msgID T) (*database.Message, error)) map[networkid.PortalKey]*Bv2Receipt { - log := zerolog.Ctx(ctx) - receipts := make(map[networkid.PortalKey]*Bv2Receipt) - for _, msgID := range input { - msg, err := getMessageFunc(ctx, msgID) - if err != nil { - log.Err(err).Any("message_id", msgID).Msg("Failed to get target message for receipt") - } else if msg == nil { - log.Debug().Any("message_id", msgID).Msg("Got receipt for unknown message") - } else { - receiptEvt, ok := receipts[msg.Room] - if !ok { - receiptEvt = &Bv2Receipt{Chat: msg.Room} - receipts[msg.Room] = receiptEvt - } - receiptEvt.IDs = append(receiptEvt.IDs, msg.ID) - if receiptEvt.LastTS.Before(msg.Timestamp) { - receiptEvt.LastTS = msg.Timestamp - receiptEvt.LastID = msg.ID - } - } - } - return receipts -} - -func (s *SignalClient) dispatchReceipts(sender uuid.UUID, receiptType signalpb.ReceiptMessage_Type, receipts map[networkid.PortalKey]*Bv2Receipt) { - evtSender := s.makeEventSender(sender) - for chat, receiptEvt := range receipts { - receiptEvt.Chat = chat - receiptEvt.Sender = evtSender - receiptEvt.Type = receiptType - s.Main.Bridge.QueueRemoteEvent(s.UserLogin, receiptEvt) - } -} - -func (s *SignalClient) handleSignalReceipt(evt *events.Receipt) { - log := s.UserLogin.Log.With(). - Str("action", "handle signal receipt"). - Stringer("sender_id", evt.Sender). - Stringer("receipt_type", evt.Content.GetType()). - Logger() - ctx := log.WithContext(context.TODO()) - receipts := convertReceipts(ctx, evt.Content.Timestamp, func(ctx context.Context, msgTS uint64) (*database.Message, error) { - return s.Main.Bridge.DB.Message.GetFirstPartByID(ctx, makeMessageID(s.Client.Store.ACI, msgTS)) - }) - s.dispatchReceipts(evt.Sender, evt.Content.GetType(), receipts) -} - -func (s *SignalClient) handleSignalReadSelf(evt *events.ReadSelf) { - log := s.UserLogin.Log.With(). - Str("action", "handle signal read self"). - Logger() - ctx := log.WithContext(context.TODO()) - receipts := convertReceipts(ctx, evt.Messages, func(ctx context.Context, msgInfo *signalpb.SyncMessage_Read) (*database.Message, error) { - aciUUID, err := uuid.Parse(msgInfo.GetSenderAci()) - if err != nil { - return nil, err - } - return s.Main.Bridge.DB.Message.GetFirstPartByID(ctx, makeMessageID(aciUUID, msgInfo.GetTimestamp())) - }) - s.dispatchReceipts(s.Client.Store.ACI, signalpb.ReceiptMessage_READ, receipts) -} - -func (s *SignalClient) handleSignalEvent(rawEvt events.SignalEvent) { - switch evt := rawEvt.(type) { - case *events.ChatEvent: - s.Main.Bridge.QueueRemoteEvent(s.UserLogin, &Bv2ChatEvent{ChatEvent: evt, s: s}) - case *events.DecryptionError: - case *events.Receipt: - s.handleSignalReceipt(evt) - case *events.ReadSelf: - s.handleSignalReadSelf(evt) - case *events.Call: - case *events.ContactList: - s.handleSignalContactList(evt) - case *events.ACIFound: - s.handleSignalACIFound(evt) - } -} - -func (s *SignalClient) handleSignalACIFound(evt *events.ACIFound) { - log := s.UserLogin.Log.With(). - Str("action", "handle aci found"). - Stringer("aci", evt.ACI). - Stringer("pni", evt.PNI). - Logger() - ctx := log.WithContext(context.TODO()) - pniPortalKey := networkid.PortalKey{ - ID: networkid.PortalID(evt.PNI.String()), - Receiver: s.UserLogin.ID, - } - aciPortalKey := networkid.PortalKey{ - ID: networkid.PortalID(evt.ACI.String()), - Receiver: s.UserLogin.ID, - } - result, portal, err := s.Main.Bridge.ReIDPortal(ctx, pniPortalKey, aciPortalKey) - if err != nil { - log.Err(err).Msg("Failed to re-ID portal") - } else if result == bridgev2.ReIDResultSourceReIDd || result == bridgev2.ReIDResultTargetDeletedAndSourceReIDd { - // If the source portal is re-ID'd, we need to sync metadata and participants. - // If the source is deleted, then it doesn't matter, any existing target will already be correct - info, err := s.GetChatInfo(ctx, portal) - if err != nil { - log.Err(err).Msg("Failed to get chat info to update portal after re-ID") - } else { - portal.UpdateInfo(ctx, info, s.UserLogin, nil, time.Time{}) - } - } -} - -func (s *SignalClient) handleSignalContactList(evt *events.ContactList) { - log := s.UserLogin.Log.With().Str("action", "handle contact list").Logger() - ctx := log.WithContext(context.TODO()) - for _, contact := range evt.Contacts { - if contact.ACI != uuid.Nil { - fullContact, err := s.Client.ContactByACI(ctx, contact.ACI) - if err != nil { - log.Err(err).Msg("Failed to get full contact info from store") - continue - } - fullContact.ContactAvatar = contact.ContactAvatar - ghost, err := s.Main.Bridge.GetGhostByID(ctx, makeUserID(contact.ACI)) - if err != nil { - log.Err(err).Msg("Failed to get ghost to update contact info") - continue - } - ghost.UpdateInfo(ctx, s.contactToUserInfo(contact)) - } - } -} - -func (s *SignalClient) HandleMatrixMessage(ctx context.Context, msg *bridgev2.MatrixMessage) (message *bridgev2.MatrixMessageResponse, err error) { - mcCtx := &msgconvContext{ - Connector: s.Main, - Intent: nil, - Client: s, - Portal: msg.Portal, - ReplyTo: msg.ReplyTo, - } - ctx = context.WithValue(ctx, msgconvContextKey, mcCtx) - converted, err := s.Main.MsgConv.ToSignal(ctx, msg.Event, msg.Content, msg.OrigSender != nil) - if err != nil { - return nil, err - } - res, err := s.sendMessage(ctx, msg.Portal.ID, &signalpb.Content{DataMessage: converted}) - if err != nil { - return nil, err - } - // TODO check result - fmt.Println(res) - dbMsg := &database.Message{ - ID: makeMessageID(s.Client.Store.ACI, converted.GetTimestamp()), - SenderID: makeUserID(s.Client.Store.ACI), - Timestamp: time.UnixMilli(int64(converted.GetTimestamp())), - } - dbMsg.Metadata.Extra = map[string]any{ - "contains_attachments": len(converted.Attachments) > 0, - } - if msg.ReplyTo != nil { - dbMsg.RelatesToRowID = msg.ReplyTo.RowID - } - return &bridgev2.MatrixMessageResponse{ - DB: dbMsg, - }, nil -} - -func (s *SignalClient) HandleMatrixEdit(ctx context.Context, msg *bridgev2.MatrixEdit) error { - _, targetSentTimestamp, err := parseMessageID(msg.EditTarget.ID) - if err != nil { - return fmt.Errorf("failed to parse target message ID: %w", err) - } else if msg.EditTarget.SenderID != makeUserID(s.Client.Store.ACI) { - return fmt.Errorf("cannot edit other people's messages") - } - mcCtx := &msgconvContext{ - Connector: s.Main, - Intent: nil, - Client: s, - Portal: msg.Portal, - } - if msg.EditTarget.RelatesToRowID != 0 { - var err error - mcCtx.ReplyTo, err = s.Main.Bridge.DB.Message.GetByRowID(ctx, msg.EditTarget.RelatesToRowID) - if err != nil { - return fmt.Errorf("failed to get message reply target: %w", err) - } - } - ctx = context.WithValue(ctx, msgconvContextKey, mcCtx) - converted, err := s.Main.MsgConv.ToSignal(ctx, msg.Event, msg.Content, msg.OrigSender != nil) - if err != nil { - return err - } - res, err := s.sendMessage(ctx, msg.Portal.ID, &signalpb.Content{EditMessage: &signalpb.EditMessage{ - TargetSentTimestamp: proto.Uint64(targetSentTimestamp), - DataMessage: converted, - }}) - if err != nil { - return err - } - // TODO check result - fmt.Println(res) - msg.EditTarget.ID = makeMessageID(s.Client.Store.ACI, converted.GetTimestamp()) - msg.EditTarget.Metadata.Extra["contains_attachments"] = len(converted.Attachments) > 0 - return nil -} - -func (s *SignalClient) sendMessage(ctx context.Context, portalID networkid.PortalID, content *signalpb.Content) (signalmeow.SendResult, error) { - userID, groupID, err := s.parsePortalID(portalID) - if err != nil { - return nil, err - } - if groupID != "" { - res, err := s.Client.SendGroupMessage(ctx, groupID, content) - if err != nil { - return nil, err - } - return res, nil - } else { - res := s.Client.SendMessage(ctx, userID, content) - return &res, nil - } -} - -func (s *SignalClient) PreHandleMatrixReaction(ctx context.Context, msg *bridgev2.MatrixReaction) (bridgev2.MatrixReactionPreResponse, error) { - return bridgev2.MatrixReactionPreResponse{ - SenderID: makeUserID(s.Client.Store.ACI), - EmojiID: "", - Emoji: variationselector.FullyQualify(msg.Content.RelatesTo.Key), - }, nil -} - -func (s *SignalClient) HandleMatrixReaction(ctx context.Context, msg *bridgev2.MatrixReaction) (reaction *database.Reaction, err error) { - targetAuthorACI, targetSentTimestamp, err := parseMessageID(msg.TargetMessage.ID) - if err != nil { - return nil, fmt.Errorf("failed to parse target message ID: %w", err) - } - wrappedContent := &signalpb.Content{ - DataMessage: &signalpb.DataMessage{ - Timestamp: proto.Uint64(uint64(msg.Event.Timestamp)), - RequiredProtocolVersion: proto.Uint32(uint32(signalpb.DataMessage_REACTIONS)), - Reaction: &signalpb.DataMessage_Reaction{ - Emoji: proto.String(msg.PreHandleResp.Emoji), - Remove: proto.Bool(false), - TargetAuthorAci: proto.String(targetAuthorACI.String()), - TargetSentTimestamp: proto.Uint64(targetSentTimestamp), - }, - }, - } - res, err := s.sendMessage(ctx, msg.Portal.ID, wrappedContent) - if err != nil { - return nil, err - } - // TODO check result - fmt.Println(res) - return &database.Reaction{}, nil -} - -func (s *SignalClient) HandleMatrixReactionRemove(ctx context.Context, msg *bridgev2.MatrixReactionRemove) error { - targetAuthorACI, targetSentTimestamp, err := parseMessageID(msg.TargetReaction.MessageID) - if err != nil { - return fmt.Errorf("failed to parse target message ID: %w", err) - } - wrappedContent := &signalpb.Content{ - DataMessage: &signalpb.DataMessage{ - Timestamp: proto.Uint64(uint64(msg.Event.Timestamp)), - RequiredProtocolVersion: proto.Uint32(uint32(signalpb.DataMessage_REACTIONS)), - Reaction: &signalpb.DataMessage_Reaction{ - Emoji: proto.String(msg.TargetReaction.Metadata.Emoji), - Remove: proto.Bool(true), - TargetAuthorAci: proto.String(targetAuthorACI.String()), - TargetSentTimestamp: proto.Uint64(targetSentTimestamp), - }, - }, - } - res, err := s.sendMessage(ctx, msg.Portal.ID, wrappedContent) - if err != nil { - return err - } - // TODO check result - fmt.Println(res) - return nil -} - -func (s *SignalClient) HandleMatrixMessageRemove(ctx context.Context, msg *bridgev2.MatrixMessageRemove) error { - _, targetSentTimestamp, err := parseMessageID(msg.TargetMessage.ID) - if err != nil { - return fmt.Errorf("failed to parse target message ID: %w", err) - } else if msg.TargetMessage.SenderID != makeUserID(s.Client.Store.ACI) { - return fmt.Errorf("cannot delete other people's messages") - } - wrappedContent := &signalpb.Content{ - DataMessage: &signalpb.DataMessage{ - Timestamp: proto.Uint64(uint64(msg.Event.Timestamp)), - Delete: &signalpb.DataMessage_Delete{ - TargetSentTimestamp: proto.Uint64(targetSentTimestamp), - }, - }, - } - res, err := s.sendMessage(ctx, msg.Portal.ID, wrappedContent) - if err != nil { - return err - } - // TODO check result - fmt.Println(res) - return nil -} - -func (s *SignalClient) HandleMatrixReadReceipt(ctx context.Context, receipt *bridgev2.MatrixReadReceipt) error { - if !receipt.ReadUpTo.After(receipt.LastRead) { - return nil - } - if receipt.LastRead.IsZero() { - receipt.LastRead = receipt.ReadUpTo.Add(-5 * time.Second) - } - dbMessages, err := s.Main.Bridge.DB.Message.GetMessagesBetweenTimeQuery(ctx, receipt.Portal.PortalKey, receipt.LastRead, receipt.ReadUpTo) - if err != nil { - return fmt.Errorf("failed to get messages to mark as read: %w", err) - } else if len(dbMessages) == 0 { - return nil - } - messagesToRead := map[uuid.UUID][]uint64{} - for _, msg := range dbMessages { - userID, timestamp, err := parseMessageID(msg.ID) - if err != nil { - return fmt.Errorf("failed to parse message ID %q: %w", msg.ID, err) - } - messagesToRead[userID] = append(messagesToRead[userID], timestamp) - } - zerolog.Ctx(ctx).Debug(). - Any("targets", messagesToRead). - Msg("Collected read receipt target messages") - - // TODO send sync message manually containing all read receipts instead of a separate message for each recipient - - for destination, messages := range messagesToRead { - // Don't send read receipts for own messages - if destination == s.Client.Store.ACI { - continue - } - // Don't use portal.sendSignalMessage because we're sending this straight to - // who sent the original message, not the portal's ChatID - ctx, cancel := context.WithTimeout(ctx, 10*time.Second) - result := s.Client.SendMessage(ctx, libsignalgo.NewACIServiceID(destination), signalmeow.ReadReceptMessageForTimestamps(messages)) - cancel() - if !result.WasSuccessful { - zerolog.Ctx(ctx).Err(result.FailedSendResult.Error). - Stringer("destination", destination). - Uints64("message_ids", messages). - Msg("Failed to send read receipt to Signal") - } else { - zerolog.Ctx(ctx).Debug(). - Stringer("destination", destination). - Uints64("message_ids", messages). - Msg("Sent read receipt to Signal") - } - } - return nil -} - -func (s *SignalClient) HandleMatrixTyping(ctx context.Context, typing *bridgev2.MatrixTyping) error { - userID, _, err := s.parsePortalID(typing.Portal.ID) - if err != nil { - return err - } - // Only send typing notifications in DMs for now - // Sending efficiently to groups requires implementing the proper SenderKey stuff first - if !userID.IsEmpty() && userID.Type == libsignalgo.ServiceIDTypeACI { - typingMessage := signalmeow.TypingMessage(typing.IsTyping) - result := s.Client.SendMessage(ctx, userID, typingMessage) - fmt.Println(result) - // TODO check result - } - return nil -} - -type msgconvPortalMethods struct{} - -func (mpm *msgconvPortalMethods) UploadMatrixMedia(ctx context.Context, data []byte, fileName, contentType string) (id.ContentURIString, error) { - mcCtx := ctx.Value(msgconvContextKey).(*msgconvContext) - uri, _, err := mcCtx.Intent.UploadMedia(ctx, "", data, fileName, contentType) - return uri, err -} - -func (mpm *msgconvPortalMethods) DownloadMatrixMedia(ctx context.Context, uri id.ContentURIString) ([]byte, error) { - return ctx.Value(msgconvContextKey).(*msgconvContext).Connector.Bridge.Bot.DownloadMedia(ctx, uri, nil) -} - -func (mpm *msgconvPortalMethods) GetMatrixReply(ctx context.Context, msg *signalpb.DataMessage_Quote) (replyTo id.EventID, replyTargetSender id.UserID) { - // Matrix replies are handled in bridgev2 code - return "", "" -} - -func (mpm *msgconvPortalMethods) GetSignalReply(ctx context.Context, content *event.MessageEventContent) *signalpb.DataMessage_Quote { - mcCtx := ctx.Value(msgconvContextKey).(*msgconvContext) - if mcCtx.ReplyTo == nil { - return nil - } - quote := &signalpb.DataMessage_Quote{ - Id: proto.Uint64(uint64(mcCtx.ReplyTo.Timestamp.UnixMilli())), - AuthorAci: proto.String(string(mcCtx.ReplyTo.SenderID)), - Type: signalpb.DataMessage_Quote_NORMAL.Enum(), - } - if mcCtx.ReplyTo.Metadata.Extra["contains_attachments"] != false { - quote.Attachments = make([]*signalpb.DataMessage_Quote_QuotedAttachment, 1) - } - return quote -} - -func (mpm *msgconvPortalMethods) GetClient(ctx context.Context) *signalmeow.Client { - return ctx.Value(msgconvContextKey).(*msgconvContext).Client.Client -} - -func (mpm *msgconvPortalMethods) GetData(ctx context.Context) *legacydb.Portal { - mcCtx := ctx.Value(msgconvContextKey).(*msgconvContext) - portal := mcCtx.Portal - userID, groupID, _ := mcCtx.Client.parsePortalID(portal.ID) - chatID := string(groupID) - if chatID == "" { - chatID = userID.String() - } - pk := legacydb.PortalKey{ - ChatID: chatID, - } - if len(chatID) != 44 { - pk.Receiver = mcCtx.Client.Client.Store.ACI - } - return &legacydb.Portal{ - PortalKey: pk, - MXID: portal.MXID, - Name: portal.Name, - Topic: portal.Topic, - //AvatarPath: "", - //AvatarHash: "", - //AvatarURL: id.ContentURI{}, - NameSet: portal.NameSet, - AvatarSet: portal.AvatarSet, - TopicSet: portal.TopicSet, - //Revision: portal.Metadata["revision"].(uint32), - Encrypted: true, - //RelayUserID: portal.Relay.UserMXID, - ExpirationTime: uint32(portal.Metadata.DisappearTimer.Milliseconds()), - } -} diff --git a/pkg/connector/handlematrix.go b/pkg/connector/handlematrix.go new file mode 100644 index 0000000..839c644 --- /dev/null +++ b/pkg/connector/handlematrix.go @@ -0,0 +1,278 @@ +// mautrix-signal - A Matrix-Signal puppeting bridge. +// Copyright (C) 2024 Tulir Asokan +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +package connector + +import ( + "context" + "fmt" + "time" + + "github.com/google/uuid" + "github.com/rs/zerolog" + "go.mau.fi/util/variationselector" + "google.golang.org/protobuf/proto" + "maunium.net/go/mautrix/bridgev2" + "maunium.net/go/mautrix/bridgev2/database" + "maunium.net/go/mautrix/bridgev2/networkid" + + "go.mau.fi/mautrix-signal/pkg/libsignalgo" + "go.mau.fi/mautrix-signal/pkg/signalmeow" + signalpb "go.mau.fi/mautrix-signal/pkg/signalmeow/protobuf" +) + +func (s *SignalClient) sendMessage(ctx context.Context, portalID networkid.PortalID, content *signalpb.Content) (signalmeow.SendResult, error) { + userID, groupID, err := s.parsePortalID(portalID) + if err != nil { + return nil, err + } + if groupID != "" { + res, err := s.Client.SendGroupMessage(ctx, groupID, content) + if err != nil { + return nil, err + } + return res, nil + } else { + res := s.Client.SendMessage(ctx, userID, content) + return &res, nil + } +} + +func (s *SignalClient) HandleMatrixMessage(ctx context.Context, msg *bridgev2.MatrixMessage) (message *bridgev2.MatrixMessageResponse, err error) { + mcCtx := &msgconvContext{ + Connector: s.Main, + Intent: nil, + Client: s, + Portal: msg.Portal, + ReplyTo: msg.ReplyTo, + } + ctx = context.WithValue(ctx, msgconvContextKey, mcCtx) + converted, err := s.Main.MsgConv.ToSignal(ctx, msg.Event, msg.Content, msg.OrigSender != nil) + if err != nil { + return nil, err + } + res, err := s.sendMessage(ctx, msg.Portal.ID, &signalpb.Content{DataMessage: converted}) + if err != nil { + return nil, err + } + // TODO check result + fmt.Println(res) + dbMsg := &database.Message{ + ID: makeMessageID(s.Client.Store.ACI, converted.GetTimestamp()), + SenderID: makeUserID(s.Client.Store.ACI), + Timestamp: time.UnixMilli(int64(converted.GetTimestamp())), + } + dbMsg.Metadata.Extra = map[string]any{ + "contains_attachments": len(converted.Attachments) > 0, + } + if msg.ReplyTo != nil { + dbMsg.RelatesToRowID = msg.ReplyTo.RowID + } + return &bridgev2.MatrixMessageResponse{ + DB: dbMsg, + }, nil +} + +func (s *SignalClient) HandleMatrixEdit(ctx context.Context, msg *bridgev2.MatrixEdit) error { + _, targetSentTimestamp, err := parseMessageID(msg.EditTarget.ID) + if err != nil { + return fmt.Errorf("failed to parse target message ID: %w", err) + } else if msg.EditTarget.SenderID != makeUserID(s.Client.Store.ACI) { + return fmt.Errorf("cannot edit other people's messages") + } + mcCtx := &msgconvContext{ + Connector: s.Main, + Intent: nil, + Client: s, + Portal: msg.Portal, + } + if msg.EditTarget.RelatesToRowID != 0 { + var err error + mcCtx.ReplyTo, err = s.Main.Bridge.DB.Message.GetByRowID(ctx, msg.EditTarget.RelatesToRowID) + if err != nil { + return fmt.Errorf("failed to get message reply target: %w", err) + } + } + ctx = context.WithValue(ctx, msgconvContextKey, mcCtx) + converted, err := s.Main.MsgConv.ToSignal(ctx, msg.Event, msg.Content, msg.OrigSender != nil) + if err != nil { + return err + } + res, err := s.sendMessage(ctx, msg.Portal.ID, &signalpb.Content{EditMessage: &signalpb.EditMessage{ + TargetSentTimestamp: proto.Uint64(targetSentTimestamp), + DataMessage: converted, + }}) + if err != nil { + return err + } + // TODO check result + fmt.Println(res) + msg.EditTarget.ID = makeMessageID(s.Client.Store.ACI, converted.GetTimestamp()) + msg.EditTarget.Metadata.Extra["contains_attachments"] = len(converted.Attachments) > 0 + return nil +} + +func (s *SignalClient) PreHandleMatrixReaction(ctx context.Context, msg *bridgev2.MatrixReaction) (bridgev2.MatrixReactionPreResponse, error) { + return bridgev2.MatrixReactionPreResponse{ + SenderID: makeUserID(s.Client.Store.ACI), + EmojiID: "", + Emoji: variationselector.FullyQualify(msg.Content.RelatesTo.Key), + }, nil +} + +func (s *SignalClient) HandleMatrixReaction(ctx context.Context, msg *bridgev2.MatrixReaction) (reaction *database.Reaction, err error) { + targetAuthorACI, targetSentTimestamp, err := parseMessageID(msg.TargetMessage.ID) + if err != nil { + return nil, fmt.Errorf("failed to parse target message ID: %w", err) + } + wrappedContent := &signalpb.Content{ + DataMessage: &signalpb.DataMessage{ + Timestamp: proto.Uint64(uint64(msg.Event.Timestamp)), + RequiredProtocolVersion: proto.Uint32(uint32(signalpb.DataMessage_REACTIONS)), + Reaction: &signalpb.DataMessage_Reaction{ + Emoji: proto.String(msg.PreHandleResp.Emoji), + Remove: proto.Bool(false), + TargetAuthorAci: proto.String(targetAuthorACI.String()), + TargetSentTimestamp: proto.Uint64(targetSentTimestamp), + }, + }, + } + res, err := s.sendMessage(ctx, msg.Portal.ID, wrappedContent) + if err != nil { + return nil, err + } + // TODO check result + fmt.Println(res) + return &database.Reaction{}, nil +} + +func (s *SignalClient) HandleMatrixReactionRemove(ctx context.Context, msg *bridgev2.MatrixReactionRemove) error { + targetAuthorACI, targetSentTimestamp, err := parseMessageID(msg.TargetReaction.MessageID) + if err != nil { + return fmt.Errorf("failed to parse target message ID: %w", err) + } + wrappedContent := &signalpb.Content{ + DataMessage: &signalpb.DataMessage{ + Timestamp: proto.Uint64(uint64(msg.Event.Timestamp)), + RequiredProtocolVersion: proto.Uint32(uint32(signalpb.DataMessage_REACTIONS)), + Reaction: &signalpb.DataMessage_Reaction{ + Emoji: proto.String(msg.TargetReaction.Metadata.Emoji), + Remove: proto.Bool(true), + TargetAuthorAci: proto.String(targetAuthorACI.String()), + TargetSentTimestamp: proto.Uint64(targetSentTimestamp), + }, + }, + } + res, err := s.sendMessage(ctx, msg.Portal.ID, wrappedContent) + if err != nil { + return err + } + // TODO check result + fmt.Println(res) + return nil +} + +func (s *SignalClient) HandleMatrixMessageRemove(ctx context.Context, msg *bridgev2.MatrixMessageRemove) error { + _, targetSentTimestamp, err := parseMessageID(msg.TargetMessage.ID) + if err != nil { + return fmt.Errorf("failed to parse target message ID: %w", err) + } else if msg.TargetMessage.SenderID != makeUserID(s.Client.Store.ACI) { + return fmt.Errorf("cannot delete other people's messages") + } + wrappedContent := &signalpb.Content{ + DataMessage: &signalpb.DataMessage{ + Timestamp: proto.Uint64(uint64(msg.Event.Timestamp)), + Delete: &signalpb.DataMessage_Delete{ + TargetSentTimestamp: proto.Uint64(targetSentTimestamp), + }, + }, + } + res, err := s.sendMessage(ctx, msg.Portal.ID, wrappedContent) + if err != nil { + return err + } + // TODO check result + fmt.Println(res) + return nil +} + +func (s *SignalClient) HandleMatrixReadReceipt(ctx context.Context, receipt *bridgev2.MatrixReadReceipt) error { + if !receipt.ReadUpTo.After(receipt.LastRead) { + return nil + } + if receipt.LastRead.IsZero() { + receipt.LastRead = receipt.ReadUpTo.Add(-5 * time.Second) + } + dbMessages, err := s.Main.Bridge.DB.Message.GetMessagesBetweenTimeQuery(ctx, receipt.Portal.PortalKey, receipt.LastRead, receipt.ReadUpTo) + if err != nil { + return fmt.Errorf("failed to get messages to mark as read: %w", err) + } else if len(dbMessages) == 0 { + return nil + } + messagesToRead := map[uuid.UUID][]uint64{} + for _, msg := range dbMessages { + userID, timestamp, err := parseMessageID(msg.ID) + if err != nil { + return fmt.Errorf("failed to parse message ID %q: %w", msg.ID, err) + } + messagesToRead[userID] = append(messagesToRead[userID], timestamp) + } + zerolog.Ctx(ctx).Debug(). + Any("targets", messagesToRead). + Msg("Collected read receipt target messages") + + // TODO send sync message manually containing all read receipts instead of a separate message for each recipient + + for destination, messages := range messagesToRead { + // Don't send read receipts for own messages + if destination == s.Client.Store.ACI { + continue + } + // Don't use portal.sendSignalMessage because we're sending this straight to + // who sent the original message, not the portal's ChatID + ctx, cancel := context.WithTimeout(ctx, 10*time.Second) + result := s.Client.SendMessage(ctx, libsignalgo.NewACIServiceID(destination), signalmeow.ReadReceptMessageForTimestamps(messages)) + cancel() + if !result.WasSuccessful { + zerolog.Ctx(ctx).Err(result.FailedSendResult.Error). + Stringer("destination", destination). + Uints64("message_ids", messages). + Msg("Failed to send read receipt to Signal") + } else { + zerolog.Ctx(ctx).Debug(). + Stringer("destination", destination). + Uints64("message_ids", messages). + Msg("Sent read receipt to Signal") + } + } + return nil +} + +func (s *SignalClient) HandleMatrixTyping(ctx context.Context, typing *bridgev2.MatrixTyping) error { + userID, _, err := s.parsePortalID(typing.Portal.ID) + if err != nil { + return err + } + // Only send typing notifications in DMs for now + // Sending efficiently to groups requires implementing the proper SenderKey stuff first + if !userID.IsEmpty() && userID.Type == libsignalgo.ServiceIDTypeACI { + typingMessage := signalmeow.TypingMessage(typing.IsTyping) + result := s.Client.SendMessage(ctx, userID, typingMessage) + fmt.Println(result) + // TODO check result + } + return nil +} diff --git a/pkg/connector/handlesignal.go b/pkg/connector/handlesignal.go new file mode 100644 index 0000000..bfbc773 --- /dev/null +++ b/pkg/connector/handlesignal.go @@ -0,0 +1,431 @@ +// mautrix-signal - A Matrix-Signal puppeting bridge. +// Copyright (C) 2024 Tulir Asokan +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +package connector + +import ( + "context" + "fmt" + "time" + + "github.com/google/uuid" + "github.com/rs/zerolog" + "go.mau.fi/util/exzerolog" + "maunium.net/go/mautrix/bridgev2" + "maunium.net/go/mautrix/bridgev2/database" + "maunium.net/go/mautrix/bridgev2/networkid" + + "go.mau.fi/mautrix-signal/pkg/signalmeow/events" + signalpb "go.mau.fi/mautrix-signal/pkg/signalmeow/protobuf" +) + +func (s *SignalClient) handleSignalEvent(rawEvt events.SignalEvent) { + switch evt := rawEvt.(type) { + case *events.ChatEvent: + s.Main.Bridge.QueueRemoteEvent(s.UserLogin, &Bv2ChatEvent{ChatEvent: evt, s: s}) + case *events.DecryptionError: + case *events.Receipt: + s.handleSignalReceipt(evt) + case *events.ReadSelf: + s.handleSignalReadSelf(evt) + case *events.Call: + case *events.ContactList: + s.handleSignalContactList(evt) + case *events.ACIFound: + s.handleSignalACIFound(evt) + } +} + +type Bv2ChatEvent struct { + *events.ChatEvent + s *SignalClient +} + +var ( + _ bridgev2.RemoteMessage = (*Bv2ChatEvent)(nil) + _ bridgev2.RemoteEdit = (*Bv2ChatEvent)(nil) + _ bridgev2.RemoteEventWithTimestamp = (*Bv2ChatEvent)(nil) + _ bridgev2.RemoteReaction = (*Bv2ChatEvent)(nil) + _ bridgev2.RemoteReactionRemove = (*Bv2ChatEvent)(nil) + _ bridgev2.RemoteMessageRemove = (*Bv2ChatEvent)(nil) + _ bridgev2.RemoteTyping = (*Bv2ChatEvent)(nil) +) + +func (evt *Bv2ChatEvent) GetType() bridgev2.RemoteEventType { + switch innerEvt := evt.Event.(type) { + case *signalpb.DataMessage: + switch { + case innerEvt.Body != nil, innerEvt.Attachments != nil, innerEvt.Contact != nil, innerEvt.Sticker != nil: + return bridgev2.RemoteEventMessage + case innerEvt.Reaction != nil: + if innerEvt.Reaction.GetRemove() { + return bridgev2.RemoteEventReactionRemove + } + return bridgev2.RemoteEventReaction + case innerEvt.Delete != nil: + return bridgev2.RemoteEventMessageRemove + } + case *signalpb.EditMessage: + return bridgev2.RemoteEventEdit + case *signalpb.TypingMessage: + return bridgev2.RemoteEventTyping + } + return bridgev2.RemoteEventUnknown +} + +func (evt *Bv2ChatEvent) GetTimeout() time.Duration { + if evt.Event.(*signalpb.TypingMessage).GetAction() == signalpb.TypingMessage_STARTED { + return 15 * time.Second + } else { + return 0 + } +} + +func (evt *Bv2ChatEvent) GetPortalKey() networkid.PortalKey { + return evt.s.makePortalKey(evt.Info.ChatID) +} + +func (evt *Bv2ChatEvent) ShouldCreatePortal() bool { + return evt.GetType() == bridgev2.RemoteEventMessage +} + +func (evt *Bv2ChatEvent) AddLogContext(c zerolog.Context) zerolog.Context { + c = c.Stringer("sender_id", evt.Info.Sender) + switch innerEvt := evt.Event.(type) { + case *signalpb.DataMessage: + c = c.Uint64("message_ts", innerEvt.GetTimestamp()) + switch { + case innerEvt.Reaction != nil: + c = c.Uint64("reaction_target_ts", innerEvt.Reaction.GetTargetSentTimestamp()) + case innerEvt.Delete != nil: + c = c.Uint64("delete_target_ts", innerEvt.Delete.GetTargetSentTimestamp()) + } + case *signalpb.EditMessage: + c = c. + Uint64("edit_target_ts", innerEvt.GetTargetSentTimestamp()). + Uint64("edit_ts", innerEvt.GetDataMessage().GetTimestamp()) + } + return c +} + +func (evt *Bv2ChatEvent) GetSender() bridgev2.EventSender { + return evt.s.makeEventSender(evt.Info.Sender) +} + +func (evt *Bv2ChatEvent) GetID() networkid.MessageID { + ts := evt.getDataMsgTimestamp() + if ts == 0 { + panic(fmt.Errorf("GetID() called for non-DataMessage event")) + } + return makeMessageID(evt.Info.Sender, ts) +} + +func (evt *Bv2ChatEvent) getDataMsgTimestamp() uint64 { + switch innerEvt := evt.Event.(type) { + case *signalpb.DataMessage: + return innerEvt.GetTimestamp() + case *signalpb.EditMessage: + return innerEvt.GetDataMessage().GetTimestamp() + default: + return 0 + } +} + +func (evt *Bv2ChatEvent) GetTimestamp() time.Time { + ts := evt.getDataMsgTimestamp() + if ts == 0 { + return time.Now() + } + return time.UnixMilli(int64(ts)) +} + +func (evt *Bv2ChatEvent) GetTargetMessage() networkid.MessageID { + var targetAuthorACI string + var targetSentTS uint64 + switch innerEvt := evt.Event.(type) { + case *signalpb.DataMessage: + switch { + case innerEvt.Reaction != nil: + targetAuthorACI = innerEvt.Reaction.GetTargetAuthorAci() + targetSentTS = innerEvt.Reaction.GetTargetSentTimestamp() + case innerEvt.Delete != nil: + targetSentTS = innerEvt.Delete.GetTargetSentTimestamp() + default: + panic(fmt.Errorf("GetTargetMessage() called for message type without target")) + } + case *signalpb.EditMessage: + targetSentTS = innerEvt.GetTargetSentTimestamp() + default: + panic(fmt.Errorf("GetTargetMessage() called for message type without target")) + } + targetAuthorUUID := evt.Info.Sender + if targetAuthorACI != "" { + targetAuthorUUID, _ = uuid.Parse(targetAuthorACI) + } + return makeMessageID(targetAuthorUUID, targetSentTS) +} + +func (evt *Bv2ChatEvent) GetReactionEmoji() (string, networkid.EmojiID) { + dataMsg, ok := evt.Event.(*signalpb.DataMessage) + if !ok || dataMsg.Reaction == nil { + panic(fmt.Errorf("GetReactionEmoji() called for non-reaction event")) + } + return dataMsg.GetReaction().GetEmoji(), "" +} + +func (evt *Bv2ChatEvent) GetRemovedEmojiID() networkid.EmojiID { + return "" +} + +func (evt *Bv2ChatEvent) ConvertMessage(ctx context.Context, portal *bridgev2.Portal, intent bridgev2.MatrixAPI) (*bridgev2.ConvertedMessage, error) { + mcCtx := &msgconvContext{ + Connector: evt.s.Main, + Intent: intent, + Client: evt.s, + Portal: portal, + } + ctx = context.WithValue(ctx, msgconvContextKey, mcCtx) + dataMsg, ok := evt.Event.(*signalpb.DataMessage) + if !ok { + return nil, fmt.Errorf("ConvertMessage() called for non-DataMessage event") + } + converted := evt.s.Main.MsgConv.ToMatrix(ctx, dataMsg) + converted.MergeCaption() + var replyTo *networkid.MessageOptionalPartID + if dataMsg.GetQuote() != nil { + quoteAuthor, _ := uuid.Parse(dataMsg.Quote.GetAuthorAci()) + replyTo = &networkid.MessageOptionalPartID{ + MessageID: makeMessageID(quoteAuthor, dataMsg.Quote.GetId()), + } + } + convertedParts := make([]*bridgev2.ConvertedMessagePart, len(converted.Parts)) + for i, part := range converted.Parts { + convertedParts[i] = &bridgev2.ConvertedMessagePart{ + ID: makeMessagePartID(i), + Type: part.Type, + Content: part.Content, + Extra: part.Extra, + } + } + var disappear database.DisappearingSetting + if converted.DisappearIn != 0 { + disappear = database.DisappearingSetting{ + Type: database.DisappearingTypeAfterRead, + Timer: time.Duration(converted.DisappearIn) * time.Second, + } + if evt.Info.Sender == evt.s.Client.Store.ACI { + disappear.DisappearAt = time.UnixMilli(int64(dataMsg.GetTimestamp())).Add(disappear.Timer) + } + if portal.Metadata.DisappearTimer != disappear.Timer { + portal.Metadata.DisappearType = disappear.Type + portal.Metadata.DisappearTimer = disappear.Timer + // TODO if the message doesn't have the DataMessage_EXPIRATION_TIMER_UPDATE, + // we should send a message to the portal notifying of the implicit update + err := portal.Save(ctx) + if err != nil { + zerolog.Ctx(ctx).Err(err).Msg("Failed to save portal metadata after updating disappearing timer") + } else { + zerolog.Ctx(ctx).Debug().Dur("new_timer", portal.Metadata.DisappearTimer).Msg("Updated disappearing timer in portal") + } + } + } + return &bridgev2.ConvertedMessage{ + ReplyTo: replyTo, + Parts: convertedParts, + Disappear: disappear, + }, nil +} + +func (evt *Bv2ChatEvent) ConvertEdit(ctx context.Context, portal *bridgev2.Portal, intent bridgev2.MatrixAPI, existing []*database.Message) (*bridgev2.ConvertedEdit, error) { + mcCtx := &msgconvContext{ + Connector: evt.s.Main, + Intent: intent, + Client: evt.s, + Portal: portal, + } + ctx = context.WithValue(ctx, msgconvContextKey, mcCtx) + editMsg, ok := evt.Event.(*signalpb.EditMessage) + if !ok { + return nil, fmt.Errorf("ConvertEdit() called for non-EditMessage event") + } + // TODO tell converter about existing parts to avoid reupload? + converted := evt.s.Main.MsgConv.ToMatrix(ctx, editMsg.GetDataMessage()) + converted.MergeCaption() + convertedEdit := &bridgev2.ConvertedEdit{} + // TODO can anything other than the text be edited? + lastPart := converted.Parts[len(converted.Parts)-1] + convertedEdit.ModifiedParts = append(convertedEdit.ModifiedParts, &bridgev2.ConvertedEditPart{ + Part: existing[len(existing)-1], + Type: lastPart.Type, + Content: lastPart.Content, + Extra: lastPart.Extra, + }) + return convertedEdit, nil +} + +type Bv2Receipt struct { + Type signalpb.ReceiptMessage_Type + Chat networkid.PortalKey + Sender bridgev2.EventSender + + LastTS time.Time + LastID networkid.MessageID + IDs []networkid.MessageID +} + +func (b *Bv2Receipt) GetType() bridgev2.RemoteEventType { + switch b.Type { + case signalpb.ReceiptMessage_READ: + return bridgev2.RemoteEventReadReceipt + case signalpb.ReceiptMessage_DELIVERY: + return bridgev2.RemoteEventDeliveryReceipt + default: + return bridgev2.RemoteEventUnknown + } +} + +func (b *Bv2Receipt) GetPortalKey() networkid.PortalKey { + return b.Chat +} + +func (b *Bv2Receipt) AddLogContext(c zerolog.Context) zerolog.Context { + return c. + Str("sender_id", string(b.Sender.Sender)). + Stringer("receipt_type", b.Type). + Array("message_ids", exzerolog.ArrayOfStrs(b.IDs)) +} + +func (b *Bv2Receipt) GetSender() bridgev2.EventSender { + return b.Sender +} + +func (b *Bv2Receipt) GetLastReceiptTarget() networkid.MessageID { + return b.LastID +} + +func (b *Bv2Receipt) GetReceiptTargets() []networkid.MessageID { + return b.IDs +} + +var _ bridgev2.RemoteReceipt = (*Bv2Receipt)(nil) + +func convertReceipts[T any](ctx context.Context, input []T, getMessageFunc func(ctx context.Context, msgID T) (*database.Message, error)) map[networkid.PortalKey]*Bv2Receipt { + log := zerolog.Ctx(ctx) + receipts := make(map[networkid.PortalKey]*Bv2Receipt) + for _, msgID := range input { + msg, err := getMessageFunc(ctx, msgID) + if err != nil { + log.Err(err).Any("message_id", msgID).Msg("Failed to get target message for receipt") + } else if msg == nil { + log.Debug().Any("message_id", msgID).Msg("Got receipt for unknown message") + } else { + receiptEvt, ok := receipts[msg.Room] + if !ok { + receiptEvt = &Bv2Receipt{Chat: msg.Room} + receipts[msg.Room] = receiptEvt + } + receiptEvt.IDs = append(receiptEvt.IDs, msg.ID) + if receiptEvt.LastTS.Before(msg.Timestamp) { + receiptEvt.LastTS = msg.Timestamp + receiptEvt.LastID = msg.ID + } + } + } + return receipts +} + +func (s *SignalClient) dispatchReceipts(sender uuid.UUID, receiptType signalpb.ReceiptMessage_Type, receipts map[networkid.PortalKey]*Bv2Receipt) { + evtSender := s.makeEventSender(sender) + for chat, receiptEvt := range receipts { + receiptEvt.Chat = chat + receiptEvt.Sender = evtSender + receiptEvt.Type = receiptType + s.Main.Bridge.QueueRemoteEvent(s.UserLogin, receiptEvt) + } +} + +func (s *SignalClient) handleSignalReceipt(evt *events.Receipt) { + log := s.UserLogin.Log.With(). + Str("action", "handle signal receipt"). + Stringer("sender_id", evt.Sender). + Stringer("receipt_type", evt.Content.GetType()). + Logger() + ctx := log.WithContext(context.TODO()) + receipts := convertReceipts(ctx, evt.Content.Timestamp, func(ctx context.Context, msgTS uint64) (*database.Message, error) { + return s.Main.Bridge.DB.Message.GetFirstPartByID(ctx, makeMessageID(s.Client.Store.ACI, msgTS)) + }) + s.dispatchReceipts(evt.Sender, evt.Content.GetType(), receipts) +} + +func (s *SignalClient) handleSignalReadSelf(evt *events.ReadSelf) { + log := s.UserLogin.Log.With(). + Str("action", "handle signal read self"). + Logger() + ctx := log.WithContext(context.TODO()) + receipts := convertReceipts(ctx, evt.Messages, func(ctx context.Context, msgInfo *signalpb.SyncMessage_Read) (*database.Message, error) { + aciUUID, err := uuid.Parse(msgInfo.GetSenderAci()) + if err != nil { + return nil, err + } + return s.Main.Bridge.DB.Message.GetFirstPartByID(ctx, makeMessageID(aciUUID, msgInfo.GetTimestamp())) + }) + s.dispatchReceipts(s.Client.Store.ACI, signalpb.ReceiptMessage_READ, receipts) +} + +func (s *SignalClient) handleSignalACIFound(evt *events.ACIFound) { + log := s.UserLogin.Log.With(). + Str("action", "handle aci found"). + Stringer("aci", evt.ACI). + Stringer("pni", evt.PNI). + Logger() + ctx := log.WithContext(context.TODO()) + pniPortalKey := s.makeDMPortalKey(evt.PNI) + aciPortalKey := s.makeDMPortalKey(evt.ACI) + result, portal, err := s.Main.Bridge.ReIDPortal(ctx, pniPortalKey, aciPortalKey) + if err != nil { + log.Err(err).Msg("Failed to re-ID portal") + } else if result == bridgev2.ReIDResultSourceReIDd || result == bridgev2.ReIDResultTargetDeletedAndSourceReIDd { + // If the source portal is re-ID'd, we need to sync metadata and participants. + // If the source is deleted, then it doesn't matter, any existing target will already be correct + info, err := s.GetChatInfo(ctx, portal) + if err != nil { + log.Err(err).Msg("Failed to get chat info to update portal after re-ID") + } else { + portal.UpdateInfo(ctx, info, s.UserLogin, nil, time.Time{}) + } + } +} + +func (s *SignalClient) handleSignalContactList(evt *events.ContactList) { + log := s.UserLogin.Log.With().Str("action", "handle contact list").Logger() + ctx := log.WithContext(context.TODO()) + for _, contact := range evt.Contacts { + if contact.ACI != uuid.Nil { + fullContact, err := s.Client.ContactByACI(ctx, contact.ACI) + if err != nil { + log.Err(err).Msg("Failed to get full contact info from store") + continue + } + fullContact.ContactAvatar = contact.ContactAvatar + ghost, err := s.Main.Bridge.GetGhostByID(ctx, makeUserID(contact.ACI)) + if err != nil { + log.Err(err).Msg("Failed to get ghost to update contact info") + continue + } + ghost.UpdateInfo(ctx, s.contactToUserInfo(contact)) + } + } +} diff --git a/pkg/connector/id.go b/pkg/connector/id.go new file mode 100644 index 0000000..147b21f --- /dev/null +++ b/pkg/connector/id.go @@ -0,0 +1,130 @@ +// mautrix-signal - A Matrix-Signal puppeting bridge. +// Copyright (C) 2024 Tulir Asokan +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +package connector + +import ( + "fmt" + "strconv" + "strings" + + "github.com/google/uuid" + "maunium.net/go/mautrix/bridgev2" + "maunium.net/go/mautrix/bridgev2/networkid" + + "go.mau.fi/mautrix-signal/pkg/libsignalgo" + "go.mau.fi/mautrix-signal/pkg/signalmeow/types" +) + +func parseUserID(userID networkid.UserID) (uuid.UUID, error) { + serviceID, err := parseUserIDAsServiceID(userID) + if err != nil { + return uuid.Nil, err + } else if serviceID.Type != libsignalgo.ServiceIDTypeACI { + return uuid.Nil, fmt.Errorf("invalid user ID: expected ACI type") + } else { + return serviceID.UUID, nil + } +} + +func parseUserIDAsServiceID(userID networkid.UserID) (libsignalgo.ServiceID, error) { + return libsignalgo.ServiceIDFromString(string(userID)) +} + +func (s *SignalClient) parsePortalID(portalID networkid.PortalID) (userID libsignalgo.ServiceID, groupID types.GroupIdentifier, err error) { + if len(portalID) == 44 { + groupID = types.GroupIdentifier(portalID) + } else { + userID, err = libsignalgo.ServiceIDFromString(string(portalID)) + } + return +} + +func parseMessageID(messageID networkid.MessageID) (sender uuid.UUID, timestamp uint64, err error) { + parts := strings.Split(string(messageID), "|") + if len(parts) != 2 { + err = fmt.Errorf("invalid message ID: expected two pipe-separated parts") + return + } + sender, err = uuid.Parse(parts[0]) + if err != nil { + return + } + timestamp, err = strconv.ParseUint(parts[1], 10, 64) + return +} + +func makeGroupPortalID(groupID types.GroupIdentifier) networkid.PortalID { + return networkid.PortalID(groupID) +} + +func makeGroupPortalKey(groupID types.GroupIdentifier) networkid.PortalKey { + return networkid.PortalKey{ + ID: makeGroupPortalID(groupID), + Receiver: "", + } +} + +func makeDMPortalID(serviceID libsignalgo.ServiceID) networkid.PortalID { + return networkid.PortalID(serviceID.String()) +} + +func (s *SignalClient) makePortalKey(chatID string) networkid.PortalKey { + key := networkid.PortalKey{ID: networkid.PortalID(chatID)} + // For non-group chats, add receiver + if len(chatID) != 44 { + key.Receiver = s.UserLogin.ID + } + return key +} + +func (s *SignalClient) makeDMPortalKey(serviceID libsignalgo.ServiceID) networkid.PortalKey { + return networkid.PortalKey{ + ID: makeDMPortalID(serviceID), + Receiver: s.UserLogin.ID, + } +} + +func makeMessageID(sender uuid.UUID, timestamp uint64) networkid.MessageID { + return networkid.MessageID(fmt.Sprintf("%s|%d", sender, timestamp)) +} + +func makeUserID(user uuid.UUID) networkid.UserID { + return networkid.UserID(user.String()) +} + +func makeUserIDFromServiceID(user libsignalgo.ServiceID) networkid.UserID { + return networkid.UserID(user.String()) +} + +func makeUserLoginID(user uuid.UUID) networkid.UserLoginID { + return networkid.UserLoginID(user.String()) +} + +func (s *SignalClient) makeEventSender(sender uuid.UUID) bridgev2.EventSender { + return bridgev2.EventSender{ + IsFromMe: sender == s.Client.Store.ACI, + SenderLogin: makeUserLoginID(sender), + Sender: makeUserID(sender), + } +} + +func makeMessagePartID(index int) networkid.PartID { + if index == 0 { + return "" + } + return networkid.PartID(strconv.Itoa(index)) +} diff --git a/pkg/connector/msgconvproxy.go b/pkg/connector/msgconvproxy.go new file mode 100644 index 0000000..bf1ef3d --- /dev/null +++ b/pkg/connector/msgconvproxy.go @@ -0,0 +1,115 @@ +// mautrix-signal - A Matrix-Signal puppeting bridge. +// Copyright (C) 2024 Tulir Asokan +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +package connector + +import ( + "context" + + "google.golang.org/protobuf/proto" + "maunium.net/go/mautrix/bridgev2" + "maunium.net/go/mautrix/bridgev2/database" + "maunium.net/go/mautrix/event" + "maunium.net/go/mautrix/id" + + legacydb "go.mau.fi/mautrix-signal/database" + "go.mau.fi/mautrix-signal/msgconv" + "go.mau.fi/mautrix-signal/pkg/signalmeow" + signalpb "go.mau.fi/mautrix-signal/pkg/signalmeow/protobuf" +) + +type contextKey int + +var msgconvContextKey contextKey + +type msgconvContext struct { + Connector *SignalConnector + Intent bridgev2.MatrixAPI + Client *SignalClient + Portal *bridgev2.Portal + ReplyTo *database.Message +} + +type msgconvPortalMethods struct{} + +var _ msgconv.PortalMethods = (*msgconvPortalMethods)(nil) + +func (mpm *msgconvPortalMethods) UploadMatrixMedia(ctx context.Context, data []byte, fileName, contentType string) (id.ContentURIString, error) { + mcCtx := ctx.Value(msgconvContextKey).(*msgconvContext) + uri, _, err := mcCtx.Intent.UploadMedia(ctx, "", data, fileName, contentType) + return uri, err +} + +func (mpm *msgconvPortalMethods) DownloadMatrixMedia(ctx context.Context, uri id.ContentURIString) ([]byte, error) { + return ctx.Value(msgconvContextKey).(*msgconvContext).Connector.Bridge.Bot.DownloadMedia(ctx, uri, nil) +} + +func (mpm *msgconvPortalMethods) GetMatrixReply(ctx context.Context, msg *signalpb.DataMessage_Quote) (replyTo id.EventID, replyTargetSender id.UserID) { + // Matrix replies are handled in bridgev2 code + return "", "" +} + +func (mpm *msgconvPortalMethods) GetSignalReply(ctx context.Context, content *event.MessageEventContent) *signalpb.DataMessage_Quote { + mcCtx := ctx.Value(msgconvContextKey).(*msgconvContext) + if mcCtx.ReplyTo == nil { + return nil + } + quote := &signalpb.DataMessage_Quote{ + Id: proto.Uint64(uint64(mcCtx.ReplyTo.Timestamp.UnixMilli())), + AuthorAci: proto.String(string(mcCtx.ReplyTo.SenderID)), + Type: signalpb.DataMessage_Quote_NORMAL.Enum(), + } + if mcCtx.ReplyTo.Metadata.Extra["contains_attachments"] != false { + quote.Attachments = make([]*signalpb.DataMessage_Quote_QuotedAttachment, 1) + } + return quote +} + +func (mpm *msgconvPortalMethods) GetClient(ctx context.Context) *signalmeow.Client { + return ctx.Value(msgconvContextKey).(*msgconvContext).Client.Client +} + +func (mpm *msgconvPortalMethods) GetData(ctx context.Context) *legacydb.Portal { + mcCtx := ctx.Value(msgconvContextKey).(*msgconvContext) + portal := mcCtx.Portal + userID, groupID, _ := mcCtx.Client.parsePortalID(portal.ID) + chatID := string(groupID) + if chatID == "" { + chatID = userID.String() + } + pk := legacydb.PortalKey{ + ChatID: chatID, + } + if len(chatID) != 44 { + pk.Receiver = mcCtx.Client.Client.Store.ACI + } + return &legacydb.Portal{ + PortalKey: pk, + MXID: portal.MXID, + Name: portal.Name, + Topic: portal.Topic, + //AvatarPath: "", + //AvatarHash: "", + //AvatarURL: id.ContentURI{}, + NameSet: portal.NameSet, + AvatarSet: portal.AvatarSet, + TopicSet: portal.TopicSet, + //Revision: portal.Metadata["revision"].(uint32), + Encrypted: true, + //RelayUserID: portal.Relay.UserMXID, + ExpirationTime: uint32(portal.Metadata.DisappearTimer.Milliseconds()), + } +} From 58a1b873489a8afb88dcd9eb6b48304b6c60cf64 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Wed, 19 Jun 2024 23:30:38 +0300 Subject: [PATCH 061/580] v2: implement note to self avatar --- go.mod | 2 +- go.sum | 4 ++-- pkg/connector/chatinfo.go | 9 +++++++++ 3 files changed, 12 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index fd1ea3f..e36b1c1 100644 --- a/go.mod +++ b/go.mod @@ -19,7 +19,7 @@ require ( golang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8 golang.org/x/net v0.26.0 google.golang.org/protobuf v1.34.2 - maunium.net/go/mautrix v0.19.0-beta.1.0.20240619195836-2a7a5070fb32 + maunium.net/go/mautrix v0.19.0-beta.1.0.20240619204109-68d8ab6896fd nhooyr.io/websocket v1.8.11 ) diff --git a/go.sum b/go.sum index a6c0ff3..9c14fb4 100644 --- a/go.sum +++ b/go.sum @@ -93,7 +93,7 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= maunium.net/go/mauflag v1.0.0 h1:YiaRc0tEI3toYtJMRIfjP+jklH45uDHtT80nUamyD4M= maunium.net/go/mauflag v1.0.0/go.mod h1:nLivPOpTpHnpzEh8jEdSL9UqO9+/KBJFmNRlwKfkPeA= -maunium.net/go/mautrix v0.19.0-beta.1.0.20240619195836-2a7a5070fb32 h1:BiUVpB1hejeuCivlLOv5jKzU/Y8TTwDlQ0i1qO+JGdI= -maunium.net/go/mautrix v0.19.0-beta.1.0.20240619195836-2a7a5070fb32/go.mod h1:cxv1w6+syudmEpOewHYIQT9yO7TM5UOWmf6xEBVI4H4= +maunium.net/go/mautrix v0.19.0-beta.1.0.20240619204109-68d8ab6896fd h1:NZYFpztfJCdynpWJTGOyPcYfr+95zCut/IobMzaKCdU= +maunium.net/go/mautrix v0.19.0-beta.1.0.20240619204109-68d8ab6896fd/go.mod h1:cxv1w6+syudmEpOewHYIQT9yO7TM5UOWmf6xEBVI4H4= nhooyr.io/websocket v1.8.11 h1:f/qXNc2/3DpoSZkHt1DQu6rj4zGC8JmkkLkWss0MgN0= nhooyr.io/websocket v1.8.11/go.mod h1:rN9OFWIUwuxg4fR5tELlYC04bXYowCP9GX47ivo2l+c= diff --git a/pkg/connector/chatinfo.go b/pkg/connector/chatinfo.go index eea4381..ceb2a86 100644 --- a/pkg/connector/chatinfo.go +++ b/pkg/connector/chatinfo.go @@ -18,6 +18,7 @@ package connector import ( "context" + "crypto/sha256" "errors" "fmt" "strconv" @@ -193,12 +194,19 @@ func (s *SignalClient) makeCreateDMResponse(recipient *types.Recipient) *bridgev topic = fmt.Sprintf("%s with %s", PrivateChatTopic, recipient.E164) } var serviceID libsignalgo.ServiceID + var avatar *bridgev2.Avatar if recipient.ACI == uuid.Nil { name = s.Main.Config.FormatDisplayname(recipient) serviceID = libsignalgo.NewPNIServiceID(recipient.PNI) } else { if recipient.ACI == s.Client.Store.ACI { name = NoteToSelfName + avatar = &bridgev2.Avatar{ + ID: networkid.AvatarID(s.Main.Config.NoteToSelfAvatar), + Remove: len(s.Main.Config.NoteToSelfAvatar) == 0, + MXC: s.Main.Config.NoteToSelfAvatar, + Hash: sha256.Sum256([]byte(s.Main.Config.NoteToSelfAvatar)), + } } else { // The other user is only present if their ACI is known members = append(members, makeUserID(recipient.ACI)) @@ -209,6 +217,7 @@ func (s *SignalClient) makeCreateDMResponse(recipient *types.Recipient) *bridgev PortalID: s.makeDMPortalKey(serviceID), PortalInfo: &bridgev2.PortalInfo{ Name: &name, + Avatar: avatar, Topic: &topic, Members: members, IsDirectChat: &isDirectChat, From 70d747e1bd6415bfbaa1d567c6f3b0c488609735 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Thu, 20 Jun 2024 16:52:02 +0300 Subject: [PATCH 062/580] v2: allow re-authing existing login --- go.mod | 2 +- go.sum | 4 ++-- pkg/connector/login.go | 17 +++++++++-------- 3 files changed, 12 insertions(+), 11 deletions(-) diff --git a/go.mod b/go.mod index e36b1c1..5a418be 100644 --- a/go.mod +++ b/go.mod @@ -19,7 +19,7 @@ require ( golang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8 golang.org/x/net v0.26.0 google.golang.org/protobuf v1.34.2 - maunium.net/go/mautrix v0.19.0-beta.1.0.20240619204109-68d8ab6896fd + maunium.net/go/mautrix v0.19.0-beta.1.0.20240620135116-0418273bdbb1 nhooyr.io/websocket v1.8.11 ) diff --git a/go.sum b/go.sum index 9c14fb4..fe0d52e 100644 --- a/go.sum +++ b/go.sum @@ -93,7 +93,7 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= maunium.net/go/mauflag v1.0.0 h1:YiaRc0tEI3toYtJMRIfjP+jklH45uDHtT80nUamyD4M= maunium.net/go/mauflag v1.0.0/go.mod h1:nLivPOpTpHnpzEh8jEdSL9UqO9+/KBJFmNRlwKfkPeA= -maunium.net/go/mautrix v0.19.0-beta.1.0.20240619204109-68d8ab6896fd h1:NZYFpztfJCdynpWJTGOyPcYfr+95zCut/IobMzaKCdU= -maunium.net/go/mautrix v0.19.0-beta.1.0.20240619204109-68d8ab6896fd/go.mod h1:cxv1w6+syudmEpOewHYIQT9yO7TM5UOWmf6xEBVI4H4= +maunium.net/go/mautrix v0.19.0-beta.1.0.20240620135116-0418273bdbb1 h1:sSz/VCo3GLtnAjMBpjfn7dtN1f7RDdZ+9OTZdaxZSJc= +maunium.net/go/mautrix v0.19.0-beta.1.0.20240620135116-0418273bdbb1/go.mod h1:cxv1w6+syudmEpOewHYIQT9yO7TM5UOWmf6xEBVI4H4= nhooyr.io/websocket v1.8.11 h1:f/qXNc2/3DpoSZkHt1DQu6rj4zGC8JmkkLkWss0MgN0= nhooyr.io/websocket v1.8.11/go.mod h1:rN9OFWIUwuxg4fR5tELlYC04bXYowCP9GX47ivo2l+c= diff --git a/pkg/connector/login.go b/pkg/connector/login.go index ecb12f7..cd0aa1f 100644 --- a/pkg/connector/login.go +++ b/pkg/connector/login.go @@ -44,7 +44,6 @@ func (s *SignalConnector) CreateLogin(ctx context.Context, user *bridgev2.User, type QRLogin struct { User *bridgev2.User - Existing *bridgev2.UserLogin Main *SignalConnector cancelChan context.CancelFunc ProvChan chan signalmeow.ProvisioningResponse @@ -116,9 +115,6 @@ func (qr *QRLogin) Wait(ctx context.Context) (*bridgev2.LoginStep, error) { return nil, ctx.Err() } newLoginID := makeUserLoginID(signalID) - if qr.Existing != nil && qr.Existing.ID != newLoginID { - return nil, fmt.Errorf("user ID mismatch for re-auth") - } select { case resp := <-qr.ProvChan: @@ -131,9 +127,15 @@ func (qr *QRLogin) Wait(ctx context.Context) (*bridgev2.LoginStep, error) { return nil, ctx.Err() } - var ul *bridgev2.UserLogin - var err error - if qr.Existing == nil { + ul, err := qr.Main.Bridge.GetUserLoginByID(ctx, newLoginID) + if err != nil { + return nil, fmt.Errorf("failed to get existing login: %w", err) + } + if ul.UserMXID != qr.User.MXID { + // TODO delete old user login instead of failing new login + return nil, fmt.Errorf("login ID already in use by another user") + } + if ul == nil { ul, err = qr.User.NewLogin(ctx, &database.UserLogin{ ID: newLoginID, Metadata: database.UserLoginMetadata{ @@ -149,7 +151,6 @@ func (qr *QRLogin) Wait(ctx context.Context) (*bridgev2.LoginStep, error) { return nil, fmt.Errorf("failed to save new login: %w", err) } } else { - ul = qr.Existing ul.Metadata.Extra["phone"] = signalPhone ul.Metadata.RemoteName = signalPhone err = ul.Save(ctx) From 5e4ddb93baeac0513c8678046ca59e2b4383339f Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Thu, 20 Jun 2024 17:29:55 +0300 Subject: [PATCH 063/580] v2: add contact listing method --- go.mod | 2 +- go.sum | 4 ++-- pkg/connector/chatinfo.go | 32 ++++++++++++++++++++++++- pkg/connector/client.go | 2 ++ pkg/signalmeow/store/recipient_store.go | 20 +++++++++++----- 5 files changed, 50 insertions(+), 10 deletions(-) diff --git a/go.mod b/go.mod index 5a418be..c5862b4 100644 --- a/go.mod +++ b/go.mod @@ -19,7 +19,7 @@ require ( golang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8 golang.org/x/net v0.26.0 google.golang.org/protobuf v1.34.2 - maunium.net/go/mautrix v0.19.0-beta.1.0.20240620135116-0418273bdbb1 + maunium.net/go/mautrix v0.19.0-beta.1.0.20240620142853-7b6f3ba0541d nhooyr.io/websocket v1.8.11 ) diff --git a/go.sum b/go.sum index fe0d52e..bbb191e 100644 --- a/go.sum +++ b/go.sum @@ -93,7 +93,7 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= maunium.net/go/mauflag v1.0.0 h1:YiaRc0tEI3toYtJMRIfjP+jklH45uDHtT80nUamyD4M= maunium.net/go/mauflag v1.0.0/go.mod h1:nLivPOpTpHnpzEh8jEdSL9UqO9+/KBJFmNRlwKfkPeA= -maunium.net/go/mautrix v0.19.0-beta.1.0.20240620135116-0418273bdbb1 h1:sSz/VCo3GLtnAjMBpjfn7dtN1f7RDdZ+9OTZdaxZSJc= -maunium.net/go/mautrix v0.19.0-beta.1.0.20240620135116-0418273bdbb1/go.mod h1:cxv1w6+syudmEpOewHYIQT9yO7TM5UOWmf6xEBVI4H4= +maunium.net/go/mautrix v0.19.0-beta.1.0.20240620142853-7b6f3ba0541d h1:s3wbfQ3jJOlZy0oYE/dVSTxAHDMQHwBlHVLqQZGeQX4= +maunium.net/go/mautrix v0.19.0-beta.1.0.20240620142853-7b6f3ba0541d/go.mod h1:cxv1w6+syudmEpOewHYIQT9yO7TM5UOWmf6xEBVI4H4= nhooyr.io/websocket v1.8.11 h1:f/qXNc2/3DpoSZkHt1DQu6rj4zGC8JmkkLkWss0MgN0= nhooyr.io/websocket v1.8.11/go.mod h1:rN9OFWIUwuxg4fR5tELlYC04bXYowCP9GX47ivo2l+c= diff --git a/pkg/connector/chatinfo.go b/pkg/connector/chatinfo.go index ceb2a86..7c4c646 100644 --- a/pkg/connector/chatinfo.go +++ b/pkg/connector/chatinfo.go @@ -91,7 +91,11 @@ func (s *SignalClient) GetChatInfo(ctx context.Context, portal *bridgev2.Portal) func (s *SignalClient) contactToUserInfo(contact *types.Recipient) *bridgev2.UserInfo { isBot := false ui := &bridgev2.UserInfo{ - IsBot: &isBot, + IsBot: &isBot, + Identifiers: []string{}, + } + if contact.E164 != "" { + ui.Identifiers = append(ui.Identifiers, "tel:"+contact.E164) } name := s.Main.Config.FormatDisplayname(contact) ui.Name = &name @@ -184,6 +188,32 @@ func (s *SignalClient) CreateGroup(ctx context.Context, name string, users ...ne return nil, fmt.Errorf("not implemented") } +func (s *SignalClient) GetContactList(ctx context.Context) ([]*bridgev2.ResolveIdentifierResponse, error) { + recipients, err := s.Client.Store.RecipientStore.LoadAllContacts(ctx) + if err != nil { + return nil, err + } + resp := make([]*bridgev2.ResolveIdentifierResponse, len(recipients)) + for i, recipient := range recipients { + recipientResp := &bridgev2.ResolveIdentifierResponse{ + UserInfo: s.contactToUserInfo(recipient), + Chat: s.makeCreateDMResponse(recipient), + } + if recipient.ACI != uuid.Nil { + recipientResp.UserID = makeUserID(recipient.ACI) + ghost, err := s.Main.Bridge.GetGhostByID(ctx, recipientResp.UserID) + if err != nil { + return nil, fmt.Errorf("failed to get ghost for %s: %w", recipient.ACI, err) + } + recipientResp.Ghost = ghost + } else { + recipientResp.UserID = makeUserIDFromServiceID(libsignalgo.NewPNIServiceID(recipient.PNI)) + } + resp[i] = recipientResp + } + return resp, nil +} + func (s *SignalClient) makeCreateDMResponse(recipient *types.Recipient) *bridgev2.CreateChatResponse { isDirectChat := true isSpace := false diff --git a/pkg/connector/client.go b/pkg/connector/client.go index 6034a7c..20f3d8e 100644 --- a/pkg/connector/client.go +++ b/pkg/connector/client.go @@ -21,7 +21,9 @@ type SignalClient struct { var _ bridgev2.NetworkAPI = (*SignalClient)(nil) var _ bridgev2.PushableNetworkAPI = (*SignalClient)(nil) +var _ bridgev2.IdentifierResolvingNetworkAPI = (*SignalClient)(nil) var _ bridgev2.GroupCreatingNetworkAPI = (*SignalClient)(nil) +var _ bridgev2.ContactListingNetworkAPI = (*SignalClient)(nil) var pushCfg = &bridgev2.PushConfig{ FCM: &bridgev2.FCMPushConfig{ diff --git a/pkg/signalmeow/store/recipient_store.go b/pkg/signalmeow/store/recipient_store.go index 216dfc8..3463a00 100644 --- a/pkg/signalmeow/store/recipient_store.go +++ b/pkg/signalmeow/store/recipient_store.go @@ -40,6 +40,8 @@ type RecipientStore interface { LoadRecipientByE164(ctx context.Context, e164 string) (*types.Recipient, error) StoreRecipient(ctx context.Context, recipient *types.Recipient) error UpdateRecipientE164(ctx context.Context, aci, pni uuid.UUID, e164 string) (*types.Recipient, error) + + LoadAllContacts(ctx context.Context) ([]*types.Recipient, error) } var _ RecipientStore = (*sqlStore)(nil) @@ -62,12 +64,13 @@ const ( FROM signalmeow_recipients WHERE account_id = $1 ` - getRecipientByACIQuery = getAllRecipientsQuery + `AND aci_uuid = $2` - getRecipientByPNIQuery = getAllRecipientsQuery + `AND pni_uuid = $2` - getRecipientByACIOrPNIQuery = getAllRecipientsQuery + `AND (($2<>'00000000-0000-0000-0000-000000000000' AND aci_uuid = $2) OR ($3<>'00000000-0000-0000-0000-000000000000' AND pni_uuid = $3))` - getRecipientByPhoneQuery = getAllRecipientsQuery + `AND e164_number = $2` - deleteRecipientByPNIQuery = `DELETE FROM signalmeow_recipients WHERE account_id = $1 AND pni_uuid = $2` - upsertACIRecipientQuery = ` + getAllRecipientsWithNameOrPhoneQuery = getAllRecipientsQuery + `AND (contact_name <> '' OR profile_name <> '' OR e164_number <> '')` + getRecipientByACIQuery = getAllRecipientsQuery + `AND aci_uuid = $2` + getRecipientByPNIQuery = getAllRecipientsQuery + `AND pni_uuid = $2` + getRecipientByACIOrPNIQuery = getAllRecipientsQuery + `AND (($2<>'00000000-0000-0000-0000-000000000000' AND aci_uuid = $2) OR ($3<>'00000000-0000-0000-0000-000000000000' AND pni_uuid = $3))` + getRecipientByPhoneQuery = getAllRecipientsQuery + `AND e164_number = $2` + deleteRecipientByPNIQuery = `DELETE FROM signalmeow_recipients WHERE account_id = $1 AND pni_uuid = $2` + upsertACIRecipientQuery = ` INSERT INTO signalmeow_recipients ( account_id, aci_uuid, @@ -278,6 +281,11 @@ func (s *sqlStore) LoadRecipientByE164(ctx context.Context, e164 string) (*types return scanRecipient(s.db.QueryRow(ctx, getRecipientByPhoneQuery, s.AccountID, e164)) } +func (s *sqlStore) LoadAllContacts(ctx context.Context) ([]*types.Recipient, error) { + rows, err := s.db.Query(ctx, getAllRecipientsWithNameOrPhoneQuery, s.AccountID) + return dbutil.NewRowIterWithError(rows, scanRecipient, err).AsList() +} + func (s *sqlStore) DeleteRecipientByPNI(ctx context.Context, pni uuid.UUID) error { _, err := s.db.Exec(ctx, deleteRecipientByPNIQuery, s.AccountID, pni) return err From 32401e37f1d63c14ed8dbbde095c598ab21604f0 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Fri, 21 Jun 2024 20:13:52 +0300 Subject: [PATCH 064/580] v2: update mautrix-go and fix bug in login --- go.mod | 2 +- go.sum | 4 ++-- pkg/connector/client.go | 40 ++++++++++++++++++++++++++++++----- pkg/connector/connector.go | 8 +++++-- pkg/connector/handlematrix.go | 1 + pkg/connector/handlesignal.go | 1 + pkg/connector/login.go | 9 ++++---- 7 files changed, 51 insertions(+), 14 deletions(-) diff --git a/go.mod b/go.mod index c5862b4..d5f40d6 100644 --- a/go.mod +++ b/go.mod @@ -19,7 +19,7 @@ require ( golang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8 golang.org/x/net v0.26.0 google.golang.org/protobuf v1.34.2 - maunium.net/go/mautrix v0.19.0-beta.1.0.20240620142853-7b6f3ba0541d + maunium.net/go/mautrix v0.19.0-beta.1.0.20240621171215-921240d99bf7 nhooyr.io/websocket v1.8.11 ) diff --git a/go.sum b/go.sum index bbb191e..3e03464 100644 --- a/go.sum +++ b/go.sum @@ -93,7 +93,7 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= maunium.net/go/mauflag v1.0.0 h1:YiaRc0tEI3toYtJMRIfjP+jklH45uDHtT80nUamyD4M= maunium.net/go/mauflag v1.0.0/go.mod h1:nLivPOpTpHnpzEh8jEdSL9UqO9+/KBJFmNRlwKfkPeA= -maunium.net/go/mautrix v0.19.0-beta.1.0.20240620142853-7b6f3ba0541d h1:s3wbfQ3jJOlZy0oYE/dVSTxAHDMQHwBlHVLqQZGeQX4= -maunium.net/go/mautrix v0.19.0-beta.1.0.20240620142853-7b6f3ba0541d/go.mod h1:cxv1w6+syudmEpOewHYIQT9yO7TM5UOWmf6xEBVI4H4= +maunium.net/go/mautrix v0.19.0-beta.1.0.20240621171215-921240d99bf7 h1:kdp/zZXtl0vMXa6/Vto34mQ4YhHoj4DHSffr4j101eA= +maunium.net/go/mautrix v0.19.0-beta.1.0.20240621171215-921240d99bf7/go.mod h1:cxv1w6+syudmEpOewHYIQT9yO7TM5UOWmf6xEBVI4H4= nhooyr.io/websocket v1.8.11 h1:f/qXNc2/3DpoSZkHt1DQu6rj4zGC8JmkkLkWss0MgN0= nhooyr.io/websocket v1.8.11/go.mod h1:rN9OFWIUwuxg4fR5tELlYC04bXYowCP9GX47ivo2l+c= diff --git a/pkg/connector/client.go b/pkg/connector/client.go index 20f3d8e..6f1a3ec 100644 --- a/pkg/connector/client.go +++ b/pkg/connector/client.go @@ -19,11 +19,41 @@ type SignalClient struct { Client *signalmeow.Client } -var _ bridgev2.NetworkAPI = (*SignalClient)(nil) -var _ bridgev2.PushableNetworkAPI = (*SignalClient)(nil) -var _ bridgev2.IdentifierResolvingNetworkAPI = (*SignalClient)(nil) -var _ bridgev2.GroupCreatingNetworkAPI = (*SignalClient)(nil) -var _ bridgev2.ContactListingNetworkAPI = (*SignalClient)(nil) +var signalCaps = &bridgev2.NetworkRoomCapabilities{ + FormattedText: true, + UserMentions: true, + LocationMessages: true, + Captions: true, + Replies: true, + Edits: true, + EditMaxCount: 10, + EditMaxAge: 24 * time.Hour, + Deletes: true, + DeleteMaxAge: 24 * time.Hour, + DefaultFileRestriction: &bridgev2.FileRestriction{ + MaxSize: 100 * 1024 * 1024, + }, + ReadReceipts: true, + Reactions: true, + ReactionCount: 1, +} + +func (s *SignalClient) GetCapabilities(ctx context.Context, portal *bridgev2.Portal) *bridgev2.NetworkRoomCapabilities { + return signalCaps +} + +var ( + _ bridgev2.NetworkAPI = (*SignalClient)(nil) + _ bridgev2.EditHandlingNetworkAPI = (*SignalClient)(nil) + _ bridgev2.ReactionHandlingNetworkAPI = (*SignalClient)(nil) + _ bridgev2.RedactionHandlingNetworkAPI = (*SignalClient)(nil) + _ bridgev2.ReadReceiptHandlingNetworkAPI = (*SignalClient)(nil) + _ bridgev2.ReadReceiptHandlingNetworkAPI = (*SignalClient)(nil) + _ bridgev2.TypingHandlingNetworkAPI = (*SignalClient)(nil) + _ bridgev2.IdentifierResolvingNetworkAPI = (*SignalClient)(nil) + _ bridgev2.GroupCreatingNetworkAPI = (*SignalClient)(nil) + _ bridgev2.ContactListingNetworkAPI = (*SignalClient)(nil) +) var pushCfg = &bridgev2.PushConfig{ FCM: &bridgev2.FCMPushConfig{ diff --git a/pkg/connector/connector.go b/pkg/connector/connector.go index fe594dd..2e6d59d 100644 --- a/pkg/connector/connector.go +++ b/pkg/connector/connector.go @@ -80,7 +80,7 @@ func (s *SignalConnector) Init(bridge *bridgev2.Bridge) { return signalfmt.UserInfo{} } userInfo := signalfmt.UserInfo{ - MXID: ghost.MXID, + MXID: ghost.Intent.GetMXID(), Name: ghost.Name, } userLogin := s.Bridge.GetCachedUserLoginByID(networkid.UserLoginID(uuid.String())) @@ -124,7 +124,11 @@ func (s *SignalConnector) SetMaxFileSize(maxSize int64) { } func (s *SignalConnector) Start(ctx context.Context) error { - return s.Store.Upgrade(ctx) + err := s.Store.Upgrade(ctx) + if err != nil { + return bridgev2.DBUpgradeError{Err: err, Section: "signalmeow"} + } + return nil } func (s *SignalConnector) LoadUserLogin(ctx context.Context, login *bridgev2.UserLogin) error { diff --git a/pkg/connector/handlematrix.go b/pkg/connector/handlematrix.go index 839c644..30b10e6 100644 --- a/pkg/connector/handlematrix.go +++ b/pkg/connector/handlematrix.go @@ -122,6 +122,7 @@ func (s *SignalClient) HandleMatrixEdit(ctx context.Context, msg *bridgev2.Matri fmt.Println(res) msg.EditTarget.ID = makeMessageID(s.Client.Store.ACI, converted.GetTimestamp()) msg.EditTarget.Metadata.Extra["contains_attachments"] = len(converted.Attachments) > 0 + msg.EditTarget.Metadata.EditCount++ return nil } diff --git a/pkg/connector/handlesignal.go b/pkg/connector/handlesignal.go index bfbc773..479ce2a 100644 --- a/pkg/connector/handlesignal.go +++ b/pkg/connector/handlesignal.go @@ -273,6 +273,7 @@ func (evt *Bv2ChatEvent) ConvertEdit(ctx context.Context, portal *bridgev2.Porta Content: lastPart.Content, Extra: lastPart.Extra, }) + convertedEdit.ModifiedParts[0].Part.Metadata.EditCount++ return convertedEdit, nil } diff --git a/pkg/connector/login.go b/pkg/connector/login.go index cd0aa1f..4205f67 100644 --- a/pkg/connector/login.go +++ b/pkg/connector/login.go @@ -21,6 +21,7 @@ import ( "fmt" "github.com/google/uuid" + "maunium.net/go/mautrix/bridge/status" "maunium.net/go/mautrix/bridgev2" "maunium.net/go/mautrix/bridgev2/database" @@ -127,13 +128,13 @@ func (qr *QRLogin) Wait(ctx context.Context) (*bridgev2.LoginStep, error) { return nil, ctx.Err() } - ul, err := qr.Main.Bridge.GetUserLoginByID(ctx, newLoginID) + ul, err := qr.Main.Bridge.GetExistingUserLoginByID(ctx, newLoginID) if err != nil { return nil, fmt.Errorf("failed to get existing login: %w", err) } - if ul.UserMXID != qr.User.MXID { - // TODO delete old user login instead of failing new login - return nil, fmt.Errorf("login ID already in use by another user") + if ul != nil && ul.UserMXID != qr.User.MXID { + ul.Delete(ctx, status.BridgeState{StateEvent: status.StateLoggedOut, Error: "overridden-by-another-user"}, false) + ul = nil } if ul == nil { ul, err = qr.User.NewLogin(ctx, &database.UserLogin{ From 98747f267be942598f3d42f294909ae73278d31f Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Mon, 24 Jun 2024 15:34:26 +0300 Subject: [PATCH 065/580] v2: update mautrix-go --- go.mod | 2 +- go.sum | 4 ++-- pkg/connector/connector.go | 8 ++++++++ 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index d5f40d6..b279c4c 100644 --- a/go.mod +++ b/go.mod @@ -19,7 +19,7 @@ require ( golang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8 golang.org/x/net v0.26.0 google.golang.org/protobuf v1.34.2 - maunium.net/go/mautrix v0.19.0-beta.1.0.20240621171215-921240d99bf7 + maunium.net/go/mautrix v0.19.0-beta.1.0.20240624123328-e13b62807ff7 nhooyr.io/websocket v1.8.11 ) diff --git a/go.sum b/go.sum index 3e03464..fea9103 100644 --- a/go.sum +++ b/go.sum @@ -93,7 +93,7 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= maunium.net/go/mauflag v1.0.0 h1:YiaRc0tEI3toYtJMRIfjP+jklH45uDHtT80nUamyD4M= maunium.net/go/mauflag v1.0.0/go.mod h1:nLivPOpTpHnpzEh8jEdSL9UqO9+/KBJFmNRlwKfkPeA= -maunium.net/go/mautrix v0.19.0-beta.1.0.20240621171215-921240d99bf7 h1:kdp/zZXtl0vMXa6/Vto34mQ4YhHoj4DHSffr4j101eA= -maunium.net/go/mautrix v0.19.0-beta.1.0.20240621171215-921240d99bf7/go.mod h1:cxv1w6+syudmEpOewHYIQT9yO7TM5UOWmf6xEBVI4H4= +maunium.net/go/mautrix v0.19.0-beta.1.0.20240624123328-e13b62807ff7 h1:l2nguDM5+Dlud5hdsaUBgyBT7FJ86BknpGmUTI/CemA= +maunium.net/go/mautrix v0.19.0-beta.1.0.20240624123328-e13b62807ff7/go.mod h1:cxv1w6+syudmEpOewHYIQT9yO7TM5UOWmf6xEBVI4H4= nhooyr.io/websocket v1.8.11 h1:f/qXNc2/3DpoSZkHt1DQu6rj4zGC8JmkkLkWss0MgN0= nhooyr.io/websocket v1.8.11/go.mod h1:rN9OFWIUwuxg4fR5tELlYC04bXYowCP9GX47ivo2l+c= diff --git a/pkg/connector/connector.go b/pkg/connector/connector.go index 2e6d59d..fec0f42 100644 --- a/pkg/connector/connector.go +++ b/pkg/connector/connector.go @@ -50,6 +50,14 @@ func NewConnector() *SignalConnector { } } +var signalGeneralCaps = &bridgev2.NetworkGeneralCapabilities{ + DisappearingMessages: true, +} + +func (s *SignalConnector) GetCapabilities() *bridgev2.NetworkGeneralCapabilities { + return signalGeneralCaps +} + func (s *SignalConnector) GetName() bridgev2.BridgeName { return bridgev2.BridgeName{ DisplayName: "Signal", From f4fc21eeb95a4b7e30cdc8cf0976d6a1d79437f0 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Mon, 24 Jun 2024 15:57:25 +0300 Subject: [PATCH 066/580] v2: update ghost info more often --- go.mod | 2 +- go.sum | 4 ++-- pkg/connector/connector.go | 1 + 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index b279c4c..9d0253d 100644 --- a/go.mod +++ b/go.mod @@ -19,7 +19,7 @@ require ( golang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8 golang.org/x/net v0.26.0 google.golang.org/protobuf v1.34.2 - maunium.net/go/mautrix v0.19.0-beta.1.0.20240624123328-e13b62807ff7 + maunium.net/go/mautrix v0.19.0-beta.1.0.20240624125613-855715bbed92 nhooyr.io/websocket v1.8.11 ) diff --git a/go.sum b/go.sum index fea9103..2387052 100644 --- a/go.sum +++ b/go.sum @@ -93,7 +93,7 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= maunium.net/go/mauflag v1.0.0 h1:YiaRc0tEI3toYtJMRIfjP+jklH45uDHtT80nUamyD4M= maunium.net/go/mauflag v1.0.0/go.mod h1:nLivPOpTpHnpzEh8jEdSL9UqO9+/KBJFmNRlwKfkPeA= -maunium.net/go/mautrix v0.19.0-beta.1.0.20240624123328-e13b62807ff7 h1:l2nguDM5+Dlud5hdsaUBgyBT7FJ86BknpGmUTI/CemA= -maunium.net/go/mautrix v0.19.0-beta.1.0.20240624123328-e13b62807ff7/go.mod h1:cxv1w6+syudmEpOewHYIQT9yO7TM5UOWmf6xEBVI4H4= +maunium.net/go/mautrix v0.19.0-beta.1.0.20240624125613-855715bbed92 h1:TcVnSLhftv6pCz+bO9+y5fjHlGewRRUtJw0bIgfr+Ss= +maunium.net/go/mautrix v0.19.0-beta.1.0.20240624125613-855715bbed92/go.mod h1:cxv1w6+syudmEpOewHYIQT9yO7TM5UOWmf6xEBVI4H4= nhooyr.io/websocket v1.8.11 h1:f/qXNc2/3DpoSZkHt1DQu6rj4zGC8JmkkLkWss0MgN0= nhooyr.io/websocket v1.8.11/go.mod h1:rN9OFWIUwuxg4fR5tELlYC04bXYowCP9GX47ivo2l+c= diff --git a/pkg/connector/connector.go b/pkg/connector/connector.go index fec0f42..5fdec0a 100644 --- a/pkg/connector/connector.go +++ b/pkg/connector/connector.go @@ -52,6 +52,7 @@ func NewConnector() *SignalConnector { var signalGeneralCaps = &bridgev2.NetworkGeneralCapabilities{ DisappearingMessages: true, + AggressiveUpdateInfo: true, } func (s *SignalConnector) GetCapabilities() *bridgev2.NetworkGeneralCapabilities { From 25dbeb31904e696d67c07af444e003c1fc272700 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Mon, 24 Jun 2024 20:10:49 +0300 Subject: [PATCH 067/580] v2: update mautrix-go --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 9d0253d..0e08d47 100644 --- a/go.mod +++ b/go.mod @@ -19,7 +19,7 @@ require ( golang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8 golang.org/x/net v0.26.0 google.golang.org/protobuf v1.34.2 - maunium.net/go/mautrix v0.19.0-beta.1.0.20240624125613-855715bbed92 + maunium.net/go/mautrix v0.19.0-beta.1.0.20240624171009-09a8a5104a6c nhooyr.io/websocket v1.8.11 ) diff --git a/go.sum b/go.sum index 2387052..d405943 100644 --- a/go.sum +++ b/go.sum @@ -93,7 +93,7 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= maunium.net/go/mauflag v1.0.0 h1:YiaRc0tEI3toYtJMRIfjP+jklH45uDHtT80nUamyD4M= maunium.net/go/mauflag v1.0.0/go.mod h1:nLivPOpTpHnpzEh8jEdSL9UqO9+/KBJFmNRlwKfkPeA= -maunium.net/go/mautrix v0.19.0-beta.1.0.20240624125613-855715bbed92 h1:TcVnSLhftv6pCz+bO9+y5fjHlGewRRUtJw0bIgfr+Ss= -maunium.net/go/mautrix v0.19.0-beta.1.0.20240624125613-855715bbed92/go.mod h1:cxv1w6+syudmEpOewHYIQT9yO7TM5UOWmf6xEBVI4H4= +maunium.net/go/mautrix v0.19.0-beta.1.0.20240624171009-09a8a5104a6c h1:jm1n2dI2mVDnmrxFgRA1a3MfYdkwBYgKseVKgJHv/a4= +maunium.net/go/mautrix v0.19.0-beta.1.0.20240624171009-09a8a5104a6c/go.mod h1:cxv1w6+syudmEpOewHYIQT9yO7TM5UOWmf6xEBVI4H4= nhooyr.io/websocket v1.8.11 h1:f/qXNc2/3DpoSZkHt1DQu6rj4zGC8JmkkLkWss0MgN0= nhooyr.io/websocket v1.8.11/go.mod h1:rN9OFWIUwuxg4fR5tELlYC04bXYowCP9GX47ivo2l+c= From 760ec87c9bf3010ae236e92265a9d573b163d4df Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Mon, 24 Jun 2024 21:10:14 +0300 Subject: [PATCH 068/580] v2: fix expiration timer unit --- pkg/connector/msgconvproxy.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/connector/msgconvproxy.go b/pkg/connector/msgconvproxy.go index bf1ef3d..8ffeb6f 100644 --- a/pkg/connector/msgconvproxy.go +++ b/pkg/connector/msgconvproxy.go @@ -110,6 +110,6 @@ func (mpm *msgconvPortalMethods) GetData(ctx context.Context) *legacydb.Portal { //Revision: portal.Metadata["revision"].(uint32), Encrypted: true, //RelayUserID: portal.Relay.UserMXID, - ExpirationTime: uint32(portal.Metadata.DisappearTimer.Milliseconds()), + ExpirationTime: uint32(portal.Metadata.DisappearTimer.Seconds()), } } From a74bad426513704cce7581c2b48208e542accfe7 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Tue, 25 Jun 2024 13:45:39 +0300 Subject: [PATCH 069/580] v2: add automatic migration from v1 --- cmd/mautrix-signal-v2/legacymigrate.go | 49 +++++++ cmd/mautrix-signal-v2/legacymigrate.sql | 175 ++++++++++++++++++++++++ cmd/mautrix-signal-v2/main.go | 26 ++-- go.mod | 4 +- go.sum | 8 +- 5 files changed, 248 insertions(+), 14 deletions(-) create mode 100644 cmd/mautrix-signal-v2/legacymigrate.go create mode 100644 cmd/mautrix-signal-v2/legacymigrate.sql diff --git a/cmd/mautrix-signal-v2/legacymigrate.go b/cmd/mautrix-signal-v2/legacymigrate.go new file mode 100644 index 0000000..377b5af --- /dev/null +++ b/cmd/mautrix-signal-v2/legacymigrate.go @@ -0,0 +1,49 @@ +// mautrix-signal - A Matrix-Signal puppeting bridge. +// Copyright (C) 2024 Tulir Asokan +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +package main + +import ( + _ "embed" + + up "go.mau.fi/util/configupgrade" + + "maunium.net/go/mautrix/bridgev2/bridgeconfig" +) + +const legacyMigrateRenameTables = ` +ALTER TABLE portal RENAME TO portal_old; +ALTER TABLE puppet RENAME TO puppet_old; +ALTER TABLE "user" RENAME TO user_old; +ALTER TABLE user_portal RENAME TO user_portal_old; +ALTER TABLE message RENAME TO message_old; +ALTER TABLE reaction RENAME TO reaction_old; +ALTER TABLE disappearing_message RENAME TO disappearing_message_old; +` + +//go:embed legacymigrate.sql +var legacyMigrateCopyData string + +func migrateLegacyConfig(helper up.Helper) { + helper.Set(up.Str, "mautrix.bridge.e2ee", "encryption", "pickle_key") + bridgeconfig.CopyToOtherLocation(helper, up.Str, []string{"bridge", "displayname_template"}, []string{"network", "displayname_template"}) + bridgeconfig.CopyToOtherLocation(helper, up.Str, []string{"bridge", "note_to_self_avatar"}, []string{"network", "note_to_self_avatar"}) + bridgeconfig.CopyToOtherLocation(helper, up.Str, []string{"bridge", "location_format"}, []string{"network", "location_format"}) + bridgeconfig.CopyToOtherLocation(helper, up.Bool, []string{"bridge", "use_contact_avatars"}, []string{"network", "use_contact_avatars"}) + bridgeconfig.CopyToOtherLocation(helper, up.Bool, []string{"bridge", "use_outdated_profiles"}, []string{"network", "use_outdated_profiles"}) + bridgeconfig.CopyToOtherLocation(helper, up.Bool, []string{"bridge", "number_in_topic"}, []string{"network", "number_in_topic"}) + bridgeconfig.CopyToOtherLocation(helper, up.Str, []string{"signal", "device_name"}, []string{"network", "device_name"}) +} diff --git a/cmd/mautrix-signal-v2/legacymigrate.sql b/cmd/mautrix-signal-v2/legacymigrate.sql new file mode 100644 index 0000000..60b08d5 --- /dev/null +++ b/cmd/mautrix-signal-v2/legacymigrate.sql @@ -0,0 +1,175 @@ +INSERT INTO portal ( + bridge_id, id, receiver, mxid, parent_id, parent_receiver, + name, topic, avatar_id, avatar_hash, avatar_mxc, + name_set, avatar_set, topic_set, in_space, metadata +) +SELECT + '', -- bridge_id + chat_id, -- id + CASE + WHEN receiver='00000000-0000-0000-0000-000000000000' THEN '' + ELSE CAST(receiver AS TEXT) + END, -- receiver + mxid, + NULL, -- parent_id + '', -- parent_receiver + name, + topic, + CASE + WHEN avatar_path='notetoself' THEN avatar_url + WHEN avatar_path<>'' THEN ('path:' || avatar_path) + WHEN avatar_hash<>'' THEN ('hash:' || avatar_hash) + ELSE '' + END, -- avatar_id + avatar_hash, -- avatar_hash + avatar_url, -- avatar_mxc + name_set, + avatar_set, + topic_set, + false, -- in_space + CAST( + CASE WHEN expiration_time = 0 + THEN '{}' + ELSE '{"disappear_type": "after_read", "disappear_timer": "' || (expiration_time * 1000000000) || '"}' + END + -- only: postgres + AS jsonb + -- only: sqlite (line commented) +-- AS text + ) -- metadata + -- TODO migrate relay user id +FROM portal_old; + +INSERT INTO ghost ( + bridge_id, id, name, avatar_id, avatar_hash, avatar_mxc, name_set, avatar_set, metadata +) +SELECT + '', -- bridge_id + cast(uuid AS TEXT), -- id + name, + CASE + WHEN avatar_path<>'' THEN ('path:' || avatar_path) + WHEN avatar_hash<>'' THEN ('hash:' || avatar_hash) + ELSE '' + END, -- avatar_id + avatar_hash, -- avatar_hash + avatar_url, -- avatar_mxc + name_set, + avatar_set, + CAST( + CASE + WHEN profile_fetched_at IS NOT NULL THEN ('{"profile_fetched_at":' || profile_fetched_at || '}') + ELSE '{}' + END + -- only: postgres + AS jsonb + -- only: sqlite (line commented) +-- AS text + ) -- metadata +FROM puppet_old; + +INSERT INTO message ( + bridge_id, id, part_id, mxid, room_id, room_receiver, + sender_id, timestamp, relates_to, metadata +) +SELECT + '', -- bridge_id + cast(sender AS TEXT) || '|' || timestamp, -- id + CAST(part_index AS TEXT), -- part_id + mxid, + signal_chat_id, -- room_id + CASE + WHEN signal_receiver='00000000-0000-0000-0000-000000000000' THEN '' + ELSE cast(signal_receiver AS TEXT) + END, -- room_receiver + cast(sender AS TEXT), -- sender_id + timestamp * 1000000, + NULL, -- relates_to + -- only: postgres + '{}'::jsonb -- metadata + -- only: sqlite (line commented +-- '{}' +FROM message_old; + +INSERT INTO disappearing_message ( + bridge_id, mx_room, mxid, type, timer, disappear_at +) +SELECT + '', -- bridge_id + room_id, -- mx_room + mxid, + 'after_read', -- type + expiration_seconds * 1000000000, -- timer + CASE WHEN expiration_ts IS NOT NULL THEN expiration_ts * 1000000000 END -- disappear_at +FROM disappearing_message_old; + +INSERT INTO reaction ( + bridge_id, message_id, message_part_id, sender_id, emoji_id, + room_id, room_receiver, mxid, timestamp, metadata +) +SELECT + '', -- bridge_id + cast(msg_author AS TEXT) || '|' || msg_timestamp, -- message_id + '', -- message_part_id + cast(author AS TEXT), -- sender_id + '', -- emoji_id + signal_chat_id, -- room_id + CASE + WHEN signal_receiver='00000000-0000-0000-0000-000000000000' THEN '' + ELSE cast(signal_receiver AS TEXT) + END, -- room_receiver + mxid, + msg_timestamp * 1000000, -- timestamp (actual reaction timestamp not available) + CAST( + '{"emoji":"' || emoji || '"}' + -- only: postgres + AS jsonb + -- only: sqlite (line commented) +-- AS text + ) -- metadata +FROM reaction_old; + +INSERT INTO "user" (bridge_id, mxid, management_room, access_token) +SELECT '', mxid, management_room, NULL +FROM user_old; + +INSERT INTO user_login (bridge_id, user_mxid, id, space_room, metadata) +SELECT + '', + mxid, + cast(uuid AS TEXT), + space_room, + CAST( + '{"phone":"' || phone || '","remote_name":"' || phone || '"}' + -- only: postgres + AS jsonb + -- only: sqlite (line commented) +-- AS text + ) +FROM user_old WHERE uuid IS NOT NULL AND phone IS NOT NULL; + +INSERT INTO user_portal ( + bridge_id, user_mxid, login_id, portal_id, portal_receiver, in_space, preferred, last_read +) +SELECT + '', -- bridge_id + user_mxid, + cast(user_old.uuid AS TEXT), -- login_id + portal_chat_id, -- portal_id + CASE + WHEN portal_receiver='00000000-0000-0000-0000-000000000000' THEN '' + ELSE cast(portal_receiver AS TEXT) + END, -- portal_receiver + in_space, + false, -- preferred + CASE WHEN last_read_ts = 0 THEN NULL ELSE last_read_ts * 1000000 END -- last_read +FROM user_portal_old +LEFT JOIN user_old ON user_old.mxid = user_portal_old.user_mxid; + +DROP TABLE disappearing_message_old; +DROP TABLE reaction_old; +DROP TABLE user_portal_old; +DROP TABLE message_old; +DROP TABLE puppet_old; +DROP TABLE portal_old; +DROP TABLE user_old; diff --git a/cmd/mautrix-signal-v2/main.go b/cmd/mautrix-signal-v2/main.go index e397e14..bc55d45 100644 --- a/cmd/mautrix-signal-v2/main.go +++ b/cmd/mautrix-signal-v2/main.go @@ -17,6 +17,7 @@ package main import ( + "maunium.net/go/mautrix/bridgev2/bridgeconfig" "maunium.net/go/mautrix/bridgev2/matrix/mxmain" "go.mau.fi/mautrix-signal/pkg/connector" @@ -31,17 +32,26 @@ var ( BuildTime = "unknown" ) -func main() { - m := mxmain.BridgeMain{ - Name: "mautrix-signal", - URL: "https://github.com/mautrix/signal", - Description: "A Matrix-Signal puppeting bridge.", - Version: "0.7.0", +var m = mxmain.BridgeMain{ + Name: "mautrix-signal", + URL: "https://github.com/mautrix/signal", + Description: "A Matrix-Signal puppeting bridge.", + Version: "0.7.0", - Connector: connector.NewConnector(), - } + Connector: connector.NewConnector(), +} + +func main() { + bridgeconfig.HackyMigrateLegacyNetworkConfig = migrateLegacyConfig m.PostInit = func() { signalmeow.SetLogger(m.Log.With().Str("component", "signalmeow").Logger()) + m.CheckLegacyDB( + 20, + "v0.5.1", + "v0.7.0", + m.LegacyMigrateSimple(legacyMigrateRenameTables, legacyMigrateCopyData), + true, + ) } m.InitVersion(Tag, Commit, BuildTime) m.Run() diff --git a/go.mod b/go.mod index 0e08d47..046efb6 100644 --- a/go.mod +++ b/go.mod @@ -14,12 +14,12 @@ require ( github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e github.com/stretchr/testify v1.9.0 github.com/tidwall/gjson v1.17.1 - go.mau.fi/util v0.5.0 + go.mau.fi/util v0.5.1-0.20240625085258-678695edd51c golang.org/x/crypto v0.24.0 golang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8 golang.org/x/net v0.26.0 google.golang.org/protobuf v1.34.2 - maunium.net/go/mautrix v0.19.0-beta.1.0.20240624171009-09a8a5104a6c + maunium.net/go/mautrix v0.19.0-beta.1.0.20240625104456-54ff874fac72 nhooyr.io/websocket v1.8.11 ) diff --git a/go.sum b/go.sum index d405943..3ee63e2 100644 --- a/go.sum +++ b/go.sum @@ -67,8 +67,8 @@ github.com/tidwall/sjson v1.2.5 h1:kLy8mja+1c9jlljvWTlSazM7cKDRfJuR/bOJhcY5NcY= github.com/tidwall/sjson v1.2.5/go.mod h1:Fvgq9kS/6ociJEDnK0Fk1cpYF4FIW6ZF7LAe+6jwd28= github.com/yuin/goldmark v1.7.2 h1:NjGd7lO7zrUn/A7eKwn5PEOt4ONYGqpxSEeZuduvgxc= github.com/yuin/goldmark v1.7.2/go.mod h1:uzxRWxtg69N339t3louHJ7+O03ezfj6PlliRlaOzY1E= -go.mau.fi/util v0.5.0 h1:8yELAl+1CDRrwGe9NUmREgVclSs26Z68pTWePHVxuDo= -go.mau.fi/util v0.5.0/go.mod h1:DsJzUrJAG53lCZnnYvq9/mOyLuPScWwYhvETiTrpdP4= +go.mau.fi/util v0.5.1-0.20240625085258-678695edd51c h1:LAXHOnupWCFvTyx4ZAu5t+6n7zADldeRHIk1s+2luow= +go.mau.fi/util v0.5.1-0.20240625085258-678695edd51c/go.mod h1:DsJzUrJAG53lCZnnYvq9/mOyLuPScWwYhvETiTrpdP4= go.mau.fi/zeroconfig v0.1.2 h1:DKOydWnhPMn65GbXZOafgkPm11BvFashZWLct0dGFto= go.mau.fi/zeroconfig v0.1.2/go.mod h1:NcSJkf180JT+1IId76PcMuLTNa1CzsFFZ0nBygIQM70= golang.org/x/crypto v0.24.0 h1:mnl8DM0o513X8fdIkmyFE/5hTYxbwYOjDS/+rK6qpRI= @@ -93,7 +93,7 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= maunium.net/go/mauflag v1.0.0 h1:YiaRc0tEI3toYtJMRIfjP+jklH45uDHtT80nUamyD4M= maunium.net/go/mauflag v1.0.0/go.mod h1:nLivPOpTpHnpzEh8jEdSL9UqO9+/KBJFmNRlwKfkPeA= -maunium.net/go/mautrix v0.19.0-beta.1.0.20240624171009-09a8a5104a6c h1:jm1n2dI2mVDnmrxFgRA1a3MfYdkwBYgKseVKgJHv/a4= -maunium.net/go/mautrix v0.19.0-beta.1.0.20240624171009-09a8a5104a6c/go.mod h1:cxv1w6+syudmEpOewHYIQT9yO7TM5UOWmf6xEBVI4H4= +maunium.net/go/mautrix v0.19.0-beta.1.0.20240625104456-54ff874fac72 h1:66ojF6y1KlyOyPLj6/XVxoj+ex/LmxFoCiR6SzvEFBI= +maunium.net/go/mautrix v0.19.0-beta.1.0.20240625104456-54ff874fac72/go.mod h1:pFbqAannSyJnohVycF4NW3IngBLWUt/f9KYfJcwyQec= nhooyr.io/websocket v1.8.11 h1:f/qXNc2/3DpoSZkHt1DQu6rj4zGC8JmkkLkWss0MgN0= nhooyr.io/websocket v1.8.11/go.mod h1:rN9OFWIUwuxg4fR5tELlYC04bXYowCP9GX47ivo2l+c= From 0b0379aebf17ddbfd76d50db6fc709f8d0580242 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Tue, 25 Jun 2024 15:04:54 +0300 Subject: [PATCH 070/580] v2: add backwards-compatible resolve identifier provisioning API --- cmd/mautrix-signal-v2/legacyprovision.go | 133 +++++++++++++++++++++ cmd/mautrix-signal-v2/main.go | 12 ++ go.mod | 2 +- go.sum | 4 +- legacyprovision/types.go | 92 ++++++++++++++ pkg/connector/chatinfo.go | 3 +- provisioning.go | 145 ++++++----------------- 7 files changed, 280 insertions(+), 111 deletions(-) create mode 100644 cmd/mautrix-signal-v2/legacyprovision.go create mode 100644 legacyprovision/types.go diff --git a/cmd/mautrix-signal-v2/legacyprovision.go b/cmd/mautrix-signal-v2/legacyprovision.go new file mode 100644 index 0000000..5b8e203 --- /dev/null +++ b/cmd/mautrix-signal-v2/legacyprovision.go @@ -0,0 +1,133 @@ +// mautrix-signal - A Matrix-Signal puppeting bridge. +// Copyright (C) 2024 Tulir Asokan +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is istributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +package main + +import ( + "fmt" + "net/http" + + "github.com/gorilla/mux" + "github.com/rs/zerolog" + + "go.mau.fi/mautrix-signal/legacyprovision" + "maunium.net/go/mautrix" + "maunium.net/go/mautrix/bridgev2" +) + +func legacyProvLinkNew(w http.ResponseWriter, r *http.Request) { + w.WriteHeader(http.StatusNotImplemented) +} + +func legacyProvLinkWaitScan(w http.ResponseWriter, r *http.Request) { + w.WriteHeader(http.StatusNotImplemented) +} + +func legacyProvLinkWaitAccount(w http.ResponseWriter, r *http.Request) { + w.WriteHeader(http.StatusNotImplemented) +} + +func legacyProvLogout(w http.ResponseWriter, r *http.Request) { + user := m.Matrix.Provisioning.GetUser(r) + for { + login := user.GetDefaultLogin() + if login == nil { + break + } + login.Logout(r.Context()) + } + legacyprovision.JSONResponse(w, http.StatusOK, nil) +} + +func legacyResolveIdentifierOrStartChat(w http.ResponseWriter, r *http.Request, create bool) { + login := m.Matrix.Provisioning.GetLoginForRequest(w, r) + if login == nil { + return + } + api := login.Client.(bridgev2.IdentifierResolvingNetworkAPI) + resp, err := api.ResolveIdentifier(r.Context(), mux.Vars(r)["phonenum"], create) + if err != nil { + zerolog.Ctx(r.Context()).Err(err).Msg("Failed to resolve identifier") + legacyprovision.JSONResponse(w, http.StatusInternalServerError, &legacyprovision.Error{ + Error: fmt.Sprintf("Failed to resolve identifier: %v", err), + ErrCode: "M_UNKNOWN", + }) + return + } else if resp == nil { + legacyprovision.JSONResponse(w, http.StatusNotFound, &legacyprovision.Error{ + ErrCode: mautrix.MNotFound.ErrCode, + Error: "User not found on Signal", + }) + return + } + status := http.StatusOK + apiResp := &legacyprovision.ResolveIdentifierResponse{ + ChatID: legacyprovision.ResolveIdentifierResponseChatID{ + UUID: string(resp.UserID), + Number: "", + }, + } + if resp.Ghost != nil { + if resp.UserInfo != nil { + resp.Ghost.UpdateInfo(r.Context(), resp.UserInfo) + } + apiResp.OtherUser = &legacyprovision.ResolveIdentifierResponseOtherUser{ + MXID: resp.Ghost.Intent.GetMXID(), + DisplayName: resp.Ghost.Name, + AvatarURL: resp.Ghost.AvatarMXC.ParseOrIgnore(), + } + } + if resp.Chat != nil { + if resp.Chat.Portal == nil { + resp.Chat.Portal, err = m.Bridge.GetPortalByID(r.Context(), resp.Chat.PortalID) + if err != nil { + zerolog.Ctx(r.Context()).Err(err).Msg("Failed to get portal") + legacyprovision.JSONResponse(w, http.StatusInternalServerError, &mautrix.RespError{ + Err: "Failed to get portal", + ErrCode: "M_UNKNOWN", + }) + return + } + } + if create && resp.Chat.Portal.MXID == "" { + apiResp.JustCreated = true + status = http.StatusCreated + err = resp.Chat.Portal.CreateMatrixRoom(r.Context(), login, resp.Chat.PortalInfo) + if err != nil { + zerolog.Ctx(r.Context()).Err(err).Msg("Failed to create portal room") + legacyprovision.JSONResponse(w, http.StatusInternalServerError, &mautrix.RespError{ + Err: "Failed to create portal room", + ErrCode: "M_UNKNOWN", + }) + return + } + } + apiResp.RoomID = resp.Chat.Portal.MXID + } + legacyprovision.JSONResponse(w, status, &legacyprovision.Response{ + Success: true, + Status: "ok", + ResolveIdentifierResponse: apiResp, + }) +} + +func legacyProvResolveIdentifier(w http.ResponseWriter, r *http.Request) { + legacyResolveIdentifierOrStartChat(w, r, false) +} + +func legacyProvPM(w http.ResponseWriter, r *http.Request) { + legacyResolveIdentifierOrStartChat(w, r, true) +} diff --git a/cmd/mautrix-signal-v2/main.go b/cmd/mautrix-signal-v2/main.go index bc55d45..7c0762c 100644 --- a/cmd/mautrix-signal-v2/main.go +++ b/cmd/mautrix-signal-v2/main.go @@ -17,6 +17,8 @@ package main import ( + "net/http" + "maunium.net/go/mautrix/bridgev2/bridgeconfig" "maunium.net/go/mautrix/bridgev2/matrix/mxmain" @@ -53,6 +55,16 @@ func main() { true, ) } + m.PostStart = func() { + if m.Matrix.Provisioning != nil { + m.Matrix.Provisioning.Router.HandleFunc("/v2/link/new", legacyProvLinkNew).Methods(http.MethodPost) + m.Matrix.Provisioning.Router.HandleFunc("/v2/link/wait/scan", legacyProvLinkWaitScan).Methods(http.MethodPost) + m.Matrix.Provisioning.Router.HandleFunc("/v2/link/wait/account", legacyProvLinkWaitAccount).Methods(http.MethodPost) + m.Matrix.Provisioning.Router.HandleFunc("/v2/logout", legacyProvLogout).Methods(http.MethodPost) + m.Matrix.Provisioning.Router.HandleFunc("/v2/resolve_identifier/{phonenum}", legacyProvResolveIdentifier).Methods(http.MethodGet) + m.Matrix.Provisioning.Router.HandleFunc("/v2/pm/{phonenum}", legacyProvPM).Methods(http.MethodPost) + } + } m.InitVersion(Tag, Commit, BuildTime) m.Run() } diff --git a/go.mod b/go.mod index 046efb6..0f99be4 100644 --- a/go.mod +++ b/go.mod @@ -19,7 +19,7 @@ require ( golang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8 golang.org/x/net v0.26.0 google.golang.org/protobuf v1.34.2 - maunium.net/go/mautrix v0.19.0-beta.1.0.20240625104456-54ff874fac72 + maunium.net/go/mautrix v0.19.0-beta.1.0.20240625120422-13b2d6275302 nhooyr.io/websocket v1.8.11 ) diff --git a/go.sum b/go.sum index 3ee63e2..c6356ce 100644 --- a/go.sum +++ b/go.sum @@ -93,7 +93,7 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= maunium.net/go/mauflag v1.0.0 h1:YiaRc0tEI3toYtJMRIfjP+jklH45uDHtT80nUamyD4M= maunium.net/go/mauflag v1.0.0/go.mod h1:nLivPOpTpHnpzEh8jEdSL9UqO9+/KBJFmNRlwKfkPeA= -maunium.net/go/mautrix v0.19.0-beta.1.0.20240625104456-54ff874fac72 h1:66ojF6y1KlyOyPLj6/XVxoj+ex/LmxFoCiR6SzvEFBI= -maunium.net/go/mautrix v0.19.0-beta.1.0.20240625104456-54ff874fac72/go.mod h1:pFbqAannSyJnohVycF4NW3IngBLWUt/f9KYfJcwyQec= +maunium.net/go/mautrix v0.19.0-beta.1.0.20240625120422-13b2d6275302 h1:PbCdso3xltp5ztKXpAW4C4tC8LLgxeHkJ4mF/7HE3Z0= +maunium.net/go/mautrix v0.19.0-beta.1.0.20240625120422-13b2d6275302/go.mod h1:pFbqAannSyJnohVycF4NW3IngBLWUt/f9KYfJcwyQec= nhooyr.io/websocket v1.8.11 h1:f/qXNc2/3DpoSZkHt1DQu6rj4zGC8JmkkLkWss0MgN0= nhooyr.io/websocket v1.8.11/go.mod h1:rN9OFWIUwuxg4fR5tELlYC04bXYowCP9GX47ivo2l+c= diff --git a/legacyprovision/types.go b/legacyprovision/types.go new file mode 100644 index 0000000..72f393a --- /dev/null +++ b/legacyprovision/types.go @@ -0,0 +1,92 @@ +// mautrix-signal - A Matrix-Signal puppeting bridge. +// Copyright (C) 2024 Tulir Asokan +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is istributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +package legacyprovision + +import ( + "encoding/json" + "net/http" + + "maunium.net/go/mautrix/id" +) + +func JSONResponse(w http.ResponseWriter, status int, response any) { + w.Header().Add("Content-Type", "application/json") + w.WriteHeader(status) + _ = json.NewEncoder(w).Encode(response) +} + +type Error struct { + Success bool `json:"success"` + Error string `json:"error"` + ErrCode string `json:"errcode"` +} + +type Response struct { + Success bool `json:"success"` + Status string `json:"status"` + + // For response in LinkNew + SessionID string `json:"session_id,omitempty"` + URI string `json:"uri,omitempty"` + + // For response in LinkWaitForAccount + UUID string `json:"uuid,omitempty"` + Number string `json:"number,omitempty"` + + // For response in ResolveIdentifier + *ResolveIdentifierResponse +} + +type WhoAmIResponse struct { + Permissions int `json:"permissions"` + MXID string `json:"mxid"` + Signal *WhoAmIResponseSignal `json:"signal,omitempty"` +} + +type WhoAmIResponseSignal struct { + Number string `json:"number"` + UUID string `json:"uuid"` + Name string `json:"name"` + Ok bool `json:"ok"` +} + +type ResolveIdentifierResponse struct { + RoomID id.RoomID `json:"room_id"` + ChatID ResolveIdentifierResponseChatID `json:"chat_id"` + JustCreated bool `json:"just_created"` + OtherUser *ResolveIdentifierResponseOtherUser `json:"other_user,omitempty"` +} + +type ResolveIdentifierResponseChatID struct { + UUID string `json:"uuid"` + Number string `json:"number"` +} + +type ResolveIdentifierResponseOtherUser struct { + MXID id.UserID `json:"mxid"` + DisplayName string `json:"displayname"` + AvatarURL id.ContentURI `json:"avatar_url"` +} + +type LinkWaitForScanRequest struct { + SessionID string `json:"session_id"` +} + +type LinkWaitForAccountRequest struct { + SessionID string `json:"session_id"` + DeviceName string `json:"device_name"` // TODO this seems to not be used anywhere +} diff --git a/pkg/connector/chatinfo.go b/pkg/connector/chatinfo.go index 7c4c646..f0f06f3 100644 --- a/pkg/connector/chatinfo.go +++ b/pkg/connector/chatinfo.go @@ -19,7 +19,6 @@ package connector import ( "context" "crypto/sha256" - "errors" "fmt" "strconv" "strings" @@ -148,7 +147,7 @@ func (s *SignalClient) ResolveIdentifier(ctx context.Context, number string, cre aci = resp[e164Number].ACI pni = resp[e164Number].PNI if aci == uuid.Nil && pni == uuid.Nil { - return nil, errors.New("user not found on Signal") + return nil, nil } recipient, err = s.Client.Store.RecipientStore.UpdateRecipientE164(ctx, aci, pni, e164String) if err != nil { diff --git a/provisioning.go b/provisioning.go index 3be384b..46b52d1 100644 --- a/provisioning.go +++ b/provisioning.go @@ -36,6 +36,7 @@ import ( "maunium.net/go/mautrix" "maunium.net/go/mautrix/id" + "go.mau.fi/mautrix-signal/legacyprovision" "go.mau.fi/mautrix-signal/pkg/libsignalgo" "go.mau.fi/mautrix-signal/pkg/signalmeow" "go.mau.fi/mautrix-signal/pkg/signalmeow/types" @@ -86,18 +87,12 @@ func (prov *ProvisioningAPI) Init() { } } -func jsonResponse(w http.ResponseWriter, status int, response any) { - w.Header().Add("Content-Type", "application/json") - w.WriteHeader(status) - _ = json.NewEncoder(w).Encode(response) -} - func (prov *ProvisioningAPI) AuthMiddleware(h http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { auth := strings.TrimPrefix(r.Header.Get("Authorization"), "Bearer ") if auth != prov.bridge.Config.Bridge.Provisioning.SharedSecret { zerolog.Ctx(r.Context()).Warn().Msg("Authentication token does not match shared secret") - jsonResponse(w, http.StatusForbidden, &mautrix.RespError{ + legacyprovision.JSONResponse(w, http.StatusForbidden, &mautrix.RespError{ Err: "Authentication token does not match shared secret", ErrCode: mautrix.MForbidden.ErrCode, }) @@ -109,60 +104,7 @@ func (prov *ProvisioningAPI) AuthMiddleware(h http.Handler) http.Handler { }) } -type Error struct { - Success bool `json:"success"` - Error string `json:"error"` - ErrCode string `json:"errcode"` -} - -type Response struct { - Success bool `json:"success"` - Status string `json:"status"` - - // For response in LinkNew - SessionID string `json:"session_id,omitempty"` - URI string `json:"uri,omitempty"` - - // For response in LinkWaitForAccount - UUID string `json:"uuid,omitempty"` - Number string `json:"number,omitempty"` - - // For response in ResolveIdentifier - *ResolveIdentifierResponse -} - -type WhoAmIResponse struct { - Permissions int `json:"permissions"` - MXID string `json:"mxid"` - Signal *WhoAmIResponseSignal `json:"signal,omitempty"` -} - -type WhoAmIResponseSignal struct { - Number string `json:"number"` - UUID string `json:"uuid"` - Name string `json:"name"` - Ok bool `json:"ok"` -} - -type ResolveIdentifierResponse struct { - RoomID id.RoomID `json:"room_id"` - ChatID ResolveIdentifierResponseChatID `json:"chat_id"` - JustCreated bool `json:"just_created"` - OtherUser *ResolveIdentifierResponseOtherUser `json:"other_user,omitempty"` -} - -type ResolveIdentifierResponseChatID struct { - UUID string `json:"uuid"` - Number string `json:"number"` -} - -type ResolveIdentifierResponseOtherUser struct { - MXID string `json:"mxid"` - DisplayName string `json:"displayname"` - AvatarURL string `json:"avatar_url"` -} - -func (prov *ProvisioningAPI) resolveIdentifier(ctx context.Context, user *User, inputPhone string) (int, *ResolveIdentifierResponse, error) { +func (prov *ProvisioningAPI) resolveIdentifier(ctx context.Context, user *User, inputPhone string) (int, *legacyprovision.ResolveIdentifierResponse, error) { if user.Client == nil { return http.StatusUnauthorized, nil, errors.New("not currently connected to Signal") } @@ -199,14 +141,14 @@ func (prov *ProvisioningAPI) resolveIdentifier(ctx context.Context, user *User, Msg("Found DM target user") var targetServiceID libsignalgo.ServiceID - var otherUserInfo *ResolveIdentifierResponseOtherUser + var otherUserInfo *legacyprovision.ResolveIdentifierResponseOtherUser if aci != uuid.Nil { targetServiceID = libsignalgo.NewACIServiceID(aci) puppet := prov.bridge.GetPuppetBySignalID(aci) - otherUserInfo = &ResolveIdentifierResponseOtherUser{ - MXID: puppet.MXID.String(), + otherUserInfo = &legacyprovision.ResolveIdentifierResponseOtherUser{ + MXID: puppet.MXID, DisplayName: puppet.Name, - AvatarURL: puppet.AvatarURL.String(), + AvatarURL: puppet.AvatarURL, } } else { targetServiceID = libsignalgo.NewPNIServiceID(pni) @@ -214,9 +156,9 @@ func (prov *ProvisioningAPI) resolveIdentifier(ctx context.Context, user *User, } portal := user.GetPortalByChatID(targetServiceID.String()) - return http.StatusOK, &ResolveIdentifierResponse{ + return http.StatusOK, &legacyprovision.ResolveIdentifierResponse{ RoomID: portal.MXID, - ChatID: ResolveIdentifierResponseChatID{ + ChatID: legacyprovision.ResolveIdentifierResponseChatID{ UUID: targetServiceID.String(), Number: e164String, }, @@ -245,14 +187,14 @@ func (prov *ProvisioningAPI) ResolveIdentifier(w http.ResponseWriter, r *http.Re } else { log.Err(err).Msg("error looking up contact") } - jsonResponse(w, status, Error{ + legacyprovision.JSONResponse(w, status, legacyprovision.Error{ Success: false, Error: err.Error(), ErrCode: errCode, }) return } - jsonResponse(w, status, Response{ + legacyprovision.JSONResponse(w, status, legacyprovision.Response{ Success: true, Status: "ok", ResolveIdentifierResponse: resp, @@ -280,7 +222,7 @@ func (prov *ProvisioningAPI) StartPM(w http.ResponseWriter, r *http.Request) { } else { log.Err(err).Msg("error looking up contact") } - jsonResponse(w, status, Error{ + legacyprovision.JSONResponse(w, status, legacyprovision.Error{ Success: false, Error: err.Error(), ErrCode: errCode, @@ -292,7 +234,7 @@ func (prov *ProvisioningAPI) StartPM(w http.ResponseWriter, r *http.Request) { if portal.MXID == "" { if err := portal.CreateMatrixRoom(r.Context(), user, 0); err != nil { log.Err(err).Msg("error looking up contact") - jsonResponse(w, http.StatusInternalServerError, Error{ + legacyprovision.JSONResponse(w, http.StatusInternalServerError, legacyprovision.Error{ Success: false, Error: "Error creating Matrix room", ErrCode: "M_INTERNAL", @@ -306,7 +248,7 @@ func (prov *ProvisioningAPI) StartPM(w http.ResponseWriter, r *http.Request) { status = http.StatusCreated } - jsonResponse(w, status, Response{ + legacyprovision.JSONResponse(w, status, legacyprovision.Response{ Success: true, Status: "ok", ResolveIdentifierResponse: resp, @@ -401,7 +343,7 @@ func (prov *ProvisioningAPI) checkSessionAndReturnHandle(ctx context.Context, w handle := prov.existingSession(user) if handle == nil { log.Warn().Msg("no session found") - jsonResponse(w, http.StatusNotFound, Error{ + legacyprovision.JSONResponse(w, http.StatusNotFound, legacyprovision.Error{ Success: false, Error: "No session found", ErrCode: "M_NOT_FOUND", @@ -413,7 +355,7 @@ func (prov *ProvisioningAPI) checkSessionAndReturnHandle(ctx context.Context, w Int("handle_id", handle.id). Int("current_session", currentSession). Msg("session_id does not match user's session_id") - jsonResponse(w, http.StatusBadRequest, Error{ + legacyprovision.JSONResponse(w, http.StatusBadRequest, legacyprovision.Error{ Success: false, Error: "session_id does not match user's session_id", ErrCode: "M_BAD_JSON", @@ -431,12 +373,12 @@ func (prov *ProvisioningAPI) WhoAmI(w http.ResponseWriter, r *http.Request) { Logger() log.Debug().Msg("getting whoami") - data := WhoAmIResponse{ + data := legacyprovision.WhoAmIResponse{ Permissions: int(user.PermissionLevel), MXID: user.MXID.String(), } if user.IsLoggedIn() { - data.Signal = &WhoAmIResponseSignal{ + data.Signal = &legacyprovision.WhoAmIResponseSignal{ Number: user.SignalUsername, UUID: user.SignalID.String(), Ok: user.Client.IsConnected(), @@ -446,7 +388,7 @@ func (prov *ProvisioningAPI) WhoAmI(w http.ResponseWriter, r *http.Request) { data.Signal.Name = puppet.Name } } - jsonResponse(w, http.StatusOK, data) + legacyprovision.JSONResponse(w, http.StatusOK, data) } func (prov *ProvisioningAPI) LinkNew(w http.ResponseWriter, r *http.Request) { @@ -460,7 +402,7 @@ func (prov *ProvisioningAPI) LinkNew(w http.ResponseWriter, r *http.Request) { handle, err := prov.loginOrSendError(ctx, w, user) if err != nil { - jsonResponse(w, http.StatusInternalServerError, Error{ + legacyprovision.JSONResponse(w, http.StatusInternalServerError, legacyprovision.Error{ Success: false, Error: err.Error(), ErrCode: "M_INTERNAL", @@ -475,7 +417,7 @@ func (prov *ProvisioningAPI) LinkNew(w http.ResponseWriter, r *http.Request) { case resp := <-handle.channel: if resp.Err != nil || resp.State == signalmeow.StateProvisioningError { log.Err(resp.Err).Msg("Error getting provisioning URL") - jsonResponse(w, http.StatusInternalServerError, Error{ + legacyprovision.JSONResponse(w, http.StatusInternalServerError, legacyprovision.Error{ Success: false, Error: resp.Err.Error(), ErrCode: "M_INTERNAL", @@ -484,7 +426,7 @@ func (prov *ProvisioningAPI) LinkNew(w http.ResponseWriter, r *http.Request) { } if resp.State != signalmeow.StateProvisioningURLReceived { log.Err(resp.Err).Stringer("state", resp.State).Msg("unexpected state") - jsonResponse(w, http.StatusInternalServerError, Error{ + legacyprovision.JSONResponse(w, http.StatusInternalServerError, legacyprovision.Error{ Success: false, Error: fmt.Sprintf("Unexpected state %s", resp.State.String()), ErrCode: "M_INTERNAL", @@ -493,7 +435,7 @@ func (prov *ProvisioningAPI) LinkNew(w http.ResponseWriter, r *http.Request) { } log.Debug().Str("provisioning_url", resp.ProvisioningURL).Msg("provisioning URL received") - jsonResponse(w, http.StatusOK, Response{ + legacyprovision.JSONResponse(w, http.StatusOK, legacyprovision.Response{ Success: true, Status: "provisioning_url_received", SessionID: fmt.Sprintf("%d", handle.id), @@ -501,7 +443,7 @@ func (prov *ProvisioningAPI) LinkNew(w http.ResponseWriter, r *http.Request) { }) case <-time.After(30 * time.Second): log.Warn().Msg("Timeout waiting for provisioning response (new)") - jsonResponse(w, http.StatusGatewayTimeout, Error{ + legacyprovision.JSONResponse(w, http.StatusGatewayTimeout, legacyprovision.Error{ Success: false, Error: "Timeout waiting for provisioning response (new)", ErrCode: "M_TIMEOUT", @@ -509,17 +451,13 @@ func (prov *ProvisioningAPI) LinkNew(w http.ResponseWriter, r *http.Request) { } } -type LinkWaitForScanRequest struct { - SessionID string `json:"session_id"` -} - func (prov *ProvisioningAPI) LinkWaitForScan(w http.ResponseWriter, r *http.Request) { user := r.Context().Value(provisioningUserKey).(*User) - var body LinkWaitForScanRequest + var body legacyprovision.LinkWaitForScanRequest err := json.NewDecoder(r.Body).Decode(&body) if err != nil { - jsonResponse(w, http.StatusBadRequest, Error{ + legacyprovision.JSONResponse(w, http.StatusBadRequest, legacyprovision.Error{ Success: false, Error: "Error decoding JSON body", ErrCode: "M_BAD_JSON", @@ -528,7 +466,7 @@ func (prov *ProvisioningAPI) LinkWaitForScan(w http.ResponseWriter, r *http.Requ } sessionID, err := strconv.Atoi(body.SessionID) if err != nil { - jsonResponse(w, http.StatusBadRequest, Error{ + legacyprovision.JSONResponse(w, http.StatusBadRequest, legacyprovision.Error{ Success: false, Error: "Error decoding session ID in JSON body", ErrCode: "M_BAD_JSON", @@ -561,7 +499,7 @@ func (prov *ProvisioningAPI) LinkWaitForScan(w http.ResponseWriter, r *http.Requ // If we error waiting for the scan, treat it as a normal error not 5xx // so that the client will retry quietly. Also, it's really not an internal // error, sitting with a WS open waiting for a scan is inherently flaky. - jsonResponse(w, http.StatusBadRequest, Error{ + legacyprovision.JSONResponse(w, http.StatusBadRequest, legacyprovision.Error{ Success: false, Error: resp.Err.Error(), ErrCode: "M_INTERNAL", @@ -570,7 +508,7 @@ func (prov *ProvisioningAPI) LinkWaitForScan(w http.ResponseWriter, r *http.Requ } if resp.State != signalmeow.StateProvisioningDataReceived { log.Err(resp.Err).Stringer("state", resp.State).Msg("unexpected state") - jsonResponse(w, http.StatusInternalServerError, Error{ + legacyprovision.JSONResponse(w, http.StatusInternalServerError, legacyprovision.Error{ Success: false, Error: fmt.Sprintf("Unexpected state %s", resp.State.String()), ErrCode: "M_INTERNAL", @@ -578,7 +516,7 @@ func (prov *ProvisioningAPI) LinkWaitForScan(w http.ResponseWriter, r *http.Requ return } log.Debug().Msg("provisioning data received") - jsonResponse(w, http.StatusOK, Response{ + legacyprovision.JSONResponse(w, http.StatusOK, legacyprovision.Response{ Success: true, Status: "provisioning_data_received", }) @@ -591,7 +529,7 @@ func (prov *ProvisioningAPI) LinkWaitForScan(w http.ResponseWriter, r *http.Requ case <-time.After(45 * time.Second): log.Warn().Msg("Timeout waiting for provisioning response (scan)") // Using 400 here to match the old bridge - jsonResponse(w, http.StatusBadRequest, Error{ + legacyprovision.JSONResponse(w, http.StatusBadRequest, legacyprovision.Error{ Success: false, Error: "Timeout waiting for QR code scan", ErrCode: "M_BAD_REQUEST", @@ -600,18 +538,13 @@ func (prov *ProvisioningAPI) LinkWaitForScan(w http.ResponseWriter, r *http.Requ } } -type LinkWaitForAccountRequest struct { - SessionID string `json:"session_id"` - DeviceName string `json:"device_name"` // TODO this seems to not be used anywhere -} - func (prov *ProvisioningAPI) LinkWaitForAccount(w http.ResponseWriter, r *http.Request) { user := r.Context().Value(provisioningUserKey).(*User) - var body LinkWaitForAccountRequest + var body legacyprovision.LinkWaitForAccountRequest err := json.NewDecoder(r.Body).Decode(&body) if err != nil { - jsonResponse(w, http.StatusBadRequest, Error{ + legacyprovision.JSONResponse(w, http.StatusBadRequest, legacyprovision.Error{ Success: false, Error: "Error decoding JSON body", ErrCode: "M_BAD_JSON", @@ -620,7 +553,7 @@ func (prov *ProvisioningAPI) LinkWaitForAccount(w http.ResponseWriter, r *http.R } sessionID, err := strconv.Atoi(body.SessionID) if err != nil { - jsonResponse(w, http.StatusBadRequest, Error{ + legacyprovision.JSONResponse(w, http.StatusBadRequest, legacyprovision.Error{ Success: false, Error: "Error decoding session ID in JSON body", ErrCode: "M_BAD_JSON", @@ -647,7 +580,7 @@ func (prov *ProvisioningAPI) LinkWaitForAccount(w http.ResponseWriter, r *http.R case resp := <-handle.channel: if resp.Err != nil || resp.State == signalmeow.StateProvisioningError { log.Err(resp.Err).Msg("Error waiting for account") - jsonResponse(w, http.StatusInternalServerError, Error{ + legacyprovision.JSONResponse(w, http.StatusInternalServerError, legacyprovision.Error{ Success: false, Error: resp.Err.Error(), ErrCode: "M_INTERNAL", @@ -656,7 +589,7 @@ func (prov *ProvisioningAPI) LinkWaitForAccount(w http.ResponseWriter, r *http.R } if resp.State != signalmeow.StateProvisioningPreKeysRegistered { log.Err(resp.Err).Stringer("state", resp.State).Msg("unexpected state") - jsonResponse(w, http.StatusInternalServerError, Error{ + legacyprovision.JSONResponse(w, http.StatusInternalServerError, legacyprovision.Error{ Success: false, Error: fmt.Sprintf("Unexpected state %s", resp.State.String()), ErrCode: "M_INTERNAL", @@ -665,7 +598,7 @@ func (prov *ProvisioningAPI) LinkWaitForAccount(w http.ResponseWriter, r *http.R } log.Debug().Msg("prekeys registered") - jsonResponse(w, http.StatusOK, Response{ + legacyprovision.JSONResponse(w, http.StatusOK, legacyprovision.Response{ Success: true, Status: "prekeys_registered", UUID: user.SignalID.String(), @@ -677,7 +610,7 @@ func (prov *ProvisioningAPI) LinkWaitForAccount(w http.ResponseWriter, r *http.R return case <-time.After(30 * time.Second): log.Warn().Msg("Timeout waiting for provisioning response (account)") - jsonResponse(w, http.StatusGatewayTimeout, Error{ + legacyprovision.JSONResponse(w, http.StatusGatewayTimeout, legacyprovision.Error{ Success: false, Error: "Timeout waiting for provisioning response (account)", ErrCode: "M_TIMEOUT", @@ -700,7 +633,7 @@ func (prov *ProvisioningAPI) Logout(w http.ResponseWriter, r *http.Request) { // For now do nothing - we need this API to return 200 to be compatible with // the old Signal bridge, which needed a call to Logout before allowing LinkNew // to be called, but we don't actually want to logout, we want to allow a reconnect. - jsonResponse(w, http.StatusOK, Response{ + legacyprovision.JSONResponse(w, http.StatusOK, legacyprovision.Response{ Success: true, Status: "logged_out", }) From 43ee1bb438497e7bfc8dbdeed903d3dc66de5253 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Tue, 25 Jun 2024 16:14:21 +0300 Subject: [PATCH 071/580] signalmeow: don't update e164 if it's empty --- pkg/signalmeow/receiving.go | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/pkg/signalmeow/receiving.go b/pkg/signalmeow/receiving.go index ba29914..96d066a 100644 --- a/pkg/signalmeow/receiving.go +++ b/pkg/signalmeow/receiving.go @@ -475,7 +475,12 @@ func (cli *Client) decryptUnidentifiedSenderEnvelope(ctx context.Context, destin ctx = log.WithContext(ctx) log.Trace().Msg("Received SealedSender message") - cli.Store.RecipientStore.UpdateRecipientE164(ctx, senderUUID, uuid.Nil, senderE164) + if senderE164 != "" { + _, err = cli.Store.RecipientStore.UpdateRecipientE164(ctx, senderUUID, uuid.Nil, senderE164) + if err != nil { + log.Warn().Err(err).Msg("Failed to update sender E164 in recipient store") + } + } switch messageType { case libsignalgo.CiphertextMessageTypeSenderKey: From 0c82b56012f1a0ee1db2f9997fa9411a6ac15c0f Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Tue, 25 Jun 2024 21:28:08 +0300 Subject: [PATCH 072/580] signalmeow: fix edge case in LoadAndUpdateRecipient --- pkg/signalmeow/store/recipient_store.go | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/pkg/signalmeow/store/recipient_store.go b/pkg/signalmeow/store/recipient_store.go index 3463a00..bdcd0c0 100644 --- a/pkg/signalmeow/store/recipient_store.go +++ b/pkg/signalmeow/store/recipient_store.go @@ -244,6 +244,14 @@ func (s *sqlStore) LoadAndUpdateRecipient(ctx context.Context, aci, pni uuid.UUI if err != nil { return fmt.Errorf("failed to run updater function: %w", err) } + // SQL only supports one ON CONFLICT clause, which means StoreRecipient will key on the ACI if it's present. + // If we're adding an ACI to a PNI row, just delete the PNI row first to avoid conflicts on the PNI key. + if outRecipient.PNI != uuid.Nil && outRecipient.ACI == uuid.Nil && aci != uuid.Nil { + err = s.DeleteRecipientByPNI(ctx, outRecipient.PNI) + if err != nil { + return fmt.Errorf("failed to delete old PNI row: %w", err) + } + } if outRecipient.PNI == uuid.Nil && pni != uuid.Nil { outRecipient.PNI = pni changed = true From 7291895376c19b755176fc2f45baffc32909bfae Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Tue, 25 Jun 2024 21:33:37 +0300 Subject: [PATCH 073/580] v2: update mautrix-go to fix state bug after syncing members --- go.mod | 4 ++-- go.sum | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/go.mod b/go.mod index 0f99be4..ac9d0a0 100644 --- a/go.mod +++ b/go.mod @@ -14,12 +14,12 @@ require ( github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e github.com/stretchr/testify v1.9.0 github.com/tidwall/gjson v1.17.1 - go.mau.fi/util v0.5.1-0.20240625085258-678695edd51c + go.mau.fi/util v0.5.1-0.20240625181823-38eefa626984 golang.org/x/crypto v0.24.0 golang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8 golang.org/x/net v0.26.0 google.golang.org/protobuf v1.34.2 - maunium.net/go/mautrix v0.19.0-beta.1.0.20240625120422-13b2d6275302 + maunium.net/go/mautrix v0.19.0-beta.1.0.20240625183146-ae054177794b nhooyr.io/websocket v1.8.11 ) diff --git a/go.sum b/go.sum index c6356ce..49ae2b7 100644 --- a/go.sum +++ b/go.sum @@ -67,8 +67,8 @@ github.com/tidwall/sjson v1.2.5 h1:kLy8mja+1c9jlljvWTlSazM7cKDRfJuR/bOJhcY5NcY= github.com/tidwall/sjson v1.2.5/go.mod h1:Fvgq9kS/6ociJEDnK0Fk1cpYF4FIW6ZF7LAe+6jwd28= github.com/yuin/goldmark v1.7.2 h1:NjGd7lO7zrUn/A7eKwn5PEOt4ONYGqpxSEeZuduvgxc= github.com/yuin/goldmark v1.7.2/go.mod h1:uzxRWxtg69N339t3louHJ7+O03ezfj6PlliRlaOzY1E= -go.mau.fi/util v0.5.1-0.20240625085258-678695edd51c h1:LAXHOnupWCFvTyx4ZAu5t+6n7zADldeRHIk1s+2luow= -go.mau.fi/util v0.5.1-0.20240625085258-678695edd51c/go.mod h1:DsJzUrJAG53lCZnnYvq9/mOyLuPScWwYhvETiTrpdP4= +go.mau.fi/util v0.5.1-0.20240625181823-38eefa626984 h1:63X00R1qL5G+m2LWxdKzAS8cyihFu5IaaOzJ7QHvkzs= +go.mau.fi/util v0.5.1-0.20240625181823-38eefa626984/go.mod h1:DsJzUrJAG53lCZnnYvq9/mOyLuPScWwYhvETiTrpdP4= go.mau.fi/zeroconfig v0.1.2 h1:DKOydWnhPMn65GbXZOafgkPm11BvFashZWLct0dGFto= go.mau.fi/zeroconfig v0.1.2/go.mod h1:NcSJkf180JT+1IId76PcMuLTNa1CzsFFZ0nBygIQM70= golang.org/x/crypto v0.24.0 h1:mnl8DM0o513X8fdIkmyFE/5hTYxbwYOjDS/+rK6qpRI= @@ -93,7 +93,7 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= maunium.net/go/mauflag v1.0.0 h1:YiaRc0tEI3toYtJMRIfjP+jklH45uDHtT80nUamyD4M= maunium.net/go/mauflag v1.0.0/go.mod h1:nLivPOpTpHnpzEh8jEdSL9UqO9+/KBJFmNRlwKfkPeA= -maunium.net/go/mautrix v0.19.0-beta.1.0.20240625120422-13b2d6275302 h1:PbCdso3xltp5ztKXpAW4C4tC8LLgxeHkJ4mF/7HE3Z0= -maunium.net/go/mautrix v0.19.0-beta.1.0.20240625120422-13b2d6275302/go.mod h1:pFbqAannSyJnohVycF4NW3IngBLWUt/f9KYfJcwyQec= +maunium.net/go/mautrix v0.19.0-beta.1.0.20240625183146-ae054177794b h1:mwtsH2BvxwOCn+VG79gsl7f5prD1YcqG06HCZXKcix4= +maunium.net/go/mautrix v0.19.0-beta.1.0.20240625183146-ae054177794b/go.mod h1:pFbqAannSyJnohVycF4NW3IngBLWUt/f9KYfJcwyQec= nhooyr.io/websocket v1.8.11 h1:f/qXNc2/3DpoSZkHt1DQu6rj4zGC8JmkkLkWss0MgN0= nhooyr.io/websocket v1.8.11/go.mod h1:rN9OFWIUwuxg4fR5tELlYC04bXYowCP9GX47ivo2l+c= From 86135c576a67da44cff331bd4a047e7a37d2f6f5 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Tue, 25 Jun 2024 21:47:38 +0300 Subject: [PATCH 074/580] v2: update mautrix-go --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index ac9d0a0..a59527c 100644 --- a/go.mod +++ b/go.mod @@ -19,7 +19,7 @@ require ( golang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8 golang.org/x/net v0.26.0 google.golang.org/protobuf v1.34.2 - maunium.net/go/mautrix v0.19.0-beta.1.0.20240625183146-ae054177794b + maunium.net/go/mautrix v0.19.0-beta.1.0.20240625184543-3f8bb2fd54b1 nhooyr.io/websocket v1.8.11 ) diff --git a/go.sum b/go.sum index 49ae2b7..40f1dee 100644 --- a/go.sum +++ b/go.sum @@ -93,7 +93,7 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= maunium.net/go/mauflag v1.0.0 h1:YiaRc0tEI3toYtJMRIfjP+jklH45uDHtT80nUamyD4M= maunium.net/go/mauflag v1.0.0/go.mod h1:nLivPOpTpHnpzEh8jEdSL9UqO9+/KBJFmNRlwKfkPeA= -maunium.net/go/mautrix v0.19.0-beta.1.0.20240625183146-ae054177794b h1:mwtsH2BvxwOCn+VG79gsl7f5prD1YcqG06HCZXKcix4= -maunium.net/go/mautrix v0.19.0-beta.1.0.20240625183146-ae054177794b/go.mod h1:pFbqAannSyJnohVycF4NW3IngBLWUt/f9KYfJcwyQec= +maunium.net/go/mautrix v0.19.0-beta.1.0.20240625184543-3f8bb2fd54b1 h1:V+PMBFKZwUA0Jy5DrLh1TtDZhnagQMFN9/2/m3T+SLc= +maunium.net/go/mautrix v0.19.0-beta.1.0.20240625184543-3f8bb2fd54b1/go.mod h1:pFbqAannSyJnohVycF4NW3IngBLWUt/f9KYfJcwyQec= nhooyr.io/websocket v1.8.11 h1:f/qXNc2/3DpoSZkHt1DQu6rj4zGC8JmkkLkWss0MgN0= nhooyr.io/websocket v1.8.11/go.mod h1:rN9OFWIUwuxg4fR5tELlYC04bXYowCP9GX47ivo2l+c= From baf113fb03296e641ec951fd97036f2e9a4ec9dc Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Wed, 26 Jun 2024 14:43:43 +0300 Subject: [PATCH 075/580] v2: add backwards-compatible login API --- cmd/mautrix-signal-v2/legacyprovision.go | 153 ++++++++++++++++++++++- cmd/mautrix-signal-v2/main.go | 2 +- go.mod | 2 +- go.sum | 4 +- pkg/connector/login.go | 1 + 5 files changed, 153 insertions(+), 9 deletions(-) diff --git a/cmd/mautrix-signal-v2/legacyprovision.go b/cmd/mautrix-signal-v2/legacyprovision.go index 5b8e203..87140b9 100644 --- a/cmd/mautrix-signal-v2/legacyprovision.go +++ b/cmd/mautrix-signal-v2/legacyprovision.go @@ -17,27 +17,170 @@ package main import ( + "encoding/json" "fmt" "net/http" + "strconv" + "sync" + "sync/atomic" "github.com/gorilla/mux" "github.com/rs/zerolog" - - "go.mau.fi/mautrix-signal/legacyprovision" "maunium.net/go/mautrix" "maunium.net/go/mautrix/bridgev2" + + "go.mau.fi/mautrix-signal/legacyprovision" ) +var legacyProvisionHandleID atomic.Uint32 +var loginSessions = make(map[uint32]*legacyLoginProcess) +var loginSessionsLock sync.Mutex + +type legacyLoginProcess struct { + ID uint32 + Login bridgev2.LoginProcess + User *bridgev2.User + Done *bridgev2.UserLogin +} + +func (llp *legacyLoginProcess) Delete() { + loginSessionsLock.Lock() + delete(loginSessions, llp.ID) + loginSessionsLock.Unlock() +} + func legacyProvLinkNew(w http.ResponseWriter, r *http.Request) { - w.WriteHeader(http.StatusNotImplemented) + handleID := legacyProvisionHandleID.Add(1) + user := m.Matrix.Provisioning.GetUser(r) + defLogin := user.GetDefaultLogin() + if defLogin != nil && defLogin.Client != nil && defLogin.Client.IsLoggedIn() { + legacyprovision.JSONResponse(w, http.StatusConflict, &legacyprovision.Error{ + Error: "Already logged in", + ErrCode: "FI.MAU.ALREADY_LOGGED_IN", + }) + return + } + log := zerolog.Ctx(r.Context()) + login, err := m.Connector.CreateLogin(r.Context(), user, "qr") + if err != nil { + log.Err(err).Msg("Failed to create login") + legacyprovision.JSONResponse(w, http.StatusInternalServerError, &legacyprovision.Error{ + Error: "Internal error starting login", + ErrCode: "M_UNKNOWN", + }) + return + } + firstStep, err := login.Start(r.Context()) + if err != nil { + log.Err(err).Msg("Failed to start login") + legacyprovision.JSONResponse(w, http.StatusInternalServerError, &legacyprovision.Error{ + Error: "Internal error starting login", + ErrCode: "M_UNKNOWN", + }) + return + } else if firstStep.Type != bridgev2.LoginStepTypeDisplayAndWait || firstStep.DisplayAndWaitParams.Type != bridgev2.LoginDisplayTypeQR { + log.Error().Any("first_step", firstStep).Msg("Unexpected first step") + legacyprovision.JSONResponse(w, http.StatusInternalServerError, &legacyprovision.Error{ + Error: "Unexpected first login step", + ErrCode: "M_UNKNOWN", + }) + return + } + loginSessionsLock.Lock() + loginSessions[handleID] = &legacyLoginProcess{ + ID: handleID, + Login: login, + User: user, + } + loginSessionsLock.Unlock() + legacyprovision.JSONResponse(w, http.StatusOK, legacyprovision.Response{ + Success: true, + Status: "provisioning_url_received", + SessionID: strconv.Itoa(int(handleID)), + URI: firstStep.DisplayAndWaitParams.Data, + }) +} + +func getLoginProcess(w http.ResponseWriter, r *http.Request) *legacyLoginProcess { + var body legacyprovision.LinkWaitForAccountRequest + err := json.NewDecoder(r.Body).Decode(&body) + if err != nil { + legacyprovision.JSONResponse(w, http.StatusBadRequest, legacyprovision.Error{ + Success: false, + Error: "Error decoding JSON body", + ErrCode: mautrix.MBadJSON.ErrCode, + }) + return nil + } + sessionID, err := strconv.Atoi(body.SessionID) + if err != nil { + legacyprovision.JSONResponse(w, http.StatusBadRequest, legacyprovision.Error{ + Success: false, + Error: "Error decoding session ID in JSON body", + ErrCode: mautrix.MBadJSON.ErrCode, + }) + return nil + } + process, ok := loginSessions[uint32(sessionID)] + user := m.Matrix.Provisioning.GetUser(r) + if !ok || process.User != user { + legacyprovision.JSONResponse(w, http.StatusNotFound, legacyprovision.Error{ + Success: false, + Error: "No session found", + ErrCode: mautrix.MNotFound.ErrCode, + }) + return nil + } + return process } func legacyProvLinkWaitScan(w http.ResponseWriter, r *http.Request) { - w.WriteHeader(http.StatusNotImplemented) + login := getLoginProcess(w, r) + if login == nil { + return + } + res, err := login.Login.(bridgev2.LoginProcessDisplayAndWait).Wait(r.Context()) + if err != nil { + legacyprovision.JSONResponse(w, http.StatusInternalServerError, legacyprovision.Error{ + Error: "Failed to log in", + ErrCode: "M_UNKNOWN", + }) + login.Delete() + return + } else if res.Type != bridgev2.LoginStepTypeComplete { + legacyprovision.JSONResponse(w, http.StatusInternalServerError, legacyprovision.Error{ + Error: "Unexpected login step", + ErrCode: "M_UNKNOWN", + }) + login.Delete() + return + } + login.Done = res.CompleteParams.UserLogin + legacyprovision.JSONResponse(w, http.StatusOK, legacyprovision.Response{ + Success: true, + Status: "provisioning_data_received", + }) } func legacyProvLinkWaitAccount(w http.ResponseWriter, r *http.Request) { - w.WriteHeader(http.StatusNotImplemented) + login := getLoginProcess(w, r) + if login == nil { + return + } + if login.Done != nil { + legacyprovision.JSONResponse(w, http.StatusOK, legacyprovision.Response{ + Success: true, + Status: "prekeys_registered", + UUID: string(login.Done.ID), + Number: login.Done.Metadata.RemoteName, + }) + login.Delete() + } else { + legacyprovision.JSONResponse(w, http.StatusInternalServerError, legacyprovision.Error{ + Error: "Login not completed", + ErrCode: "M_UNKNOWN", + }) + } } func legacyProvLogout(w http.ResponseWriter, r *http.Request) { diff --git a/cmd/mautrix-signal-v2/main.go b/cmd/mautrix-signal-v2/main.go index 7c0762c..0e85c38 100644 --- a/cmd/mautrix-signal-v2/main.go +++ b/cmd/mautrix-signal-v2/main.go @@ -51,7 +51,7 @@ func main() { 20, "v0.5.1", "v0.7.0", - m.LegacyMigrateSimple(legacyMigrateRenameTables, legacyMigrateCopyData), + m.LegacyMigrateSimple(legacyMigrateRenameTables, legacyMigrateCopyData, 2), true, ) } diff --git a/go.mod b/go.mod index a59527c..1462e0b 100644 --- a/go.mod +++ b/go.mod @@ -19,7 +19,7 @@ require ( golang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8 golang.org/x/net v0.26.0 google.golang.org/protobuf v1.34.2 - maunium.net/go/mautrix v0.19.0-beta.1.0.20240625184543-3f8bb2fd54b1 + maunium.net/go/mautrix v0.19.0-beta.1.0.20240626114248-5dbfd7093e58 nhooyr.io/websocket v1.8.11 ) diff --git a/go.sum b/go.sum index 40f1dee..be925ba 100644 --- a/go.sum +++ b/go.sum @@ -93,7 +93,7 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= maunium.net/go/mauflag v1.0.0 h1:YiaRc0tEI3toYtJMRIfjP+jklH45uDHtT80nUamyD4M= maunium.net/go/mauflag v1.0.0/go.mod h1:nLivPOpTpHnpzEh8jEdSL9UqO9+/KBJFmNRlwKfkPeA= -maunium.net/go/mautrix v0.19.0-beta.1.0.20240625184543-3f8bb2fd54b1 h1:V+PMBFKZwUA0Jy5DrLh1TtDZhnagQMFN9/2/m3T+SLc= -maunium.net/go/mautrix v0.19.0-beta.1.0.20240625184543-3f8bb2fd54b1/go.mod h1:pFbqAannSyJnohVycF4NW3IngBLWUt/f9KYfJcwyQec= +maunium.net/go/mautrix v0.19.0-beta.1.0.20240626114248-5dbfd7093e58 h1:N2Mll8zmQPEFhLgJdH/QPw9Wu4nnLD1LIrAyk0vohHo= +maunium.net/go/mautrix v0.19.0-beta.1.0.20240626114248-5dbfd7093e58/go.mod h1:pFbqAannSyJnohVycF4NW3IngBLWUt/f9KYfJcwyQec= nhooyr.io/websocket v1.8.11 h1:f/qXNc2/3DpoSZkHt1DQu6rj4zGC8JmkkLkWss0MgN0= nhooyr.io/websocket v1.8.11/go.mod h1:rN9OFWIUwuxg4fR5tELlYC04bXYowCP9GX47ivo2l+c= diff --git a/pkg/connector/login.go b/pkg/connector/login.go index 4205f67..824f8f1 100644 --- a/pkg/connector/login.go +++ b/pkg/connector/login.go @@ -174,6 +174,7 @@ func (qr *QRLogin) Wait(ctx context.Context) (*bridgev2.LoginStep, error) { Instructions: fmt.Sprintf("Successfully logged in as %s / %s", signalPhone, signalID), CompleteParams: &bridgev2.LoginCompleteParams{ UserLoginID: ul.ID, + UserLogin: ul, }, }, nil } From 4352712426a4352bc2f8aa347e79206a462fe231 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Wed, 26 Jun 2024 17:15:05 +0300 Subject: [PATCH 076/580] v2: remove -v2 suffix in binary name inside docker image --- Dockerfile.v2.ci | 2 +- docker-run.sh | 3 --- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/Dockerfile.v2.ci b/Dockerfile.v2.ci index d5868a7..0ff0c8c 100644 --- a/Dockerfile.v2.ci +++ b/Dockerfile.v2.ci @@ -6,7 +6,7 @@ ENV UID=1337 \ RUN apk add --no-cache ffmpeg su-exec ca-certificates bash jq curl yq-go ARG EXECUTABLE=./mautrix-signal-v2 -COPY $EXECUTABLE /usr/bin/mautrix-signal-v2 +COPY $EXECUTABLE /usr/bin/mautrix-signal COPY ./docker-run.sh /docker-run.sh ENV BRIDGEV2=1 VOLUME /data diff --git a/docker-run.sh b/docker-run.sh index 6d6f3a7..bcc6bc4 100755 --- a/docker-run.sh +++ b/docker-run.sh @@ -5,9 +5,6 @@ if [[ -z "$GID" ]]; then fi BINARY_NAME=/usr/bin/mautrix-signal -if [[ "$BRIDGEV2" == "1" ]]; then - BINARY_NAME=/usr/bin/mautrix-signal-v2 -fi # Define functions. function fixperms { From 72e9cc6c11ff8e0e52aae68a5e1d44702e7d9971 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Wed, 26 Jun 2024 20:09:00 +0300 Subject: [PATCH 077/580] v2: add extra wait step to login --- cmd/mautrix-signal-v2/legacyprovision.go | 35 +++++++++------ go.mod | 2 +- go.sum | 4 +- pkg/connector/login.go | 55 ++++++++++++++++++------ 4 files changed, 67 insertions(+), 29 deletions(-) diff --git a/cmd/mautrix-signal-v2/legacyprovision.go b/cmd/mautrix-signal-v2/legacyprovision.go index 87140b9..007cf33 100644 --- a/cmd/mautrix-signal-v2/legacyprovision.go +++ b/cmd/mautrix-signal-v2/legacyprovision.go @@ -30,6 +30,7 @@ import ( "maunium.net/go/mautrix/bridgev2" "go.mau.fi/mautrix-signal/legacyprovision" + "go.mau.fi/mautrix-signal/pkg/connector" ) var legacyProvisionHandleID atomic.Uint32 @@ -40,7 +41,6 @@ type legacyLoginProcess struct { ID uint32 Login bridgev2.LoginProcess User *bridgev2.User - Done *bridgev2.UserLogin } func (llp *legacyLoginProcess) Delete() { @@ -78,7 +78,7 @@ func legacyProvLinkNew(w http.ResponseWriter, r *http.Request) { ErrCode: "M_UNKNOWN", }) return - } else if firstStep.Type != bridgev2.LoginStepTypeDisplayAndWait || firstStep.DisplayAndWaitParams.Type != bridgev2.LoginDisplayTypeQR { + } else if firstStep.StepID != connector.LoginStepQR || firstStep.Type != bridgev2.LoginStepTypeDisplayAndWait || firstStep.DisplayAndWaitParams.Type != bridgev2.LoginDisplayTypeQR { log.Error().Any("first_step", firstStep).Msg("Unexpected first step") legacyprovision.JSONResponse(w, http.StatusInternalServerError, &legacyprovision.Error{ Error: "Unexpected first login step", @@ -141,13 +141,15 @@ func legacyProvLinkWaitScan(w http.ResponseWriter, r *http.Request) { } res, err := login.Login.(bridgev2.LoginProcessDisplayAndWait).Wait(r.Context()) if err != nil { + zerolog.Ctx(r.Context()).Err(err).Msg("Failed to log in") legacyprovision.JSONResponse(w, http.StatusInternalServerError, legacyprovision.Error{ Error: "Failed to log in", ErrCode: "M_UNKNOWN", }) login.Delete() return - } else if res.Type != bridgev2.LoginStepTypeComplete { + } else if res.StepID != connector.LoginStepProcess { + zerolog.Ctx(r.Context()).Error().Any("first_step", res).Msg("Unexpected login step") legacyprovision.JSONResponse(w, http.StatusInternalServerError, legacyprovision.Error{ Error: "Unexpected login step", ErrCode: "M_UNKNOWN", @@ -155,7 +157,6 @@ func legacyProvLinkWaitScan(w http.ResponseWriter, r *http.Request) { login.Delete() return } - login.Done = res.CompleteParams.UserLogin legacyprovision.JSONResponse(w, http.StatusOK, legacyprovision.Response{ Success: true, Status: "provisioning_data_received", @@ -167,20 +168,28 @@ func legacyProvLinkWaitAccount(w http.ResponseWriter, r *http.Request) { if login == nil { return } - if login.Done != nil { + res, err := login.Login.(bridgev2.LoginProcessDisplayAndWait).Wait(r.Context()) + if err != nil { + zerolog.Ctx(r.Context()).Err(err).Msg("Failed to log in") + legacyprovision.JSONResponse(w, http.StatusInternalServerError, legacyprovision.Error{ + Error: "Failed to log in", + ErrCode: "M_UNKNOWN", + }) + } else if res.StepID != connector.LoginStepComplete || res.Type != bridgev2.LoginStepTypeComplete { + zerolog.Ctx(r.Context()).Error().Any("first_step", res).Msg("Unexpected login step") + legacyprovision.JSONResponse(w, http.StatusInternalServerError, legacyprovision.Error{ + Error: "Unexpected login step", + ErrCode: "M_UNKNOWN", + }) + } else { legacyprovision.JSONResponse(w, http.StatusOK, legacyprovision.Response{ Success: true, Status: "prekeys_registered", - UUID: string(login.Done.ID), - Number: login.Done.Metadata.RemoteName, - }) - login.Delete() - } else { - legacyprovision.JSONResponse(w, http.StatusInternalServerError, legacyprovision.Error{ - Error: "Login not completed", - ErrCode: "M_UNKNOWN", + UUID: string(res.CompleteParams.UserLogin.ID), + Number: res.CompleteParams.UserLogin.Metadata.RemoteName, }) } + login.Delete() } func legacyProvLogout(w http.ResponseWriter, r *http.Request) { diff --git a/go.mod b/go.mod index 1462e0b..af271eb 100644 --- a/go.mod +++ b/go.mod @@ -19,7 +19,7 @@ require ( golang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8 golang.org/x/net v0.26.0 google.golang.org/protobuf v1.34.2 - maunium.net/go/mautrix v0.19.0-beta.1.0.20240626114248-5dbfd7093e58 + maunium.net/go/mautrix v0.19.0-beta.1.0.20240626170142-1a18d9ee55f1 nhooyr.io/websocket v1.8.11 ) diff --git a/go.sum b/go.sum index be925ba..43b7309 100644 --- a/go.sum +++ b/go.sum @@ -93,7 +93,7 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= maunium.net/go/mauflag v1.0.0 h1:YiaRc0tEI3toYtJMRIfjP+jklH45uDHtT80nUamyD4M= maunium.net/go/mauflag v1.0.0/go.mod h1:nLivPOpTpHnpzEh8jEdSL9UqO9+/KBJFmNRlwKfkPeA= -maunium.net/go/mautrix v0.19.0-beta.1.0.20240626114248-5dbfd7093e58 h1:N2Mll8zmQPEFhLgJdH/QPw9Wu4nnLD1LIrAyk0vohHo= -maunium.net/go/mautrix v0.19.0-beta.1.0.20240626114248-5dbfd7093e58/go.mod h1:pFbqAannSyJnohVycF4NW3IngBLWUt/f9KYfJcwyQec= +maunium.net/go/mautrix v0.19.0-beta.1.0.20240626170142-1a18d9ee55f1 h1:iE/MzeUGHAs2pbtq/hVnJp7pFQhgjRnZZFfnFDwZdq0= +maunium.net/go/mautrix v0.19.0-beta.1.0.20240626170142-1a18d9ee55f1/go.mod h1:pFbqAannSyJnohVycF4NW3IngBLWUt/f9KYfJcwyQec= nhooyr.io/websocket v1.8.11 h1:f/qXNc2/3DpoSZkHt1DQu6rj4zGC8JmkkLkWss0MgN0= nhooyr.io/websocket v1.8.11/go.mod h1:rN9OFWIUwuxg4fR5tELlYC04bXYowCP9GX47ivo2l+c= diff --git a/pkg/connector/login.go b/pkg/connector/login.go index 824f8f1..24cbcd7 100644 --- a/pkg/connector/login.go +++ b/pkg/connector/login.go @@ -26,6 +26,7 @@ import ( "maunium.net/go/mautrix/bridgev2/database" "go.mau.fi/mautrix-signal/pkg/signalmeow" + "go.mau.fi/mautrix-signal/pkg/signalmeow/store" ) func (s *SignalConnector) GetLoginFlows() []bridgev2.LoginFlow { @@ -48,6 +49,8 @@ type QRLogin struct { Main *SignalConnector cancelChan context.CancelFunc ProvChan chan signalmeow.ProvisioningResponse + + ProvData *store.DeviceData } var _ bridgev2.LoginProcessDisplayAndWait = (*QRLogin)(nil) @@ -60,6 +63,12 @@ func (qr *QRLogin) Cancel() { }() } +const ( + LoginStepQR = "fi.mau.signal.login.qr" + LoginStepProcess = "fi.mau.signal.login.processing" + LoginStepComplete = "fi.mau.signal.login.complete" +) + func (qr *QRLogin) Start(ctx context.Context) (*bridgev2.LoginStep, error) { log := qr.Main.Bridge.Log.With(). Str("action", "login"). @@ -84,7 +93,7 @@ func (qr *QRLogin) Start(ctx context.Context) (*bridgev2.LoginStep, error) { } return &bridgev2.LoginStep{ Type: bridgev2.LoginStepTypeDisplayAndWait, - StepID: "fi.mau.signal.login.qr", + StepID: LoginStepQR, Instructions: "Scan the QR code on your Signal app to log in", DisplayAndWaitParams: &bridgev2.LoginDisplayAndWaitParams{ Type: bridgev2.LoginDisplayTypeQR, @@ -97,25 +106,45 @@ func (qr *QRLogin) Wait(ctx context.Context) (*bridgev2.LoginStep, error) { if qr.ProvChan == nil { return nil, fmt.Errorf("login not started") } - defer qr.cancelChan() - var signalID uuid.UUID - var signalPhone string + if qr.ProvData == nil { + return qr.qrWait(ctx) + } else { + return qr.processingWait(ctx) + } +} + +func (qr *QRLogin) qrWait(ctx context.Context) (*bridgev2.LoginStep, error) { select { case resp := <-qr.ProvChan: if resp.Err != nil || resp.State == signalmeow.StateProvisioningError { + qr.cancelChan() return nil, resp.Err } else if resp.State != signalmeow.StateProvisioningDataReceived { + qr.cancelChan() return nil, fmt.Errorf("unexpected state %v", resp.State) } else if resp.ProvisioningData.ACI == uuid.Nil { + qr.cancelChan() return nil, fmt.Errorf("no signal account ID received") } - signalID = resp.ProvisioningData.ACI - signalPhone = resp.ProvisioningData.Number + qr.ProvData = resp.ProvisioningData + return &bridgev2.LoginStep{ + Type: bridgev2.LoginStepTypeDisplayAndWait, + StepID: LoginStepProcess, + Instructions: fmt.Sprintf("Processing login as %s...", resp.ProvisioningData.Number), + DisplayAndWaitParams: &bridgev2.LoginDisplayAndWaitParams{ + Type: bridgev2.LoginDisplayTypeNothing, + }, + }, nil case <-ctx.Done(): + qr.cancelChan() return nil, ctx.Err() } - newLoginID := makeUserLoginID(signalID) +} + +func (qr *QRLogin) processingWait(ctx context.Context) (*bridgev2.LoginStep, error) { + defer qr.cancelChan() + newLoginID := makeUserLoginID(qr.ProvData.ACI) select { case resp := <-qr.ProvChan: @@ -141,10 +170,10 @@ func (qr *QRLogin) Wait(ctx context.Context) (*bridgev2.LoginStep, error) { ID: newLoginID, Metadata: database.UserLoginMetadata{ StandardUserLoginMetadata: database.StandardUserLoginMetadata{ - RemoteName: signalPhone, + RemoteName: qr.ProvData.Number, }, Extra: map[string]any{ - "phone": signalPhone, + "phone": qr.ProvData.Number, }, }, }, nil) @@ -152,8 +181,8 @@ func (qr *QRLogin) Wait(ctx context.Context) (*bridgev2.LoginStep, error) { return nil, fmt.Errorf("failed to save new login: %w", err) } } else { - ul.Metadata.Extra["phone"] = signalPhone - ul.Metadata.RemoteName = signalPhone + ul.Metadata.Extra["phone"] = qr.ProvData.Number + ul.Metadata.RemoteName = qr.ProvData.Number err = ul.Save(ctx) if err != nil { return nil, fmt.Errorf("failed to update existing login: %w", err) @@ -170,8 +199,8 @@ func (qr *QRLogin) Wait(ctx context.Context) (*bridgev2.LoginStep, error) { } return &bridgev2.LoginStep{ Type: bridgev2.LoginStepTypeComplete, - StepID: "fi.mau.signal.login.complete", - Instructions: fmt.Sprintf("Successfully logged in as %s / %s", signalPhone, signalID), + StepID: LoginStepComplete, + Instructions: fmt.Sprintf("Successfully logged in as %s / %s", qr.ProvData.Number, qr.ProvData.ACI), CompleteParams: &bridgev2.LoginCompleteParams{ UserLoginID: ul.ID, UserLogin: ul, From d50bc09788a0793d84e62d9db11abf6849cb38a0 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Wed, 26 Jun 2024 21:00:58 +0300 Subject: [PATCH 078/580] v2: make legacy provisioning logout a no-op --- cmd/mautrix-signal-v2/legacyprovision.go | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/cmd/mautrix-signal-v2/legacyprovision.go b/cmd/mautrix-signal-v2/legacyprovision.go index 007cf33..0eef485 100644 --- a/cmd/mautrix-signal-v2/legacyprovision.go +++ b/cmd/mautrix-signal-v2/legacyprovision.go @@ -193,14 +193,7 @@ func legacyProvLinkWaitAccount(w http.ResponseWriter, r *http.Request) { } func legacyProvLogout(w http.ResponseWriter, r *http.Request) { - user := m.Matrix.Provisioning.GetUser(r) - for { - login := user.GetDefaultLogin() - if login == nil { - break - } - login.Logout(r.Context()) - } + // No-op for backwards compatibility legacyprovision.JSONResponse(w, http.StatusOK, nil) } From 80e59d62bf4a70826d29348e5eb1d7d58967ca20 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Wed, 26 Jun 2024 21:15:32 +0300 Subject: [PATCH 079/580] v2: fix typo in legacymigrate.sql --- cmd/mautrix-signal-v2/legacymigrate.sql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/mautrix-signal-v2/legacymigrate.sql b/cmd/mautrix-signal-v2/legacymigrate.sql index 60b08d5..32f7aa0 100644 --- a/cmd/mautrix-signal-v2/legacymigrate.sql +++ b/cmd/mautrix-signal-v2/legacymigrate.sql @@ -87,7 +87,7 @@ SELECT NULL, -- relates_to -- only: postgres '{}'::jsonb -- metadata - -- only: sqlite (line commented + -- only: sqlite (line commented) -- '{}' FROM message_old; From 29d248b125a84b4d0ffb88b1ac9a05219c764bc2 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Wed, 26 Jun 2024 21:32:05 +0300 Subject: [PATCH 080/580] v2: fix more legacymigrate.sql issues --- cmd/mautrix-signal-v2/legacymigrate.sql | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/cmd/mautrix-signal-v2/legacymigrate.sql b/cmd/mautrix-signal-v2/legacymigrate.sql index 32f7aa0..ba91f9c 100644 --- a/cmd/mautrix-signal-v2/legacymigrate.sql +++ b/cmd/mautrix-signal-v2/legacymigrate.sql @@ -75,7 +75,7 @@ INSERT INTO message ( SELECT '', -- bridge_id cast(sender AS TEXT) || '|' || timestamp, -- id - CAST(part_index AS TEXT), -- part_id + CASE WHEN part_index=0 THEN '' ELSE CAST(part_index AS TEXT) END, -- part_id mxid, signal_chat_id, -- room_id CASE @@ -85,10 +85,7 @@ SELECT cast(sender AS TEXT), -- sender_id timestamp * 1000000, NULL, -- relates_to - -- only: postgres - '{}'::jsonb -- metadata - -- only: sqlite (line commented) --- '{}' + '{}' -- metadata FROM message_old; INSERT INTO disappearing_message ( From 4e5db9026c4984f25910a7d20b1ab62ec629b8f9 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Wed, 26 Jun 2024 21:45:32 +0300 Subject: [PATCH 081/580] v2: update mautrix-go to maybe fix migration on SQLite --- go.mod | 4 ++-- go.sum | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/go.mod b/go.mod index af271eb..9f3eef2 100644 --- a/go.mod +++ b/go.mod @@ -14,12 +14,12 @@ require ( github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e github.com/stretchr/testify v1.9.0 github.com/tidwall/gjson v1.17.1 - go.mau.fi/util v0.5.1-0.20240625181823-38eefa626984 + go.mau.fi/util v0.5.1-0.20240626184357-b3f4d78c25cf golang.org/x/crypto v0.24.0 golang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8 golang.org/x/net v0.26.0 google.golang.org/protobuf v1.34.2 - maunium.net/go/mautrix v0.19.0-beta.1.0.20240626170142-1a18d9ee55f1 + maunium.net/go/mautrix v0.19.0-beta.1.0.20240626184459-c9314c6a63f8 nhooyr.io/websocket v1.8.11 ) diff --git a/go.sum b/go.sum index 43b7309..a2117b9 100644 --- a/go.sum +++ b/go.sum @@ -67,8 +67,8 @@ github.com/tidwall/sjson v1.2.5 h1:kLy8mja+1c9jlljvWTlSazM7cKDRfJuR/bOJhcY5NcY= github.com/tidwall/sjson v1.2.5/go.mod h1:Fvgq9kS/6ociJEDnK0Fk1cpYF4FIW6ZF7LAe+6jwd28= github.com/yuin/goldmark v1.7.2 h1:NjGd7lO7zrUn/A7eKwn5PEOt4ONYGqpxSEeZuduvgxc= github.com/yuin/goldmark v1.7.2/go.mod h1:uzxRWxtg69N339t3louHJ7+O03ezfj6PlliRlaOzY1E= -go.mau.fi/util v0.5.1-0.20240625181823-38eefa626984 h1:63X00R1qL5G+m2LWxdKzAS8cyihFu5IaaOzJ7QHvkzs= -go.mau.fi/util v0.5.1-0.20240625181823-38eefa626984/go.mod h1:DsJzUrJAG53lCZnnYvq9/mOyLuPScWwYhvETiTrpdP4= +go.mau.fi/util v0.5.1-0.20240626184357-b3f4d78c25cf h1:ceXQTB6IqjqGBGhzOTEBGbxQu7xDyuT9YR06gxr9Ncw= +go.mau.fi/util v0.5.1-0.20240626184357-b3f4d78c25cf/go.mod h1:DsJzUrJAG53lCZnnYvq9/mOyLuPScWwYhvETiTrpdP4= go.mau.fi/zeroconfig v0.1.2 h1:DKOydWnhPMn65GbXZOafgkPm11BvFashZWLct0dGFto= go.mau.fi/zeroconfig v0.1.2/go.mod h1:NcSJkf180JT+1IId76PcMuLTNa1CzsFFZ0nBygIQM70= golang.org/x/crypto v0.24.0 h1:mnl8DM0o513X8fdIkmyFE/5hTYxbwYOjDS/+rK6qpRI= @@ -93,7 +93,7 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= maunium.net/go/mauflag v1.0.0 h1:YiaRc0tEI3toYtJMRIfjP+jklH45uDHtT80nUamyD4M= maunium.net/go/mauflag v1.0.0/go.mod h1:nLivPOpTpHnpzEh8jEdSL9UqO9+/KBJFmNRlwKfkPeA= -maunium.net/go/mautrix v0.19.0-beta.1.0.20240626170142-1a18d9ee55f1 h1:iE/MzeUGHAs2pbtq/hVnJp7pFQhgjRnZZFfnFDwZdq0= -maunium.net/go/mautrix v0.19.0-beta.1.0.20240626170142-1a18d9ee55f1/go.mod h1:pFbqAannSyJnohVycF4NW3IngBLWUt/f9KYfJcwyQec= +maunium.net/go/mautrix v0.19.0-beta.1.0.20240626184459-c9314c6a63f8 h1:zxjQQrIOXw5MyE82I2SmWsgAFgh9lB8Ijjdilld59/U= +maunium.net/go/mautrix v0.19.0-beta.1.0.20240626184459-c9314c6a63f8/go.mod h1:eu/C1dTewrW7yiFNiCKGm4zuWJANyt7zPjaY5g3f3r4= nhooyr.io/websocket v1.8.11 h1:f/qXNc2/3DpoSZkHt1DQu6rj4zGC8JmkkLkWss0MgN0= nhooyr.io/websocket v1.8.11/go.mod h1:rN9OFWIUwuxg4fR5tELlYC04bXYowCP9GX47ivo2l+c= From be21dac6cf66b53a7d7ed717cc8c28a51cbc544b Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Thu, 27 Jun 2024 11:34:48 +0300 Subject: [PATCH 082/580] v2: improve handling of logins in bad credentials --- go.mod | 2 +- go.sum | 4 ++-- pkg/connector/client.go | 19 +++++++++++++++++++ pkg/connector/connector.go | 12 ++++++------ 4 files changed, 28 insertions(+), 9 deletions(-) diff --git a/go.mod b/go.mod index 9f3eef2..19843dc 100644 --- a/go.mod +++ b/go.mod @@ -19,7 +19,7 @@ require ( golang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8 golang.org/x/net v0.26.0 google.golang.org/protobuf v1.34.2 - maunium.net/go/mautrix v0.19.0-beta.1.0.20240626184459-c9314c6a63f8 + maunium.net/go/mautrix v0.19.0-beta.1.0.20240627083250-e25578d435a2 nhooyr.io/websocket v1.8.11 ) diff --git a/go.sum b/go.sum index a2117b9..f73fa34 100644 --- a/go.sum +++ b/go.sum @@ -93,7 +93,7 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= maunium.net/go/mauflag v1.0.0 h1:YiaRc0tEI3toYtJMRIfjP+jklH45uDHtT80nUamyD4M= maunium.net/go/mauflag v1.0.0/go.mod h1:nLivPOpTpHnpzEh8jEdSL9UqO9+/KBJFmNRlwKfkPeA= -maunium.net/go/mautrix v0.19.0-beta.1.0.20240626184459-c9314c6a63f8 h1:zxjQQrIOXw5MyE82I2SmWsgAFgh9lB8Ijjdilld59/U= -maunium.net/go/mautrix v0.19.0-beta.1.0.20240626184459-c9314c6a63f8/go.mod h1:eu/C1dTewrW7yiFNiCKGm4zuWJANyt7zPjaY5g3f3r4= +maunium.net/go/mautrix v0.19.0-beta.1.0.20240627083250-e25578d435a2 h1:HnP1dmvCVO/V22BdJre56Vu1IaEtMRUt86AD/1rmyME= +maunium.net/go/mautrix v0.19.0-beta.1.0.20240627083250-e25578d435a2/go.mod h1:eu/C1dTewrW7yiFNiCKGm4zuWJANyt7zPjaY5g3f3r4= nhooyr.io/websocket v1.8.11 h1:f/qXNc2/3DpoSZkHt1DQu6rj4zGC8JmkkLkWss0MgN0= nhooyr.io/websocket v1.8.11/go.mod h1:rN9OFWIUwuxg4fR5tELlYC04bXYowCP9GX47ivo2l+c= diff --git a/pkg/connector/client.go b/pkg/connector/client.go index 6f1a3ec..285e207 100644 --- a/pkg/connector/client.go +++ b/pkg/connector/client.go @@ -70,6 +70,9 @@ func (s *SignalClient) GetPushConfigs() *bridgev2.PushConfig { } func (s *SignalClient) RegisterPushNotifications(ctx context.Context, pushType bridgev2.PushType, token string) error { + if s.Client == nil { + return bridgev2.ErrNotLoggedIn + } if pushType != bridgev2.PushTypeFCM { return fmt.Errorf("unsupported push type: %s", pushType) } @@ -77,6 +80,9 @@ func (s *SignalClient) RegisterPushNotifications(ctx context.Context, pushType b } func (s *SignalClient) LogoutRemote(ctx context.Context) { + if s.Client == nil { + return + } err := s.Client.StopReceiveLoops() if err != nil { zerolog.Ctx(ctx).Err(err).Msg("Failed to stop receive loops for logout") @@ -88,6 +94,9 @@ func (s *SignalClient) LogoutRemote(ctx context.Context) { } func (s *SignalClient) IsThisUser(_ context.Context, userID networkid.UserID) bool { + if s.Client == nil { + return false + } return userID == makeUserID(s.Client.Store.ACI) } @@ -200,6 +209,9 @@ func (s *SignalClient) Connect(ctx context.Context) error { } func (s *SignalClient) Disconnect() { + if s.Client == nil { + return + } err := s.Client.StopReceiveLoops() if err != nil { s.UserLogin.Log.Err(err).Msg("Failed to stop receive loops") @@ -207,6 +219,10 @@ func (s *SignalClient) Disconnect() { } func (s *SignalClient) tryConnect(ctx context.Context, retryCount int) { + if s.Client == nil { + s.UserLogin.BridgeState.Send(status.BridgeState{StateEvent: status.StateBadCredentials, Message: "You're not logged into Signal"}) + return + } ch, err := s.Client.StartReceiveLoops(ctx) if err != nil { zerolog.Ctx(ctx).Err(err).Msg("Failed to start receive loops") @@ -225,5 +241,8 @@ func (s *SignalClient) tryConnect(ctx context.Context, retryCount int) { } func (s *SignalClient) IsLoggedIn() bool { + if s.Client == nil { + return false + } return s.Client.IsLoggedIn() } diff --git a/pkg/connector/connector.go b/pkg/connector/connector.go index 5fdec0a..8aec917 100644 --- a/pkg/connector/connector.go +++ b/pkg/connector/connector.go @@ -148,17 +148,17 @@ func (s *SignalConnector) LoadUserLogin(ctx context.Context, login *bridgev2.Use device, err := s.Store.DeviceByACI(ctx, aci) if err != nil { return fmt.Errorf("failed to get device from store: %w", err) - } else if device == nil { - return fmt.Errorf("%w: device not found in store", bridgev2.ErrNotLoggedIn) } sc := &SignalClient{ Main: s, UserLogin: login, - Client: &signalmeow.Client{ - Store: device, - }, } - sc.Client.EventHandler = sc.handleSignalEvent + if device != nil { + sc.Client = &signalmeow.Client{ + Store: device, + EventHandler: sc.handleSignalEvent, + } + } login.Client = sc return nil } From 1366e2721bb9bbb96ceaed4f3e0aa5ca8740dcc7 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Thu, 27 Jun 2024 11:35:06 +0300 Subject: [PATCH 083/580] v2: bridge more types of messages as normal messages --- pkg/connector/handlesignal.go | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/pkg/connector/handlesignal.go b/pkg/connector/handlesignal.go index 479ce2a..6af25ab 100644 --- a/pkg/connector/handlesignal.go +++ b/pkg/connector/handlesignal.go @@ -68,7 +68,10 @@ func (evt *Bv2ChatEvent) GetType() bridgev2.RemoteEventType { switch innerEvt := evt.Event.(type) { case *signalpb.DataMessage: switch { - case innerEvt.Body != nil, innerEvt.Attachments != nil, innerEvt.Contact != nil, innerEvt.Sticker != nil: + case innerEvt.Body != nil, innerEvt.Attachments != nil, innerEvt.Contact != nil, innerEvt.Sticker != nil, + innerEvt.Payment != nil, innerEvt.GiftBadge != nil, + innerEvt.GetRequiredProtocolVersion() > uint32(signalpb.DataMessage_CURRENT), + innerEvt.GetFlags()&uint32(signalpb.DataMessage_EXPIRATION_TIMER_UPDATE) != 0: return bridgev2.RemoteEventMessage case innerEvt.Reaction != nil: if innerEvt.Reaction.GetRemove() { From 5b1941c0ab5db50df70b592d5fba43722a1a448b Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Thu, 27 Jun 2024 11:53:21 +0300 Subject: [PATCH 084/580] v2: check send message results --- pkg/connector/handlematrix.go | 56 ++++++++++++++++++++++------------- 1 file changed, 35 insertions(+), 21 deletions(-) diff --git a/pkg/connector/handlematrix.go b/pkg/connector/handlematrix.go index 30b10e6..052428f 100644 --- a/pkg/connector/handlematrix.go +++ b/pkg/connector/handlematrix.go @@ -18,6 +18,7 @@ package connector import ( "context" + "errors" "fmt" "time" @@ -34,20 +35,43 @@ import ( signalpb "go.mau.fi/mautrix-signal/pkg/signalmeow/protobuf" ) -func (s *SignalClient) sendMessage(ctx context.Context, portalID networkid.PortalID, content *signalpb.Content) (signalmeow.SendResult, error) { +func (s *SignalClient) sendMessage(ctx context.Context, portalID networkid.PortalID, content *signalpb.Content) error { userID, groupID, err := s.parsePortalID(portalID) if err != nil { - return nil, err + return err } if groupID != "" { - res, err := s.Client.SendGroupMessage(ctx, groupID, content) + result, err := s.Client.SendGroupMessage(ctx, groupID, content) if err != nil { - return nil, err + return err } - return res, nil + totalRecipients := len(result.FailedToSendTo) + len(result.SuccessfullySentTo) + log := zerolog.Ctx(ctx).With(). + Int("total_recipients", totalRecipients). + Int("failed_to_send_to_count", len(result.FailedToSendTo)). + Int("successfully_sent_to_count", len(result.SuccessfullySentTo)). + Logger() + if len(result.FailedToSendTo) > 0 { + log.Error().Msg("Failed to send event to some members of Signal group") + } + if len(result.SuccessfullySentTo) == 0 && len(result.FailedToSendTo) == 0 { + log.Debug().Msg("No successes or failures - Probably sent to myself") + } else if len(result.SuccessfullySentTo) == 0 { + log.Error().Msg("Failed to send event to all members of Signal group") + return errors.New("failed to send to any members of Signal group") + + } else if len(result.SuccessfullySentTo) < totalRecipients { + log.Warn().Msg("Only sent event to some members of Signal group") + } else { + log.Debug().Msg("Sent event to all members of Signal group") + } + return nil } else { res := s.Client.SendMessage(ctx, userID, content) - return &res, nil + if !res.WasSuccessful { + return res.Error + } + return nil } } @@ -64,12 +88,10 @@ func (s *SignalClient) HandleMatrixMessage(ctx context.Context, msg *bridgev2.Ma if err != nil { return nil, err } - res, err := s.sendMessage(ctx, msg.Portal.ID, &signalpb.Content{DataMessage: converted}) + err = s.sendMessage(ctx, msg.Portal.ID, &signalpb.Content{DataMessage: converted}) if err != nil { return nil, err } - // TODO check result - fmt.Println(res) dbMsg := &database.Message{ ID: makeMessageID(s.Client.Store.ACI, converted.GetTimestamp()), SenderID: makeUserID(s.Client.Store.ACI), @@ -111,15 +133,13 @@ func (s *SignalClient) HandleMatrixEdit(ctx context.Context, msg *bridgev2.Matri if err != nil { return err } - res, err := s.sendMessage(ctx, msg.Portal.ID, &signalpb.Content{EditMessage: &signalpb.EditMessage{ + err = s.sendMessage(ctx, msg.Portal.ID, &signalpb.Content{EditMessage: &signalpb.EditMessage{ TargetSentTimestamp: proto.Uint64(targetSentTimestamp), DataMessage: converted, }}) if err != nil { return err } - // TODO check result - fmt.Println(res) msg.EditTarget.ID = makeMessageID(s.Client.Store.ACI, converted.GetTimestamp()) msg.EditTarget.Metadata.Extra["contains_attachments"] = len(converted.Attachments) > 0 msg.EditTarget.Metadata.EditCount++ @@ -151,12 +171,10 @@ func (s *SignalClient) HandleMatrixReaction(ctx context.Context, msg *bridgev2.M }, }, } - res, err := s.sendMessage(ctx, msg.Portal.ID, wrappedContent) + err = s.sendMessage(ctx, msg.Portal.ID, wrappedContent) if err != nil { return nil, err } - // TODO check result - fmt.Println(res) return &database.Reaction{}, nil } @@ -177,12 +195,10 @@ func (s *SignalClient) HandleMatrixReactionRemove(ctx context.Context, msg *brid }, }, } - res, err := s.sendMessage(ctx, msg.Portal.ID, wrappedContent) + err = s.sendMessage(ctx, msg.Portal.ID, wrappedContent) if err != nil { return err } - // TODO check result - fmt.Println(res) return nil } @@ -201,12 +217,10 @@ func (s *SignalClient) HandleMatrixMessageRemove(ctx context.Context, msg *bridg }, }, } - res, err := s.sendMessage(ctx, msg.Portal.ID, wrappedContent) + err = s.sendMessage(ctx, msg.Portal.ID, wrappedContent) if err != nil { return err } - // TODO check result - fmt.Println(res) return nil } From fdb9e7dc09599fd982cff4ea90903971e368983e Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Thu, 27 Jun 2024 16:43:53 +0300 Subject: [PATCH 085/580] v2: fix handling disappearing timer changes --- msgconv/from-signal.go | 16 ++++++++++------ msgconv/msgconv.go | 3 ++- pkg/connector/connector.go | 17 ++++++++++++++++- pkg/connector/handlesignal.go | 17 +++++++++++++---- 4 files changed, 41 insertions(+), 12 deletions(-) diff --git a/msgconv/from-signal.go b/msgconv/from-signal.go index 8a4b5d1..918c749 100644 --- a/msgconv/from-signal.go +++ b/msgconv/from-signal.go @@ -173,12 +173,16 @@ func (mc *MessageConverter) ConvertDisappearingTimerChangeToMatrix(ctx context.C if timer == 0 { part.Content.Body = "Disappearing messages disabled" } - if updatePortal && !mc.NoUpdateDisappearing { - portal := mc.GetData(ctx) - portal.ExpirationTime = timer - err := portal.Update(ctx) - if err != nil { - zerolog.Ctx(ctx).Err(err).Msg("Failed to update portal disappearing timer in database") + if updatePortal { + if mc.UpdateDisappearing != nil { + mc.UpdateDisappearing(ctx, time.Duration(timer)*time.Second) + } else { + portal := mc.GetData(ctx) + portal.ExpirationTime = timer + err := portal.Update(ctx) + if err != nil { + zerolog.Ctx(ctx).Err(err).Msg("Failed to update portal disappearing timer in database") + } } } return part diff --git a/msgconv/msgconv.go b/msgconv/msgconv.go index 33ac4a5..ee3ff55 100644 --- a/msgconv/msgconv.go +++ b/msgconv/msgconv.go @@ -18,6 +18,7 @@ package msgconv import ( "context" + "time" "maunium.net/go/mautrix/event" "maunium.net/go/mautrix/id" @@ -54,7 +55,7 @@ type MessageConverter struct { ConvertGIFToAPNG bool MaxFileSize int64 AsyncFiles bool - NoUpdateDisappearing bool + UpdateDisappearing func(ctx context.Context, newTimer time.Duration) LocationFormat string } diff --git a/pkg/connector/connector.go b/pkg/connector/connector.go index 8aec917..dcb7ada 100644 --- a/pkg/connector/connector.go +++ b/pkg/connector/connector.go @@ -20,10 +20,13 @@ import ( "context" "fmt" "text/template" + "time" "github.com/google/uuid" + "github.com/rs/zerolog" "go.mau.fi/util/dbutil" "maunium.net/go/mautrix/bridgev2" + "maunium.net/go/mautrix/bridgev2/database" "maunium.net/go/mautrix/bridgev2/networkid" "maunium.net/go/mautrix/id" @@ -124,7 +127,19 @@ func (s *SignalConnector) Init(bridge *bridgev2.Bridge) { MaxFileSize: 50 * 1024 * 1024, AsyncFiles: true, LocationFormat: s.Config.LocationFormat, - NoUpdateDisappearing: true, + UpdateDisappearing: func(ctx context.Context, newTimer time.Duration) { + portal := ctx.Value(msgconvContextKey).(*msgconvContext).Portal + portal.Metadata.DisappearTimer = newTimer + if newTimer == 0 { + portal.Metadata.DisappearType = "" + } else { + portal.Metadata.DisappearType = database.DisappearingTypeAfterRead + } + err := portal.Save(ctx) + if err != nil { + zerolog.Ctx(ctx).Err(err).Msg("Failed to update portal disappearing timer in database") + } + }, } } diff --git a/pkg/connector/handlesignal.go b/pkg/connector/handlesignal.go index 6af25ab..5d10716 100644 --- a/pkg/connector/handlesignal.go +++ b/pkg/connector/handlesignal.go @@ -23,10 +23,12 @@ import ( "github.com/google/uuid" "github.com/rs/zerolog" + "go.mau.fi/util/exfmt" "go.mau.fi/util/exzerolog" "maunium.net/go/mautrix/bridgev2" "maunium.net/go/mautrix/bridgev2/database" "maunium.net/go/mautrix/bridgev2/networkid" + "maunium.net/go/mautrix/event" "go.mau.fi/mautrix-signal/pkg/signalmeow/events" signalpb "go.mau.fi/mautrix-signal/pkg/signalmeow/protobuf" @@ -235,13 +237,20 @@ func (evt *Bv2ChatEvent) ConvertMessage(ctx context.Context, portal *bridgev2.Po if portal.Metadata.DisappearTimer != disappear.Timer { portal.Metadata.DisappearType = disappear.Type portal.Metadata.DisappearTimer = disappear.Timer - // TODO if the message doesn't have the DataMessage_EXPIRATION_TIMER_UPDATE, - // we should send a message to the portal notifying of the implicit update err := portal.Save(ctx) if err != nil { - zerolog.Ctx(ctx).Err(err).Msg("Failed to save portal metadata after updating disappearing timer") + zerolog.Ctx(ctx).Err(err).Msg("Failed to save portal metadata after implicitly updating disappearing timer") } else { - zerolog.Ctx(ctx).Debug().Dur("new_timer", portal.Metadata.DisappearTimer).Msg("Updated disappearing timer in portal") + zerolog.Ctx(ctx).Debug().Dur("new_timer", portal.Metadata.DisappearTimer).Msg("Implicitly updated disappearing timer in portal") + } + _, err = portal.Bridge.Bot.SendMessage(ctx, portal.MXID, event.EventMessage, &event.Content{ + Parsed: &event.MessageEventContent{ + MsgType: event.MsgNotice, + Body: fmt.Sprintf("Automatically enabled disappearing message timer (%s) because incoming message is disappearing", exfmt.Duration(disappear.Timer)), + }, + }, time.UnixMilli(int64(dataMsg.GetTimestamp()))) + if err != nil { + zerolog.Ctx(ctx).Err(err).Msg("Failed to send notice about disappearing message timer changing implicitly") } } } From 6a92ccc1dd49df2f023c4984fb7dc0054ae6b7d9 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Thu, 27 Jun 2024 19:00:05 +0300 Subject: [PATCH 086/580] v2: add group change handling --- go.mod | 2 +- go.sum | 4 +- pkg/connector/chatinfo.go | 25 +------ pkg/connector/groupinfo.go | 135 ++++++++++++++++++++++++++++++++++ pkg/connector/handlesignal.go | 59 +++++++++------ 5 files changed, 175 insertions(+), 50 deletions(-) create mode 100644 pkg/connector/groupinfo.go diff --git a/go.mod b/go.mod index 19843dc..7edae3d 100644 --- a/go.mod +++ b/go.mod @@ -19,7 +19,7 @@ require ( golang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8 golang.org/x/net v0.26.0 google.golang.org/protobuf v1.34.2 - maunium.net/go/mautrix v0.19.0-beta.1.0.20240627083250-e25578d435a2 + maunium.net/go/mautrix v0.19.0-beta.1.0.20240627155110-35f8d837b5f5 nhooyr.io/websocket v1.8.11 ) diff --git a/go.sum b/go.sum index f73fa34..476c3d9 100644 --- a/go.sum +++ b/go.sum @@ -93,7 +93,7 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= maunium.net/go/mauflag v1.0.0 h1:YiaRc0tEI3toYtJMRIfjP+jklH45uDHtT80nUamyD4M= maunium.net/go/mauflag v1.0.0/go.mod h1:nLivPOpTpHnpzEh8jEdSL9UqO9+/KBJFmNRlwKfkPeA= -maunium.net/go/mautrix v0.19.0-beta.1.0.20240627083250-e25578d435a2 h1:HnP1dmvCVO/V22BdJre56Vu1IaEtMRUt86AD/1rmyME= -maunium.net/go/mautrix v0.19.0-beta.1.0.20240627083250-e25578d435a2/go.mod h1:eu/C1dTewrW7yiFNiCKGm4zuWJANyt7zPjaY5g3f3r4= +maunium.net/go/mautrix v0.19.0-beta.1.0.20240627155110-35f8d837b5f5 h1:dJBtUNpc9G0IKq1uRU6kZetBmgMtcmh1F/sMiyDpbDc= +maunium.net/go/mautrix v0.19.0-beta.1.0.20240627155110-35f8d837b5f5/go.mod h1:eu/C1dTewrW7yiFNiCKGm4zuWJANyt7zPjaY5g3f3r4= nhooyr.io/websocket v1.8.11 h1:f/qXNc2/3DpoSZkHt1DQu6rj4zGC8JmkkLkWss0MgN0= nhooyr.io/websocket v1.8.11/go.mod h1:rN9OFWIUwuxg4fR5tELlYC04bXYowCP9GX47ivo2l+c= diff --git a/pkg/connector/chatinfo.go b/pkg/connector/chatinfo.go index f0f06f3..aa5c7c8 100644 --- a/pkg/connector/chatinfo.go +++ b/pkg/connector/chatinfo.go @@ -53,30 +53,7 @@ func (s *SignalClient) GetChatInfo(ctx context.Context, portal *bridgev2.Portal) return nil, err } if groupID != "" { - groupInfo, err := s.Client.RetrieveGroupByID(ctx, groupID, 0) - if err != nil { - return nil, err - } - isDM := false - isSpace := false - members := make([]networkid.UserID, len(groupInfo.Members)) - for i, member := range groupInfo.Members { - members[i] = makeUserID(member.ACI) - } - return &bridgev2.PortalInfo{ - Name: &groupInfo.Title, - Topic: &groupInfo.Description, - Avatar: &bridgev2.Avatar{ - ID: makeAvatarPathID(groupInfo.AvatarPath), - Get: func(ctx context.Context) ([]byte, error) { - return s.Client.DownloadGroupAvatar(ctx, groupInfo) - }, - Remove: groupInfo.AvatarPath == "", - }, - Members: members, - IsDirectChat: &isDM, - IsSpace: &isSpace, - }, nil + return s.getGroupInfo(ctx, groupID, 0) } else { aci, pni := serviceIDToACIAndPNI(userID) contact, err := s.Client.Store.RecipientStore.LoadAndUpdateRecipient(ctx, aci, pni, nil) diff --git a/pkg/connector/groupinfo.go b/pkg/connector/groupinfo.go new file mode 100644 index 0000000..e436412 --- /dev/null +++ b/pkg/connector/groupinfo.go @@ -0,0 +1,135 @@ +// mautrix-signal - A Matrix-Signal puppeting bridge. +// Copyright (C) 2024 Tulir Asokan +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +package connector + +import ( + "context" + "time" + + "github.com/rs/zerolog" + "maunium.net/go/mautrix/bridgev2" + "maunium.net/go/mautrix/bridgev2/database" + "maunium.net/go/mautrix/bridgev2/networkid" + + "go.mau.fi/mautrix-signal/pkg/signalmeow" + "go.mau.fi/mautrix-signal/pkg/signalmeow/types" +) + +func (s *SignalClient) getGroupInfo(ctx context.Context, groupID types.GroupIdentifier, minRevision uint32) (*bridgev2.PortalInfo, error) { + groupInfo, err := s.Client.RetrieveGroupByID(ctx, groupID, minRevision) + if err != nil { + return nil, err + } + isDM := false + isSpace := false + members := make([]networkid.UserID, len(groupInfo.Members)) + for i, member := range groupInfo.Members { + members[i] = makeUserID(member.ACI) + } + return &bridgev2.PortalInfo{ + Name: &groupInfo.Title, + Topic: &groupInfo.Description, + Avatar: s.makeGroupAvatar(groupInfo), + Disappear: &database.DisappearingSetting{ + Type: database.DisappearingTypeAfterRead, + Timer: time.Duration(groupInfo.DisappearingMessagesDuration) * time.Second, + }, + Members: members, + IsDirectChat: &isDM, + IsSpace: &isSpace, + ExtraUpdates: makeRevisionUpdater(groupInfo.Revision), + }, nil +} + +func (s *SignalClient) makeGroupAvatar(meta signalmeow.GroupAvatarMeta) *bridgev2.Avatar { + path := meta.GetAvatarPath() + if path == nil { + return nil + } + return &bridgev2.Avatar{ + ID: makeAvatarPathID(*path), + Get: func(ctx context.Context) ([]byte, error) { + return s.Client.DownloadGroupAvatar(ctx, meta) + }, + Remove: *path == "", + } +} + +func makeRevisionUpdater(rev uint32) func(ctx context.Context, portal *bridgev2.Portal) bool { + return func(ctx context.Context, portal *bridgev2.Portal) bool { + currentRev, _ := database.GetNumberFromMap[uint32](portal.Metadata.Extra, "revision") + if currentRev < rev { + portal.Metadata.Extra["revision"] = rev + return true + } + return false + } +} + +func (s *SignalClient) groupChangeToChatInfoChange(ctx context.Context, rev uint32, groupChange *signalmeow.GroupChange) *bridgev2.ChatInfoChange { + ic := &bridgev2.ChatInfoChange{ + PortalInfo: &bridgev2.PortalInfo{ + ExtraUpdates: makeRevisionUpdater(rev), + Name: groupChange.ModifyTitle, + Topic: groupChange.ModifyDescription, + Avatar: s.makeGroupAvatar(groupChange), + }, + } + if groupChange.ModifyDisappearingMessagesDuration != nil { + ic.PortalInfo.Disappear = &database.DisappearingSetting{ + Type: database.DisappearingTypeAfterRead, + Timer: time.Duration(*groupChange.ModifyDisappearingMessagesDuration) * time.Second, + } + } + // TODO handle member/permission/etc changes + return ic +} + +func (s *SignalClient) catchUpGroup(ctx context.Context, portal *bridgev2.Portal, fromRevision, toRevision uint32, ts uint64) { + if fromRevision >= toRevision { + return + } + log := zerolog.Ctx(ctx).With(). + Str("action", "catch up group changes"). + Uint32("from_revision", fromRevision). + Uint32("to_revision", toRevision). + Logger() + if fromRevision == 0 { + log.Info().Msg("Syncing full group info") + info, err := s.getGroupInfo(ctx, types.GroupIdentifier(portal.ID), toRevision) + if err != nil { + log.Err(err).Msg("Failed to get group info") + } else { + portal.UpdateInfo(ctx, info, s.UserLogin, nil, time.Time{}) + } + } else { + log.Info().Msg("Syncing missed group changes") + groupChanges, err := s.Client.GetGroupHistoryPage(ctx, types.GroupIdentifier(portal.ID), fromRevision, false) + if err != nil { + log.Err(err).Msg("Failed to get group history page") + return + } + for _, gc := range groupChanges { + log.Debug().Uint32("current_rev", gc.GroupChange.Revision).Msg("Processing group change") + chatInfoChange := s.groupChangeToChatInfoChange(ctx, gc.GroupChange.Revision, gc.GroupChange) + portal.ProcessChatInfoChange(ctx, s.makeEventSender(gc.GroupChange.SourceACI), s.UserLogin, chatInfoChange, time.UnixMilli(int64(ts))) + if gc.GroupChange.Revision == toRevision { + break + } + } + } +} diff --git a/pkg/connector/handlesignal.go b/pkg/connector/handlesignal.go index 5d10716..768b69c 100644 --- a/pkg/connector/handlesignal.go +++ b/pkg/connector/handlesignal.go @@ -23,12 +23,10 @@ import ( "github.com/google/uuid" "github.com/rs/zerolog" - "go.mau.fi/util/exfmt" "go.mau.fi/util/exzerolog" "maunium.net/go/mautrix/bridgev2" "maunium.net/go/mautrix/bridgev2/database" "maunium.net/go/mautrix/bridgev2/networkid" - "maunium.net/go/mautrix/event" "go.mau.fi/mautrix-signal/pkg/signalmeow/events" signalpb "go.mau.fi/mautrix-signal/pkg/signalmeow/protobuf" @@ -64,6 +62,8 @@ var ( _ bridgev2.RemoteReactionRemove = (*Bv2ChatEvent)(nil) _ bridgev2.RemoteMessageRemove = (*Bv2ChatEvent)(nil) _ bridgev2.RemoteTyping = (*Bv2ChatEvent)(nil) + _ bridgev2.RemotePreHandler = (*Bv2ChatEvent)(nil) + _ bridgev2.RemoteChatInfoChange = (*Bv2ChatEvent)(nil) ) func (evt *Bv2ChatEvent) GetType() bridgev2.RemoteEventType { @@ -82,6 +82,8 @@ func (evt *Bv2ChatEvent) GetType() bridgev2.RemoteEventType { return bridgev2.RemoteEventReaction case innerEvt.Delete != nil: return bridgev2.RemoteEventMessageRemove + case innerEvt.GetGroupV2().GetGroupChange() != nil: + return bridgev2.RemoteEventChatInfoChange } case *signalpb.EditMessage: return bridgev2.RemoteEventEdit @@ -91,6 +93,34 @@ func (evt *Bv2ChatEvent) GetType() bridgev2.RemoteEventType { return bridgev2.RemoteEventUnknown } +func (evt *Bv2ChatEvent) GetChatInfoChange(ctx context.Context) (*bridgev2.ChatInfoChange, error) { + dm, _ := evt.Event.(*signalpb.DataMessage) + gv2 := dm.GetGroupV2() + if gv2 == nil || gv2.GroupChange == nil { + return nil, fmt.Errorf("GetChatInfoChange() called for non-GroupChange event") + } + groupChange, err := evt.s.Client.DecryptGroupChange(ctx, gv2) + if err != nil { + return nil, fmt.Errorf("failed to decrypt group change: %w", err) + } + return evt.s.groupChangeToChatInfoChange(ctx, gv2.GetRevision(), groupChange), nil +} + +func (evt *Bv2ChatEvent) PreHandle(ctx context.Context, portal *bridgev2.Portal) { + dataMsg, ok := evt.Event.(*signalpb.DataMessage) + if !ok || dataMsg.GroupV2 == nil { + return + } + portalRev, _ := database.GetNumberFromMap[uint32](portal.Metadata.Extra, "revision") + if evt.Info.GroupRevision > portalRev { + toRevision := evt.Info.GroupRevision + if dataMsg.GetGroupV2().GetGroupChange() != nil { + toRevision-- + } + evt.s.catchUpGroup(ctx, portal, portalRev, toRevision, dataMsg.GetTimestamp()) + } +} + func (evt *Bv2ChatEvent) GetTimeout() time.Duration { if evt.Event.(*signalpb.TypingMessage).GetAction() == signalpb.TypingMessage_STARTED { return 15 * time.Second @@ -104,7 +134,7 @@ func (evt *Bv2ChatEvent) GetPortalKey() networkid.PortalKey { } func (evt *Bv2ChatEvent) ShouldCreatePortal() bool { - return evt.GetType() == bridgev2.RemoteEventMessage + return evt.GetType() == bridgev2.RemoteEventMessage || evt.GetType() == bridgev2.RemoteEventChatInfoChange } func (evt *Bv2ChatEvent) AddLogContext(c zerolog.Context) zerolog.Context { @@ -231,28 +261,11 @@ func (evt *Bv2ChatEvent) ConvertMessage(ctx context.Context, portal *bridgev2.Po Type: database.DisappearingTypeAfterRead, Timer: time.Duration(converted.DisappearIn) * time.Second, } + dataMsgTS := time.UnixMilli(int64(dataMsg.GetTimestamp())) if evt.Info.Sender == evt.s.Client.Store.ACI { - disappear.DisappearAt = time.UnixMilli(int64(dataMsg.GetTimestamp())).Add(disappear.Timer) - } - if portal.Metadata.DisappearTimer != disappear.Timer { - portal.Metadata.DisappearType = disappear.Type - portal.Metadata.DisappearTimer = disappear.Timer - err := portal.Save(ctx) - if err != nil { - zerolog.Ctx(ctx).Err(err).Msg("Failed to save portal metadata after implicitly updating disappearing timer") - } else { - zerolog.Ctx(ctx).Debug().Dur("new_timer", portal.Metadata.DisappearTimer).Msg("Implicitly updated disappearing timer in portal") - } - _, err = portal.Bridge.Bot.SendMessage(ctx, portal.MXID, event.EventMessage, &event.Content{ - Parsed: &event.MessageEventContent{ - MsgType: event.MsgNotice, - Body: fmt.Sprintf("Automatically enabled disappearing message timer (%s) because incoming message is disappearing", exfmt.Duration(disappear.Timer)), - }, - }, time.UnixMilli(int64(dataMsg.GetTimestamp()))) - if err != nil { - zerolog.Ctx(ctx).Err(err).Msg("Failed to send notice about disappearing message timer changing implicitly") - } + disappear.DisappearAt = dataMsgTS.Add(disappear.Timer) } + portal.UpdateDisappearingSetting(ctx, disappear, nil, dataMsgTS, true, true) } return &bridgev2.ConvertedMessage{ ReplyTo: replyTo, From 9121a0c29f50755bda14b13d4c5489243562454c Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Thu, 27 Jun 2024 19:08:19 +0300 Subject: [PATCH 087/580] v2/legacymigrate: copy revision in portals --- cmd/mautrix-signal-v2/legacymigrate.sql | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cmd/mautrix-signal-v2/legacymigrate.sql b/cmd/mautrix-signal-v2/legacymigrate.sql index ba91f9c..8aac4db 100644 --- a/cmd/mautrix-signal-v2/legacymigrate.sql +++ b/cmd/mautrix-signal-v2/legacymigrate.sql @@ -29,8 +29,8 @@ SELECT false, -- in_space CAST( CASE WHEN expiration_time = 0 - THEN '{}' - ELSE '{"disappear_type": "after_read", "disappear_timer": "' || (expiration_time * 1000000000) || '"}' + THEN '{"revision":"' || revision || '"}' + ELSE '{"disappear_type": "after_read", "disappear_timer": "' || (expiration_time * 1000000000) || '","revision":"' || revision || '"}' END -- only: postgres AS jsonb From 7b538502f157c619141f7029b51db63a2587cf61 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Fri, 28 Jun 2024 18:50:37 +0300 Subject: [PATCH 088/580] v2: bridge all member states and permissions --- go.mod | 2 +- go.sum | 4 +- pkg/connector/chatinfo.go | 20 +++- pkg/connector/groupinfo.go | 220 +++++++++++++++++++++++++++++++++++-- 4 files changed, 231 insertions(+), 15 deletions(-) diff --git a/go.mod b/go.mod index 7edae3d..b4f8e16 100644 --- a/go.mod +++ b/go.mod @@ -19,7 +19,7 @@ require ( golang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8 golang.org/x/net v0.26.0 google.golang.org/protobuf v1.34.2 - maunium.net/go/mautrix v0.19.0-beta.1.0.20240627155110-35f8d837b5f5 + maunium.net/go/mautrix v0.19.0-beta.1.0.20240628154312-d7251a4c6950 nhooyr.io/websocket v1.8.11 ) diff --git a/go.sum b/go.sum index 476c3d9..8ae9f4b 100644 --- a/go.sum +++ b/go.sum @@ -93,7 +93,7 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= maunium.net/go/mauflag v1.0.0 h1:YiaRc0tEI3toYtJMRIfjP+jklH45uDHtT80nUamyD4M= maunium.net/go/mauflag v1.0.0/go.mod h1:nLivPOpTpHnpzEh8jEdSL9UqO9+/KBJFmNRlwKfkPeA= -maunium.net/go/mautrix v0.19.0-beta.1.0.20240627155110-35f8d837b5f5 h1:dJBtUNpc9G0IKq1uRU6kZetBmgMtcmh1F/sMiyDpbDc= -maunium.net/go/mautrix v0.19.0-beta.1.0.20240627155110-35f8d837b5f5/go.mod h1:eu/C1dTewrW7yiFNiCKGm4zuWJANyt7zPjaY5g3f3r4= +maunium.net/go/mautrix v0.19.0-beta.1.0.20240628154312-d7251a4c6950 h1:A43PQ5ltou4KhcCMxZz1gb3QXrhOjVKweYDW5YQ/Gok= +maunium.net/go/mautrix v0.19.0-beta.1.0.20240628154312-d7251a4c6950/go.mod h1:eu/C1dTewrW7yiFNiCKGm4zuWJANyt7zPjaY5g3f3r4= nhooyr.io/websocket v1.8.11 h1:f/qXNc2/3DpoSZkHt1DQu6rj4zGC8JmkkLkWss0MgN0= nhooyr.io/websocket v1.8.11/go.mod h1:rN9OFWIUwuxg4fR5tELlYC04bXYowCP9GX47ivo2l+c= diff --git a/pkg/connector/chatinfo.go b/pkg/connector/chatinfo.go index aa5c7c8..79b253d 100644 --- a/pkg/connector/chatinfo.go +++ b/pkg/connector/chatinfo.go @@ -27,6 +27,7 @@ import ( "github.com/rs/zerolog" "maunium.net/go/mautrix/bridgev2" "maunium.net/go/mautrix/bridgev2/networkid" + "maunium.net/go/mautrix/event" "go.mau.fi/mautrix-signal/pkg/libsignalgo" "go.mau.fi/mautrix-signal/pkg/signalmeow/types" @@ -195,7 +196,16 @@ func (s *SignalClient) makeCreateDMResponse(recipient *types.Recipient) *bridgev isSpace := false name := "" topic := PrivateChatTopic - members := []networkid.UserID{makeUserID(s.Client.Store.ACI)} + members := &bridgev2.ChatMemberList{ + IsFull: true, + Members: []bridgev2.ChatMember{ + { + EventSender: s.makeEventSender(s.Client.Store.ACI), + Membership: event.MembershipJoin, + PowerLevel: moderatorPL, + }, + }, + } if s.Main.Config.NumberInTopic && recipient.E164 != "" { topic = fmt.Sprintf("%s with %s", PrivateChatTopic, recipient.E164) } @@ -215,13 +225,17 @@ func (s *SignalClient) makeCreateDMResponse(recipient *types.Recipient) *bridgev } } else { // The other user is only present if their ACI is known - members = append(members, makeUserID(recipient.ACI)) + members.Members = append(members.Members, bridgev2.ChatMember{ + EventSender: s.makeEventSender(recipient.ACI), + Membership: event.MembershipJoin, + PowerLevel: moderatorPL, + }) } serviceID = libsignalgo.NewACIServiceID(recipient.ACI) } return &bridgev2.CreateChatResponse{ PortalID: s.makeDMPortalKey(serviceID), - PortalInfo: &bridgev2.PortalInfo{ + PortalInfo: &bridgev2.ChatInfo{ Name: &name, Avatar: avatar, Topic: &topic, diff --git a/pkg/connector/groupinfo.go b/pkg/connector/groupinfo.go index e436412..65cbab2 100644 --- a/pkg/connector/groupinfo.go +++ b/pkg/connector/groupinfo.go @@ -23,24 +23,128 @@ import ( "github.com/rs/zerolog" "maunium.net/go/mautrix/bridgev2" "maunium.net/go/mautrix/bridgev2/database" - "maunium.net/go/mautrix/bridgev2/networkid" + "maunium.net/go/mautrix/event" + "go.mau.fi/mautrix-signal/pkg/libsignalgo" "go.mau.fi/mautrix-signal/pkg/signalmeow" "go.mau.fi/mautrix-signal/pkg/signalmeow/types" ) -func (s *SignalClient) getGroupInfo(ctx context.Context, groupID types.GroupIdentifier, minRevision uint32) (*bridgev2.PortalInfo, error) { +var defaultPL = 0 +var moderatorPL = 50 + +func roleToPL(role signalmeow.GroupMemberRole) int { + switch role { + case signalmeow.GroupMember_ADMINISTRATOR: + return moderatorPL + case signalmeow.GroupMember_DEFAULT: + fallthrough + default: + return defaultPL + } +} + +func applyAnnouncementsOnly(plc *bridgev2.PowerLevelChanges, announcementsOnly bool) { + if announcementsOnly { + plc.EventsDefault = &moderatorPL + } else { + plc.EventsDefault = &defaultPL + } +} + +func applyAttributesAccess(plc *bridgev2.PowerLevelChanges, attributeAccess signalmeow.AccessControl) { + attributePL := defaultPL + if attributeAccess == signalmeow.AccessControl_ADMINISTRATOR { + attributePL = moderatorPL + } + plc.Events[event.StateRoomName] = attributePL + plc.Events[event.StateRoomAvatar] = attributePL + plc.Events[event.StateTopic] = attributePL +} + +func applyMembersAccess(plc *bridgev2.PowerLevelChanges, memberAccess signalmeow.AccessControl) { + if memberAccess == signalmeow.AccessControl_ADMINISTRATOR { + plc.Invite = &moderatorPL + } else { + plc.Invite = &defaultPL + } +} + +func inviteLinkToJoinRule(inviteLinkAccess signalmeow.AccessControl) event.JoinRule { + switch inviteLinkAccess { + case signalmeow.AccessControl_UNSATISFIABLE: + return event.JoinRuleInvite + case signalmeow.AccessControl_ADMINISTRATOR: + return event.JoinRuleKnock + case signalmeow.AccessControl_ANY: + // TODO allow public portals? + publicPortals := false + if publicPortals { + return event.JoinRulePublic + } else { + return event.JoinRuleKnock + } + default: + return event.JoinRuleInvite + } +} + +func (s *SignalClient) getGroupInfo(ctx context.Context, groupID types.GroupIdentifier, minRevision uint32) (*bridgev2.ChatInfo, error) { groupInfo, err := s.Client.RetrieveGroupByID(ctx, groupID, minRevision) if err != nil { return nil, err } isDM := false isSpace := false - members := make([]networkid.UserID, len(groupInfo.Members)) - for i, member := range groupInfo.Members { - members[i] = makeUserID(member.ACI) + members := &bridgev2.ChatMemberList{ + IsFull: true, + Members: make([]bridgev2.ChatMember, len(groupInfo.Members), len(groupInfo.Members)+len(groupInfo.PendingMembers)+len(groupInfo.RequestingMembers)+len(groupInfo.BannedMembers)), + PowerLevels: &bridgev2.PowerLevelChanges{ + Events: map[event.Type]int{ + event.StatePowerLevels: moderatorPL, + }, + }, } - return &bridgev2.PortalInfo{ + applyAnnouncementsOnly(members.PowerLevels, groupInfo.AnnouncementsOnly) + joinRule := event.JoinRuleInvite + if groupInfo.AccessControl != nil { + applyAttributesAccess(members.PowerLevels, groupInfo.AccessControl.Attributes) + applyMembersAccess(members.PowerLevels, groupInfo.AccessControl.Members) + joinRule = inviteLinkToJoinRule(groupInfo.AccessControl.AddFromInviteLink) + } + for i, member := range groupInfo.Members { + members.Members[i] = bridgev2.ChatMember{ + EventSender: s.makeEventSender(member.ACI), + PowerLevel: roleToPL(member.Role), + Membership: event.MembershipJoin, + } + } + for _, member := range groupInfo.PendingMembers { + if member.ServiceID.Type != libsignalgo.ServiceIDTypeACI { + continue + } + members.Members = append(members.Members, bridgev2.ChatMember{ + EventSender: s.makeEventSender(member.ServiceID.UUID), + PowerLevel: roleToPL(member.Role), + Membership: event.MembershipInvite, + }) + } + for _, member := range groupInfo.RequestingMembers { + members.Members = append(members.Members, bridgev2.ChatMember{ + EventSender: s.makeEventSender(member.ACI), + Membership: event.MembershipKnock, + }) + } + for _, member := range groupInfo.BannedMembers { + if member.ServiceID.Type != libsignalgo.ServiceIDTypeACI { + continue + } + members.Members = append(members.Members, bridgev2.ChatMember{ + EventSender: s.makeEventSender(member.ServiceID.UUID), + Membership: event.MembershipBan, + }) + } + return &bridgev2.ChatInfo{ Name: &groupInfo.Title, Topic: &groupInfo.Description, Avatar: s.makeGroupAvatar(groupInfo), @@ -51,6 +155,7 @@ func (s *SignalClient) getGroupInfo(ctx context.Context, groupID types.GroupIden Members: members, IsDirectChat: &isDM, IsSpace: &isSpace, + JoinRule: &event.JoinRulesEventContent{JoinRule: joinRule}, ExtraUpdates: makeRevisionUpdater(groupInfo.Revision), }, nil } @@ -82,7 +187,7 @@ func makeRevisionUpdater(rev uint32) func(ctx context.Context, portal *bridgev2. func (s *SignalClient) groupChangeToChatInfoChange(ctx context.Context, rev uint32, groupChange *signalmeow.GroupChange) *bridgev2.ChatInfoChange { ic := &bridgev2.ChatInfoChange{ - PortalInfo: &bridgev2.PortalInfo{ + ChatInfo: &bridgev2.ChatInfo{ ExtraUpdates: makeRevisionUpdater(rev), Name: groupChange.ModifyTitle, Topic: groupChange.ModifyDescription, @@ -90,12 +195,109 @@ func (s *SignalClient) groupChangeToChatInfoChange(ctx context.Context, rev uint }, } if groupChange.ModifyDisappearingMessagesDuration != nil { - ic.PortalInfo.Disappear = &database.DisappearingSetting{ + ic.ChatInfo.Disappear = &database.DisappearingSetting{ Type: database.DisappearingTypeAfterRead, Timer: time.Duration(*groupChange.ModifyDisappearingMessagesDuration) * time.Second, } } - // TODO handle member/permission/etc changes + + var pls *bridgev2.PowerLevelChanges + if groupChange.ModifyAnnouncementsOnly != nil || + groupChange.ModifyAttributesAccess != nil || + groupChange.ModifyMemberAccess != nil { + pls = &bridgev2.PowerLevelChanges{Events: make(map[event.Type]int)} + if groupChange.ModifyAnnouncementsOnly != nil { + applyAnnouncementsOnly(pls, *groupChange.ModifyAnnouncementsOnly) + } + if groupChange.ModifyAttributesAccess != nil { + applyAttributesAccess(pls, *groupChange.ModifyAttributesAccess) + } + if groupChange.ModifyMemberAccess != nil { + applyMembersAccess(pls, *groupChange.ModifyMemberAccess) + } + } + if groupChange.ModifyAddFromInviteLinkAccess != nil { + ic.ChatInfo.JoinRule = &event.JoinRulesEventContent{ + JoinRule: inviteLinkToJoinRule(*groupChange.ModifyAddFromInviteLinkAccess), + } + } + var mc []bridgev2.ChatMember + for _, member := range groupChange.AddMembers { + mc = append(mc, bridgev2.ChatMember{ + EventSender: s.makeEventSender(member.ACI), + PowerLevel: roleToPL(member.Role), + Membership: event.MembershipJoin, + }) + } + for _, member := range groupChange.ModifyMemberRoles { + mc = append(mc, bridgev2.ChatMember{ + EventSender: s.makeEventSender(member.ACI), + PowerLevel: roleToPL(member.Role), + Membership: event.MembershipJoin, + }) + } + for _, memberACI := range groupChange.DeleteMembers { + mc = append(mc, bridgev2.ChatMember{ + EventSender: s.makeEventSender(*memberACI), + Membership: event.MembershipLeave, + PrevMembership: event.MembershipJoin, + }) + } + for _, member := range groupChange.AddPendingMembers { + if member.ServiceID.Type != libsignalgo.ServiceIDTypeACI { + continue + } + mc = append(mc, bridgev2.ChatMember{ + EventSender: s.makeEventSender(member.ServiceID.UUID), + PowerLevel: roleToPL(member.Role), + Membership: event.MembershipInvite, + }) + } + for _, memberServiceID := range groupChange.DeletePendingMembers { + if memberServiceID.Type != libsignalgo.ServiceIDTypeACI { + continue + } + mc = append(mc, bridgev2.ChatMember{ + EventSender: s.makeEventSender(memberServiceID.UUID), + Membership: event.MembershipLeave, + PrevMembership: event.MembershipInvite, + }) + } + for _, member := range groupChange.AddRequestingMembers { + mc = append(mc, bridgev2.ChatMember{ + EventSender: s.makeEventSender(member.ACI), + Membership: event.MembershipKnock, + }) + } + for _, memberACI := range groupChange.DeleteRequestingMembers { + mc = append(mc, bridgev2.ChatMember{ + EventSender: s.makeEventSender(*memberACI), + Membership: event.MembershipLeave, + PrevMembership: event.MembershipKnock, + }) + } + for _, member := range groupChange.AddBannedMembers { + if member.ServiceID.Type != libsignalgo.ServiceIDTypeACI { + continue + } + mc = append(mc, bridgev2.ChatMember{ + EventSender: s.makeEventSender(member.ServiceID.UUID), + Membership: event.MembershipBan, + }) + } + for _, memberServiceID := range groupChange.DeleteBannedMembers { + if memberServiceID.Type != libsignalgo.ServiceIDTypeACI { + continue + } + mc = append(mc, bridgev2.ChatMember{ + EventSender: s.makeEventSender(memberServiceID.UUID), + Membership: event.MembershipLeave, + PrevMembership: event.MembershipBan, + }) + } + if len(mc) > 0 || pls != nil { + ic.MemberChanges = &bridgev2.ChatMemberList{Members: mc, PowerLevels: pls} + } return ic } From 7196535e29a20a116144a2673ca15142ccdf0576 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Fri, 28 Jun 2024 19:34:18 +0300 Subject: [PATCH 089/580] v2: add call start/end notices --- pkg/connector/chatinfo.go | 2 +- pkg/connector/handlematrix.go | 4 ++-- pkg/connector/handlesignal.go | 40 +++++++++++++++++++++++++++++++++++ pkg/connector/id.go | 2 +- pkg/connector/msgconvproxy.go | 2 +- 5 files changed, 45 insertions(+), 5 deletions(-) diff --git a/pkg/connector/chatinfo.go b/pkg/connector/chatinfo.go index 79b253d..30dc546 100644 --- a/pkg/connector/chatinfo.go +++ b/pkg/connector/chatinfo.go @@ -49,7 +49,7 @@ func (s *SignalClient) GetUserInfo(ctx context.Context, ghost *bridgev2.Ghost) ( } func (s *SignalClient) GetChatInfo(ctx context.Context, portal *bridgev2.Portal) (*bridgev2.PortalInfo, error) { - userID, groupID, err := s.parsePortalID(portal.ID) + userID, groupID, err := parsePortalID(portal.ID) if err != nil { return nil, err } diff --git a/pkg/connector/handlematrix.go b/pkg/connector/handlematrix.go index 052428f..a3203cc 100644 --- a/pkg/connector/handlematrix.go +++ b/pkg/connector/handlematrix.go @@ -36,7 +36,7 @@ import ( ) func (s *SignalClient) sendMessage(ctx context.Context, portalID networkid.PortalID, content *signalpb.Content) error { - userID, groupID, err := s.parsePortalID(portalID) + userID, groupID, err := parsePortalID(portalID) if err != nil { return err } @@ -277,7 +277,7 @@ func (s *SignalClient) HandleMatrixReadReceipt(ctx context.Context, receipt *bri } func (s *SignalClient) HandleMatrixTyping(ctx context.Context, typing *bridgev2.MatrixTyping) error { - userID, _, err := s.parsePortalID(typing.Portal.ID) + userID, _, err := parsePortalID(typing.Portal.ID) if err != nil { return err } diff --git a/pkg/connector/handlesignal.go b/pkg/connector/handlesignal.go index 768b69c..f4e4cb0 100644 --- a/pkg/connector/handlesignal.go +++ b/pkg/connector/handlesignal.go @@ -27,6 +27,7 @@ import ( "maunium.net/go/mautrix/bridgev2" "maunium.net/go/mautrix/bridgev2/database" "maunium.net/go/mautrix/bridgev2/networkid" + "maunium.net/go/mautrix/event" "go.mau.fi/mautrix-signal/pkg/signalmeow/events" signalpb "go.mau.fi/mautrix-signal/pkg/signalmeow/protobuf" @@ -42,6 +43,7 @@ func (s *SignalClient) handleSignalEvent(rawEvt events.SignalEvent) { case *events.ReadSelf: s.handleSignalReadSelf(evt) case *events.Call: + s.Main.Bridge.QueueRemoteEvent(s.UserLogin, s.wrapCallEvent(evt)) case *events.ContactList: s.handleSignalContactList(evt) case *events.ACIFound: @@ -49,6 +51,44 @@ func (s *SignalClient) handleSignalEvent(rawEvt events.SignalEvent) { } } +func (s *SignalClient) wrapCallEvent(evt *events.Call) bridgev2.RemoteMessage { + return &bridgev2.SimpleRemoteEvent[*events.Call]{ + Type: bridgev2.RemoteEventMessage, + LogContext: func(c zerolog.Context) zerolog.Context { + c = c.Stringer("sender_id", evt.Info.Sender) + c = c.Uint64("message_ts", evt.Timestamp) + return c + }, + PortalKey: s.makePortalKey(evt.Info.ChatID), + Data: evt, + CreatePortal: true, + ID: makeMessageID(evt.Info.Sender, evt.Timestamp), + Sender: s.makeEventSender(evt.Info.Sender), + Timestamp: time.UnixMilli(int64(evt.Timestamp)), + ConvertMessageFunc: convertCallEvent, + } +} + +func convertCallEvent(ctx context.Context, portal *bridgev2.Portal, intent bridgev2.MatrixAPI, data *events.Call) (*bridgev2.ConvertedMessage, error) { + content := &event.MessageEventContent{ + MsgType: event.MsgNotice, + } + if data.IsRinging { + content.Body = "Incoming call" + if userID, _, _ := parsePortalID(portal.ID); !userID.IsEmpty() { + content.MsgType = event.MsgText + } + } else { + content.Body = "Call ended" + } + return &bridgev2.ConvertedMessage{ + Parts: []*bridgev2.ConvertedMessagePart{{ + Type: event.EventMessage, + Content: content, + }}, + }, nil +} + type Bv2ChatEvent struct { *events.ChatEvent s *SignalClient diff --git a/pkg/connector/id.go b/pkg/connector/id.go index 147b21f..6aa4f82 100644 --- a/pkg/connector/id.go +++ b/pkg/connector/id.go @@ -44,7 +44,7 @@ func parseUserIDAsServiceID(userID networkid.UserID) (libsignalgo.ServiceID, err return libsignalgo.ServiceIDFromString(string(userID)) } -func (s *SignalClient) parsePortalID(portalID networkid.PortalID) (userID libsignalgo.ServiceID, groupID types.GroupIdentifier, err error) { +func parsePortalID(portalID networkid.PortalID) (userID libsignalgo.ServiceID, groupID types.GroupIdentifier, err error) { if len(portalID) == 44 { groupID = types.GroupIdentifier(portalID) } else { diff --git a/pkg/connector/msgconvproxy.go b/pkg/connector/msgconvproxy.go index 8ffeb6f..c8d97a4 100644 --- a/pkg/connector/msgconvproxy.go +++ b/pkg/connector/msgconvproxy.go @@ -85,7 +85,7 @@ func (mpm *msgconvPortalMethods) GetClient(ctx context.Context) *signalmeow.Clie func (mpm *msgconvPortalMethods) GetData(ctx context.Context) *legacydb.Portal { mcCtx := ctx.Value(msgconvContextKey).(*msgconvContext) portal := mcCtx.Portal - userID, groupID, _ := mcCtx.Client.parsePortalID(portal.ID) + userID, groupID, _ := parsePortalID(portal.ID) chatID := string(groupID) if chatID == "" { chatID = userID.String() From 5883ade9d881015902ec001fce5b0d5178f9f897 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Fri, 28 Jun 2024 23:13:52 +0300 Subject: [PATCH 090/580] v2: add support for changing group name/avatar/topic from Matrix --- go.mod | 2 +- go.sum | 4 +- pkg/connector/client.go | 3 ++ pkg/connector/handlematrix.go | 78 ++++++++++++++++++++++++++++++++++- 4 files changed, 82 insertions(+), 5 deletions(-) diff --git a/go.mod b/go.mod index b4f8e16..16d31e0 100644 --- a/go.mod +++ b/go.mod @@ -19,7 +19,7 @@ require ( golang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8 golang.org/x/net v0.26.0 google.golang.org/protobuf v1.34.2 - maunium.net/go/mautrix v0.19.0-beta.1.0.20240628154312-d7251a4c6950 + maunium.net/go/mautrix v0.19.0-beta.1.0.20240628200158-86ac5c340b35 nhooyr.io/websocket v1.8.11 ) diff --git a/go.sum b/go.sum index 8ae9f4b..6a6b6f9 100644 --- a/go.sum +++ b/go.sum @@ -93,7 +93,7 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= maunium.net/go/mauflag v1.0.0 h1:YiaRc0tEI3toYtJMRIfjP+jklH45uDHtT80nUamyD4M= maunium.net/go/mauflag v1.0.0/go.mod h1:nLivPOpTpHnpzEh8jEdSL9UqO9+/KBJFmNRlwKfkPeA= -maunium.net/go/mautrix v0.19.0-beta.1.0.20240628154312-d7251a4c6950 h1:A43PQ5ltou4KhcCMxZz1gb3QXrhOjVKweYDW5YQ/Gok= -maunium.net/go/mautrix v0.19.0-beta.1.0.20240628154312-d7251a4c6950/go.mod h1:eu/C1dTewrW7yiFNiCKGm4zuWJANyt7zPjaY5g3f3r4= +maunium.net/go/mautrix v0.19.0-beta.1.0.20240628200158-86ac5c340b35 h1:ghI1MLQc4JS0ov31rpjuHrCwqVP7b+4wZfwXsD/5i0k= +maunium.net/go/mautrix v0.19.0-beta.1.0.20240628200158-86ac5c340b35/go.mod h1:eu/C1dTewrW7yiFNiCKGm4zuWJANyt7zPjaY5g3f3r4= nhooyr.io/websocket v1.8.11 h1:f/qXNc2/3DpoSZkHt1DQu6rj4zGC8JmkkLkWss0MgN0= nhooyr.io/websocket v1.8.11/go.mod h1:rN9OFWIUwuxg4fR5tELlYC04bXYowCP9GX47ivo2l+c= diff --git a/pkg/connector/client.go b/pkg/connector/client.go index 285e207..0b92901 100644 --- a/pkg/connector/client.go +++ b/pkg/connector/client.go @@ -53,6 +53,9 @@ var ( _ bridgev2.IdentifierResolvingNetworkAPI = (*SignalClient)(nil) _ bridgev2.GroupCreatingNetworkAPI = (*SignalClient)(nil) _ bridgev2.ContactListingNetworkAPI = (*SignalClient)(nil) + _ bridgev2.RoomNameHandlingNetworkAPI = (*SignalClient)(nil) + _ bridgev2.RoomAvatarHandlingNetworkAPI = (*SignalClient)(nil) + _ bridgev2.RoomTopicHandlingNetworkAPI = (*SignalClient)(nil) ) var pushCfg = &bridgev2.PushConfig{ diff --git a/pkg/connector/handlematrix.go b/pkg/connector/handlematrix.go index a3203cc..41b5ecd 100644 --- a/pkg/connector/handlematrix.go +++ b/pkg/connector/handlematrix.go @@ -18,6 +18,7 @@ package connector import ( "context" + "crypto/sha256" "errors" "fmt" "time" @@ -286,8 +287,81 @@ func (s *SignalClient) HandleMatrixTyping(ctx context.Context, typing *bridgev2. if !userID.IsEmpty() && userID.Type == libsignalgo.ServiceIDTypeACI { typingMessage := signalmeow.TypingMessage(typing.IsTyping) result := s.Client.SendMessage(ctx, userID, typingMessage) - fmt.Println(result) - // TODO check result + if !result.WasSuccessful { + return result.Error + } } return nil } + +func (s *SignalClient) handleMatrixRoomMeta(ctx context.Context, portal *bridgev2.Portal, gc *signalmeow.GroupChange, postUpdatePortal func()) (bool, error) { + _, groupID, err := parsePortalID(portal.ID) + if err != nil || groupID == "" { + return false, err + } + rev, ok := database.GetNumberFromMap[uint32](portal.Metadata.Extra, "revision") + if !ok { + return false, fmt.Errorf("missing revision in portal metadata") + } + gc.Revision = rev + 1 + revision, err := s.Client.UpdateGroup(ctx, gc, groupID) + if err != nil { + return false, err + } + if gc.ModifyTitle != nil { + portal.Name = *gc.ModifyTitle + portal.NameSet = true + } + if gc.ModifyDescription != nil { + portal.Topic = *gc.ModifyDescription + portal.TopicSet = true + } + if gc.ModifyAvatar != nil { + portal.AvatarID = makeAvatarPathID(*gc.ModifyAvatar) + portal.AvatarSet = true + } + if postUpdatePortal != nil { + postUpdatePortal() + } + portal.Metadata.Extra["revision"] = revision + return true, nil +} + +func (s *SignalClient) HandleMatrixRoomName(ctx context.Context, msg *bridgev2.MatrixRoomName) (bool, error) { + return s.handleMatrixRoomMeta(ctx, msg.Portal, &signalmeow.GroupChange{ + ModifyTitle: &msg.Content.Name, + }, nil) +} + +func (s *SignalClient) HandleMatrixRoomAvatar(ctx context.Context, msg *bridgev2.MatrixRoomAvatar) (bool, error) { + _, groupID, err := parsePortalID(msg.Portal.ID) + if err != nil || groupID == "" { + return false, err + } + var avatarPath string + var avatarHash [32]byte + if msg.Content.URL != "" { + data, err := s.Main.Bridge.Bot.DownloadMedia(ctx, msg.Content.URL, nil) + if err != nil { + return false, fmt.Errorf("failed to download avatar: %w", err) + } + avatarHash = sha256.Sum256(data) + avatarPathPtr, err := s.Client.UploadGroupAvatar(ctx, data, groupID) + if err != nil { + return false, fmt.Errorf("failed to reupload avatar: %w", err) + } + avatarPath = *avatarPathPtr + } + return s.handleMatrixRoomMeta(ctx, msg.Portal, &signalmeow.GroupChange{ + ModifyAvatar: &avatarPath, + }, func() { + msg.Portal.AvatarMXC = msg.Content.URL + msg.Portal.AvatarHash = avatarHash + }) +} + +func (s *SignalClient) HandleMatrixRoomTopic(ctx context.Context, msg *bridgev2.MatrixRoomTopic) (bool, error) { + return s.handleMatrixRoomMeta(ctx, msg.Portal, &signalmeow.GroupChange{ + ModifyDescription: &msg.Content.Topic, + }, nil) +} From 1bc7b100ee1a341b12ef483e52cd9c14292673d3 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Fri, 28 Jun 2024 23:17:39 +0300 Subject: [PATCH 091/580] pre-commit: add local imports flag --- .pre-commit-config.yaml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 064e948..b22a061 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -13,6 +13,10 @@ repos: hooks: - id: go-imports exclude: "pb\\.go$" + args: + - "-local" + - "go.mau.fi/mautrix-signal" + - "-w" - id: go-vet-mod #- id: go-staticcheck-repo-mod # TODO: reenable this and fix all the problems From 96724bd9dcdb476fc5a6003fd3b6dbe2e2d7db78 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Fri, 28 Jun 2024 23:48:52 +0300 Subject: [PATCH 092/580] libsignalgo: update libsignal to v0.52.0 --- pkg/libsignalgo/libsignal | 2 +- pkg/libsignalgo/libsignal-ffi.h | 56 ++++++++++++++++----------------- pkg/libsignalgo/version.go | 2 +- 3 files changed, 30 insertions(+), 30 deletions(-) diff --git a/pkg/libsignalgo/libsignal b/pkg/libsignalgo/libsignal index 95bf4e7..e13e3de 160000 --- a/pkg/libsignalgo/libsignal +++ b/pkg/libsignalgo/libsignal @@ -1 +1 @@ -Subproject commit 95bf4e77155b5110e80a8d140cce7adaef8aa0ac +Subproject commit e13e3de8b25c8204b9bb5f04cc50dd12e7f40fc3 diff --git a/pkg/libsignalgo/libsignal-ffi.h b/pkg/libsignalgo/libsignal-ffi.h index bd99f60..0e5e893 100644 --- a/pkg/libsignalgo/libsignal-ffi.h +++ b/pkg/libsignalgo/libsignal-ffi.h @@ -1228,6 +1228,18 @@ SignalFfiError *signal_device_transfer_generate_certificate(SignalOwnedBuffer *o SignalFfiError *signal_cds2_client_state_new(SignalSgxClientState **out, SignalBorrowedBuffer mrenclave, SignalBorrowedBuffer attestation_msg, uint64_t current_timestamp); +SignalFfiError *signal_hsm_enclave_client_destroy(SignalHsmEnclaveClient *p); + +SignalFfiError *signal_hsm_enclave_client_new(SignalHsmEnclaveClient **out, SignalBorrowedBuffer trusted_public_key, SignalBorrowedBuffer trusted_code_hashes); + +SignalFfiError *signal_hsm_enclave_client_complete_handshake(SignalHsmEnclaveClient *cli, SignalBorrowedBuffer handshake_received); + +SignalFfiError *signal_hsm_enclave_client_established_send(SignalOwnedBuffer *out, SignalHsmEnclaveClient *cli, SignalBorrowedBuffer plaintext_to_send); + +SignalFfiError *signal_hsm_enclave_client_established_recv(SignalOwnedBuffer *out, SignalHsmEnclaveClient *cli, SignalBorrowedBuffer received_ciphertext); + +SignalFfiError *signal_hsm_enclave_client_initial_request(SignalOwnedBuffer *out, const SignalHsmEnclaveClient *obj); + SignalFfiError *signal_sgx_client_state_destroy(SignalSgxClientState *p); SignalFfiError *signal_sgx_client_state_initial_request(SignalOwnedBuffer *out, const SignalSgxClientState *obj); @@ -1238,18 +1250,6 @@ SignalFfiError *signal_sgx_client_state_established_send(SignalOwnedBuffer *out, SignalFfiError *signal_sgx_client_state_established_recv(SignalOwnedBuffer *out, SignalSgxClientState *cli, SignalBorrowedBuffer received_ciphertext); -SignalFfiError *signal_hsm_enclave_client_destroy(SignalHsmEnclaveClient *p); - -SignalFfiError *signal_hsm_enclave_client_new(SignalHsmEnclaveClient **out, SignalBorrowedBuffer trusted_public_key, SignalBorrowedBuffer trusted_code_hashes); - -SignalFfiError *signal_hsm_enclave_client_initial_request(SignalOwnedBuffer *out, const SignalHsmEnclaveClient *obj); - -SignalFfiError *signal_hsm_enclave_client_complete_handshake(SignalHsmEnclaveClient *cli, SignalBorrowedBuffer handshake_received); - -SignalFfiError *signal_hsm_enclave_client_established_send(SignalOwnedBuffer *out, SignalHsmEnclaveClient *cli, SignalBorrowedBuffer plaintext_to_send); - -SignalFfiError *signal_hsm_enclave_client_established_recv(SignalOwnedBuffer *out, SignalHsmEnclaveClient *cli, SignalBorrowedBuffer received_ciphertext); - SignalFfiError *signal_expiring_profile_key_credential_check_valid_contents(SignalBorrowedBuffer buffer); SignalFfiError *signal_expiring_profile_key_credential_response_check_valid_contents(SignalBorrowedBuffer buffer); @@ -1510,14 +1510,14 @@ SignalFfiError *signal_group_send_full_token_verify(SignalBorrowedBuffer token, SignalFfiError *signal_verify_signature(bool *out, SignalBorrowedBuffer cert_pem, SignalBorrowedBuffer body, SignalBorrowedBuffer signature, uint64_t current_timestamp); +SignalFfiError *signal_connection_manager_destroy(SignalConnectionManager *p); + SignalFfiError *signal_connection_manager_new(SignalConnectionManager **out, uint8_t environment, const char *user_agent); SignalFfiError *signal_connection_manager_set_proxy(const SignalConnectionManager *connection_manager, const char *host, int32_t port); SignalFfiError *signal_connection_manager_clear_proxy(const SignalConnectionManager *connection_manager); -SignalFfiError *signal_connection_manager_destroy(SignalConnectionManager *p); - SignalFfiError *signal_create_otp(const char **out, const char *username, SignalBorrowedBuffer secret); SignalFfiError *signal_create_otp_from_base64(const char **out, const char *username, const char *secret); @@ -1528,6 +1528,8 @@ SignalFfiError *signal_svr3_restore(SignalCPromiseOwnedBufferOfc_uchar *promise, SignalFfiError *signal_svr3_remove(SignalCPromisebool *promise, const SignalTokioAsyncContext *async_runtime, const SignalConnectionManager *connection_manager, const char *username, const char *enclave_password); +SignalFfiError *signal_lookup_request_destroy(SignalLookupRequest *p); + SignalFfiError *signal_lookup_request_new(SignalLookupRequest **out); SignalFfiError *signal_lookup_request_add_e164(const SignalLookupRequest *request, const char *e164); @@ -1540,8 +1542,6 @@ SignalFfiError *signal_lookup_request_add_aci_and_access_key(const SignalLookupR SignalFfiError *signal_lookup_request_set_return_acis_without_uaks(const SignalLookupRequest *request, bool return_acis_without_uaks); -SignalFfiError *signal_lookup_request_destroy(SignalLookupRequest *p); - SignalFfiError *signal_cdsi_lookup_destroy(SignalCdsiLookup *p); SignalFfiError *signal_cdsi_lookup_new(SignalCPromiseCdsiLookup *promise, const SignalTokioAsyncContext *async_runtime, const SignalConnectionManager *connection_manager, const char *username, const char *password, const SignalLookupRequest *request); @@ -1610,10 +1610,10 @@ SignalFfiError *signal_pin_verify_local_hash(bool *out, const char *encoded_hash SignalFfiError *signal_svr2_client_new(SignalSgxClientState **out, SignalBorrowedBuffer mrenclave, SignalBorrowedBuffer attestation_msg, uint64_t current_timestamp); -SignalFfiError *signal_incremental_mac_calculate_chunk_size(uint32_t *out, uint32_t data_size); - SignalFfiError *signal_incremental_mac_destroy(SignalIncrementalMac *p); +SignalFfiError *signal_incremental_mac_calculate_chunk_size(uint32_t *out, uint32_t data_size); + SignalFfiError *signal_incremental_mac_initialize(SignalIncrementalMac **out, SignalBorrowedBuffer key, uint32_t chunk_size); SignalFfiError *signal_incremental_mac_update(SignalOwnedBuffer *out, SignalIncrementalMac *mac, SignalBorrowedBuffer bytes, uint32_t offset, uint32_t length); @@ -1630,10 +1630,10 @@ SignalFfiError *signal_validating_mac_finalize(int32_t *out, SignalValidatingMac SignalFfiError *signal_message_backup_key_destroy(SignalMessageBackupKey *p); -SignalFfiError *signal_message_backup_key_new(SignalMessageBackupKey **out, const uint8_t (*master_key)[32], const SignalServiceIdFixedWidthBinaryBytes *aci); - SignalFfiError *signal_message_backup_validation_outcome_destroy(SignalMessageBackupValidationOutcome *p); +SignalFfiError *signal_message_backup_key_new(SignalMessageBackupKey **out, const uint8_t (*master_key)[32], const SignalServiceIdFixedWidthBinaryBytes *aci); + SignalFfiError *signal_message_backup_validation_outcome_get_error_message(const char **out, const SignalMessageBackupValidationOutcome *outcome); SignalFfiError *signal_message_backup_validation_outcome_get_unknown_fields(SignalStringArray *out, const SignalMessageBackupValidationOutcome *outcome); @@ -1654,6 +1654,14 @@ SignalFfiError *signal_username_link_create(SignalOwnedBuffer *out, const char * SignalFfiError *signal_username_link_decrypt_username(const char **out, SignalBorrowedBuffer entropy, SignalBorrowedBuffer encrypted_username); +#if defined(SIGNAL_MEDIA_SUPPORTED) +SignalFfiError *signal_sanitized_metadata_destroy(SignalSanitizedMetadata *p); +#endif + +#if defined(SIGNAL_MEDIA_SUPPORTED) +SignalFfiError *signal_sanitized_metadata_clone(SignalSanitizedMetadata **new_obj, const SignalSanitizedMetadata *obj); +#endif + #if defined(SIGNAL_MEDIA_SUPPORTED) SignalFfiError *signal_signal_media_check_available(void); #endif @@ -1666,14 +1674,6 @@ SignalFfiError *signal_mp4_sanitizer_sanitize(SignalSanitizedMetadata **out, con SignalFfiError *signal_webp_sanitizer_sanitize(const SignalSyncInputStream *input); #endif -#if defined(SIGNAL_MEDIA_SUPPORTED) -SignalFfiError *signal_sanitized_metadata_destroy(SignalSanitizedMetadata *p); -#endif - -#if defined(SIGNAL_MEDIA_SUPPORTED) -SignalFfiError *signal_sanitized_metadata_clone(SignalSanitizedMetadata **new_obj, const SignalSanitizedMetadata *obj); -#endif - #if defined(SIGNAL_MEDIA_SUPPORTED) SignalFfiError *signal_sanitized_metadata_get_metadata(SignalOwnedBuffer *out, const SignalSanitizedMetadata *sanitized); #endif diff --git a/pkg/libsignalgo/version.go b/pkg/libsignalgo/version.go index cf2f348..8191319 100644 --- a/pkg/libsignalgo/version.go +++ b/pkg/libsignalgo/version.go @@ -2,4 +2,4 @@ package libsignalgo -const Version = "v0.51.0" +const Version = "v0.52.0" From 21282c3e6772a73e94077f14f8838779fe53bbe4 Mon Sep 17 00:00:00 2001 From: Andrew Ferrazzutti Date: Sat, 29 Jun 2024 06:20:02 +0900 Subject: [PATCH 093/580] Fix example location URL template config for OSM (#516) [skip ci] --- example-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/example-config.yaml b/example-config.yaml index 71caa9c..93a7955 100644 --- a/example-config.yaml +++ b/example-config.yaml @@ -141,7 +141,7 @@ bridge: caption_in_message: false # Format for generating URLs from location messages for sending to Signal # Google Maps: 'https://www.google.com/maps/place/%[1]s,%[2]s' - # OpenStreetMap: 'https://www.openstreetmap.org/?mlat=%[1]s&mlon=%[2]' + # OpenStreetMap: 'https://www.openstreetmap.org/?mlat=%[1]s&mlon=%[2]s' location_format: 'https://www.google.com/maps/place/%[1]s,%[2]s' # Whether or not created rooms should have federation enabled. # If false, created portal rooms will never be federated. From 97d87b5160b32079b97034466581c253bb6d919c Mon Sep 17 00:00:00 2001 From: Malte E <97891689+maltee1@users.noreply.github.com> Date: Fri, 28 Jun 2024 23:20:30 +0200 Subject: [PATCH 094/580] v1/portal: log more errors for addmember (#475) [skip ci] --- portal.go | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/portal.go b/portal.go index 0369c04..37fabe6 100644 --- a/portal.go +++ b/portal.go @@ -1018,12 +1018,15 @@ func (portal *Portal) applySignalGroupChange(ctx context.Context, source *User, } } } else { - puppet, _ = portal.sendMembershipForPuppetAndUser(ctx, sender, addMember.ACI, event.MembershipInvite, "added") + puppet, err = portal.sendMembershipForPuppetAndUser(ctx, sender, addMember.ACI, event.MembershipInvite, "added") } - if puppet != nil { - puppet.IntentFor(portal).SendCustomMembershipEvent(ctx, portal.MXID, puppet.IntentFor(portal).UserID, event.MembershipJoin, "") - } else { - log.Warn().Stringer("signal_user_id", addMember.ACI).Msg("Couldn't get puppet for invite") + if err != nil { + log.Err(err).Stringer("signal_user_id", addMember.ACI).Msg("Couldn't get puppet for invite") + return + } + _, err = puppet.IntentFor(portal).SendCustomMembershipEvent(ctx, portal.MXID, puppet.IntentFor(portal).UserID, event.MembershipJoin, "") + if err != nil { + log.Err(err).Stringer("mxid", puppet.MXID).Msg("Failed to join user") } } bannedMembers := make(map[uuid.UUID]bool) From 10eefaf92897d406949fadd9d13d470f2b4a4583 Mon Sep 17 00:00:00 2001 From: Malte E <97891689+maltee1@users.noreply.github.com> Date: Fri, 28 Jun 2024 23:21:34 +0200 Subject: [PATCH 095/580] v1: sync groups command (#490) [skip cd] --- commands.go | 73 ++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 52 insertions(+), 21 deletions(-) diff --git a/commands.go b/commands.go index e3021c0..7600d66 100644 --- a/commands.go +++ b/commands.go @@ -61,7 +61,7 @@ func (br *SignalBridge) RegisterCommands() { cmdSetDeviceName, cmdPM, cmdResolvePhone, - cmdSyncSpace, + cmdSync, cmdDeleteSession, cmdSetRelay, cmdUnsetRelay, @@ -537,18 +537,26 @@ func fnResolvePhone(ce *WrappedCommandEvent) { } } -var cmdSyncSpace = &commands.FullHandler{ - Func: wrapCommand(fnSyncSpace), - Name: "sync-space", +var cmdSync = &commands.FullHandler{ + Func: wrapCommand(fnSync), + Name: "sync", Help: commands.HelpMeta{ Section: HelpSectionMiscellaneous, - Description: "Synchronize your personal filtering space", + Description: "Synchronize Signal bridge data", + Args: "", }, RequiresLogin: true, } -func fnSyncSpace(ce *WrappedCommandEvent) { - if !ce.Bridge.Config.Bridge.PersonalFilteringSpaces { +func fnSync(ce *WrappedCommandEvent) { + args := strings.ToLower(strings.Join(ce.Args, " ")) + space := strings.Contains(args, "space") + groups := strings.Contains(args, "groups") + if !space && !groups { + ce.Reply("**Usage:** `sync `") + return + } + if !ce.Bridge.Config.Bridge.PersonalFilteringSpaces && space { ce.Reply("Personal filtering spaces are not enabled on this instance of the bridge") return } @@ -559,26 +567,49 @@ func fnSyncSpace(ce *WrappedCommandEvent) { ce.Reply("Failed to get private chat IDs from database") return } - count := 0 allPortals := ce.Bridge.GetAllPortalsWithMXID() - for _, portal := range allPortals { - if portal.IsPrivateChat() { - continue + if space { + count := 0 + for _, portal := range allPortals { + if portal.IsPrivateChat() { + continue + } + if ce.Bridge.StateStore.IsInRoom(ctx, portal.MXID, ce.User.MXID) && portal.addToPersonalSpace(ctx, ce.User) { + count++ + } } - if ce.Bridge.StateStore.IsInRoom(ctx, portal.MXID, ce.User.MXID) && portal.addToPersonalSpace(ctx, ce.User) { + for _, key := range dmKeys { + portal := ce.Bridge.GetPortalByChatID(key) + portal.addToPersonalSpace(ctx, ce.User) count++ } + plural := "s" + if count == 1 { + plural = "" + } + ce.Reply("Added %d room%s to space", count, plural) } - for _, key := range dmKeys { - portal := ce.Bridge.GetPortalByChatID(key) - portal.addToPersonalSpace(ctx, ce.User) - count++ + if groups { + count := 0 + for _, portal := range allPortals { + if portal.IsPrivateChat() { + continue + } + if ce.Bridge.StateStore.IsInRoom(ctx, portal.MXID, ce.User.MXID) { + groupInfo := portal.UpdateGroupInfo(ce.Ctx, ce.User, nil, 0, true) + if groupInfo != nil { + members := portal.SyncParticipants(ctx, ce.User, groupInfo) + portal.updatePowerLevelsAndJoinRule(ctx, groupInfo, members) + count++ + } + } + } + plural := "s" + if count == 1 { + plural = "" + } + ce.Reply("Synced %d group%s", count, plural) } - plural := "s" - if count == 1 { - plural = "" - } - ce.Reply("Added %d room%s to space", count, plural) } var cmdLogin = &commands.FullHandler{ From a3e20a8423e3b1c2f81f399e38d09fe7357a3bbe Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Sat, 29 Jun 2024 12:22:55 +0300 Subject: [PATCH 096/580] v2: copy relay user ID in legacy migration --- cmd/mautrix-signal-v2/legacymigrate.sql | 43 +++++++++++++------------ cmd/mautrix-signal-v2/main.go | 2 +- go.mod | 2 +- go.sum | 4 +-- 4 files changed, 26 insertions(+), 25 deletions(-) diff --git a/cmd/mautrix-signal-v2/legacymigrate.sql b/cmd/mautrix-signal-v2/legacymigrate.sql index 8aac4db..5e8c5ba 100644 --- a/cmd/mautrix-signal-v2/legacymigrate.sql +++ b/cmd/mautrix-signal-v2/legacymigrate.sql @@ -1,5 +1,24 @@ +INSERT INTO "user" (bridge_id, mxid, management_room, access_token) +SELECT '', mxid, management_room, NULL +FROM user_old; + +INSERT INTO user_login (bridge_id, user_mxid, id, space_room, metadata) +SELECT + '', + mxid, + cast(uuid AS TEXT), + space_room, + CAST( + '{"phone":"' || phone || '","remote_name":"' || phone || '"}' + -- only: postgres + AS jsonb + -- only: sqlite (line commented) +-- AS text + ) +FROM user_old WHERE uuid IS NOT NULL AND phone IS NOT NULL; + INSERT INTO portal ( - bridge_id, id, receiver, mxid, parent_id, parent_receiver, + bridge_id, id, receiver, mxid, parent_id, parent_receiver, relay_bridge_id, relay_login_id, name, topic, avatar_id, avatar_hash, avatar_mxc, name_set, avatar_set, topic_set, in_space, metadata ) @@ -13,6 +32,8 @@ SELECT mxid, NULL, -- parent_id '', -- parent_receiver + CASE WHEN portal_old.relay_user_id<>'' THEN '' END, -- relay_bridge_id + CASE WHEN portal_old.relay_user_id<>'' THEN portal_old.relay_user_id END, -- relay_login_id name, topic, CASE @@ -37,7 +58,6 @@ SELECT -- only: sqlite (line commented) -- AS text ) -- metadata - -- TODO migrate relay user id FROM portal_old; INSERT INTO ghost ( @@ -126,25 +146,6 @@ SELECT ) -- metadata FROM reaction_old; -INSERT INTO "user" (bridge_id, mxid, management_room, access_token) -SELECT '', mxid, management_room, NULL -FROM user_old; - -INSERT INTO user_login (bridge_id, user_mxid, id, space_room, metadata) -SELECT - '', - mxid, - cast(uuid AS TEXT), - space_room, - CAST( - '{"phone":"' || phone || '","remote_name":"' || phone || '"}' - -- only: postgres - AS jsonb - -- only: sqlite (line commented) --- AS text - ) -FROM user_old WHERE uuid IS NOT NULL AND phone IS NOT NULL; - INSERT INTO user_portal ( bridge_id, user_mxid, login_id, portal_id, portal_receiver, in_space, preferred, last_read ) diff --git a/cmd/mautrix-signal-v2/main.go b/cmd/mautrix-signal-v2/main.go index 0e85c38..80d2efc 100644 --- a/cmd/mautrix-signal-v2/main.go +++ b/cmd/mautrix-signal-v2/main.go @@ -51,7 +51,7 @@ func main() { 20, "v0.5.1", "v0.7.0", - m.LegacyMigrateSimple(legacyMigrateRenameTables, legacyMigrateCopyData, 2), + m.LegacyMigrateSimple(legacyMigrateRenameTables, legacyMigrateCopyData, 4), true, ) } diff --git a/go.mod b/go.mod index 16d31e0..535a7da 100644 --- a/go.mod +++ b/go.mod @@ -19,7 +19,7 @@ require ( golang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8 golang.org/x/net v0.26.0 google.golang.org/protobuf v1.34.2 - maunium.net/go/mautrix v0.19.0-beta.1.0.20240628200158-86ac5c340b35 + maunium.net/go/mautrix v0.19.0-beta.1.0.20240629130130-2b668652aba5 nhooyr.io/websocket v1.8.11 ) diff --git a/go.sum b/go.sum index 6a6b6f9..30198cf 100644 --- a/go.sum +++ b/go.sum @@ -93,7 +93,7 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= maunium.net/go/mauflag v1.0.0 h1:YiaRc0tEI3toYtJMRIfjP+jklH45uDHtT80nUamyD4M= maunium.net/go/mauflag v1.0.0/go.mod h1:nLivPOpTpHnpzEh8jEdSL9UqO9+/KBJFmNRlwKfkPeA= -maunium.net/go/mautrix v0.19.0-beta.1.0.20240628200158-86ac5c340b35 h1:ghI1MLQc4JS0ov31rpjuHrCwqVP7b+4wZfwXsD/5i0k= -maunium.net/go/mautrix v0.19.0-beta.1.0.20240628200158-86ac5c340b35/go.mod h1:eu/C1dTewrW7yiFNiCKGm4zuWJANyt7zPjaY5g3f3r4= +maunium.net/go/mautrix v0.19.0-beta.1.0.20240629130130-2b668652aba5 h1:OtQxTxVhivW4U6VC0UhGZINemqePLigA70ot2p+zp6I= +maunium.net/go/mautrix v0.19.0-beta.1.0.20240629130130-2b668652aba5/go.mod h1:eu/C1dTewrW7yiFNiCKGm4zuWJANyt7zPjaY5g3f3r4= nhooyr.io/websocket v1.8.11 h1:f/qXNc2/3DpoSZkHt1DQu6rj4zGC8JmkkLkWss0MgN0= nhooyr.io/websocket v1.8.11/go.mod h1:rN9OFWIUwuxg4fR5tELlYC04bXYowCP9GX47ivo2l+c= From b2c1efc85c9d90a015d0dc15bba05c0325dc9208 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Sun, 30 Jun 2024 00:15:37 +0300 Subject: [PATCH 097/580] v2: update mautrix-go --- go.mod | 2 +- go.sum | 4 ++-- pkg/connector/handlesignal.go | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/go.mod b/go.mod index 535a7da..0a81303 100644 --- a/go.mod +++ b/go.mod @@ -19,7 +19,7 @@ require ( golang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8 golang.org/x/net v0.26.0 google.golang.org/protobuf v1.34.2 - maunium.net/go/mautrix v0.19.0-beta.1.0.20240629130130-2b668652aba5 + maunium.net/go/mautrix v0.19.0-beta.1.0.20240629212545-63c49bf8400d nhooyr.io/websocket v1.8.11 ) diff --git a/go.sum b/go.sum index 30198cf..af4e6a3 100644 --- a/go.sum +++ b/go.sum @@ -93,7 +93,7 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= maunium.net/go/mauflag v1.0.0 h1:YiaRc0tEI3toYtJMRIfjP+jklH45uDHtT80nUamyD4M= maunium.net/go/mauflag v1.0.0/go.mod h1:nLivPOpTpHnpzEh8jEdSL9UqO9+/KBJFmNRlwKfkPeA= -maunium.net/go/mautrix v0.19.0-beta.1.0.20240629130130-2b668652aba5 h1:OtQxTxVhivW4U6VC0UhGZINemqePLigA70ot2p+zp6I= -maunium.net/go/mautrix v0.19.0-beta.1.0.20240629130130-2b668652aba5/go.mod h1:eu/C1dTewrW7yiFNiCKGm4zuWJANyt7zPjaY5g3f3r4= +maunium.net/go/mautrix v0.19.0-beta.1.0.20240629212545-63c49bf8400d h1:hKmeOEHr6woCQCDhq8nzT0ekuCRGelx3k5FDo2+DD34= +maunium.net/go/mautrix v0.19.0-beta.1.0.20240629212545-63c49bf8400d/go.mod h1:eu/C1dTewrW7yiFNiCKGm4zuWJANyt7zPjaY5g3f3r4= nhooyr.io/websocket v1.8.11 h1:f/qXNc2/3DpoSZkHt1DQu6rj4zGC8JmkkLkWss0MgN0= nhooyr.io/websocket v1.8.11/go.mod h1:rN9OFWIUwuxg4fR5tELlYC04bXYowCP9GX47ivo2l+c= diff --git a/pkg/connector/handlesignal.go b/pkg/connector/handlesignal.go index f4e4cb0..993d23f 100644 --- a/pkg/connector/handlesignal.go +++ b/pkg/connector/handlesignal.go @@ -431,7 +431,7 @@ func (s *SignalClient) handleSignalReceipt(evt *events.Receipt) { Logger() ctx := log.WithContext(context.TODO()) receipts := convertReceipts(ctx, evt.Content.Timestamp, func(ctx context.Context, msgTS uint64) (*database.Message, error) { - return s.Main.Bridge.DB.Message.GetFirstPartByID(ctx, makeMessageID(s.Client.Store.ACI, msgTS)) + return s.Main.Bridge.DB.Message.GetFirstPartByID(ctx, s.UserLogin.ID, makeMessageID(s.Client.Store.ACI, msgTS)) }) s.dispatchReceipts(evt.Sender, evt.Content.GetType(), receipts) } @@ -446,7 +446,7 @@ func (s *SignalClient) handleSignalReadSelf(evt *events.ReadSelf) { if err != nil { return nil, err } - return s.Main.Bridge.DB.Message.GetFirstPartByID(ctx, makeMessageID(aciUUID, msgInfo.GetTimestamp())) + return s.Main.Bridge.DB.Message.GetFirstPartByID(ctx, s.UserLogin.ID, makeMessageID(aciUUID, msgInfo.GetTimestamp())) }) s.dispatchReceipts(s.Client.Store.ACI, signalpb.ReceiptMessage_READ, receipts) } From 85f3c153767cef5449189e9d01cb93437723b399 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Sun, 7 Jul 2024 15:33:41 +0300 Subject: [PATCH 098/580] v2: use improved NewLogin function --- go.mod | 6 +++--- go.sum | 12 +++++------ pkg/connector/login.go | 48 ++++++++++++------------------------------ 3 files changed, 23 insertions(+), 43 deletions(-) diff --git a/go.mod b/go.mod index 0a81303..e7cb76e 100644 --- a/go.mod +++ b/go.mod @@ -14,12 +14,12 @@ require ( github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e github.com/stretchr/testify v1.9.0 github.com/tidwall/gjson v1.17.1 - go.mau.fi/util v0.5.1-0.20240626184357-b3f4d78c25cf + go.mau.fi/util v0.5.1-0.20240702170310-bd1da3c069eb golang.org/x/crypto v0.24.0 golang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8 golang.org/x/net v0.26.0 google.golang.org/protobuf v1.34.2 - maunium.net/go/mautrix v0.19.0-beta.1.0.20240629212545-63c49bf8400d + maunium.net/go/mautrix v0.19.0-beta.1.0.20240706124659-b4057a26c3ed nhooyr.io/websocket v1.8.11 ) @@ -40,7 +40,7 @@ require ( github.com/tidwall/match v1.1.1 // indirect github.com/tidwall/pretty v1.2.0 // indirect github.com/tidwall/sjson v1.2.5 // indirect - github.com/yuin/goldmark v1.7.2 // indirect + github.com/yuin/goldmark v1.7.4 // indirect go.mau.fi/zeroconfig v0.1.2 // indirect golang.org/x/sys v0.21.0 // indirect gopkg.in/natefinch/lumberjack.v2 v2.2.1 // indirect diff --git a/go.sum b/go.sum index af4e6a3..45caa46 100644 --- a/go.sum +++ b/go.sum @@ -65,10 +65,10 @@ github.com/tidwall/pretty v1.2.0 h1:RWIZEg2iJ8/g6fDDYzMpobmaoGh5OLl4AXtGUGPcqCs= github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU= github.com/tidwall/sjson v1.2.5 h1:kLy8mja+1c9jlljvWTlSazM7cKDRfJuR/bOJhcY5NcY= github.com/tidwall/sjson v1.2.5/go.mod h1:Fvgq9kS/6ociJEDnK0Fk1cpYF4FIW6ZF7LAe+6jwd28= -github.com/yuin/goldmark v1.7.2 h1:NjGd7lO7zrUn/A7eKwn5PEOt4ONYGqpxSEeZuduvgxc= -github.com/yuin/goldmark v1.7.2/go.mod h1:uzxRWxtg69N339t3louHJ7+O03ezfj6PlliRlaOzY1E= -go.mau.fi/util v0.5.1-0.20240626184357-b3f4d78c25cf h1:ceXQTB6IqjqGBGhzOTEBGbxQu7xDyuT9YR06gxr9Ncw= -go.mau.fi/util v0.5.1-0.20240626184357-b3f4d78c25cf/go.mod h1:DsJzUrJAG53lCZnnYvq9/mOyLuPScWwYhvETiTrpdP4= +github.com/yuin/goldmark v1.7.4 h1:BDXOHExt+A7gwPCJgPIIq7ENvceR7we7rOS9TNoLZeg= +github.com/yuin/goldmark v1.7.4/go.mod h1:uzxRWxtg69N339t3louHJ7+O03ezfj6PlliRlaOzY1E= +go.mau.fi/util v0.5.1-0.20240702170310-bd1da3c069eb h1:VZPo2pvfjNj6fkFv5e9FyTYx96BLwwYNA19WYaY+KN8= +go.mau.fi/util v0.5.1-0.20240702170310-bd1da3c069eb/go.mod h1:DsJzUrJAG53lCZnnYvq9/mOyLuPScWwYhvETiTrpdP4= go.mau.fi/zeroconfig v0.1.2 h1:DKOydWnhPMn65GbXZOafgkPm11BvFashZWLct0dGFto= go.mau.fi/zeroconfig v0.1.2/go.mod h1:NcSJkf180JT+1IId76PcMuLTNa1CzsFFZ0nBygIQM70= golang.org/x/crypto v0.24.0 h1:mnl8DM0o513X8fdIkmyFE/5hTYxbwYOjDS/+rK6qpRI= @@ -93,7 +93,7 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= maunium.net/go/mauflag v1.0.0 h1:YiaRc0tEI3toYtJMRIfjP+jklH45uDHtT80nUamyD4M= maunium.net/go/mauflag v1.0.0/go.mod h1:nLivPOpTpHnpzEh8jEdSL9UqO9+/KBJFmNRlwKfkPeA= -maunium.net/go/mautrix v0.19.0-beta.1.0.20240629212545-63c49bf8400d h1:hKmeOEHr6woCQCDhq8nzT0ekuCRGelx3k5FDo2+DD34= -maunium.net/go/mautrix v0.19.0-beta.1.0.20240629212545-63c49bf8400d/go.mod h1:eu/C1dTewrW7yiFNiCKGm4zuWJANyt7zPjaY5g3f3r4= +maunium.net/go/mautrix v0.19.0-beta.1.0.20240706124659-b4057a26c3ed h1:3F4YHSFaUJ9N0l4zNGeXZvnTBIHC9PDVOWOFiOvNn3Y= +maunium.net/go/mautrix v0.19.0-beta.1.0.20240706124659-b4057a26c3ed/go.mod h1:bNQrvIftiwJ+7OjSh+Gza5xcncq1ooHk6oyDWq4B4sg= nhooyr.io/websocket v1.8.11 h1:f/qXNc2/3DpoSZkHt1DQu6rj4zGC8JmkkLkWss0MgN0= nhooyr.io/websocket v1.8.11/go.mod h1:rN9OFWIUwuxg4fR5tELlYC04bXYowCP9GX47ivo2l+c= diff --git a/pkg/connector/login.go b/pkg/connector/login.go index 24cbcd7..3a58312 100644 --- a/pkg/connector/login.go +++ b/pkg/connector/login.go @@ -21,7 +21,6 @@ import ( "fmt" "github.com/google/uuid" - "maunium.net/go/mautrix/bridge/status" "maunium.net/go/mautrix/bridgev2" "maunium.net/go/mautrix/bridgev2/database" @@ -157,42 +156,23 @@ func (qr *QRLogin) processingWait(ctx context.Context) (*bridgev2.LoginStep, err return nil, ctx.Err() } - ul, err := qr.Main.Bridge.GetExistingUserLoginByID(ctx, newLoginID) - if err != nil { - return nil, fmt.Errorf("failed to get existing login: %w", err) - } - if ul != nil && ul.UserMXID != qr.User.MXID { - ul.Delete(ctx, status.BridgeState{StateEvent: status.StateLoggedOut, Error: "overridden-by-another-user"}, false) - ul = nil - } - if ul == nil { - ul, err = qr.User.NewLogin(ctx, &database.UserLogin{ - ID: newLoginID, - Metadata: database.UserLoginMetadata{ - StandardUserLoginMetadata: database.StandardUserLoginMetadata{ - RemoteName: qr.ProvData.Number, - }, - Extra: map[string]any{ - "phone": qr.ProvData.Number, - }, + ul, err := qr.User.NewLogin(ctx, &database.UserLogin{ + ID: newLoginID, + Metadata: database.UserLoginMetadata{ + StandardUserLoginMetadata: database.StandardUserLoginMetadata{ + RemoteName: qr.ProvData.Number, }, - }, nil) - if err != nil { - return nil, fmt.Errorf("failed to save new login: %w", err) - } - } else { - ul.Metadata.Extra["phone"] = qr.ProvData.Number - ul.Metadata.RemoteName = qr.ProvData.Number - err = ul.Save(ctx) - if err != nil { - return nil, fmt.Errorf("failed to update existing login: %w", err) - } + Extra: map[string]any{ + "phone": qr.ProvData.Number, + }, + }, + }, &bridgev2.NewLoginParams{ + DeleteOnConflict: true, + }) + if err != nil { + return nil, fmt.Errorf("failed to create user login: %w", err) } backgroundCtx := ul.Log.WithContext(context.Background()) - err = qr.Main.LoadUserLogin(backgroundCtx, ul) - if err != nil { - return nil, fmt.Errorf("failed to prepare connection after login: %w", err) - } err = ul.Client.Connect(backgroundCtx) if err != nil { return nil, fmt.Errorf("failed to connect after login: %w", err) From c5c12135c5a87388a3b78fc8583ecc1a708b0c88 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Tue, 9 Jul 2024 21:25:42 +0300 Subject: [PATCH 099/580] v2: update mautrix-go --- go.mod | 2 +- go.sum | 4 ++-- pkg/connector/handlesignal.go | 4 ++++ 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index e7cb76e..8d62958 100644 --- a/go.mod +++ b/go.mod @@ -19,7 +19,7 @@ require ( golang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8 golang.org/x/net v0.26.0 google.golang.org/protobuf v1.34.2 - maunium.net/go/mautrix v0.19.0-beta.1.0.20240706124659-b4057a26c3ed + maunium.net/go/mautrix v0.19.0-beta.1.0.20240709160900-fc7ed77e2630 nhooyr.io/websocket v1.8.11 ) diff --git a/go.sum b/go.sum index 45caa46..094f2d1 100644 --- a/go.sum +++ b/go.sum @@ -93,7 +93,7 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= maunium.net/go/mauflag v1.0.0 h1:YiaRc0tEI3toYtJMRIfjP+jklH45uDHtT80nUamyD4M= maunium.net/go/mauflag v1.0.0/go.mod h1:nLivPOpTpHnpzEh8jEdSL9UqO9+/KBJFmNRlwKfkPeA= -maunium.net/go/mautrix v0.19.0-beta.1.0.20240706124659-b4057a26c3ed h1:3F4YHSFaUJ9N0l4zNGeXZvnTBIHC9PDVOWOFiOvNn3Y= -maunium.net/go/mautrix v0.19.0-beta.1.0.20240706124659-b4057a26c3ed/go.mod h1:bNQrvIftiwJ+7OjSh+Gza5xcncq1ooHk6oyDWq4B4sg= +maunium.net/go/mautrix v0.19.0-beta.1.0.20240709160900-fc7ed77e2630 h1:X+IuVExANBr0gfFQ22vpecvDzkiSCVAnFAYvyIZ+uOI= +maunium.net/go/mautrix v0.19.0-beta.1.0.20240709160900-fc7ed77e2630/go.mod h1:bNQrvIftiwJ+7OjSh+Gza5xcncq1ooHk6oyDWq4B4sg= nhooyr.io/websocket v1.8.11 h1:f/qXNc2/3DpoSZkHt1DQu6rj4zGC8JmkkLkWss0MgN0= nhooyr.io/websocket v1.8.11/go.mod h1:rN9OFWIUwuxg4fR5tELlYC04bXYowCP9GX47ivo2l+c= diff --git a/pkg/connector/handlesignal.go b/pkg/connector/handlesignal.go index 993d23f..0618957 100644 --- a/pkg/connector/handlesignal.go +++ b/pkg/connector/handlesignal.go @@ -386,6 +386,10 @@ func (b *Bv2Receipt) GetReceiptTargets() []networkid.MessageID { return b.IDs } +func (b *Bv2Receipt) GetReadUpTo() time.Time { + return time.Time{} +} + var _ bridgev2.RemoteReceipt = (*Bv2Receipt)(nil) func convertReceipts[T any](ctx context.Context, input []T, getMessageFunc func(ctx context.Context, msgID T) (*database.Message, error)) map[networkid.PortalKey]*Bv2Receipt { From fe389bf65a5869f99c2a1b4d22a4012b9f7227be Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Wed, 10 Jul 2024 20:36:07 +0300 Subject: [PATCH 100/580] signalmeow: update registration capabilities --- pkg/signalmeow/provisioning.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/signalmeow/provisioning.go b/pkg/signalmeow/provisioning.go index 88f8485..1aff0cd 100644 --- a/pkg/signalmeow/provisioning.go +++ b/pkg/signalmeow/provisioning.go @@ -384,7 +384,7 @@ func confirmDevice( "registrationId": aciRegistrationID, "pniRegistrationId": pniRegistrationID, "capabilities": map[string]any{ - "pni": true, + "deleteSync": true, }, }, "aciSignedPreKey": aciSignedPreKeyJson, From 4fd377707026dd803611c8684a3ee8e1f86998bb Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Wed, 10 Jul 2024 20:40:07 +0300 Subject: [PATCH 101/580] signalmeow: update protobufs --- pkg/signalmeow/protobuf/Groups.pb.go | 661 ++++++++++------ pkg/signalmeow/protobuf/Groups.proto | 13 +- pkg/signalmeow/protobuf/SignalService.pb.go | 822 ++++++++++++-------- pkg/signalmeow/protobuf/SignalService.proto | 18 +- pkg/signalmeow/protobuf/update-protos.sh | 4 +- 5 files changed, 935 insertions(+), 583 deletions(-) diff --git a/pkg/signalmeow/protobuf/Groups.pb.go b/pkg/signalmeow/protobuf/Groups.pb.go index 8ec4a97..ae4b64b 100644 --- a/pkg/signalmeow/protobuf/Groups.pb.go +++ b/pkg/signalmeow/protobuf/Groups.pb.go @@ -761,18 +761,74 @@ func (x *GroupChange) GetChangeEpoch() uint32 { return 0 } +type GroupResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Group *Group `protobuf:"bytes,1,opt,name=group,proto3" json:"group,omitempty"` + GroupSendEndorsementsResponse []byte `protobuf:"bytes,2,opt,name=groupSendEndorsementsResponse,proto3" json:"groupSendEndorsementsResponse,omitempty"` +} + +func (x *GroupResponse) Reset() { + *x = GroupResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_Groups_proto_msgTypes[8] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GroupResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GroupResponse) ProtoMessage() {} + +func (x *GroupResponse) ProtoReflect() protoreflect.Message { + mi := &file_Groups_proto_msgTypes[8] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GroupResponse.ProtoReflect.Descriptor instead. +func (*GroupResponse) Descriptor() ([]byte, []int) { + return file_Groups_proto_rawDescGZIP(), []int{8} +} + +func (x *GroupResponse) GetGroup() *Group { + if x != nil { + return x.Group + } + return nil +} + +func (x *GroupResponse) GetGroupSendEndorsementsResponse() []byte { + if x != nil { + return x.GroupSendEndorsementsResponse + } + return nil +} + type GroupChanges struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - GroupChanges []*GroupChanges_GroupChangeState `protobuf:"bytes,1,rep,name=groupChanges,proto3" json:"groupChanges,omitempty"` + GroupChanges []*GroupChanges_GroupChangeState `protobuf:"bytes,1,rep,name=groupChanges,proto3" json:"groupChanges,omitempty"` + GroupSendEndorsementsResponse []byte `protobuf:"bytes,2,opt,name=groupSendEndorsementsResponse,proto3" json:"groupSendEndorsementsResponse,omitempty"` } func (x *GroupChanges) Reset() { *x = GroupChanges{} if protoimpl.UnsafeEnabled { - mi := &file_Groups_proto_msgTypes[8] + mi := &file_Groups_proto_msgTypes[9] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -785,7 +841,7 @@ func (x *GroupChanges) String() string { func (*GroupChanges) ProtoMessage() {} func (x *GroupChanges) ProtoReflect() protoreflect.Message { - mi := &file_Groups_proto_msgTypes[8] + mi := &file_Groups_proto_msgTypes[9] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -798,7 +854,7 @@ func (x *GroupChanges) ProtoReflect() protoreflect.Message { // Deprecated: Use GroupChanges.ProtoReflect.Descriptor instead. func (*GroupChanges) Descriptor() ([]byte, []int) { - return file_Groups_proto_rawDescGZIP(), []int{8} + return file_Groups_proto_rawDescGZIP(), []int{9} } func (x *GroupChanges) GetGroupChanges() []*GroupChanges_GroupChangeState { @@ -808,6 +864,68 @@ func (x *GroupChanges) GetGroupChanges() []*GroupChanges_GroupChangeState { return nil } +func (x *GroupChanges) GetGroupSendEndorsementsResponse() []byte { + if x != nil { + return x.GroupSendEndorsementsResponse + } + return nil +} + +type GroupChangeResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + GroupChange *GroupChange `protobuf:"bytes,1,opt,name=groupChange,proto3" json:"groupChange,omitempty"` + GroupSendEndorsementsResponse []byte `protobuf:"bytes,2,opt,name=groupSendEndorsementsResponse,proto3" json:"groupSendEndorsementsResponse,omitempty"` +} + +func (x *GroupChangeResponse) Reset() { + *x = GroupChangeResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_Groups_proto_msgTypes[10] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GroupChangeResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GroupChangeResponse) ProtoMessage() {} + +func (x *GroupChangeResponse) ProtoReflect() protoreflect.Message { + mi := &file_Groups_proto_msgTypes[10] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GroupChangeResponse.ProtoReflect.Descriptor instead. +func (*GroupChangeResponse) Descriptor() ([]byte, []int) { + return file_Groups_proto_rawDescGZIP(), []int{10} +} + +func (x *GroupChangeResponse) GetGroupChange() *GroupChange { + if x != nil { + return x.GroupChange + } + return nil +} + +func (x *GroupChangeResponse) GetGroupSendEndorsementsResponse() []byte { + if x != nil { + return x.GroupSendEndorsementsResponse + } + return nil +} + type GroupAttributeBlob struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -825,7 +943,7 @@ type GroupAttributeBlob struct { func (x *GroupAttributeBlob) Reset() { *x = GroupAttributeBlob{} if protoimpl.UnsafeEnabled { - mi := &file_Groups_proto_msgTypes[9] + mi := &file_Groups_proto_msgTypes[11] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -838,7 +956,7 @@ func (x *GroupAttributeBlob) String() string { func (*GroupAttributeBlob) ProtoMessage() {} func (x *GroupAttributeBlob) ProtoReflect() protoreflect.Message { - mi := &file_Groups_proto_msgTypes[9] + mi := &file_Groups_proto_msgTypes[11] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -851,7 +969,7 @@ func (x *GroupAttributeBlob) ProtoReflect() protoreflect.Message { // Deprecated: Use GroupAttributeBlob.ProtoReflect.Descriptor instead. func (*GroupAttributeBlob) Descriptor() ([]byte, []int) { - return file_Groups_proto_rawDescGZIP(), []int{9} + return file_Groups_proto_rawDescGZIP(), []int{11} } func (m *GroupAttributeBlob) GetContent() isGroupAttributeBlob_Content { @@ -931,7 +1049,7 @@ type GroupInviteLink struct { func (x *GroupInviteLink) Reset() { *x = GroupInviteLink{} if protoimpl.UnsafeEnabled { - mi := &file_Groups_proto_msgTypes[10] + mi := &file_Groups_proto_msgTypes[12] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -944,7 +1062,7 @@ func (x *GroupInviteLink) String() string { func (*GroupInviteLink) ProtoMessage() {} func (x *GroupInviteLink) ProtoReflect() protoreflect.Message { - mi := &file_Groups_proto_msgTypes[10] + mi := &file_Groups_proto_msgTypes[12] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -957,7 +1075,7 @@ func (x *GroupInviteLink) ProtoReflect() protoreflect.Message { // Deprecated: Use GroupInviteLink.ProtoReflect.Descriptor instead. func (*GroupInviteLink) Descriptor() ([]byte, []int) { - return file_Groups_proto_rawDescGZIP(), []int{10} + return file_Groups_proto_rawDescGZIP(), []int{12} } func (m *GroupInviteLink) GetContents() isGroupInviteLink_Contents { @@ -1002,7 +1120,7 @@ type GroupJoinInfo struct { func (x *GroupJoinInfo) Reset() { *x = GroupJoinInfo{} if protoimpl.UnsafeEnabled { - mi := &file_Groups_proto_msgTypes[11] + mi := &file_Groups_proto_msgTypes[13] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1015,7 +1133,7 @@ func (x *GroupJoinInfo) String() string { func (*GroupJoinInfo) ProtoMessage() {} func (x *GroupJoinInfo) ProtoReflect() protoreflect.Message { - mi := &file_Groups_proto_msgTypes[11] + mi := &file_Groups_proto_msgTypes[13] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1028,7 +1146,7 @@ func (x *GroupJoinInfo) ProtoReflect() protoreflect.Message { // Deprecated: Use GroupJoinInfo.ProtoReflect.Descriptor instead. func (*GroupJoinInfo) Descriptor() ([]byte, []int) { - return file_Groups_proto_rawDescGZIP(), []int{11} + return file_Groups_proto_rawDescGZIP(), []int{13} } func (x *GroupJoinInfo) GetPublicKey() []byte { @@ -1098,7 +1216,7 @@ type GroupExternalCredential struct { func (x *GroupExternalCredential) Reset() { *x = GroupExternalCredential{} if protoimpl.UnsafeEnabled { - mi := &file_Groups_proto_msgTypes[12] + mi := &file_Groups_proto_msgTypes[14] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1111,7 +1229,7 @@ func (x *GroupExternalCredential) String() string { func (*GroupExternalCredential) ProtoMessage() {} func (x *GroupExternalCredential) ProtoReflect() protoreflect.Message { - mi := &file_Groups_proto_msgTypes[12] + mi := &file_Groups_proto_msgTypes[14] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1124,7 +1242,7 @@ func (x *GroupExternalCredential) ProtoReflect() protoreflect.Message { // Deprecated: Use GroupExternalCredential.ProtoReflect.Descriptor instead. func (*GroupExternalCredential) Descriptor() ([]byte, []int) { - return file_Groups_proto_rawDescGZIP(), []int{12} + return file_Groups_proto_rawDescGZIP(), []int{14} } func (x *GroupExternalCredential) GetToken() string { @@ -1168,7 +1286,7 @@ type GroupChange_Actions struct { func (x *GroupChange_Actions) Reset() { *x = GroupChange_Actions{} if protoimpl.UnsafeEnabled { - mi := &file_Groups_proto_msgTypes[13] + mi := &file_Groups_proto_msgTypes[15] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1181,7 +1299,7 @@ func (x *GroupChange_Actions) String() string { func (*GroupChange_Actions) ProtoMessage() {} func (x *GroupChange_Actions) ProtoReflect() protoreflect.Message { - mi := &file_Groups_proto_msgTypes[13] + mi := &file_Groups_proto_msgTypes[15] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1377,7 +1495,7 @@ type GroupChange_Actions_AddMemberAction struct { func (x *GroupChange_Actions_AddMemberAction) Reset() { *x = GroupChange_Actions_AddMemberAction{} if protoimpl.UnsafeEnabled { - mi := &file_Groups_proto_msgTypes[14] + mi := &file_Groups_proto_msgTypes[16] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1390,7 +1508,7 @@ func (x *GroupChange_Actions_AddMemberAction) String() string { func (*GroupChange_Actions_AddMemberAction) ProtoMessage() {} func (x *GroupChange_Actions_AddMemberAction) ProtoReflect() protoreflect.Message { - mi := &file_Groups_proto_msgTypes[14] + mi := &file_Groups_proto_msgTypes[16] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1431,7 +1549,7 @@ type GroupChange_Actions_DeleteMemberAction struct { func (x *GroupChange_Actions_DeleteMemberAction) Reset() { *x = GroupChange_Actions_DeleteMemberAction{} if protoimpl.UnsafeEnabled { - mi := &file_Groups_proto_msgTypes[15] + mi := &file_Groups_proto_msgTypes[17] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1444,7 +1562,7 @@ func (x *GroupChange_Actions_DeleteMemberAction) String() string { func (*GroupChange_Actions_DeleteMemberAction) ProtoMessage() {} func (x *GroupChange_Actions_DeleteMemberAction) ProtoReflect() protoreflect.Message { - mi := &file_Groups_proto_msgTypes[15] + mi := &file_Groups_proto_msgTypes[17] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1479,7 +1597,7 @@ type GroupChange_Actions_ModifyMemberRoleAction struct { func (x *GroupChange_Actions_ModifyMemberRoleAction) Reset() { *x = GroupChange_Actions_ModifyMemberRoleAction{} if protoimpl.UnsafeEnabled { - mi := &file_Groups_proto_msgTypes[16] + mi := &file_Groups_proto_msgTypes[18] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1492,7 +1610,7 @@ func (x *GroupChange_Actions_ModifyMemberRoleAction) String() string { func (*GroupChange_Actions_ModifyMemberRoleAction) ProtoMessage() {} func (x *GroupChange_Actions_ModifyMemberRoleAction) ProtoReflect() protoreflect.Message { - mi := &file_Groups_proto_msgTypes[16] + mi := &file_Groups_proto_msgTypes[18] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1535,7 +1653,7 @@ type GroupChange_Actions_ModifyMemberProfileKeyAction struct { func (x *GroupChange_Actions_ModifyMemberProfileKeyAction) Reset() { *x = GroupChange_Actions_ModifyMemberProfileKeyAction{} if protoimpl.UnsafeEnabled { - mi := &file_Groups_proto_msgTypes[17] + mi := &file_Groups_proto_msgTypes[19] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1548,7 +1666,7 @@ func (x *GroupChange_Actions_ModifyMemberProfileKeyAction) String() string { func (*GroupChange_Actions_ModifyMemberProfileKeyAction) ProtoMessage() {} func (x *GroupChange_Actions_ModifyMemberProfileKeyAction) ProtoReflect() protoreflect.Message { - mi := &file_Groups_proto_msgTypes[17] + mi := &file_Groups_proto_msgTypes[19] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1596,7 +1714,7 @@ type GroupChange_Actions_AddPendingMemberAction struct { func (x *GroupChange_Actions_AddPendingMemberAction) Reset() { *x = GroupChange_Actions_AddPendingMemberAction{} if protoimpl.UnsafeEnabled { - mi := &file_Groups_proto_msgTypes[18] + mi := &file_Groups_proto_msgTypes[20] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1609,7 +1727,7 @@ func (x *GroupChange_Actions_AddPendingMemberAction) String() string { func (*GroupChange_Actions_AddPendingMemberAction) ProtoMessage() {} func (x *GroupChange_Actions_AddPendingMemberAction) ProtoReflect() protoreflect.Message { - mi := &file_Groups_proto_msgTypes[18] + mi := &file_Groups_proto_msgTypes[20] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1643,7 +1761,7 @@ type GroupChange_Actions_DeletePendingMemberAction struct { func (x *GroupChange_Actions_DeletePendingMemberAction) Reset() { *x = GroupChange_Actions_DeletePendingMemberAction{} if protoimpl.UnsafeEnabled { - mi := &file_Groups_proto_msgTypes[19] + mi := &file_Groups_proto_msgTypes[21] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1656,7 +1774,7 @@ func (x *GroupChange_Actions_DeletePendingMemberAction) String() string { func (*GroupChange_Actions_DeletePendingMemberAction) ProtoMessage() {} func (x *GroupChange_Actions_DeletePendingMemberAction) ProtoReflect() protoreflect.Message { - mi := &file_Groups_proto_msgTypes[19] + mi := &file_Groups_proto_msgTypes[21] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1692,7 +1810,7 @@ type GroupChange_Actions_PromotePendingMemberAction struct { func (x *GroupChange_Actions_PromotePendingMemberAction) Reset() { *x = GroupChange_Actions_PromotePendingMemberAction{} if protoimpl.UnsafeEnabled { - mi := &file_Groups_proto_msgTypes[20] + mi := &file_Groups_proto_msgTypes[22] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1705,7 +1823,7 @@ func (x *GroupChange_Actions_PromotePendingMemberAction) String() string { func (*GroupChange_Actions_PromotePendingMemberAction) ProtoMessage() {} func (x *GroupChange_Actions_PromotePendingMemberAction) ProtoReflect() protoreflect.Message { - mi := &file_Groups_proto_msgTypes[20] + mi := &file_Groups_proto_msgTypes[22] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1756,7 +1874,7 @@ type GroupChange_Actions_PromotePendingPniAciMemberProfileKeyAction struct { func (x *GroupChange_Actions_PromotePendingPniAciMemberProfileKeyAction) Reset() { *x = GroupChange_Actions_PromotePendingPniAciMemberProfileKeyAction{} if protoimpl.UnsafeEnabled { - mi := &file_Groups_proto_msgTypes[21] + mi := &file_Groups_proto_msgTypes[23] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1769,7 +1887,7 @@ func (x *GroupChange_Actions_PromotePendingPniAciMemberProfileKeyAction) String( func (*GroupChange_Actions_PromotePendingPniAciMemberProfileKeyAction) ProtoMessage() {} func (x *GroupChange_Actions_PromotePendingPniAciMemberProfileKeyAction) ProtoReflect() protoreflect.Message { - mi := &file_Groups_proto_msgTypes[21] + mi := &file_Groups_proto_msgTypes[23] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1824,7 +1942,7 @@ type GroupChange_Actions_AddRequestingMemberAction struct { func (x *GroupChange_Actions_AddRequestingMemberAction) Reset() { *x = GroupChange_Actions_AddRequestingMemberAction{} if protoimpl.UnsafeEnabled { - mi := &file_Groups_proto_msgTypes[22] + mi := &file_Groups_proto_msgTypes[24] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1837,7 +1955,7 @@ func (x *GroupChange_Actions_AddRequestingMemberAction) String() string { func (*GroupChange_Actions_AddRequestingMemberAction) ProtoMessage() {} func (x *GroupChange_Actions_AddRequestingMemberAction) ProtoReflect() protoreflect.Message { - mi := &file_Groups_proto_msgTypes[22] + mi := &file_Groups_proto_msgTypes[24] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1871,7 +1989,7 @@ type GroupChange_Actions_DeleteRequestingMemberAction struct { func (x *GroupChange_Actions_DeleteRequestingMemberAction) Reset() { *x = GroupChange_Actions_DeleteRequestingMemberAction{} if protoimpl.UnsafeEnabled { - mi := &file_Groups_proto_msgTypes[23] + mi := &file_Groups_proto_msgTypes[25] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1884,7 +2002,7 @@ func (x *GroupChange_Actions_DeleteRequestingMemberAction) String() string { func (*GroupChange_Actions_DeleteRequestingMemberAction) ProtoMessage() {} func (x *GroupChange_Actions_DeleteRequestingMemberAction) ProtoReflect() protoreflect.Message { - mi := &file_Groups_proto_msgTypes[23] + mi := &file_Groups_proto_msgTypes[25] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1919,7 +2037,7 @@ type GroupChange_Actions_PromoteRequestingMemberAction struct { func (x *GroupChange_Actions_PromoteRequestingMemberAction) Reset() { *x = GroupChange_Actions_PromoteRequestingMemberAction{} if protoimpl.UnsafeEnabled { - mi := &file_Groups_proto_msgTypes[24] + mi := &file_Groups_proto_msgTypes[26] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1932,7 +2050,7 @@ func (x *GroupChange_Actions_PromoteRequestingMemberAction) String() string { func (*GroupChange_Actions_PromoteRequestingMemberAction) ProtoMessage() {} func (x *GroupChange_Actions_PromoteRequestingMemberAction) ProtoReflect() protoreflect.Message { - mi := &file_Groups_proto_msgTypes[24] + mi := &file_Groups_proto_msgTypes[26] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1973,7 +2091,7 @@ type GroupChange_Actions_AddBannedMemberAction struct { func (x *GroupChange_Actions_AddBannedMemberAction) Reset() { *x = GroupChange_Actions_AddBannedMemberAction{} if protoimpl.UnsafeEnabled { - mi := &file_Groups_proto_msgTypes[25] + mi := &file_Groups_proto_msgTypes[27] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1986,7 +2104,7 @@ func (x *GroupChange_Actions_AddBannedMemberAction) String() string { func (*GroupChange_Actions_AddBannedMemberAction) ProtoMessage() {} func (x *GroupChange_Actions_AddBannedMemberAction) ProtoReflect() protoreflect.Message { - mi := &file_Groups_proto_msgTypes[25] + mi := &file_Groups_proto_msgTypes[27] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2020,7 +2138,7 @@ type GroupChange_Actions_DeleteBannedMemberAction struct { func (x *GroupChange_Actions_DeleteBannedMemberAction) Reset() { *x = GroupChange_Actions_DeleteBannedMemberAction{} if protoimpl.UnsafeEnabled { - mi := &file_Groups_proto_msgTypes[26] + mi := &file_Groups_proto_msgTypes[28] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2033,7 +2151,7 @@ func (x *GroupChange_Actions_DeleteBannedMemberAction) String() string { func (*GroupChange_Actions_DeleteBannedMemberAction) ProtoMessage() {} func (x *GroupChange_Actions_DeleteBannedMemberAction) ProtoReflect() protoreflect.Message { - mi := &file_Groups_proto_msgTypes[26] + mi := &file_Groups_proto_msgTypes[28] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2067,7 +2185,7 @@ type GroupChange_Actions_ModifyTitleAction struct { func (x *GroupChange_Actions_ModifyTitleAction) Reset() { *x = GroupChange_Actions_ModifyTitleAction{} if protoimpl.UnsafeEnabled { - mi := &file_Groups_proto_msgTypes[27] + mi := &file_Groups_proto_msgTypes[29] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2080,7 +2198,7 @@ func (x *GroupChange_Actions_ModifyTitleAction) String() string { func (*GroupChange_Actions_ModifyTitleAction) ProtoMessage() {} func (x *GroupChange_Actions_ModifyTitleAction) ProtoReflect() protoreflect.Message { - mi := &file_Groups_proto_msgTypes[27] + mi := &file_Groups_proto_msgTypes[29] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2114,7 +2232,7 @@ type GroupChange_Actions_ModifyDescriptionAction struct { func (x *GroupChange_Actions_ModifyDescriptionAction) Reset() { *x = GroupChange_Actions_ModifyDescriptionAction{} if protoimpl.UnsafeEnabled { - mi := &file_Groups_proto_msgTypes[28] + mi := &file_Groups_proto_msgTypes[30] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2127,7 +2245,7 @@ func (x *GroupChange_Actions_ModifyDescriptionAction) String() string { func (*GroupChange_Actions_ModifyDescriptionAction) ProtoMessage() {} func (x *GroupChange_Actions_ModifyDescriptionAction) ProtoReflect() protoreflect.Message { - mi := &file_Groups_proto_msgTypes[28] + mi := &file_Groups_proto_msgTypes[30] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2161,7 +2279,7 @@ type GroupChange_Actions_ModifyAvatarAction struct { func (x *GroupChange_Actions_ModifyAvatarAction) Reset() { *x = GroupChange_Actions_ModifyAvatarAction{} if protoimpl.UnsafeEnabled { - mi := &file_Groups_proto_msgTypes[29] + mi := &file_Groups_proto_msgTypes[31] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2174,7 +2292,7 @@ func (x *GroupChange_Actions_ModifyAvatarAction) String() string { func (*GroupChange_Actions_ModifyAvatarAction) ProtoMessage() {} func (x *GroupChange_Actions_ModifyAvatarAction) ProtoReflect() protoreflect.Message { - mi := &file_Groups_proto_msgTypes[29] + mi := &file_Groups_proto_msgTypes[31] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2208,7 +2326,7 @@ type GroupChange_Actions_ModifyDisappearingMessagesTimerAction struct { func (x *GroupChange_Actions_ModifyDisappearingMessagesTimerAction) Reset() { *x = GroupChange_Actions_ModifyDisappearingMessagesTimerAction{} if protoimpl.UnsafeEnabled { - mi := &file_Groups_proto_msgTypes[30] + mi := &file_Groups_proto_msgTypes[32] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2221,7 +2339,7 @@ func (x *GroupChange_Actions_ModifyDisappearingMessagesTimerAction) String() str func (*GroupChange_Actions_ModifyDisappearingMessagesTimerAction) ProtoMessage() {} func (x *GroupChange_Actions_ModifyDisappearingMessagesTimerAction) ProtoReflect() protoreflect.Message { - mi := &file_Groups_proto_msgTypes[30] + mi := &file_Groups_proto_msgTypes[32] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2255,7 +2373,7 @@ type GroupChange_Actions_ModifyAttributesAccessControlAction struct { func (x *GroupChange_Actions_ModifyAttributesAccessControlAction) Reset() { *x = GroupChange_Actions_ModifyAttributesAccessControlAction{} if protoimpl.UnsafeEnabled { - mi := &file_Groups_proto_msgTypes[31] + mi := &file_Groups_proto_msgTypes[33] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2268,7 +2386,7 @@ func (x *GroupChange_Actions_ModifyAttributesAccessControlAction) String() strin func (*GroupChange_Actions_ModifyAttributesAccessControlAction) ProtoMessage() {} func (x *GroupChange_Actions_ModifyAttributesAccessControlAction) ProtoReflect() protoreflect.Message { - mi := &file_Groups_proto_msgTypes[31] + mi := &file_Groups_proto_msgTypes[33] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2302,7 +2420,7 @@ type GroupChange_Actions_ModifyMembersAccessControlAction struct { func (x *GroupChange_Actions_ModifyMembersAccessControlAction) Reset() { *x = GroupChange_Actions_ModifyMembersAccessControlAction{} if protoimpl.UnsafeEnabled { - mi := &file_Groups_proto_msgTypes[32] + mi := &file_Groups_proto_msgTypes[34] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2315,7 +2433,7 @@ func (x *GroupChange_Actions_ModifyMembersAccessControlAction) String() string { func (*GroupChange_Actions_ModifyMembersAccessControlAction) ProtoMessage() {} func (x *GroupChange_Actions_ModifyMembersAccessControlAction) ProtoReflect() protoreflect.Message { - mi := &file_Groups_proto_msgTypes[32] + mi := &file_Groups_proto_msgTypes[34] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2349,7 +2467,7 @@ type GroupChange_Actions_ModifyAddFromInviteLinkAccessControlAction struct { func (x *GroupChange_Actions_ModifyAddFromInviteLinkAccessControlAction) Reset() { *x = GroupChange_Actions_ModifyAddFromInviteLinkAccessControlAction{} if protoimpl.UnsafeEnabled { - mi := &file_Groups_proto_msgTypes[33] + mi := &file_Groups_proto_msgTypes[35] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2362,7 +2480,7 @@ func (x *GroupChange_Actions_ModifyAddFromInviteLinkAccessControlAction) String( func (*GroupChange_Actions_ModifyAddFromInviteLinkAccessControlAction) ProtoMessage() {} func (x *GroupChange_Actions_ModifyAddFromInviteLinkAccessControlAction) ProtoReflect() protoreflect.Message { - mi := &file_Groups_proto_msgTypes[33] + mi := &file_Groups_proto_msgTypes[35] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2396,7 +2514,7 @@ type GroupChange_Actions_ModifyInviteLinkPasswordAction struct { func (x *GroupChange_Actions_ModifyInviteLinkPasswordAction) Reset() { *x = GroupChange_Actions_ModifyInviteLinkPasswordAction{} if protoimpl.UnsafeEnabled { - mi := &file_Groups_proto_msgTypes[34] + mi := &file_Groups_proto_msgTypes[36] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2409,7 +2527,7 @@ func (x *GroupChange_Actions_ModifyInviteLinkPasswordAction) String() string { func (*GroupChange_Actions_ModifyInviteLinkPasswordAction) ProtoMessage() {} func (x *GroupChange_Actions_ModifyInviteLinkPasswordAction) ProtoReflect() protoreflect.Message { - mi := &file_Groups_proto_msgTypes[34] + mi := &file_Groups_proto_msgTypes[36] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2443,7 +2561,7 @@ type GroupChange_Actions_ModifyAnnouncementsOnlyAction struct { func (x *GroupChange_Actions_ModifyAnnouncementsOnlyAction) Reset() { *x = GroupChange_Actions_ModifyAnnouncementsOnlyAction{} if protoimpl.UnsafeEnabled { - mi := &file_Groups_proto_msgTypes[35] + mi := &file_Groups_proto_msgTypes[37] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2456,7 +2574,7 @@ func (x *GroupChange_Actions_ModifyAnnouncementsOnlyAction) String() string { func (*GroupChange_Actions_ModifyAnnouncementsOnlyAction) ProtoMessage() {} func (x *GroupChange_Actions_ModifyAnnouncementsOnlyAction) ProtoReflect() protoreflect.Message { - mi := &file_Groups_proto_msgTypes[35] + mi := &file_Groups_proto_msgTypes[37] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2491,7 +2609,7 @@ type GroupChanges_GroupChangeState struct { func (x *GroupChanges_GroupChangeState) Reset() { *x = GroupChanges_GroupChangeState{} if protoimpl.UnsafeEnabled { - mi := &file_Groups_proto_msgTypes[36] + mi := &file_Groups_proto_msgTypes[38] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2504,7 +2622,7 @@ func (x *GroupChanges_GroupChangeState) String() string { func (*GroupChanges_GroupChangeState) ProtoMessage() {} func (x *GroupChanges_GroupChangeState) ProtoReflect() protoreflect.Message { - mi := &file_Groups_proto_msgTypes[36] + mi := &file_Groups_proto_msgTypes[38] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2517,7 +2635,7 @@ func (x *GroupChanges_GroupChangeState) ProtoReflect() protoreflect.Message { // Deprecated: Use GroupChanges_GroupChangeState.ProtoReflect.Descriptor instead. func (*GroupChanges_GroupChangeState) Descriptor() ([]byte, []int) { - return file_Groups_proto_rawDescGZIP(), []int{8, 0} + return file_Groups_proto_rawDescGZIP(), []int{9, 0} } func (x *GroupChanges_GroupChangeState) GetGroupChange() *GroupChange { @@ -2546,7 +2664,7 @@ type GroupInviteLink_GroupInviteLinkContentsV1 struct { func (x *GroupInviteLink_GroupInviteLinkContentsV1) Reset() { *x = GroupInviteLink_GroupInviteLinkContentsV1{} if protoimpl.UnsafeEnabled { - mi := &file_Groups_proto_msgTypes[37] + mi := &file_Groups_proto_msgTypes[39] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2559,7 +2677,7 @@ func (x *GroupInviteLink_GroupInviteLinkContentsV1) String() string { func (*GroupInviteLink_GroupInviteLinkContentsV1) ProtoMessage() {} func (x *GroupInviteLink_GroupInviteLinkContentsV1) ProtoReflect() protoreflect.Message { - mi := &file_Groups_proto_msgTypes[37] + mi := &file_Groups_proto_msgTypes[39] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2572,7 +2690,7 @@ func (x *GroupInviteLink_GroupInviteLinkContentsV1) ProtoReflect() protoreflect. // Deprecated: Use GroupInviteLink_GroupInviteLinkContentsV1.ProtoReflect.Descriptor instead. func (*GroupInviteLink_GroupInviteLinkContentsV1) Descriptor() ([]byte, []int) { - return file_Groups_proto_rawDescGZIP(), []int{10, 0} + return file_Groups_proto_rawDescGZIP(), []int{12, 0} } func (x *GroupInviteLink_GroupInviteLinkContentsV1) GetGroupMasterKey() []byte { @@ -2964,71 +3082,92 @@ var file_Groups_proto_rawDesc = []byte{ 0x69, 0x6f, 0x6e, 0x12, 0x2c, 0x0a, 0x11, 0x61, 0x6e, 0x6e, 0x6f, 0x75, 0x6e, 0x63, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x4f, 0x6e, 0x6c, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x11, 0x61, 0x6e, 0x6e, 0x6f, 0x75, 0x6e, 0x63, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x4f, 0x6e, 0x6c, - 0x79, 0x22, 0xbe, 0x01, 0x0a, 0x0c, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x43, 0x68, 0x61, 0x6e, 0x67, - 0x65, 0x73, 0x12, 0x42, 0x0a, 0x0c, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x43, 0x68, 0x61, 0x6e, 0x67, - 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x47, 0x72, 0x6f, 0x75, 0x70, - 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x2e, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x43, 0x68, 0x61, - 0x6e, 0x67, 0x65, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x0c, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x43, - 0x68, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x1a, 0x6a, 0x0a, 0x10, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x43, - 0x68, 0x61, 0x6e, 0x67, 0x65, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x2e, 0x0a, 0x0b, 0x67, 0x72, - 0x6f, 0x75, 0x70, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x0c, 0x2e, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x52, 0x0b, 0x67, - 0x72, 0x6f, 0x75, 0x70, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x12, 0x26, 0x0a, 0x0a, 0x67, 0x72, - 0x6f, 0x75, 0x70, 0x53, 0x74, 0x61, 0x74, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x06, - 0x2e, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x52, 0x0a, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x53, 0x74, 0x61, - 0x74, 0x65, 0x22, 0xbb, 0x01, 0x0a, 0x12, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x41, 0x74, 0x74, 0x72, - 0x69, 0x62, 0x75, 0x74, 0x65, 0x42, 0x6c, 0x6f, 0x62, 0x12, 0x16, 0x0a, 0x05, 0x74, 0x69, 0x74, - 0x6c, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x05, 0x74, 0x69, 0x74, 0x6c, - 0x65, 0x12, 0x18, 0x0a, 0x06, 0x61, 0x76, 0x61, 0x74, 0x61, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x0c, 0x48, 0x00, 0x52, 0x06, 0x61, 0x76, 0x61, 0x74, 0x61, 0x72, 0x12, 0x44, 0x0a, 0x1c, 0x64, - 0x69, 0x73, 0x61, 0x70, 0x70, 0x65, 0x61, 0x72, 0x69, 0x6e, 0x67, 0x4d, 0x65, 0x73, 0x73, 0x61, - 0x67, 0x65, 0x73, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, - 0x0d, 0x48, 0x00, 0x52, 0x1c, 0x64, 0x69, 0x73, 0x61, 0x70, 0x70, 0x65, 0x61, 0x72, 0x69, 0x6e, - 0x67, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x12, 0x22, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, - 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, - 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x42, 0x09, 0x0a, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, - 0x22, 0xe0, 0x01, 0x0a, 0x0f, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x49, 0x6e, 0x76, 0x69, 0x74, 0x65, - 0x4c, 0x69, 0x6e, 0x6b, 0x12, 0x4c, 0x0a, 0x0a, 0x76, 0x31, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, - 0x74, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2a, 0x2e, 0x47, 0x72, 0x6f, 0x75, 0x70, - 0x49, 0x6e, 0x76, 0x69, 0x74, 0x65, 0x4c, 0x69, 0x6e, 0x6b, 0x2e, 0x47, 0x72, 0x6f, 0x75, 0x70, - 0x49, 0x6e, 0x76, 0x69, 0x74, 0x65, 0x4c, 0x69, 0x6e, 0x6b, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, - 0x74, 0x73, 0x56, 0x31, 0x48, 0x00, 0x52, 0x0a, 0x76, 0x31, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, - 0x74, 0x73, 0x1a, 0x73, 0x0a, 0x19, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x49, 0x6e, 0x76, 0x69, 0x74, - 0x65, 0x4c, 0x69, 0x6e, 0x6b, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x73, 0x56, 0x31, 0x12, - 0x26, 0x0a, 0x0e, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x4d, 0x61, 0x73, 0x74, 0x65, 0x72, 0x4b, 0x65, - 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0e, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x4d, 0x61, - 0x73, 0x74, 0x65, 0x72, 0x4b, 0x65, 0x79, 0x12, 0x2e, 0x0a, 0x12, 0x69, 0x6e, 0x76, 0x69, 0x74, - 0x65, 0x4c, 0x69, 0x6e, 0x6b, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x0c, 0x52, 0x12, 0x69, 0x6e, 0x76, 0x69, 0x74, 0x65, 0x4c, 0x69, 0x6e, 0x6b, 0x50, - 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x42, 0x0a, 0x0a, 0x08, 0x63, 0x6f, 0x6e, 0x74, 0x65, - 0x6e, 0x74, 0x73, 0x22, 0xbc, 0x02, 0x0a, 0x0d, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x4a, 0x6f, 0x69, - 0x6e, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x1c, 0x0a, 0x09, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, - 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, - 0x4b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x0c, 0x52, 0x05, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x61, 0x76, 0x61, - 0x74, 0x61, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x61, 0x76, 0x61, 0x74, 0x61, - 0x72, 0x12, 0x20, 0x0a, 0x0b, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x43, 0x6f, 0x75, 0x6e, 0x74, - 0x18, 0x04, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0b, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x43, 0x6f, - 0x75, 0x6e, 0x74, 0x12, 0x4b, 0x0a, 0x11, 0x61, 0x64, 0x64, 0x46, 0x72, 0x6f, 0x6d, 0x49, 0x6e, - 0x76, 0x69, 0x74, 0x65, 0x4c, 0x69, 0x6e, 0x6b, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1d, - 0x2e, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x2e, 0x41, - 0x63, 0x63, 0x65, 0x73, 0x73, 0x52, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x52, 0x11, 0x61, - 0x64, 0x64, 0x46, 0x72, 0x6f, 0x6d, 0x49, 0x6e, 0x76, 0x69, 0x74, 0x65, 0x4c, 0x69, 0x6e, 0x6b, - 0x12, 0x1a, 0x0a, 0x08, 0x72, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x06, 0x20, 0x01, - 0x28, 0x0d, 0x52, 0x08, 0x72, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x32, 0x0a, 0x14, - 0x70, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x41, 0x64, 0x6d, 0x69, 0x6e, 0x41, 0x70, 0x70, 0x72, - 0x6f, 0x76, 0x61, 0x6c, 0x18, 0x07, 0x20, 0x01, 0x28, 0x08, 0x52, 0x14, 0x70, 0x65, 0x6e, 0x64, - 0x69, 0x6e, 0x67, 0x41, 0x64, 0x6d, 0x69, 0x6e, 0x41, 0x70, 0x70, 0x72, 0x6f, 0x76, 0x61, 0x6c, - 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, - 0x08, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, - 0x6f, 0x6e, 0x22, 0x2f, 0x0a, 0x17, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x45, 0x78, 0x74, 0x65, 0x72, - 0x6e, 0x61, 0x6c, 0x43, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x12, 0x14, 0x0a, - 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x74, 0x6f, - 0x6b, 0x65, 0x6e, 0x42, 0x2b, 0x0a, 0x27, 0x6f, 0x72, 0x67, 0x2e, 0x73, 0x69, 0x67, 0x6e, 0x61, - 0x6c, 0x2e, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, - 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2e, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x50, 0x01, - 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x79, 0x22, 0x73, 0x0a, 0x0d, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x12, 0x1c, 0x0a, 0x05, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x06, 0x2e, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x52, 0x05, 0x67, 0x72, 0x6f, 0x75, 0x70, + 0x12, 0x44, 0x0a, 0x1d, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x53, 0x65, 0x6e, 0x64, 0x45, 0x6e, 0x64, + 0x6f, 0x72, 0x73, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x1d, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x53, 0x65, + 0x6e, 0x64, 0x45, 0x6e, 0x64, 0x6f, 0x72, 0x73, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x84, 0x02, 0x0a, 0x0c, 0x47, 0x72, 0x6f, 0x75, 0x70, + 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x12, 0x42, 0x0a, 0x0c, 0x67, 0x72, 0x6f, 0x75, 0x70, + 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1e, 0x2e, + 0x47, 0x72, 0x6f, 0x75, 0x70, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x2e, 0x47, 0x72, 0x6f, + 0x75, 0x70, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x0c, 0x67, + 0x72, 0x6f, 0x75, 0x70, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x12, 0x44, 0x0a, 0x1d, 0x67, + 0x72, 0x6f, 0x75, 0x70, 0x53, 0x65, 0x6e, 0x64, 0x45, 0x6e, 0x64, 0x6f, 0x72, 0x73, 0x65, 0x6d, + 0x65, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x0c, 0x52, 0x1d, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x53, 0x65, 0x6e, 0x64, 0x45, 0x6e, 0x64, + 0x6f, 0x72, 0x73, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x1a, 0x6a, 0x0a, 0x10, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, + 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x2e, 0x0a, 0x0b, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x43, 0x68, + 0x61, 0x6e, 0x67, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x47, 0x72, 0x6f, + 0x75, 0x70, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x52, 0x0b, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x43, + 0x68, 0x61, 0x6e, 0x67, 0x65, 0x12, 0x26, 0x0a, 0x0a, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x53, 0x74, + 0x61, 0x74, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x06, 0x2e, 0x47, 0x72, 0x6f, 0x75, + 0x70, 0x52, 0x0a, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x53, 0x74, 0x61, 0x74, 0x65, 0x22, 0x8b, 0x01, + 0x0a, 0x13, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2e, 0x0a, 0x0b, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x43, 0x68, + 0x61, 0x6e, 0x67, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x47, 0x72, 0x6f, + 0x75, 0x70, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x52, 0x0b, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x43, + 0x68, 0x61, 0x6e, 0x67, 0x65, 0x12, 0x44, 0x0a, 0x1d, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x53, 0x65, + 0x6e, 0x64, 0x45, 0x6e, 0x64, 0x6f, 0x72, 0x73, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x1d, 0x67, 0x72, + 0x6f, 0x75, 0x70, 0x53, 0x65, 0x6e, 0x64, 0x45, 0x6e, 0x64, 0x6f, 0x72, 0x73, 0x65, 0x6d, 0x65, + 0x6e, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0xbb, 0x01, 0x0a, 0x12, + 0x47, 0x72, 0x6f, 0x75, 0x70, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x42, 0x6c, + 0x6f, 0x62, 0x12, 0x16, 0x0a, 0x05, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x48, 0x00, 0x52, 0x05, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x12, 0x18, 0x0a, 0x06, 0x61, 0x76, + 0x61, 0x74, 0x61, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x48, 0x00, 0x52, 0x06, 0x61, 0x76, + 0x61, 0x74, 0x61, 0x72, 0x12, 0x44, 0x0a, 0x1c, 0x64, 0x69, 0x73, 0x61, 0x70, 0x70, 0x65, 0x61, + 0x72, 0x69, 0x6e, 0x67, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x44, 0x75, 0x72, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x48, 0x00, 0x52, 0x1c, 0x64, 0x69, + 0x73, 0x61, 0x70, 0x70, 0x65, 0x61, 0x72, 0x69, 0x6e, 0x67, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, + 0x65, 0x73, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x22, 0x0a, 0x0b, 0x64, 0x65, + 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x48, + 0x00, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x42, 0x09, + 0x0a, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x22, 0xe0, 0x01, 0x0a, 0x0f, 0x47, 0x72, + 0x6f, 0x75, 0x70, 0x49, 0x6e, 0x76, 0x69, 0x74, 0x65, 0x4c, 0x69, 0x6e, 0x6b, 0x12, 0x4c, 0x0a, + 0x0a, 0x76, 0x31, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x2a, 0x2e, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x49, 0x6e, 0x76, 0x69, 0x74, 0x65, 0x4c, + 0x69, 0x6e, 0x6b, 0x2e, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x49, 0x6e, 0x76, 0x69, 0x74, 0x65, 0x4c, + 0x69, 0x6e, 0x6b, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x73, 0x56, 0x31, 0x48, 0x00, 0x52, + 0x0a, 0x76, 0x31, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x73, 0x1a, 0x73, 0x0a, 0x19, 0x47, + 0x72, 0x6f, 0x75, 0x70, 0x49, 0x6e, 0x76, 0x69, 0x74, 0x65, 0x4c, 0x69, 0x6e, 0x6b, 0x43, 0x6f, + 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x73, 0x56, 0x31, 0x12, 0x26, 0x0a, 0x0e, 0x67, 0x72, 0x6f, 0x75, + 0x70, 0x4d, 0x61, 0x73, 0x74, 0x65, 0x72, 0x4b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, + 0x52, 0x0e, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x4d, 0x61, 0x73, 0x74, 0x65, 0x72, 0x4b, 0x65, 0x79, + 0x12, 0x2e, 0x0a, 0x12, 0x69, 0x6e, 0x76, 0x69, 0x74, 0x65, 0x4c, 0x69, 0x6e, 0x6b, 0x50, 0x61, + 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x12, 0x69, 0x6e, + 0x76, 0x69, 0x74, 0x65, 0x4c, 0x69, 0x6e, 0x6b, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, + 0x42, 0x0a, 0x0a, 0x08, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x73, 0x22, 0xbc, 0x02, 0x0a, + 0x0d, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x4a, 0x6f, 0x69, 0x6e, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x1c, + 0x0a, 0x09, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x0c, 0x52, 0x09, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, + 0x74, 0x69, 0x74, 0x6c, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x74, 0x69, 0x74, + 0x6c, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x61, 0x76, 0x61, 0x74, 0x61, 0x72, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x06, 0x61, 0x76, 0x61, 0x74, 0x61, 0x72, 0x12, 0x20, 0x0a, 0x0b, 0x6d, 0x65, + 0x6d, 0x62, 0x65, 0x72, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0d, 0x52, + 0x0b, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x4b, 0x0a, 0x11, + 0x61, 0x64, 0x64, 0x46, 0x72, 0x6f, 0x6d, 0x49, 0x6e, 0x76, 0x69, 0x74, 0x65, 0x4c, 0x69, 0x6e, + 0x6b, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1d, 0x2e, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, + 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x2e, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x52, 0x65, + 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x52, 0x11, 0x61, 0x64, 0x64, 0x46, 0x72, 0x6f, 0x6d, 0x49, + 0x6e, 0x76, 0x69, 0x74, 0x65, 0x4c, 0x69, 0x6e, 0x6b, 0x12, 0x1a, 0x0a, 0x08, 0x72, 0x65, 0x76, + 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x08, 0x72, 0x65, 0x76, + 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x32, 0x0a, 0x14, 0x70, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, + 0x41, 0x64, 0x6d, 0x69, 0x6e, 0x41, 0x70, 0x70, 0x72, 0x6f, 0x76, 0x61, 0x6c, 0x18, 0x07, 0x20, + 0x01, 0x28, 0x08, 0x52, 0x14, 0x70, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x41, 0x64, 0x6d, 0x69, + 0x6e, 0x41, 0x70, 0x70, 0x72, 0x6f, 0x76, 0x61, 0x6c, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, + 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0b, + 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x2f, 0x0a, 0x17, 0x47, + 0x72, 0x6f, 0x75, 0x70, 0x45, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x43, 0x72, 0x65, 0x64, + 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x42, 0x2b, 0x0a, 0x27, + 0x6f, 0x72, 0x67, 0x2e, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x6c, 0x2e, 0x73, 0x74, 0x6f, 0x72, 0x61, + 0x67, 0x65, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, + 0x2e, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x50, 0x01, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x33, } var ( @@ -3044,48 +3183,50 @@ func file_Groups_proto_rawDescGZIP() []byte { } var file_Groups_proto_enumTypes = make([]protoimpl.EnumInfo, 2) -var file_Groups_proto_msgTypes = make([]protoimpl.MessageInfo, 38) +var file_Groups_proto_msgTypes = make([]protoimpl.MessageInfo, 40) var file_Groups_proto_goTypes = []interface{}{ - (Member_Role)(0), // 0: Member.Role - (AccessControl_AccessRequired)(0), // 1: AccessControl.AccessRequired - (*AvatarUploadAttributes)(nil), // 2: AvatarUploadAttributes - (*Member)(nil), // 3: Member - (*PendingMember)(nil), // 4: PendingMember - (*RequestingMember)(nil), // 5: RequestingMember - (*BannedMember)(nil), // 6: BannedMember - (*AccessControl)(nil), // 7: AccessControl - (*Group)(nil), // 8: Group - (*GroupChange)(nil), // 9: GroupChange - (*GroupChanges)(nil), // 10: GroupChanges - (*GroupAttributeBlob)(nil), // 11: GroupAttributeBlob - (*GroupInviteLink)(nil), // 12: GroupInviteLink - (*GroupJoinInfo)(nil), // 13: GroupJoinInfo - (*GroupExternalCredential)(nil), // 14: GroupExternalCredential - (*GroupChange_Actions)(nil), // 15: GroupChange.Actions - (*GroupChange_Actions_AddMemberAction)(nil), // 16: GroupChange.Actions.AddMemberAction - (*GroupChange_Actions_DeleteMemberAction)(nil), // 17: GroupChange.Actions.DeleteMemberAction - (*GroupChange_Actions_ModifyMemberRoleAction)(nil), // 18: GroupChange.Actions.ModifyMemberRoleAction - (*GroupChange_Actions_ModifyMemberProfileKeyAction)(nil), // 19: GroupChange.Actions.ModifyMemberProfileKeyAction - (*GroupChange_Actions_AddPendingMemberAction)(nil), // 20: GroupChange.Actions.AddPendingMemberAction - (*GroupChange_Actions_DeletePendingMemberAction)(nil), // 21: GroupChange.Actions.DeletePendingMemberAction - (*GroupChange_Actions_PromotePendingMemberAction)(nil), // 22: GroupChange.Actions.PromotePendingMemberAction - (*GroupChange_Actions_PromotePendingPniAciMemberProfileKeyAction)(nil), // 23: GroupChange.Actions.PromotePendingPniAciMemberProfileKeyAction - (*GroupChange_Actions_AddRequestingMemberAction)(nil), // 24: GroupChange.Actions.AddRequestingMemberAction - (*GroupChange_Actions_DeleteRequestingMemberAction)(nil), // 25: GroupChange.Actions.DeleteRequestingMemberAction - (*GroupChange_Actions_PromoteRequestingMemberAction)(nil), // 26: GroupChange.Actions.PromoteRequestingMemberAction - (*GroupChange_Actions_AddBannedMemberAction)(nil), // 27: GroupChange.Actions.AddBannedMemberAction - (*GroupChange_Actions_DeleteBannedMemberAction)(nil), // 28: GroupChange.Actions.DeleteBannedMemberAction - (*GroupChange_Actions_ModifyTitleAction)(nil), // 29: GroupChange.Actions.ModifyTitleAction - (*GroupChange_Actions_ModifyDescriptionAction)(nil), // 30: GroupChange.Actions.ModifyDescriptionAction - (*GroupChange_Actions_ModifyAvatarAction)(nil), // 31: GroupChange.Actions.ModifyAvatarAction - (*GroupChange_Actions_ModifyDisappearingMessagesTimerAction)(nil), // 32: GroupChange.Actions.ModifyDisappearingMessagesTimerAction - (*GroupChange_Actions_ModifyAttributesAccessControlAction)(nil), // 33: GroupChange.Actions.ModifyAttributesAccessControlAction - (*GroupChange_Actions_ModifyMembersAccessControlAction)(nil), // 34: GroupChange.Actions.ModifyMembersAccessControlAction - (*GroupChange_Actions_ModifyAddFromInviteLinkAccessControlAction)(nil), // 35: GroupChange.Actions.ModifyAddFromInviteLinkAccessControlAction - (*GroupChange_Actions_ModifyInviteLinkPasswordAction)(nil), // 36: GroupChange.Actions.ModifyInviteLinkPasswordAction - (*GroupChange_Actions_ModifyAnnouncementsOnlyAction)(nil), // 37: GroupChange.Actions.ModifyAnnouncementsOnlyAction - (*GroupChanges_GroupChangeState)(nil), // 38: GroupChanges.GroupChangeState - (*GroupInviteLink_GroupInviteLinkContentsV1)(nil), // 39: GroupInviteLink.GroupInviteLinkContentsV1 + (Member_Role)(0), // 0: Member.Role + (AccessControl_AccessRequired)(0), // 1: AccessControl.AccessRequired + (*AvatarUploadAttributes)(nil), // 2: AvatarUploadAttributes + (*Member)(nil), // 3: Member + (*PendingMember)(nil), // 4: PendingMember + (*RequestingMember)(nil), // 5: RequestingMember + (*BannedMember)(nil), // 6: BannedMember + (*AccessControl)(nil), // 7: AccessControl + (*Group)(nil), // 8: Group + (*GroupChange)(nil), // 9: GroupChange + (*GroupResponse)(nil), // 10: GroupResponse + (*GroupChanges)(nil), // 11: GroupChanges + (*GroupChangeResponse)(nil), // 12: GroupChangeResponse + (*GroupAttributeBlob)(nil), // 13: GroupAttributeBlob + (*GroupInviteLink)(nil), // 14: GroupInviteLink + (*GroupJoinInfo)(nil), // 15: GroupJoinInfo + (*GroupExternalCredential)(nil), // 16: GroupExternalCredential + (*GroupChange_Actions)(nil), // 17: GroupChange.Actions + (*GroupChange_Actions_AddMemberAction)(nil), // 18: GroupChange.Actions.AddMemberAction + (*GroupChange_Actions_DeleteMemberAction)(nil), // 19: GroupChange.Actions.DeleteMemberAction + (*GroupChange_Actions_ModifyMemberRoleAction)(nil), // 20: GroupChange.Actions.ModifyMemberRoleAction + (*GroupChange_Actions_ModifyMemberProfileKeyAction)(nil), // 21: GroupChange.Actions.ModifyMemberProfileKeyAction + (*GroupChange_Actions_AddPendingMemberAction)(nil), // 22: GroupChange.Actions.AddPendingMemberAction + (*GroupChange_Actions_DeletePendingMemberAction)(nil), // 23: GroupChange.Actions.DeletePendingMemberAction + (*GroupChange_Actions_PromotePendingMemberAction)(nil), // 24: GroupChange.Actions.PromotePendingMemberAction + (*GroupChange_Actions_PromotePendingPniAciMemberProfileKeyAction)(nil), // 25: GroupChange.Actions.PromotePendingPniAciMemberProfileKeyAction + (*GroupChange_Actions_AddRequestingMemberAction)(nil), // 26: GroupChange.Actions.AddRequestingMemberAction + (*GroupChange_Actions_DeleteRequestingMemberAction)(nil), // 27: GroupChange.Actions.DeleteRequestingMemberAction + (*GroupChange_Actions_PromoteRequestingMemberAction)(nil), // 28: GroupChange.Actions.PromoteRequestingMemberAction + (*GroupChange_Actions_AddBannedMemberAction)(nil), // 29: GroupChange.Actions.AddBannedMemberAction + (*GroupChange_Actions_DeleteBannedMemberAction)(nil), // 30: GroupChange.Actions.DeleteBannedMemberAction + (*GroupChange_Actions_ModifyTitleAction)(nil), // 31: GroupChange.Actions.ModifyTitleAction + (*GroupChange_Actions_ModifyDescriptionAction)(nil), // 32: GroupChange.Actions.ModifyDescriptionAction + (*GroupChange_Actions_ModifyAvatarAction)(nil), // 33: GroupChange.Actions.ModifyAvatarAction + (*GroupChange_Actions_ModifyDisappearingMessagesTimerAction)(nil), // 34: GroupChange.Actions.ModifyDisappearingMessagesTimerAction + (*GroupChange_Actions_ModifyAttributesAccessControlAction)(nil), // 35: GroupChange.Actions.ModifyAttributesAccessControlAction + (*GroupChange_Actions_ModifyMembersAccessControlAction)(nil), // 36: GroupChange.Actions.ModifyMembersAccessControlAction + (*GroupChange_Actions_ModifyAddFromInviteLinkAccessControlAction)(nil), // 37: GroupChange.Actions.ModifyAddFromInviteLinkAccessControlAction + (*GroupChange_Actions_ModifyInviteLinkPasswordAction)(nil), // 38: GroupChange.Actions.ModifyInviteLinkPasswordAction + (*GroupChange_Actions_ModifyAnnouncementsOnlyAction)(nil), // 39: GroupChange.Actions.ModifyAnnouncementsOnlyAction + (*GroupChanges_GroupChangeState)(nil), // 40: GroupChanges.GroupChangeState + (*GroupInviteLink_GroupInviteLinkContentsV1)(nil), // 41: GroupInviteLink.GroupInviteLinkContentsV1 } var file_Groups_proto_depIdxs = []int32{ 0, // 0: Member.role:type_name -> Member.Role @@ -3098,47 +3239,49 @@ var file_Groups_proto_depIdxs = []int32{ 4, // 7: Group.pendingMembers:type_name -> PendingMember 5, // 8: Group.requestingMembers:type_name -> RequestingMember 6, // 9: Group.bannedMembers:type_name -> BannedMember - 38, // 10: GroupChanges.groupChanges:type_name -> GroupChanges.GroupChangeState - 39, // 11: GroupInviteLink.v1Contents:type_name -> GroupInviteLink.GroupInviteLinkContentsV1 - 1, // 12: GroupJoinInfo.addFromInviteLink:type_name -> AccessControl.AccessRequired - 16, // 13: GroupChange.Actions.addMembers:type_name -> GroupChange.Actions.AddMemberAction - 17, // 14: GroupChange.Actions.deleteMembers:type_name -> GroupChange.Actions.DeleteMemberAction - 18, // 15: GroupChange.Actions.modifyMemberRoles:type_name -> GroupChange.Actions.ModifyMemberRoleAction - 19, // 16: GroupChange.Actions.modifyMemberProfileKeys:type_name -> GroupChange.Actions.ModifyMemberProfileKeyAction - 20, // 17: GroupChange.Actions.addPendingMembers:type_name -> GroupChange.Actions.AddPendingMemberAction - 21, // 18: GroupChange.Actions.deletePendingMembers:type_name -> GroupChange.Actions.DeletePendingMemberAction - 22, // 19: GroupChange.Actions.promotePendingMembers:type_name -> GroupChange.Actions.PromotePendingMemberAction - 29, // 20: GroupChange.Actions.modifyTitle:type_name -> GroupChange.Actions.ModifyTitleAction - 31, // 21: GroupChange.Actions.modifyAvatar:type_name -> GroupChange.Actions.ModifyAvatarAction - 32, // 22: GroupChange.Actions.modifyDisappearingMessagesTimer:type_name -> GroupChange.Actions.ModifyDisappearingMessagesTimerAction - 33, // 23: GroupChange.Actions.modifyAttributesAccess:type_name -> GroupChange.Actions.ModifyAttributesAccessControlAction - 34, // 24: GroupChange.Actions.modifyMemberAccess:type_name -> GroupChange.Actions.ModifyMembersAccessControlAction - 35, // 25: GroupChange.Actions.modifyAddFromInviteLinkAccess:type_name -> GroupChange.Actions.ModifyAddFromInviteLinkAccessControlAction - 24, // 26: GroupChange.Actions.addRequestingMembers:type_name -> GroupChange.Actions.AddRequestingMemberAction - 25, // 27: GroupChange.Actions.deleteRequestingMembers:type_name -> GroupChange.Actions.DeleteRequestingMemberAction - 26, // 28: GroupChange.Actions.promoteRequestingMembers:type_name -> GroupChange.Actions.PromoteRequestingMemberAction - 36, // 29: GroupChange.Actions.modifyInviteLinkPassword:type_name -> GroupChange.Actions.ModifyInviteLinkPasswordAction - 30, // 30: GroupChange.Actions.modifyDescription:type_name -> GroupChange.Actions.ModifyDescriptionAction - 37, // 31: GroupChange.Actions.modifyAnnouncementsOnly:type_name -> GroupChange.Actions.ModifyAnnouncementsOnlyAction - 27, // 32: GroupChange.Actions.addBannedMembers:type_name -> GroupChange.Actions.AddBannedMemberAction - 28, // 33: GroupChange.Actions.deleteBannedMembers:type_name -> GroupChange.Actions.DeleteBannedMemberAction - 23, // 34: GroupChange.Actions.promotePendingPniAciMembers:type_name -> GroupChange.Actions.PromotePendingPniAciMemberProfileKeyAction - 3, // 35: GroupChange.Actions.AddMemberAction.added:type_name -> Member - 0, // 36: GroupChange.Actions.ModifyMemberRoleAction.role:type_name -> Member.Role - 4, // 37: GroupChange.Actions.AddPendingMemberAction.added:type_name -> PendingMember - 5, // 38: GroupChange.Actions.AddRequestingMemberAction.added:type_name -> RequestingMember - 0, // 39: GroupChange.Actions.PromoteRequestingMemberAction.role:type_name -> Member.Role - 6, // 40: GroupChange.Actions.AddBannedMemberAction.added:type_name -> BannedMember - 1, // 41: GroupChange.Actions.ModifyAttributesAccessControlAction.attributesAccess:type_name -> AccessControl.AccessRequired - 1, // 42: GroupChange.Actions.ModifyMembersAccessControlAction.membersAccess:type_name -> AccessControl.AccessRequired - 1, // 43: GroupChange.Actions.ModifyAddFromInviteLinkAccessControlAction.addFromInviteLinkAccess:type_name -> AccessControl.AccessRequired - 9, // 44: GroupChanges.GroupChangeState.groupChange:type_name -> GroupChange - 8, // 45: GroupChanges.GroupChangeState.groupState:type_name -> Group - 46, // [46:46] is the sub-list for method output_type - 46, // [46:46] is the sub-list for method input_type - 46, // [46:46] is the sub-list for extension type_name - 46, // [46:46] is the sub-list for extension extendee - 0, // [0:46] is the sub-list for field type_name + 8, // 10: GroupResponse.group:type_name -> Group + 40, // 11: GroupChanges.groupChanges:type_name -> GroupChanges.GroupChangeState + 9, // 12: GroupChangeResponse.groupChange:type_name -> GroupChange + 41, // 13: GroupInviteLink.v1Contents:type_name -> GroupInviteLink.GroupInviteLinkContentsV1 + 1, // 14: GroupJoinInfo.addFromInviteLink:type_name -> AccessControl.AccessRequired + 18, // 15: GroupChange.Actions.addMembers:type_name -> GroupChange.Actions.AddMemberAction + 19, // 16: GroupChange.Actions.deleteMembers:type_name -> GroupChange.Actions.DeleteMemberAction + 20, // 17: GroupChange.Actions.modifyMemberRoles:type_name -> GroupChange.Actions.ModifyMemberRoleAction + 21, // 18: GroupChange.Actions.modifyMemberProfileKeys:type_name -> GroupChange.Actions.ModifyMemberProfileKeyAction + 22, // 19: GroupChange.Actions.addPendingMembers:type_name -> GroupChange.Actions.AddPendingMemberAction + 23, // 20: GroupChange.Actions.deletePendingMembers:type_name -> GroupChange.Actions.DeletePendingMemberAction + 24, // 21: GroupChange.Actions.promotePendingMembers:type_name -> GroupChange.Actions.PromotePendingMemberAction + 31, // 22: GroupChange.Actions.modifyTitle:type_name -> GroupChange.Actions.ModifyTitleAction + 33, // 23: GroupChange.Actions.modifyAvatar:type_name -> GroupChange.Actions.ModifyAvatarAction + 34, // 24: GroupChange.Actions.modifyDisappearingMessagesTimer:type_name -> GroupChange.Actions.ModifyDisappearingMessagesTimerAction + 35, // 25: GroupChange.Actions.modifyAttributesAccess:type_name -> GroupChange.Actions.ModifyAttributesAccessControlAction + 36, // 26: GroupChange.Actions.modifyMemberAccess:type_name -> GroupChange.Actions.ModifyMembersAccessControlAction + 37, // 27: GroupChange.Actions.modifyAddFromInviteLinkAccess:type_name -> GroupChange.Actions.ModifyAddFromInviteLinkAccessControlAction + 26, // 28: GroupChange.Actions.addRequestingMembers:type_name -> GroupChange.Actions.AddRequestingMemberAction + 27, // 29: GroupChange.Actions.deleteRequestingMembers:type_name -> GroupChange.Actions.DeleteRequestingMemberAction + 28, // 30: GroupChange.Actions.promoteRequestingMembers:type_name -> GroupChange.Actions.PromoteRequestingMemberAction + 38, // 31: GroupChange.Actions.modifyInviteLinkPassword:type_name -> GroupChange.Actions.ModifyInviteLinkPasswordAction + 32, // 32: GroupChange.Actions.modifyDescription:type_name -> GroupChange.Actions.ModifyDescriptionAction + 39, // 33: GroupChange.Actions.modifyAnnouncementsOnly:type_name -> GroupChange.Actions.ModifyAnnouncementsOnlyAction + 29, // 34: GroupChange.Actions.addBannedMembers:type_name -> GroupChange.Actions.AddBannedMemberAction + 30, // 35: GroupChange.Actions.deleteBannedMembers:type_name -> GroupChange.Actions.DeleteBannedMemberAction + 25, // 36: GroupChange.Actions.promotePendingPniAciMembers:type_name -> GroupChange.Actions.PromotePendingPniAciMemberProfileKeyAction + 3, // 37: GroupChange.Actions.AddMemberAction.added:type_name -> Member + 0, // 38: GroupChange.Actions.ModifyMemberRoleAction.role:type_name -> Member.Role + 4, // 39: GroupChange.Actions.AddPendingMemberAction.added:type_name -> PendingMember + 5, // 40: GroupChange.Actions.AddRequestingMemberAction.added:type_name -> RequestingMember + 0, // 41: GroupChange.Actions.PromoteRequestingMemberAction.role:type_name -> Member.Role + 6, // 42: GroupChange.Actions.AddBannedMemberAction.added:type_name -> BannedMember + 1, // 43: GroupChange.Actions.ModifyAttributesAccessControlAction.attributesAccess:type_name -> AccessControl.AccessRequired + 1, // 44: GroupChange.Actions.ModifyMembersAccessControlAction.membersAccess:type_name -> AccessControl.AccessRequired + 1, // 45: GroupChange.Actions.ModifyAddFromInviteLinkAccessControlAction.addFromInviteLinkAccess:type_name -> AccessControl.AccessRequired + 9, // 46: GroupChanges.GroupChangeState.groupChange:type_name -> GroupChange + 8, // 47: GroupChanges.GroupChangeState.groupState:type_name -> Group + 48, // [48:48] is the sub-list for method output_type + 48, // [48:48] is the sub-list for method input_type + 48, // [48:48] is the sub-list for extension type_name + 48, // [48:48] is the sub-list for extension extendee + 0, // [0:48] is the sub-list for field type_name } func init() { file_Groups_proto_init() } @@ -3244,7 +3387,7 @@ func file_Groups_proto_init() { } } file_Groups_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*GroupChanges); i { + switch v := v.(*GroupResponse); i { case 0: return &v.state case 1: @@ -3256,7 +3399,7 @@ func file_Groups_proto_init() { } } file_Groups_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*GroupAttributeBlob); i { + switch v := v.(*GroupChanges); i { case 0: return &v.state case 1: @@ -3268,7 +3411,7 @@ func file_Groups_proto_init() { } } file_Groups_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*GroupInviteLink); i { + switch v := v.(*GroupChangeResponse); i { case 0: return &v.state case 1: @@ -3280,7 +3423,7 @@ func file_Groups_proto_init() { } } file_Groups_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*GroupJoinInfo); i { + switch v := v.(*GroupAttributeBlob); i { case 0: return &v.state case 1: @@ -3292,7 +3435,7 @@ func file_Groups_proto_init() { } } file_Groups_proto_msgTypes[12].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*GroupExternalCredential); i { + switch v := v.(*GroupInviteLink); i { case 0: return &v.state case 1: @@ -3304,7 +3447,7 @@ func file_Groups_proto_init() { } } file_Groups_proto_msgTypes[13].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*GroupChange_Actions); i { + switch v := v.(*GroupJoinInfo); i { case 0: return &v.state case 1: @@ -3316,7 +3459,7 @@ func file_Groups_proto_init() { } } file_Groups_proto_msgTypes[14].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*GroupChange_Actions_AddMemberAction); i { + switch v := v.(*GroupExternalCredential); i { case 0: return &v.state case 1: @@ -3328,7 +3471,7 @@ func file_Groups_proto_init() { } } file_Groups_proto_msgTypes[15].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*GroupChange_Actions_DeleteMemberAction); i { + switch v := v.(*GroupChange_Actions); i { case 0: return &v.state case 1: @@ -3340,7 +3483,7 @@ func file_Groups_proto_init() { } } file_Groups_proto_msgTypes[16].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*GroupChange_Actions_ModifyMemberRoleAction); i { + switch v := v.(*GroupChange_Actions_AddMemberAction); i { case 0: return &v.state case 1: @@ -3352,7 +3495,7 @@ func file_Groups_proto_init() { } } file_Groups_proto_msgTypes[17].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*GroupChange_Actions_ModifyMemberProfileKeyAction); i { + switch v := v.(*GroupChange_Actions_DeleteMemberAction); i { case 0: return &v.state case 1: @@ -3364,7 +3507,7 @@ func file_Groups_proto_init() { } } file_Groups_proto_msgTypes[18].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*GroupChange_Actions_AddPendingMemberAction); i { + switch v := v.(*GroupChange_Actions_ModifyMemberRoleAction); i { case 0: return &v.state case 1: @@ -3376,7 +3519,7 @@ func file_Groups_proto_init() { } } file_Groups_proto_msgTypes[19].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*GroupChange_Actions_DeletePendingMemberAction); i { + switch v := v.(*GroupChange_Actions_ModifyMemberProfileKeyAction); i { case 0: return &v.state case 1: @@ -3388,7 +3531,7 @@ func file_Groups_proto_init() { } } file_Groups_proto_msgTypes[20].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*GroupChange_Actions_PromotePendingMemberAction); i { + switch v := v.(*GroupChange_Actions_AddPendingMemberAction); i { case 0: return &v.state case 1: @@ -3400,7 +3543,7 @@ func file_Groups_proto_init() { } } file_Groups_proto_msgTypes[21].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*GroupChange_Actions_PromotePendingPniAciMemberProfileKeyAction); i { + switch v := v.(*GroupChange_Actions_DeletePendingMemberAction); i { case 0: return &v.state case 1: @@ -3412,7 +3555,7 @@ func file_Groups_proto_init() { } } file_Groups_proto_msgTypes[22].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*GroupChange_Actions_AddRequestingMemberAction); i { + switch v := v.(*GroupChange_Actions_PromotePendingMemberAction); i { case 0: return &v.state case 1: @@ -3424,7 +3567,7 @@ func file_Groups_proto_init() { } } file_Groups_proto_msgTypes[23].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*GroupChange_Actions_DeleteRequestingMemberAction); i { + switch v := v.(*GroupChange_Actions_PromotePendingPniAciMemberProfileKeyAction); i { case 0: return &v.state case 1: @@ -3436,7 +3579,7 @@ func file_Groups_proto_init() { } } file_Groups_proto_msgTypes[24].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*GroupChange_Actions_PromoteRequestingMemberAction); i { + switch v := v.(*GroupChange_Actions_AddRequestingMemberAction); i { case 0: return &v.state case 1: @@ -3448,7 +3591,7 @@ func file_Groups_proto_init() { } } file_Groups_proto_msgTypes[25].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*GroupChange_Actions_AddBannedMemberAction); i { + switch v := v.(*GroupChange_Actions_DeleteRequestingMemberAction); i { case 0: return &v.state case 1: @@ -3460,7 +3603,7 @@ func file_Groups_proto_init() { } } file_Groups_proto_msgTypes[26].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*GroupChange_Actions_DeleteBannedMemberAction); i { + switch v := v.(*GroupChange_Actions_PromoteRequestingMemberAction); i { case 0: return &v.state case 1: @@ -3472,7 +3615,7 @@ func file_Groups_proto_init() { } } file_Groups_proto_msgTypes[27].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*GroupChange_Actions_ModifyTitleAction); i { + switch v := v.(*GroupChange_Actions_AddBannedMemberAction); i { case 0: return &v.state case 1: @@ -3484,7 +3627,7 @@ func file_Groups_proto_init() { } } file_Groups_proto_msgTypes[28].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*GroupChange_Actions_ModifyDescriptionAction); i { + switch v := v.(*GroupChange_Actions_DeleteBannedMemberAction); i { case 0: return &v.state case 1: @@ -3496,7 +3639,7 @@ func file_Groups_proto_init() { } } file_Groups_proto_msgTypes[29].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*GroupChange_Actions_ModifyAvatarAction); i { + switch v := v.(*GroupChange_Actions_ModifyTitleAction); i { case 0: return &v.state case 1: @@ -3508,7 +3651,7 @@ func file_Groups_proto_init() { } } file_Groups_proto_msgTypes[30].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*GroupChange_Actions_ModifyDisappearingMessagesTimerAction); i { + switch v := v.(*GroupChange_Actions_ModifyDescriptionAction); i { case 0: return &v.state case 1: @@ -3520,7 +3663,7 @@ func file_Groups_proto_init() { } } file_Groups_proto_msgTypes[31].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*GroupChange_Actions_ModifyAttributesAccessControlAction); i { + switch v := v.(*GroupChange_Actions_ModifyAvatarAction); i { case 0: return &v.state case 1: @@ -3532,7 +3675,7 @@ func file_Groups_proto_init() { } } file_Groups_proto_msgTypes[32].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*GroupChange_Actions_ModifyMembersAccessControlAction); i { + switch v := v.(*GroupChange_Actions_ModifyDisappearingMessagesTimerAction); i { case 0: return &v.state case 1: @@ -3544,7 +3687,7 @@ func file_Groups_proto_init() { } } file_Groups_proto_msgTypes[33].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*GroupChange_Actions_ModifyAddFromInviteLinkAccessControlAction); i { + switch v := v.(*GroupChange_Actions_ModifyAttributesAccessControlAction); i { case 0: return &v.state case 1: @@ -3556,7 +3699,7 @@ func file_Groups_proto_init() { } } file_Groups_proto_msgTypes[34].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*GroupChange_Actions_ModifyInviteLinkPasswordAction); i { + switch v := v.(*GroupChange_Actions_ModifyMembersAccessControlAction); i { case 0: return &v.state case 1: @@ -3568,7 +3711,7 @@ func file_Groups_proto_init() { } } file_Groups_proto_msgTypes[35].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*GroupChange_Actions_ModifyAnnouncementsOnlyAction); i { + switch v := v.(*GroupChange_Actions_ModifyAddFromInviteLinkAccessControlAction); i { case 0: return &v.state case 1: @@ -3580,7 +3723,7 @@ func file_Groups_proto_init() { } } file_Groups_proto_msgTypes[36].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*GroupChanges_GroupChangeState); i { + switch v := v.(*GroupChange_Actions_ModifyInviteLinkPasswordAction); i { case 0: return &v.state case 1: @@ -3592,6 +3735,30 @@ func file_Groups_proto_init() { } } file_Groups_proto_msgTypes[37].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GroupChange_Actions_ModifyAnnouncementsOnlyAction); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_Groups_proto_msgTypes[38].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GroupChanges_GroupChangeState); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_Groups_proto_msgTypes[39].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*GroupInviteLink_GroupInviteLinkContentsV1); i { case 0: return &v.state @@ -3604,13 +3771,13 @@ func file_Groups_proto_init() { } } } - file_Groups_proto_msgTypes[9].OneofWrappers = []interface{}{ + file_Groups_proto_msgTypes[11].OneofWrappers = []interface{}{ (*GroupAttributeBlob_Title)(nil), (*GroupAttributeBlob_Avatar)(nil), (*GroupAttributeBlob_DisappearingMessagesDuration)(nil), (*GroupAttributeBlob_Description)(nil), } - file_Groups_proto_msgTypes[10].OneofWrappers = []interface{}{ + file_Groups_proto_msgTypes[12].OneofWrappers = []interface{}{ (*GroupInviteLink_V1Contents)(nil), } type x struct{} @@ -3619,7 +3786,7 @@ func file_Groups_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_Groups_proto_rawDesc, NumEnums: 2, - NumMessages: 38, + NumMessages: 40, NumExtensions: 0, NumServices: 0, }, diff --git a/pkg/signalmeow/protobuf/Groups.proto b/pkg/signalmeow/protobuf/Groups.proto index 3f0b730..63970c7 100644 --- a/pkg/signalmeow/protobuf/Groups.proto +++ b/pkg/signalmeow/protobuf/Groups.proto @@ -213,13 +213,24 @@ message GroupChange { uint32 changeEpoch = 3; } +message GroupResponse { + Group group = 1; + bytes groupSendEndorsementsResponse = 2; +} + message GroupChanges { message GroupChangeState { GroupChange groupChange = 1; Group groupState = 2; } - repeated GroupChangeState groupChanges = 1; + repeated GroupChangeState groupChanges = 1; + bytes groupSendEndorsementsResponse = 2; +} + +message GroupChangeResponse { + GroupChange groupChange = 1; + bytes groupSendEndorsementsResponse = 2; } message GroupAttributeBlob { diff --git a/pkg/signalmeow/protobuf/SignalService.pb.go b/pkg/signalmeow/protobuf/SignalService.pb.go index 1ff1228..7987d7c 100644 --- a/pkg/signalmeow/protobuf/SignalService.pb.go +++ b/pkg/signalmeow/protobuf/SignalService.pb.go @@ -1403,6 +1403,7 @@ const ( SyncMessage_CallEvent_ACCEPTED SyncMessage_CallEvent_Event = 1 SyncMessage_CallEvent_NOT_ACCEPTED SyncMessage_CallEvent_Event = 2 SyncMessage_CallEvent_DELETE SyncMessage_CallEvent_Event = 3 + SyncMessage_CallEvent_OBSERVED SyncMessage_CallEvent_Event = 4 ) // Enum value maps for SyncMessage_CallEvent_Event. @@ -1412,12 +1413,14 @@ var ( 1: "ACCEPTED", 2: "NOT_ACCEPTED", 3: "DELETE", + 4: "OBSERVED", } SyncMessage_CallEvent_Event_value = map[string]int32{ "UNKNOWN_ACTION": 0, "ACCEPTED": 1, "NOT_ACCEPTED": 2, "DELETE": 3, + "OBSERVED": 4, } ) @@ -3119,7 +3122,8 @@ type AttachmentPointer struct { Caption *string `protobuf:"bytes,11,opt,name=caption" json:"caption,omitempty"` BlurHash *string `protobuf:"bytes,12,opt,name=blurHash" json:"blurHash,omitempty"` UploadTimestamp *uint64 `protobuf:"varint,13,opt,name=uploadTimestamp" json:"uploadTimestamp,omitempty"` - CdnNumber *uint32 `protobuf:"varint,14,opt,name=cdnNumber" json:"cdnNumber,omitempty"` // Next ID: 19 + CdnNumber *uint32 `protobuf:"varint,14,opt,name=cdnNumber" json:"cdnNumber,omitempty"` + Uuid []byte `protobuf:"bytes,20,opt,name=uuid" json:"uuid,omitempty"` // Next ID: 21 } func (x *AttachmentPointer) Reset() { @@ -3280,6 +3284,13 @@ func (x *AttachmentPointer) GetCdnNumber() uint32 { return 0 } +func (x *AttachmentPointer) GetUuid() []byte { + if x != nil { + return x.Uuid + } + return nil +} + type isAttachmentPointer_AttachmentIdentifier interface { isAttachmentPointer_AttachmentIdentifier() } @@ -6844,6 +6855,7 @@ type SyncMessage_DeleteForMe struct { MessageDeletes []*SyncMessage_DeleteForMe_MessageDeletes `protobuf:"bytes,1,rep,name=messageDeletes" json:"messageDeletes,omitempty"` ConversationDeletes []*SyncMessage_DeleteForMe_ConversationDelete `protobuf:"bytes,2,rep,name=conversationDeletes" json:"conversationDeletes,omitempty"` LocalOnlyConversationDeletes []*SyncMessage_DeleteForMe_LocalOnlyConversationDelete `protobuf:"bytes,3,rep,name=localOnlyConversationDeletes" json:"localOnlyConversationDeletes,omitempty"` + AttachmentDeletes []*SyncMessage_DeleteForMe_AttachmentDelete `protobuf:"bytes,4,rep,name=attachmentDeletes" json:"attachmentDeletes,omitempty"` } func (x *SyncMessage_DeleteForMe) Reset() { @@ -6899,6 +6911,13 @@ func (x *SyncMessage_DeleteForMe) GetLocalOnlyConversationDeletes() []*SyncMessa return nil } +func (x *SyncMessage_DeleteForMe) GetAttachmentDeletes() []*SyncMessage_DeleteForMe_AttachmentDelete { + if x != nil { + return x.AttachmentDeletes + } + return nil +} + type SyncMessage_Sent_UnidentifiedDeliveryStatus struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -7138,7 +7157,7 @@ type SyncMessage_DeleteForMe_ConversationIdentifier struct { // Types that are assignable to Identifier: // - // *SyncMessage_DeleteForMe_ConversationIdentifier_ThreadAci + // *SyncMessage_DeleteForMe_ConversationIdentifier_ThreadServiceId // *SyncMessage_DeleteForMe_ConversationIdentifier_ThreadGroupId // *SyncMessage_DeleteForMe_ConversationIdentifier_ThreadE164 Identifier isSyncMessage_DeleteForMe_ConversationIdentifier_Identifier `protobuf_oneof:"identifier"` @@ -7183,9 +7202,9 @@ func (m *SyncMessage_DeleteForMe_ConversationIdentifier) GetIdentifier() isSyncM return nil } -func (x *SyncMessage_DeleteForMe_ConversationIdentifier) GetThreadAci() string { - if x, ok := x.GetIdentifier().(*SyncMessage_DeleteForMe_ConversationIdentifier_ThreadAci); ok { - return x.ThreadAci +func (x *SyncMessage_DeleteForMe_ConversationIdentifier) GetThreadServiceId() string { + if x, ok := x.GetIdentifier().(*SyncMessage_DeleteForMe_ConversationIdentifier_ThreadServiceId); ok { + return x.ThreadServiceId } return "" } @@ -7208,8 +7227,8 @@ type isSyncMessage_DeleteForMe_ConversationIdentifier_Identifier interface { isSyncMessage_DeleteForMe_ConversationIdentifier_Identifier() } -type SyncMessage_DeleteForMe_ConversationIdentifier_ThreadAci struct { - ThreadAci string `protobuf:"bytes,1,opt,name=threadAci,oneof"` +type SyncMessage_DeleteForMe_ConversationIdentifier_ThreadServiceId struct { + ThreadServiceId string `protobuf:"bytes,1,opt,name=threadServiceId,oneof"` } type SyncMessage_DeleteForMe_ConversationIdentifier_ThreadGroupId struct { @@ -7220,7 +7239,7 @@ type SyncMessage_DeleteForMe_ConversationIdentifier_ThreadE164 struct { ThreadE164 string `protobuf:"bytes,3,opt,name=threadE164,oneof"` } -func (*SyncMessage_DeleteForMe_ConversationIdentifier_ThreadAci) isSyncMessage_DeleteForMe_ConversationIdentifier_Identifier() { +func (*SyncMessage_DeleteForMe_ConversationIdentifier_ThreadServiceId) isSyncMessage_DeleteForMe_ConversationIdentifier_Identifier() { } func (*SyncMessage_DeleteForMe_ConversationIdentifier_ThreadGroupId) isSyncMessage_DeleteForMe_ConversationIdentifier_Identifier() { @@ -7236,7 +7255,7 @@ type SyncMessage_DeleteForMe_AddressableMessage struct { // Types that are assignable to Author: // - // *SyncMessage_DeleteForMe_AddressableMessage_AuthorAci + // *SyncMessage_DeleteForMe_AddressableMessage_AuthorServiceId // *SyncMessage_DeleteForMe_AddressableMessage_AuthorE164 Author isSyncMessage_DeleteForMe_AddressableMessage_Author `protobuf_oneof:"author"` SentTimestamp *uint64 `protobuf:"varint,3,opt,name=sentTimestamp" json:"sentTimestamp,omitempty"` @@ -7281,9 +7300,9 @@ func (m *SyncMessage_DeleteForMe_AddressableMessage) GetAuthor() isSyncMessage_D return nil } -func (x *SyncMessage_DeleteForMe_AddressableMessage) GetAuthorAci() string { - if x, ok := x.GetAuthor().(*SyncMessage_DeleteForMe_AddressableMessage_AuthorAci); ok { - return x.AuthorAci +func (x *SyncMessage_DeleteForMe_AddressableMessage) GetAuthorServiceId() string { + if x, ok := x.GetAuthor().(*SyncMessage_DeleteForMe_AddressableMessage_AuthorServiceId); ok { + return x.AuthorServiceId } return "" } @@ -7306,15 +7325,15 @@ type isSyncMessage_DeleteForMe_AddressableMessage_Author interface { isSyncMessage_DeleteForMe_AddressableMessage_Author() } -type SyncMessage_DeleteForMe_AddressableMessage_AuthorAci struct { - AuthorAci string `protobuf:"bytes,1,opt,name=authorAci,oneof"` +type SyncMessage_DeleteForMe_AddressableMessage_AuthorServiceId struct { + AuthorServiceId string `protobuf:"bytes,1,opt,name=authorServiceId,oneof"` } type SyncMessage_DeleteForMe_AddressableMessage_AuthorE164 struct { AuthorE164 string `protobuf:"bytes,2,opt,name=authorE164,oneof"` } -func (*SyncMessage_DeleteForMe_AddressableMessage_AuthorAci) isSyncMessage_DeleteForMe_AddressableMessage_Author() { +func (*SyncMessage_DeleteForMe_AddressableMessage_AuthorServiceId) isSyncMessage_DeleteForMe_AddressableMessage_Author() { } func (*SyncMessage_DeleteForMe_AddressableMessage_AuthorE164) isSyncMessage_DeleteForMe_AddressableMessage_Author() { @@ -7375,20 +7394,100 @@ func (x *SyncMessage_DeleteForMe_MessageDeletes) GetMessages() []*SyncMessage_De return nil } +type SyncMessage_DeleteForMe_AttachmentDelete struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Conversation *SyncMessage_DeleteForMe_ConversationIdentifier `protobuf:"bytes,1,opt,name=conversation" json:"conversation,omitempty"` + TargetMessage *SyncMessage_DeleteForMe_AddressableMessage `protobuf:"bytes,2,opt,name=targetMessage" json:"targetMessage,omitempty"` + Uuid []byte `protobuf:"bytes,3,opt,name=uuid" json:"uuid,omitempty"` // The `uuid` from the `Attachment`. + FallbackDigest []byte `protobuf:"bytes,4,opt,name=fallbackDigest" json:"fallbackDigest,omitempty"` + FallbackPlaintextHash []byte `protobuf:"bytes,5,opt,name=fallbackPlaintextHash" json:"fallbackPlaintextHash,omitempty"` +} + +func (x *SyncMessage_DeleteForMe_AttachmentDelete) Reset() { + *x = SyncMessage_DeleteForMe_AttachmentDelete{} + if protoimpl.UnsafeEnabled { + mi := &file_SignalService_proto_msgTypes[73] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *SyncMessage_DeleteForMe_AttachmentDelete) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SyncMessage_DeleteForMe_AttachmentDelete) ProtoMessage() {} + +func (x *SyncMessage_DeleteForMe_AttachmentDelete) ProtoReflect() protoreflect.Message { + mi := &file_SignalService_proto_msgTypes[73] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use SyncMessage_DeleteForMe_AttachmentDelete.ProtoReflect.Descriptor instead. +func (*SyncMessage_DeleteForMe_AttachmentDelete) Descriptor() ([]byte, []int) { + return file_SignalService_proto_rawDescGZIP(), []int{12, 17, 3} +} + +func (x *SyncMessage_DeleteForMe_AttachmentDelete) GetConversation() *SyncMessage_DeleteForMe_ConversationIdentifier { + if x != nil { + return x.Conversation + } + return nil +} + +func (x *SyncMessage_DeleteForMe_AttachmentDelete) GetTargetMessage() *SyncMessage_DeleteForMe_AddressableMessage { + if x != nil { + return x.TargetMessage + } + return nil +} + +func (x *SyncMessage_DeleteForMe_AttachmentDelete) GetUuid() []byte { + if x != nil { + return x.Uuid + } + return nil +} + +func (x *SyncMessage_DeleteForMe_AttachmentDelete) GetFallbackDigest() []byte { + if x != nil { + return x.FallbackDigest + } + return nil +} + +func (x *SyncMessage_DeleteForMe_AttachmentDelete) GetFallbackPlaintextHash() []byte { + if x != nil { + return x.FallbackPlaintextHash + } + return nil +} + type SyncMessage_DeleteForMe_ConversationDelete struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Conversation *SyncMessage_DeleteForMe_ConversationIdentifier `protobuf:"bytes,1,opt,name=conversation" json:"conversation,omitempty"` - MostRecentMessages []*SyncMessage_DeleteForMe_AddressableMessage `protobuf:"bytes,2,rep,name=mostRecentMessages" json:"mostRecentMessages,omitempty"` - IsFullDelete *bool `protobuf:"varint,3,opt,name=isFullDelete" json:"isFullDelete,omitempty"` + Conversation *SyncMessage_DeleteForMe_ConversationIdentifier `protobuf:"bytes,1,opt,name=conversation" json:"conversation,omitempty"` + MostRecentMessages []*SyncMessage_DeleteForMe_AddressableMessage `protobuf:"bytes,2,rep,name=mostRecentMessages" json:"mostRecentMessages,omitempty"` + MostRecentNonExpiringMessages []*SyncMessage_DeleteForMe_AddressableMessage `protobuf:"bytes,4,rep,name=mostRecentNonExpiringMessages" json:"mostRecentNonExpiringMessages,omitempty"` + IsFullDelete *bool `protobuf:"varint,3,opt,name=isFullDelete" json:"isFullDelete,omitempty"` } func (x *SyncMessage_DeleteForMe_ConversationDelete) Reset() { *x = SyncMessage_DeleteForMe_ConversationDelete{} if protoimpl.UnsafeEnabled { - mi := &file_SignalService_proto_msgTypes[73] + mi := &file_SignalService_proto_msgTypes[74] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7401,7 +7500,7 @@ func (x *SyncMessage_DeleteForMe_ConversationDelete) String() string { func (*SyncMessage_DeleteForMe_ConversationDelete) ProtoMessage() {} func (x *SyncMessage_DeleteForMe_ConversationDelete) ProtoReflect() protoreflect.Message { - mi := &file_SignalService_proto_msgTypes[73] + mi := &file_SignalService_proto_msgTypes[74] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7414,7 +7513,7 @@ func (x *SyncMessage_DeleteForMe_ConversationDelete) ProtoReflect() protoreflect // Deprecated: Use SyncMessage_DeleteForMe_ConversationDelete.ProtoReflect.Descriptor instead. func (*SyncMessage_DeleteForMe_ConversationDelete) Descriptor() ([]byte, []int) { - return file_SignalService_proto_rawDescGZIP(), []int{12, 17, 3} + return file_SignalService_proto_rawDescGZIP(), []int{12, 17, 4} } func (x *SyncMessage_DeleteForMe_ConversationDelete) GetConversation() *SyncMessage_DeleteForMe_ConversationIdentifier { @@ -7431,6 +7530,13 @@ func (x *SyncMessage_DeleteForMe_ConversationDelete) GetMostRecentMessages() []* return nil } +func (x *SyncMessage_DeleteForMe_ConversationDelete) GetMostRecentNonExpiringMessages() []*SyncMessage_DeleteForMe_AddressableMessage { + if x != nil { + return x.MostRecentNonExpiringMessages + } + return nil +} + func (x *SyncMessage_DeleteForMe_ConversationDelete) GetIsFullDelete() bool { if x != nil && x.IsFullDelete != nil { return *x.IsFullDelete @@ -7449,7 +7555,7 @@ type SyncMessage_DeleteForMe_LocalOnlyConversationDelete struct { func (x *SyncMessage_DeleteForMe_LocalOnlyConversationDelete) Reset() { *x = SyncMessage_DeleteForMe_LocalOnlyConversationDelete{} if protoimpl.UnsafeEnabled { - mi := &file_SignalService_proto_msgTypes[74] + mi := &file_SignalService_proto_msgTypes[75] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7462,7 +7568,7 @@ func (x *SyncMessage_DeleteForMe_LocalOnlyConversationDelete) String() string { func (*SyncMessage_DeleteForMe_LocalOnlyConversationDelete) ProtoMessage() {} func (x *SyncMessage_DeleteForMe_LocalOnlyConversationDelete) ProtoReflect() protoreflect.Message { - mi := &file_SignalService_proto_msgTypes[74] + mi := &file_SignalService_proto_msgTypes[75] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7475,7 +7581,7 @@ func (x *SyncMessage_DeleteForMe_LocalOnlyConversationDelete) ProtoReflect() pro // Deprecated: Use SyncMessage_DeleteForMe_LocalOnlyConversationDelete.ProtoReflect.Descriptor instead. func (*SyncMessage_DeleteForMe_LocalOnlyConversationDelete) Descriptor() ([]byte, []int) { - return file_SignalService_proto_rawDescGZIP(), []int{12, 17, 4} + return file_SignalService_proto_rawDescGZIP(), []int{12, 17, 5} } func (x *SyncMessage_DeleteForMe_LocalOnlyConversationDelete) GetConversation() *SyncMessage_DeleteForMe_ConversationIdentifier { @@ -7496,7 +7602,7 @@ type GroupContext_Member struct { func (x *GroupContext_Member) Reset() { *x = GroupContext_Member{} if protoimpl.UnsafeEnabled { - mi := &file_SignalService_proto_msgTypes[75] + mi := &file_SignalService_proto_msgTypes[76] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7509,7 +7615,7 @@ func (x *GroupContext_Member) String() string { func (*GroupContext_Member) ProtoMessage() {} func (x *GroupContext_Member) ProtoReflect() protoreflect.Message { - mi := &file_SignalService_proto_msgTypes[75] + mi := &file_SignalService_proto_msgTypes[76] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7544,7 +7650,7 @@ type ContactDetails_Avatar struct { func (x *ContactDetails_Avatar) Reset() { *x = ContactDetails_Avatar{} if protoimpl.UnsafeEnabled { - mi := &file_SignalService_proto_msgTypes[76] + mi := &file_SignalService_proto_msgTypes[77] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7557,7 +7663,7 @@ func (x *ContactDetails_Avatar) String() string { func (*ContactDetails_Avatar) ProtoMessage() {} func (x *ContactDetails_Avatar) ProtoReflect() protoreflect.Message { - mi := &file_SignalService_proto_msgTypes[76] + mi := &file_SignalService_proto_msgTypes[77] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7599,7 +7705,7 @@ type GroupDetails_Avatar struct { func (x *GroupDetails_Avatar) Reset() { *x = GroupDetails_Avatar{} if protoimpl.UnsafeEnabled { - mi := &file_SignalService_proto_msgTypes[77] + mi := &file_SignalService_proto_msgTypes[78] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7612,7 +7718,7 @@ func (x *GroupDetails_Avatar) String() string { func (*GroupDetails_Avatar) ProtoMessage() {} func (x *GroupDetails_Avatar) ProtoReflect() protoreflect.Message { - mi := &file_SignalService_proto_msgTypes[77] + mi := &file_SignalService_proto_msgTypes[78] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7653,7 +7759,7 @@ type GroupDetails_Member struct { func (x *GroupDetails_Member) Reset() { *x = GroupDetails_Member{} if protoimpl.UnsafeEnabled { - mi := &file_SignalService_proto_msgTypes[78] + mi := &file_SignalService_proto_msgTypes[79] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7666,7 +7772,7 @@ func (x *GroupDetails_Member) String() string { func (*GroupDetails_Member) ProtoMessage() {} func (x *GroupDetails_Member) ProtoReflect() protoreflect.Message { - mi := &file_SignalService_proto_msgTypes[78] + mi := &file_SignalService_proto_msgTypes[79] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7701,7 +7807,7 @@ type PaymentAddress_MobileCoinAddress struct { func (x *PaymentAddress_MobileCoinAddress) Reset() { *x = PaymentAddress_MobileCoinAddress{} if protoimpl.UnsafeEnabled { - mi := &file_SignalService_proto_msgTypes[79] + mi := &file_SignalService_proto_msgTypes[80] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7714,7 +7820,7 @@ func (x *PaymentAddress_MobileCoinAddress) String() string { func (*PaymentAddress_MobileCoinAddress) ProtoMessage() {} func (x *PaymentAddress_MobileCoinAddress) ProtoReflect() protoreflect.Message { - mi := &file_SignalService_proto_msgTypes[79] + mi := &file_SignalService_proto_msgTypes[80] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8301,7 +8407,7 @@ var file_SignalService_proto_rawDesc = []byte{ 0x67, 0x65, 0x22, 0x32, 0x0a, 0x05, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x0b, 0x0a, 0x07, 0x44, 0x45, 0x46, 0x41, 0x55, 0x4c, 0x54, 0x10, 0x00, 0x12, 0x0c, 0x0a, 0x08, 0x56, 0x45, 0x52, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x01, 0x12, 0x0e, 0x0a, 0x0a, 0x55, 0x4e, 0x56, 0x45, 0x52, 0x49, - 0x46, 0x49, 0x45, 0x44, 0x10, 0x02, 0x4a, 0x04, 0x08, 0x01, 0x10, 0x02, 0x22, 0x97, 0x36, 0x0a, + 0x46, 0x49, 0x45, 0x44, 0x10, 0x02, 0x4a, 0x04, 0x08, 0x01, 0x10, 0x02, 0x22, 0xf0, 0x3a, 0x0a, 0x0b, 0x53, 0x79, 0x6e, 0x63, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x33, 0x0a, 0x04, 0x73, 0x65, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x6c, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x53, 0x79, 0x6e, 0x63, 0x4d, @@ -8596,7 +8702,7 @@ var file_SignalService_proto_rawDesc = []byte{ 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0e, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x18, 0x0a, 0x07, 0x6e, 0x65, 0x77, 0x45, 0x31, 0x36, 0x34, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x07, 0x6e, 0x65, 0x77, 0x45, 0x31, 0x36, 0x34, 0x1a, 0x94, 0x04, 0x0a, 0x09, 0x43, 0x61, 0x6c, + 0x07, 0x6e, 0x65, 0x77, 0x45, 0x31, 0x36, 0x34, 0x1a, 0xa2, 0x04, 0x0a, 0x09, 0x43, 0x61, 0x6c, 0x6c, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x26, 0x0a, 0x0e, 0x63, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0e, 0x63, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x0e, @@ -8625,232 +8731,242 @@ var file_SignalService_proto_rawDesc = []byte{ 0x69, 0x6f, 0x6e, 0x12, 0x15, 0x0a, 0x11, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x5f, 0x44, 0x49, 0x52, 0x45, 0x43, 0x54, 0x49, 0x4f, 0x4e, 0x10, 0x00, 0x12, 0x0c, 0x0a, 0x08, 0x49, 0x4e, 0x43, 0x4f, 0x4d, 0x49, 0x4e, 0x47, 0x10, 0x01, 0x12, 0x0c, 0x0a, 0x08, 0x4f, 0x55, 0x54, 0x47, - 0x4f, 0x49, 0x4e, 0x47, 0x10, 0x02, 0x22, 0x47, 0x0a, 0x05, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, + 0x4f, 0x49, 0x4e, 0x47, 0x10, 0x02, 0x22, 0x55, 0x0a, 0x05, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x12, 0x0a, 0x0e, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x5f, 0x41, 0x43, 0x54, 0x49, 0x4f, 0x4e, 0x10, 0x00, 0x12, 0x0c, 0x0a, 0x08, 0x41, 0x43, 0x43, 0x45, 0x50, 0x54, 0x45, 0x44, 0x10, 0x01, 0x12, 0x10, 0x0a, 0x0c, 0x4e, 0x4f, 0x54, 0x5f, 0x41, 0x43, 0x43, 0x45, 0x50, 0x54, 0x45, - 0x44, 0x10, 0x02, 0x12, 0x0a, 0x0a, 0x06, 0x44, 0x45, 0x4c, 0x45, 0x54, 0x45, 0x10, 0x03, 0x1a, - 0xb2, 0x01, 0x0a, 0x0e, 0x43, 0x61, 0x6c, 0x6c, 0x4c, 0x69, 0x6e, 0x6b, 0x55, 0x70, 0x64, 0x61, - 0x74, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x72, 0x6f, 0x6f, 0x74, 0x4b, 0x65, 0x79, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x0c, 0x52, 0x07, 0x72, 0x6f, 0x6f, 0x74, 0x4b, 0x65, 0x79, 0x12, 0x22, 0x0a, 0x0c, - 0x61, 0x64, 0x6d, 0x69, 0x6e, 0x50, 0x61, 0x73, 0x73, 0x4b, 0x65, 0x79, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x0c, 0x52, 0x0c, 0x61, 0x64, 0x6d, 0x69, 0x6e, 0x50, 0x61, 0x73, 0x73, 0x4b, 0x65, 0x79, - 0x12, 0x42, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x2e, - 0x2e, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x6c, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x53, - 0x79, 0x6e, 0x63, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x43, 0x61, 0x6c, 0x6c, 0x4c, - 0x69, 0x6e, 0x6b, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x2e, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, - 0x74, 0x79, 0x70, 0x65, 0x22, 0x1e, 0x0a, 0x04, 0x54, 0x79, 0x70, 0x65, 0x12, 0x0a, 0x0a, 0x06, - 0x55, 0x50, 0x44, 0x41, 0x54, 0x45, 0x10, 0x00, 0x12, 0x0a, 0x0a, 0x06, 0x44, 0x45, 0x4c, 0x45, - 0x54, 0x45, 0x10, 0x01, 0x1a, 0xf9, 0x01, 0x0a, 0x0c, 0x43, 0x61, 0x6c, 0x6c, 0x4c, 0x6f, 0x67, - 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x40, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x0e, 0x32, 0x2c, 0x2e, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x6c, 0x73, 0x65, 0x72, 0x76, - 0x69, 0x63, 0x65, 0x2e, 0x53, 0x79, 0x6e, 0x63, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, - 0x43, 0x61, 0x6c, 0x6c, 0x4c, 0x6f, 0x67, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x2e, 0x54, 0x79, 0x70, - 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, - 0x74, 0x61, 0x6d, 0x70, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, - 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x26, 0x0a, 0x0e, 0x63, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0e, 0x63, - 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x16, 0x0a, - 0x06, 0x63, 0x61, 0x6c, 0x6c, 0x49, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x04, 0x52, 0x06, 0x63, - 0x61, 0x6c, 0x6c, 0x49, 0x64, 0x22, 0x49, 0x0a, 0x04, 0x54, 0x79, 0x70, 0x65, 0x12, 0x09, 0x0a, - 0x05, 0x43, 0x4c, 0x45, 0x41, 0x52, 0x10, 0x00, 0x12, 0x12, 0x0a, 0x0e, 0x4d, 0x41, 0x52, 0x4b, - 0x45, 0x44, 0x5f, 0x41, 0x53, 0x5f, 0x52, 0x45, 0x41, 0x44, 0x10, 0x01, 0x12, 0x22, 0x0a, 0x1e, - 0x4d, 0x41, 0x52, 0x4b, 0x45, 0x44, 0x5f, 0x41, 0x53, 0x5f, 0x52, 0x45, 0x41, 0x44, 0x5f, 0x49, - 0x4e, 0x5f, 0x43, 0x4f, 0x4e, 0x56, 0x45, 0x52, 0x53, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x10, 0x02, - 0x1a, 0xd7, 0x09, 0x0a, 0x0b, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x46, 0x6f, 0x72, 0x4d, 0x65, - 0x12, 0x5d, 0x0a, 0x0e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x44, 0x65, 0x6c, 0x65, 0x74, - 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x35, 0x2e, 0x73, 0x69, 0x67, 0x6e, 0x61, - 0x6c, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x53, 0x79, 0x6e, 0x63, 0x4d, 0x65, 0x73, - 0x73, 0x61, 0x67, 0x65, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x46, 0x6f, 0x72, 0x4d, 0x65, - 0x2e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x73, 0x52, - 0x0e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x73, 0x12, - 0x6b, 0x0a, 0x13, 0x63, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x44, - 0x65, 0x6c, 0x65, 0x74, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x39, 0x2e, 0x73, + 0x44, 0x10, 0x02, 0x12, 0x0a, 0x0a, 0x06, 0x44, 0x45, 0x4c, 0x45, 0x54, 0x45, 0x10, 0x03, 0x12, + 0x0c, 0x0a, 0x08, 0x4f, 0x42, 0x53, 0x45, 0x52, 0x56, 0x45, 0x44, 0x10, 0x04, 0x1a, 0xb2, 0x01, + 0x0a, 0x0e, 0x43, 0x61, 0x6c, 0x6c, 0x4c, 0x69, 0x6e, 0x6b, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, + 0x12, 0x18, 0x0a, 0x07, 0x72, 0x6f, 0x6f, 0x74, 0x4b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x0c, 0x52, 0x07, 0x72, 0x6f, 0x6f, 0x74, 0x4b, 0x65, 0x79, 0x12, 0x22, 0x0a, 0x0c, 0x61, 0x64, + 0x6d, 0x69, 0x6e, 0x50, 0x61, 0x73, 0x73, 0x4b, 0x65, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, + 0x52, 0x0c, 0x61, 0x64, 0x6d, 0x69, 0x6e, 0x50, 0x61, 0x73, 0x73, 0x4b, 0x65, 0x79, 0x12, 0x42, + 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x2e, 0x2e, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x6c, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x53, 0x79, 0x6e, - 0x63, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x46, - 0x6f, 0x72, 0x4d, 0x65, 0x2e, 0x43, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x13, 0x63, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x73, 0x12, 0x86, 0x01, 0x0a, - 0x1c, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x4f, 0x6e, 0x6c, 0x79, 0x43, 0x6f, 0x6e, 0x76, 0x65, 0x72, - 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x73, 0x18, 0x03, 0x20, - 0x03, 0x28, 0x0b, 0x32, 0x42, 0x2e, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x6c, 0x73, 0x65, 0x72, 0x76, - 0x69, 0x63, 0x65, 0x2e, 0x53, 0x79, 0x6e, 0x63, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, - 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x46, 0x6f, 0x72, 0x4d, 0x65, 0x2e, 0x4c, 0x6f, 0x63, 0x61, - 0x6c, 0x4f, 0x6e, 0x6c, 0x79, 0x43, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x1c, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x4f, 0x6e, - 0x6c, 0x79, 0x43, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x44, 0x65, - 0x6c, 0x65, 0x74, 0x65, 0x73, 0x1a, 0x90, 0x01, 0x0a, 0x16, 0x43, 0x6f, 0x6e, 0x76, 0x65, 0x72, - 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, - 0x12, 0x1e, 0x0a, 0x09, 0x74, 0x68, 0x72, 0x65, 0x61, 0x64, 0x41, 0x63, 0x69, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x09, 0x74, 0x68, 0x72, 0x65, 0x61, 0x64, 0x41, 0x63, 0x69, - 0x12, 0x26, 0x0a, 0x0d, 0x74, 0x68, 0x72, 0x65, 0x61, 0x64, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x49, - 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x48, 0x00, 0x52, 0x0d, 0x74, 0x68, 0x72, 0x65, 0x61, - 0x64, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x49, 0x64, 0x12, 0x20, 0x0a, 0x0a, 0x74, 0x68, 0x72, 0x65, - 0x61, 0x64, 0x45, 0x31, 0x36, 0x34, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x0a, - 0x74, 0x68, 0x72, 0x65, 0x61, 0x64, 0x45, 0x31, 0x36, 0x34, 0x42, 0x0c, 0x0a, 0x0a, 0x69, 0x64, - 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x1a, 0x86, 0x01, 0x0a, 0x12, 0x41, 0x64, 0x64, - 0x72, 0x65, 0x73, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, - 0x1e, 0x0a, 0x09, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x41, 0x63, 0x69, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x09, 0x48, 0x00, 0x52, 0x09, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x41, 0x63, 0x69, 0x12, - 0x20, 0x0a, 0x0a, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x45, 0x31, 0x36, 0x34, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x0a, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x45, 0x31, 0x36, - 0x34, 0x12, 0x24, 0x0a, 0x0d, 0x73, 0x65, 0x6e, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, - 0x6d, 0x70, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0d, 0x73, 0x65, 0x6e, 0x74, 0x54, 0x69, - 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x42, 0x08, 0x0a, 0x06, 0x61, 0x75, 0x74, 0x68, 0x6f, - 0x72, 0x1a, 0xca, 0x01, 0x0a, 0x0e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x44, 0x65, 0x6c, - 0x65, 0x74, 0x65, 0x73, 0x12, 0x61, 0x0a, 0x0c, 0x63, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x3d, 0x2e, 0x73, 0x69, 0x67, + 0x63, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x43, 0x61, 0x6c, 0x6c, 0x4c, 0x69, 0x6e, + 0x6b, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x2e, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, + 0x70, 0x65, 0x22, 0x1e, 0x0a, 0x04, 0x54, 0x79, 0x70, 0x65, 0x12, 0x0a, 0x0a, 0x06, 0x55, 0x50, + 0x44, 0x41, 0x54, 0x45, 0x10, 0x00, 0x12, 0x0a, 0x0a, 0x06, 0x44, 0x45, 0x4c, 0x45, 0x54, 0x45, + 0x10, 0x01, 0x1a, 0xf9, 0x01, 0x0a, 0x0c, 0x43, 0x61, 0x6c, 0x6c, 0x4c, 0x6f, 0x67, 0x45, 0x76, + 0x65, 0x6e, 0x74, 0x12, 0x40, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x0e, 0x32, 0x2c, 0x2e, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x6c, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, + 0x65, 0x2e, 0x53, 0x79, 0x6e, 0x63, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x43, 0x61, + 0x6c, 0x6c, 0x4c, 0x6f, 0x67, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x2e, 0x54, 0x79, 0x70, 0x65, 0x52, + 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, + 0x6d, 0x70, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, + 0x61, 0x6d, 0x70, 0x12, 0x26, 0x0a, 0x0e, 0x63, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0e, 0x63, 0x6f, 0x6e, + 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x63, + 0x61, 0x6c, 0x6c, 0x49, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x04, 0x52, 0x06, 0x63, 0x61, 0x6c, + 0x6c, 0x49, 0x64, 0x22, 0x49, 0x0a, 0x04, 0x54, 0x79, 0x70, 0x65, 0x12, 0x09, 0x0a, 0x05, 0x43, + 0x4c, 0x45, 0x41, 0x52, 0x10, 0x00, 0x12, 0x12, 0x0a, 0x0e, 0x4d, 0x41, 0x52, 0x4b, 0x45, 0x44, + 0x5f, 0x41, 0x53, 0x5f, 0x52, 0x45, 0x41, 0x44, 0x10, 0x01, 0x12, 0x22, 0x0a, 0x1e, 0x4d, 0x41, + 0x52, 0x4b, 0x45, 0x44, 0x5f, 0x41, 0x53, 0x5f, 0x52, 0x45, 0x41, 0x44, 0x5f, 0x49, 0x4e, 0x5f, + 0x43, 0x4f, 0x4e, 0x56, 0x45, 0x52, 0x53, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x10, 0x02, 0x1a, 0xa2, + 0x0e, 0x0a, 0x0b, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x46, 0x6f, 0x72, 0x4d, 0x65, 0x12, 0x5d, + 0x0a, 0x0e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x73, + 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x35, 0x2e, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x6c, 0x73, + 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x53, 0x79, 0x6e, 0x63, 0x4d, 0x65, 0x73, 0x73, 0x61, + 0x67, 0x65, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x46, 0x6f, 0x72, 0x4d, 0x65, 0x2e, 0x4d, + 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x73, 0x52, 0x0e, 0x6d, + 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x73, 0x12, 0x6b, 0x0a, + 0x13, 0x63, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x44, 0x65, 0x6c, + 0x65, 0x74, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x39, 0x2e, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x6c, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x53, 0x79, 0x6e, 0x63, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x46, 0x6f, 0x72, - 0x4d, 0x65, 0x2e, 0x43, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, - 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x52, 0x0c, 0x63, 0x6f, 0x6e, 0x76, 0x65, - 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x55, 0x0a, 0x08, 0x6d, 0x65, 0x73, 0x73, 0x61, - 0x67, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x39, 0x2e, 0x73, 0x69, 0x67, 0x6e, - 0x61, 0x6c, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x53, 0x79, 0x6e, 0x63, 0x4d, 0x65, - 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x46, 0x6f, 0x72, 0x4d, - 0x65, 0x2e, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x4d, 0x65, 0x73, - 0x73, 0x61, 0x67, 0x65, 0x52, 0x08, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x1a, 0x86, - 0x02, 0x0a, 0x12, 0x43, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x44, - 0x65, 0x6c, 0x65, 0x74, 0x65, 0x12, 0x61, 0x0a, 0x0c, 0x63, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x3d, 0x2e, 0x73, 0x69, - 0x67, 0x6e, 0x61, 0x6c, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x53, 0x79, 0x6e, 0x63, - 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x46, 0x6f, - 0x72, 0x4d, 0x65, 0x2e, 0x43, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x52, 0x0c, 0x63, 0x6f, 0x6e, 0x76, - 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x69, 0x0a, 0x12, 0x6d, 0x6f, 0x73, 0x74, - 0x52, 0x65, 0x63, 0x65, 0x6e, 0x74, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x18, 0x02, - 0x20, 0x03, 0x28, 0x0b, 0x32, 0x39, 0x2e, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x6c, 0x73, 0x65, 0x72, - 0x76, 0x69, 0x63, 0x65, 0x2e, 0x53, 0x79, 0x6e, 0x63, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, - 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x46, 0x6f, 0x72, 0x4d, 0x65, 0x2e, 0x41, 0x64, 0x64, - 0x72, 0x65, 0x73, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, - 0x12, 0x6d, 0x6f, 0x73, 0x74, 0x52, 0x65, 0x63, 0x65, 0x6e, 0x74, 0x4d, 0x65, 0x73, 0x73, 0x61, - 0x67, 0x65, 0x73, 0x12, 0x22, 0x0a, 0x0c, 0x69, 0x73, 0x46, 0x75, 0x6c, 0x6c, 0x44, 0x65, 0x6c, - 0x65, 0x74, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0c, 0x69, 0x73, 0x46, 0x75, 0x6c, - 0x6c, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x1a, 0x80, 0x01, 0x0a, 0x1b, 0x4c, 0x6f, 0x63, 0x61, - 0x6c, 0x4f, 0x6e, 0x6c, 0x79, 0x43, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x12, 0x61, 0x0a, 0x0c, 0x63, 0x6f, 0x6e, 0x76, 0x65, - 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x3d, 0x2e, - 0x73, 0x69, 0x67, 0x6e, 0x61, 0x6c, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x53, 0x79, - 0x6e, 0x63, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, - 0x46, 0x6f, 0x72, 0x4d, 0x65, 0x2e, 0x43, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x52, 0x0c, 0x63, 0x6f, - 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4a, 0x04, 0x08, 0x03, 0x10, 0x04, - 0x4a, 0x04, 0x08, 0x11, 0x10, 0x12, 0x22, 0xe3, 0x04, 0x0a, 0x11, 0x41, 0x74, 0x74, 0x61, 0x63, - 0x68, 0x6d, 0x65, 0x6e, 0x74, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x12, 0x16, 0x0a, 0x05, - 0x63, 0x64, 0x6e, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x06, 0x48, 0x00, 0x52, 0x05, 0x63, - 0x64, 0x6e, 0x49, 0x64, 0x12, 0x18, 0x0a, 0x06, 0x63, 0x64, 0x6e, 0x4b, 0x65, 0x79, 0x18, 0x0f, - 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x06, 0x63, 0x64, 0x6e, 0x4b, 0x65, 0x79, 0x12, 0x20, - 0x0a, 0x0b, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x0b, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, - 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x03, 0x6b, - 0x65, 0x79, 0x12, 0x12, 0x0a, 0x04, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0d, - 0x52, 0x04, 0x73, 0x69, 0x7a, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x68, 0x75, 0x6d, 0x62, 0x6e, - 0x61, 0x69, 0x6c, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x74, 0x68, 0x75, 0x6d, 0x62, - 0x6e, 0x61, 0x69, 0x6c, 0x12, 0x16, 0x0a, 0x06, 0x64, 0x69, 0x67, 0x65, 0x73, 0x74, 0x18, 0x06, - 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x64, 0x69, 0x67, 0x65, 0x73, 0x74, 0x12, 0x26, 0x0a, 0x0e, - 0x69, 0x6e, 0x63, 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x61, 0x6c, 0x4d, 0x61, 0x63, 0x18, 0x13, - 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0e, 0x69, 0x6e, 0x63, 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x61, - 0x6c, 0x4d, 0x61, 0x63, 0x12, 0x38, 0x0a, 0x17, 0x69, 0x6e, 0x63, 0x72, 0x65, 0x6d, 0x65, 0x6e, - 0x74, 0x61, 0x6c, 0x4d, 0x61, 0x63, 0x43, 0x68, 0x75, 0x6e, 0x6b, 0x53, 0x69, 0x7a, 0x65, 0x18, - 0x11, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x17, 0x69, 0x6e, 0x63, 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, - 0x61, 0x6c, 0x4d, 0x61, 0x63, 0x43, 0x68, 0x75, 0x6e, 0x6b, 0x53, 0x69, 0x7a, 0x65, 0x12, 0x1a, - 0x0a, 0x08, 0x66, 0x69, 0x6c, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x08, 0x66, 0x69, 0x6c, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x66, 0x6c, - 0x61, 0x67, 0x73, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x05, 0x66, 0x6c, 0x61, 0x67, 0x73, - 0x12, 0x14, 0x0a, 0x05, 0x77, 0x69, 0x64, 0x74, 0x68, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0d, 0x52, - 0x05, 0x77, 0x69, 0x64, 0x74, 0x68, 0x12, 0x16, 0x0a, 0x06, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, - 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x06, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x12, 0x18, - 0x0a, 0x07, 0x63, 0x61, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x07, 0x63, 0x61, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1a, 0x0a, 0x08, 0x62, 0x6c, 0x75, 0x72, - 0x48, 0x61, 0x73, 0x68, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x62, 0x6c, 0x75, 0x72, - 0x48, 0x61, 0x73, 0x68, 0x12, 0x28, 0x0a, 0x0f, 0x75, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x54, 0x69, - 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0f, 0x75, - 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x1c, - 0x0a, 0x09, 0x63, 0x64, 0x6e, 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x18, 0x0e, 0x20, 0x01, 0x28, - 0x0d, 0x52, 0x09, 0x63, 0x64, 0x6e, 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x22, 0x39, 0x0a, 0x05, - 0x46, 0x6c, 0x61, 0x67, 0x73, 0x12, 0x11, 0x0a, 0x0d, 0x56, 0x4f, 0x49, 0x43, 0x45, 0x5f, 0x4d, - 0x45, 0x53, 0x53, 0x41, 0x47, 0x45, 0x10, 0x01, 0x12, 0x0e, 0x0a, 0x0a, 0x42, 0x4f, 0x52, 0x44, - 0x45, 0x52, 0x4c, 0x45, 0x53, 0x53, 0x10, 0x02, 0x12, 0x07, 0x0a, 0x03, 0x47, 0x49, 0x46, 0x10, - 0x04, 0x22, 0x04, 0x08, 0x03, 0x10, 0x03, 0x42, 0x17, 0x0a, 0x15, 0x61, 0x74, 0x74, 0x61, 0x63, - 0x68, 0x6d, 0x65, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, - 0x4a, 0x04, 0x08, 0x10, 0x10, 0x11, 0x4a, 0x04, 0x08, 0x12, 0x10, 0x13, 0x22, 0xf0, 0x02, 0x0a, - 0x0c, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x12, 0x0e, 0x0a, - 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x02, 0x69, 0x64, 0x12, 0x34, 0x0a, - 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x20, 0x2e, 0x73, 0x69, - 0x67, 0x6e, 0x61, 0x6c, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x47, 0x72, 0x6f, 0x75, - 0x70, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x2e, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, - 0x79, 0x70, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x6d, 0x65, 0x6d, 0x62, 0x65, - 0x72, 0x73, 0x45, 0x31, 0x36, 0x34, 0x18, 0x04, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0b, 0x6d, 0x65, - 0x6d, 0x62, 0x65, 0x72, 0x73, 0x45, 0x31, 0x36, 0x34, 0x12, 0x3c, 0x0a, 0x07, 0x6d, 0x65, 0x6d, - 0x62, 0x65, 0x72, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x73, 0x69, 0x67, - 0x6e, 0x61, 0x6c, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x47, 0x72, 0x6f, 0x75, 0x70, - 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x2e, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x52, 0x07, - 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x12, 0x38, 0x0a, 0x06, 0x61, 0x76, 0x61, 0x74, 0x61, - 0x72, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x6c, - 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x41, 0x74, 0x74, 0x61, 0x63, 0x68, 0x6d, 0x65, - 0x6e, 0x74, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x52, 0x06, 0x61, 0x76, 0x61, 0x74, 0x61, - 0x72, 0x1a, 0x22, 0x0a, 0x06, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x12, 0x12, 0x0a, 0x04, 0x65, - 0x31, 0x36, 0x34, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x65, 0x31, 0x36, 0x34, 0x4a, - 0x04, 0x08, 0x01, 0x10, 0x02, 0x22, 0x48, 0x0a, 0x04, 0x54, 0x79, 0x70, 0x65, 0x12, 0x0b, 0x0a, - 0x07, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x00, 0x12, 0x0a, 0x0a, 0x06, 0x55, 0x50, - 0x44, 0x41, 0x54, 0x45, 0x10, 0x01, 0x12, 0x0b, 0x0a, 0x07, 0x44, 0x45, 0x4c, 0x49, 0x56, 0x45, - 0x52, 0x10, 0x02, 0x12, 0x08, 0x0a, 0x04, 0x51, 0x55, 0x49, 0x54, 0x10, 0x03, 0x12, 0x10, 0x0a, - 0x0c, 0x52, 0x45, 0x51, 0x55, 0x45, 0x53, 0x54, 0x5f, 0x49, 0x4e, 0x46, 0x4f, 0x10, 0x04, 0x22, - 0x6c, 0x0a, 0x0e, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x56, - 0x32, 0x12, 0x1c, 0x0a, 0x09, 0x6d, 0x61, 0x73, 0x74, 0x65, 0x72, 0x4b, 0x65, 0x79, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x6d, 0x61, 0x73, 0x74, 0x65, 0x72, 0x4b, 0x65, 0x79, 0x12, - 0x1a, 0x0a, 0x08, 0x72, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x0d, 0x52, 0x08, 0x72, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x20, 0x0a, 0x0b, 0x67, - 0x72, 0x6f, 0x75, 0x70, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, - 0x52, 0x0b, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x22, 0xa5, 0x03, - 0x0a, 0x0e, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x63, 0x74, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, - 0x12, 0x16, 0x0a, 0x06, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x06, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x12, 0x10, 0x0a, 0x03, 0x61, 0x63, 0x69, 0x18, - 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x61, 0x63, 0x69, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, - 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x3c, - 0x0a, 0x06, 0x61, 0x76, 0x61, 0x74, 0x61, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x24, - 0x2e, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x6c, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x43, - 0x6f, 0x6e, 0x74, 0x61, 0x63, 0x74, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x2e, 0x41, 0x76, - 0x61, 0x74, 0x61, 0x72, 0x52, 0x06, 0x61, 0x76, 0x61, 0x74, 0x61, 0x72, 0x12, 0x14, 0x0a, 0x05, - 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x63, 0x6f, 0x6c, - 0x6f, 0x72, 0x12, 0x33, 0x0a, 0x08, 0x76, 0x65, 0x72, 0x69, 0x66, 0x69, 0x65, 0x64, 0x18, 0x05, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x6c, 0x73, 0x65, 0x72, - 0x76, 0x69, 0x63, 0x65, 0x2e, 0x56, 0x65, 0x72, 0x69, 0x66, 0x69, 0x65, 0x64, 0x52, 0x08, 0x76, - 0x65, 0x72, 0x69, 0x66, 0x69, 0x65, 0x64, 0x12, 0x1e, 0x0a, 0x0a, 0x70, 0x72, 0x6f, 0x66, 0x69, - 0x6c, 0x65, 0x4b, 0x65, 0x79, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0a, 0x70, 0x72, 0x6f, - 0x66, 0x69, 0x6c, 0x65, 0x4b, 0x65, 0x79, 0x12, 0x20, 0x0a, 0x0b, 0x65, 0x78, 0x70, 0x69, 0x72, - 0x65, 0x54, 0x69, 0x6d, 0x65, 0x72, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0b, 0x65, 0x78, - 0x70, 0x69, 0x72, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x72, 0x12, 0x24, 0x0a, 0x0d, 0x69, 0x6e, 0x62, - 0x6f, 0x78, 0x50, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0d, - 0x52, 0x0d, 0x69, 0x6e, 0x62, 0x6f, 0x78, 0x50, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x12, - 0x1a, 0x0a, 0x08, 0x61, 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, 0x64, 0x18, 0x0b, 0x20, 0x01, 0x28, - 0x08, 0x52, 0x08, 0x61, 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, 0x64, 0x1a, 0x42, 0x0a, 0x06, 0x41, - 0x76, 0x61, 0x74, 0x61, 0x72, 0x12, 0x20, 0x0a, 0x0b, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, - 0x54, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x63, 0x6f, 0x6e, 0x74, - 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x6c, 0x65, 0x6e, 0x67, 0x74, - 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x06, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x4a, - 0x04, 0x08, 0x07, 0x10, 0x08, 0x22, 0xe8, 0x03, 0x0a, 0x0c, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x44, - 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x0c, 0x52, 0x02, 0x69, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x6d, 0x65, - 0x6d, 0x62, 0x65, 0x72, 0x73, 0x45, 0x31, 0x36, 0x34, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, - 0x0b, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x45, 0x31, 0x36, 0x34, 0x12, 0x3c, 0x0a, 0x07, - 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x18, 0x09, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x22, 0x2e, - 0x73, 0x69, 0x67, 0x6e, 0x61, 0x6c, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x47, 0x72, - 0x6f, 0x75, 0x70, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x2e, 0x4d, 0x65, 0x6d, 0x62, 0x65, - 0x72, 0x52, 0x07, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x12, 0x3a, 0x0a, 0x06, 0x61, 0x76, - 0x61, 0x74, 0x61, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x73, 0x69, 0x67, - 0x6e, 0x61, 0x6c, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x47, 0x72, 0x6f, 0x75, 0x70, - 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x2e, 0x41, 0x76, 0x61, 0x74, 0x61, 0x72, 0x52, 0x06, - 0x61, 0x76, 0x61, 0x74, 0x61, 0x72, 0x12, 0x1c, 0x0a, 0x06, 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, - 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x3a, 0x04, 0x74, 0x72, 0x75, 0x65, 0x52, 0x06, 0x61, 0x63, - 0x74, 0x69, 0x76, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x65, 0x78, 0x70, 0x69, 0x72, 0x65, 0x54, 0x69, - 0x6d, 0x65, 0x72, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0b, 0x65, 0x78, 0x70, 0x69, 0x72, - 0x65, 0x54, 0x69, 0x6d, 0x65, 0x72, 0x12, 0x14, 0x0a, 0x05, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x18, - 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x12, 0x18, 0x0a, 0x07, - 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x65, 0x64, 0x18, 0x08, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x62, - 0x6c, 0x6f, 0x63, 0x6b, 0x65, 0x64, 0x12, 0x24, 0x0a, 0x0d, 0x69, 0x6e, 0x62, 0x6f, 0x78, 0x50, + 0x4d, 0x65, 0x2e, 0x43, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x44, + 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x13, 0x63, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x73, 0x12, 0x86, 0x01, 0x0a, 0x1c, 0x6c, + 0x6f, 0x63, 0x61, 0x6c, 0x4f, 0x6e, 0x6c, 0x79, 0x43, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, + 0x0b, 0x32, 0x42, 0x2e, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x6c, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, + 0x65, 0x2e, 0x53, 0x79, 0x6e, 0x63, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x44, 0x65, + 0x6c, 0x65, 0x74, 0x65, 0x46, 0x6f, 0x72, 0x4d, 0x65, 0x2e, 0x4c, 0x6f, 0x63, 0x61, 0x6c, 0x4f, + 0x6e, 0x6c, 0x79, 0x43, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x44, + 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x1c, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x4f, 0x6e, 0x6c, 0x79, + 0x43, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x44, 0x65, 0x6c, 0x65, + 0x74, 0x65, 0x73, 0x12, 0x65, 0x0a, 0x11, 0x61, 0x74, 0x74, 0x61, 0x63, 0x68, 0x6d, 0x65, 0x6e, + 0x74, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x37, + 0x2e, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x6c, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x53, + 0x79, 0x6e, 0x63, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, + 0x65, 0x46, 0x6f, 0x72, 0x4d, 0x65, 0x2e, 0x41, 0x74, 0x74, 0x61, 0x63, 0x68, 0x6d, 0x65, 0x6e, + 0x74, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x11, 0x61, 0x74, 0x74, 0x61, 0x63, 0x68, 0x6d, + 0x65, 0x6e, 0x74, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x73, 0x1a, 0x9c, 0x01, 0x0a, 0x16, 0x43, + 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x65, 0x6e, 0x74, + 0x69, 0x66, 0x69, 0x65, 0x72, 0x12, 0x2a, 0x0a, 0x0f, 0x74, 0x68, 0x72, 0x65, 0x61, 0x64, 0x53, + 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, + 0x52, 0x0f, 0x74, 0x68, 0x72, 0x65, 0x61, 0x64, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x49, + 0x64, 0x12, 0x26, 0x0a, 0x0d, 0x74, 0x68, 0x72, 0x65, 0x61, 0x64, 0x47, 0x72, 0x6f, 0x75, 0x70, + 0x49, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x48, 0x00, 0x52, 0x0d, 0x74, 0x68, 0x72, 0x65, + 0x61, 0x64, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x49, 0x64, 0x12, 0x20, 0x0a, 0x0a, 0x74, 0x68, 0x72, + 0x65, 0x61, 0x64, 0x45, 0x31, 0x36, 0x34, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, + 0x0a, 0x74, 0x68, 0x72, 0x65, 0x61, 0x64, 0x45, 0x31, 0x36, 0x34, 0x42, 0x0c, 0x0a, 0x0a, 0x69, + 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x1a, 0x92, 0x01, 0x0a, 0x12, 0x41, 0x64, + 0x64, 0x72, 0x65, 0x73, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, + 0x12, 0x2a, 0x0a, 0x0f, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, + 0x65, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x0f, 0x61, 0x75, 0x74, + 0x68, 0x6f, 0x72, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x49, 0x64, 0x12, 0x20, 0x0a, 0x0a, + 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x45, 0x31, 0x36, 0x34, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, + 0x48, 0x00, 0x52, 0x0a, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x45, 0x31, 0x36, 0x34, 0x12, 0x24, + 0x0a, 0x0d, 0x73, 0x65, 0x6e, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, + 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0d, 0x73, 0x65, 0x6e, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x73, + 0x74, 0x61, 0x6d, 0x70, 0x42, 0x08, 0x0a, 0x06, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x1a, 0xca, + 0x01, 0x0a, 0x0e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, + 0x73, 0x12, 0x61, 0x0a, 0x0c, 0x63, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x3d, 0x2e, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x6c, + 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x53, 0x79, 0x6e, 0x63, 0x4d, 0x65, 0x73, 0x73, + 0x61, 0x67, 0x65, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x46, 0x6f, 0x72, 0x4d, 0x65, 0x2e, + 0x43, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x65, 0x6e, + 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x52, 0x0c, 0x63, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x55, 0x0a, 0x08, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, + 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x39, 0x2e, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x6c, 0x73, + 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x53, 0x79, 0x6e, 0x63, 0x4d, 0x65, 0x73, 0x73, 0x61, + 0x67, 0x65, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x46, 0x6f, 0x72, 0x4d, 0x65, 0x2e, 0x41, + 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, + 0x65, 0x52, 0x08, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x1a, 0xc8, 0x02, 0x0a, 0x10, + 0x41, 0x74, 0x74, 0x61, 0x63, 0x68, 0x6d, 0x65, 0x6e, 0x74, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, + 0x12, 0x61, 0x0a, 0x0c, 0x63, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x3d, 0x2e, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x6c, 0x73, + 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x53, 0x79, 0x6e, 0x63, 0x4d, 0x65, 0x73, 0x73, 0x61, + 0x67, 0x65, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x46, 0x6f, 0x72, 0x4d, 0x65, 0x2e, 0x43, + 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x65, 0x6e, 0x74, + 0x69, 0x66, 0x69, 0x65, 0x72, 0x52, 0x0c, 0x63, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x12, 0x5f, 0x0a, 0x0d, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x4d, 0x65, 0x73, + 0x73, 0x61, 0x67, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x39, 0x2e, 0x73, 0x69, 0x67, + 0x6e, 0x61, 0x6c, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x53, 0x79, 0x6e, 0x63, 0x4d, + 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x46, 0x6f, 0x72, + 0x4d, 0x65, 0x2e, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x4d, 0x65, + 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x0d, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x4d, 0x65, 0x73, + 0x73, 0x61, 0x67, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x75, 0x75, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x0c, 0x52, 0x04, 0x75, 0x75, 0x69, 0x64, 0x12, 0x26, 0x0a, 0x0e, 0x66, 0x61, 0x6c, 0x6c, + 0x62, 0x61, 0x63, 0x6b, 0x44, 0x69, 0x67, 0x65, 0x73, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, + 0x52, 0x0e, 0x66, 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x44, 0x69, 0x67, 0x65, 0x73, 0x74, + 0x12, 0x34, 0x0a, 0x15, 0x66, 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x50, 0x6c, 0x61, 0x69, + 0x6e, 0x74, 0x65, 0x78, 0x74, 0x48, 0x61, 0x73, 0x68, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0c, 0x52, + 0x15, 0x66, 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x50, 0x6c, 0x61, 0x69, 0x6e, 0x74, 0x65, + 0x78, 0x74, 0x48, 0x61, 0x73, 0x68, 0x1a, 0x87, 0x03, 0x0a, 0x12, 0x43, 0x6f, 0x6e, 0x76, 0x65, + 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x12, 0x61, 0x0a, + 0x0c, 0x63, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x3d, 0x2e, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x6c, 0x73, 0x65, 0x72, 0x76, + 0x69, 0x63, 0x65, 0x2e, 0x53, 0x79, 0x6e, 0x63, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, + 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x46, 0x6f, 0x72, 0x4d, 0x65, 0x2e, 0x43, 0x6f, 0x6e, 0x76, + 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, + 0x65, 0x72, 0x52, 0x0c, 0x63, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x12, 0x69, 0x0a, 0x12, 0x6d, 0x6f, 0x73, 0x74, 0x52, 0x65, 0x63, 0x65, 0x6e, 0x74, 0x4d, 0x65, + 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x39, 0x2e, 0x73, + 0x69, 0x67, 0x6e, 0x61, 0x6c, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x53, 0x79, 0x6e, + 0x63, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x46, + 0x6f, 0x72, 0x4d, 0x65, 0x2e, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x61, 0x62, 0x6c, 0x65, + 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x12, 0x6d, 0x6f, 0x73, 0x74, 0x52, 0x65, 0x63, + 0x65, 0x6e, 0x74, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x12, 0x7f, 0x0a, 0x1d, 0x6d, + 0x6f, 0x73, 0x74, 0x52, 0x65, 0x63, 0x65, 0x6e, 0x74, 0x4e, 0x6f, 0x6e, 0x45, 0x78, 0x70, 0x69, + 0x72, 0x69, 0x6e, 0x67, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x18, 0x04, 0x20, 0x03, + 0x28, 0x0b, 0x32, 0x39, 0x2e, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x6c, 0x73, 0x65, 0x72, 0x76, 0x69, + 0x63, 0x65, 0x2e, 0x53, 0x79, 0x6e, 0x63, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x44, + 0x65, 0x6c, 0x65, 0x74, 0x65, 0x46, 0x6f, 0x72, 0x4d, 0x65, 0x2e, 0x41, 0x64, 0x64, 0x72, 0x65, + 0x73, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x1d, 0x6d, + 0x6f, 0x73, 0x74, 0x52, 0x65, 0x63, 0x65, 0x6e, 0x74, 0x4e, 0x6f, 0x6e, 0x45, 0x78, 0x70, 0x69, + 0x72, 0x69, 0x6e, 0x67, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x12, 0x22, 0x0a, 0x0c, + 0x69, 0x73, 0x46, 0x75, 0x6c, 0x6c, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x08, 0x52, 0x0c, 0x69, 0x73, 0x46, 0x75, 0x6c, 0x6c, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, + 0x1a, 0x80, 0x01, 0x0a, 0x1b, 0x4c, 0x6f, 0x63, 0x61, 0x6c, 0x4f, 0x6e, 0x6c, 0x79, 0x43, 0x6f, + 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, + 0x12, 0x61, 0x0a, 0x0c, 0x63, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x3d, 0x2e, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x6c, 0x73, + 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x53, 0x79, 0x6e, 0x63, 0x4d, 0x65, 0x73, 0x73, 0x61, + 0x67, 0x65, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x46, 0x6f, 0x72, 0x4d, 0x65, 0x2e, 0x43, + 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x65, 0x6e, 0x74, + 0x69, 0x66, 0x69, 0x65, 0x72, 0x52, 0x0c, 0x63, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x4a, 0x04, 0x08, 0x03, 0x10, 0x04, 0x4a, 0x04, 0x08, 0x11, 0x10, 0x12, 0x22, + 0xf7, 0x04, 0x0a, 0x11, 0x41, 0x74, 0x74, 0x61, 0x63, 0x68, 0x6d, 0x65, 0x6e, 0x74, 0x50, 0x6f, + 0x69, 0x6e, 0x74, 0x65, 0x72, 0x12, 0x16, 0x0a, 0x05, 0x63, 0x64, 0x6e, 0x49, 0x64, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x06, 0x48, 0x00, 0x52, 0x05, 0x63, 0x64, 0x6e, 0x49, 0x64, 0x12, 0x18, 0x0a, + 0x06, 0x63, 0x64, 0x6e, 0x4b, 0x65, 0x79, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, + 0x06, 0x63, 0x64, 0x6e, 0x4b, 0x65, 0x79, 0x12, 0x20, 0x0a, 0x0b, 0x63, 0x6f, 0x6e, 0x74, 0x65, + 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x63, 0x6f, + 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, + 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x12, 0x0a, 0x04, 0x73, + 0x69, 0x7a, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x04, 0x73, 0x69, 0x7a, 0x65, 0x12, + 0x1c, 0x0a, 0x09, 0x74, 0x68, 0x75, 0x6d, 0x62, 0x6e, 0x61, 0x69, 0x6c, 0x18, 0x05, 0x20, 0x01, + 0x28, 0x0c, 0x52, 0x09, 0x74, 0x68, 0x75, 0x6d, 0x62, 0x6e, 0x61, 0x69, 0x6c, 0x12, 0x16, 0x0a, + 0x06, 0x64, 0x69, 0x67, 0x65, 0x73, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x64, + 0x69, 0x67, 0x65, 0x73, 0x74, 0x12, 0x26, 0x0a, 0x0e, 0x69, 0x6e, 0x63, 0x72, 0x65, 0x6d, 0x65, + 0x6e, 0x74, 0x61, 0x6c, 0x4d, 0x61, 0x63, 0x18, 0x13, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0e, 0x69, + 0x6e, 0x63, 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x61, 0x6c, 0x4d, 0x61, 0x63, 0x12, 0x38, 0x0a, + 0x17, 0x69, 0x6e, 0x63, 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x61, 0x6c, 0x4d, 0x61, 0x63, 0x43, + 0x68, 0x75, 0x6e, 0x6b, 0x53, 0x69, 0x7a, 0x65, 0x18, 0x11, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x17, + 0x69, 0x6e, 0x63, 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x61, 0x6c, 0x4d, 0x61, 0x63, 0x43, 0x68, + 0x75, 0x6e, 0x6b, 0x53, 0x69, 0x7a, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x66, 0x69, 0x6c, 0x65, 0x4e, + 0x61, 0x6d, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x66, 0x69, 0x6c, 0x65, 0x4e, + 0x61, 0x6d, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x66, 0x6c, 0x61, 0x67, 0x73, 0x18, 0x08, 0x20, 0x01, + 0x28, 0x0d, 0x52, 0x05, 0x66, 0x6c, 0x61, 0x67, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x77, 0x69, 0x64, + 0x74, 0x68, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x05, 0x77, 0x69, 0x64, 0x74, 0x68, 0x12, + 0x16, 0x0a, 0x06, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0d, 0x52, + 0x06, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x61, 0x70, 0x74, 0x69, + 0x6f, 0x6e, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x63, 0x61, 0x70, 0x74, 0x69, 0x6f, + 0x6e, 0x12, 0x1a, 0x0a, 0x08, 0x62, 0x6c, 0x75, 0x72, 0x48, 0x61, 0x73, 0x68, 0x18, 0x0c, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x08, 0x62, 0x6c, 0x75, 0x72, 0x48, 0x61, 0x73, 0x68, 0x12, 0x28, 0x0a, + 0x0f, 0x75, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, + 0x18, 0x0d, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0f, 0x75, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x54, 0x69, + 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x1c, 0x0a, 0x09, 0x63, 0x64, 0x6e, 0x4e, 0x75, + 0x6d, 0x62, 0x65, 0x72, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x63, 0x64, 0x6e, 0x4e, + 0x75, 0x6d, 0x62, 0x65, 0x72, 0x12, 0x12, 0x0a, 0x04, 0x75, 0x75, 0x69, 0x64, 0x18, 0x14, 0x20, + 0x01, 0x28, 0x0c, 0x52, 0x04, 0x75, 0x75, 0x69, 0x64, 0x22, 0x39, 0x0a, 0x05, 0x46, 0x6c, 0x61, + 0x67, 0x73, 0x12, 0x11, 0x0a, 0x0d, 0x56, 0x4f, 0x49, 0x43, 0x45, 0x5f, 0x4d, 0x45, 0x53, 0x53, + 0x41, 0x47, 0x45, 0x10, 0x01, 0x12, 0x0e, 0x0a, 0x0a, 0x42, 0x4f, 0x52, 0x44, 0x45, 0x52, 0x4c, + 0x45, 0x53, 0x53, 0x10, 0x02, 0x12, 0x07, 0x0a, 0x03, 0x47, 0x49, 0x46, 0x10, 0x04, 0x22, 0x04, + 0x08, 0x03, 0x10, 0x03, 0x42, 0x17, 0x0a, 0x15, 0x61, 0x74, 0x74, 0x61, 0x63, 0x68, 0x6d, 0x65, + 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x4a, 0x04, 0x08, + 0x10, 0x10, 0x11, 0x4a, 0x04, 0x08, 0x12, 0x10, 0x13, 0x22, 0xf0, 0x02, 0x0a, 0x0c, 0x47, 0x72, + 0x6f, 0x75, 0x70, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x02, 0x69, 0x64, 0x12, 0x34, 0x0a, 0x04, 0x74, 0x79, + 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x20, 0x2e, 0x73, 0x69, 0x67, 0x6e, 0x61, + 0x6c, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x43, 0x6f, + 0x6e, 0x74, 0x65, 0x78, 0x74, 0x2e, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, + 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, + 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x45, + 0x31, 0x36, 0x34, 0x18, 0x04, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0b, 0x6d, 0x65, 0x6d, 0x62, 0x65, + 0x72, 0x73, 0x45, 0x31, 0x36, 0x34, 0x12, 0x3c, 0x0a, 0x07, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, + 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x6c, + 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x43, 0x6f, 0x6e, + 0x74, 0x65, 0x78, 0x74, 0x2e, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x52, 0x07, 0x6d, 0x65, 0x6d, + 0x62, 0x65, 0x72, 0x73, 0x12, 0x38, 0x0a, 0x06, 0x61, 0x76, 0x61, 0x74, 0x61, 0x72, 0x18, 0x05, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x6c, 0x73, 0x65, 0x72, + 0x76, 0x69, 0x63, 0x65, 0x2e, 0x41, 0x74, 0x74, 0x61, 0x63, 0x68, 0x6d, 0x65, 0x6e, 0x74, 0x50, + 0x6f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x52, 0x06, 0x61, 0x76, 0x61, 0x74, 0x61, 0x72, 0x1a, 0x22, + 0x0a, 0x06, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x12, 0x12, 0x0a, 0x04, 0x65, 0x31, 0x36, 0x34, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x65, 0x31, 0x36, 0x34, 0x4a, 0x04, 0x08, 0x01, + 0x10, 0x02, 0x22, 0x48, 0x0a, 0x04, 0x54, 0x79, 0x70, 0x65, 0x12, 0x0b, 0x0a, 0x07, 0x55, 0x4e, + 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x00, 0x12, 0x0a, 0x0a, 0x06, 0x55, 0x50, 0x44, 0x41, 0x54, + 0x45, 0x10, 0x01, 0x12, 0x0b, 0x0a, 0x07, 0x44, 0x45, 0x4c, 0x49, 0x56, 0x45, 0x52, 0x10, 0x02, + 0x12, 0x08, 0x0a, 0x04, 0x51, 0x55, 0x49, 0x54, 0x10, 0x03, 0x12, 0x10, 0x0a, 0x0c, 0x52, 0x45, + 0x51, 0x55, 0x45, 0x53, 0x54, 0x5f, 0x49, 0x4e, 0x46, 0x4f, 0x10, 0x04, 0x22, 0x6c, 0x0a, 0x0e, + 0x47, 0x72, 0x6f, 0x75, 0x70, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x56, 0x32, 0x12, 0x1c, + 0x0a, 0x09, 0x6d, 0x61, 0x73, 0x74, 0x65, 0x72, 0x4b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x0c, 0x52, 0x09, 0x6d, 0x61, 0x73, 0x74, 0x65, 0x72, 0x4b, 0x65, 0x79, 0x12, 0x1a, 0x0a, 0x08, + 0x72, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x08, + 0x72, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x20, 0x0a, 0x0b, 0x67, 0x72, 0x6f, 0x75, + 0x70, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0b, 0x67, + 0x72, 0x6f, 0x75, 0x70, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x22, 0xa5, 0x03, 0x0a, 0x0e, 0x43, + 0x6f, 0x6e, 0x74, 0x61, 0x63, 0x74, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x12, 0x16, 0x0a, + 0x06, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x6e, + 0x75, 0x6d, 0x62, 0x65, 0x72, 0x12, 0x10, 0x0a, 0x03, 0x61, 0x63, 0x69, 0x18, 0x09, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x03, 0x61, 0x63, 0x69, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x3c, 0x0a, 0x06, 0x61, + 0x76, 0x61, 0x74, 0x61, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x73, 0x69, + 0x67, 0x6e, 0x61, 0x6c, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x43, 0x6f, 0x6e, 0x74, + 0x61, 0x63, 0x74, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x2e, 0x41, 0x76, 0x61, 0x74, 0x61, + 0x72, 0x52, 0x06, 0x61, 0x76, 0x61, 0x74, 0x61, 0x72, 0x12, 0x14, 0x0a, 0x05, 0x63, 0x6f, 0x6c, + 0x6f, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x12, + 0x33, 0x0a, 0x08, 0x76, 0x65, 0x72, 0x69, 0x66, 0x69, 0x65, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x17, 0x2e, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x6c, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, + 0x65, 0x2e, 0x56, 0x65, 0x72, 0x69, 0x66, 0x69, 0x65, 0x64, 0x52, 0x08, 0x76, 0x65, 0x72, 0x69, + 0x66, 0x69, 0x65, 0x64, 0x12, 0x1e, 0x0a, 0x0a, 0x70, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x4b, + 0x65, 0x79, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0a, 0x70, 0x72, 0x6f, 0x66, 0x69, 0x6c, + 0x65, 0x4b, 0x65, 0x79, 0x12, 0x20, 0x0a, 0x0b, 0x65, 0x78, 0x70, 0x69, 0x72, 0x65, 0x54, 0x69, + 0x6d, 0x65, 0x72, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0b, 0x65, 0x78, 0x70, 0x69, 0x72, + 0x65, 0x54, 0x69, 0x6d, 0x65, 0x72, 0x12, 0x24, 0x0a, 0x0d, 0x69, 0x6e, 0x62, 0x6f, 0x78, 0x50, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0d, 0x69, 0x6e, 0x62, 0x6f, 0x78, 0x50, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1a, 0x0a, 0x08, 0x61, 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, 0x64, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, @@ -8858,46 +8974,75 @@ var file_SignalService_proto_rawDesc = []byte{ 0x61, 0x72, 0x12, 0x20, 0x0a, 0x0b, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x0d, 0x52, 0x06, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x1a, 0x22, 0x0a, 0x06, - 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x12, 0x12, 0x0a, 0x04, 0x65, 0x31, 0x36, 0x34, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x65, 0x31, 0x36, 0x34, 0x4a, 0x04, 0x08, 0x01, 0x10, 0x02, - 0x22, 0xc9, 0x01, 0x0a, 0x0e, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x41, 0x64, 0x64, 0x72, - 0x65, 0x73, 0x73, 0x12, 0x5f, 0x0a, 0x11, 0x6d, 0x6f, 0x62, 0x69, 0x6c, 0x65, 0x43, 0x6f, 0x69, - 0x6e, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2f, - 0x2e, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x6c, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x50, - 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x2e, 0x4d, 0x6f, - 0x62, 0x69, 0x6c, 0x65, 0x43, 0x6f, 0x69, 0x6e, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x48, - 0x00, 0x52, 0x11, 0x6d, 0x6f, 0x62, 0x69, 0x6c, 0x65, 0x43, 0x6f, 0x69, 0x6e, 0x41, 0x64, 0x64, - 0x72, 0x65, 0x73, 0x73, 0x1a, 0x4b, 0x0a, 0x11, 0x4d, 0x6f, 0x62, 0x69, 0x6c, 0x65, 0x43, 0x6f, - 0x69, 0x6e, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x61, 0x64, 0x64, - 0x72, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x61, 0x64, 0x64, 0x72, - 0x65, 0x73, 0x73, 0x12, 0x1c, 0x0a, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, - 0x65, 0x42, 0x09, 0x0a, 0x07, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x22, 0x72, 0x0a, 0x16, - 0x44, 0x65, 0x63, 0x72, 0x79, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x4d, - 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x1e, 0x0a, 0x0a, 0x72, 0x61, 0x74, 0x63, 0x68, 0x65, - 0x74, 0x4b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0a, 0x72, 0x61, 0x74, 0x63, - 0x68, 0x65, 0x74, 0x4b, 0x65, 0x79, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, - 0x61, 0x6d, 0x70, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, - 0x74, 0x61, 0x6d, 0x70, 0x12, 0x1a, 0x0a, 0x08, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x49, 0x64, - 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x08, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x49, 0x64, - 0x22, 0x45, 0x0a, 0x13, 0x50, 0x6e, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, - 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x70, 0x6e, 0x69, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x0c, 0x52, 0x03, 0x70, 0x6e, 0x69, 0x12, 0x1c, 0x0a, 0x09, 0x73, 0x69, 0x67, - 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x73, 0x69, - 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x22, 0x7d, 0x0a, 0x0b, 0x45, 0x64, 0x69, 0x74, 0x4d, - 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x30, 0x0a, 0x13, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, - 0x53, 0x65, 0x6e, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x04, 0x52, 0x13, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x53, 0x65, 0x6e, 0x74, 0x54, - 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x3c, 0x0a, 0x0b, 0x64, 0x61, 0x74, 0x61, - 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, - 0x73, 0x69, 0x67, 0x6e, 0x61, 0x6c, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x44, 0x61, - 0x74, 0x61, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x0b, 0x64, 0x61, 0x74, 0x61, 0x4d, - 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x42, 0x45, 0x0a, 0x2e, 0x6f, 0x72, 0x67, 0x2e, 0x77, 0x68, - 0x69, 0x73, 0x70, 0x65, 0x72, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x73, 0x2e, 0x73, 0x69, 0x67, - 0x6e, 0x61, 0x6c, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, - 0x6e, 0x61, 0x6c, 0x2e, 0x70, 0x75, 0x73, 0x68, 0x42, 0x13, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x6c, - 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x73, + 0x20, 0x01, 0x28, 0x0d, 0x52, 0x06, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x4a, 0x04, 0x08, 0x07, + 0x10, 0x08, 0x22, 0xe8, 0x03, 0x0a, 0x0c, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x44, 0x65, 0x74, 0x61, + 0x69, 0x6c, 0x73, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, + 0x02, 0x69, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x6d, 0x65, 0x6d, 0x62, 0x65, + 0x72, 0x73, 0x45, 0x31, 0x36, 0x34, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0b, 0x6d, 0x65, + 0x6d, 0x62, 0x65, 0x72, 0x73, 0x45, 0x31, 0x36, 0x34, 0x12, 0x3c, 0x0a, 0x07, 0x6d, 0x65, 0x6d, + 0x62, 0x65, 0x72, 0x73, 0x18, 0x09, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x73, 0x69, 0x67, + 0x6e, 0x61, 0x6c, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x47, 0x72, 0x6f, 0x75, 0x70, + 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x2e, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x52, 0x07, + 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x12, 0x3a, 0x0a, 0x06, 0x61, 0x76, 0x61, 0x74, 0x61, + 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x6c, + 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x44, 0x65, 0x74, + 0x61, 0x69, 0x6c, 0x73, 0x2e, 0x41, 0x76, 0x61, 0x74, 0x61, 0x72, 0x52, 0x06, 0x61, 0x76, 0x61, + 0x74, 0x61, 0x72, 0x12, 0x1c, 0x0a, 0x06, 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x18, 0x05, 0x20, + 0x01, 0x28, 0x08, 0x3a, 0x04, 0x74, 0x72, 0x75, 0x65, 0x52, 0x06, 0x61, 0x63, 0x74, 0x69, 0x76, + 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x65, 0x78, 0x70, 0x69, 0x72, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x72, + 0x18, 0x06, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0b, 0x65, 0x78, 0x70, 0x69, 0x72, 0x65, 0x54, 0x69, + 0x6d, 0x65, 0x72, 0x12, 0x14, 0x0a, 0x05, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x18, 0x07, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x05, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x12, 0x18, 0x0a, 0x07, 0x62, 0x6c, 0x6f, + 0x63, 0x6b, 0x65, 0x64, 0x18, 0x08, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x62, 0x6c, 0x6f, 0x63, + 0x6b, 0x65, 0x64, 0x12, 0x24, 0x0a, 0x0d, 0x69, 0x6e, 0x62, 0x6f, 0x78, 0x50, 0x6f, 0x73, 0x69, + 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0d, 0x69, 0x6e, 0x62, 0x6f, + 0x78, 0x50, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1a, 0x0a, 0x08, 0x61, 0x72, 0x63, + 0x68, 0x69, 0x76, 0x65, 0x64, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x61, 0x72, 0x63, + 0x68, 0x69, 0x76, 0x65, 0x64, 0x1a, 0x42, 0x0a, 0x06, 0x41, 0x76, 0x61, 0x74, 0x61, 0x72, 0x12, + 0x20, 0x0a, 0x0b, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70, + 0x65, 0x12, 0x16, 0x0a, 0x06, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x0d, 0x52, 0x06, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x1a, 0x22, 0x0a, 0x06, 0x4d, 0x65, 0x6d, + 0x62, 0x65, 0x72, 0x12, 0x12, 0x0a, 0x04, 0x65, 0x31, 0x36, 0x34, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x04, 0x65, 0x31, 0x36, 0x34, 0x4a, 0x04, 0x08, 0x01, 0x10, 0x02, 0x22, 0xc9, 0x01, + 0x0a, 0x0e, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, + 0x12, 0x5f, 0x0a, 0x11, 0x6d, 0x6f, 0x62, 0x69, 0x6c, 0x65, 0x43, 0x6f, 0x69, 0x6e, 0x41, 0x64, + 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2f, 0x2e, 0x73, 0x69, + 0x67, 0x6e, 0x61, 0x6c, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x50, 0x61, 0x79, 0x6d, + 0x65, 0x6e, 0x74, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x2e, 0x4d, 0x6f, 0x62, 0x69, 0x6c, + 0x65, 0x43, 0x6f, 0x69, 0x6e, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x48, 0x00, 0x52, 0x11, + 0x6d, 0x6f, 0x62, 0x69, 0x6c, 0x65, 0x43, 0x6f, 0x69, 0x6e, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, + 0x73, 0x1a, 0x4b, 0x0a, 0x11, 0x4d, 0x6f, 0x62, 0x69, 0x6c, 0x65, 0x43, 0x6f, 0x69, 0x6e, 0x41, + 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, + 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, + 0x12, 0x1c, 0x0a, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x0c, 0x52, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x42, 0x09, + 0x0a, 0x07, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x22, 0x72, 0x0a, 0x16, 0x44, 0x65, 0x63, + 0x72, 0x79, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x4d, 0x65, 0x73, 0x73, + 0x61, 0x67, 0x65, 0x12, 0x1e, 0x0a, 0x0a, 0x72, 0x61, 0x74, 0x63, 0x68, 0x65, 0x74, 0x4b, 0x65, + 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0a, 0x72, 0x61, 0x74, 0x63, 0x68, 0x65, 0x74, + 0x4b, 0x65, 0x79, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, + 0x70, 0x12, 0x1a, 0x0a, 0x08, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x49, 0x64, 0x18, 0x03, 0x20, + 0x01, 0x28, 0x0d, 0x52, 0x08, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x49, 0x64, 0x22, 0x45, 0x0a, + 0x13, 0x50, 0x6e, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x4d, 0x65, 0x73, + 0x73, 0x61, 0x67, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x70, 0x6e, 0x69, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x0c, 0x52, 0x03, 0x70, 0x6e, 0x69, 0x12, 0x1c, 0x0a, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, + 0x75, 0x72, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, + 0x74, 0x75, 0x72, 0x65, 0x22, 0x7d, 0x0a, 0x0b, 0x45, 0x64, 0x69, 0x74, 0x4d, 0x65, 0x73, 0x73, + 0x61, 0x67, 0x65, 0x12, 0x30, 0x0a, 0x13, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x53, 0x65, 0x6e, + 0x74, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, + 0x52, 0x13, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x53, 0x65, 0x6e, 0x74, 0x54, 0x69, 0x6d, 0x65, + 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x3c, 0x0a, 0x0b, 0x64, 0x61, 0x74, 0x61, 0x4d, 0x65, 0x73, + 0x73, 0x61, 0x67, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x73, 0x69, 0x67, + 0x6e, 0x61, 0x6c, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x44, 0x61, 0x74, 0x61, 0x4d, + 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x0b, 0x64, 0x61, 0x74, 0x61, 0x4d, 0x65, 0x73, 0x73, + 0x61, 0x67, 0x65, 0x42, 0x45, 0x0a, 0x2e, 0x6f, 0x72, 0x67, 0x2e, 0x77, 0x68, 0x69, 0x73, 0x70, + 0x65, 0x72, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x73, 0x2e, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x6c, + 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, + 0x2e, 0x70, 0x75, 0x73, 0x68, 0x42, 0x13, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x6c, 0x53, 0x65, 0x72, + 0x76, 0x69, 0x63, 0x65, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x73, } var ( @@ -8913,7 +9058,7 @@ func file_SignalService_proto_rawDescGZIP() []byte { } var file_SignalService_proto_enumTypes = make([]protoimpl.EnumInfo, 27) -var file_SignalService_proto_msgTypes = make([]protoimpl.MessageInfo, 80) +var file_SignalService_proto_msgTypes = make([]protoimpl.MessageInfo, 81) var file_SignalService_proto_goTypes = []interface{}{ (Envelope_Type)(0), // 0: signalservice.Envelope.Type (CallMessage_Offer_Type)(0), // 1: signalservice.CallMessage.Offer.Type @@ -9015,13 +9160,14 @@ var file_SignalService_proto_goTypes = []interface{}{ (*SyncMessage_DeleteForMe_ConversationIdentifier)(nil), // 97: signalservice.SyncMessage.DeleteForMe.ConversationIdentifier (*SyncMessage_DeleteForMe_AddressableMessage)(nil), // 98: signalservice.SyncMessage.DeleteForMe.AddressableMessage (*SyncMessage_DeleteForMe_MessageDeletes)(nil), // 99: signalservice.SyncMessage.DeleteForMe.MessageDeletes - (*SyncMessage_DeleteForMe_ConversationDelete)(nil), // 100: signalservice.SyncMessage.DeleteForMe.ConversationDelete - (*SyncMessage_DeleteForMe_LocalOnlyConversationDelete)(nil), // 101: signalservice.SyncMessage.DeleteForMe.LocalOnlyConversationDelete - (*GroupContext_Member)(nil), // 102: signalservice.GroupContext.Member - (*ContactDetails_Avatar)(nil), // 103: signalservice.ContactDetails.Avatar - (*GroupDetails_Avatar)(nil), // 104: signalservice.GroupDetails.Avatar - (*GroupDetails_Member)(nil), // 105: signalservice.GroupDetails.Member - (*PaymentAddress_MobileCoinAddress)(nil), // 106: signalservice.PaymentAddress.MobileCoinAddress + (*SyncMessage_DeleteForMe_AttachmentDelete)(nil), // 100: signalservice.SyncMessage.DeleteForMe.AttachmentDelete + (*SyncMessage_DeleteForMe_ConversationDelete)(nil), // 101: signalservice.SyncMessage.DeleteForMe.ConversationDelete + (*SyncMessage_DeleteForMe_LocalOnlyConversationDelete)(nil), // 102: signalservice.SyncMessage.DeleteForMe.LocalOnlyConversationDelete + (*GroupContext_Member)(nil), // 103: signalservice.GroupContext.Member + (*ContactDetails_Avatar)(nil), // 104: signalservice.ContactDetails.Avatar + (*GroupDetails_Avatar)(nil), // 105: signalservice.GroupDetails.Avatar + (*GroupDetails_Member)(nil), // 106: signalservice.GroupDetails.Member + (*PaymentAddress_MobileCoinAddress)(nil), // 107: signalservice.PaymentAddress.MobileCoinAddress } var file_SignalService_proto_depIdxs = []int32{ 0, // 0: signalservice.Envelope.type:type_name -> signalservice.Envelope.Type @@ -9085,13 +9231,13 @@ var file_SignalService_proto_depIdxs = []int32{ 92, // 58: signalservice.SyncMessage.callLogEvent:type_name -> signalservice.SyncMessage.CallLogEvent 93, // 59: signalservice.SyncMessage.deleteForMe:type_name -> signalservice.SyncMessage.DeleteForMe 26, // 60: signalservice.GroupContext.type:type_name -> signalservice.GroupContext.Type - 102, // 61: signalservice.GroupContext.members:type_name -> signalservice.GroupContext.Member + 103, // 61: signalservice.GroupContext.members:type_name -> signalservice.GroupContext.Member 40, // 62: signalservice.GroupContext.avatar:type_name -> signalservice.AttachmentPointer - 103, // 63: signalservice.ContactDetails.avatar:type_name -> signalservice.ContactDetails.Avatar + 104, // 63: signalservice.ContactDetails.avatar:type_name -> signalservice.ContactDetails.Avatar 38, // 64: signalservice.ContactDetails.verified:type_name -> signalservice.Verified - 105, // 65: signalservice.GroupDetails.members:type_name -> signalservice.GroupDetails.Member - 104, // 66: signalservice.GroupDetails.avatar:type_name -> signalservice.GroupDetails.Avatar - 106, // 67: signalservice.PaymentAddress.mobileCoinAddress:type_name -> signalservice.PaymentAddress.MobileCoinAddress + 106, // 65: signalservice.GroupDetails.members:type_name -> signalservice.GroupDetails.Member + 105, // 66: signalservice.GroupDetails.avatar:type_name -> signalservice.GroupDetails.Avatar + 107, // 67: signalservice.PaymentAddress.mobileCoinAddress:type_name -> signalservice.PaymentAddress.MobileCoinAddress 31, // 68: signalservice.EditMessage.dataMessage:type_name -> signalservice.DataMessage 1, // 69: signalservice.CallMessage.Offer.type:type_name -> signalservice.CallMessage.Offer.Type 2, // 70: signalservice.CallMessage.Hangup.type:type_name -> signalservice.CallMessage.Hangup.Type @@ -9132,18 +9278,22 @@ var file_SignalService_proto_depIdxs = []int32{ 23, // 105: signalservice.SyncMessage.CallLinkUpdate.type:type_name -> signalservice.SyncMessage.CallLinkUpdate.Type 24, // 106: signalservice.SyncMessage.CallLogEvent.type:type_name -> signalservice.SyncMessage.CallLogEvent.Type 99, // 107: signalservice.SyncMessage.DeleteForMe.messageDeletes:type_name -> signalservice.SyncMessage.DeleteForMe.MessageDeletes - 100, // 108: signalservice.SyncMessage.DeleteForMe.conversationDeletes:type_name -> signalservice.SyncMessage.DeleteForMe.ConversationDelete - 101, // 109: signalservice.SyncMessage.DeleteForMe.localOnlyConversationDeletes:type_name -> signalservice.SyncMessage.DeleteForMe.LocalOnlyConversationDelete - 97, // 110: signalservice.SyncMessage.DeleteForMe.MessageDeletes.conversation:type_name -> signalservice.SyncMessage.DeleteForMe.ConversationIdentifier - 98, // 111: signalservice.SyncMessage.DeleteForMe.MessageDeletes.messages:type_name -> signalservice.SyncMessage.DeleteForMe.AddressableMessage - 97, // 112: signalservice.SyncMessage.DeleteForMe.ConversationDelete.conversation:type_name -> signalservice.SyncMessage.DeleteForMe.ConversationIdentifier - 98, // 113: signalservice.SyncMessage.DeleteForMe.ConversationDelete.mostRecentMessages:type_name -> signalservice.SyncMessage.DeleteForMe.AddressableMessage - 97, // 114: signalservice.SyncMessage.DeleteForMe.LocalOnlyConversationDelete.conversation:type_name -> signalservice.SyncMessage.DeleteForMe.ConversationIdentifier - 115, // [115:115] is the sub-list for method output_type - 115, // [115:115] is the sub-list for method input_type - 115, // [115:115] is the sub-list for extension type_name - 115, // [115:115] is the sub-list for extension extendee - 0, // [0:115] is the sub-list for field type_name + 101, // 108: signalservice.SyncMessage.DeleteForMe.conversationDeletes:type_name -> signalservice.SyncMessage.DeleteForMe.ConversationDelete + 102, // 109: signalservice.SyncMessage.DeleteForMe.localOnlyConversationDeletes:type_name -> signalservice.SyncMessage.DeleteForMe.LocalOnlyConversationDelete + 100, // 110: signalservice.SyncMessage.DeleteForMe.attachmentDeletes:type_name -> signalservice.SyncMessage.DeleteForMe.AttachmentDelete + 97, // 111: signalservice.SyncMessage.DeleteForMe.MessageDeletes.conversation:type_name -> signalservice.SyncMessage.DeleteForMe.ConversationIdentifier + 98, // 112: signalservice.SyncMessage.DeleteForMe.MessageDeletes.messages:type_name -> signalservice.SyncMessage.DeleteForMe.AddressableMessage + 97, // 113: signalservice.SyncMessage.DeleteForMe.AttachmentDelete.conversation:type_name -> signalservice.SyncMessage.DeleteForMe.ConversationIdentifier + 98, // 114: signalservice.SyncMessage.DeleteForMe.AttachmentDelete.targetMessage:type_name -> signalservice.SyncMessage.DeleteForMe.AddressableMessage + 97, // 115: signalservice.SyncMessage.DeleteForMe.ConversationDelete.conversation:type_name -> signalservice.SyncMessage.DeleteForMe.ConversationIdentifier + 98, // 116: signalservice.SyncMessage.DeleteForMe.ConversationDelete.mostRecentMessages:type_name -> signalservice.SyncMessage.DeleteForMe.AddressableMessage + 98, // 117: signalservice.SyncMessage.DeleteForMe.ConversationDelete.mostRecentNonExpiringMessages:type_name -> signalservice.SyncMessage.DeleteForMe.AddressableMessage + 97, // 118: signalservice.SyncMessage.DeleteForMe.LocalOnlyConversationDelete.conversation:type_name -> signalservice.SyncMessage.DeleteForMe.ConversationIdentifier + 119, // [119:119] is the sub-list for method output_type + 119, // [119:119] is the sub-list for method input_type + 119, // [119:119] is the sub-list for extension type_name + 119, // [119:119] is the sub-list for extension extendee + 0, // [0:119] is the sub-list for field type_name } func init() { file_SignalService_proto_init() } @@ -10029,7 +10179,7 @@ func file_SignalService_proto_init() { } } file_SignalService_proto_msgTypes[73].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*SyncMessage_DeleteForMe_ConversationDelete); i { + switch v := v.(*SyncMessage_DeleteForMe_AttachmentDelete); i { case 0: return &v.state case 1: @@ -10041,7 +10191,7 @@ func file_SignalService_proto_init() { } } file_SignalService_proto_msgTypes[74].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*SyncMessage_DeleteForMe_LocalOnlyConversationDelete); i { + switch v := v.(*SyncMessage_DeleteForMe_ConversationDelete); i { case 0: return &v.state case 1: @@ -10053,7 +10203,7 @@ func file_SignalService_proto_init() { } } file_SignalService_proto_msgTypes[75].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*GroupContext_Member); i { + switch v := v.(*SyncMessage_DeleteForMe_LocalOnlyConversationDelete); i { case 0: return &v.state case 1: @@ -10065,7 +10215,7 @@ func file_SignalService_proto_init() { } } file_SignalService_proto_msgTypes[76].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ContactDetails_Avatar); i { + switch v := v.(*GroupContext_Member); i { case 0: return &v.state case 1: @@ -10077,7 +10227,7 @@ func file_SignalService_proto_init() { } } file_SignalService_proto_msgTypes[77].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*GroupDetails_Avatar); i { + switch v := v.(*ContactDetails_Avatar); i { case 0: return &v.state case 1: @@ -10089,7 +10239,7 @@ func file_SignalService_proto_init() { } } file_SignalService_proto_msgTypes[78].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*GroupDetails_Member); i { + switch v := v.(*GroupDetails_Avatar); i { case 0: return &v.state case 1: @@ -10101,6 +10251,18 @@ func file_SignalService_proto_init() { } } file_SignalService_proto_msgTypes[79].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GroupDetails_Member); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_SignalService_proto_msgTypes[80].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*PaymentAddress_MobileCoinAddress); i { case 0: return &v.state @@ -10146,12 +10308,12 @@ func file_SignalService_proto_init() { (*SyncMessage_OutgoingPayment_MobileCoin_)(nil), } file_SignalService_proto_msgTypes[70].OneofWrappers = []interface{}{ - (*SyncMessage_DeleteForMe_ConversationIdentifier_ThreadAci)(nil), + (*SyncMessage_DeleteForMe_ConversationIdentifier_ThreadServiceId)(nil), (*SyncMessage_DeleteForMe_ConversationIdentifier_ThreadGroupId)(nil), (*SyncMessage_DeleteForMe_ConversationIdentifier_ThreadE164)(nil), } file_SignalService_proto_msgTypes[71].OneofWrappers = []interface{}{ - (*SyncMessage_DeleteForMe_AddressableMessage_AuthorAci)(nil), + (*SyncMessage_DeleteForMe_AddressableMessage_AuthorServiceId)(nil), (*SyncMessage_DeleteForMe_AddressableMessage_AuthorE164)(nil), } type x struct{} @@ -10160,7 +10322,7 @@ func file_SignalService_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_SignalService_proto_rawDesc, NumEnums: 27, - NumMessages: 80, + NumMessages: 81, NumExtensions: 0, NumServices: 0, }, diff --git a/pkg/signalmeow/protobuf/SignalService.proto b/pkg/signalmeow/protobuf/SignalService.proto index dceaf0a..30127a1 100644 --- a/pkg/signalmeow/protobuf/SignalService.proto +++ b/pkg/signalmeow/protobuf/SignalService.proto @@ -614,6 +614,7 @@ message SyncMessage { ACCEPTED = 1; NOT_ACCEPTED = 2; DELETE = 3; + OBSERVED = 4; } optional bytes conversationId = 1; @@ -656,7 +657,7 @@ message SyncMessage { message DeleteForMe { message ConversationIdentifier { oneof identifier { - string threadAci = 1; + string threadServiceId = 1; bytes threadGroupId = 2; string threadE164 = 3; } @@ -664,7 +665,7 @@ message SyncMessage { message AddressableMessage { oneof author { - string authorAci = 1; + string authorServiceId = 1; string authorE164 = 2; } optional uint64 sentTimestamp = 3; @@ -675,9 +676,18 @@ message SyncMessage { repeated AddressableMessage messages = 2; } + message AttachmentDelete { + optional ConversationIdentifier conversation = 1; + optional AddressableMessage targetMessage = 2; + optional bytes uuid = 3; // The `uuid` from the `Attachment`. + optional bytes fallbackDigest = 4; + optional bytes fallbackPlaintextHash = 5; + } + message ConversationDelete { optional ConversationIdentifier conversation = 1; repeated AddressableMessage mostRecentMessages = 2; + repeated AddressableMessage mostRecentNonExpiringMessages = 4; optional bool isFullDelete = 3; } @@ -688,6 +698,7 @@ message SyncMessage { repeated MessageDeletes messageDeletes = 1; repeated ConversationDelete conversationDeletes = 2; repeated LocalOnlyConversationDelete localOnlyConversationDeletes = 3; + repeated AttachmentDelete attachmentDeletes = 4; } optional Sent sent = 1; @@ -743,7 +754,8 @@ message AttachmentPointer { optional string blurHash = 12; optional uint64 uploadTimestamp = 13; optional uint32 cdnNumber = 14; - // Next ID: 19 + optional bytes uuid = 20; + // Next ID: 21 } message GroupContext { diff --git a/pkg/signalmeow/protobuf/update-protos.sh b/pkg/signalmeow/protobuf/update-protos.sh index dac087b..e6d0ea3 100755 --- a/pkg/signalmeow/protobuf/update-protos.sh +++ b/pkg/signalmeow/protobuf/update-protos.sh @@ -1,8 +1,8 @@ #!/bin/bash set -euo pipefail -ANDROID_GIT_REVISION=${1:-c4805126008977827f8ee08e016568fc9a374b4d} -DESKTOP_GIT_REVISION=${1:-af1c593fef4e485127ea356b3b592f3c781c2a16} +ANDROID_GIT_REVISION=${1:-6c302b708a6980041ff57271f800c0b092e74ef9} +DESKTOP_GIT_REVISION=${1:-b34f2fbb99d68bd462715f8519524100580fb372} update_proto() { case "$1" in From fdacfc2f677b9a00b53a31ece44bbd2826023816 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Wed, 10 Jul 2024 23:50:41 +0300 Subject: [PATCH 102/580] v2: update mautrix-go --- cmd/mautrix-signal-v2/legacymigrate.sql | 3 +-- cmd/mautrix-signal-v2/main.go | 2 +- go.mod | 2 +- go.sum | 4 ++-- pkg/connector/handlematrix.go | 7 ++----- 5 files changed, 7 insertions(+), 11 deletions(-) diff --git a/cmd/mautrix-signal-v2/legacymigrate.sql b/cmd/mautrix-signal-v2/legacymigrate.sql index 5e8c5ba..eec7101 100644 --- a/cmd/mautrix-signal-v2/legacymigrate.sql +++ b/cmd/mautrix-signal-v2/legacymigrate.sql @@ -90,7 +90,7 @@ FROM puppet_old; INSERT INTO message ( bridge_id, id, part_id, mxid, room_id, room_receiver, - sender_id, timestamp, relates_to, metadata + sender_id, timestamp, metadata ) SELECT '', -- bridge_id @@ -104,7 +104,6 @@ SELECT END, -- room_receiver cast(sender AS TEXT), -- sender_id timestamp * 1000000, - NULL, -- relates_to '{}' -- metadata FROM message_old; diff --git a/cmd/mautrix-signal-v2/main.go b/cmd/mautrix-signal-v2/main.go index 80d2efc..39a3496 100644 --- a/cmd/mautrix-signal-v2/main.go +++ b/cmd/mautrix-signal-v2/main.go @@ -51,7 +51,7 @@ func main() { 20, "v0.5.1", "v0.7.0", - m.LegacyMigrateSimple(legacyMigrateRenameTables, legacyMigrateCopyData, 4), + m.LegacyMigrateSimple(legacyMigrateRenameTables, legacyMigrateCopyData, 7), true, ) } diff --git a/go.mod b/go.mod index 8d62958..3f068ba 100644 --- a/go.mod +++ b/go.mod @@ -19,7 +19,7 @@ require ( golang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8 golang.org/x/net v0.26.0 google.golang.org/protobuf v1.34.2 - maunium.net/go/mautrix v0.19.0-beta.1.0.20240709160900-fc7ed77e2630 + maunium.net/go/mautrix v0.19.0-beta.1.0.20240710204602-dd16a8d1d90b nhooyr.io/websocket v1.8.11 ) diff --git a/go.sum b/go.sum index 094f2d1..a7c534e 100644 --- a/go.sum +++ b/go.sum @@ -93,7 +93,7 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= maunium.net/go/mauflag v1.0.0 h1:YiaRc0tEI3toYtJMRIfjP+jklH45uDHtT80nUamyD4M= maunium.net/go/mauflag v1.0.0/go.mod h1:nLivPOpTpHnpzEh8jEdSL9UqO9+/KBJFmNRlwKfkPeA= -maunium.net/go/mautrix v0.19.0-beta.1.0.20240709160900-fc7ed77e2630 h1:X+IuVExANBr0gfFQ22vpecvDzkiSCVAnFAYvyIZ+uOI= -maunium.net/go/mautrix v0.19.0-beta.1.0.20240709160900-fc7ed77e2630/go.mod h1:bNQrvIftiwJ+7OjSh+Gza5xcncq1ooHk6oyDWq4B4sg= +maunium.net/go/mautrix v0.19.0-beta.1.0.20240710204602-dd16a8d1d90b h1:xYEIkM0OzirvHPpTwYiDQrh6PHjDny5Ox84SIkD2aXc= +maunium.net/go/mautrix v0.19.0-beta.1.0.20240710204602-dd16a8d1d90b/go.mod h1:bNQrvIftiwJ+7OjSh+Gza5xcncq1ooHk6oyDWq4B4sg= nhooyr.io/websocket v1.8.11 h1:f/qXNc2/3DpoSZkHt1DQu6rj4zGC8JmkkLkWss0MgN0= nhooyr.io/websocket v1.8.11/go.mod h1:rN9OFWIUwuxg4fR5tELlYC04bXYowCP9GX47ivo2l+c= diff --git a/pkg/connector/handlematrix.go b/pkg/connector/handlematrix.go index 41b5ecd..ea3475e 100644 --- a/pkg/connector/handlematrix.go +++ b/pkg/connector/handlematrix.go @@ -101,9 +101,6 @@ func (s *SignalClient) HandleMatrixMessage(ctx context.Context, msg *bridgev2.Ma dbMsg.Metadata.Extra = map[string]any{ "contains_attachments": len(converted.Attachments) > 0, } - if msg.ReplyTo != nil { - dbMsg.RelatesToRowID = msg.ReplyTo.RowID - } return &bridgev2.MatrixMessageResponse{ DB: dbMsg, }, nil @@ -122,9 +119,9 @@ func (s *SignalClient) HandleMatrixEdit(ctx context.Context, msg *bridgev2.Matri Client: s, Portal: msg.Portal, } - if msg.EditTarget.RelatesToRowID != 0 { + if msg.EditTarget.ReplyTo.MessageID != "" { var err error - mcCtx.ReplyTo, err = s.Main.Bridge.DB.Message.GetByRowID(ctx, msg.EditTarget.RelatesToRowID) + mcCtx.ReplyTo, err = s.Main.Bridge.DB.Message.GetFirstOrSpecificPartByID(ctx, msg.Portal.Receiver, msg.EditTarget.ReplyTo) if err != nil { return fmt.Errorf("failed to get message reply target: %w", err) } From 76462a7938f077479c27f4925df3d99e502938da Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Fri, 12 Jul 2024 15:01:31 +0300 Subject: [PATCH 103/580] v2: update mautrix-go --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 3f068ba..f2c0b50 100644 --- a/go.mod +++ b/go.mod @@ -19,7 +19,7 @@ require ( golang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8 golang.org/x/net v0.26.0 google.golang.org/protobuf v1.34.2 - maunium.net/go/mautrix v0.19.0-beta.1.0.20240710204602-dd16a8d1d90b + maunium.net/go/mautrix v0.19.0-beta.1.0.20240712120058-0f9f923378c5 nhooyr.io/websocket v1.8.11 ) diff --git a/go.sum b/go.sum index a7c534e..bf5118a 100644 --- a/go.sum +++ b/go.sum @@ -93,7 +93,7 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= maunium.net/go/mauflag v1.0.0 h1:YiaRc0tEI3toYtJMRIfjP+jklH45uDHtT80nUamyD4M= maunium.net/go/mauflag v1.0.0/go.mod h1:nLivPOpTpHnpzEh8jEdSL9UqO9+/KBJFmNRlwKfkPeA= -maunium.net/go/mautrix v0.19.0-beta.1.0.20240710204602-dd16a8d1d90b h1:xYEIkM0OzirvHPpTwYiDQrh6PHjDny5Ox84SIkD2aXc= -maunium.net/go/mautrix v0.19.0-beta.1.0.20240710204602-dd16a8d1d90b/go.mod h1:bNQrvIftiwJ+7OjSh+Gza5xcncq1ooHk6oyDWq4B4sg= +maunium.net/go/mautrix v0.19.0-beta.1.0.20240712120058-0f9f923378c5 h1:trHMeTOodR/JvlYiy6xGgGnXcy/VAuJp9eeP816S6yw= +maunium.net/go/mautrix v0.19.0-beta.1.0.20240712120058-0f9f923378c5/go.mod h1:bNQrvIftiwJ+7OjSh+Gza5xcncq1ooHk6oyDWq4B4sg= nhooyr.io/websocket v1.8.11 h1:f/qXNc2/3DpoSZkHt1DQu6rj4zGC8JmkkLkWss0MgN0= nhooyr.io/websocket v1.8.11/go.mod h1:rN9OFWIUwuxg4fR5tELlYC04bXYowCP9GX47ivo2l+c= From 0e46919ace5f63f5ef6a1991d49aaef022a3abf0 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Fri, 12 Jul 2024 16:54:37 +0300 Subject: [PATCH 104/580] v2: update mautrix-go to support appservice websockets --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index f2c0b50..18c1c10 100644 --- a/go.mod +++ b/go.mod @@ -19,7 +19,7 @@ require ( golang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8 golang.org/x/net v0.26.0 google.golang.org/protobuf v1.34.2 - maunium.net/go/mautrix v0.19.0-beta.1.0.20240712120058-0f9f923378c5 + maunium.net/go/mautrix v0.19.0-beta.1.0.20240712135340-7c9b8cb28773 nhooyr.io/websocket v1.8.11 ) diff --git a/go.sum b/go.sum index bf5118a..72bf004 100644 --- a/go.sum +++ b/go.sum @@ -93,7 +93,7 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= maunium.net/go/mauflag v1.0.0 h1:YiaRc0tEI3toYtJMRIfjP+jklH45uDHtT80nUamyD4M= maunium.net/go/mauflag v1.0.0/go.mod h1:nLivPOpTpHnpzEh8jEdSL9UqO9+/KBJFmNRlwKfkPeA= -maunium.net/go/mautrix v0.19.0-beta.1.0.20240712120058-0f9f923378c5 h1:trHMeTOodR/JvlYiy6xGgGnXcy/VAuJp9eeP816S6yw= -maunium.net/go/mautrix v0.19.0-beta.1.0.20240712120058-0f9f923378c5/go.mod h1:bNQrvIftiwJ+7OjSh+Gza5xcncq1ooHk6oyDWq4B4sg= +maunium.net/go/mautrix v0.19.0-beta.1.0.20240712135340-7c9b8cb28773 h1:4rpBbhsdOkRF3bZ6VscH+yTbk3sDV1w+Bkr+J9XLHeU= +maunium.net/go/mautrix v0.19.0-beta.1.0.20240712135340-7c9b8cb28773/go.mod h1:bNQrvIftiwJ+7OjSh+Gza5xcncq1ooHk6oyDWq4B4sg= nhooyr.io/websocket v1.8.11 h1:f/qXNc2/3DpoSZkHt1DQu6rj4zGC8JmkkLkWss0MgN0= nhooyr.io/websocket v1.8.11/go.mod h1:rN9OFWIUwuxg4fR5tELlYC04bXYowCP9GX47ivo2l+c= From b853d1756f8fee1c873a294a07a724f1aed8e5f8 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Fri, 12 Jul 2024 19:55:55 +0300 Subject: [PATCH 105/580] main: update dependencies --- go.mod | 12 ++++++------ go.sum | 24 ++++++++++++------------ 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/go.mod b/go.mod index 18c1c10..18a5606 100644 --- a/go.mod +++ b/go.mod @@ -14,12 +14,12 @@ require ( github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e github.com/stretchr/testify v1.9.0 github.com/tidwall/gjson v1.17.1 - go.mau.fi/util v0.5.1-0.20240702170310-bd1da3c069eb - golang.org/x/crypto v0.24.0 - golang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8 - golang.org/x/net v0.26.0 + go.mau.fi/util v0.5.1-0.20240710154926-931b33d6d530 + golang.org/x/crypto v0.25.0 + golang.org/x/exp v0.0.0-20240707233637-46b078467d37 + golang.org/x/net v0.27.0 google.golang.org/protobuf v1.34.2 - maunium.net/go/mautrix v0.19.0-beta.1.0.20240712135340-7c9b8cb28773 + maunium.net/go/mautrix v0.19.0-beta.1.0.20240712164309-85e0664cb441 nhooyr.io/websocket v1.8.11 ) @@ -42,7 +42,7 @@ require ( github.com/tidwall/sjson v1.2.5 // indirect github.com/yuin/goldmark v1.7.4 // indirect go.mau.fi/zeroconfig v0.1.2 // indirect - golang.org/x/sys v0.21.0 // indirect + golang.org/x/sys v0.22.0 // indirect gopkg.in/natefinch/lumberjack.v2 v2.2.1 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect maunium.net/go/mauflag v1.0.0 // indirect diff --git a/go.sum b/go.sum index 72bf004..e7f09ae 100644 --- a/go.sum +++ b/go.sum @@ -67,21 +67,21 @@ github.com/tidwall/sjson v1.2.5 h1:kLy8mja+1c9jlljvWTlSazM7cKDRfJuR/bOJhcY5NcY= github.com/tidwall/sjson v1.2.5/go.mod h1:Fvgq9kS/6ociJEDnK0Fk1cpYF4FIW6ZF7LAe+6jwd28= github.com/yuin/goldmark v1.7.4 h1:BDXOHExt+A7gwPCJgPIIq7ENvceR7we7rOS9TNoLZeg= github.com/yuin/goldmark v1.7.4/go.mod h1:uzxRWxtg69N339t3louHJ7+O03ezfj6PlliRlaOzY1E= -go.mau.fi/util v0.5.1-0.20240702170310-bd1da3c069eb h1:VZPo2pvfjNj6fkFv5e9FyTYx96BLwwYNA19WYaY+KN8= -go.mau.fi/util v0.5.1-0.20240702170310-bd1da3c069eb/go.mod h1:DsJzUrJAG53lCZnnYvq9/mOyLuPScWwYhvETiTrpdP4= +go.mau.fi/util v0.5.1-0.20240710154926-931b33d6d530 h1:ZWMrLC+Fn2AmKL8HM04YY0zyMDMOagQZVukpxp0rmic= +go.mau.fi/util v0.5.1-0.20240710154926-931b33d6d530/go.mod h1:DsJzUrJAG53lCZnnYvq9/mOyLuPScWwYhvETiTrpdP4= go.mau.fi/zeroconfig v0.1.2 h1:DKOydWnhPMn65GbXZOafgkPm11BvFashZWLct0dGFto= go.mau.fi/zeroconfig v0.1.2/go.mod h1:NcSJkf180JT+1IId76PcMuLTNa1CzsFFZ0nBygIQM70= -golang.org/x/crypto v0.24.0 h1:mnl8DM0o513X8fdIkmyFE/5hTYxbwYOjDS/+rK6qpRI= -golang.org/x/crypto v0.24.0/go.mod h1:Z1PMYSOR5nyMcyAVAIQSKCDwalqy85Aqn1x3Ws4L5DM= -golang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8 h1:yixxcjnhBmY0nkL253HFVIm0JsFHwrHdT3Yh6szTnfY= -golang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8/go.mod h1:jj3sYF3dwk5D+ghuXyeI3r5MFf+NT2An6/9dOA95KSI= -golang.org/x/net v0.26.0 h1:soB7SVo0PWrY4vPW/+ay0jKDNScG2X9wFeYlXIvJsOQ= -golang.org/x/net v0.26.0/go.mod h1:5YKkiSynbBIh3p6iOc/vibscux0x38BZDkn8sCUPxHE= +golang.org/x/crypto v0.25.0 h1:ypSNr+bnYL2YhwoMt2zPxHFmbAN1KZs/njMG3hxUp30= +golang.org/x/crypto v0.25.0/go.mod h1:T+wALwcMOSE0kXgUAnPAHqTLW+XHgcELELW8VaDgm/M= +golang.org/x/exp v0.0.0-20240707233637-46b078467d37 h1:uLDX+AfeFCct3a2C7uIWBKMJIR3CJMhcgfrUAqjRK6w= +golang.org/x/exp v0.0.0-20240707233637-46b078467d37/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY= +golang.org/x/net v0.27.0 h1:5K3Njcw06/l2y9vpGCSdcxWOYHOUk3dVNGDXN+FvAys= +golang.org/x/net v0.27.0/go.mod h1:dDi0PyhWNoiUOrAS8uXv/vnScO4wnHQO4mj9fn/RytE= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.21.0 h1:rF+pYz3DAGSQAxAu1CbC7catZg4ebC4UIeIhKxBZvws= -golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI= +golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= @@ -93,7 +93,7 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= maunium.net/go/mauflag v1.0.0 h1:YiaRc0tEI3toYtJMRIfjP+jklH45uDHtT80nUamyD4M= maunium.net/go/mauflag v1.0.0/go.mod h1:nLivPOpTpHnpzEh8jEdSL9UqO9+/KBJFmNRlwKfkPeA= -maunium.net/go/mautrix v0.19.0-beta.1.0.20240712135340-7c9b8cb28773 h1:4rpBbhsdOkRF3bZ6VscH+yTbk3sDV1w+Bkr+J9XLHeU= -maunium.net/go/mautrix v0.19.0-beta.1.0.20240712135340-7c9b8cb28773/go.mod h1:bNQrvIftiwJ+7OjSh+Gza5xcncq1ooHk6oyDWq4B4sg= +maunium.net/go/mautrix v0.19.0-beta.1.0.20240712164309-85e0664cb441 h1:k2yoj2UiUX4X1csGiXpyxkN3hWR4kmzlCseY0iznVb4= +maunium.net/go/mautrix v0.19.0-beta.1.0.20240712164309-85e0664cb441/go.mod h1:bNQrvIftiwJ+7OjSh+Gza5xcncq1ooHk6oyDWq4B4sg= nhooyr.io/websocket v1.8.11 h1:f/qXNc2/3DpoSZkHt1DQu6rj4zGC8JmkkLkWss0MgN0= nhooyr.io/websocket v1.8.11/go.mod h1:rN9OFWIUwuxg4fR5tELlYC04bXYowCP9GX47ivo2l+c= From 1e093d6dc6840ed99aedd79c1a1ddd3a16af30e7 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Sat, 13 Jul 2024 14:11:28 +0300 Subject: [PATCH 106/580] v2: update mautrix-go and use new typed metadata structs --- cmd/mautrix-signal-v2/legacymigrate.sql | 38 ++++++++++-------- cmd/mautrix-signal-v2/legacyprovision.go | 2 +- cmd/mautrix-signal-v2/main.go | 2 +- go.mod | 2 +- go.sum | 4 +- pkg/connector/chatinfo.go | 15 ++++---- pkg/connector/connector.go | 6 +-- pkg/connector/dbmeta.go | 49 ++++++++++++++++++++++++ pkg/connector/groupinfo.go | 12 +++--- pkg/connector/handlematrix.go | 20 ++++------ pkg/connector/handlesignal.go | 13 ++++--- pkg/connector/login.go | 12 ++---- pkg/connector/msgconvproxy.go | 6 +-- 13 files changed, 112 insertions(+), 69 deletions(-) create mode 100644 pkg/connector/dbmeta.go diff --git a/cmd/mautrix-signal-v2/legacymigrate.sql b/cmd/mautrix-signal-v2/legacymigrate.sql index eec7101..952dc4d 100644 --- a/cmd/mautrix-signal-v2/legacymigrate.sql +++ b/cmd/mautrix-signal-v2/legacymigrate.sql @@ -2,14 +2,15 @@ INSERT INTO "user" (bridge_id, mxid, management_room, access_token) SELECT '', mxid, management_room, NULL FROM user_old; -INSERT INTO user_login (bridge_id, user_mxid, id, space_room, metadata) +INSERT INTO user_login (bridge_id, user_mxid, id, remote_name, space_room, metadata) SELECT '', mxid, cast(uuid AS TEXT), + phone, -- remote_name space_room, CAST( - '{"phone":"' || phone || '","remote_name":"' || phone || '"}' + '{"phone":"' || phone || '"}' -- only: postgres AS jsonb -- only: sqlite (line commented) @@ -20,7 +21,8 @@ FROM user_old WHERE uuid IS NOT NULL AND phone IS NOT NULL; INSERT INTO portal ( bridge_id, id, receiver, mxid, parent_id, parent_receiver, relay_bridge_id, relay_login_id, name, topic, avatar_id, avatar_hash, avatar_mxc, - name_set, avatar_set, topic_set, in_space, metadata + name_set, avatar_set, topic_set, in_space, + room_type, disappear_type, disappear_timer, metadata ) SELECT '', -- bridge_id @@ -48,11 +50,11 @@ SELECT avatar_set, topic_set, false, -- in_space + CASE WHEN LENGTH(chat_id)=44 THEN '' ELSE 'dm' END, -- room_type + CASE WHEN expiration_time<>0 THEN 'after_read' END, + CASE WHEN expiration_time<>0 THEN expiration_time * 1000000000 END, CAST( - CASE WHEN expiration_time = 0 - THEN '{"revision":"' || revision || '"}' - ELSE '{"disappear_type": "after_read", "disappear_timer": "' || (expiration_time * 1000000000) || '","revision":"' || revision || '"}' - END + '{"revision":' || revision || '}' -- only: postgres AS jsonb -- only: sqlite (line commented) @@ -61,7 +63,9 @@ SELECT FROM portal_old; INSERT INTO ghost ( - bridge_id, id, name, avatar_id, avatar_hash, avatar_mxc, name_set, avatar_set, metadata + bridge_id, id, name, avatar_id, avatar_hash, avatar_mxc, + name_set, avatar_set, contact_info_set, + is_bot, identifiers, metadata ) SELECT '', -- bridge_id @@ -76,6 +80,9 @@ SELECT avatar_url, -- avatar_mxc name_set, avatar_set, + contact_info_set, + false, -- is_bot + '[]', -- identifiers CAST( CASE WHEN profile_fetched_at IS NOT NULL THEN ('{"profile_fetched_at":' || profile_fetched_at || '}') @@ -90,7 +97,7 @@ FROM puppet_old; INSERT INTO message ( bridge_id, id, part_id, mxid, room_id, room_receiver, - sender_id, timestamp, metadata + sender_id, sender_mxid, timestamp, edit_count, metadata ) SELECT '', -- bridge_id @@ -103,7 +110,9 @@ SELECT ELSE cast(signal_receiver AS TEXT) END, -- room_receiver cast(sender AS TEXT), -- sender_id + '', -- sender_mxid timestamp * 1000000, + 0, -- edit_count '{}' -- metadata FROM message_old; @@ -120,7 +129,7 @@ SELECT FROM disappearing_message_old; INSERT INTO reaction ( - bridge_id, message_id, message_part_id, sender_id, emoji_id, + bridge_id, message_id, message_part_id, sender_id, emoji_id, emoji, room_id, room_receiver, mxid, timestamp, metadata ) SELECT @@ -129,6 +138,7 @@ SELECT '', -- message_part_id cast(author AS TEXT), -- sender_id '', -- emoji_id + emoji, signal_chat_id, -- room_id CASE WHEN signal_receiver='00000000-0000-0000-0000-000000000000' THEN '' @@ -136,13 +146,7 @@ SELECT END, -- room_receiver mxid, msg_timestamp * 1000000, -- timestamp (actual reaction timestamp not available) - CAST( - '{"emoji":"' || emoji || '"}' - -- only: postgres - AS jsonb - -- only: sqlite (line commented) --- AS text - ) -- metadata + '{}' -- metadata FROM reaction_old; INSERT INTO user_portal ( diff --git a/cmd/mautrix-signal-v2/legacyprovision.go b/cmd/mautrix-signal-v2/legacyprovision.go index 0eef485..48a9c5f 100644 --- a/cmd/mautrix-signal-v2/legacyprovision.go +++ b/cmd/mautrix-signal-v2/legacyprovision.go @@ -186,7 +186,7 @@ func legacyProvLinkWaitAccount(w http.ResponseWriter, r *http.Request) { Success: true, Status: "prekeys_registered", UUID: string(res.CompleteParams.UserLogin.ID), - Number: res.CompleteParams.UserLogin.Metadata.RemoteName, + Number: res.CompleteParams.UserLogin.RemoteName, }) } login.Delete() diff --git a/cmd/mautrix-signal-v2/main.go b/cmd/mautrix-signal-v2/main.go index 39a3496..cc1f0bf 100644 --- a/cmd/mautrix-signal-v2/main.go +++ b/cmd/mautrix-signal-v2/main.go @@ -51,7 +51,7 @@ func main() { 20, "v0.5.1", "v0.7.0", - m.LegacyMigrateSimple(legacyMigrateRenameTables, legacyMigrateCopyData, 7), + m.LegacyMigrateSimple(legacyMigrateRenameTables, legacyMigrateCopyData, 9), true, ) } diff --git a/go.mod b/go.mod index 18a5606..42b930a 100644 --- a/go.mod +++ b/go.mod @@ -19,7 +19,7 @@ require ( golang.org/x/exp v0.0.0-20240707233637-46b078467d37 golang.org/x/net v0.27.0 google.golang.org/protobuf v1.34.2 - maunium.net/go/mautrix v0.19.0-beta.1.0.20240712164309-85e0664cb441 + maunium.net/go/mautrix v0.19.0-beta.1.0.20240713090952-9fdf94132a3d nhooyr.io/websocket v1.8.11 ) diff --git a/go.sum b/go.sum index e7f09ae..2fc2c90 100644 --- a/go.sum +++ b/go.sum @@ -93,7 +93,7 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= maunium.net/go/mauflag v1.0.0 h1:YiaRc0tEI3toYtJMRIfjP+jklH45uDHtT80nUamyD4M= maunium.net/go/mauflag v1.0.0/go.mod h1:nLivPOpTpHnpzEh8jEdSL9UqO9+/KBJFmNRlwKfkPeA= -maunium.net/go/mautrix v0.19.0-beta.1.0.20240712164309-85e0664cb441 h1:k2yoj2UiUX4X1csGiXpyxkN3hWR4kmzlCseY0iznVb4= -maunium.net/go/mautrix v0.19.0-beta.1.0.20240712164309-85e0664cb441/go.mod h1:bNQrvIftiwJ+7OjSh+Gza5xcncq1ooHk6oyDWq4B4sg= +maunium.net/go/mautrix v0.19.0-beta.1.0.20240713090952-9fdf94132a3d h1:Fxpvg1sOmkKKsYqbTLEIf6La9+qeBFKmnwkZfcxa8eM= +maunium.net/go/mautrix v0.19.0-beta.1.0.20240713090952-9fdf94132a3d/go.mod h1:bNQrvIftiwJ+7OjSh+Gza5xcncq1ooHk6oyDWq4B4sg= nhooyr.io/websocket v1.8.11 h1:f/qXNc2/3DpoSZkHt1DQu6rj4zGC8JmkkLkWss0MgN0= nhooyr.io/websocket v1.8.11/go.mod h1:rN9OFWIUwuxg4fR5tELlYC04bXYowCP9GX47ivo2l+c= diff --git a/pkg/connector/chatinfo.go b/pkg/connector/chatinfo.go index 30dc546..36daecb 100644 --- a/pkg/connector/chatinfo.go +++ b/pkg/connector/chatinfo.go @@ -25,7 +25,9 @@ import ( "github.com/google/uuid" "github.com/rs/zerolog" + "go.mau.fi/util/ptr" "maunium.net/go/mautrix/bridgev2" + "maunium.net/go/mautrix/bridgev2/database" "maunium.net/go/mautrix/bridgev2/networkid" "maunium.net/go/mautrix/event" @@ -192,8 +194,6 @@ func (s *SignalClient) GetContactList(ctx context.Context) ([]*bridgev2.ResolveI } func (s *SignalClient) makeCreateDMResponse(recipient *types.Recipient) *bridgev2.CreateChatResponse { - isDirectChat := true - isSpace := false name := "" topic := PrivateChatTopic members := &bridgev2.ChatMemberList{ @@ -236,12 +236,11 @@ func (s *SignalClient) makeCreateDMResponse(recipient *types.Recipient) *bridgev return &bridgev2.CreateChatResponse{ PortalID: s.makeDMPortalKey(serviceID), PortalInfo: &bridgev2.ChatInfo{ - Name: &name, - Avatar: avatar, - Topic: &topic, - Members: members, - IsDirectChat: &isDirectChat, - IsSpace: &isSpace, + Name: &name, + Avatar: avatar, + Topic: &topic, + Members: members, + Type: ptr.Ptr(database.RoomTypeDM), }, } } diff --git a/pkg/connector/connector.go b/pkg/connector/connector.go index dcb7ada..4c36674 100644 --- a/pkg/connector/connector.go +++ b/pkg/connector/connector.go @@ -129,11 +129,11 @@ func (s *SignalConnector) Init(bridge *bridgev2.Bridge) { LocationFormat: s.Config.LocationFormat, UpdateDisappearing: func(ctx context.Context, newTimer time.Duration) { portal := ctx.Value(msgconvContextKey).(*msgconvContext).Portal - portal.Metadata.DisappearTimer = newTimer + portal.Disappear.Timer = newTimer if newTimer == 0 { - portal.Metadata.DisappearType = "" + portal.Disappear.Type = "" } else { - portal.Metadata.DisappearType = database.DisappearingTypeAfterRead + portal.Disappear.Type = database.DisappearingTypeAfterRead } err := portal.Save(ctx) if err != nil { diff --git a/pkg/connector/dbmeta.go b/pkg/connector/dbmeta.go new file mode 100644 index 0000000..18de885 --- /dev/null +++ b/pkg/connector/dbmeta.go @@ -0,0 +1,49 @@ +// mautrix-signal - A Matrix-Signal puppeting bridge. +// Copyright (C) 2024 Tulir Asokan +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +package connector + +import ( + "maunium.net/go/mautrix/bridgev2/database" +) + +func (s *SignalConnector) GetDBMetaTypes() database.MetaTypes { + return database.MetaTypes{ + Portal: func() any { + return &PortalMetadata{} + }, + Ghost: nil, + Message: func() any { + return &MessageMetadata{} + }, + Reaction: nil, + UserLogin: func() any { + return &UserLoginMetadata{} + }, + } +} + +type PortalMetadata struct { + Revision uint32 `json:"revision"` +} + +type MessageMetadata struct { + ContainsAttachments bool `json:"contains_attachments,omitempty"` +} + +type UserLoginMetadata struct { + Phone string `json:"phone"` +} diff --git a/pkg/connector/groupinfo.go b/pkg/connector/groupinfo.go index 65cbab2..333ed7c 100644 --- a/pkg/connector/groupinfo.go +++ b/pkg/connector/groupinfo.go @@ -21,6 +21,7 @@ import ( "time" "github.com/rs/zerolog" + "go.mau.fi/util/ptr" "maunium.net/go/mautrix/bridgev2" "maunium.net/go/mautrix/bridgev2/database" "maunium.net/go/mautrix/event" @@ -94,8 +95,6 @@ func (s *SignalClient) getGroupInfo(ctx context.Context, groupID types.GroupIden if err != nil { return nil, err } - isDM := false - isSpace := false members := &bridgev2.ChatMemberList{ IsFull: true, Members: make([]bridgev2.ChatMember, len(groupInfo.Members), len(groupInfo.Members)+len(groupInfo.PendingMembers)+len(groupInfo.RequestingMembers)+len(groupInfo.BannedMembers)), @@ -153,8 +152,7 @@ func (s *SignalClient) getGroupInfo(ctx context.Context, groupID types.GroupIden Timer: time.Duration(groupInfo.DisappearingMessagesDuration) * time.Second, }, Members: members, - IsDirectChat: &isDM, - IsSpace: &isSpace, + Type: ptr.Ptr(database.RoomTypeDefault), JoinRule: &event.JoinRulesEventContent{JoinRule: joinRule}, ExtraUpdates: makeRevisionUpdater(groupInfo.Revision), }, nil @@ -176,9 +174,9 @@ func (s *SignalClient) makeGroupAvatar(meta signalmeow.GroupAvatarMeta) *bridgev func makeRevisionUpdater(rev uint32) func(ctx context.Context, portal *bridgev2.Portal) bool { return func(ctx context.Context, portal *bridgev2.Portal) bool { - currentRev, _ := database.GetNumberFromMap[uint32](portal.Metadata.Extra, "revision") - if currentRev < rev { - portal.Metadata.Extra["revision"] = rev + meta := portal.Metadata.(*PortalMetadata) + if meta.Revision < rev { + meta.Revision = rev return true } return false diff --git a/pkg/connector/handlematrix.go b/pkg/connector/handlematrix.go index ea3475e..2f36ae7 100644 --- a/pkg/connector/handlematrix.go +++ b/pkg/connector/handlematrix.go @@ -97,9 +97,9 @@ func (s *SignalClient) HandleMatrixMessage(ctx context.Context, msg *bridgev2.Ma ID: makeMessageID(s.Client.Store.ACI, converted.GetTimestamp()), SenderID: makeUserID(s.Client.Store.ACI), Timestamp: time.UnixMilli(int64(converted.GetTimestamp())), - } - dbMsg.Metadata.Extra = map[string]any{ - "contains_attachments": len(converted.Attachments) > 0, + Metadata: &MessageMetadata{ + ContainsAttachments: len(converted.Attachments) > 0, + }, } return &bridgev2.MatrixMessageResponse{ DB: dbMsg, @@ -139,8 +139,8 @@ func (s *SignalClient) HandleMatrixEdit(ctx context.Context, msg *bridgev2.Matri return err } msg.EditTarget.ID = makeMessageID(s.Client.Store.ACI, converted.GetTimestamp()) - msg.EditTarget.Metadata.Extra["contains_attachments"] = len(converted.Attachments) > 0 - msg.EditTarget.Metadata.EditCount++ + msg.EditTarget.Metadata = &MessageMetadata{ContainsAttachments: len(converted.Attachments) > 0} + msg.EditTarget.EditCount++ return nil } @@ -186,7 +186,7 @@ func (s *SignalClient) HandleMatrixReactionRemove(ctx context.Context, msg *brid Timestamp: proto.Uint64(uint64(msg.Event.Timestamp)), RequiredProtocolVersion: proto.Uint32(uint32(signalpb.DataMessage_REACTIONS)), Reaction: &signalpb.DataMessage_Reaction{ - Emoji: proto.String(msg.TargetReaction.Metadata.Emoji), + Emoji: proto.String(msg.TargetReaction.Emoji), Remove: proto.Bool(true), TargetAuthorAci: proto.String(targetAuthorACI.String()), TargetSentTimestamp: proto.Uint64(targetSentTimestamp), @@ -296,11 +296,7 @@ func (s *SignalClient) handleMatrixRoomMeta(ctx context.Context, portal *bridgev if err != nil || groupID == "" { return false, err } - rev, ok := database.GetNumberFromMap[uint32](portal.Metadata.Extra, "revision") - if !ok { - return false, fmt.Errorf("missing revision in portal metadata") - } - gc.Revision = rev + 1 + gc.Revision = portal.Metadata.(*PortalMetadata).Revision + 1 revision, err := s.Client.UpdateGroup(ctx, gc, groupID) if err != nil { return false, err @@ -320,7 +316,7 @@ func (s *SignalClient) handleMatrixRoomMeta(ctx context.Context, portal *bridgev if postUpdatePortal != nil { postUpdatePortal() } - portal.Metadata.Extra["revision"] = revision + portal.Metadata.(*PortalMetadata).Revision = revision return true, nil } diff --git a/pkg/connector/handlesignal.go b/pkg/connector/handlesignal.go index 0618957..500ec96 100644 --- a/pkg/connector/handlesignal.go +++ b/pkg/connector/handlesignal.go @@ -151,7 +151,7 @@ func (evt *Bv2ChatEvent) PreHandle(ctx context.Context, portal *bridgev2.Portal) if !ok || dataMsg.GroupV2 == nil { return } - portalRev, _ := database.GetNumberFromMap[uint32](portal.Metadata.Extra, "revision") + portalRev := portal.Metadata.(*PortalMetadata).Revision if evt.Info.GroupRevision > portalRev { toRevision := evt.Info.GroupRevision if dataMsg.GetGroupV2().GetGroupChange() != nil { @@ -289,10 +289,11 @@ func (evt *Bv2ChatEvent) ConvertMessage(ctx context.Context, portal *bridgev2.Po convertedParts := make([]*bridgev2.ConvertedMessagePart, len(converted.Parts)) for i, part := range converted.Parts { convertedParts[i] = &bridgev2.ConvertedMessagePart{ - ID: makeMessagePartID(i), - Type: part.Type, - Content: part.Content, - Extra: part.Extra, + ID: makeMessagePartID(i), + Type: part.Type, + Content: part.Content, + Extra: part.Extra, + DBMetadata: &MessageMetadata{ContainsAttachments: len(dataMsg.GetAttachments()) > 0}, } } var disappear database.DisappearingSetting @@ -338,7 +339,7 @@ func (evt *Bv2ChatEvent) ConvertEdit(ctx context.Context, portal *bridgev2.Porta Content: lastPart.Content, Extra: lastPart.Extra, }) - convertedEdit.ModifiedParts[0].Part.Metadata.EditCount++ + convertedEdit.ModifiedParts[0].Part.EditCount++ return convertedEdit, nil } diff --git a/pkg/connector/login.go b/pkg/connector/login.go index 3a58312..82ddac5 100644 --- a/pkg/connector/login.go +++ b/pkg/connector/login.go @@ -157,14 +157,10 @@ func (qr *QRLogin) processingWait(ctx context.Context) (*bridgev2.LoginStep, err } ul, err := qr.User.NewLogin(ctx, &database.UserLogin{ - ID: newLoginID, - Metadata: database.UserLoginMetadata{ - StandardUserLoginMetadata: database.StandardUserLoginMetadata{ - RemoteName: qr.ProvData.Number, - }, - Extra: map[string]any{ - "phone": qr.ProvData.Number, - }, + ID: newLoginID, + RemoteName: qr.ProvData.Number, + Metadata: &UserLoginMetadata{ + Phone: qr.ProvData.Number, }, }, &bridgev2.NewLoginParams{ DeleteOnConflict: true, diff --git a/pkg/connector/msgconvproxy.go b/pkg/connector/msgconvproxy.go index c8d97a4..87ebbb9 100644 --- a/pkg/connector/msgconvproxy.go +++ b/pkg/connector/msgconvproxy.go @@ -72,7 +72,7 @@ func (mpm *msgconvPortalMethods) GetSignalReply(ctx context.Context, content *ev AuthorAci: proto.String(string(mcCtx.ReplyTo.SenderID)), Type: signalpb.DataMessage_Quote_NORMAL.Enum(), } - if mcCtx.ReplyTo.Metadata.Extra["contains_attachments"] != false { + if mcCtx.ReplyTo.Metadata.(*MessageMetadata).ContainsAttachments { quote.Attachments = make([]*signalpb.DataMessage_Quote_QuotedAttachment, 1) } return quote @@ -107,9 +107,9 @@ func (mpm *msgconvPortalMethods) GetData(ctx context.Context) *legacydb.Portal { NameSet: portal.NameSet, AvatarSet: portal.AvatarSet, TopicSet: portal.TopicSet, - //Revision: portal.Metadata["revision"].(uint32), + Revision: portal.Metadata.(*PortalMetadata).Revision, Encrypted: true, //RelayUserID: portal.Relay.UserMXID, - ExpirationTime: uint32(portal.Metadata.DisappearTimer.Seconds()), + ExpirationTime: uint32(portal.Disappear.Timer.Seconds()), } } From ca21d467de314fac2b644d52c0e7c21ece5b382f Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Sun, 14 Jul 2024 11:13:08 +0300 Subject: [PATCH 107/580] v2: update mautrix-go --- cmd/mautrix-signal-v2/legacyprovision.go | 2 +- cmd/mautrix-signal-v2/main.go | 2 +- database/upgrades/upgrades.go | 4 ++-- go.mod | 4 ++-- go.sum | 8 ++++---- pkg/connector/chatinfo.go | 2 +- pkg/signalmeow/store/upgrades/16-remove-extra-prekeys.go | 2 +- 7 files changed, 12 insertions(+), 12 deletions(-) diff --git a/cmd/mautrix-signal-v2/legacyprovision.go b/cmd/mautrix-signal-v2/legacyprovision.go index 48a9c5f..b3c3f80 100644 --- a/cmd/mautrix-signal-v2/legacyprovision.go +++ b/cmd/mautrix-signal-v2/legacyprovision.go @@ -237,7 +237,7 @@ func legacyResolveIdentifierOrStartChat(w http.ResponseWriter, r *http.Request, } if resp.Chat != nil { if resp.Chat.Portal == nil { - resp.Chat.Portal, err = m.Bridge.GetPortalByID(r.Context(), resp.Chat.PortalID) + resp.Chat.Portal, err = m.Bridge.GetPortalByKey(r.Context(), resp.Chat.PortalKey) if err != nil { zerolog.Ctx(r.Context()).Err(err).Msg("Failed to get portal") legacyprovision.JSONResponse(w, http.StatusInternalServerError, &mautrix.RespError{ diff --git a/cmd/mautrix-signal-v2/main.go b/cmd/mautrix-signal-v2/main.go index cc1f0bf..55ef75c 100644 --- a/cmd/mautrix-signal-v2/main.go +++ b/cmd/mautrix-signal-v2/main.go @@ -51,7 +51,7 @@ func main() { 20, "v0.5.1", "v0.7.0", - m.LegacyMigrateSimple(legacyMigrateRenameTables, legacyMigrateCopyData, 9), + m.LegacyMigrateSimple(legacyMigrateRenameTables, legacyMigrateCopyData, 11), true, ) } diff --git a/database/upgrades/upgrades.go b/database/upgrades/upgrades.go index 895be62..20f60f4 100644 --- a/database/upgrades/upgrades.go +++ b/database/upgrades/upgrades.go @@ -30,10 +30,10 @@ var Table dbutil.UpgradeTable var rawUpgrades embed.FS func init() { - Table.Register(-1, 12, 0, "Unsupported version", false, func(ctx context.Context, database *dbutil.Database) error { + Table.Register(-1, 12, 0, "Unsupported version", dbutil.TxnModeOff, func(ctx context.Context, database *dbutil.Database) error { return errors.New("please upgrade to mautrix-signal v0.4.3 before upgrading to a newer version") }) - Table.Register(1, 13, 0, "Jump to version 13", false, func(ctx context.Context, database *dbutil.Database) error { + Table.Register(1, 13, 0, "Jump to version 13", dbutil.TxnModeOff, func(ctx context.Context, database *dbutil.Database) error { return nil }) Table.RegisterFS(rawUpgrades) diff --git a/go.mod b/go.mod index 42b930a..a0cb89d 100644 --- a/go.mod +++ b/go.mod @@ -14,12 +14,12 @@ require ( github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e github.com/stretchr/testify v1.9.0 github.com/tidwall/gjson v1.17.1 - go.mau.fi/util v0.5.1-0.20240710154926-931b33d6d530 + go.mau.fi/util v0.5.1-0.20240714080209-e8e8154ce82a golang.org/x/crypto v0.25.0 golang.org/x/exp v0.0.0-20240707233637-46b078467d37 golang.org/x/net v0.27.0 google.golang.org/protobuf v1.34.2 - maunium.net/go/mautrix v0.19.0-beta.1.0.20240713090952-9fdf94132a3d + maunium.net/go/mautrix v0.19.0-beta.1.0.20240714080619-d1905f623215 nhooyr.io/websocket v1.8.11 ) diff --git a/go.sum b/go.sum index 2fc2c90..92dabd2 100644 --- a/go.sum +++ b/go.sum @@ -67,8 +67,8 @@ github.com/tidwall/sjson v1.2.5 h1:kLy8mja+1c9jlljvWTlSazM7cKDRfJuR/bOJhcY5NcY= github.com/tidwall/sjson v1.2.5/go.mod h1:Fvgq9kS/6ociJEDnK0Fk1cpYF4FIW6ZF7LAe+6jwd28= github.com/yuin/goldmark v1.7.4 h1:BDXOHExt+A7gwPCJgPIIq7ENvceR7we7rOS9TNoLZeg= github.com/yuin/goldmark v1.7.4/go.mod h1:uzxRWxtg69N339t3louHJ7+O03ezfj6PlliRlaOzY1E= -go.mau.fi/util v0.5.1-0.20240710154926-931b33d6d530 h1:ZWMrLC+Fn2AmKL8HM04YY0zyMDMOagQZVukpxp0rmic= -go.mau.fi/util v0.5.1-0.20240710154926-931b33d6d530/go.mod h1:DsJzUrJAG53lCZnnYvq9/mOyLuPScWwYhvETiTrpdP4= +go.mau.fi/util v0.5.1-0.20240714080209-e8e8154ce82a h1:m9QJacb5JfXDCdYoi/DvG4/FaHGketCSGzqys3Wyr10= +go.mau.fi/util v0.5.1-0.20240714080209-e8e8154ce82a/go.mod h1:DsJzUrJAG53lCZnnYvq9/mOyLuPScWwYhvETiTrpdP4= go.mau.fi/zeroconfig v0.1.2 h1:DKOydWnhPMn65GbXZOafgkPm11BvFashZWLct0dGFto= go.mau.fi/zeroconfig v0.1.2/go.mod h1:NcSJkf180JT+1IId76PcMuLTNa1CzsFFZ0nBygIQM70= golang.org/x/crypto v0.25.0 h1:ypSNr+bnYL2YhwoMt2zPxHFmbAN1KZs/njMG3hxUp30= @@ -93,7 +93,7 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= maunium.net/go/mauflag v1.0.0 h1:YiaRc0tEI3toYtJMRIfjP+jklH45uDHtT80nUamyD4M= maunium.net/go/mauflag v1.0.0/go.mod h1:nLivPOpTpHnpzEh8jEdSL9UqO9+/KBJFmNRlwKfkPeA= -maunium.net/go/mautrix v0.19.0-beta.1.0.20240713090952-9fdf94132a3d h1:Fxpvg1sOmkKKsYqbTLEIf6La9+qeBFKmnwkZfcxa8eM= -maunium.net/go/mautrix v0.19.0-beta.1.0.20240713090952-9fdf94132a3d/go.mod h1:bNQrvIftiwJ+7OjSh+Gza5xcncq1ooHk6oyDWq4B4sg= +maunium.net/go/mautrix v0.19.0-beta.1.0.20240714080619-d1905f623215 h1:cy3Ge8DMOQj+a6G8QhWEcg8FWsx2wEwTgSATHzg3wIE= +maunium.net/go/mautrix v0.19.0-beta.1.0.20240714080619-d1905f623215/go.mod h1:ldNVOQXaljMk4YLzlohp+DniMQtCSzTVcwjEFBlYQLM= nhooyr.io/websocket v1.8.11 h1:f/qXNc2/3DpoSZkHt1DQu6rj4zGC8JmkkLkWss0MgN0= nhooyr.io/websocket v1.8.11/go.mod h1:rN9OFWIUwuxg4fR5tELlYC04bXYowCP9GX47ivo2l+c= diff --git a/pkg/connector/chatinfo.go b/pkg/connector/chatinfo.go index 36daecb..984a4ef 100644 --- a/pkg/connector/chatinfo.go +++ b/pkg/connector/chatinfo.go @@ -234,7 +234,7 @@ func (s *SignalClient) makeCreateDMResponse(recipient *types.Recipient) *bridgev serviceID = libsignalgo.NewACIServiceID(recipient.ACI) } return &bridgev2.CreateChatResponse{ - PortalID: s.makeDMPortalKey(serviceID), + PortalKey: s.makeDMPortalKey(serviceID), PortalInfo: &bridgev2.ChatInfo{ Name: &name, Avatar: avatar, diff --git a/pkg/signalmeow/store/upgrades/16-remove-extra-prekeys.go b/pkg/signalmeow/store/upgrades/16-remove-extra-prekeys.go index 9a5b011..5046abf 100644 --- a/pkg/signalmeow/store/upgrades/16-remove-extra-prekeys.go +++ b/pkg/signalmeow/store/upgrades/16-remove-extra-prekeys.go @@ -59,7 +59,7 @@ func deleteExtraPrekeys(ctx context.Context, db *dbutil.Database, selectQuery, d } func init() { - Table.Register(-1, 16, 13, "Remove extra prekeys", true, func(ctx context.Context, db *dbutil.Database) error { + Table.Register(-1, 16, 13, "Remove extra prekeys", dbutil.TxnModeOn, func(ctx context.Context, db *dbutil.Database) error { err := deleteExtraPrekeys(ctx, db, ` SELECT account_id, service_id, COUNT(*), MAX(key_id) FROM signalmeow_pre_keys WHERE is_signed=false GROUP BY 1, 2 `, ` From 41a7187dff34f8568ff5af26852c67d62010c193 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Sun, 14 Jul 2024 14:47:58 +0300 Subject: [PATCH 108/580] v2: update mautrix-go --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index a0cb89d..be6c9f1 100644 --- a/go.mod +++ b/go.mod @@ -19,7 +19,7 @@ require ( golang.org/x/exp v0.0.0-20240707233637-46b078467d37 golang.org/x/net v0.27.0 google.golang.org/protobuf v1.34.2 - maunium.net/go/mautrix v0.19.0-beta.1.0.20240714080619-d1905f623215 + maunium.net/go/mautrix v0.19.0-beta.1.0.20240714114557-edf1a8d8d022 nhooyr.io/websocket v1.8.11 ) diff --git a/go.sum b/go.sum index 92dabd2..0fdbe27 100644 --- a/go.sum +++ b/go.sum @@ -93,7 +93,7 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= maunium.net/go/mauflag v1.0.0 h1:YiaRc0tEI3toYtJMRIfjP+jklH45uDHtT80nUamyD4M= maunium.net/go/mauflag v1.0.0/go.mod h1:nLivPOpTpHnpzEh8jEdSL9UqO9+/KBJFmNRlwKfkPeA= -maunium.net/go/mautrix v0.19.0-beta.1.0.20240714080619-d1905f623215 h1:cy3Ge8DMOQj+a6G8QhWEcg8FWsx2wEwTgSATHzg3wIE= -maunium.net/go/mautrix v0.19.0-beta.1.0.20240714080619-d1905f623215/go.mod h1:ldNVOQXaljMk4YLzlohp+DniMQtCSzTVcwjEFBlYQLM= +maunium.net/go/mautrix v0.19.0-beta.1.0.20240714114557-edf1a8d8d022 h1:YOc5Ulfjd4Iw9unao18rXcy/nhrHMWZwutBT3bcc/3I= +maunium.net/go/mautrix v0.19.0-beta.1.0.20240714114557-edf1a8d8d022/go.mod h1:ldNVOQXaljMk4YLzlohp+DniMQtCSzTVcwjEFBlYQLM= nhooyr.io/websocket v1.8.11 h1:f/qXNc2/3DpoSZkHt1DQu6rj4zGC8JmkkLkWss0MgN0= nhooyr.io/websocket v1.8.11/go.mod h1:rN9OFWIUwuxg4fR5tELlYC04bXYowCP9GX47ivo2l+c= From e627ad878e4b7b69de7bf3216ec694f8159eb2af Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Sun, 14 Jul 2024 19:19:02 +0300 Subject: [PATCH 109/580] signalmeow/receiving: handle sync messages sent to PNIs properly * store destination E.164 numbers received in sync messages * fetch PNI identity from server if it isn't found in database when handling PNI signature message --- pkg/connector/chatinfo.go | 12 ++---------- pkg/libsignalgo/serviceid.go | 8 ++++++++ pkg/signalmeow/receiving.go | 20 +++++++++++++++++++- 3 files changed, 29 insertions(+), 11 deletions(-) diff --git a/pkg/connector/chatinfo.go b/pkg/connector/chatinfo.go index 984a4ef..a851260 100644 --- a/pkg/connector/chatinfo.go +++ b/pkg/connector/chatinfo.go @@ -50,7 +50,7 @@ func (s *SignalClient) GetUserInfo(ctx context.Context, ghost *bridgev2.Ghost) ( return s.contactToUserInfo(contact), nil } -func (s *SignalClient) GetChatInfo(ctx context.Context, portal *bridgev2.Portal) (*bridgev2.PortalInfo, error) { +func (s *SignalClient) GetChatInfo(ctx context.Context, portal *bridgev2.Portal) (*bridgev2.ChatInfo, error) { userID, groupID, err := parsePortalID(portal.ID) if err != nil { return nil, err @@ -58,7 +58,7 @@ func (s *SignalClient) GetChatInfo(ctx context.Context, portal *bridgev2.Portal) if groupID != "" { return s.getGroupInfo(ctx, groupID, 0) } else { - aci, pni := serviceIDToACIAndPNI(userID) + aci, pni := userID.ToACIAndPNI() contact, err := s.Client.Store.RecipientStore.LoadAndUpdateRecipient(ctx, aci, pni, nil) if err != nil { return nil, err @@ -251,11 +251,3 @@ func makeAvatarPathID(avatarPath string) networkid.AvatarID { } return networkid.AvatarID("path:" + avatarPath) } - -func serviceIDToACIAndPNI(serviceID libsignalgo.ServiceID) (aci, pni uuid.UUID) { - if serviceID.Type == libsignalgo.ServiceIDTypeACI { - return serviceID.UUID, uuid.Nil - } else { - return uuid.Nil, serviceID.UUID - } -} diff --git a/pkg/libsignalgo/serviceid.go b/pkg/libsignalgo/serviceid.go index cd08f4d..5308af1 100644 --- a/pkg/libsignalgo/serviceid.go +++ b/pkg/libsignalgo/serviceid.go @@ -81,6 +81,14 @@ func NewACIServiceID(uuid uuid.UUID) ServiceID { } } +func (s ServiceID) ToACIAndPNI() (aci, pni uuid.UUID) { + if s.Type == ServiceIDTypeACI { + return s.UUID, uuid.Nil + } else { + return uuid.Nil, s.UUID + } +} + func (s ServiceID) IsEmpty() bool { return s.UUID == uuid.Nil } diff --git a/pkg/signalmeow/receiving.go b/pkg/signalmeow/receiving.go index 96d066a..b28a992 100644 --- a/pkg/signalmeow/receiving.go +++ b/pkg/signalmeow/receiving.go @@ -734,6 +734,13 @@ func (cli *Client) handleDecryptedResult( log.Err(err).Msg("Sync message destination parse error") return err } + if syncSent.GetDestinationE164() != "" { + aci, pni := syncDestinationServiceID.ToACIAndPNI() + _, err = cli.Store.RecipientStore.UpdateRecipientE164(ctx, aci, pni, syncSent.GetDestinationE164()) + if err != nil { + log.Err(err).Msg("Failed to update recipient E164 after receiving sync message") + } + } } if destination == nil && syncSent.GetMessage().GetGroupV2() == nil && syncSent.GetEditMessage().GetDataMessage().GetGroupV2() == nil { log.Warn().Msg("sync message sent destination is nil") @@ -913,7 +920,18 @@ func (cli *Client) handlePNISignatureMessage(ctx context.Context, sender libsign if err != nil { return fmt.Errorf("failed to get identity for PNI %s: %w", pni, err) } else if pniIdentity == nil { - return fmt.Errorf("identity not found for PNI %s", pni) + zerolog.Ctx(ctx).Debug(). + Stringer("aci", sender.UUID). + Stringer("pni", pni). + Msg("Fetching PNI identity for signature verification as it wasn't found in store") + err = cli.FetchAndProcessPreKey(ctx, pniServiceID, 0) + if err != nil { + return fmt.Errorf("failed to fetch prekey for PNI %s after identity wasn't found in store: %w", pni, err) + } else if pniIdentity, err = cli.Store.IdentityKeyStore.GetIdentityKey(ctx, pniServiceID); err != nil { + return fmt.Errorf("failed to get identity for PNI %s after fetching: %w", pni, err) + } else if pniIdentity == nil { + return fmt.Errorf("identity not found for PNI %s even after fetching", pni) + } } aciIdentity, err := cli.Store.IdentityKeyStore.GetIdentityKey(ctx, sender) if err != nil { From b42164a6f5c30d2cd3394bb4fba5262b7d02d358 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Mon, 15 Jul 2024 15:40:31 +0300 Subject: [PATCH 110/580] dependencies: update --- go.mod | 6 +++--- go.sum | 12 ++++++------ 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/go.mod b/go.mod index be6c9f1..c3e796a 100644 --- a/go.mod +++ b/go.mod @@ -14,12 +14,12 @@ require ( github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e github.com/stretchr/testify v1.9.0 github.com/tidwall/gjson v1.17.1 - go.mau.fi/util v0.5.1-0.20240714080209-e8e8154ce82a + go.mau.fi/util v0.5.1-0.20240714204302-8d7c8742a899 golang.org/x/crypto v0.25.0 golang.org/x/exp v0.0.0-20240707233637-46b078467d37 golang.org/x/net v0.27.0 google.golang.org/protobuf v1.34.2 - maunium.net/go/mautrix v0.19.0-beta.1.0.20240714114557-edf1a8d8d022 + maunium.net/go/mautrix v0.19.0-beta.1.0.20240715123557-cb850e3f0293 nhooyr.io/websocket v1.8.11 ) @@ -41,7 +41,7 @@ require ( github.com/tidwall/pretty v1.2.0 // indirect github.com/tidwall/sjson v1.2.5 // indirect github.com/yuin/goldmark v1.7.4 // indirect - go.mau.fi/zeroconfig v0.1.2 // indirect + go.mau.fi/zeroconfig v0.1.3 // indirect golang.org/x/sys v0.22.0 // indirect gopkg.in/natefinch/lumberjack.v2 v2.2.1 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect diff --git a/go.sum b/go.sum index 0fdbe27..e8999e7 100644 --- a/go.sum +++ b/go.sum @@ -67,10 +67,10 @@ github.com/tidwall/sjson v1.2.5 h1:kLy8mja+1c9jlljvWTlSazM7cKDRfJuR/bOJhcY5NcY= github.com/tidwall/sjson v1.2.5/go.mod h1:Fvgq9kS/6ociJEDnK0Fk1cpYF4FIW6ZF7LAe+6jwd28= github.com/yuin/goldmark v1.7.4 h1:BDXOHExt+A7gwPCJgPIIq7ENvceR7we7rOS9TNoLZeg= github.com/yuin/goldmark v1.7.4/go.mod h1:uzxRWxtg69N339t3louHJ7+O03ezfj6PlliRlaOzY1E= -go.mau.fi/util v0.5.1-0.20240714080209-e8e8154ce82a h1:m9QJacb5JfXDCdYoi/DvG4/FaHGketCSGzqys3Wyr10= -go.mau.fi/util v0.5.1-0.20240714080209-e8e8154ce82a/go.mod h1:DsJzUrJAG53lCZnnYvq9/mOyLuPScWwYhvETiTrpdP4= -go.mau.fi/zeroconfig v0.1.2 h1:DKOydWnhPMn65GbXZOafgkPm11BvFashZWLct0dGFto= -go.mau.fi/zeroconfig v0.1.2/go.mod h1:NcSJkf180JT+1IId76PcMuLTNa1CzsFFZ0nBygIQM70= +go.mau.fi/util v0.5.1-0.20240714204302-8d7c8742a899 h1:6/4XgDIvH2/4+aQ1WADo7UOmQCiHjx7wd0jjezew7JE= +go.mau.fi/util v0.5.1-0.20240714204302-8d7c8742a899/go.mod h1:DsJzUrJAG53lCZnnYvq9/mOyLuPScWwYhvETiTrpdP4= +go.mau.fi/zeroconfig v0.1.3 h1:As9wYDKmktjmNZW5i1vn8zvJlmGKHeVxHVIBMXsm4kM= +go.mau.fi/zeroconfig v0.1.3/go.mod h1:NcSJkf180JT+1IId76PcMuLTNa1CzsFFZ0nBygIQM70= golang.org/x/crypto v0.25.0 h1:ypSNr+bnYL2YhwoMt2zPxHFmbAN1KZs/njMG3hxUp30= golang.org/x/crypto v0.25.0/go.mod h1:T+wALwcMOSE0kXgUAnPAHqTLW+XHgcELELW8VaDgm/M= golang.org/x/exp v0.0.0-20240707233637-46b078467d37 h1:uLDX+AfeFCct3a2C7uIWBKMJIR3CJMhcgfrUAqjRK6w= @@ -93,7 +93,7 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= maunium.net/go/mauflag v1.0.0 h1:YiaRc0tEI3toYtJMRIfjP+jklH45uDHtT80nUamyD4M= maunium.net/go/mauflag v1.0.0/go.mod h1:nLivPOpTpHnpzEh8jEdSL9UqO9+/KBJFmNRlwKfkPeA= -maunium.net/go/mautrix v0.19.0-beta.1.0.20240714114557-edf1a8d8d022 h1:YOc5Ulfjd4Iw9unao18rXcy/nhrHMWZwutBT3bcc/3I= -maunium.net/go/mautrix v0.19.0-beta.1.0.20240714114557-edf1a8d8d022/go.mod h1:ldNVOQXaljMk4YLzlohp+DniMQtCSzTVcwjEFBlYQLM= +maunium.net/go/mautrix v0.19.0-beta.1.0.20240715123557-cb850e3f0293 h1:/9nLAfETGuy4juesa+XYfM0fl2v2DgSVrYjlcG9CB2o= +maunium.net/go/mautrix v0.19.0-beta.1.0.20240715123557-cb850e3f0293/go.mod h1:ji+Od74MtqQk7KYWKmfZ8L6/z+DKNnZafFYvEJHkDEk= nhooyr.io/websocket v1.8.11 h1:f/qXNc2/3DpoSZkHt1DQu6rj4zGC8JmkkLkWss0MgN0= nhooyr.io/websocket v1.8.11/go.mod h1:rN9OFWIUwuxg4fR5tELlYC04bXYowCP9GX47ivo2l+c= From d94864d1f9dcba2b00c32fdf72299eba364c4450 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Tue, 16 Jul 2024 11:50:19 +0300 Subject: [PATCH 111/580] Bump version to v0.6.3 --- CHANGELOG.md | 13 +++++++++++++ go.mod | 4 ++-- go.sum | 8 ++++---- main.go | 2 +- 4 files changed, 20 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f31a4c2..f00f374 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,16 @@ +# v0.6.3 (2024-07-16) + +* Updated to libsignal v0.52.0. +* Fixed bridge losing track of user phone numbers in some cases. +* Fixed edge cases in handling new outgoing DMs started from other devices. +* Added `sync groups` command (thanks to [@maltee1] in [#490]). +* Fixed typo in location bridging example config + (thanks to [@AndrewFerr] in [#516]). + +[#490]: https://github.com/mautrix/signal/pull/490 +[#516]: https://github.com/mautrix/signal/pull/516 +[@AndrewFerr]: https://github.com/mautrix/signal/pull/516 + # v0.6.2 (2024-06-16) * Updated to libsignal v0.51.0. diff --git a/go.mod b/go.mod index c3e796a..147ab5c 100644 --- a/go.mod +++ b/go.mod @@ -14,12 +14,12 @@ require ( github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e github.com/stretchr/testify v1.9.0 github.com/tidwall/gjson v1.17.1 - go.mau.fi/util v0.5.1-0.20240714204302-8d7c8742a899 + go.mau.fi/util v0.6.0 golang.org/x/crypto v0.25.0 golang.org/x/exp v0.0.0-20240707233637-46b078467d37 golang.org/x/net v0.27.0 google.golang.org/protobuf v1.34.2 - maunium.net/go/mautrix v0.19.0-beta.1.0.20240715123557-cb850e3f0293 + maunium.net/go/mautrix v0.19.0 nhooyr.io/websocket v1.8.11 ) diff --git a/go.sum b/go.sum index e8999e7..00314ae 100644 --- a/go.sum +++ b/go.sum @@ -67,8 +67,8 @@ github.com/tidwall/sjson v1.2.5 h1:kLy8mja+1c9jlljvWTlSazM7cKDRfJuR/bOJhcY5NcY= github.com/tidwall/sjson v1.2.5/go.mod h1:Fvgq9kS/6ociJEDnK0Fk1cpYF4FIW6ZF7LAe+6jwd28= github.com/yuin/goldmark v1.7.4 h1:BDXOHExt+A7gwPCJgPIIq7ENvceR7we7rOS9TNoLZeg= github.com/yuin/goldmark v1.7.4/go.mod h1:uzxRWxtg69N339t3louHJ7+O03ezfj6PlliRlaOzY1E= -go.mau.fi/util v0.5.1-0.20240714204302-8d7c8742a899 h1:6/4XgDIvH2/4+aQ1WADo7UOmQCiHjx7wd0jjezew7JE= -go.mau.fi/util v0.5.1-0.20240714204302-8d7c8742a899/go.mod h1:DsJzUrJAG53lCZnnYvq9/mOyLuPScWwYhvETiTrpdP4= +go.mau.fi/util v0.6.0 h1:W6SyB3Bm/GjenQ5iq8Z8WWdN85Gy2xS6L0wmnR7SVjg= +go.mau.fi/util v0.6.0/go.mod h1:ljYdq3sPfpICc3zMU+/mHV/sa4z0nKxc67hSBwnrk8U= go.mau.fi/zeroconfig v0.1.3 h1:As9wYDKmktjmNZW5i1vn8zvJlmGKHeVxHVIBMXsm4kM= go.mau.fi/zeroconfig v0.1.3/go.mod h1:NcSJkf180JT+1IId76PcMuLTNa1CzsFFZ0nBygIQM70= golang.org/x/crypto v0.25.0 h1:ypSNr+bnYL2YhwoMt2zPxHFmbAN1KZs/njMG3hxUp30= @@ -93,7 +93,7 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= maunium.net/go/mauflag v1.0.0 h1:YiaRc0tEI3toYtJMRIfjP+jklH45uDHtT80nUamyD4M= maunium.net/go/mauflag v1.0.0/go.mod h1:nLivPOpTpHnpzEh8jEdSL9UqO9+/KBJFmNRlwKfkPeA= -maunium.net/go/mautrix v0.19.0-beta.1.0.20240715123557-cb850e3f0293 h1:/9nLAfETGuy4juesa+XYfM0fl2v2DgSVrYjlcG9CB2o= -maunium.net/go/mautrix v0.19.0-beta.1.0.20240715123557-cb850e3f0293/go.mod h1:ji+Od74MtqQk7KYWKmfZ8L6/z+DKNnZafFYvEJHkDEk= +maunium.net/go/mautrix v0.19.0 h1:67eSJWam93mw44Q0/1SiOG7zQzXMUknUv5UaWkrODDU= +maunium.net/go/mautrix v0.19.0/go.mod h1:UE+mSQ4sDUuJMbjN0aB9EjQSGgXd48AzMvZ6+QJV1k8= nhooyr.io/websocket v1.8.11 h1:f/qXNc2/3DpoSZkHt1DQu6rj4zGC8JmkkLkWss0MgN0= nhooyr.io/websocket v1.8.11/go.mod h1:rN9OFWIUwuxg4fR5tELlYC04bXYowCP9GX47ivo2l+c= diff --git a/main.go b/main.go index 16dbd05..eb24aa0 100644 --- a/main.go +++ b/main.go @@ -331,7 +331,7 @@ func main() { Name: "mautrix-signal", URL: "https://github.com/mautrix/signal", Description: "A Matrix-Signal puppeting bridge.", - Version: "0.6.2", + Version: "0.6.3", ProtocolName: "Signal", BeeperServiceName: "signal", BeeperNetworkName: "signal", From ef4d776730001e87c6ac281d79c05d5c0cb7831f Mon Sep 17 00:00:00 2001 From: Sumner Evans Date: Tue, 16 Jul 2024 19:16:23 -0600 Subject: [PATCH 112/580] flake: remove Signed-off-by: Sumner Evans --- .envrc | 8 ------- flake.lock | 61 ------------------------------------------------------ flake.nix | 33 ----------------------------- 3 files changed, 102 deletions(-) delete mode 100644 .envrc delete mode 100644 flake.lock delete mode 100644 flake.nix diff --git a/.envrc b/.envrc deleted file mode 100644 index 4520fd1..0000000 --- a/.envrc +++ /dev/null @@ -1,8 +0,0 @@ -if [[ $(uname -s) == "Linux" && $(uname --kernel-version | grep "NixOS") ]]; then - echo "The best OS (NixOS) has been detected. Using nice tools." - if ! has nix_direnv_version || ! nix_direnv_version 3.0.0; then - source_url "https://raw.githubusercontent.com/nix-community/nix-direnv/3.0.0/direnvrc" "sha256-21TMnI2xWX7HkSTjFFri2UaohXVj854mgvWapWrxRXg=" - fi - - use flake -fi diff --git a/flake.lock b/flake.lock deleted file mode 100644 index 80c5341..0000000 --- a/flake.lock +++ /dev/null @@ -1,61 +0,0 @@ -{ - "nodes": { - "flake-utils": { - "inputs": { - "systems": "systems" - }, - "locked": { - "lastModified": 1701680307, - "narHash": "sha256-kAuep2h5ajznlPMD9rnQyffWG8EM/C73lejGofXvdM8=", - "owner": "numtide", - "repo": "flake-utils", - "rev": "4022d587cbbfd70fe950c1e2083a02621806a725", - "type": "github" - }, - "original": { - "owner": "numtide", - "repo": "flake-utils", - "type": "github" - } - }, - "nixpkgs": { - "locked": { - "lastModified": 1703255338, - "narHash": "sha256-Z6wfYJQKmDN9xciTwU3cOiOk+NElxdZwy/FiHctCzjU=", - "owner": "NixOS", - "repo": "nixpkgs", - "rev": "6df37dc6a77654682fe9f071c62b4242b5342e04", - "type": "github" - }, - "original": { - "owner": "NixOS", - "ref": "nixos-unstable", - "repo": "nixpkgs", - "type": "github" - } - }, - "root": { - "inputs": { - "flake-utils": "flake-utils", - "nixpkgs": "nixpkgs" - } - }, - "systems": { - "locked": { - "lastModified": 1681028828, - "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", - "owner": "nix-systems", - "repo": "default", - "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", - "type": "github" - }, - "original": { - "owner": "nix-systems", - "repo": "default", - "type": "github" - } - } - }, - "root": "root", - "version": 7 -} diff --git a/flake.nix b/flake.nix deleted file mode 100644 index cbb2b61..0000000 --- a/flake.nix +++ /dev/null @@ -1,33 +0,0 @@ -{ - description = "mautrix-signal development environment"; - - inputs = { - nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable"; - flake-utils.url = "github:numtide/flake-utils"; - }; - - outputs = { self, nixpkgs, flake-utils }: - (flake-utils.lib.eachDefaultSystem (system: - let pkgs = import nixpkgs { inherit system; }; - in { - devShells.default = pkgs.mkShell { - LIBCLANG_PATH = "${pkgs.llvmPackages_11.libclang.lib}/lib"; - - buildInputs = with pkgs; [ - clang - cmake - gnumake - protobuf - rust-cbindgen - rustup - olm - - go_1_20 - go-tools - gotools - - pre-commit - ]; - }; - })); -} From fd3ef2ebc3b417097a0bfe82418e96ee4d18a806 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Wed, 17 Jul 2024 11:58:30 +0300 Subject: [PATCH 113/580] v2: fix edit time limits --- go.mod | 2 +- go.sum | 4 ++-- pkg/connector/client.go | 11 +++++++++++ 3 files changed, 14 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 147ab5c..1288396 100644 --- a/go.mod +++ b/go.mod @@ -19,7 +19,7 @@ require ( golang.org/x/exp v0.0.0-20240707233637-46b078467d37 golang.org/x/net v0.27.0 google.golang.org/protobuf v1.34.2 - maunium.net/go/mautrix v0.19.0 + maunium.net/go/mautrix v0.19.1-0.20240717085751-0d81a91c9feb nhooyr.io/websocket v1.8.11 ) diff --git a/go.sum b/go.sum index 00314ae..174319f 100644 --- a/go.sum +++ b/go.sum @@ -93,7 +93,7 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= maunium.net/go/mauflag v1.0.0 h1:YiaRc0tEI3toYtJMRIfjP+jklH45uDHtT80nUamyD4M= maunium.net/go/mauflag v1.0.0/go.mod h1:nLivPOpTpHnpzEh8jEdSL9UqO9+/KBJFmNRlwKfkPeA= -maunium.net/go/mautrix v0.19.0 h1:67eSJWam93mw44Q0/1SiOG7zQzXMUknUv5UaWkrODDU= -maunium.net/go/mautrix v0.19.0/go.mod h1:UE+mSQ4sDUuJMbjN0aB9EjQSGgXd48AzMvZ6+QJV1k8= +maunium.net/go/mautrix v0.19.1-0.20240717085751-0d81a91c9feb h1:acwViarBwsMMnDRLMNylAfWj9wsrpmMI39O8o0bOXww= +maunium.net/go/mautrix v0.19.1-0.20240717085751-0d81a91c9feb/go.mod h1:UE+mSQ4sDUuJMbjN0aB9EjQSGgXd48AzMvZ6+QJV1k8= nhooyr.io/websocket v1.8.11 h1:f/qXNc2/3DpoSZkHt1DQu6rj4zGC8JmkkLkWss0MgN0= nhooyr.io/websocket v1.8.11/go.mod h1:rN9OFWIUwuxg4fR5tELlYC04bXYowCP9GX47ivo2l+c= diff --git a/pkg/connector/client.go b/pkg/connector/client.go index 0b92901..2293a33 100644 --- a/pkg/connector/client.go +++ b/pkg/connector/client.go @@ -6,6 +6,7 @@ import ( "time" "github.com/rs/zerolog" + "go.mau.fi/util/ptr" "maunium.net/go/mautrix/bridge/status" "maunium.net/go/mautrix/bridgev2" "maunium.net/go/mautrix/bridgev2/networkid" @@ -38,7 +39,17 @@ var signalCaps = &bridgev2.NetworkRoomCapabilities{ ReactionCount: 1, } +var signalCapsNoteToSelf *bridgev2.NetworkRoomCapabilities + +func init() { + signalCapsNoteToSelf = ptr.Clone(signalCaps) + signalCapsNoteToSelf.EditMaxAge = 0 +} + func (s *SignalClient) GetCapabilities(ctx context.Context, portal *bridgev2.Portal) *bridgev2.NetworkRoomCapabilities { + if portal.Receiver == s.UserLogin.ID && portal.ID == networkid.PortalID(s.UserLogin.ID) { + return signalCapsNoteToSelf + } return signalCaps } From ca460d8021434fb4df804ac48cc214bc810053cb Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Wed, 17 Jul 2024 12:18:42 +0300 Subject: [PATCH 114/580] v2: fill other user ID in DM portals --- cmd/mautrix-signal-v2/legacymigrate.sql | 3 ++- cmd/mautrix-signal-v2/main.go | 2 +- pkg/connector/chatinfo.go | 1 + 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/cmd/mautrix-signal-v2/legacymigrate.sql b/cmd/mautrix-signal-v2/legacymigrate.sql index 952dc4d..6ad95b0 100644 --- a/cmd/mautrix-signal-v2/legacymigrate.sql +++ b/cmd/mautrix-signal-v2/legacymigrate.sql @@ -19,7 +19,7 @@ SELECT FROM user_old WHERE uuid IS NOT NULL AND phone IS NOT NULL; INSERT INTO portal ( - bridge_id, id, receiver, mxid, parent_id, parent_receiver, relay_bridge_id, relay_login_id, + bridge_id, id, receiver, mxid, parent_id, parent_receiver, relay_bridge_id, relay_login_id, other_user_id, name, topic, avatar_id, avatar_hash, avatar_mxc, name_set, avatar_set, topic_set, in_space, room_type, disappear_type, disappear_timer, metadata @@ -36,6 +36,7 @@ SELECT '', -- parent_receiver CASE WHEN portal_old.relay_user_id<>'' THEN '' END, -- relay_bridge_id CASE WHEN portal_old.relay_user_id<>'' THEN portal_old.relay_user_id END, -- relay_login_id + CASE WHEN LENGTH(chat_id)=44 THEN NULL ELSE chat_id END, -- other_user_id name, topic, CASE diff --git a/cmd/mautrix-signal-v2/main.go b/cmd/mautrix-signal-v2/main.go index 55ef75c..8d7a1c2 100644 --- a/cmd/mautrix-signal-v2/main.go +++ b/cmd/mautrix-signal-v2/main.go @@ -51,7 +51,7 @@ func main() { 20, "v0.5.1", "v0.7.0", - m.LegacyMigrateSimple(legacyMigrateRenameTables, legacyMigrateCopyData, 11), + m.LegacyMigrateSimple(legacyMigrateRenameTables, legacyMigrateCopyData, 12), true, ) } diff --git a/pkg/connector/chatinfo.go b/pkg/connector/chatinfo.go index a851260..85758c7 100644 --- a/pkg/connector/chatinfo.go +++ b/pkg/connector/chatinfo.go @@ -215,6 +215,7 @@ func (s *SignalClient) makeCreateDMResponse(recipient *types.Recipient) *bridgev name = s.Main.Config.FormatDisplayname(recipient) serviceID = libsignalgo.NewPNIServiceID(recipient.PNI) } else { + members.OtherUserID = makeUserID(recipient.ACI) if recipient.ACI == s.Client.Store.ACI { name = NoteToSelfName avatar = &bridgev2.Avatar{ From dc109a254e8e69bed170efe6cfa17561e0ed90b0 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Fri, 19 Jul 2024 14:10:05 +0300 Subject: [PATCH 115/580] v2: update mautrix-go to get post-migration handling for rooms --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 1288396..faa4cee 100644 --- a/go.mod +++ b/go.mod @@ -19,7 +19,7 @@ require ( golang.org/x/exp v0.0.0-20240707233637-46b078467d37 golang.org/x/net v0.27.0 google.golang.org/protobuf v1.34.2 - maunium.net/go/mautrix v0.19.1-0.20240717085751-0d81a91c9feb + maunium.net/go/mautrix v0.19.1-0.20240719110719-b881a7d45511 nhooyr.io/websocket v1.8.11 ) diff --git a/go.sum b/go.sum index 174319f..235a78f 100644 --- a/go.sum +++ b/go.sum @@ -93,7 +93,7 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= maunium.net/go/mauflag v1.0.0 h1:YiaRc0tEI3toYtJMRIfjP+jklH45uDHtT80nUamyD4M= maunium.net/go/mauflag v1.0.0/go.mod h1:nLivPOpTpHnpzEh8jEdSL9UqO9+/KBJFmNRlwKfkPeA= -maunium.net/go/mautrix v0.19.1-0.20240717085751-0d81a91c9feb h1:acwViarBwsMMnDRLMNylAfWj9wsrpmMI39O8o0bOXww= -maunium.net/go/mautrix v0.19.1-0.20240717085751-0d81a91c9feb/go.mod h1:UE+mSQ4sDUuJMbjN0aB9EjQSGgXd48AzMvZ6+QJV1k8= +maunium.net/go/mautrix v0.19.1-0.20240719110719-b881a7d45511 h1:Qbpe6EdaZn4YzNsJTrowWv34afbc1c8OYij58e7Vl70= +maunium.net/go/mautrix v0.19.1-0.20240719110719-b881a7d45511/go.mod h1:UE+mSQ4sDUuJMbjN0aB9EjQSGgXd48AzMvZ6+QJV1k8= nhooyr.io/websocket v1.8.11 h1:f/qXNc2/3DpoSZkHt1DQu6rj4zGC8JmkkLkWss0MgN0= nhooyr.io/websocket v1.8.11/go.mod h1:rN9OFWIUwuxg4fR5tELlYC04bXYowCP9GX47ivo2l+c= From 1f3558032237c9987705a9733cc89ddb35925920 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Fri, 19 Jul 2024 21:21:39 +0300 Subject: [PATCH 116/580] v2/legacymigrate: add name_is_custom field --- cmd/mautrix-signal-v2/legacymigrate.sql | 3 ++- cmd/mautrix-signal-v2/main.go | 2 +- go.mod | 4 ++-- go.sum | 8 ++++---- 4 files changed, 9 insertions(+), 8 deletions(-) diff --git a/cmd/mautrix-signal-v2/legacymigrate.sql b/cmd/mautrix-signal-v2/legacymigrate.sql index 6ad95b0..9266e9d 100644 --- a/cmd/mautrix-signal-v2/legacymigrate.sql +++ b/cmd/mautrix-signal-v2/legacymigrate.sql @@ -21,7 +21,7 @@ FROM user_old WHERE uuid IS NOT NULL AND phone IS NOT NULL; INSERT INTO portal ( bridge_id, id, receiver, mxid, parent_id, parent_receiver, relay_bridge_id, relay_login_id, other_user_id, name, topic, avatar_id, avatar_hash, avatar_mxc, - name_set, avatar_set, topic_set, in_space, + name_set, avatar_set, topic_set, name_is_custom, in_space, room_type, disappear_type, disappear_timer, metadata ) SELECT @@ -50,6 +50,7 @@ SELECT name_set, avatar_set, topic_set, + CASE WHEN LENGTH(chat_id)=44 THEN true ELSE false END, -- name_is_custom false, -- in_space CASE WHEN LENGTH(chat_id)=44 THEN '' ELSE 'dm' END, -- room_type CASE WHEN expiration_time<>0 THEN 'after_read' END, diff --git a/cmd/mautrix-signal-v2/main.go b/cmd/mautrix-signal-v2/main.go index 8d7a1c2..5fe7117 100644 --- a/cmd/mautrix-signal-v2/main.go +++ b/cmd/mautrix-signal-v2/main.go @@ -51,7 +51,7 @@ func main() { 20, "v0.5.1", "v0.7.0", - m.LegacyMigrateSimple(legacyMigrateRenameTables, legacyMigrateCopyData, 12), + m.LegacyMigrateSimple(legacyMigrateRenameTables, legacyMigrateCopyData, 14), true, ) } diff --git a/go.mod b/go.mod index faa4cee..7ab4c53 100644 --- a/go.mod +++ b/go.mod @@ -14,12 +14,12 @@ require ( github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e github.com/stretchr/testify v1.9.0 github.com/tidwall/gjson v1.17.1 - go.mau.fi/util v0.6.0 + go.mau.fi/util v0.6.1-0.20240719175439-20a6073e1dd4 golang.org/x/crypto v0.25.0 golang.org/x/exp v0.0.0-20240707233637-46b078467d37 golang.org/x/net v0.27.0 google.golang.org/protobuf v1.34.2 - maunium.net/go/mautrix v0.19.1-0.20240719110719-b881a7d45511 + maunium.net/go/mautrix v0.19.1-0.20240719181800-ea591b0a2e23 nhooyr.io/websocket v1.8.11 ) diff --git a/go.sum b/go.sum index 235a78f..3c2192b 100644 --- a/go.sum +++ b/go.sum @@ -67,8 +67,8 @@ github.com/tidwall/sjson v1.2.5 h1:kLy8mja+1c9jlljvWTlSazM7cKDRfJuR/bOJhcY5NcY= github.com/tidwall/sjson v1.2.5/go.mod h1:Fvgq9kS/6ociJEDnK0Fk1cpYF4FIW6ZF7LAe+6jwd28= github.com/yuin/goldmark v1.7.4 h1:BDXOHExt+A7gwPCJgPIIq7ENvceR7we7rOS9TNoLZeg= github.com/yuin/goldmark v1.7.4/go.mod h1:uzxRWxtg69N339t3louHJ7+O03ezfj6PlliRlaOzY1E= -go.mau.fi/util v0.6.0 h1:W6SyB3Bm/GjenQ5iq8Z8WWdN85Gy2xS6L0wmnR7SVjg= -go.mau.fi/util v0.6.0/go.mod h1:ljYdq3sPfpICc3zMU+/mHV/sa4z0nKxc67hSBwnrk8U= +go.mau.fi/util v0.6.1-0.20240719175439-20a6073e1dd4 h1:CYKYs5jwJ0bFJqh6pRoWtC9NIJ0lz0/6i2SC4qEBFaU= +go.mau.fi/util v0.6.1-0.20240719175439-20a6073e1dd4/go.mod h1:ljYdq3sPfpICc3zMU+/mHV/sa4z0nKxc67hSBwnrk8U= go.mau.fi/zeroconfig v0.1.3 h1:As9wYDKmktjmNZW5i1vn8zvJlmGKHeVxHVIBMXsm4kM= go.mau.fi/zeroconfig v0.1.3/go.mod h1:NcSJkf180JT+1IId76PcMuLTNa1CzsFFZ0nBygIQM70= golang.org/x/crypto v0.25.0 h1:ypSNr+bnYL2YhwoMt2zPxHFmbAN1KZs/njMG3hxUp30= @@ -93,7 +93,7 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= maunium.net/go/mauflag v1.0.0 h1:YiaRc0tEI3toYtJMRIfjP+jklH45uDHtT80nUamyD4M= maunium.net/go/mauflag v1.0.0/go.mod h1:nLivPOpTpHnpzEh8jEdSL9UqO9+/KBJFmNRlwKfkPeA= -maunium.net/go/mautrix v0.19.1-0.20240719110719-b881a7d45511 h1:Qbpe6EdaZn4YzNsJTrowWv34afbc1c8OYij58e7Vl70= -maunium.net/go/mautrix v0.19.1-0.20240719110719-b881a7d45511/go.mod h1:UE+mSQ4sDUuJMbjN0aB9EjQSGgXd48AzMvZ6+QJV1k8= +maunium.net/go/mautrix v0.19.1-0.20240719181800-ea591b0a2e23 h1:F3LI6273WRwlpgkjY/5646XAm0xTnCtyZ5BgIqcfVIg= +maunium.net/go/mautrix v0.19.1-0.20240719181800-ea591b0a2e23/go.mod h1:xP3DCXdPBUe1sPiugLbd5mRh/mJQWfGWyED1S8s9V7c= nhooyr.io/websocket v1.8.11 h1:f/qXNc2/3DpoSZkHt1DQu6rj4zGC8JmkkLkWss0MgN0= nhooyr.io/websocket v1.8.11/go.mod h1:rN9OFWIUwuxg4fR5tELlYC04bXYowCP9GX47ivo2l+c= From 1978a73888e014d72c99c94337919d60ed2054c0 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Mon, 22 Jul 2024 21:02:54 +0300 Subject: [PATCH 117/580] docker: fix typo in docker-run.sh --- docker-run.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docker-run.sh b/docker-run.sh index bcc6bc4..fdb22b2 100755 --- a/docker-run.sh +++ b/docker-run.sh @@ -18,7 +18,7 @@ function fixperms { if [[ ! -f /data/config.yaml ]]; then if [[ "$BRIDGEV2" == "1" ]]; then - $BINARY_NAME -c /data/config -e + $BINARY_NAME -c /data/config.yaml -e else cp /opt/mautrix-signal/example-config.yaml /data/config.yaml fi From 5027cb591b2c1c673d0c29fbfb52a525f25aca54 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Mon, 22 Jul 2024 21:03:02 +0300 Subject: [PATCH 118/580] v2: update mautrix-go --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 7ab4c53..a6350d2 100644 --- a/go.mod +++ b/go.mod @@ -19,7 +19,7 @@ require ( golang.org/x/exp v0.0.0-20240707233637-46b078467d37 golang.org/x/net v0.27.0 google.golang.org/protobuf v1.34.2 - maunium.net/go/mautrix v0.19.1-0.20240719181800-ea591b0a2e23 + maunium.net/go/mautrix v0.19.1-0.20240722162239-edb026c8a35c nhooyr.io/websocket v1.8.11 ) diff --git a/go.sum b/go.sum index 3c2192b..aff2e47 100644 --- a/go.sum +++ b/go.sum @@ -93,7 +93,7 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= maunium.net/go/mauflag v1.0.0 h1:YiaRc0tEI3toYtJMRIfjP+jklH45uDHtT80nUamyD4M= maunium.net/go/mauflag v1.0.0/go.mod h1:nLivPOpTpHnpzEh8jEdSL9UqO9+/KBJFmNRlwKfkPeA= -maunium.net/go/mautrix v0.19.1-0.20240719181800-ea591b0a2e23 h1:F3LI6273WRwlpgkjY/5646XAm0xTnCtyZ5BgIqcfVIg= -maunium.net/go/mautrix v0.19.1-0.20240719181800-ea591b0a2e23/go.mod h1:xP3DCXdPBUe1sPiugLbd5mRh/mJQWfGWyED1S8s9V7c= +maunium.net/go/mautrix v0.19.1-0.20240722162239-edb026c8a35c h1:oSYl9jldWBocSwO3yUe0vXxzrV9DeOsa1adisM5nbfc= +maunium.net/go/mautrix v0.19.1-0.20240722162239-edb026c8a35c/go.mod h1:xP3DCXdPBUe1sPiugLbd5mRh/mJQWfGWyED1S8s9V7c= nhooyr.io/websocket v1.8.11 h1:f/qXNc2/3DpoSZkHt1DQu6rj4zGC8JmkkLkWss0MgN0= nhooyr.io/websocket v1.8.11/go.mod h1:rN9OFWIUwuxg4fR5tELlYC04bXYowCP9GX47ivo2l+c= From 5d2163056a8fb00556eff5580bad26e6dfdb1bd5 Mon Sep 17 00:00:00 2001 From: Scott Weber Date: Mon, 22 Jul 2024 19:14:13 -0400 Subject: [PATCH 119/580] Disable encryption for local bridges (#525) --- pkg/connector/msgconvproxy.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/pkg/connector/msgconvproxy.go b/pkg/connector/msgconvproxy.go index 87ebbb9..8dc2db8 100644 --- a/pkg/connector/msgconvproxy.go +++ b/pkg/connector/msgconvproxy.go @@ -18,6 +18,7 @@ package connector import ( "context" + "strings" "google.golang.org/protobuf/proto" "maunium.net/go/mautrix/bridgev2" @@ -108,7 +109,8 @@ func (mpm *msgconvPortalMethods) GetData(ctx context.Context) *legacydb.Portal { AvatarSet: portal.AvatarSet, TopicSet: portal.TopicSet, Revision: portal.Metadata.(*PortalMetadata).Revision, - Encrypted: true, + // Hack to prevent encryption while using the bridge as a "local bridge" + Encrypted: !strings.HasSuffix(portal.Bridge.Matrix.ServerName(), ".localhost"), //RelayUserID: portal.Relay.UserMXID, ExpirationTime: uint32(portal.Disappear.Timer.Seconds()), } From 478a3f14b9bf67cf920f4d9f26a3755729913ec2 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Mon, 29 Jul 2024 16:41:08 +0300 Subject: [PATCH 120/580] v2: fix message ID when handling incoming edits --- pkg/connector/handlesignal.go | 1 + 1 file changed, 1 insertion(+) diff --git a/pkg/connector/handlesignal.go b/pkg/connector/handlesignal.go index 500ec96..ba3f6ff 100644 --- a/pkg/connector/handlesignal.go +++ b/pkg/connector/handlesignal.go @@ -340,6 +340,7 @@ func (evt *Bv2ChatEvent) ConvertEdit(ctx context.Context, portal *bridgev2.Porta Extra: lastPart.Extra, }) convertedEdit.ModifiedParts[0].Part.EditCount++ + convertedEdit.ModifiedParts[0].Part.ID = makeMessageID(evt.Info.Sender, editMsg.GetDataMessage().GetTimestamp()) return convertedEdit, nil } From 570d0542b8f165aea360f8a26f315197ea6b15e7 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Tue, 30 Jul 2024 16:46:41 +0300 Subject: [PATCH 121/580] dependencies: update --- go.mod | 8 ++++---- go.sum | 16 ++++++++-------- pkg/connector/chatinfo.go | 4 ++-- pkg/connector/groupinfo.go | 6 +++--- 4 files changed, 17 insertions(+), 17 deletions(-) diff --git a/go.mod b/go.mod index a6350d2..a501f5f 100644 --- a/go.mod +++ b/go.mod @@ -13,13 +13,13 @@ require ( github.com/rs/zerolog v1.33.0 github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e github.com/stretchr/testify v1.9.0 - github.com/tidwall/gjson v1.17.1 - go.mau.fi/util v0.6.1-0.20240719175439-20a6073e1dd4 + github.com/tidwall/gjson v1.17.3 + go.mau.fi/util v0.6.1-0.20240722085753-2d7945696c9b golang.org/x/crypto v0.25.0 - golang.org/x/exp v0.0.0-20240707233637-46b078467d37 + golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 golang.org/x/net v0.27.0 google.golang.org/protobuf v1.34.2 - maunium.net/go/mautrix v0.19.1-0.20240722162239-edb026c8a35c + maunium.net/go/mautrix v0.19.1-0.20240730133608-779f61ac9c69 nhooyr.io/websocket v1.8.11 ) diff --git a/go.sum b/go.sum index aff2e47..374199d 100644 --- a/go.sum +++ b/go.sum @@ -57,8 +57,8 @@ github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e/go.mod h1:XV66xRDq github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/tidwall/gjson v1.14.2/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= -github.com/tidwall/gjson v1.17.1 h1:wlYEnwqAHgzmhNUFfw7Xalt2JzQvsMx2Se4PcoFCT/U= -github.com/tidwall/gjson v1.17.1/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= +github.com/tidwall/gjson v1.17.3 h1:bwWLZU7icoKRG+C+0PNwIKC6FCJO/Q3p2pZvuP0jN94= +github.com/tidwall/gjson v1.17.3/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA= github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM= github.com/tidwall/pretty v1.2.0 h1:RWIZEg2iJ8/g6fDDYzMpobmaoGh5OLl4AXtGUGPcqCs= @@ -67,14 +67,14 @@ github.com/tidwall/sjson v1.2.5 h1:kLy8mja+1c9jlljvWTlSazM7cKDRfJuR/bOJhcY5NcY= github.com/tidwall/sjson v1.2.5/go.mod h1:Fvgq9kS/6ociJEDnK0Fk1cpYF4FIW6ZF7LAe+6jwd28= github.com/yuin/goldmark v1.7.4 h1:BDXOHExt+A7gwPCJgPIIq7ENvceR7we7rOS9TNoLZeg= github.com/yuin/goldmark v1.7.4/go.mod h1:uzxRWxtg69N339t3louHJ7+O03ezfj6PlliRlaOzY1E= -go.mau.fi/util v0.6.1-0.20240719175439-20a6073e1dd4 h1:CYKYs5jwJ0bFJqh6pRoWtC9NIJ0lz0/6i2SC4qEBFaU= -go.mau.fi/util v0.6.1-0.20240719175439-20a6073e1dd4/go.mod h1:ljYdq3sPfpICc3zMU+/mHV/sa4z0nKxc67hSBwnrk8U= +go.mau.fi/util v0.6.1-0.20240722085753-2d7945696c9b h1:8s3uTMPZts03evXLqdTJ0WXB0YWZDNSovpd6oFfCFvY= +go.mau.fi/util v0.6.1-0.20240722085753-2d7945696c9b/go.mod h1:ljYdq3sPfpICc3zMU+/mHV/sa4z0nKxc67hSBwnrk8U= go.mau.fi/zeroconfig v0.1.3 h1:As9wYDKmktjmNZW5i1vn8zvJlmGKHeVxHVIBMXsm4kM= go.mau.fi/zeroconfig v0.1.3/go.mod h1:NcSJkf180JT+1IId76PcMuLTNa1CzsFFZ0nBygIQM70= golang.org/x/crypto v0.25.0 h1:ypSNr+bnYL2YhwoMt2zPxHFmbAN1KZs/njMG3hxUp30= golang.org/x/crypto v0.25.0/go.mod h1:T+wALwcMOSE0kXgUAnPAHqTLW+XHgcELELW8VaDgm/M= -golang.org/x/exp v0.0.0-20240707233637-46b078467d37 h1:uLDX+AfeFCct3a2C7uIWBKMJIR3CJMhcgfrUAqjRK6w= -golang.org/x/exp v0.0.0-20240707233637-46b078467d37/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY= +golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 h1:2dVuKD2vS7b0QIHQbpyTISPd0LeHDbnYEryqj5Q1ug8= +golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY= golang.org/x/net v0.27.0 h1:5K3Njcw06/l2y9vpGCSdcxWOYHOUk3dVNGDXN+FvAys= golang.org/x/net v0.27.0/go.mod h1:dDi0PyhWNoiUOrAS8uXv/vnScO4wnHQO4mj9fn/RytE= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -93,7 +93,7 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= maunium.net/go/mauflag v1.0.0 h1:YiaRc0tEI3toYtJMRIfjP+jklH45uDHtT80nUamyD4M= maunium.net/go/mauflag v1.0.0/go.mod h1:nLivPOpTpHnpzEh8jEdSL9UqO9+/KBJFmNRlwKfkPeA= -maunium.net/go/mautrix v0.19.1-0.20240722162239-edb026c8a35c h1:oSYl9jldWBocSwO3yUe0vXxzrV9DeOsa1adisM5nbfc= -maunium.net/go/mautrix v0.19.1-0.20240722162239-edb026c8a35c/go.mod h1:xP3DCXdPBUe1sPiugLbd5mRh/mJQWfGWyED1S8s9V7c= +maunium.net/go/mautrix v0.19.1-0.20240730133608-779f61ac9c69 h1:bKO9y6moTiKWBYry5KwhiGmdyZR1xfIX4ujAWt7KuUU= +maunium.net/go/mautrix v0.19.1-0.20240730133608-779f61ac9c69/go.mod h1:xP3DCXdPBUe1sPiugLbd5mRh/mJQWfGWyED1S8s9V7c= nhooyr.io/websocket v1.8.11 h1:f/qXNc2/3DpoSZkHt1DQu6rj4zGC8JmkkLkWss0MgN0= nhooyr.io/websocket v1.8.11/go.mod h1:rN9OFWIUwuxg4fR5tELlYC04bXYowCP9GX47ivo2l+c= diff --git a/pkg/connector/chatinfo.go b/pkg/connector/chatinfo.go index 85758c7..732b0ae 100644 --- a/pkg/connector/chatinfo.go +++ b/pkg/connector/chatinfo.go @@ -202,7 +202,7 @@ func (s *SignalClient) makeCreateDMResponse(recipient *types.Recipient) *bridgev { EventSender: s.makeEventSender(s.Client.Store.ACI), Membership: event.MembershipJoin, - PowerLevel: moderatorPL, + PowerLevel: &moderatorPL, }, }, } @@ -229,7 +229,7 @@ func (s *SignalClient) makeCreateDMResponse(recipient *types.Recipient) *bridgev members.Members = append(members.Members, bridgev2.ChatMember{ EventSender: s.makeEventSender(recipient.ACI), Membership: event.MembershipJoin, - PowerLevel: moderatorPL, + PowerLevel: &moderatorPL, }) } serviceID = libsignalgo.NewACIServiceID(recipient.ACI) diff --git a/pkg/connector/groupinfo.go b/pkg/connector/groupinfo.go index 333ed7c..6bea361 100644 --- a/pkg/connector/groupinfo.go +++ b/pkg/connector/groupinfo.go @@ -34,14 +34,14 @@ import ( var defaultPL = 0 var moderatorPL = 50 -func roleToPL(role signalmeow.GroupMemberRole) int { +func roleToPL(role signalmeow.GroupMemberRole) *int { switch role { case signalmeow.GroupMember_ADMINISTRATOR: - return moderatorPL + return &moderatorPL case signalmeow.GroupMember_DEFAULT: fallthrough default: - return defaultPL + return &defaultPL } } From 03995c219ca2c3f71a9884e2e7d46bb489ad73ed Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Tue, 30 Jul 2024 16:51:40 +0300 Subject: [PATCH 122/580] libsignal: update to v0.54.0 --- pkg/libsignalgo/libsignal | 2 +- pkg/libsignalgo/libsignal-ffi.h | 13 ++++++++++--- pkg/libsignalgo/version.go | 2 +- 3 files changed, 12 insertions(+), 5 deletions(-) diff --git a/pkg/libsignalgo/libsignal b/pkg/libsignalgo/libsignal index e13e3de..b86d58e 160000 --- a/pkg/libsignalgo/libsignal +++ b/pkg/libsignalgo/libsignal @@ -1 +1 @@ -Subproject commit e13e3de8b25c8204b9bb5f04cc50dd12e7f40fc3 +Subproject commit b86d58e8d61e2d6f1687bfd30bd143e3eeeaaf6f diff --git a/pkg/libsignalgo/libsignal-ffi.h b/pkg/libsignalgo/libsignal-ffi.h index 0e5e893..0292867 100644 --- a/pkg/libsignalgo/libsignal-ffi.h +++ b/pkg/libsignalgo/libsignal-ffi.h @@ -196,6 +196,7 @@ typedef enum { SignalErrorCodeSvrRestoreFailed = 151, SignalErrorCodeAppExpired = 160, SignalErrorCodeDeviceDeregistered = 161, + SignalErrorCodeBackupValidation = 170, } SignalErrorCode; /** @@ -376,6 +377,8 @@ typedef struct { SignalOwnedBufferOfusize lengths; } SignalBytestringArray; +typedef SignalBytestringArray SignalStringArray; + typedef struct { const unsigned char *base; size_t length; @@ -660,8 +663,6 @@ typedef struct { typedef SignalFfiChatListenerStruct SignalFfiMakeChatListenerStruct; -typedef SignalBytestringArray SignalStringArray; - typedef int (*SignalRead)(void *ctx, uint8_t *buf, size_t buf_len, size_t *amount_read); typedef int (*SignalSkip)(void *ctx, uint64_t amount); @@ -760,6 +761,8 @@ SignalFfiError *signal_error_get_retry_after_seconds(const SignalFfiError *err, SignalFfiError *signal_error_get_tries_remaining(const SignalFfiError *err, uint32_t *out); +SignalFfiError *signal_error_get_unknown_fields(const SignalFfiError *err, SignalStringArray *out); + void signal_error_free(SignalFfiError *err); SignalFfiError *signal_identitykeypair_deserialize(SignalPrivateKey **private_key, SignalPublicKey **public_key, SignalBorrowedBuffer input); @@ -1524,6 +1527,8 @@ SignalFfiError *signal_create_otp_from_base64(const char **out, const char *user SignalFfiError *signal_svr3_backup(SignalCPromiseOwnedBufferOfc_uchar *promise, const SignalTokioAsyncContext *async_runtime, const SignalConnectionManager *connection_manager, SignalBorrowedBuffer secret, const char *password, uint32_t max_tries, const char *username, const char *enclave_password); +SignalFfiError *signal_svr3_migrate(SignalCPromiseOwnedBufferOfc_uchar *promise, const SignalTokioAsyncContext *async_runtime, const SignalConnectionManager *connection_manager, SignalBorrowedBuffer secret, const char *password, uint32_t max_tries, const char *username, const char *enclave_password); + SignalFfiError *signal_svr3_restore(SignalCPromiseOwnedBufferOfc_uchar *promise, const SignalTokioAsyncContext *async_runtime, const SignalConnectionManager *connection_manager, const char *password, SignalBorrowedBuffer share_set, const char *username, const char *enclave_password); SignalFfiError *signal_svr3_remove(SignalCPromisebool *promise, const SignalTokioAsyncContext *async_runtime, const SignalConnectionManager *connection_manager, const char *username, const char *enclave_password); @@ -1560,7 +1565,7 @@ SignalFfiError *signal_http_request_new_without_body(SignalHttpRequest **out, co SignalFfiError *signal_http_request_add_header(const SignalHttpRequest *request, const char *name, const char *value); -SignalFfiError *signal_chat_service_new(SignalChat **out, const SignalConnectionManager *connection_manager, const char *username, const char *password); +SignalFfiError *signal_chat_service_new(SignalChat **out, const SignalConnectionManager *connection_manager, const char *username, const char *password, bool receive_stories); SignalFfiError *signal_chat_service_disconnect(SignalCPromisebool *promise, const SignalTokioAsyncContext *async_runtime, const SignalChat *chat); @@ -1748,6 +1753,8 @@ SignalFfiError *signal_testing_return_string_array(SignalStringArray *out); SignalFfiError *signal_testing_process_bytestring_array(SignalBytestringArray *out, SignalBorrowedSliceOfBuffers input); +SignalFfiError *signal_testing_input_stream_read_into_zero_length_slice(SignalOwnedBuffer *out, const SignalInputStream *caps_alphabet_input); + SignalFfiError *signal_testing_cdsi_lookup_response_convert(SignalCPromiseFfiCdsiLookupResponse *promise, const SignalTokioAsyncContext *async_runtime); SignalFfiError *signal_testing_only_completes_by_cancellation(SignalCPromisebool *promise, const SignalTokioAsyncContext *async_runtime); diff --git a/pkg/libsignalgo/version.go b/pkg/libsignalgo/version.go index 8191319..59cbbd7 100644 --- a/pkg/libsignalgo/version.go +++ b/pkg/libsignalgo/version.go @@ -2,4 +2,4 @@ package libsignalgo -const Version = "v0.52.0" +const Version = "v0.54.0" From 5d2dfa48c7121ca34e8e6ae67d19b69abfa0c33a Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Thu, 1 Aug 2024 18:20:57 +0300 Subject: [PATCH 123/580] v2: update mautrix-go --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index a501f5f..b55a072 100644 --- a/go.mod +++ b/go.mod @@ -19,7 +19,7 @@ require ( golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 golang.org/x/net v0.27.0 google.golang.org/protobuf v1.34.2 - maunium.net/go/mautrix v0.19.1-0.20240730133608-779f61ac9c69 + maunium.net/go/mautrix v0.19.1-0.20240801151952-a1a245be10db nhooyr.io/websocket v1.8.11 ) diff --git a/go.sum b/go.sum index 374199d..9088583 100644 --- a/go.sum +++ b/go.sum @@ -93,7 +93,7 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= maunium.net/go/mauflag v1.0.0 h1:YiaRc0tEI3toYtJMRIfjP+jklH45uDHtT80nUamyD4M= maunium.net/go/mauflag v1.0.0/go.mod h1:nLivPOpTpHnpzEh8jEdSL9UqO9+/KBJFmNRlwKfkPeA= -maunium.net/go/mautrix v0.19.1-0.20240730133608-779f61ac9c69 h1:bKO9y6moTiKWBYry5KwhiGmdyZR1xfIX4ujAWt7KuUU= -maunium.net/go/mautrix v0.19.1-0.20240730133608-779f61ac9c69/go.mod h1:xP3DCXdPBUe1sPiugLbd5mRh/mJQWfGWyED1S8s9V7c= +maunium.net/go/mautrix v0.19.1-0.20240801151952-a1a245be10db h1:ouSy8EJgvkopHXPZHaxXDw47wrWLaHOrL6nlcIsvZbA= +maunium.net/go/mautrix v0.19.1-0.20240801151952-a1a245be10db/go.mod h1:xP3DCXdPBUe1sPiugLbd5mRh/mJQWfGWyED1S8s9V7c= nhooyr.io/websocket v1.8.11 h1:f/qXNc2/3DpoSZkHt1DQu6rj4zGC8JmkkLkWss0MgN0= nhooyr.io/websocket v1.8.11/go.mod h1:rN9OFWIUwuxg4fR5tELlYC04bXYowCP9GX47ivo2l+c= From 480c2a404e55f2e8a8436a69916d702c4c259636 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Thu, 1 Aug 2024 22:15:19 +0300 Subject: [PATCH 124/580] v2: update mautrix-go --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index b55a072..463bc67 100644 --- a/go.mod +++ b/go.mod @@ -19,7 +19,7 @@ require ( golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 golang.org/x/net v0.27.0 google.golang.org/protobuf v1.34.2 - maunium.net/go/mautrix v0.19.1-0.20240801151952-a1a245be10db + maunium.net/go/mautrix v0.19.1-0.20240801191314-7402f5a70501 nhooyr.io/websocket v1.8.11 ) diff --git a/go.sum b/go.sum index 9088583..e22a3ca 100644 --- a/go.sum +++ b/go.sum @@ -93,7 +93,7 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= maunium.net/go/mauflag v1.0.0 h1:YiaRc0tEI3toYtJMRIfjP+jklH45uDHtT80nUamyD4M= maunium.net/go/mauflag v1.0.0/go.mod h1:nLivPOpTpHnpzEh8jEdSL9UqO9+/KBJFmNRlwKfkPeA= -maunium.net/go/mautrix v0.19.1-0.20240801151952-a1a245be10db h1:ouSy8EJgvkopHXPZHaxXDw47wrWLaHOrL6nlcIsvZbA= -maunium.net/go/mautrix v0.19.1-0.20240801151952-a1a245be10db/go.mod h1:xP3DCXdPBUe1sPiugLbd5mRh/mJQWfGWyED1S8s9V7c= +maunium.net/go/mautrix v0.19.1-0.20240801191314-7402f5a70501 h1:fikXfFmwO3azwAbBS1Js7MLs657xGZrtyAMFPri9TGc= +maunium.net/go/mautrix v0.19.1-0.20240801191314-7402f5a70501/go.mod h1:xP3DCXdPBUe1sPiugLbd5mRh/mJQWfGWyED1S8s9V7c= nhooyr.io/websocket v1.8.11 h1:f/qXNc2/3DpoSZkHt1DQu6rj4zGC8JmkkLkWss0MgN0= nhooyr.io/websocket v1.8.11/go.mod h1:rN9OFWIUwuxg4fR5tELlYC04bXYowCP9GX47ivo2l+c= From 219b3bec1de066d889b802481b6498f522ca05f3 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Mon, 5 Aug 2024 17:36:35 +0300 Subject: [PATCH 125/580] v2: store remote profile info in UserLogin --- go.mod | 5 +-- go.sum | 10 +++--- pkg/connector/client.go | 10 +++--- pkg/connector/dbmeta.go | 10 ++---- pkg/connector/handlesignal.go | 68 ++++++++++++++++++++++++++++------- pkg/connector/login.go | 3 +- 6 files changed, 74 insertions(+), 32 deletions(-) diff --git a/go.mod b/go.mod index 463bc67..27964e4 100644 --- a/go.mod +++ b/go.mod @@ -14,12 +14,12 @@ require ( github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e github.com/stretchr/testify v1.9.0 github.com/tidwall/gjson v1.17.3 - go.mau.fi/util v0.6.1-0.20240722085753-2d7945696c9b + go.mau.fi/util v0.6.1-0.20240802175451-b430ebbffc98 golang.org/x/crypto v0.25.0 golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 golang.org/x/net v0.27.0 google.golang.org/protobuf v1.34.2 - maunium.net/go/mautrix v0.19.1-0.20240801191314-7402f5a70501 + maunium.net/go/mautrix v0.19.1-0.20240804192210-9d6622c29325 nhooyr.io/websocket v1.8.11 ) @@ -43,6 +43,7 @@ require ( github.com/yuin/goldmark v1.7.4 // indirect go.mau.fi/zeroconfig v0.1.3 // indirect golang.org/x/sys v0.22.0 // indirect + golang.org/x/text v0.16.0 // indirect gopkg.in/natefinch/lumberjack.v2 v2.2.1 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect maunium.net/go/mauflag v1.0.0 // indirect diff --git a/go.sum b/go.sum index e22a3ca..054a6be 100644 --- a/go.sum +++ b/go.sum @@ -67,8 +67,8 @@ github.com/tidwall/sjson v1.2.5 h1:kLy8mja+1c9jlljvWTlSazM7cKDRfJuR/bOJhcY5NcY= github.com/tidwall/sjson v1.2.5/go.mod h1:Fvgq9kS/6ociJEDnK0Fk1cpYF4FIW6ZF7LAe+6jwd28= github.com/yuin/goldmark v1.7.4 h1:BDXOHExt+A7gwPCJgPIIq7ENvceR7we7rOS9TNoLZeg= github.com/yuin/goldmark v1.7.4/go.mod h1:uzxRWxtg69N339t3louHJ7+O03ezfj6PlliRlaOzY1E= -go.mau.fi/util v0.6.1-0.20240722085753-2d7945696c9b h1:8s3uTMPZts03evXLqdTJ0WXB0YWZDNSovpd6oFfCFvY= -go.mau.fi/util v0.6.1-0.20240722085753-2d7945696c9b/go.mod h1:ljYdq3sPfpICc3zMU+/mHV/sa4z0nKxc67hSBwnrk8U= +go.mau.fi/util v0.6.1-0.20240802175451-b430ebbffc98 h1:gJ0peWecBm6TtlxKFVIc1KbooXSCHtPfsfb2Eha5A0A= +go.mau.fi/util v0.6.1-0.20240802175451-b430ebbffc98/go.mod h1:S1juuPWGau2GctPY3FR/4ec/MDLhAG2QPhdnUwpzWIo= go.mau.fi/zeroconfig v0.1.3 h1:As9wYDKmktjmNZW5i1vn8zvJlmGKHeVxHVIBMXsm4kM= go.mau.fi/zeroconfig v0.1.3/go.mod h1:NcSJkf180JT+1IId76PcMuLTNa1CzsFFZ0nBygIQM70= golang.org/x/crypto v0.25.0 h1:ypSNr+bnYL2YhwoMt2zPxHFmbAN1KZs/njMG3hxUp30= @@ -82,6 +82,8 @@ golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI= golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= +golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= @@ -93,7 +95,7 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= maunium.net/go/mauflag v1.0.0 h1:YiaRc0tEI3toYtJMRIfjP+jklH45uDHtT80nUamyD4M= maunium.net/go/mauflag v1.0.0/go.mod h1:nLivPOpTpHnpzEh8jEdSL9UqO9+/KBJFmNRlwKfkPeA= -maunium.net/go/mautrix v0.19.1-0.20240801191314-7402f5a70501 h1:fikXfFmwO3azwAbBS1Js7MLs657xGZrtyAMFPri9TGc= -maunium.net/go/mautrix v0.19.1-0.20240801191314-7402f5a70501/go.mod h1:xP3DCXdPBUe1sPiugLbd5mRh/mJQWfGWyED1S8s9V7c= +maunium.net/go/mautrix v0.19.1-0.20240804192210-9d6622c29325 h1:2Ontl4ZDFytmhCKyp5io4HQD+t9bQOZod0lPwtwiXPA= +maunium.net/go/mautrix v0.19.1-0.20240804192210-9d6622c29325/go.mod h1:ZWyxoQxRTBxzWIMs0kQCVogZIY0clTu33h102veCT/Q= nhooyr.io/websocket v1.8.11 h1:f/qXNc2/3DpoSZkHt1DQu6rj4zGC8JmkkLkWss0MgN0= nhooyr.io/websocket v1.8.11/go.mod h1:rN9OFWIUwuxg4fR5tELlYC04bXYowCP9GX47ivo2l+c= diff --git a/pkg/connector/client.go b/pkg/connector/client.go index 2293a33..838c0ee 100644 --- a/pkg/connector/client.go +++ b/pkg/connector/client.go @@ -18,6 +18,7 @@ type SignalClient struct { Main *SignalConnector UserLogin *bridgev2.UserLogin Client *signalmeow.Client + Ghost *bridgev2.Ghost } var signalCaps = &bridgev2.NetworkRoomCapabilities{ @@ -218,6 +219,11 @@ func (s *SignalClient) bridgeStateLoop(statusChan <-chan signalmeow.SignalConnec } func (s *SignalClient) Connect(ctx context.Context) error { + if s.Client == nil { + s.UserLogin.BridgeState.Send(status.BridgeState{StateEvent: status.StateBadCredentials, Message: "You're not logged into Signal"}) + return nil + } + s.updateRemoteProfile(ctx, false) s.tryConnect(ctx, 0) return nil } @@ -233,10 +239,6 @@ func (s *SignalClient) Disconnect() { } func (s *SignalClient) tryConnect(ctx context.Context, retryCount int) { - if s.Client == nil { - s.UserLogin.BridgeState.Send(status.BridgeState{StateEvent: status.StateBadCredentials, Message: "You're not logged into Signal"}) - return - } ch, err := s.Client.StartReceiveLoops(ctx) if err != nil { zerolog.Ctx(ctx).Err(err).Msg("Failed to start receive loops") diff --git a/pkg/connector/dbmeta.go b/pkg/connector/dbmeta.go index 18de885..68e21d5 100644 --- a/pkg/connector/dbmeta.go +++ b/pkg/connector/dbmeta.go @@ -29,10 +29,8 @@ func (s *SignalConnector) GetDBMetaTypes() database.MetaTypes { Message: func() any { return &MessageMetadata{} }, - Reaction: nil, - UserLogin: func() any { - return &UserLoginMetadata{} - }, + Reaction: nil, + UserLogin: nil, } } @@ -43,7 +41,3 @@ type PortalMetadata struct { type MessageMetadata struct { ContainsAttachments bool `json:"contains_attachments,omitempty"` } - -type UserLoginMetadata struct { - Phone string `json:"phone"` -} diff --git a/pkg/connector/handlesignal.go b/pkg/connector/handlesignal.go index ba3f6ff..169338d 100644 --- a/pkg/connector/handlesignal.go +++ b/pkg/connector/handlesignal.go @@ -19,6 +19,7 @@ package connector import ( "context" "fmt" + "strings" "time" "github.com/google/uuid" @@ -485,19 +486,60 @@ func (s *SignalClient) handleSignalContactList(evt *events.ContactList) { log := s.UserLogin.Log.With().Str("action", "handle contact list").Logger() ctx := log.WithContext(context.TODO()) for _, contact := range evt.Contacts { - if contact.ACI != uuid.Nil { - fullContact, err := s.Client.ContactByACI(ctx, contact.ACI) - if err != nil { - log.Err(err).Msg("Failed to get full contact info from store") - continue - } - fullContact.ContactAvatar = contact.ContactAvatar - ghost, err := s.Main.Bridge.GetGhostByID(ctx, makeUserID(contact.ACI)) - if err != nil { - log.Err(err).Msg("Failed to get ghost to update contact info") - continue - } - ghost.UpdateInfo(ctx, s.contactToUserInfo(contact)) + if contact.ACI == uuid.Nil { + continue + } + fullContact, err := s.Client.ContactByACI(ctx, contact.ACI) + if err != nil { + log.Err(err).Msg("Failed to get full contact info from store") + continue + } + fullContact.ContactAvatar = contact.ContactAvatar + ghost, err := s.Main.Bridge.GetGhostByID(ctx, makeUserID(contact.ACI)) + if err != nil { + log.Err(err).Msg("Failed to get ghost to update contact info") + continue + } + ghost.UpdateInfo(ctx, s.contactToUserInfo(contact)) + if contact.ACI == s.Client.Store.ACI { + s.updateRemoteProfile(ctx, true) + } + } +} + +func (s *SignalClient) updateRemoteProfile(ctx context.Context, resendState bool) { + var err error + if s.Ghost == nil { + s.Ghost, err = s.Main.Bridge.GetGhostByID(ctx, makeUserID(s.Client.Store.ACI)) + if err != nil { + zerolog.Ctx(ctx).Err(err).Msg("Failed to get ghost for remote profile update") + return + } + } + changed := false + if s.UserLogin.RemoteProfile.Name != s.Ghost.Name { + s.UserLogin.RemoteProfile.Name = s.Ghost.Name + changed = true + } + if s.UserLogin.RemoteProfile.Avatar != s.Ghost.AvatarMXC { + s.UserLogin.RemoteProfile.Avatar = s.Ghost.AvatarMXC + changed = true + } + if len(s.Ghost.Identifiers) > 0 && strings.HasPrefix(s.Ghost.Identifiers[0], "tel:") { + phone := strings.TrimPrefix(s.Ghost.Identifiers[0], "tel:") + if s.UserLogin.RemoteProfile.Phone != phone { + s.UserLogin.RemoteProfile.Phone = phone + changed = true + } + } + if changed { + err = s.UserLogin.Save(ctx) + if err != nil { + zerolog.Ctx(ctx).Err(err).Msg("Failed to save updated remote profile") + } + if resendState { + // TODO this has potential race conditions + s.UserLogin.BridgeState.Send(s.UserLogin.BridgeState.GetPrevUnsent()) } } } diff --git a/pkg/connector/login.go b/pkg/connector/login.go index 82ddac5..3acd926 100644 --- a/pkg/connector/login.go +++ b/pkg/connector/login.go @@ -21,6 +21,7 @@ import ( "fmt" "github.com/google/uuid" + "maunium.net/go/mautrix/bridge/status" "maunium.net/go/mautrix/bridgev2" "maunium.net/go/mautrix/bridgev2/database" @@ -159,7 +160,7 @@ func (qr *QRLogin) processingWait(ctx context.Context) (*bridgev2.LoginStep, err ul, err := qr.User.NewLogin(ctx, &database.UserLogin{ ID: newLoginID, RemoteName: qr.ProvData.Number, - Metadata: &UserLoginMetadata{ + RemoteProfile: status.RemoteProfile{ Phone: qr.ProvData.Number, }, }, &bridgev2.NewLoginParams{ From c246473b52533624083635ddb9d623fe5eb2f405 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Wed, 7 Aug 2024 00:45:01 +0300 Subject: [PATCH 126/580] v2: update mautrix-go --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 27964e4..a04e88a 100644 --- a/go.mod +++ b/go.mod @@ -19,7 +19,7 @@ require ( golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 golang.org/x/net v0.27.0 google.golang.org/protobuf v1.34.2 - maunium.net/go/mautrix v0.19.1-0.20240804192210-9d6622c29325 + maunium.net/go/mautrix v0.19.1-0.20240806214251-e0f58dccf432 nhooyr.io/websocket v1.8.11 ) diff --git a/go.sum b/go.sum index 054a6be..50a5dcc 100644 --- a/go.sum +++ b/go.sum @@ -95,7 +95,7 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= maunium.net/go/mauflag v1.0.0 h1:YiaRc0tEI3toYtJMRIfjP+jklH45uDHtT80nUamyD4M= maunium.net/go/mauflag v1.0.0/go.mod h1:nLivPOpTpHnpzEh8jEdSL9UqO9+/KBJFmNRlwKfkPeA= -maunium.net/go/mautrix v0.19.1-0.20240804192210-9d6622c29325 h1:2Ontl4ZDFytmhCKyp5io4HQD+t9bQOZod0lPwtwiXPA= -maunium.net/go/mautrix v0.19.1-0.20240804192210-9d6622c29325/go.mod h1:ZWyxoQxRTBxzWIMs0kQCVogZIY0clTu33h102veCT/Q= +maunium.net/go/mautrix v0.19.1-0.20240806214251-e0f58dccf432 h1:Gz1nMg/s4B0VZD4e31wfaghR5cSk2NQVuQkxdCBuI7o= +maunium.net/go/mautrix v0.19.1-0.20240806214251-e0f58dccf432/go.mod h1:ZWyxoQxRTBxzWIMs0kQCVogZIY0clTu33h102veCT/Q= nhooyr.io/websocket v1.8.11 h1:f/qXNc2/3DpoSZkHt1DQu6rj4zGC8JmkkLkWss0MgN0= nhooyr.io/websocket v1.8.11/go.mod h1:rN9OFWIUwuxg4fR5tELlYC04bXYowCP9GX47ivo2l+c= From 0c9f2c19d22f8d8021748eaaa387d35b0e448247 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Wed, 7 Aug 2024 02:14:39 +0300 Subject: [PATCH 127/580] all: delete legacy bridge --- .gitignore | 2 - .gitlab-ci.yml | 7 +- .pre-commit-config.yaml | 6 +- CHANGELOG.md | 6 + Dockerfile.ci | 14 - Makefile | 28 - ROADMAP.md | 14 +- build-go-v2.sh | 9 - build-go.sh | 4 +- build-v2.sh | 6 +- build.sh | 4 - .../legacymigrate.go | 0 .../legacymigrate.sql | 0 .../legacyprovision.go | 118 +- .../main.go | 0 commands.go | 1161 ------- config/bridge.go | 241 -- config/config.go | 44 - config/upgrade.go | 167 - custompuppet.go | 97 - database/database.go | 53 - database/disappearingmessage.go | 125 - database/lostportal.go | 58 - database/message.go | 179 - database/portal.go | 206 -- database/puppet.go | 158 - database/reaction.go | 97 - database/upgrades/00-latest.sql | 116 - .../upgrades/13-upgrade-mx-state-store.sql | 18 - database/upgrades/14-remove-notice-room.sql | 3 - .../15-remove-unused-puppet-columns.sql | 3 - database/upgrades/16-refactor-postgres.sql | 123 - database/upgrades/17-refactor-sqlite.sql | 198 -- database/upgrades/18-spaces.sql | 17 - database/upgrades/19-more-portal-metadata.sql | 5 - .../upgrades/20-puppet-profile-fetch-ts.sql | 2 - database/user.go | 115 - database/userportal.go | 116 - disappearing.go | 156 - docker-run.sh | 6 +- example-config.yaml | 317 -- go.mod | 3 + legacyprovision/types.go | 92 - main.go | 352 -- messagetracking.go | 311 -- metrics.go | 281 -- msgconv/msgconv.go | 65 - pkg/connector/chatinfo.go | 17 +- pkg/connector/client.go | 3 +- pkg/connector/connector.go | 69 +- pkg/connector/dbmeta.go | 14 +- pkg/connector/groupinfo.go | 3 +- pkg/connector/handlematrix.go | 62 +- pkg/connector/handlesignal.go | 92 +- pkg/connector/id.go | 88 +- pkg/connector/login.go | 3 +- pkg/connector/msgconvproxy.go | 117 - {msgconv => pkg/msgconv}/from-matrix.go | 83 +- {msgconv => pkg/msgconv}/from-signal.go | 226 +- {msgconv => pkg/msgconv}/matrixfmt/convert.go | 0 .../msgconv}/matrixfmt/convert_test.go | 4 +- {msgconv => pkg/msgconv}/matrixfmt/html.go | 2 +- pkg/msgconv/msgconv.go | 107 + {msgconv => pkg/msgconv}/signalfmt/convert.go | 0 .../msgconv}/signalfmt/convert_test.go | 2 +- {msgconv => pkg/msgconv}/signalfmt/html.go | 0 {msgconv => pkg/msgconv}/signalfmt/tags.go | 0 {msgconv => pkg/msgconv}/signalfmt/tree.go | 0 {msgconv => pkg/msgconv}/urlpreview.go | 71 +- .../upgrades.go => pkg/signalid/dbmeta.go | 31 +- pkg/signalid/ids.go | 105 + portal.go | 3026 ----------------- provisioning.go | 640 ---- puppet.go | 411 --- user.go | 1020 ------ 75 files changed, 562 insertions(+), 10737 deletions(-) delete mode 100644 Dockerfile.ci delete mode 100644 Makefile delete mode 100755 build-go-v2.sh delete mode 100755 build.sh rename cmd/{mautrix-signal-v2 => mautrix-signal}/legacymigrate.go (100%) rename cmd/{mautrix-signal-v2 => mautrix-signal}/legacymigrate.sql (100%) rename cmd/{mautrix-signal-v2 => mautrix-signal}/legacyprovision.go (69%) rename cmd/{mautrix-signal-v2 => mautrix-signal}/main.go (100%) delete mode 100644 commands.go delete mode 100644 config/bridge.go delete mode 100644 config/config.go delete mode 100644 config/upgrade.go delete mode 100644 custompuppet.go delete mode 100644 database/database.go delete mode 100644 database/disappearingmessage.go delete mode 100644 database/lostportal.go delete mode 100644 database/message.go delete mode 100644 database/portal.go delete mode 100644 database/puppet.go delete mode 100644 database/reaction.go delete mode 100644 database/upgrades/00-latest.sql delete mode 100644 database/upgrades/13-upgrade-mx-state-store.sql delete mode 100644 database/upgrades/14-remove-notice-room.sql delete mode 100644 database/upgrades/15-remove-unused-puppet-columns.sql delete mode 100644 database/upgrades/16-refactor-postgres.sql delete mode 100644 database/upgrades/17-refactor-sqlite.sql delete mode 100644 database/upgrades/18-spaces.sql delete mode 100644 database/upgrades/19-more-portal-metadata.sql delete mode 100644 database/upgrades/20-puppet-profile-fetch-ts.sql delete mode 100644 database/user.go delete mode 100644 database/userportal.go delete mode 100644 disappearing.go delete mode 100644 example-config.yaml delete mode 100644 legacyprovision/types.go delete mode 100644 main.go delete mode 100644 messagetracking.go delete mode 100644 metrics.go delete mode 100644 msgconv/msgconv.go delete mode 100644 pkg/connector/msgconvproxy.go rename {msgconv => pkg/msgconv}/from-matrix.go (74%) rename {msgconv => pkg/msgconv}/from-signal.go (72%) rename {msgconv => pkg/msgconv}/matrixfmt/convert.go (100%) rename {msgconv => pkg/msgconv}/matrixfmt/convert_test.go (97%) rename {msgconv => pkg/msgconv}/matrixfmt/html.go (99%) create mode 100644 pkg/msgconv/msgconv.go rename {msgconv => pkg/msgconv}/signalfmt/convert.go (100%) rename {msgconv => pkg/msgconv}/signalfmt/convert_test.go (99%) rename {msgconv => pkg/msgconv}/signalfmt/html.go (100%) rename {msgconv => pkg/msgconv}/signalfmt/tags.go (100%) rename {msgconv => pkg/msgconv}/signalfmt/tree.go (100%) rename {msgconv => pkg/msgconv}/urlpreview.go (53%) rename database/upgrades/upgrades.go => pkg/signalid/dbmeta.go (54%) create mode 100644 pkg/signalid/ids.go delete mode 100644 portal.go delete mode 100644 provisioning.go delete mode 100644 puppet.go delete mode 100644 user.go diff --git a/.gitignore b/.gitignore index 0031287..ab00deb 100644 --- a/.gitignore +++ b/.gitignore @@ -6,7 +6,5 @@ *.log* /mautrix-signal -/mautrix-signalgo -/mautrix-signal-v2 /start /libsignal_ffi.a diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 03bd8f5..952dabc 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1,17 +1,12 @@ include: -- project: 'mautrix/ci' - file: '/go.yml' - project: 'mautrix/ci' file: '/gov2.yml' variables: BUILDER_IMAGE: dock.mau.dev/tulir/gomuks-build-docker/signal + BINARY_NAME_V2: mautrix-signal # 32-bit arm builds aren't supported -build arm: - rules: - - when: never - build arm v2: rules: - when: never diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index b22a061..8a667b3 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,6 +1,6 @@ repos: - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v4.5.0 + rev: v4.6.0 hooks: - id: trailing-whitespace exclude_types: [markdown] @@ -18,11 +18,11 @@ repos: - "go.mau.fi/mautrix-signal" - "-w" - id: go-vet-mod - #- id: go-staticcheck-repo-mod +# - id: go-staticcheck-repo-mod # TODO: reenable this and fix all the problems - repo: https://github.com/beeper/pre-commit-go - rev: v0.3.0 + rev: v0.3.1 hooks: - id: zerolog-ban-msgf - id: zerolog-use-stringer diff --git a/CHANGELOG.md b/CHANGELOG.md index f00f374..f0c11f6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,9 @@ +# v0.7.0 (unreleased) + +* Updated to libsignal v0.54.0. +* Rewrote bridge using bridgev2 architecture. + * It is recommended to check the config file after upgrading. + # v0.6.3 (2024-07-16) * Updated to libsignal v0.52.0. diff --git a/Dockerfile.ci b/Dockerfile.ci deleted file mode 100644 index e75845e..0000000 --- a/Dockerfile.ci +++ /dev/null @@ -1,14 +0,0 @@ -FROM alpine:3.19 - -ENV UID=1337 \ - GID=1337 - -RUN apk add --no-cache ffmpeg su-exec ca-certificates bash jq curl yq - -ARG EXECUTABLE=./mautrix-signal -COPY $EXECUTABLE /usr/bin/mautrix-signal -COPY ./example-config.yaml /opt/mautrix-signal/example-config.yaml -COPY ./docker-run.sh /docker-run.sh -VOLUME /data - -CMD ["/docker-run.sh"] diff --git a/Makefile b/Makefile deleted file mode 100644 index b497635..0000000 --- a/Makefile +++ /dev/null @@ -1,28 +0,0 @@ -.PHONY: all build_rust copy_library build_go clean - -all: build_rust copy_library build_go - -LIBRARY_FILENAME=libsignal_ffi.a -RUST_DIR=pkg/libsignalgo/libsignal -GO_BINARY=mautrix-signal - -# TODO fix linking with debug library -#ifneq ($(DBG),1) -RUST_TARGET_SUBDIR=release -#else -#RUST_TARGET_SUBDIR=debug -#endif - -build_rust: - ./build-rust.sh - -copy_library: - cp $(RUST_DIR)/target/$(RUST_TARGET_SUBDIR)/$(LIBRARY_FILENAME) . - -build_go: - LIBRARY_PATH="$${LIBRARY_PATH}:." ./build-go.sh - -clean: - rm -f ./$(LIBRARY_FILENAME) - cd $(RUST_DIR) && cargo clean - rm -f $(GO_BINARY) diff --git a/ROADMAP.md b/ROADMAP.md index 85c7494..9c0cedb 100644 --- a/ROADMAP.md +++ b/ROADMAP.md @@ -1,17 +1,17 @@ # Features & roadmap * Matrix → Signal - * [ ] Message content + * [x] Message content * [x] Text * [x] Formatting * [x] Mentions - * [ ] Media + * [x] Media * [x] Images * [x] Audio files * [x] Voice messages * [x] Files * [x] Gifs - * [ ] Locations + * [x] Locations * [x] Stickers * [x] Message edits * [x] Message reactions @@ -22,9 +22,9 @@ * [x] Topic * [ ] Membership actions * [ ] Join (accepting invites) - * [x] Invite - * [x] Leave - * [x] Kick/Ban/Unban + * [ ] Invite + * [ ] Leave + * [ ] Kick/Ban/Unban * [x] Group permissions * [x] Typing notifications * [x] Read receipts @@ -70,5 +70,5 @@ * [x] When receiving message * [x] Linking as secondary device * [ ] Registering as primary device - * [x] Private chat/group creation by inviting Matrix puppet of Signal user to new room + * [ ] Private chat/group creation by inviting Matrix puppet of Signal user to new room * [x] Option to use own Matrix account for messages sent from other Signal clients diff --git a/build-go-v2.sh b/build-go-v2.sh deleted file mode 100755 index 199f474..0000000 --- a/build-go-v2.sh +++ /dev/null @@ -1,9 +0,0 @@ -#!/bin/sh -MAUTRIX_VERSION=$(cat go.mod | grep 'maunium.net/go/mautrix ' | awk '{ print $2 }') -GO_LDFLAGS="-X main.Tag=$(git describe --exact-match --tags 2>/dev/null) -X main.Commit=$(git rev-parse HEAD) -X 'main.BuildTime=`date -Iseconds`' -X 'maunium.net/go/mautrix.GoModVersion=$MAUTRIX_VERSION'" -if [ "$DBG" = 1 ]; then - GO_GCFLAGS='all=-N -l' -else - GO_LDFLAGS="-s -w ${GO_LDFLAGS}" -fi -go build -gcflags="$GO_GCFLAGS" -ldflags="$GO_LDFLAGS" -o mautrix-signal-v2 ./cmd/mautrix-signal-v2 "$@" diff --git a/build-go.sh b/build-go.sh index ecf8907..faaac6f 100755 --- a/build-go.sh +++ b/build-go.sh @@ -1,9 +1,9 @@ #!/bin/sh MAUTRIX_VERSION=$(cat go.mod | grep 'maunium.net/go/mautrix ' | awk '{ print $2 }') -GO_LDFLAGS="-X main.Tag=$(git describe --exact-match --tags 2>/dev/null) -X main.Commit=$(git rev-parse HEAD) -X 'main.BuildTime=`date '+%b %_d %Y, %H:%M:%S'`' -X 'maunium.net/go/mautrix.GoModVersion=$MAUTRIX_VERSION'" +GO_LDFLAGS="-X main.Tag=$(git describe --exact-match --tags 2>/dev/null) -X main.Commit=$(git rev-parse HEAD) -X 'main.BuildTime=`date -Iseconds`' -X 'maunium.net/go/mautrix.GoModVersion=$MAUTRIX_VERSION'" if [ "$DBG" = 1 ]; then GO_GCFLAGS='all=-N -l' else GO_LDFLAGS="-s -w ${GO_LDFLAGS}" fi -go build -gcflags="$GO_GCFLAGS" -ldflags="$GO_LDFLAGS" -o mautrix-signal "$@" +go build -gcflags="$GO_GCFLAGS" -ldflags="$GO_LDFLAGS" -o mautrix-signal ./cmd/mautrix-signal "$@" diff --git a/build-v2.sh b/build-v2.sh index b541932..2b51084 100755 --- a/build-v2.sh +++ b/build-v2.sh @@ -1,4 +1,4 @@ #!/bin/sh -#./build-rust.sh -#cp -f pkg/libsignalgo/libsignal/target/release/libsignal_ffi.a . -LIBRARY_PATH=.:$LIBRARY_PATH ./build-go-v2.sh +./build-rust.sh +cp -f pkg/libsignalgo/libsignal/target/release/libsignal_ffi.a . +LIBRARY_PATH=.:$LIBRARY_PATH ./build-go.sh diff --git a/build.sh b/build.sh deleted file mode 100755 index b17ad4f..0000000 --- a/build.sh +++ /dev/null @@ -1,4 +0,0 @@ -#!/bin/sh -git submodule init -git submodule update -make diff --git a/cmd/mautrix-signal-v2/legacymigrate.go b/cmd/mautrix-signal/legacymigrate.go similarity index 100% rename from cmd/mautrix-signal-v2/legacymigrate.go rename to cmd/mautrix-signal/legacymigrate.go diff --git a/cmd/mautrix-signal-v2/legacymigrate.sql b/cmd/mautrix-signal/legacymigrate.sql similarity index 100% rename from cmd/mautrix-signal-v2/legacymigrate.sql rename to cmd/mautrix-signal/legacymigrate.sql diff --git a/cmd/mautrix-signal-v2/legacyprovision.go b/cmd/mautrix-signal/legacyprovision.go similarity index 69% rename from cmd/mautrix-signal-v2/legacyprovision.go rename to cmd/mautrix-signal/legacyprovision.go index b3c3f80..8e8e752 100644 --- a/cmd/mautrix-signal-v2/legacyprovision.go +++ b/cmd/mautrix-signal/legacyprovision.go @@ -28,8 +28,8 @@ import ( "github.com/rs/zerolog" "maunium.net/go/mautrix" "maunium.net/go/mautrix/bridgev2" + "maunium.net/go/mautrix/id" - "go.mau.fi/mautrix-signal/legacyprovision" "go.mau.fi/mautrix-signal/pkg/connector" ) @@ -54,7 +54,7 @@ func legacyProvLinkNew(w http.ResponseWriter, r *http.Request) { user := m.Matrix.Provisioning.GetUser(r) defLogin := user.GetDefaultLogin() if defLogin != nil && defLogin.Client != nil && defLogin.Client.IsLoggedIn() { - legacyprovision.JSONResponse(w, http.StatusConflict, &legacyprovision.Error{ + JSONResponse(w, http.StatusConflict, &Error{ Error: "Already logged in", ErrCode: "FI.MAU.ALREADY_LOGGED_IN", }) @@ -64,7 +64,7 @@ func legacyProvLinkNew(w http.ResponseWriter, r *http.Request) { login, err := m.Connector.CreateLogin(r.Context(), user, "qr") if err != nil { log.Err(err).Msg("Failed to create login") - legacyprovision.JSONResponse(w, http.StatusInternalServerError, &legacyprovision.Error{ + JSONResponse(w, http.StatusInternalServerError, &Error{ Error: "Internal error starting login", ErrCode: "M_UNKNOWN", }) @@ -73,14 +73,14 @@ func legacyProvLinkNew(w http.ResponseWriter, r *http.Request) { firstStep, err := login.Start(r.Context()) if err != nil { log.Err(err).Msg("Failed to start login") - legacyprovision.JSONResponse(w, http.StatusInternalServerError, &legacyprovision.Error{ + JSONResponse(w, http.StatusInternalServerError, &Error{ Error: "Internal error starting login", ErrCode: "M_UNKNOWN", }) return } else if firstStep.StepID != connector.LoginStepQR || firstStep.Type != bridgev2.LoginStepTypeDisplayAndWait || firstStep.DisplayAndWaitParams.Type != bridgev2.LoginDisplayTypeQR { log.Error().Any("first_step", firstStep).Msg("Unexpected first step") - legacyprovision.JSONResponse(w, http.StatusInternalServerError, &legacyprovision.Error{ + JSONResponse(w, http.StatusInternalServerError, &Error{ Error: "Unexpected first login step", ErrCode: "M_UNKNOWN", }) @@ -93,7 +93,7 @@ func legacyProvLinkNew(w http.ResponseWriter, r *http.Request) { User: user, } loginSessionsLock.Unlock() - legacyprovision.JSONResponse(w, http.StatusOK, legacyprovision.Response{ + JSONResponse(w, http.StatusOK, Response{ Success: true, Status: "provisioning_url_received", SessionID: strconv.Itoa(int(handleID)), @@ -102,10 +102,10 @@ func legacyProvLinkNew(w http.ResponseWriter, r *http.Request) { } func getLoginProcess(w http.ResponseWriter, r *http.Request) *legacyLoginProcess { - var body legacyprovision.LinkWaitForAccountRequest + var body LinkWaitForAccountRequest err := json.NewDecoder(r.Body).Decode(&body) if err != nil { - legacyprovision.JSONResponse(w, http.StatusBadRequest, legacyprovision.Error{ + JSONResponse(w, http.StatusBadRequest, Error{ Success: false, Error: "Error decoding JSON body", ErrCode: mautrix.MBadJSON.ErrCode, @@ -114,7 +114,7 @@ func getLoginProcess(w http.ResponseWriter, r *http.Request) *legacyLoginProcess } sessionID, err := strconv.Atoi(body.SessionID) if err != nil { - legacyprovision.JSONResponse(w, http.StatusBadRequest, legacyprovision.Error{ + JSONResponse(w, http.StatusBadRequest, Error{ Success: false, Error: "Error decoding session ID in JSON body", ErrCode: mautrix.MBadJSON.ErrCode, @@ -124,7 +124,7 @@ func getLoginProcess(w http.ResponseWriter, r *http.Request) *legacyLoginProcess process, ok := loginSessions[uint32(sessionID)] user := m.Matrix.Provisioning.GetUser(r) if !ok || process.User != user { - legacyprovision.JSONResponse(w, http.StatusNotFound, legacyprovision.Error{ + JSONResponse(w, http.StatusNotFound, Error{ Success: false, Error: "No session found", ErrCode: mautrix.MNotFound.ErrCode, @@ -142,7 +142,7 @@ func legacyProvLinkWaitScan(w http.ResponseWriter, r *http.Request) { res, err := login.Login.(bridgev2.LoginProcessDisplayAndWait).Wait(r.Context()) if err != nil { zerolog.Ctx(r.Context()).Err(err).Msg("Failed to log in") - legacyprovision.JSONResponse(w, http.StatusInternalServerError, legacyprovision.Error{ + JSONResponse(w, http.StatusInternalServerError, Error{ Error: "Failed to log in", ErrCode: "M_UNKNOWN", }) @@ -150,14 +150,14 @@ func legacyProvLinkWaitScan(w http.ResponseWriter, r *http.Request) { return } else if res.StepID != connector.LoginStepProcess { zerolog.Ctx(r.Context()).Error().Any("first_step", res).Msg("Unexpected login step") - legacyprovision.JSONResponse(w, http.StatusInternalServerError, legacyprovision.Error{ + JSONResponse(w, http.StatusInternalServerError, Error{ Error: "Unexpected login step", ErrCode: "M_UNKNOWN", }) login.Delete() return } - legacyprovision.JSONResponse(w, http.StatusOK, legacyprovision.Response{ + JSONResponse(w, http.StatusOK, Response{ Success: true, Status: "provisioning_data_received", }) @@ -171,18 +171,18 @@ func legacyProvLinkWaitAccount(w http.ResponseWriter, r *http.Request) { res, err := login.Login.(bridgev2.LoginProcessDisplayAndWait).Wait(r.Context()) if err != nil { zerolog.Ctx(r.Context()).Err(err).Msg("Failed to log in") - legacyprovision.JSONResponse(w, http.StatusInternalServerError, legacyprovision.Error{ + JSONResponse(w, http.StatusInternalServerError, Error{ Error: "Failed to log in", ErrCode: "M_UNKNOWN", }) } else if res.StepID != connector.LoginStepComplete || res.Type != bridgev2.LoginStepTypeComplete { zerolog.Ctx(r.Context()).Error().Any("first_step", res).Msg("Unexpected login step") - legacyprovision.JSONResponse(w, http.StatusInternalServerError, legacyprovision.Error{ + JSONResponse(w, http.StatusInternalServerError, Error{ Error: "Unexpected login step", ErrCode: "M_UNKNOWN", }) } else { - legacyprovision.JSONResponse(w, http.StatusOK, legacyprovision.Response{ + JSONResponse(w, http.StatusOK, Response{ Success: true, Status: "prekeys_registered", UUID: string(res.CompleteParams.UserLogin.ID), @@ -194,7 +194,7 @@ func legacyProvLinkWaitAccount(w http.ResponseWriter, r *http.Request) { func legacyProvLogout(w http.ResponseWriter, r *http.Request) { // No-op for backwards compatibility - legacyprovision.JSONResponse(w, http.StatusOK, nil) + JSONResponse(w, http.StatusOK, nil) } func legacyResolveIdentifierOrStartChat(w http.ResponseWriter, r *http.Request, create bool) { @@ -206,21 +206,21 @@ func legacyResolveIdentifierOrStartChat(w http.ResponseWriter, r *http.Request, resp, err := api.ResolveIdentifier(r.Context(), mux.Vars(r)["phonenum"], create) if err != nil { zerolog.Ctx(r.Context()).Err(err).Msg("Failed to resolve identifier") - legacyprovision.JSONResponse(w, http.StatusInternalServerError, &legacyprovision.Error{ + JSONResponse(w, http.StatusInternalServerError, &Error{ Error: fmt.Sprintf("Failed to resolve identifier: %v", err), ErrCode: "M_UNKNOWN", }) return } else if resp == nil { - legacyprovision.JSONResponse(w, http.StatusNotFound, &legacyprovision.Error{ + JSONResponse(w, http.StatusNotFound, &Error{ ErrCode: mautrix.MNotFound.ErrCode, Error: "User not found on Signal", }) return } status := http.StatusOK - apiResp := &legacyprovision.ResolveIdentifierResponse{ - ChatID: legacyprovision.ResolveIdentifierResponseChatID{ + apiResp := &ResolveIdentifierResponse{ + ChatID: ResolveIdentifierResponseChatID{ UUID: string(resp.UserID), Number: "", }, @@ -229,7 +229,7 @@ func legacyResolveIdentifierOrStartChat(w http.ResponseWriter, r *http.Request, if resp.UserInfo != nil { resp.Ghost.UpdateInfo(r.Context(), resp.UserInfo) } - apiResp.OtherUser = &legacyprovision.ResolveIdentifierResponseOtherUser{ + apiResp.OtherUser = &ResolveIdentifierResponseOtherUser{ MXID: resp.Ghost.Intent.GetMXID(), DisplayName: resp.Ghost.Name, AvatarURL: resp.Ghost.AvatarMXC.ParseOrIgnore(), @@ -240,7 +240,7 @@ func legacyResolveIdentifierOrStartChat(w http.ResponseWriter, r *http.Request, resp.Chat.Portal, err = m.Bridge.GetPortalByKey(r.Context(), resp.Chat.PortalKey) if err != nil { zerolog.Ctx(r.Context()).Err(err).Msg("Failed to get portal") - legacyprovision.JSONResponse(w, http.StatusInternalServerError, &mautrix.RespError{ + JSONResponse(w, http.StatusInternalServerError, &mautrix.RespError{ Err: "Failed to get portal", ErrCode: "M_UNKNOWN", }) @@ -253,7 +253,7 @@ func legacyResolveIdentifierOrStartChat(w http.ResponseWriter, r *http.Request, err = resp.Chat.Portal.CreateMatrixRoom(r.Context(), login, resp.Chat.PortalInfo) if err != nil { zerolog.Ctx(r.Context()).Err(err).Msg("Failed to create portal room") - legacyprovision.JSONResponse(w, http.StatusInternalServerError, &mautrix.RespError{ + JSONResponse(w, http.StatusInternalServerError, &mautrix.RespError{ Err: "Failed to create portal room", ErrCode: "M_UNKNOWN", }) @@ -262,7 +262,7 @@ func legacyResolveIdentifierOrStartChat(w http.ResponseWriter, r *http.Request, } apiResp.RoomID = resp.Chat.Portal.MXID } - legacyprovision.JSONResponse(w, status, &legacyprovision.Response{ + JSONResponse(w, status, &Response{ Success: true, Status: "ok", ResolveIdentifierResponse: apiResp, @@ -276,3 +276,71 @@ func legacyProvResolveIdentifier(w http.ResponseWriter, r *http.Request) { func legacyProvPM(w http.ResponseWriter, r *http.Request) { legacyResolveIdentifierOrStartChat(w, r, true) } + +func JSONResponse(w http.ResponseWriter, status int, response any) { + w.Header().Add("Content-Type", "application/json") + w.WriteHeader(status) + _ = json.NewEncoder(w).Encode(response) +} + +type Error struct { + Success bool `json:"success"` + Error string `json:"error"` + ErrCode string `json:"errcode"` +} + +type Response struct { + Success bool `json:"success"` + Status string `json:"status"` + + // For response in LinkNew + SessionID string `json:"session_id,omitempty"` + URI string `json:"uri,omitempty"` + + // For response in LinkWaitForAccount + UUID string `json:"uuid,omitempty"` + Number string `json:"number,omitempty"` + + // For response in ResolveIdentifier + *ResolveIdentifierResponse +} + +type WhoAmIResponse struct { + Permissions int `json:"permissions"` + MXID string `json:"mxid"` + Signal *WhoAmIResponseSignal `json:"signal,omitempty"` +} + +type WhoAmIResponseSignal struct { + Number string `json:"number"` + UUID string `json:"uuid"` + Name string `json:"name"` + Ok bool `json:"ok"` +} + +type ResolveIdentifierResponse struct { + RoomID id.RoomID `json:"room_id"` + ChatID ResolveIdentifierResponseChatID `json:"chat_id"` + JustCreated bool `json:"just_created"` + OtherUser *ResolveIdentifierResponseOtherUser `json:"other_user,omitempty"` +} + +type ResolveIdentifierResponseChatID struct { + UUID string `json:"uuid"` + Number string `json:"number"` +} + +type ResolveIdentifierResponseOtherUser struct { + MXID id.UserID `json:"mxid"` + DisplayName string `json:"displayname"` + AvatarURL id.ContentURI `json:"avatar_url"` +} + +type LinkWaitForScanRequest struct { + SessionID string `json:"session_id"` +} + +type LinkWaitForAccountRequest struct { + SessionID string `json:"session_id"` + DeviceName string `json:"device_name"` // TODO this seems to not be used anywhere +} diff --git a/cmd/mautrix-signal-v2/main.go b/cmd/mautrix-signal/main.go similarity index 100% rename from cmd/mautrix-signal-v2/main.go rename to cmd/mautrix-signal/main.go diff --git a/commands.go b/commands.go deleted file mode 100644 index 7600d66..0000000 --- a/commands.go +++ /dev/null @@ -1,1161 +0,0 @@ -// mautrix-signal - A Matrix-signal puppeting bridge. -// Copyright (C) 2023 Scott Weber -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see . - -package main - -import ( - "context" - "crypto/sha256" - "encoding/hex" - "errors" - "fmt" - "strconv" - "strings" - - "github.com/google/uuid" - "github.com/rs/zerolog" - "github.com/skip2/go-qrcode" - "maunium.net/go/mautrix" - "maunium.net/go/mautrix/bridge/commands" - "maunium.net/go/mautrix/event" - "maunium.net/go/mautrix/id" - - "go.mau.fi/mautrix-signal/pkg/libsignalgo" - "go.mau.fi/mautrix-signal/pkg/signalmeow" - "go.mau.fi/mautrix-signal/pkg/signalmeow/types" -) - -var ( - HelpSectionConnectionManagement = commands.HelpSection{Name: "Connection management", Order: 11} - HelpSectionCreatingPortals = commands.HelpSection{Name: "Creating portals", Order: 15} - HelpSectionPortalManagement = commands.HelpSection{Name: "Portal management", Order: 20} - HelpSectionInvites = commands.HelpSection{Name: "Group invites", Order: 25} - HelpSectionMiscellaneous = commands.HelpSection{Name: "Miscellaneous", Order: 30} -) - -type WrappedCommandEvent struct { - *commands.Event - Bridge *SignalBridge - User *User - Portal *Portal -} - -func (br *SignalBridge) RegisterCommands() { - proc := br.CommandProcessor.(*commands.Processor) - proc.AddHandlers( - cmdPing, - cmdLogin, - cmdSetDeviceName, - cmdPM, - cmdResolvePhone, - cmdSync, - cmdDeleteSession, - cmdSetRelay, - cmdUnsetRelay, - cmdDeletePortal, - cmdDeleteAllPortals, - cmdCleanupLostPortals, - cmdInviteLink, - cmdResetInviteLink, - cmdCreate, - cmdInvite, - cmdListInvited, - cmdRevokeInvite, - ) -} - -func wrapCommand(handler func(*WrappedCommandEvent)) func(*commands.Event) { - return func(ce *commands.Event) { - user := ce.User.(*User) - var portal *Portal - if ce.Portal != nil { - portal = ce.Portal.(*Portal) - } - br := ce.Bridge.Child.(*SignalBridge) - handler(&WrappedCommandEvent{ce, br, user, portal}) - } -} - -var cmdSetRelay = &commands.FullHandler{ - Func: wrapCommand(fnSetRelay), - Name: "set-relay", - Help: commands.HelpMeta{ - Section: HelpSectionPortalManagement, - Description: "Relay messages in this room through your Signal account.", - }, - RequiresPortal: true, - RequiresLogin: true, -} - -func fnSetRelay(ce *WrappedCommandEvent) { - if !ce.Bridge.Config.Bridge.Relay.Enabled { - ce.Reply("Relay mode is not enabled on this instance of the bridge") - } else if ce.Bridge.Config.Bridge.Relay.AdminOnly && !ce.User.Admin { - ce.Reply("Only bridge admins are allowed to enable relay mode on this instance of the bridge") - } else { - ce.Portal.RelayUserID = ce.User.MXID - ce.Portal.Update(ce.Ctx) - ce.Reply("Messages from non-logged-in users in this room will now be bridged through your Signal account") - } -} - -var cmdUnsetRelay = &commands.FullHandler{ - Func: wrapCommand(fnUnsetRelay), - Name: "unset-relay", - Help: commands.HelpMeta{ - Section: HelpSectionPortalManagement, - Description: "Stop relaying messages in this room.", - }, - RequiresPortal: true, -} - -func fnUnsetRelay(ce *WrappedCommandEvent) { - if !ce.Bridge.Config.Bridge.Relay.Enabled { - ce.Reply("Relay mode is not enabled on this instance of the bridge") - } else if ce.Bridge.Config.Bridge.Relay.AdminOnly && !ce.User.Admin { - ce.Reply("Only bridge admins are allowed to enable relay mode on this instance of the bridge") - } else { - ce.Portal.RelayUserID = "" - ce.Portal.Update(ce.Ctx) - ce.Reply("Messages from non-logged-in users will no longer be bridged in this room") - } -} - -var cmdDeleteSession = &commands.FullHandler{ - Func: wrapCommand(fnDeleteSession), - Name: "delete-session", - Help: commands.HelpMeta{ - Section: HelpSectionConnectionManagement, - Description: "Disconnect from Signal, clearing sessions but keeping other data. Reconnect with `login`", - }, -} - -func fnDeleteSession(ce *WrappedCommandEvent) { - if !ce.User.IsLoggedIn() { - ce.Reply("You're not logged in") - return - } - ce.User.Client.ClearKeysAndDisconnect(ce.Ctx) - ce.Reply("Disconnected from Signal") -} - -var cmdPing = &commands.FullHandler{ - Func: wrapCommand(fnPing), - Name: "ping", - Help: commands.HelpMeta{ - Section: commands.HelpSectionAuth, - Description: "Check your connection to Signal", - }, -} - -func fnPing(ce *WrappedCommandEvent) { - if ce.User.SignalID == uuid.Nil { - ce.Reply("You're not logged in") - } else if !ce.User.IsLoggedIn() { - ce.Reply("You were logged in at some point, but are not anymore") - } else if !ce.User.Client.IsConnected() { - ce.Reply("You're logged into Signal, but not connected to the server") - } else { - ce.Reply("You're logged into Signal and probably connected to the server") - } -} - -var cmdSetDeviceName = &commands.FullHandler{ - Func: wrapCommand(fnSetDeviceName), - Name: "set-device-name", - Help: commands.HelpMeta{ - Section: HelpSectionConnectionManagement, - Description: "Set the name of this device in Signal", - Args: "", - }, - RequiresLogin: true, -} - -func fnSetDeviceName(ce *WrappedCommandEvent) { - if len(ce.Args) == 0 { - ce.Reply("**Usage:** `set-device-name `") - return - } - - name := strings.Join(ce.Args, " ") - err := ce.User.Client.UpdateDeviceName(ce.Ctx, name) - if err != nil { - ce.Reply("Error setting device name: %v", err) - return - } - ce.Reply("Device name updated") -} - -var cmdPM = &commands.FullHandler{ - Func: wrapCommand(fnPM), - Name: "pm", - Help: commands.HelpMeta{ - Section: HelpSectionCreatingPortals, - Description: "Open a private chat with the given phone number.", - Args: "<_international phone number_>", - }, - RequiresLogin: true, -} - -var numberCleaner = strings.NewReplacer("-", "", " ", "", "(", "", ")", "", "+", "") - -func fnPM(ce *WrappedCommandEvent) { - if len(ce.Args) == 0 { - ce.Reply("**Usage:** `pm `") - return - } - number, err := strconv.ParseUint(numberCleaner.Replace(strings.Join(ce.Args, "")), 10, 64) - if err != nil { - ce.Reply("Failed to parse number") - return - } - - user := ce.User - var aci, pni uuid.UUID - e164 := fmt.Sprintf("+%d", number) - var recipient *types.Recipient - - if recipient, err = user.Client.ContactByE164(ce.Ctx, e164); err != nil { - ce.Reply("Error looking up number in local contact list: %v", err) - return - } else if recipient != nil && (recipient.ACI != uuid.Nil || recipient.PNI != uuid.Nil) { - // TODO maybe lookup PNI if there's only ACI and E164 stored? - aci = recipient.ACI - pni = recipient.PNI - } else if resp, err := user.Client.LookupPhone(ce.Ctx, number); err != nil { - ce.ZLog.Err(err).Uint64("e164", number).Msg("Failed to lookup number on server") - ce.Reply("Error looking up number on server: %v", err) - return - } else { - aci = resp[number].ACI - pni = resp[number].PNI - if aci == uuid.Nil && pni == uuid.Nil { - ce.Reply("+%d doesn't seem to be on Signal", number) - return - } - recipient, err = user.Client.Store.RecipientStore.UpdateRecipientE164(ce.Ctx, aci, pni, e164) - if err != nil { - ce.ZLog.Err(err).Msg("Failed to save recipient entry after looking up phone") - } - aci, pni = recipient.ACI, recipient.PNI - } - ce.ZLog.Debug(). - Uint64("e164", number). - Stringer("aci", aci). - Stringer("pni", pni). - Msg("Found DM target user") - - var targetServiceID libsignalgo.ServiceID - if aci != uuid.Nil { - targetServiceID = libsignalgo.NewACIServiceID(aci) - } else { - targetServiceID = libsignalgo.NewPNIServiceID(pni) - } - portal := user.GetPortalByChatID(targetServiceID.String()) - if portal == nil { - ce.Reply("Couldn't get portal with %s/+%d", targetServiceID, number) - return - } else if portal.MXID != "" { - ok := portal.ensureUserInvited(ce.Ctx, ce.User) - if ok { - ce.Reply("You already have a portal with +%d at [%s](%s)", number, portal.MXID, portal.MXID.URI(portal.bridge.Config.Homeserver.Domain).MatrixToURL()) - return - } - ce.ZLog.Warn().Stringer("existing_room_id", portal.MXID).Msg("Ensuring user is invited to existing room failed, creating new room") - portal.Cleanup(ce.Ctx, false) - portal.MXID = "" - } - - if err = portal.CreateMatrixRoom(ce.Ctx, user, 0); err != nil { - ce.ZLog.Err(err).Msg("Failed to create portal room") - ce.Reply("Error creating Matrix room for portal to +%d", number) - } else { - ce.Reply("Created portal room [%s](%s) with +%d and invited you to it.", portal.MXID, portal.MXID.URI(portal.bridge.Config.Homeserver.Domain).MatrixToURL(), number) - } -} - -var cmdInvite = &commands.FullHandler{ - Func: wrapCommand(fnInvite), - Name: "invite", - Help: commands.HelpMeta{ - Section: HelpSectionPortalManagement, - Description: "Invite a user by phone number.", - Args: "<_international phone number_>", - }, - RequiresLogin: true, - RequiresPortal: true, -} - -func fnInvite(ce *WrappedCommandEvent) { - if len(ce.Args) == 0 { - ce.Reply("**Usage:** `invite `") - return - } - number, err := strconv.ParseUint(numberCleaner.Replace(strings.Join(ce.Args, "")), 10, 64) - if err != nil { - ce.Reply("Failed to parse number") - return - } - - user := ce.User - var aci, pni uuid.UUID - e164 := fmt.Sprintf("+%d", number) - var recipient *types.Recipient - - if recipient, err = user.Client.ContactByE164(ce.Ctx, e164); err != nil { - ce.Reply("Error looking up number in local contact list: %v", err) - return - } else if recipient != nil && (recipient.ACI != uuid.Nil || recipient.PNI != uuid.Nil) { - // TODO maybe lookup PNI if there's only ACI and E164 stored? - aci = recipient.ACI - pni = recipient.PNI - } else if resp, err := user.Client.LookupPhone(ce.Ctx, number); err != nil { - ce.ZLog.Err(err).Uint64("e164", number).Msg("Failed to lookup number on server") - ce.Reply("Error looking up number on server: %v", err) - return - } else { - aci = resp[number].ACI - pni = resp[number].PNI - if aci == uuid.Nil && pni == uuid.Nil { - ce.Reply("+%d doesn't seem to be on Signal", number) - return - } - recipient, err = user.Client.Store.RecipientStore.UpdateRecipientE164(ce.Ctx, aci, pni, e164) - if err != nil { - ce.ZLog.Err(err).Msg("Failed to save recipient entry after looking up phone") - } - aci, pni = recipient.ACI, recipient.PNI - } - ce.ZLog.Debug(). - Uint64("e164", number). - Stringer("aci", aci). - Stringer("pni", pni). - Msg("Found Invite target user") - - var groupChange signalmeow.GroupChange - if aci != uuid.Nil { - groupChange.AddMembers = []*signalmeow.AddMember{ - { - GroupMember: signalmeow.GroupMember{ - ACI: aci, - Role: signalmeow.GroupMember_DEFAULT, - }, - }, - } - } else { - groupChange.AddPendingMembers = []*signalmeow.PendingMember{ - { - ServiceID: libsignalgo.NewPNIServiceID(pni), - AddedByUserID: ce.User.SignalID, - Role: signalmeow.GroupMember_DEFAULT, - }, - } - } - revision, err := ce.User.Client.UpdateGroup(ce.Ctx, &groupChange, ce.Portal.GroupID()) - if err != nil { - ce.Reply("Failed to update group: %w", err) - return - } - ce.Portal.Revision = revision - if aci != uuid.Nil { - group, err := ce.User.Client.RetrieveGroupByID(ce.Ctx, ce.Portal.GroupID(), revision) - if err != nil { - ce.Reply("Failed to fetch group after invite: %w", err) - } - ce.Portal.SyncParticipants(ce.Ctx, user, group) - ce.Portal.Update(ce.Ctx) - return - } - ce.Portal.Update(ce.Ctx) - ce.Reply("Invited " + e164) -} - -var cmdListInvited = &commands.FullHandler{ - Func: wrapCommand(fnListInvited), - Name: "list-invited", - Help: commands.HelpMeta{ - Section: HelpSectionPortalManagement, - Description: "list pending invites", - Args: "<_international phone number_>", - }, - RequiresLogin: true, - RequiresPortal: true, -} - -func fnListInvited(ce *WrappedCommandEvent) { - group, err := ce.User.Client.RetrieveGroupByID(ce.Ctx, ce.Portal.GroupID(), ce.Portal.Revision) - if err != nil { - ce.Reply("Failed to fetch group info: %w", err) - return - } - var memberList []string - for _, pendingMember := range group.PendingMembers { - recipientString, err := pendingMemberToString(ce.Ctx, ce.User, pendingMember) - if err != nil { - ce.Reply("Failed to fetch recipient for %s: %w", pendingMember.ServiceID, err) - continue - } - memberList = append(memberList, recipientString) - } - if len(memberList) == 0 { - ce.Reply("No pending Invites") - } else { - ce.Reply(strings.Join(memberList, "\n")) - } -} - -func pendingMemberToString(ctx context.Context, user *User, pendingMember *signalmeow.PendingMember) (string, error) { - var pni, aci uuid.UUID - if pendingMember.ServiceID.Type == libsignalgo.ServiceIDTypeACI { - aci = pendingMember.ServiceID.UUID - } else { - pni = pendingMember.ServiceID.UUID - } - recipient, err := user.Client.Store.RecipientStore.LoadAndUpdateRecipient(ctx, aci, pni, nil) - if err != nil { - return "", err - } - if recipient.E164 != "" { - return recipient.E164, nil - } else { - return "Unidentified User", nil - } -} - -var cmdRevokeInvite = &commands.FullHandler{ - Func: wrapCommand(fnRevokeInvite), - Name: "revoke-invite", - Help: commands.HelpMeta{ - Section: HelpSectionPortalManagement, - Description: "Revoke an invite by phone number.", - Args: "<_international phone number_>", - }, - RequiresLogin: true, - RequiresPortal: true, -} - -func fnRevokeInvite(ce *WrappedCommandEvent) { - if len(ce.Args) == 0 { - ce.Reply("**Usage:** `RevokeInvite `") - return - } - e164 := "+" + numberCleaner.Replace(strings.Join(ce.Args, "")) - - user := ce.User - var serviceID libsignalgo.ServiceID - group, err := ce.User.Client.RetrieveGroupByID(ce.Ctx, ce.Portal.GroupID(), ce.Portal.Revision) - if err != nil { - ce.Reply("Failed to fetch group info: %w", err) - return - } - var pni, aci uuid.UUID - for _, pendingMember := range group.PendingMembers { - if pendingMember.ServiceID.Type == libsignalgo.ServiceIDTypeACI { - aci = pendingMember.ServiceID.UUID - } else { - pni = pendingMember.ServiceID.UUID - } - recipient, err := user.Client.Store.RecipientStore.LoadAndUpdateRecipient(ce.Ctx, aci, pni, nil) - if err != nil { - continue - } - if recipient.E164 == e164 { - serviceID = pendingMember.ServiceID - break - } - } - if serviceID.UUID == uuid.Nil { - ce.Reply("User not in Group") - return - } - var groupChange signalmeow.GroupChange - groupChange.DeletePendingMembers = []*libsignalgo.ServiceID{&serviceID} - revision, err := ce.User.Client.UpdateGroup(ce.Ctx, &groupChange, ce.Portal.GroupID()) - if err != nil { - ce.Reply("Failed to update group: %w", err) - return - } - if aci != uuid.Nil { - target := ce.Bridge.GetPuppetBySignalID(aci) - if target != nil { - ce.Bot.SendCustomMembershipEvent(ce.Ctx, ce.Portal.MXID, target.IntentFor(ce.Portal).UserID, event.MembershipLeave, "removed by "+user.MXID.String()) - } - } - ce.Portal.Revision = revision - ce.Portal.Update(ce.Ctx) - ce.Reply("Revoked the invitation for " + e164) -} - -var cmdResolvePhone = &commands.FullHandler{ - Func: wrapCommand(fnResolvePhone), - Name: "resolve-phone", - Help: commands.HelpMeta{ - Section: HelpSectionCreatingPortals, - Description: "Look up phone numbers on the Signal servers.", - Args: "", - }, - RequiresLogin: true, -} - -func fnResolvePhone(ce *WrappedCommandEvent) { - numbers := make([]uint64, len(ce.Args)) - for i, arg := range ce.Args { - var err error - numbers[i], err = strconv.ParseUint(numberCleaner.Replace(arg), 10, 64) - if err != nil { - ce.Reply("Failed to parse number %s: %v", arg, err) - return - } - } - resp, err := ce.User.Client.LookupPhone(ce.Ctx, numbers...) - if err != nil { - ce.Reply("Failed to look up: %v", err) - } else { - var out strings.Builder - for _, phone := range numbers { - result, found := resp[phone] - if found { - _, _ = fmt.Fprintf(&out, "+%d: %s / %s\n", phone, result.ACI, result.PNI) - } else { - _, _ = fmt.Fprintf(&out, "+%d: not found\n", phone) - } - } - ce.Reply(strings.TrimSpace(out.String())) - } -} - -var cmdSync = &commands.FullHandler{ - Func: wrapCommand(fnSync), - Name: "sync", - Help: commands.HelpMeta{ - Section: HelpSectionMiscellaneous, - Description: "Synchronize Signal bridge data", - Args: "", - }, - RequiresLogin: true, -} - -func fnSync(ce *WrappedCommandEvent) { - args := strings.ToLower(strings.Join(ce.Args, " ")) - space := strings.Contains(args, "space") - groups := strings.Contains(args, "groups") - if !space && !groups { - ce.Reply("**Usage:** `sync `") - return - } - if !ce.Bridge.Config.Bridge.PersonalFilteringSpaces && space { - ce.Reply("Personal filtering spaces are not enabled on this instance of the bridge") - return - } - ctx := ce.Ctx - dmKeys, err := ce.Bridge.DB.Portal.FindPrivateChatsNotInSpace(ctx, ce.User.SignalID) - if err != nil { - ce.ZLog.Err(err).Msg("Failed to get private chat keys") - ce.Reply("Failed to get private chat IDs from database") - return - } - allPortals := ce.Bridge.GetAllPortalsWithMXID() - if space { - count := 0 - for _, portal := range allPortals { - if portal.IsPrivateChat() { - continue - } - if ce.Bridge.StateStore.IsInRoom(ctx, portal.MXID, ce.User.MXID) && portal.addToPersonalSpace(ctx, ce.User) { - count++ - } - } - for _, key := range dmKeys { - portal := ce.Bridge.GetPortalByChatID(key) - portal.addToPersonalSpace(ctx, ce.User) - count++ - } - plural := "s" - if count == 1 { - plural = "" - } - ce.Reply("Added %d room%s to space", count, plural) - } - if groups { - count := 0 - for _, portal := range allPortals { - if portal.IsPrivateChat() { - continue - } - if ce.Bridge.StateStore.IsInRoom(ctx, portal.MXID, ce.User.MXID) { - groupInfo := portal.UpdateGroupInfo(ce.Ctx, ce.User, nil, 0, true) - if groupInfo != nil { - members := portal.SyncParticipants(ctx, ce.User, groupInfo) - portal.updatePowerLevelsAndJoinRule(ctx, groupInfo, members) - count++ - } - } - } - plural := "s" - if count == 1 { - plural = "" - } - ce.Reply("Synced %d group%s", count, plural) - } -} - -var cmdLogin = &commands.FullHandler{ - Func: wrapCommand(fnLogin), - Name: "login", - Help: commands.HelpMeta{ - Section: commands.HelpSectionAuth, - Description: "Link the bridge to your Signal account as a web client.", - }, -} - -func fnLogin(ce *WrappedCommandEvent) { - if ce.User.IsLoggedIn() { - if ce.User.Client.IsConnected() { - ce.Reply("You're already logged in") - } else { - ce.Reply("You're already logged in, but not connected 🤔") - } - return - } - - var qrEventID, msgEventID id.EventID - var signalID uuid.UUID - var signalPhone string - - // First get the provisioning URL - provChan, err := ce.User.Login() - if err != nil { - ce.ZLog.Err(err).Msg("Failure logging in") - ce.Reply("Failure logging in: %v", err) - return - } - - resp := <-provChan - if resp.Err != nil || resp.State == signalmeow.StateProvisioningError { - ce.Reply("Error getting provisioning URL: %v", resp.Err) - return - } - if resp.State == signalmeow.StateProvisioningURLReceived { - qrEventID, msgEventID = ce.User.sendQR(ce, resp.ProvisioningURL, qrEventID, msgEventID) - } else { - ce.Reply("Unexpected state: %v", resp.State) - return - } - - // Next, get the results of finishing registration - resp = <-provChan - _, _ = ce.Bot.RedactEvent(ce.Ctx, ce.RoomID, qrEventID) - _, _ = ce.Bot.RedactEvent(ce.Ctx, ce.RoomID, msgEventID) - if resp.Err != nil || resp.State == signalmeow.StateProvisioningError { - if resp.Err != nil && strings.HasSuffix(resp.Err.Error(), " EOF") { - ce.Reply("Logging in timed out, please try again.") - } else { - ce.Reply("Error finishing registration: %v", resp.Err) - } - return - } - if resp.State == signalmeow.StateProvisioningDataReceived { - signalID = resp.ProvisioningData.ACI - signalPhone = resp.ProvisioningData.Number - } else { - ce.Reply("Unexpected state: %v", resp.State) - return - } - - // Finally, get the results of generating and registering prekeys - resp = <-provChan - if resp.Err != nil || resp.State == signalmeow.StateProvisioningError { - ce.Reply("Error with prekeys: %v", resp.Err) - return - } else if resp.State != signalmeow.StateProvisioningPreKeysRegistered { - ce.Reply("Unexpected state: %v", resp.State) - return - } - - if signalID == uuid.Nil { - ce.Reply("Problem logging in - No SignalID received") - return - } - ce.User.saveSignalID(ce.Ctx, signalID, signalPhone) - - // Connect to Signal - ce.User.Connect() - ce.Reply("Successfully logged in as %s (UUID: %s)", ce.User.SignalUsername, ce.User.SignalID) -} - -func (user *User) sendQR(ce *WrappedCommandEvent, code string, prevQR, prevMsg id.EventID) (qr, msg id.EventID) { - content, ok := user.uploadQR(ce, code) - if !ok { - return prevQR, prevMsg - } - if len(prevQR) != 0 { - content.SetEdit(prevQR) - } - resp, err := ce.Bot.SendMessageEvent(ce.Ctx, ce.RoomID, event.EventMessage, &content) - if err != nil { - ce.ZLog.Err(err).Msg("Failed to send QR code to user") - } else if len(prevQR) == 0 { - prevQR = resp.EventID - } - content = event.MessageEventContent{ - MsgType: event.MsgNotice, - Body: fmt.Sprintf("Raw linking URI: %s", code), - Format: event.FormatHTML, - FormattedBody: fmt.Sprintf("Raw linking URI: %s", code), - } - if len(prevMsg) != 0 { - content.SetEdit(prevMsg) - } - resp, err = ce.Bot.SendMessageEvent(ce.Ctx, ce.RoomID, event.EventMessage, &content) - if err != nil { - ce.ZLog.Err(err).Msg("Failed to send raw code to user") - } else if len(prevMsg) == 0 { - prevMsg = resp.EventID - } - return prevQR, prevMsg -} - -func (user *User) uploadQR(ce *WrappedCommandEvent, code string) (event.MessageEventContent, bool) { - const size = 512 - qrCode, err := qrcode.Encode(code, qrcode.Low, size) - if err != nil { - ce.ZLog.Err(err).Msg("Failed to encode QR code") - ce.Reply("Failed to encode QR code: %v", err) - return event.MessageEventContent{}, false - } - - bot := user.bridge.AS.BotClient() - - resp, err := bot.UploadBytes(ce.Ctx, qrCode, "image/png") - if err != nil { - ce.ZLog.Err(err).Msg("Failed to upload QR code") - ce.Reply("Failed to upload QR code: %v", err) - return event.MessageEventContent{}, false - } - return event.MessageEventContent{ - MsgType: event.MsgImage, - Info: &event.FileInfo{ - MimeType: "image/png", - Width: size, - Height: size, - Size: len(qrCode), - }, - Body: "qr.png", - URL: resp.ContentURI.CUString(), - }, true -} - -func canDeletePortal(ctx context.Context, portal *Portal, userID id.UserID) bool { - if len(portal.MXID) == 0 { - return false - } - - members, err := portal.MainIntent().JoinedMembers(ctx, portal.MXID) - if err != nil { - portal.log.Err(err). - Stringer("user_id", userID). - Msg("Failed to get joined members to check if user can delete portal") - return false - } - for otherUser := range members.Joined { - _, isPuppet := portal.bridge.ParsePuppetMXID(otherUser) - if isPuppet || otherUser == portal.bridge.Bot.UserID || otherUser == userID { - continue - } - user := portal.bridge.GetUserByMXID(otherUser) - if user != nil && user.IsLoggedIn() { - return false - } - } - return true -} - -var cmdDeletePortal = &commands.FullHandler{ - Func: wrapCommand(fnDeletePortal), - Name: "delete-portal", - Help: commands.HelpMeta{ - Section: HelpSectionPortalManagement, - Description: "Delete the current portal. If the portal is used by other people, this is limited to bridge admins.", - }, - RequiresPortal: true, -} - -func fnDeletePortal(ce *WrappedCommandEvent) { - if !ce.User.Admin && !canDeletePortal(ce.Ctx, ce.Portal, ce.User.MXID) { - ce.Reply("Only bridge admins can delete portals with other Matrix users") - return - } - - ce.Portal.log.Info().Stringer("user_id", ce.User.MXID).Msg("User requested deletion of portal") - ce.Portal.Delete() - ce.Portal.Cleanup(ce.Ctx, false) -} - -var cmdDeleteAllPortals = &commands.FullHandler{ - Func: wrapCommand(fnDeleteAllPortals), - Name: "delete-all-portals", - Help: commands.HelpMeta{ - Section: HelpSectionPortalManagement, - Description: "Delete all portals.", - }, -} - -func fnDeleteAllPortals(ce *WrappedCommandEvent) { - portals := ce.Bridge.GetAllPortalsWithMXID() - var portalsToDelete []*Portal - - if ce.User.Admin { - portalsToDelete = portals - } else { - portalsToDelete = portals[:0] - for _, portal := range portals { - if canDeletePortal(ce.Ctx, portal, ce.User.MXID) { - portalsToDelete = append(portalsToDelete, portal) - } - } - } - if len(portalsToDelete) == 0 { - ce.Reply("Didn't find any portals to delete") - return - } - - leave := func(portal *Portal) { - if len(portal.MXID) > 0 { - _, _ = portal.MainIntent().KickUser(ce.Ctx, portal.MXID, &mautrix.ReqKickUser{ - Reason: "Deleting portal", - UserID: ce.User.MXID, - }) - } - } - customPuppet := ce.Bridge.GetPuppetByCustomMXID(ce.User.MXID) - if customPuppet != nil && customPuppet.CustomIntent() != nil { - intent := customPuppet.CustomIntent() - leave = func(portal *Portal) { - if len(portal.MXID) > 0 { - _, _ = intent.LeaveRoom(ce.Ctx, portal.MXID) - _, _ = intent.ForgetRoom(ce.Ctx, portal.MXID) - } - } - } - ce.Reply("Found %d portals, deleting...", len(portalsToDelete)) - for _, portal := range portalsToDelete { - portal.Delete() - leave(portal) - } - ce.Reply("Finished deleting portal info. Now cleaning up rooms in background.") - - backgroundCtx := context.TODO() - go func() { - for _, portal := range portalsToDelete { - portal.Cleanup(backgroundCtx, false) - } - ce.Reply("Finished background cleanup of deleted portal rooms.") - }() -} - -var cmdCleanupLostPortals = &commands.FullHandler{ - Func: wrapCommand(fnCleanupLostPortals), - Name: "cleanup-lost-portals", - Help: commands.HelpMeta{ - Section: HelpSectionPortalManagement, - Description: "Clean up portals that were discarded due to the receiver not being logged into the bridge", - }, - RequiresAdmin: true, -} - -func fnCleanupLostPortals(ce *WrappedCommandEvent) { - portals, err := ce.Bridge.DB.LostPortal.GetAll(ce.Ctx) - if err != nil { - ce.Reply("Failed to get portals: %v", err) - return - } else if len(portals) == 0 { - ce.Reply("No lost portals found") - return - } - - ce.Reply("Found %d lost portals, deleting...", len(portals)) - for _, portal := range portals { - dmUUID, err := uuid.Parse(portal.ChatID) - intent := ce.Bot - if err == nil { - intent = ce.Bridge.GetPuppetBySignalID(dmUUID).DefaultIntent() - } - ce.Bridge.CleanupRoom(ce.Ctx, ce.ZLog, intent, portal.MXID, false) - err = portal.Delete(ce.Ctx) - if err != nil { - ce.ZLog.Err(err).Msg("Failed to delete lost portal from database after cleanup") - } - } - ce.Reply("Finished cleaning up portals") -} - -var cmdInviteLink = &commands.FullHandler{ - Func: wrapCommand(fnInviteLink), - Name: "invite-link", - Help: commands.HelpMeta{ - Section: HelpSectionPortalManagement, - Description: "Get the invite link for the corresponding Signal Group", - }, - RequiresLogin: true, -} - -func fnInviteLink(ce *WrappedCommandEvent) { - if ce.Portal == nil { - ce.Reply("This is not a portal room") - return - } - if ce.Portal.IsPrivateChat() { - ce.Reply("Invite Links are not available for private chats") - return - } - inviteLinkPassword, err := ce.Portal.GetInviteLink(ce.Ctx, ce.User) - if err != nil { - ce.Reply("Error getting invite link %w", err) - return - } - ce.Reply(inviteLinkPassword) -} - -var cmdResetInviteLink = &commands.FullHandler{ - Func: wrapCommand(fnResetInviteLink), - Name: "reset-invite-link", - Help: commands.HelpMeta{ - Section: HelpSectionPortalManagement, - Description: "Generate a new invite link password", - }, - RequiresLogin: true, -} - -func fnResetInviteLink(ce *WrappedCommandEvent) { - if ce.Portal == nil { - ce.Reply("This is not a portal room") - return - } - if ce.Portal.IsPrivateChat() { - ce.Reply("Invite Links are not available for private chats") - return - } - err := ce.Portal.ResetInviteLink(ce.Ctx, ce.User) - if err != nil { - ce.Reply("Error setting new invite link %w", err) - } - inviteLink, err := ce.Portal.GetInviteLink(ce.Ctx, ce.User) - if err != nil { - ce.Reply("Error getting new invite link %w", err) - return - } - ce.Reply(inviteLink) -} - -var cmdCreate = &commands.FullHandler{ - Func: wrapCommand(fnCreate), - Name: "create", - Help: commands.HelpMeta{ - Section: HelpSectionCreatingPortals, - Description: "Create a Signal group chat for the current Matrix room.", - }, - RequiresLogin: true, -} - -func fnCreate(ce *WrappedCommandEvent) { - if ce.Portal != nil { - ce.Reply("This is already a portal room") - return - } - - roomState, err := ce.Bot.State(ce.Ctx, ce.RoomID) - if err != nil { - ce.Reply("Failed to get room state: %w", err) - return - } - members := roomState[event.StateMember] - powerLevelsRaw, ok := roomState[event.StatePowerLevels][""] - if !ok { - ce.Reply("Failed to get room power levels") - return - } - powerLevelsRaw.Content.ParseRaw(event.StatePowerLevels) - powerLevels := powerLevelsRaw.Content.AsPowerLevels() - joinRulesRaw, ok := roomState[event.StateJoinRules][""] - if !ok { - ce.Reply("Failed to get join rules") - return - } - joinRulesRaw.Content.ParseRaw(event.StateJoinRules) - joinRule := joinRulesRaw.Content.AsJoinRules().JoinRule - roomNameEventRaw, ok := roomState[event.StateRoomName][""] - if !ok { - ce.Reply("Failed to get room name") - return - } - roomNameEventRaw.Content.ParseRaw(event.StateRoomName) - roomName := roomNameEventRaw.Content.AsRoomName().Name - if len(roomName) == 0 { - ce.Reply("Please set a name for the room first") - return - } - roomTopic := "" - roomTopicEvent, ok := roomState[event.StateTopic][""] - if ok { - roomTopicEvent.Content.ParseRaw(event.StateTopic) - roomTopic = roomTopicEvent.Content.AsTopic().Topic - } - roomAvatarEvent, ok := roomState[event.StateRoomAvatar][""] - var avatarHash string - var avatarURL id.ContentURI - var avatarBytes []byte - avatarSet := false - if ok { - roomAvatarEvent.Content.ParseRaw(event.StateRoomAvatar) - avatarURL = roomAvatarEvent.Content.AsRoomAvatar().URL.ParseOrIgnore() - if !avatarURL.IsEmpty() { - avatarBytes, err = ce.Bot.DownloadBytes(ce.Ctx, avatarURL) - if err != nil { - ce.ZLog.Err(err).Stringer("Failed to download updated avatar %s", avatarURL) - return - } - hash := sha256.Sum256(avatarBytes) - avatarHash = hex.EncodeToString(hash[:]) - ce.ZLog.Debug().Stringers("%s set the group avatar to %s", []fmt.Stringer{ce.User.MXID, avatarURL}) - avatarSet = true - } - } - var encryptionEvent *event.EncryptionEventContent - encryptionEventContent, ok := roomState[event.StateEncryption][""] - if ok { - encryptionEventContent.Content.ParseRaw(event.StateEncryption) - encryptionEvent = encryptionEventContent.Content.AsEncryption() - } - var participants []*signalmeow.GroupMember - var bannedMembers []*signalmeow.BannedMember - participantDedup := make(map[uuid.UUID]bool) - participantDedup[uuid.Nil] = true - for key, member := range members { - mxid := id.UserID(key) - member.Content.ParseRaw(event.StateMember) - content := member.Content.AsMember() - membership := content.Membership - var uuid uuid.UUID - puppet := ce.Bridge.GetPuppetByMXID(mxid) - if puppet != nil { - uuid = puppet.SignalID - } else { - user := ce.Bridge.GetUserByMXID(mxid) - if user != nil && user.IsLoggedIn() { - uuid = user.SignalID - } - } - role := signalmeow.GroupMember_DEFAULT - if powerLevels.GetUserLevel(mxid) >= 50 { - role = signalmeow.GroupMember_ADMINISTRATOR - } - if !participantDedup[uuid] { - participantDedup[uuid] = true - // invites should be added on signal and then auto-joined - // joined members that need to be pending-Members should have their signal invite auto-accepted - if membership == event.MembershipJoin || membership == event.MembershipInvite { - participants = append(participants, &signalmeow.GroupMember{ - ACI: uuid, - Role: role, - }) - } else if membership == event.MembershipBan { - bannedMembers = append(bannedMembers, &signalmeow.BannedMember{ - ServiceID: libsignalgo.NewACIServiceID(uuid), - }) - } - } - } - addFromInviteLinkAccess := signalmeow.AccessControl_UNSATISFIABLE - if joinRule == event.JoinRulePublic { - addFromInviteLinkAccess = signalmeow.AccessControl_ANY - } else if joinRule == event.JoinRuleKnock { - addFromInviteLinkAccess = signalmeow.AccessControl_ADMINISTRATOR - } - var inviteLinkPassword types.SerializedInviteLinkPassword - if addFromInviteLinkAccess != signalmeow.AccessControl_UNSATISFIABLE { - inviteLinkPassword = signalmeow.GenerateInviteLinkPassword() - } - membersAccess := signalmeow.AccessControl_MEMBER - if powerLevels.Invite() >= 50 { - membersAccess = signalmeow.AccessControl_ADMINISTRATOR - } - attributesAccess := signalmeow.AccessControl_MEMBER - if powerLevels.StateDefault() >= 50 { - attributesAccess = signalmeow.AccessControl_ADMINISTRATOR - } - announcementsOnly := false - if powerLevels.EventsDefault >= 50 { - announcementsOnly = true - } - ce.ZLog.Info(). - Str("room_name", roomName). - Any("participants", participants). - Msg("Creating Signal group for Matrix room") - group, err := ce.User.Client.CreateGroup(ce.Ctx, &signalmeow.Group{ - Title: roomName, - Description: roomTopic, - Members: participants, - AccessControl: &signalmeow.GroupAccessControl{ - Members: membersAccess, - Attributes: attributesAccess, - AddFromInviteLink: addFromInviteLinkAccess, - }, - InviteLinkPassword: &inviteLinkPassword, - BannedMembers: bannedMembers, - AnnouncementsOnly: announcementsOnly, - }, avatarBytes) - if err != nil { - ce.Reply("Failed to create group: %v", err) - return - } - gid := group.GroupIdentifier - ce.ZLog.UpdateContext(func(c zerolog.Context) zerolog.Context { - return c.Stringer("group_id", gid) - }) - portal := ce.User.GetPortalByChatID(gid.String()) - portal.roomCreateLock.Lock() - defer portal.roomCreateLock.Unlock() - if len(portal.MXID) != 0 { - ce.ZLog.Warn().Msg("Detected race condition in room creation") - // TODO race condition, clean up the old room - } - portal.MXID = ce.RoomID - portal.Name = roomName - portal.Encrypted = encryptionEvent != nil && encryptionEvent.Algorithm == id.AlgorithmMegolmV1 - if !portal.Encrypted && ce.Bridge.Config.Bridge.Encryption.Default { - _, err = portal.MainIntent().SendStateEvent(ce.Ctx, portal.MXID, event.StateEncryption, "", portal.GetEncryptionEventContent()) - if err != nil { - ce.ZLog.Err(err).Msg("Failed to enable encryption in room") - if errors.Is(err, mautrix.MForbidden) { - ce.Reply("I don't seem to have permission to enable encryption in this room.") - } else { - ce.Reply("Failed to enable encryption in room: %v", err) - } - } - portal.Encrypted = true - } - portal.Revision = group.Revision - portal.AvatarHash = avatarHash - portal.AvatarURL = avatarURL - portal.AvatarPath = group.AvatarPath - portal.AvatarSet = avatarSet - err = portal.Update(ce.Ctx) - if err != nil { - ce.ZLog.Err(err).Msg("Failed to save portal after creating group") - } - portal.UpdateBridgeInfo(ce.Ctx) - ce.Reply("Successfully created Signal group %s", gid.String()) -} diff --git a/config/bridge.go b/config/bridge.go deleted file mode 100644 index e3e756c..0000000 --- a/config/bridge.go +++ /dev/null @@ -1,241 +0,0 @@ -// mautrix-signal - A Matrix-signal puppeting bridge. -// Copyright (C) 2022 Tulir Asokan -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see . - -package config - -import ( - "errors" - "fmt" - "strings" - "text/template" - "time" - - "maunium.net/go/mautrix/bridge/bridgeconfig" - "maunium.net/go/mautrix/event" - "maunium.net/go/mautrix/id" - - "go.mau.fi/mautrix-signal/pkg/signalmeow/types" -) - -type BridgeConfig struct { - UsernameTemplate string `yaml:"username_template"` - DisplaynameTemplate string `yaml:"displayname_template"` - PrivateChatPortalMeta string `yaml:"private_chat_portal_meta"` - UseContactAvatars bool `yaml:"use_contact_avatars"` - UseOutdatedProfiles bool `yaml:"use_outdated_profiles"` - NumberInTopic bool `yaml:"number_in_topic"` - - NoteToSelfAvatar id.ContentURIString `yaml:"note_to_self_avatar"` - - PortalMessageBuffer int `yaml:"portal_message_buffer"` - - PersonalFilteringSpaces bool `yaml:"personal_filtering_spaces"` - BridgeNotices bool `yaml:"bridge_notices"` - DeliveryReceipts bool `yaml:"delivery_receipts"` - MessageStatusEvents bool `yaml:"message_status_events"` - MessageErrorNotices bool `yaml:"message_error_notices"` - SyncDirectChatList bool `yaml:"sync_direct_chat_list"` - ResendBridgeInfo bool `yaml:"resend_bridge_info"` - PublicPortals bool `yaml:"public_portals"` - CaptionInMessage bool `yaml:"caption_in_message"` - LocationFormat string `yaml:"location_format"` - FederateRooms bool `yaml:"federate_rooms"` - BridgeMatrixLeave bool `yaml:"bridge_matrix_leave"` - - DoublePuppetConfig bridgeconfig.DoublePuppetConfig `yaml:",inline"` - - MessageHandlingTimeout struct { - ErrorAfterStr string `yaml:"error_after"` - DeadlineStr string `yaml:"deadline"` - - ErrorAfter time.Duration `yaml:"-"` - Deadline time.Duration `yaml:"-"` - } `yaml:"message_handling_timeout"` - - CommandPrefix string `yaml:"command_prefix"` - ManagementRoomText bridgeconfig.ManagementRoomTexts `yaml:"management_room_text"` - - Encryption bridgeconfig.EncryptionConfig `yaml:"encryption"` - - Provisioning struct { - Prefix string `yaml:"prefix"` - SharedSecret string `yaml:"shared_secret"` - DebugEndpoints bool `yaml:"debug_endpoints"` - } `yaml:"provisioning"` - - Permissions bridgeconfig.PermissionConfig `yaml:"permissions"` - - Relay RelaybotConfig `yaml:"relay"` - - usernameTemplate *template.Template `yaml:"-"` - displaynameTemplate *template.Template `yaml:"-"` -} - -func (bc *BridgeConfig) GetResendBridgeInfo() bool { - return bc.ResendBridgeInfo -} - -func (bc *BridgeConfig) EnableMessageStatusEvents() bool { - return bc.MessageStatusEvents -} - -func (bc *BridgeConfig) EnableMessageErrorNotices() bool { - return bc.MessageErrorNotices -} - -func boolToInt(val bool) int { - if val { - return 1 - } - return 0 -} - -func (bc *BridgeConfig) Validate() error { - _, hasWildcard := bc.Permissions["*"] - _, hasExampleDomain := bc.Permissions["example.com"] - _, hasExampleUser := bc.Permissions["@admin:example.com"] - exampleLen := boolToInt(hasWildcard) + boolToInt(hasExampleUser) + boolToInt(hasExampleDomain) - if len(bc.Permissions) <= exampleLen { - return errors.New("bridge.permissions not configured") - } - return nil -} - -type umBridgeConfig BridgeConfig - -func (bc *BridgeConfig) UnmarshalYAML(unmarshal func(interface{}) error) error { - err := unmarshal((*umBridgeConfig)(bc)) - if err != nil { - return err - } - - bc.usernameTemplate, err = template.New("username").Parse(bc.UsernameTemplate) - if err != nil { - return err - } else if !strings.Contains(bc.FormatUsername("1234567890"), "1234567890") { - return fmt.Errorf("username template is missing user ID placeholder") - } - bc.displaynameTemplate, err = template.New("displayname").Parse(bc.DisplaynameTemplate) - if err != nil { - return err - } - - return nil -} - -var _ bridgeconfig.BridgeConfig = (*BridgeConfig)(nil) - -func (bc BridgeConfig) GetDoublePuppetConfig() bridgeconfig.DoublePuppetConfig { - return bc.DoublePuppetConfig -} - -func (bc BridgeConfig) GetEncryptionConfig() bridgeconfig.EncryptionConfig { - return bc.Encryption -} - -func (bc BridgeConfig) GetCommandPrefix() string { - return bc.CommandPrefix -} - -func (bc BridgeConfig) GetManagementRoomTexts() bridgeconfig.ManagementRoomTexts { - return bc.ManagementRoomText -} - -func (bc BridgeConfig) FormatUsername(userID string) string { - var buffer strings.Builder - _ = bc.usernameTemplate.Execute(&buffer, userID) - return buffer.String() -} - -type DisplaynameParams struct { - ProfileName string - ContactName string - Username string - PhoneNumber string - UUID string - ACI string - PNI string - AboutEmoji string -} - -func (bc BridgeConfig) FormatDisplayname(contact *types.Recipient) string { - var buffer strings.Builder - _ = bc.displaynameTemplate.Execute(&buffer, DisplaynameParams{ - ProfileName: contact.Profile.Name, - ContactName: contact.ContactName, - //Username: contact.Username, - PhoneNumber: contact.E164, - UUID: contact.ACI.String(), - ACI: contact.ACI.String(), - PNI: contact.PNI.String(), - AboutEmoji: contact.Profile.AboutEmoji, - }) - return buffer.String() -} - -type RelaybotConfig struct { - Enabled bool `yaml:"enabled"` - AdminOnly bool `yaml:"admin_only"` - MessageFormats map[event.MessageType]string `yaml:"message_formats"` - messageTemplates *template.Template `yaml:"-"` -} - -type umRelaybotConfig RelaybotConfig - -func (rc *RelaybotConfig) UnmarshalYAML(unmarshal func(interface{}) error) error { - err := unmarshal((*umRelaybotConfig)(rc)) - if err != nil { - return err - } - - rc.messageTemplates = template.New("messageTemplates") - for key, format := range rc.MessageFormats { - _, err := rc.messageTemplates.New(string(key)).Parse(format) - if err != nil { - return err - } - } - - return nil -} - -type Sender struct { - UserID string - event.MemberEventContent -} - -type formatData struct { - Sender Sender - Message string - Content *event.MessageEventContent -} - -func (rc *RelaybotConfig) FormatMessage(content *event.MessageEventContent, sender id.UserID, member event.MemberEventContent) (string, error) { - if len(member.Displayname) == 0 { - member.Displayname = sender.String() - } - member.Displayname = template.HTMLEscapeString(member.Displayname) - var output strings.Builder - err := rc.messageTemplates.ExecuteTemplate(&output, string(content.MsgType), formatData{ - Sender: Sender{ - UserID: template.HTMLEscapeString(sender.String()), - MemberEventContent: member, - }, - Content: content, - Message: content.FormattedBody, - }) - return output.String(), err -} diff --git a/config/config.go b/config/config.go deleted file mode 100644 index de62c82..0000000 --- a/config/config.go +++ /dev/null @@ -1,44 +0,0 @@ -// mautrix-signal - A Matrix-Signal puppeting bridge. -// Copyright (C) 2022 Tulir Asokan -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see . - -package config - -import ( - "maunium.net/go/mautrix/bridge/bridgeconfig" - "maunium.net/go/mautrix/id" -) - -type Config struct { - *bridgeconfig.BaseConfig `yaml:",inline"` - - Metrics struct { - Enabled bool `yaml:"enabled"` - Listen string `yaml:"listen"` - } `yaml:"metrics"` - - Signal struct { - DeviceName string `yaml:"device_name"` - } `yaml:"signal"` - - Bridge BridgeConfig `yaml:"bridge"` -} - -func (config *Config) CanAutoDoublePuppet(userID id.UserID) bool { - _, homeserver, _ := userID.Parse() - _, hasSecret := config.Bridge.DoublePuppetConfig.SharedSecretMap[homeserver] - - return hasSecret -} diff --git a/config/upgrade.go b/config/upgrade.go deleted file mode 100644 index 219b7fc..0000000 --- a/config/upgrade.go +++ /dev/null @@ -1,167 +0,0 @@ -// mautrix-signal - A Matrix-Signal puppeting bridge. -// Copyright (C) 2022 Tulir Asokan -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see . - -package config - -import ( - "net/url" - "strings" - - up "go.mau.fi/util/configupgrade" - "go.mau.fi/util/random" - "maunium.net/go/mautrix/bridge/bridgeconfig" -) - -func DoUpgrade(helper up.Helper) { - bridgeconfig.Upgrader.DoUpgrade(helper) - - legacyDB, ok := helper.Get(up.Str, "appservice", "database") - if ok { - if strings.HasPrefix(legacyDB, "postgres") { - parsedDB, err := url.Parse(legacyDB) - if err != nil { - panic(err) - } - q := parsedDB.Query() - if parsedDB.Host == "" && !q.Has("host") { - q.Set("host", "/var/run/postgresql") - } else if !q.Has("sslmode") { - q.Set("sslmode", "disable") - } - parsedDB.RawQuery = q.Encode() - helper.Set(up.Str, parsedDB.String(), "appservice", "database", "uri") - helper.Set(up.Str, "postgres", "appservice", "database", "type") - } else { - dbPath := strings.TrimPrefix(strings.TrimPrefix(legacyDB, "sqlite:"), "///") - helper.Set(up.Str, dbPath, "appservice", "database", "uri") - helper.Set(up.Str, "sqlite3-fk-wal", "appservice", "database", "type") - } - } - if legacyDBMinSize, ok := helper.Get(up.Int, "appservice", "database_opts", "min_size"); ok { - helper.Set(up.Int, legacyDBMinSize, "appservice", "database", "max_idle_conns") - } - if legacyDBMaxSize, ok := helper.Get(up.Int, "appservice", "database_opts", "max_size"); ok { - helper.Set(up.Int, legacyDBMaxSize, "appservice", "database", "max_open_conns") - } - if legacyBotUsername, ok := helper.Get(up.Str, "appservice", "bot_username"); ok { - helper.Set(up.Str, legacyBotUsername, "appservice", "bot", "username") - } - if legacyBotDisplayname, ok := helper.Get(up.Str, "appservice", "bot_displayname"); ok { - helper.Set(up.Str, legacyBotDisplayname, "appservice", "bot", "displayname") - } - if legacyBotAvatar, ok := helper.Get(up.Str, "appservice", "bot_avatar"); ok { - helper.Set(up.Str, legacyBotAvatar, "appservice", "bot", "avatar") - } - - helper.Copy(up.Bool, "metrics", "enabled") - helper.Copy(up.Str, "metrics", "listen") - - helper.Copy(up.Str, "signal", "device_name") - - if usernameTemplate, ok := helper.Get(up.Str, "bridge", "username_template"); ok && strings.Contains(usernameTemplate, "{userid}") { - helper.Set(up.Str, strings.ReplaceAll(usernameTemplate, "{userid}", "{{.}}"), "bridge", "username_template") - } else { - helper.Copy(up.Str, "bridge", "username_template") - } - if displaynameTemplate, ok := helper.Get(up.Str, "bridge", "displayname_template"); ok && strings.Contains(displaynameTemplate, "{displayname}") { - helper.Set(up.Str, strings.ReplaceAll(displaynameTemplate, "{displayname}", `{{or .ProfileName .PhoneNumber "Unknown user"}}`), "bridge", "displayname_template") - } else { - helper.Copy(up.Str, "bridge", "displayname_template") - } - helper.Copy(up.Str, "bridge", "private_chat_portal_meta") - helper.Copy(up.Bool, "bridge", "use_contact_avatars") - helper.Copy(up.Bool, "bridge", "use_outdated_profiles") - helper.Copy(up.Bool, "bridge", "number_in_topic") - helper.Copy(up.Str, "bridge", "note_to_self_avatar") - helper.Copy(up.Int, "bridge", "portal_message_buffer") - helper.Copy(up.Bool, "bridge", "personal_filtering_spaces") - helper.Copy(up.Bool, "bridge", "bridge_notices") - helper.Copy(up.Bool, "bridge", "delivery_receipts") - helper.Copy(up.Bool, "bridge", "message_status_events") - helper.Copy(up.Bool, "bridge", "message_error_notices") - helper.Copy(up.Bool, "bridge", "sync_direct_chat_list") - helper.Copy(up.Bool, "bridge", "resend_bridge_info") - helper.Copy(up.Bool, "bridge", "public_portals") - helper.Copy(up.Bool, "bridge", "caption_in_message") - helper.Copy(up.Str, "bridge", "location_format") - helper.Copy(up.Bool, "bridge", "federate_rooms") - helper.Copy(up.Map, "bridge", "double_puppet_server_map") - helper.Copy(up.Bool, "bridge", "double_puppet_allow_discovery") - helper.Copy(up.Map, "bridge", "login_shared_secret_map") - helper.Copy(up.Str, "bridge", "command_prefix") - helper.Copy(up.Str, "bridge", "management_room_text", "welcome") - helper.Copy(up.Str, "bridge", "management_room_text", "welcome_connected") - helper.Copy(up.Str, "bridge", "management_room_text", "welcome_unconnected") - helper.Copy(up.Str|up.Null, "bridge", "management_room_text", "additional_help") - helper.Copy(up.Bool, "bridge", "encryption", "allow") - helper.Copy(up.Bool, "bridge", "encryption", "default") - helper.Copy(up.Bool, "bridge", "encryption", "require") - helper.Copy(up.Bool, "bridge", "encryption", "appservice") - helper.Copy(up.Bool, "bridge", "encryption", "allow_key_sharing") - helper.Copy(up.Bool, "bridge", "encryption", "delete_keys", "delete_outbound_on_ack") - helper.Copy(up.Bool, "bridge", "encryption", "delete_keys", "dont_store_outbound") - helper.Copy(up.Bool, "bridge", "encryption", "delete_keys", "ratchet_on_decrypt") - helper.Copy(up.Bool, "bridge", "encryption", "delete_keys", "delete_fully_used_on_decrypt") - helper.Copy(up.Bool, "bridge", "encryption", "delete_keys", "delete_prev_on_new_session") - helper.Copy(up.Bool, "bridge", "encryption", "delete_keys", "delete_on_device_delete") - helper.Copy(up.Bool, "bridge", "encryption", "delete_keys", "periodically_delete_expired") - helper.Copy(up.Bool, "bridge", "encryption", "delete_keys", "delete_outdated_inbound") - helper.Copy(up.Str, "bridge", "encryption", "verification_levels", "receive") - helper.Copy(up.Str, "bridge", "encryption", "verification_levels", "send") - helper.Copy(up.Str, "bridge", "encryption", "verification_levels", "share") - helper.Copy(up.Bool, "bridge", "encryption", "rotation", "enable_custom") - helper.Copy(up.Int, "bridge", "encryption", "rotation", "milliseconds") - helper.Copy(up.Int, "bridge", "encryption", "rotation", "messages") - helper.Copy(up.Bool, "bridge", "encryption", "rotation", "disable_device_change_key_rotation") - helper.Copy(up.Bool, "bridge", "bridge_matrix_leave") - - helper.Copy(up.Str, "bridge", "provisioning", "prefix") - if secret, ok := helper.Get(up.Str, "bridge", "provisioning", "shared_secret"); !ok || secret == "generate" { - sharedSecret := random.String(64) - helper.Set(up.Str, sharedSecret, "bridge", "provisioning", "shared_secret") - } else { - helper.Copy(up.Str, "bridge", "provisioning", "shared_secret") - } - helper.Copy(up.Bool, "bridge", "provisioning", "debug_endpoints") - - helper.Copy(up.Map, "bridge", "permissions") - helper.Copy(up.Bool, "bridge", "relay", "enabled") - helper.Copy(up.Bool, "bridge", "relay", "admin_only") - if textRelayFormat, ok := helper.Get(up.Str, "bridge", "relay", "message_formats", "m.text"); ok && strings.Contains(textRelayFormat, "$message") && !strings.Contains(textRelayFormat, ".Message") { - // don't copy legacy message formats - } else { - helper.Copy(up.Map, "bridge", "relay", "message_formats") - } -} - -var SpacedBlocks = [][]string{ - {"homeserver", "software"}, - {"appservice"}, - {"appservice", "hostname"}, - {"appservice", "database"}, - {"appservice", "id"}, - {"appservice", "as_token"}, - {"metrics"}, - {"signal"}, - {"bridge"}, - {"bridge", "personal_filtering_spaces"}, - {"bridge", "command_prefix"}, - {"bridge", "management_room_text"}, - {"bridge", "encryption"}, - {"bridge", "provisioning"}, - {"bridge", "permissions"}, - {"logging"}, -} diff --git a/custompuppet.go b/custompuppet.go deleted file mode 100644 index cde3059..0000000 --- a/custompuppet.go +++ /dev/null @@ -1,97 +0,0 @@ -// mautrix-signal - A Matrix-signal puppeting bridge. -// Copyright (C) 2023 Tulir Asokan -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see . - -package main - -import ( - "context" - "fmt" - - "maunium.net/go/mautrix/id" -) - -func (puppet *Puppet) SwitchCustomMXID(accessToken string, mxid id.UserID) error { - puppet.CustomMXID = mxid - puppet.AccessToken = accessToken - err := puppet.Update(context.TODO()) - if err != nil { - return fmt.Errorf("failed to save access token: %w", err) - } - err = puppet.StartCustomMXID(false) - if err != nil { - return err - } - // TODO leave rooms with default puppet - return nil -} - -func (puppet *Puppet) ClearCustomMXID() { - save := puppet.CustomMXID != "" || puppet.AccessToken != "" - puppet.bridge.puppetsLock.Lock() - if puppet.CustomMXID != "" && puppet.bridge.puppetsByCustomMXID[puppet.CustomMXID] == puppet { - delete(puppet.bridge.puppetsByCustomMXID, puppet.CustomMXID) - } - puppet.bridge.puppetsLock.Unlock() - puppet.CustomMXID = "" - puppet.AccessToken = "" - puppet.customIntent = nil - puppet.customUser = nil - if save { - err := puppet.Update(context.TODO()) - if err != nil { - puppet.log.Err(err).Msg("Failed to clear custom MXID") - } - } -} - -func (puppet *Puppet) StartCustomMXID(reloginOnFail bool) error { - newIntent, newAccessToken, err := puppet.bridge.DoublePuppet.Setup(context.TODO(), puppet.CustomMXID, puppet.AccessToken, reloginOnFail) - if err != nil { - puppet.ClearCustomMXID() - return err - } - puppet.bridge.puppetsLock.Lock() - puppet.bridge.puppetsByCustomMXID[puppet.CustomMXID] = puppet - puppet.bridge.puppetsLock.Unlock() - if puppet.AccessToken != newAccessToken { - puppet.AccessToken = newAccessToken - err = puppet.Update(context.TODO()) - } - puppet.customIntent = newIntent - puppet.customUser = puppet.bridge.GetUserByMXID(puppet.CustomMXID) - return err -} - -func (user *User) tryAutomaticDoublePuppeting() { - if !user.bridge.Config.CanAutoDoublePuppet(user.MXID) { - return - } - user.log.Debug().Msg("Checking if double puppeting needs to be enabled") - puppet := user.bridge.GetPuppetBySignalID(user.SignalID) - if puppet.CustomMXID == user.MXID { - user.log.Debug().Msg("User already has double-puppeting enabled") - // Custom puppet already enabled - return - } - puppet.CustomMXID = user.MXID - err := puppet.StartCustomMXID(true) - if err != nil { - user.log.Warn().Err(err).Msg("Failed to login with shared secret") - } else { - // TODO leave rooms with default puppet - user.log.Debug().Msg("Successfully automatically enabled custom puppet") - } -} diff --git a/database/database.go b/database/database.go deleted file mode 100644 index daa365f..0000000 --- a/database/database.go +++ /dev/null @@ -1,53 +0,0 @@ -// mautrix-signal - A Matrix-signal puppeting bridge. -// Copyright (C) 2023 Scott Weber, Tulir Asokan -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see . - -package database - -import ( - _ "embed" - - _ "github.com/lib/pq" - _ "github.com/mattn/go-sqlite3" - "go.mau.fi/util/dbutil" - - "go.mau.fi/mautrix-signal/database/upgrades" -) - -type Database struct { - *dbutil.Database - - User *UserQuery - Portal *PortalQuery - LostPortal *LostPortalQuery - Puppet *PuppetQuery - Message *MessageQuery - Reaction *ReactionQuery - DisappearingMessage *DisappearingMessageQuery -} - -func New(db *dbutil.Database) *Database { - db.UpgradeTable = upgrades.Table - return &Database{ - Database: db, - User: &UserQuery{dbutil.MakeQueryHelper(db, newUser)}, - Portal: &PortalQuery{dbutil.MakeQueryHelper(db, newPortal)}, - LostPortal: &LostPortalQuery{dbutil.MakeQueryHelper(db, newLostPortal)}, - Puppet: &PuppetQuery{dbutil.MakeQueryHelper(db, newPuppet)}, - Message: &MessageQuery{dbutil.MakeQueryHelper(db, newMessage)}, - Reaction: &ReactionQuery{dbutil.MakeQueryHelper(db, newReaction)}, - DisappearingMessage: &DisappearingMessageQuery{dbutil.MakeQueryHelper(db, newDisappearingMessage)}, - } -} diff --git a/database/disappearingmessage.go b/database/disappearingmessage.go deleted file mode 100644 index b32a8ee..0000000 --- a/database/disappearingmessage.go +++ /dev/null @@ -1,125 +0,0 @@ -// mautrix-signal - A Matrix-signal puppeting bridge. -// Copyright (C) 2023 Scott Weber, Tulir Asokan -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see . - -package database - -import ( - "context" - "database/sql" - "time" - - "go.mau.fi/util/dbutil" - "maunium.net/go/mautrix/id" -) - -const ( - getUnscheduledDisappearingMessagesForRoomQuery = ` - SELECT room_id, mxid, expiration_seconds, expiration_ts - FROM disappearing_message WHERE expiration_ts IS NULL AND room_id = $1 - ` - getExpiredDisappearingMessagesQuery = ` - SELECT room_id, mxid, expiration_seconds, expiration_ts - FROM disappearing_message WHERE expiration_ts IS NOT NULL AND expiration_ts <= $1 - ` - getNextDisappearingMessageQuery = ` - SELECT room_id, mxid, expiration_seconds, expiration_ts - FROM disappearing_message WHERE expiration_ts IS NOT NULL ORDER BY expiration_ts ASC LIMIT 1 - ` - insertDisappearingMessageQuery = ` - INSERT INTO disappearing_message (room_id, mxid, expiration_seconds, expiration_ts) VALUES ($1, $2, $3, $4) - ` - updateDisappearingMessageQuery = ` - UPDATE disappearing_message SET expiration_ts=$2 WHERE mxid=$1 - ` - deleteDisappearingMessageQuery = ` - DELETE FROM disappearing_message WHERE mxid=$1 - ` -) - -type DisappearingMessageQuery struct { - *dbutil.QueryHelper[*DisappearingMessage] -} - -type DisappearingMessage struct { - qh *dbutil.QueryHelper[*DisappearingMessage] - - RoomID id.RoomID - EventID id.EventID - ExpireIn time.Duration - ExpireAt time.Time -} - -func newDisappearingMessage(qh *dbutil.QueryHelper[*DisappearingMessage]) *DisappearingMessage { - return &DisappearingMessage{qh: qh} -} - -func (dmq *DisappearingMessageQuery) NewWithValues(roomID id.RoomID, eventID id.EventID, expireIn time.Duration, expireAt time.Time) *DisappearingMessage { - return &DisappearingMessage{ - qh: dmq.QueryHelper, - RoomID: roomID, - EventID: eventID, - ExpireIn: expireIn, - ExpireAt: expireAt, - } -} - -func (dmq *DisappearingMessageQuery) GetUnscheduledForRoom(ctx context.Context, roomID id.RoomID) ([]*DisappearingMessage, error) { - return dmq.QueryMany(ctx, getUnscheduledDisappearingMessagesForRoomQuery, roomID) -} - -func (dmq *DisappearingMessageQuery) GetExpiredMessages(ctx context.Context) ([]*DisappearingMessage, error) { - return dmq.QueryMany(ctx, getExpiredDisappearingMessagesQuery, time.Now().Unix()+1) -} - -func (dmq *DisappearingMessageQuery) GetNextScheduledMessage(ctx context.Context) (*DisappearingMessage, error) { - return dmq.QueryOne(ctx, getNextDisappearingMessageQuery) -} - -func (msg *DisappearingMessage) Scan(row dbutil.Scannable) (*DisappearingMessage, error) { - var expireIn int64 - var expireAt sql.NullInt64 - err := row.Scan(&msg.RoomID, &msg.EventID, &expireIn, &expireAt) - if err != nil { - return nil, err - } - msg.ExpireIn = time.Duration(expireIn) * time.Second - if expireAt.Valid { - msg.ExpireAt = time.Unix(expireAt.Int64, 0) - } - return msg, nil -} - -func (msg *DisappearingMessage) sqlVariables() []any { - var expireAt sql.NullInt64 - if !msg.ExpireAt.IsZero() { - expireAt.Valid = true - expireAt.Int64 = msg.ExpireAt.Unix() - } - return []any{msg.RoomID, msg.EventID, int64(msg.ExpireIn.Seconds()), expireAt} -} - -func (msg *DisappearingMessage) Insert(ctx context.Context) error { - return msg.qh.Exec(ctx, insertDisappearingMessageQuery, msg.sqlVariables()...) -} - -func (msg *DisappearingMessage) StartExpirationTimer(ctx context.Context) error { - msg.ExpireAt = time.Now().Add(msg.ExpireIn) - return msg.qh.Exec(ctx, updateDisappearingMessageQuery, msg.EventID, msg.ExpireAt.Unix()) -} - -func (msg *DisappearingMessage) Delete(ctx context.Context) error { - return msg.qh.Exec(ctx, deleteDisappearingMessageQuery, msg.EventID) -} diff --git a/database/lostportal.go b/database/lostportal.go deleted file mode 100644 index 29779b8..0000000 --- a/database/lostportal.go +++ /dev/null @@ -1,58 +0,0 @@ -// mautrix-signal - A Matrix-signal puppeting bridge. -// Copyright (C) 2023 Tulir Asokan -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see . - -package database - -import ( - "context" - - "go.mau.fi/util/dbutil" - "maunium.net/go/mautrix/id" -) - -const ( - getLostPortalsQuery = `SELECT chat_id, receiver, mxid FROM lost_portals` - deleteLostPortalQuery = `DELETE FROM lost_portals WHERE mxid=$1` -) - -type LostPortalQuery struct { - *dbutil.QueryHelper[*LostPortal] -} - -func (lpq *LostPortalQuery) GetAll(ctx context.Context) ([]*LostPortal, error) { - return lpq.QueryMany(ctx, getLostPortalsQuery) -} - -type LostPortal struct { - qh *dbutil.QueryHelper[*LostPortal] - - ChatID string - Receiver string - MXID id.RoomID -} - -func newLostPortal(qh *dbutil.QueryHelper[*LostPortal]) *LostPortal { - return &LostPortal{qh: qh} -} - -func (l *LostPortal) Scan(row dbutil.Scannable) (*LostPortal, error) { - err := row.Scan(&l.ChatID, &l.Receiver, &l.MXID) - return l, err -} - -func (l *LostPortal) Delete(ctx context.Context) error { - return l.qh.Exec(ctx, deleteLostPortalQuery, l.MXID) -} diff --git a/database/message.go b/database/message.go deleted file mode 100644 index 5184bd8..0000000 --- a/database/message.go +++ /dev/null @@ -1,179 +0,0 @@ -// mautrix-signal - A Matrix-signal puppeting bridge. -// Copyright (C) 2023 Scott Weber, Tulir Asokan -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see . - -package database - -import ( - "context" - "fmt" - "strings" - - "github.com/google/uuid" - "github.com/lib/pq" - "go.mau.fi/util/dbutil" - "maunium.net/go/mautrix/id" -) - -const ( - getMessageByMXIDQuery = ` - SELECT sender, timestamp, part_index, signal_chat_id, signal_receiver, mxid, mx_room FROM message - WHERE mxid=$1 - ` - getMessagePartBySignalIDQuery = ` - SELECT sender, timestamp, part_index, signal_chat_id, signal_receiver, mxid, mx_room FROM message - WHERE sender=$1 AND timestamp=$2 AND part_index=$3 AND signal_receiver=$4 - ` - getLastMessagePartBySignalIDQuery = ` - SELECT sender, timestamp, part_index, signal_chat_id, signal_receiver, mxid, mx_room FROM message - WHERE sender=$1 AND timestamp=$2 AND signal_receiver=$3 - ORDER BY part_index DESC LIMIT 1 - ` - getAllMessagePartsBySignalIDQuery = ` - SELECT sender, timestamp, part_index, signal_chat_id, signal_receiver, mxid, mx_room FROM message - WHERE sender=$1 AND timestamp=$2 AND signal_receiver=$3 - ` - getMessageLastPartBySignalIDWithUnknownReceiverQuery = ` - SELECT sender, timestamp, part_index, signal_chat_id, signal_receiver, mxid, mx_room FROM message - WHERE sender=$1 AND timestamp=$2 AND (signal_receiver=$3 OR signal_receiver='00000000-0000-0000-0000-000000000000') - ORDER BY part_index DESC LIMIT 1 - ` - getManyMessagesBySignalIDQueryPostgres = ` - SELECT sender, timestamp, part_index, signal_chat_id, signal_receiver, mxid, mx_room FROM message - WHERE sender=$1 AND (signal_receiver=$2 OR signal_receiver=$3) AND timestamp=ANY($4) - ORDER BY timestamp DESC, part_index DESC - ` - getManyMessagesBySignalIDQuerySQLite = ` - SELECT sender, timestamp, part_index, signal_chat_id, signal_receiver, mxid, mx_room FROM message - WHERE sender=?1 AND (signal_receiver=?2 OR signal_receiver=?3) AND timestamp IN (?4) - ORDER BY timestamp DESC, part_index DESC - ` - getFirstBeforeQuery = ` - SELECT sender, timestamp, part_index, signal_chat_id, signal_receiver, mxid, mx_room FROM message - WHERE mx_room=$1 AND timestamp <= $2 - ORDER BY timestamp DESC - LIMIT 1 - ` - getMessagesBetweenTimeQuery = ` - SELECT sender, timestamp, part_index, signal_chat_id, signal_receiver, mxid, mx_room FROM message - WHERE signal_chat_id=$1 AND signal_receiver=$2 AND timestamp>$3 AND timestamp<=$4 AND part_index=0 - ORDER BY timestamp ASC - ` - insertMessageQuery = ` - INSERT INTO message (sender, timestamp, part_index, signal_chat_id, signal_receiver, mxid, mx_room) - VALUES ($1, $2, $3, $4, $5, $6, $7) - ` - deleteMessageQuery = ` - DELETE FROM message - WHERE sender=$1 AND timestamp=$2 AND part_index=$3 AND signal_receiver=$4 - ` - updateMessageTimestampQuery = ` - UPDATE message SET timestamp=$4 WHERE sender=$1 AND timestamp=$2 AND signal_receiver=$3 - ` -) - -type MessageQuery struct { - *dbutil.QueryHelper[*Message] -} - -type Message struct { - qh *dbutil.QueryHelper[*Message] - - Sender uuid.UUID - Timestamp uint64 - PartIndex int - - SignalChatID string - SignalReceiver uuid.UUID - - MXID id.EventID - RoomID id.RoomID -} - -func newMessage(qh *dbutil.QueryHelper[*Message]) *Message { - return &Message{qh: qh} -} - -func (mq *MessageQuery) GetByMXID(ctx context.Context, mxid id.EventID) (*Message, error) { - return mq.QueryOne(ctx, getMessageByMXIDQuery, mxid) -} - -func (mq *MessageQuery) GetBySignalID(ctx context.Context, sender uuid.UUID, timestamp uint64, partIndex int, receiver uuid.UUID) (*Message, error) { - return mq.QueryOne(ctx, getMessagePartBySignalIDQuery, sender, timestamp, partIndex, receiver) -} - -func (mq *MessageQuery) GetLastPartBySignalID(ctx context.Context, sender uuid.UUID, timestamp uint64, receiver uuid.UUID) (*Message, error) { - return mq.QueryOne(ctx, getLastMessagePartBySignalIDQuery, sender, timestamp, receiver) -} - -func (mq *MessageQuery) GetAllPartsBySignalID(ctx context.Context, sender uuid.UUID, timestamp uint64, receiver uuid.UUID) ([]*Message, error) { - return mq.QueryMany(ctx, getAllMessagePartsBySignalIDQuery, sender, timestamp, receiver) -} - -func (mq *MessageQuery) GetAllBetweenTimestamps(ctx context.Context, key PortalKey, min, max uint64) ([]*Message, error) { - return mq.QueryMany(ctx, getMessagesBetweenTimeQuery, key.ChatID, key.Receiver, int64(min), int64(max)) -} - -func (mq *MessageQuery) GetLastPartBySignalIDWithUnknownReceiver(ctx context.Context, sender uuid.UUID, timestamp uint64, receiver uuid.UUID) (*Message, error) { - return mq.QueryOne(ctx, getMessageLastPartBySignalIDWithUnknownReceiverQuery, sender, timestamp, receiver) -} - -func (mq *MessageQuery) GetManyBySignalID(ctx context.Context, sender uuid.UUID, timestamps []uint64, receiver uuid.UUID, strictReceiver bool) ([]*Message, error) { - receiver2 := uuid.Nil - if strictReceiver { - receiver2 = receiver - } - if mq.GetDB().Dialect == dbutil.Postgres { - int64Array := make([]int64, len(timestamps)) - for i, timestamp := range timestamps { - int64Array[i] = int64(timestamp) - } - return mq.QueryMany(ctx, getManyMessagesBySignalIDQueryPostgres, sender, receiver, receiver2, pq.Array(int64Array)) - } else { - const varargIndex = 3 - arguments := make([]any, len(timestamps)+varargIndex) - placeholders := make([]string, len(timestamps)) - arguments[0] = sender - arguments[1] = receiver - arguments[2] = receiver2 - for i, timestamp := range timestamps { - arguments[i+varargIndex] = timestamp - placeholders[i] = fmt.Sprintf("?%d", i+varargIndex+1) - } - return mq.QueryMany(ctx, strings.Replace(getManyMessagesBySignalIDQuerySQLite, fmt.Sprintf("?%d", varargIndex+1), strings.Join(placeholders, ", "), 1), arguments...) - } -} - -func (msg *Message) Scan(row dbutil.Scannable) (*Message, error) { - return dbutil.ValueOrErr(msg, row.Scan( - &msg.Sender, &msg.Timestamp, &msg.PartIndex, &msg.SignalChatID, &msg.SignalReceiver, &msg.MXID, &msg.RoomID, - )) -} - -func (msg *Message) sqlVariables() []any { - return []any{msg.Sender, msg.Timestamp, msg.PartIndex, msg.SignalChatID, msg.SignalReceiver, msg.MXID, msg.RoomID} -} - -func (msg *Message) Insert(ctx context.Context) error { - return msg.qh.Exec(ctx, insertMessageQuery, msg.sqlVariables()...) -} - -func (msg *Message) Delete(ctx context.Context) error { - return msg.qh.Exec(ctx, deleteMessageQuery, msg.Sender, msg.Timestamp, msg.PartIndex, msg.SignalReceiver) -} - -func (msg *Message) SetTimestamp(ctx context.Context, editTime uint64) error { - return msg.qh.Exec(ctx, updateMessageTimestampQuery, msg.Sender, msg.Timestamp, msg.SignalReceiver, editTime) -} diff --git a/database/portal.go b/database/portal.go deleted file mode 100644 index 786f084..0000000 --- a/database/portal.go +++ /dev/null @@ -1,206 +0,0 @@ -// mautrix-signal - A Matrix-signal puppeting bridge. -// Copyright (C) 2023 Scott Weber, Tulir Asokan -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see . - -package database - -import ( - "context" - "database/sql" - - "github.com/google/uuid" - "go.mau.fi/util/dbutil" - "maunium.net/go/mautrix/id" - - "go.mau.fi/mautrix-signal/pkg/libsignalgo" - "go.mau.fi/mautrix-signal/pkg/signalmeow/types" -) - -const ( - portalBaseSelect = ` - SELECT chat_id, receiver, mxid, name, topic, avatar_path, avatar_hash, avatar_url, - name_set, avatar_set, topic_set, revision, encrypted, relay_user_id, expiration_time - FROM portal - ` - getPortalByMXIDQuery = portalBaseSelect + `WHERE mxid=$1` - getPortalByChatIDQuery = portalBaseSelect + `WHERE chat_id=$1 AND receiver=$2` - getPortalsByReceiver = portalBaseSelect + `WHERE receiver=$1` - getPortalsByUser = portalBaseSelect + `WHERE chat_id=$1` - getAllPortalsWithMXIDQuery = portalBaseSelect + `WHERE mxid IS NOT NULL` - getChatsNotInSpaceQuery = ` - SELECT chat_id FROM portal - LEFT JOIN user_portal ON portal.chat_id=user_portal.portal_chat_id AND portal.receiver=user_portal.portal_receiver - WHERE mxid<>'' AND receiver=$1 AND (user_portal.in_space=false OR user_portal.in_space IS NULL) - ` - insertPortalQuery = ` - INSERT INTO portal ( - chat_id, receiver, mxid, name, topic, avatar_path, avatar_hash, avatar_url, - name_set, avatar_set, topic_set, revision, encrypted, relay_user_id, expiration_time - ) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15) - ` - updatePortalQuery = ` - UPDATE portal SET - mxid=$3, name=$4, topic=$5, avatar_path=$6, avatar_hash=$7, avatar_url=$8, - name_set=$9, avatar_set=$10, topic_set=$11, revision=$12, encrypted=$13, relay_user_id=$14, expiration_time=$15 - WHERE chat_id=$1 AND receiver=$2 - ` - deletePortalQuery = `DELETE FROM portal WHERE chat_id=$1 AND receiver=$2` - reIDPortalQuery = `UPDATE portal SET chat_id=$2 WHERE chat_id=$1 AND receiver=$3` -) - -type PortalQuery struct { - *dbutil.QueryHelper[*Portal] -} - -type PortalKey struct { - ChatID string - Receiver uuid.UUID -} - -func (pk *PortalKey) UserID() libsignalgo.ServiceID { - parsed, _ := libsignalgo.ServiceIDFromString(pk.ChatID) - return parsed -} - -func (pk *PortalKey) GroupID() types.GroupIdentifier { - if len(pk.ChatID) == 44 { - return types.GroupIdentifier(pk.ChatID) - } - return "" -} - -func NewPortalKey(chatID string, receiver uuid.UUID) PortalKey { - return PortalKey{ - ChatID: chatID, - Receiver: receiver, - } -} - -type Portal struct { - qh *dbutil.QueryHelper[*Portal] - - PortalKey - MXID id.RoomID - Name string - Topic string - AvatarPath string - AvatarHash string - AvatarURL id.ContentURI - NameSet bool - AvatarSet bool - TopicSet bool - Revision uint32 - Encrypted bool - RelayUserID id.UserID - ExpirationTime uint32 -} - -func newPortal(qh *dbutil.QueryHelper[*Portal]) *Portal { - return &Portal{qh: qh} -} - -func (pq *PortalQuery) GetByMXID(ctx context.Context, mxid id.RoomID) (*Portal, error) { - return pq.QueryOne(ctx, getPortalByMXIDQuery, mxid) -} - -func (pq *PortalQuery) GetByChatID(ctx context.Context, pk PortalKey) (*Portal, error) { - return pq.QueryOne(ctx, getPortalByChatIDQuery, pk.ChatID, pk.Receiver) -} - -func (pq *PortalQuery) FindPrivateChatsWith(ctx context.Context, userID uuid.UUID) ([]*Portal, error) { - return pq.QueryMany(ctx, getPortalsByUser, userID.String()) -} - -func (pq *PortalQuery) FindPrivateChatsOf(ctx context.Context, receiver uuid.UUID) ([]*Portal, error) { - return pq.QueryMany(ctx, getPortalsByReceiver, receiver) -} - -func (pq *PortalQuery) GetAllWithMXID(ctx context.Context) ([]*Portal, error) { - return pq.QueryMany(ctx, getAllPortalsWithMXIDQuery) -} - -func (pq *PortalQuery) FindPrivateChatsNotInSpace(ctx context.Context, receiver uuid.UUID) ([]PortalKey, error) { - rows, err := pq.GetDB().Query(ctx, getChatsNotInSpaceQuery, receiver) - if err != nil { - return nil, err - } - return dbutil.NewRowIter(rows, func(rows dbutil.Scannable) (key PortalKey, err error) { - err = rows.Scan(&key.ChatID) - key.Receiver = receiver - return - }).AsList() -} - -func (p *Portal) Scan(row dbutil.Scannable) (*Portal, error) { - var mxid sql.NullString - err := row.Scan( - &p.ChatID, - &p.Receiver, - &mxid, - &p.Name, - &p.Topic, - &p.AvatarPath, - &p.AvatarHash, - &p.AvatarURL, - &p.NameSet, - &p.AvatarSet, - &p.TopicSet, - &p.Revision, - &p.Encrypted, - &p.RelayUserID, - &p.ExpirationTime, - ) - if err != nil { - return nil, err - } - p.MXID = id.RoomID(mxid.String) - return p, nil -} - -func (p *Portal) sqlVariables() []any { - return []any{ - p.ChatID, - p.Receiver, - dbutil.StrPtr(p.MXID), - p.Name, - p.Topic, - p.AvatarPath, - p.AvatarHash, - &p.AvatarURL, - p.NameSet, - p.AvatarSet, - p.TopicSet, - p.Revision, - p.Encrypted, - p.RelayUserID, - p.ExpirationTime, - } -} - -func (p *Portal) Insert(ctx context.Context) error { - return p.qh.Exec(ctx, insertPortalQuery, p.sqlVariables()...) -} - -func (p *Portal) Update(ctx context.Context) error { - return p.qh.Exec(ctx, updatePortalQuery, p.sqlVariables()...) -} - -func (p *Portal) Delete(ctx context.Context) error { - return p.qh.Exec(ctx, deletePortalQuery, p.ChatID, p.Receiver) -} - -func (p *Portal) ReID(ctx context.Context, newID string) error { - return p.qh.Exec(ctx, reIDPortalQuery, p.ChatID, newID, p.Receiver) -} diff --git a/database/puppet.go b/database/puppet.go deleted file mode 100644 index 99a65ff..0000000 --- a/database/puppet.go +++ /dev/null @@ -1,158 +0,0 @@ -// mautrix-signal - A Matrix-signal puppeting bridge. -// Copyright (C) 2023 Scott Weber, Tulir Asokan -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see . - -package database - -import ( - "context" - "database/sql" - "time" - - "github.com/google/uuid" - "go.mau.fi/util/dbutil" - "maunium.net/go/mautrix/id" -) - -const ( - puppetBaseSelect = ` - SELECT uuid, number, name, name_quality, avatar_path, avatar_hash, avatar_url, name_set, avatar_set, - contact_info_set, is_registered, profile_fetched_at, custom_mxid, access_token - FROM puppet - ` - getPuppetBySignalIDQuery = puppetBaseSelect + `WHERE uuid=$1` - getPuppetByNumberQuery = puppetBaseSelect + `WHERE number=$1` - getPuppetByCustomMXIDQuery = puppetBaseSelect + `WHERE custom_mxid=$1` - getPuppetsWithCustomMXID = puppetBaseSelect + `WHERE custom_mxid<>''` - updatePuppetQuery = ` - UPDATE puppet SET - number=$2, name=$3, name_quality=$4, avatar_path=$5, avatar_hash=$6, avatar_url=$7, - name_set=$8, avatar_set=$9, contact_info_set=$10, is_registered=$11, profile_fetched_at=$12, - custom_mxid=$13, access_token=$14 - WHERE uuid=$1 - ` - insertPuppetQuery = ` - INSERT INTO puppet ( - uuid, number, name, name_quality, avatar_path, avatar_hash, avatar_url, - name_set, avatar_set, contact_info_set, is_registered, profile_fetched_at, - custom_mxid, access_token - ) - VALUES ( - $1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14 - ) - ` -) - -type PuppetQuery struct { - *dbutil.QueryHelper[*Puppet] -} - -type Puppet struct { - qh *dbutil.QueryHelper[*Puppet] - - SignalID uuid.UUID - Number string - Name string - NameQuality int - AvatarPath string - AvatarHash string - AvatarURL id.ContentURI - NameSet bool - AvatarSet bool - - IsRegistered bool - ContactInfoSet bool - ProfileFetchedAt time.Time - - CustomMXID id.UserID - AccessToken string -} - -func newPuppet(qh *dbutil.QueryHelper[*Puppet]) *Puppet { - return &Puppet{qh: qh} -} - -func (pq *PuppetQuery) GetBySignalID(ctx context.Context, signalID uuid.UUID) (*Puppet, error) { - return pq.QueryOne(ctx, getPuppetBySignalIDQuery, signalID) -} - -func (pq *PuppetQuery) GetByNumber(ctx context.Context, number string) (*Puppet, error) { - return pq.QueryOne(ctx, getPuppetByNumberQuery, number) -} - -func (pq *PuppetQuery) GetByCustomMXID(ctx context.Context, mxid id.UserID) (*Puppet, error) { - return pq.QueryOne(ctx, getPuppetByCustomMXIDQuery, mxid) -} - -func (pq *PuppetQuery) GetAllWithCustomMXID(ctx context.Context) ([]*Puppet, error) { - return pq.QueryMany(ctx, getPuppetsWithCustomMXID) -} - -func (p *Puppet) Scan(row dbutil.Scannable) (*Puppet, error) { - var number, customMXID sql.NullString - var profileFetchedAt sql.NullInt64 - err := row.Scan( - &p.SignalID, - &number, - &p.Name, - &p.NameQuality, - &p.AvatarPath, - &p.AvatarHash, - &p.AvatarURL, - &p.NameSet, - &p.AvatarSet, - &p.ContactInfoSet, - &p.IsRegistered, - &profileFetchedAt, - &customMXID, - &p.AccessToken, - ) - if err != nil { - return nil, err - } - p.Number = number.String - p.CustomMXID = id.UserID(customMXID.String) - if profileFetchedAt.Valid { - p.ProfileFetchedAt = time.UnixMilli(profileFetchedAt.Int64) - } - return p, nil -} - -func (p *Puppet) sqlVariables() []any { - return []any{ - p.SignalID, - dbutil.StrPtr(p.Number), - p.Name, - p.NameQuality, - p.AvatarPath, - p.AvatarHash, - &p.AvatarURL, - p.NameSet, - p.AvatarSet, - p.ContactInfoSet, - p.IsRegistered, - dbutil.UnixMilliPtr(p.ProfileFetchedAt), - dbutil.StrPtr(p.CustomMXID), - p.AccessToken, - } -} - -func (p *Puppet) Insert(ctx context.Context) error { - return p.qh.Exec(ctx, insertPuppetQuery, p.sqlVariables()...) -} - -func (p *Puppet) Update(ctx context.Context) error { - return p.qh.Exec(ctx, updatePuppetQuery, p.sqlVariables()...) -} diff --git a/database/reaction.go b/database/reaction.go deleted file mode 100644 index fc5228e..0000000 --- a/database/reaction.go +++ /dev/null @@ -1,97 +0,0 @@ -// mautrix-signal - A Matrix-signal puppeting bridge. -// Copyright (C) 2023 Scott Weber, Tulir Asokan -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see . - -package database - -import ( - "context" - - "github.com/google/uuid" - "go.mau.fi/util/dbutil" - "maunium.net/go/mautrix/id" -) - -const ( - getReactionByMXIDQuery = `SELECT msg_author, msg_timestamp, author, emoji, signal_chat_id, signal_receiver, mxid, mx_room FROM reaction WHERE mxid=$1` - getReactionBySignalIDQuery = `SELECT msg_author, msg_timestamp, author, emoji, signal_chat_id, signal_receiver, mxid, mx_room FROM reaction WHERE msg_author=$1 AND msg_timestamp=$2 AND author=$3 AND signal_receiver=$4` - insertReactionQuery = ` - INSERT INTO reaction (msg_author, msg_timestamp, author, emoji, signal_chat_id, signal_receiver, mxid, mx_room) - VALUES ($1, $2, $3, $4, $5, $6, $7, $8) - ` - updateReactionQuery = ` - UPDATE reaction - SET mxid=$1, emoji=$2 - WHERE msg_author=$3 AND msg_timestamp=$4 AND author=$5 AND signal_receiver=$6 - ` - deleteReactionQuery = ` - DELETE FROM reaction WHERE msg_author=$1 AND msg_timestamp=$2 AND author=$3 AND signal_receiver=$4 - ` -) - -type ReactionQuery struct { - *dbutil.QueryHelper[*Reaction] -} - -func newReaction(qh *dbutil.QueryHelper[*Reaction]) *Reaction { - return &Reaction{qh: qh} -} - -type Reaction struct { - qh *dbutil.QueryHelper[*Reaction] - - MsgAuthor uuid.UUID - MsgTimestamp uint64 - Author uuid.UUID - Emoji string - - SignalChatID string - SignalReceiver uuid.UUID - - MXID id.EventID - RoomID id.RoomID -} - -func (rq *ReactionQuery) GetByMXID(ctx context.Context, mxid id.EventID) (*Reaction, error) { - return rq.QueryOne(ctx, getReactionByMXIDQuery, mxid) -} - -func (rq *ReactionQuery) GetBySignalID(ctx context.Context, msgAuthor uuid.UUID, msgTimestamp uint64, author, signalReceiver uuid.UUID) (*Reaction, error) { - return rq.QueryOne(ctx, getReactionBySignalIDQuery, msgAuthor, msgTimestamp, author, signalReceiver) -} - -func (r *Reaction) Scan(row dbutil.Scannable) (*Reaction, error) { - return dbutil.ValueOrErr(r, row.Scan( - &r.MsgAuthor, &r.MsgTimestamp, &r.Author, &r.Emoji, &r.SignalChatID, &r.SignalReceiver, &r.MXID, &r.RoomID, - )) -} - -func (r *Reaction) sqlVariables() []any { - return []any{ - r.MsgAuthor, r.MsgTimestamp, r.Author, r.Emoji, r.SignalChatID, r.SignalReceiver, r.MXID, r.RoomID, - } -} - -func (r *Reaction) Insert(ctx context.Context) error { - return r.qh.Exec(ctx, insertReactionQuery, r.sqlVariables()...) -} - -func (r *Reaction) Update(ctx context.Context) error { - return r.qh.Exec(ctx, updateReactionQuery, r.MXID, r.Emoji, r.MsgAuthor, r.MsgTimestamp, r.Author, r.SignalReceiver) -} - -func (r *Reaction) Delete(ctx context.Context) error { - return r.qh.Exec(ctx, deleteReactionQuery, r.MsgAuthor, r.MsgTimestamp, r.Author, r.SignalReceiver) -} diff --git a/database/upgrades/00-latest.sql b/database/upgrades/00-latest.sql deleted file mode 100644 index 4dec3ff..0000000 --- a/database/upgrades/00-latest.sql +++ /dev/null @@ -1,116 +0,0 @@ --- v0 -> v20 (compatible with v17+): Latest revision - -CREATE TABLE portal ( - chat_id TEXT NOT NULL, - receiver uuid NOT NULL, - mxid TEXT, - name TEXT NOT NULL, - topic TEXT NOT NULL, - encrypted BOOLEAN NOT NULL DEFAULT false, - avatar_path TEXT NOT NULL DEFAULT '', - avatar_hash TEXT NOT NULL, - avatar_url TEXT NOT NULL, - name_set BOOLEAN NOT NULL DEFAULT false, - avatar_set BOOLEAN NOT NULL DEFAULT false, - topic_set BOOLEAN NOT NULL DEFAULT false, - revision INTEGER NOT NULL DEFAULT 0, - - expiration_time BIGINT NOT NULL, - relay_user_id TEXT NOT NULL, - - PRIMARY KEY (chat_id, receiver), - CONSTRAINT portal_mxid_unique UNIQUE(mxid) -); - -CREATE TABLE puppet ( - uuid uuid PRIMARY KEY, - number TEXT UNIQUE, - name TEXT NOT NULL, - name_quality INTEGER NOT NULL, - avatar_path TEXT NOT NULL, - avatar_hash TEXT NOT NULL, - avatar_url TEXT NOT NULL, - name_set BOOLEAN NOT NULL DEFAULT false, - avatar_set BOOLEAN NOT NULL DEFAULT false, - - is_registered BOOLEAN NOT NULL DEFAULT false, - contact_info_set BOOLEAN NOT NULL DEFAULT false, - profile_fetched_at BIGINT, - - custom_mxid TEXT, - access_token TEXT NOT NULL, - - CONSTRAINT puppet_custom_mxid_unique UNIQUE(custom_mxid) -); - -CREATE TABLE "user" ( - mxid TEXT PRIMARY KEY, - uuid uuid, - phone TEXT, - - management_room TEXT, - space_room TEXT, - - CONSTRAINT user_uuid_unique UNIQUE(uuid) -); - -CREATE TABLE user_portal ( - user_mxid TEXT, - portal_chat_id TEXT, - portal_receiver uuid, - last_read_ts BIGINT NOT NULL DEFAULT 0, - in_space BOOLEAN NOT NULL DEFAULT false, - - PRIMARY KEY (user_mxid, portal_chat_id, portal_receiver), - CONSTRAINT user_portal_user_fkey FOREIGN KEY (user_mxid) - REFERENCES "user"(mxid) ON UPDATE CASCADE ON DELETE CASCADE, - CONSTRAINT user_portal_portal_fkey FOREIGN KEY (portal_chat_id, portal_receiver) - REFERENCES portal(chat_id, receiver) ON UPDATE CASCADE ON DELETE CASCADE -); - -CREATE TABLE message ( - sender uuid NOT NULL, - timestamp BIGINT NOT NULL, - part_index INTEGER NOT NULL, - - signal_chat_id TEXT NOT NULL, - signal_receiver uuid NOT NULL, - - mxid TEXT NOT NULL, - mx_room TEXT NOT NULL, - - PRIMARY KEY (sender, timestamp, part_index, signal_receiver), - CONSTRAINT message_portal_fkey FOREIGN KEY (signal_chat_id, signal_receiver) - REFERENCES portal(chat_id, receiver) ON DELETE CASCADE ON UPDATE CASCADE, - FOREIGN KEY (sender) REFERENCES puppet(uuid) ON DELETE CASCADE, - CONSTRAINT message_mxid_unique UNIQUE (mxid) -); - -CREATE TABLE reaction ( - msg_author uuid NOT NULL, - msg_timestamp BIGINT NOT NULL, - -- part_index is not used in reactions, but is required for the foreign key. - _part_index INTEGER NOT NULL DEFAULT 0, - - author uuid NOT NULL, - emoji TEXT NOT NULL, - - signal_chat_id TEXT NOT NULL, - signal_receiver uuid NOT NULL, - - mxid TEXT NOT NULL, - mx_room TEXT NOT NULL, - - PRIMARY KEY (msg_author, msg_timestamp, author, signal_receiver), - CONSTRAINT reaction_message_fkey FOREIGN KEY (msg_author, msg_timestamp, _part_index, signal_receiver) - REFERENCES message (sender, timestamp, part_index, signal_receiver) ON DELETE CASCADE ON UPDATE CASCADE, - FOREIGN KEY (author) REFERENCES puppet(uuid) ON DELETE CASCADE, - CONSTRAINT reaction_mxid_unique UNIQUE (mxid) -); - -CREATE TABLE disappearing_message ( - mxid TEXT NOT NULL PRIMARY KEY, - room_id TEXT NOT NULL, - expiration_seconds BIGINT NOT NULL, - expiration_ts BIGINT -); diff --git a/database/upgrades/13-upgrade-mx-state-store.sql b/database/upgrades/13-upgrade-mx-state-store.sql deleted file mode 100644 index ec1b6c2..0000000 --- a/database/upgrades/13-upgrade-mx-state-store.sql +++ /dev/null @@ -1,18 +0,0 @@ --- v13: Switch mx_room_state from Python to Go format -ALTER TABLE mx_room_state DROP COLUMN is_encrypted; -ALTER TABLE mx_room_state DROP COLUMN has_full_member_list; - --- only: postgres for next 2 lines -ALTER TABLE mx_room_state ALTER COLUMN power_levels TYPE jsonb USING power_levels::jsonb; -ALTER TABLE mx_room_state ALTER COLUMN encryption TYPE jsonb USING encryption::jsonb; - -ALTER TABLE "user" ADD COLUMN management_room TEXT; - -UPDATE mx_user_profile SET displayname='' WHERE displayname IS NULL; -UPDATE mx_user_profile SET avatar_url='' WHERE avatar_url IS NULL; - -CREATE TABLE mx_registrations ( - user_id TEXT PRIMARY KEY -); - -UPDATE mx_version SET version=5; diff --git a/database/upgrades/14-remove-notice-room.sql b/database/upgrades/14-remove-notice-room.sql deleted file mode 100644 index 9ad0692..0000000 --- a/database/upgrades/14-remove-notice-room.sql +++ /dev/null @@ -1,3 +0,0 @@ --- v14: Remove redundant notice_room column from users -UPDATE "user" SET management_room = COALESCE(management_room, notice_room); -ALTER TABLE "user" DROP COLUMN notice_room; diff --git a/database/upgrades/15-remove-unused-puppet-columns.sql b/database/upgrades/15-remove-unused-puppet-columns.sql deleted file mode 100644 index 925c3a8..0000000 --- a/database/upgrades/15-remove-unused-puppet-columns.sql +++ /dev/null @@ -1,3 +0,0 @@ --- v15: Remove unused columns in puppet table -ALTER TABLE puppet DROP COLUMN next_batch; -ALTER TABLE puppet DROP COLUMN base_url; diff --git a/database/upgrades/16-refactor-postgres.sql b/database/upgrades/16-refactor-postgres.sql deleted file mode 100644 index 9ab94e8..0000000 --- a/database/upgrades/16-refactor-postgres.sql +++ /dev/null @@ -1,123 +0,0 @@ --- v16: Refactor types (Postgres) --- only: postgres - -DROP TABLE IF EXISTS user_portal; - --- Drop constraints so we can fix timestamps. -ALTER TABLE reaction DROP CONSTRAINT reaction_message_fkey; -ALTER TABLE message DROP CONSTRAINT message_pkey; - --- Add part index to message and fix the hacky timestamps -ALTER TABLE message ADD COLUMN part_index INTEGER; -UPDATE message - SET timestamp=CASE WHEN timestamp > 1500000000000000 THEN timestamp / 1000 ELSE timestamp END, - part_index=CASE WHEN timestamp > 1500000000000000 THEN timestamp % 1000 ELSE 0 END; --- If the bridge users have reacted to message parts, forget about those, not worth trying to deal with potential conflicts. -DELETE FROM reaction WHERE msg_timestamp > 1500000000000000; -ALTER TABLE message ALTER COLUMN part_index SET NOT NULL; -ALTER TABLE reaction ADD COLUMN _part_index INTEGER NOT NULL DEFAULT 0; - --- Re-add the dropped constraints (but with part index and no chat) -DELETE FROM message - WHERE (sender, timestamp, part_index, signal_receiver) - IN (SELECT DISTINCT sender, timestamp, part_index, signal_receiver FROM message GROUP BY (sender, timestamp, part_index, signal_receiver) HAVING COUNT(*)>1); -ALTER TABLE message ADD PRIMARY KEY (sender, timestamp, part_index, signal_receiver); -ALTER TABLE message DROP CONSTRAINT IF EXISTS message_signal_chat_id_signal_receiver_fkey; -ALTER TABLE message DROP CONSTRAINT IF EXISTS message_signal_chat_id_fkey; --- Also update the reaction primary key -ALTER TABLE reaction DROP CONSTRAINT reaction_pkey; -ALTER TABLE reaction ADD PRIMARY KEY (author, msg_author, msg_timestamp, signal_receiver); - --- Change unique constraint from (mxid, mx_room) to just mxid. -ALTER TABLE message DROP CONSTRAINT message_mxid_mx_room_key; -ALTER TABLE message ADD CONSTRAINT message_mxid_unique UNIQUE (mxid); -ALTER TABLE reaction DROP CONSTRAINT reaction_mxid_mx_room_key; -ALTER TABLE reaction ADD CONSTRAINT reaction_mxid_unique UNIQUE (mxid); - -CREATE TABLE lost_portals ( - mxid TEXT PRIMARY KEY, - chat_id TEXT, - receiver TEXT -); -INSERT INTO lost_portals SELECT mxid, chat_id, receiver FROM portal WHERE mxid<>''; - --- Make mxid column unique (requires using nulls for missing values) -UPDATE portal SET mxid=NULL WHERE mxid=''; -ALTER TABLE portal ADD CONSTRAINT portal_mxid_unique UNIQUE(mxid); --- Delete any portals that aren't associated with logged-in users. -DELETE FROM portal WHERE receiver<>'' AND receiver NOT IN (SELECT username FROM "user" WHERE username IS NOT NULL AND uuid IS NOT NULL); --- CASCADE manually -DELETE FROM message - WHERE (signal_chat_id, signal_receiver) - NOT IN (SELECT DISTINCT signal_chat_id, signal_receiver FROM message WHERE (signal_chat_id, signal_receiver) IN (SELECT DISTINCT chat_id, receiver FROM portal)); -DELETE FROM reaction - WHERE (author, msg_author, msg_timestamp, signal_receiver) - NOT IN (SELECT DISTINCT author, msg_author, msg_timestamp, signal_receiver FROM reaction WHERE (msg_author, msg_timestamp, _part_index, signal_receiver) IN (SELECT DISTINCT sender, timestamp, part_index, signal_receiver FROM message)); --- Change receiver to uuid instead of phone number, also add nil uuid for groups. -UPDATE portal SET receiver=(SELECT uuid FROM "user" WHERE username=receiver AND uuid IS NOT NULL LIMIT 1) WHERE receiver<>''; -UPDATE portal SET receiver='00000000-0000-0000-0000-000000000000' WHERE receiver=''; --- CASCADE manually -UPDATE message SET signal_receiver=(SELECT uuid FROM "user" WHERE username=signal_receiver AND uuid IS NOT NULL LIMIT 1) WHERE signal_receiver<>''; -UPDATE message SET signal_receiver='00000000-0000-0000-0000-000000000000' WHERE signal_receiver=''; -UPDATE reaction SET signal_receiver=(SELECT uuid FROM "user" WHERE username=signal_receiver AND uuid IS NOT NULL LIMIT 1) WHERE signal_receiver<>''; -UPDATE reaction SET signal_receiver='00000000-0000-0000-0000-000000000000' WHERE signal_receiver=''; --- Change column types -ALTER TABLE portal ALTER COLUMN receiver TYPE uuid USING receiver::uuid; -ALTER TABLE message ALTER COLUMN signal_receiver TYPE uuid USING signal_receiver::uuid; -ALTER TABLE reaction ALTER COLUMN signal_receiver TYPE uuid USING signal_receiver::uuid; --- Re-add the dropped constraints again -ALTER TABLE message ADD CONSTRAINT message_portal_fkey - FOREIGN KEY (signal_chat_id, signal_receiver) - REFERENCES portal (chat_id, receiver) - ON DELETE CASCADE ON UPDATE CASCADE; -ALTER TABLE reaction ADD CONSTRAINT reaction_message_fkey FOREIGN KEY (msg_author, msg_timestamp, _part_index, signal_receiver) - REFERENCES message (sender, timestamp, part_index, signal_receiver) ON DELETE CASCADE ON UPDATE CASCADE; --- Delete group v1 portal entries -DELETE FROM portal WHERE chat_id NOT LIKE '________-____-____-____-____________' AND LENGTH(chat_id) <> 44; -DELETE FROM lost_portals WHERE mxid IN (SELECT mxid FROM portal WHERE mxid<>''); - --- Remove unnecessary nullables in portal -UPDATE portal SET name='' WHERE name IS NULL; -UPDATE portal SET topic='' WHERE topic IS NULL; -UPDATE portal SET avatar_hash='' WHERE avatar_hash IS NULL; -UPDATE portal SET avatar_url='' WHERE avatar_url IS NULL; -UPDATE portal SET expiration_time=0 WHERE expiration_time IS NULL; -UPDATE portal SET relay_user_id='' WHERE relay_user_id IS NULL; -ALTER TABLE portal ALTER COLUMN name SET NOT NULL; -ALTER TABLE portal ALTER COLUMN topic SET NOT NULL; -ALTER TABLE portal ALTER COLUMN avatar_hash SET NOT NULL; -ALTER TABLE portal ALTER COLUMN avatar_url SET NOT NULL; -ALTER TABLE portal ALTER COLUMN expiration_time SET NOT NULL; -ALTER TABLE portal ALTER COLUMN relay_user_id SET NOT NULL; - --- Add unique constraint to custom_mxid -UPDATE puppet - SET custom_mxid=NULL, access_token='' - WHERE custom_mxid<>'' - AND uuid<>COALESCE((SELECT uuid FROM "user" WHERE mxid=custom_mxid), '00000000-0000-0000-0000-000000000000'); -UPDATE puppet SET custom_mxid=NULL WHERE custom_mxid=''; -ALTER TABLE puppet ADD CONSTRAINT puppet_custom_mxid_unique UNIQUE(custom_mxid); --- Remove unnecessary nullables in puppet -UPDATE puppet SET name='' WHERE name IS NULL; -UPDATE puppet SET avatar_hash='' WHERE avatar_hash IS NULL; -UPDATE puppet SET avatar_url='' WHERE avatar_url IS NULL; -UPDATE puppet SET access_token='' WHERE access_token IS NULL; -ALTER TABLE puppet ALTER COLUMN name SET NOT NULL; -ALTER TABLE puppet ALTER COLUMN avatar_hash SET NOT NULL; -ALTER TABLE puppet ALTER COLUMN avatar_url SET NOT NULL; -ALTER TABLE puppet ALTER COLUMN access_token SET NOT NULL; -ALTER TABLE puppet ALTER COLUMN name_quality DROP DEFAULT; - -UPDATE "user" - SET uuid=NULL - WHERE uuid IN (SELECT DISTINCT uuid FROM "user" WHERE uuid IS NOT NULL GROUP BY uuid HAVING COUNT(*)>1); -ALTER TABLE "user" ADD CONSTRAINT user_uuid_unique UNIQUE(uuid); -ALTER TABLE "user" RENAME COLUMN username TO phone; - --- Drop room_id from disappearing message primary key -ALTER TABLE disappearing_message DROP CONSTRAINT disappearing_message_pkey; -ALTER TABLE disappearing_message ADD PRIMARY KEY (mxid); --- Remove unnecessary nullables in disappearing_message -ALTER TABLE disappearing_message ALTER COLUMN room_id SET NOT NULL; -UPDATE disappearing_message SET expiration_seconds=0 WHERE expiration_seconds IS NULL; -ALTER TABLE disappearing_message ALTER COLUMN expiration_seconds SET NOT NULL; diff --git a/database/upgrades/17-refactor-sqlite.sql b/database/upgrades/17-refactor-sqlite.sql deleted file mode 100644 index f55dc0b..0000000 --- a/database/upgrades/17-refactor-sqlite.sql +++ /dev/null @@ -1,198 +0,0 @@ --- v17: Refactor types (SQLite) --- transaction: off --- only: sqlite - --- This is separate from v16 so that postgres can run with transaction: on --- (split upgrades by dialect don't currently allow disabling transaction in only one dialect) - -DROP TABLE IF EXISTS user_portal; - -PRAGMA foreign_keys = OFF; -BEGIN; - -CREATE TABLE message_new ( - sender uuid NOT NULL, - timestamp BIGINT NOT NULL, - part_index INTEGER NOT NULL, - - signal_chat_id TEXT NOT NULL, - signal_receiver TEXT NOT NULL, - - mxid TEXT NOT NULL, - mx_room TEXT NOT NULL, - - PRIMARY KEY (sender, timestamp, part_index, signal_receiver), - CONSTRAINT message_portal_fkey FOREIGN KEY (signal_chat_id, signal_receiver) REFERENCES portal(chat_id, receiver) ON DELETE CASCADE ON UPDATE CASCADE, - FOREIGN KEY (sender) REFERENCES puppet(uuid) ON DELETE CASCADE, - CONSTRAINT message_mxid_unique UNIQUE (mxid) -); - -CREATE TABLE reaction_new ( - msg_author uuid NOT NULL, - msg_timestamp BIGINT NOT NULL, - -- part_index is not used in reactions, but is required for the foreign key. - _part_index INTEGER NOT NULL DEFAULT 0, - - author uuid NOT NULL, - emoji TEXT NOT NULL, - - signal_chat_id TEXT NOT NULL, - signal_receiver TEXT NOT NULL, - - mxid TEXT NOT NULL, - mx_room TEXT NOT NULL, - - PRIMARY KEY (msg_author, msg_timestamp, author, signal_receiver), - CONSTRAINT reaction_message_fkey FOREIGN KEY (msg_author, msg_timestamp, _part_index, signal_receiver) - REFERENCES message (sender, timestamp, part_index, signal_receiver) ON DELETE CASCADE ON UPDATE CASCADE, - FOREIGN KEY (author) REFERENCES puppet(uuid) ON DELETE CASCADE, - CONSTRAINT reaction_mxid_unique UNIQUE (mxid) -); - - -DELETE FROM message - WHERE (sender, timestamp, signal_receiver) - IN (SELECT sender, timestamp, signal_receiver FROM message GROUP BY sender, timestamp, signal_receiver HAVING COUNT(*)>1); - -INSERT INTO message_new -SELECT sender, - CASE WHEN timestamp > 1500000000000000 THEN timestamp / 1000 ELSE timestamp END, - CASE WHEN timestamp > 1500000000000000 THEN timestamp % 1000 ELSE 0 END, - COALESCE(signal_chat_id, ''), - COALESCE(signal_receiver, ''), - mxid, - mx_room -FROM message; - -INSERT INTO reaction_new -SELECT msg_author, - msg_timestamp, - 0, -- _part_index - author, - emoji, - COALESCE(signal_chat_id, ''), - COALESCE(signal_receiver, ''), - mxid, - mx_room -FROM reaction -WHERE msg_timestamp<1500000000000000; - -DROP TABLE message; -DROP TABLE reaction; -ALTER TABLE message_new RENAME TO message; -ALTER TABLE reaction_new RENAME TO reaction; - -PRAGMA foreign_key_check; -COMMIT; - -PRAGMA foreign_keys = ON; - -BEGIN; -CREATE TABLE lost_portals ( - mxid TEXT PRIMARY KEY, - chat_id TEXT, - receiver TEXT -); -INSERT INTO lost_portals SELECT mxid, chat_id, receiver FROM portal WHERE mxid<>''; -DELETE FROM portal WHERE receiver<>'' AND receiver NOT IN (SELECT username FROM "user" WHERE username IS NOT NULL AND uuid<>''); -UPDATE portal SET receiver=(SELECT uuid FROM "user" WHERE username=receiver AND uuid<>'' LIMIT 1) WHERE receiver<>''; -UPDATE portal SET receiver='00000000-0000-0000-0000-000000000000' WHERE receiver=''; -DELETE FROM portal WHERE chat_id NOT LIKE '________-____-____-____-____________' AND LENGTH(chat_id) <> 44; -DELETE FROM lost_portals WHERE mxid IN (SELECT mxid FROM portal WHERE mxid<>''); -COMMIT; - -PRAGMA foreign_keys = OFF; - -BEGIN; - -CREATE TABLE portal_new ( - chat_id TEXT NOT NULL, - receiver uuid NOT NULL, - mxid TEXT, - name TEXT NOT NULL, - topic TEXT NOT NULL, - encrypted BOOLEAN NOT NULL DEFAULT false, - avatar_hash TEXT NOT NULL, - avatar_url TEXT NOT NULL, - name_set BOOLEAN NOT NULL DEFAULT false, - avatar_set BOOLEAN NOT NULL DEFAULT false, - revision INTEGER NOT NULL DEFAULT 0, - - expiration_time BIGINT NOT NULL, - relay_user_id TEXT NOT NULL, - - PRIMARY KEY (chat_id, receiver), - CONSTRAINT portal_mxid_unique UNIQUE(mxid) -); - -INSERT INTO portal_new - SELECT chat_id, receiver, CASE WHEN mxid='' THEN NULL ELSE mxid END, - COALESCE(name, ''), COALESCE(topic, ''), encrypted, COALESCE(avatar_hash, ''), COALESCE(avatar_url, ''), - name_set, avatar_set, revision, COALESCE(expiration_time, 0), COALESCE(relay_user_id, '') - FROM portal; -DROP TABLE portal; -ALTER TABLE portal_new RENAME TO portal; - -CREATE TABLE puppet_new ( - uuid uuid PRIMARY KEY, - number TEXT UNIQUE, - name TEXT NOT NULL, - name_quality INTEGER NOT NULL, - avatar_hash TEXT NOT NULL, - avatar_url TEXT NOT NULL, - name_set BOOLEAN NOT NULL DEFAULT false, - avatar_set BOOLEAN NOT NULL DEFAULT false, - - is_registered BOOLEAN NOT NULL DEFAULT false, - contact_info_set BOOLEAN NOT NULL DEFAULT false, - - custom_mxid TEXT, - access_token TEXT NOT NULL, - - CONSTRAINT puppet_custom_mxid_unique UNIQUE(custom_mxid) -); - -UPDATE puppet - SET custom_mxid=NULL, access_token='' - WHERE custom_mxid<>'' - AND uuid<>COALESCE((SELECT uuid FROM "user" WHERE mxid=custom_mxid), '00000000-0000-0000-0000-000000000000'); -INSERT INTO puppet_new - SELECT uuid, number, COALESCE(name, ''), COALESCE(name_quality, 0), COALESCE(avatar_hash, ''), - COALESCE(avatar_url, ''), name_set, avatar_set, is_registered, contact_info_set, - CASE WHEN custom_mxid='' THEN NULL ELSE custom_mxid END, COALESCE(access_token, '') - FROM puppet; -DROP TABLE puppet; -ALTER TABLE puppet_new RENAME TO puppet; - -CREATE TABLE user_new ( - mxid TEXT PRIMARY KEY, - uuid uuid, - phone TEXT, - - management_room TEXT, - - CONSTRAINT user_uuid_unique UNIQUE(uuid) -); - -INSERT INTO user_new - SELECT mxid, uuid, username, management_room - FROM user; -DROP TABLE user; -ALTER TABLE user_new RENAME TO user; - -CREATE TABLE disappearing_message_new ( - mxid TEXT NOT NULL PRIMARY KEY, - room_id TEXT NOT NULL, - expiration_seconds BIGINT NOT NULL, - expiration_ts BIGINT -); - -INSERT INTO disappearing_message_new - SELECT mxid, room_id, COALESCE(expiration_seconds, 0), expiration_ts - FROM disappearing_message; -DROP TABLE disappearing_message; -ALTER TABLE disappearing_message_new RENAME TO disappearing_message; - -PRAGMA foreign_key_check; -COMMIT; -PRAGMA foreign_keys = ON; diff --git a/database/upgrades/18-spaces.sql b/database/upgrades/18-spaces.sql deleted file mode 100644 index 24248ba..0000000 --- a/database/upgrades/18-spaces.sql +++ /dev/null @@ -1,17 +0,0 @@ --- v18 (compatible with v17+): Add columns for personal filtering space info -ALTER TABLE "user" ADD COLUMN space_room TEXT; - -DROP TABLE IF EXISTS user_portal; -CREATE TABLE user_portal ( - user_mxid TEXT, - portal_chat_id TEXT, - portal_receiver uuid, - last_read_ts BIGINT NOT NULL DEFAULT 0, - in_space BOOLEAN NOT NULL DEFAULT false, - - PRIMARY KEY (user_mxid, portal_chat_id, portal_receiver), - CONSTRAINT user_portal_user_fkey FOREIGN KEY (user_mxid) - REFERENCES "user"(mxid) ON UPDATE CASCADE ON DELETE CASCADE, - CONSTRAINT user_portal_portal_fkey FOREIGN KEY (portal_chat_id, portal_receiver) - REFERENCES portal(chat_id, receiver) ON UPDATE CASCADE ON DELETE CASCADE -); diff --git a/database/upgrades/19-more-portal-metadata.sql b/database/upgrades/19-more-portal-metadata.sql deleted file mode 100644 index 6230b21..0000000 --- a/database/upgrades/19-more-portal-metadata.sql +++ /dev/null @@ -1,5 +0,0 @@ --- v19 (compatible with v17+): Add more metadata for portals -ALTER TABLE portal ADD COLUMN topic_set BOOLEAN NOT NULL DEFAULT false; -UPDATE portal SET topic_set=true WHERE topic<>''; -ALTER TABLE portal ADD COLUMN avatar_path TEXT NOT NULL DEFAULT ''; -ALTER TABLE puppet ADD COLUMN avatar_path TEXT NOT NULL DEFAULT ''; diff --git a/database/upgrades/20-puppet-profile-fetch-ts.sql b/database/upgrades/20-puppet-profile-fetch-ts.sql deleted file mode 100644 index b398b2f..0000000 --- a/database/upgrades/20-puppet-profile-fetch-ts.sql +++ /dev/null @@ -1,2 +0,0 @@ --- v20 (compatible with v17+): Add profile fetch timestamp for puppets -ALTER TABLE puppet ADD profile_fetched_at BIGINT; diff --git a/database/user.go b/database/user.go deleted file mode 100644 index aa90686..0000000 --- a/database/user.go +++ /dev/null @@ -1,115 +0,0 @@ -// mautrix-signal - A Matrix-signal puppeting bridge. -// Copyright (C) 2023 Scott Weber, Tulir Asokan -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see . - -package database - -import ( - "context" - "database/sql" - "sync" - - "github.com/google/uuid" - "go.mau.fi/util/dbutil" - "maunium.net/go/mautrix/id" -) - -const ( - getUserByMXIDQuery = `SELECT mxid, phone, uuid, management_room, space_room FROM "user" WHERE mxid=$1` - getUserByPhoneQuery = `SELECT mxid, phone, uuid, management_room, space_room FROM "user" WHERE phone=$1` - getUserByUUIDQuery = `SELECT mxid, phone, uuid, management_room, space_room FROM "user" WHERE uuid=$1` - getAllLoggedInUsersQuery = `SELECT mxid, phone, uuid, management_room, space_room FROM "user" WHERE phone IS NOT NULL` - insertUserQuery = `INSERT INTO "user" (mxid, phone, uuid, management_room, space_room) VALUES ($1, $2, $3, $4, $5)` - updateUserQuery = `UPDATE "user" SET phone=$2, uuid=$3, management_room=$4, space_room=$5 WHERE mxid=$1` -) - -type UserQuery struct { - *dbutil.QueryHelper[*User] -} - -type User struct { - qh *dbutil.QueryHelper[*User] - - MXID id.UserID - SignalUsername string - SignalID uuid.UUID - ManagementRoom id.RoomID - SpaceRoom id.RoomID - - lastReadCache map[PortalKey]uint64 - lastReadCacheLock sync.Mutex - inSpaceCache map[PortalKey]bool - inSpaceCacheLock sync.Mutex -} - -func newUser(qh *dbutil.QueryHelper[*User]) *User { - return &User{ - qh: qh, - - lastReadCache: make(map[PortalKey]uint64), - inSpaceCache: make(map[PortalKey]bool), - } -} - -func (uq *UserQuery) GetByMXID(ctx context.Context, mxid id.UserID) (*User, error) { - return uq.QueryOne(ctx, getUserByMXIDQuery, mxid) -} - -func (uq *UserQuery) GetByPhone(ctx context.Context, phone string) (*User, error) { - return uq.QueryOne(ctx, getUserByPhoneQuery, phone) -} - -func (uq *UserQuery) GetBySignalID(ctx context.Context, uuid uuid.UUID) (*User, error) { - return uq.QueryOne(ctx, getUserByUUIDQuery, uuid) -} - -func (uq *UserQuery) GetAllLoggedIn(ctx context.Context) ([]*User, error) { - return uq.QueryMany(ctx, getAllLoggedInUsersQuery) -} - -func (u *User) sqlVariables() []any { - var nu uuid.NullUUID - nu.UUID = u.SignalID - nu.Valid = u.SignalID != uuid.Nil - return []any{u.MXID, dbutil.StrPtr(u.SignalUsername), nu, dbutil.StrPtr(u.ManagementRoom), dbutil.StrPtr(u.SpaceRoom)} -} - -func (u *User) Insert(ctx context.Context) error { - return u.qh.Exec(ctx, insertUserQuery, u.sqlVariables()...) -} - -func (u *User) Update(ctx context.Context) error { - return u.qh.Exec(ctx, updateUserQuery, u.sqlVariables()...) -} - -func (u *User) Scan(row dbutil.Scannable) (*User, error) { - var phone, managementRoom, spaceRoom sql.NullString - var signalID uuid.NullUUID - err := row.Scan( - &u.MXID, - &phone, - &signalID, - &managementRoom, - &spaceRoom, - ) - if err != nil { - return nil, err - } - u.SignalUsername = phone.String - u.SignalID = signalID.UUID - u.ManagementRoom = id.RoomID(managementRoom.String) - u.SpaceRoom = id.RoomID(spaceRoom.String) - return u, nil -} diff --git a/database/userportal.go b/database/userportal.go deleted file mode 100644 index 6081ee8..0000000 --- a/database/userportal.go +++ /dev/null @@ -1,116 +0,0 @@ -// mautrix-signal - A Matrix-signal puppeting bridge. -// Copyright (C) 2023 Scott Weber, Tulir Asokan -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see . - -package database - -import ( - "context" - "database/sql" - "errors" - - "github.com/rs/zerolog" -) - -const ( - getLastReadTSQuery = `SELECT last_read_ts FROM user_portal WHERE user_mxid=$1 AND portal_chat_id=$2 AND portal_receiver=$3` - setLastReadTSQuery = ` - INSERT INTO user_portal (user_mxid, portal_chat_id, portal_receiver, last_read_ts) VALUES ($1, $2, $3, $4) - ON CONFLICT (user_mxid, portal_chat_id, portal_receiver) DO UPDATE - SET last_read_ts=excluded.last_read_ts WHERE user_portal.last_read_ts. - -package main - -import ( - "context" - "fmt" - "time" - - "github.com/rs/zerolog" - "maunium.net/go/mautrix" - "maunium.net/go/mautrix/id" - - "go.mau.fi/mautrix-signal/database" -) - -type DisappearingMessagesManager struct { - DB *database.Database - Log zerolog.Logger - Bridge *SignalBridge - checkMessagesChan chan struct{} -} - -func (dmm *DisappearingMessagesManager) ScheduleDisappearingForRoom(ctx context.Context, roomID id.RoomID) { - log := dmm.Log.With().Stringer("room_id", roomID).Logger() - disappearingMessages, err := dmm.DB.DisappearingMessage.GetUnscheduledForRoom(ctx, roomID) - if err != nil { - log.Err(err).Msg("Failed to get unscheduled disappearing messages") - return - } - for _, disappearingMessage := range disappearingMessages { - err = disappearingMessage.StartExpirationTimer(ctx) - if err != nil { - log.Err(err).Msg("Failed to schedule disappearing message") - } else { - log.Debug(). - Stringer("event_id", disappearingMessage.EventID). - Time("expire_at", disappearingMessage.ExpireAt). - Msg("Scheduling disappearing message") - } - } - - // Tell the disappearing messages loop to check again - dmm.checkMessagesChan <- struct{}{} -} - -func (dmm *DisappearingMessagesManager) StartDisappearingLoop(ctx context.Context) { - dmm.checkMessagesChan = make(chan struct{}, 1) - go func() { - log := dmm.Log.With().Str("action", "loop").Logger() - ctx = log.WithContext(ctx) - for { - dmm.redactExpiredMessages(ctx) - - duration := 10 * time.Minute // Check again in 10 minutes just in case - nextMsg, err := dmm.DB.DisappearingMessage.GetNextScheduledMessage(ctx) - if err != nil { - if ctx.Err() != nil { - return - } - log.Err(err).Msg("Failed to get next disappearing message") - continue - } else if nextMsg != nil { - duration = time.Until(nextMsg.ExpireAt) - } - - select { - case <-time.After(duration): - case <-dmm.checkMessagesChan: - case <-ctx.Done(): - return - } - } - }() -} - -func (dmm *DisappearingMessagesManager) redactExpiredMessages(ctx context.Context) { - log := zerolog.Ctx(ctx) - expiredMessages, err := dmm.DB.DisappearingMessage.GetExpiredMessages(ctx) - if err != nil { - log.Err(err).Msg("Failed to get expired disappearing messages") - return - } - - for _, msg := range expiredMessages { - portal := dmm.Bridge.GetPortalByMXID(msg.RoomID) - if portal == nil { - log.Warn().Stringer("event_id", msg.EventID).Stringer("room_id", msg.RoomID).Msg("Failed to redact message: portal not found") - err = msg.Delete(ctx) - if err != nil { - log.Err(err). - Stringer("event_id", msg.EventID). - Msg("Failed to delete disappearing message row in database") - } - continue - } - _, err = portal.MainIntent().RedactEvent(ctx, msg.RoomID, msg.EventID, mautrix.ReqRedact{ - Reason: "Message expired", - TxnID: fmt.Sprintf("mxsg_disappear_%s", msg.EventID), - }) - if err != nil { - log.Err(err). - Stringer("event_id", msg.EventID). - Stringer("room_id", msg.RoomID). - Msg("Failed to redact message") - } else { - log.Err(err). - Stringer("event_id", msg.EventID). - Stringer("room_id", msg.RoomID). - Msg("Redacted message") - } - err = msg.Delete(ctx) - if err != nil { - log.Err(err). - Stringer("event_id", msg.EventID). - Msg("Failed to delete disappearing message row in database") - } - } -} - -func (dmm *DisappearingMessagesManager) AddDisappearingMessage(ctx context.Context, eventID id.EventID, roomID id.RoomID, expireIn time.Duration, startTimerNow bool) { - if expireIn == 0 { - return - } - var expireAt time.Time - if startTimerNow { - expireAt = time.Now().Add(expireIn) - } - disappearingMessage := dmm.DB.DisappearingMessage.NewWithValues(roomID, eventID, expireIn, expireAt) - err := disappearingMessage.Insert(ctx) - if err != nil { - zerolog.Ctx(ctx).Err(err).Stringer("event_id", eventID). - Msg("Failed to add disappearing message to database") - return - } - zerolog.Ctx(ctx).Debug().Stringer("event_id", eventID). - Msg("Added disappearing message row to database") - if startTimerNow { - // Tell the disappearing messages loop to check again - dmm.checkMessagesChan <- struct{}{} - } -} diff --git a/docker-run.sh b/docker-run.sh index fdb22b2..5f1ec65 100755 --- a/docker-run.sh +++ b/docker-run.sh @@ -17,11 +17,7 @@ function fixperms { } if [[ ! -f /data/config.yaml ]]; then - if [[ "$BRIDGEV2" == "1" ]]; then - $BINARY_NAME -c /data/config.yaml -e - else - cp /opt/mautrix-signal/example-config.yaml /data/config.yaml - fi + $BINARY_NAME -c /data/config.yaml -e echo "Didn't find a config file." echo "Copied default config file to /data/config.yaml" echo "Modify that config file to your liking." diff --git a/example-config.yaml b/example-config.yaml deleted file mode 100644 index 93a7955..0000000 --- a/example-config.yaml +++ /dev/null @@ -1,317 +0,0 @@ -# Homeserver details. -homeserver: - # The address that this appservice can use to connect to the homeserver. - address: https://matrix.example.com - # The domain of the homeserver (also known as server_name, used for MXIDs, etc). - domain: example.com - - # What software is the homeserver running? - # Standard Matrix homeservers like Synapse, Dendrite and Conduit should just use "standard" here. - software: standard - # The URL to push real-time bridge status to. - # If set, the bridge will make POST requests to this URL whenever a user's Signal connection state changes. - # The bridge will use the appservice as_token to authorize requests. - status_endpoint: null - # Endpoint for reporting per-message status. - message_send_checkpoint_endpoint: null - # Does the homeserver support https://github.com/matrix-org/matrix-spec-proposals/pull/2246? - async_media: false - - # Should the bridge use a websocket for connecting to the homeserver? - # The server side is currently not documented anywhere and is only implemented by mautrix-wsproxy, - # mautrix-asmux (deprecated), and hungryserv (proprietary). - websocket: false - # How often should the websocket be pinged? Pinging will be disabled if this is zero. - ping_interval_seconds: 0 - -# Application service host/registration related details. -# Changing these values requires regeneration of the registration. -appservice: - # The address that the homeserver can use to connect to this appservice. - address: http://localhost:29328 - - # The hostname and port where this appservice should listen. - hostname: 0.0.0.0 - port: 29328 - - # Database config. - database: - # The database type. "sqlite3-fk-wal" and "postgres" are supported. - type: postgres - # The database URI. - # SQLite: A raw file path is supported, but `file:?_txlock=immediate` is recommended. - # https://github.com/mattn/go-sqlite3#connection-string - # Postgres: Connection string. For example, postgres://user:password@host/database?sslmode=disable - # To connect via Unix socket, use something like postgres:///dbname?host=/var/run/postgresql - uri: postgres://user:password@host/database?sslmode=disable - # Maximum number of connections. Mostly relevant for Postgres. - max_open_conns: 20 - max_idle_conns: 2 - # Maximum connection idle time and lifetime before they're closed. Disabled if null. - # Parsed with https://pkg.go.dev/time#ParseDuration - max_conn_idle_time: null - max_conn_lifetime: null - - # The unique ID of this appservice. - id: signal - # Appservice bot details. - bot: - # Username of the appservice bot. - username: signalbot - # Display name and avatar for bot. Set to "remove" to remove display name/avatar, leave empty - # to leave display name/avatar as-is. - displayname: Signal bridge bot - avatar: mxc://maunium.net/wPJgTQbZOtpBFmDNkiNEMDUp - - # Whether or not to receive ephemeral events via appservice transactions. - # Requires MSC2409 support (i.e. Synapse 1.22+). - ephemeral_events: true - - # Should incoming events be handled asynchronously? - # This may be necessary for large public instances with lots of messages going through. - # However, messages will not be guaranteed to be bridged in the same order they were sent in. - async_transactions: false - - # Authentication tokens for AS <-> HS communication. Autogenerated; do not modify. - as_token: "This value is generated when generating the registration" - hs_token: "This value is generated when generating the registration" - -# Prometheus config. -metrics: - # Enable prometheus metrics? - enabled: false - # IP and port where the metrics listener should be. The path is always /metrics - listen: 127.0.0.1:8000 - -signal: - # Default device name that shows up in the Signal app. - device_name: mautrix-signal - -# Bridge config -bridge: - # Localpart template of MXIDs for Signal users. - # {{.}} is replaced with the internal ID of the Signal user. - username_template: signal_{{.}} - # Displayname template for Signal users. This is also used as the room name in DMs if private_chat_portal_meta is enabled. - # {{.ProfileName}} - The Signal profile name set by the user. - # {{.ContactName}} - The name for the user from your phone's contact list. This is not safe on multi-user instances. - # {{.PhoneNumber}} - The phone number of the user. - # {{.UUID}} - The UUID of the Signal user. - # {{.AboutEmoji}} - The emoji set by the user in their profile. - displayname_template: '{{or .ProfileName .PhoneNumber "Unknown user"}}' - # Whether to explicitly set the avatar and room name for private chat portal rooms. - # If set to `default`, this will be enabled in encrypted rooms and disabled in unencrypted rooms. - # If set to `always`, all DM rooms will have explicit names and avatars set. - # If set to `never`, DM rooms will never have names and avatars set. - private_chat_portal_meta: default - # Should avatars from the user's contact list be used? This is not safe on multi-user instances. - use_contact_avatars: false - # Should the bridge sync ghost user info even if profile fetching fails? This is not safe on multi-user instances. - use_outdated_profiles: false - # Should the Signal user's phone number be included in the room topic in private chat portal rooms? - number_in_topic: true - # Avatar image for the Note to Self room. - note_to_self_avatar: mxc://maunium.net/REBIVrqjZwmaWpssCZpBlmlL - - portal_message_buffer: 128 - - # Should the bridge create a space for each logged-in user and add bridged rooms to it? - # Users who logged in before turning this on should run `!signal sync-space` to create and fill the space for the first time. - personal_filtering_spaces: false - # Should Matrix m.notice-type messages be bridged? - bridge_notices: true - # Should the bridge send a read receipt from the bridge bot when a message has been sent to Signal? - delivery_receipts: false - # Whether the bridge should send the message status as a custom com.beeper.message_send_status event. - message_status_events: false - # Whether the bridge should send error notices via m.notice events when a message fails to bridge. - message_error_notices: true - # Should the bridge update the m.direct account data event when double puppeting is enabled. - # Note that updating the m.direct event is not atomic (except with mautrix-asmux) - # and is therefore prone to race conditions. - sync_direct_chat_list: false - # Set this to true to tell the bridge to re-send m.bridge events to all rooms on the next run. - # This field will automatically be changed back to false after it, except if the config file is not writable. - resend_bridge_info: false - # Whether or not to make portals of groups that don't need approval of an admin to join by invite - # link publicly joinable on Matrix. - public_portals: false - # Send captions in the same message as images. This will send data compatible with both MSC2530. - # This is currently not supported in most clients. - caption_in_message: false - # Format for generating URLs from location messages for sending to Signal - # Google Maps: 'https://www.google.com/maps/place/%[1]s,%[2]s' - # OpenStreetMap: 'https://www.openstreetmap.org/?mlat=%[1]s&mlon=%[2]s' - location_format: 'https://www.google.com/maps/place/%[1]s,%[2]s' - # Whether or not created rooms should have federation enabled. - # If false, created portal rooms will never be federated. - federate_rooms: true - # Servers to always allow double puppeting from - double_puppet_server_map: - example.com: https://example.com - # Allow using double puppeting from any server with a valid client .well-known file. - double_puppet_allow_discovery: false - # Shared secrets for https://github.com/devture/matrix-synapse-shared-secret-auth - # - # If set, double puppeting will be enabled automatically for local users - # instead of users having to find an access token and run `login-matrix` - # manually. - login_shared_secret_map: - example.com: foobar - - # Maximum time for handling Matrix events. Duration strings formatted for https://pkg.go.dev/time#ParseDuration - # Null means there's no enforced timeout. - message_handling_timeout: - # Send an error message after this timeout, but keep waiting for the response until the deadline. - # This is counted from the origin_server_ts, so the warning time is consistent regardless of the source of delay. - # If the message is older than this when it reaches the bridge, the message won't be handled at all. - error_after: null - # Drop messages after this timeout. They may still go through if the message got sent to the servers. - # This is counted from the time the bridge starts handling the message. - deadline: 120s - - # The prefix for commands. Only required in non-management rooms. - command_prefix: '!signal' - # Messages sent upon joining a management room. - # Markdown is supported. The defaults are listed below. - management_room_text: - # Sent when joining a room. - welcome: "Hello, I'm a Signal bridge bot." - # Sent when joining a management room and the user is already logged in. - welcome_connected: "Use `help` for help." - # Sent when joining a management room and the user is not logged in. - welcome_unconnected: "Use `help` for help or `login` to log in." - # Optional extra text sent when joining a management room. - additional_help: "" - - # End-to-bridge encryption support options. - # - # See https://docs.mau.fi/bridges/general/end-to-bridge-encryption.html for more info. - encryption: - # Allow encryption, work in group chat rooms with e2ee enabled - allow: false - # Default to encryption, force-enable encryption in all portals the bridge creates - # This will cause the bridge bot to be in private chats for the encryption to work properly. - default: false - # Whether to use MSC2409/MSC3202 instead of /sync long polling for receiving encryption-related data. - appservice: false - # Require encryption, drop any unencrypted messages. - require: false - # Enable key sharing? If enabled, key requests for rooms where users are in will be fulfilled. - # You must use a client that supports requesting keys from other users to use this feature. - allow_key_sharing: false - # Options for deleting megolm sessions from the bridge. - delete_keys: - # Beeper-specific: delete outbound sessions when hungryserv confirms - # that the user has uploaded the key to key backup. - delete_outbound_on_ack: false - # Don't store outbound sessions in the inbound table. - dont_store_outbound: false - # Ratchet megolm sessions forward after decrypting messages. - ratchet_on_decrypt: false - # Delete fully used keys (index >= max_messages) after decrypting messages. - delete_fully_used_on_decrypt: false - # Delete previous megolm sessions from same device when receiving a new one. - delete_prev_on_new_session: false - # Delete megolm sessions received from a device when the device is deleted. - delete_on_device_delete: false - # Periodically delete megolm sessions when 2x max_age has passed since receiving the session. - periodically_delete_expired: false - # Delete inbound megolm sessions that don't have the received_at field used for - # automatic ratcheting and expired session deletion. This is meant as a migration - # to delete old keys prior to the bridge update. - delete_outdated_inbound: false - # What level of device verification should be required from users? - # - # Valid levels: - # unverified - Send keys to all device in the room. - # cross-signed-untrusted - Require valid cross-signing, but trust all cross-signing keys. - # cross-signed-tofu - Require valid cross-signing, trust cross-signing keys on first use (and reject changes). - # cross-signed-verified - Require valid cross-signing, plus a valid user signature from the bridge bot. - # Note that creating user signatures from the bridge bot is not currently possible. - # verified - Require manual per-device verification - # (currently only possible by modifying the `trust` column in the `crypto_device` database table). - verification_levels: - # Minimum level for which the bridge should send keys to when bridging messages from Signal to Matrix. - receive: unverified - # Minimum level that the bridge should accept for incoming Matrix messages. - send: unverified - # Minimum level that the bridge should require for accepting key requests. - share: cross-signed-tofu - # Options for Megolm room key rotation. These options allow you to - # configure the m.room.encryption event content. See: - # https://spec.matrix.org/v1.3/client-server-api/#mroomencryption for - # more information about that event. - rotation: - # Enable custom Megolm room key rotation settings. Note that these - # settings will only apply to rooms created after this option is - # set. - enable_custom: false - # The maximum number of milliseconds a session should be used - # before changing it. The Matrix spec recommends 604800000 (a week) - # as the default. - milliseconds: 604800000 - # The maximum number of messages that should be sent with a given a - # session before changing it. The Matrix spec recommends 100 as the - # default. - messages: 100 - - # Disable rotating keys when a user's devices change? - # You should not enable this option unless you understand all the implications. - disable_device_change_key_rotation: false - # Should leaving the room on Matrix make the user leave on Signal? - bridge_matrix_leave: true - # Settings for provisioning API - provisioning: - # Prefix for the provisioning API paths. - prefix: /_matrix/provision - # Shared secret for authentication. If set to "generate", a random secret will be generated, - # or if set to "disable", the provisioning API will be disabled. - shared_secret: generate - # Enable debug API at /debug with provisioning authentication. - debug_endpoints: false - - # Permissions for using the bridge. - # Permitted values: - # relay - Talk through the relaybot (if enabled), no access otherwise - # user - Access to use the bridge to chat with a Signal account. - # admin - User level and some additional administration tools - # Permitted keys: - # * - All Matrix users - # domain - All users on that homeserver - # mxid - Specific user - permissions: - "*": relay - "example.com": user - "@admin:example.com": admin - - # Settings for relay mode - relay: - # Whether relay mode should be allowed. If allowed, `!signal set-relay` can be used to turn any - # authenticated user into a relaybot for that chat. - enabled: false - # Should only admins be allowed to set themselves as relay users? - admin_only: true - # The formats to use when sending messages to Signal via the relaybot. - message_formats: - m.text: "{{ .Sender.Displayname }}: {{ .Message }}" - m.notice: "{{ .Sender.Displayname }}: {{ .Message }}" - m.emote: "* {{ .Sender.Displayname }} {{ .Message }}" - m.file: "{{ .Sender.Displayname }} sent a file" - m.image: "{{ .Sender.Displayname }} sent an image" - m.audio: "{{ .Sender.Displayname }} sent an audio file" - m.video: "{{ .Sender.Displayname }} sent a video" - m.location: "{{ .Sender.Displayname }} sent a location" - -# Logging config. See https://github.com/tulir/zeroconfig for details. -logging: - min_level: debug - writers: - - type: stdout - format: pretty-colored - - type: file - format: json - filename: ./logs/mautrix-signal.log - max_size: 100 - max_backups: 10 - compress: true diff --git a/go.mod b/go.mod index a04e88a..45187a6 100644 --- a/go.mod +++ b/go.mod @@ -48,3 +48,6 @@ require ( gopkg.in/yaml.v3 v3.0.1 // indirect maunium.net/go/mauflag v1.0.0 // indirect ) + +//replace maunium.net/go/mautrix => ../mautrix-go +//replace go.mau.fi/util => ../../Go/go-util diff --git a/legacyprovision/types.go b/legacyprovision/types.go deleted file mode 100644 index 72f393a..0000000 --- a/legacyprovision/types.go +++ /dev/null @@ -1,92 +0,0 @@ -// mautrix-signal - A Matrix-Signal puppeting bridge. -// Copyright (C) 2024 Tulir Asokan -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is istributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see . - -package legacyprovision - -import ( - "encoding/json" - "net/http" - - "maunium.net/go/mautrix/id" -) - -func JSONResponse(w http.ResponseWriter, status int, response any) { - w.Header().Add("Content-Type", "application/json") - w.WriteHeader(status) - _ = json.NewEncoder(w).Encode(response) -} - -type Error struct { - Success bool `json:"success"` - Error string `json:"error"` - ErrCode string `json:"errcode"` -} - -type Response struct { - Success bool `json:"success"` - Status string `json:"status"` - - // For response in LinkNew - SessionID string `json:"session_id,omitempty"` - URI string `json:"uri,omitempty"` - - // For response in LinkWaitForAccount - UUID string `json:"uuid,omitempty"` - Number string `json:"number,omitempty"` - - // For response in ResolveIdentifier - *ResolveIdentifierResponse -} - -type WhoAmIResponse struct { - Permissions int `json:"permissions"` - MXID string `json:"mxid"` - Signal *WhoAmIResponseSignal `json:"signal,omitempty"` -} - -type WhoAmIResponseSignal struct { - Number string `json:"number"` - UUID string `json:"uuid"` - Name string `json:"name"` - Ok bool `json:"ok"` -} - -type ResolveIdentifierResponse struct { - RoomID id.RoomID `json:"room_id"` - ChatID ResolveIdentifierResponseChatID `json:"chat_id"` - JustCreated bool `json:"just_created"` - OtherUser *ResolveIdentifierResponseOtherUser `json:"other_user,omitempty"` -} - -type ResolveIdentifierResponseChatID struct { - UUID string `json:"uuid"` - Number string `json:"number"` -} - -type ResolveIdentifierResponseOtherUser struct { - MXID id.UserID `json:"mxid"` - DisplayName string `json:"displayname"` - AvatarURL id.ContentURI `json:"avatar_url"` -} - -type LinkWaitForScanRequest struct { - SessionID string `json:"session_id"` -} - -type LinkWaitForAccountRequest struct { - SessionID string `json:"session_id"` - DeviceName string `json:"device_name"` // TODO this seems to not be used anywhere -} diff --git a/main.go b/main.go deleted file mode 100644 index eb24aa0..0000000 --- a/main.go +++ /dev/null @@ -1,352 +0,0 @@ -// mautrix-signal - A Matrix-signal puppeting bridge. -// Copyright (C) 2023 Scott Weber -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see . - -package main - -import ( - "context" - _ "embed" - "fmt" - "os" - "sync" - - "github.com/google/uuid" - "github.com/rs/zerolog" - "go.mau.fi/util/configupgrade" - "go.mau.fi/util/dbutil" - "maunium.net/go/mautrix" - "maunium.net/go/mautrix/bridge" - "maunium.net/go/mautrix/bridge/commands" - "maunium.net/go/mautrix/event" - "maunium.net/go/mautrix/format" - "maunium.net/go/mautrix/id" - - "go.mau.fi/mautrix-signal/config" - "go.mau.fi/mautrix-signal/database" - "go.mau.fi/mautrix-signal/msgconv/matrixfmt" - "go.mau.fi/mautrix-signal/msgconv/signalfmt" - "go.mau.fi/mautrix-signal/pkg/signalmeow" - "go.mau.fi/mautrix-signal/pkg/signalmeow/store" -) - -//go:embed example-config.yaml -var ExampleConfig string - -// Information to find out exactly which commit the bridge was built from. -// These are filled at build time with the -X linker flag. -var ( - Tag = "unknown" - Commit = "unknown" - BuildTime = "unknown" -) - -type SignalBridge struct { - bridge.Bridge - - Config *config.Config - DB *database.Database - Metrics *MetricsHandler - MeowStore *store.Container - - provisioning *ProvisioningAPI - - usersByMXID map[id.UserID]*User - usersBySignalID map[uuid.UUID]*User - usersLock sync.Mutex - - managementRooms map[id.RoomID]*User - managementRoomsLock sync.Mutex - - portalsByMXID map[id.RoomID]*Portal - portalsByID map[database.PortalKey]*Portal - portalsLock sync.Mutex - - puppets map[uuid.UUID]*Puppet - puppetsByCustomMXID map[id.UserID]*Puppet - puppetsLock sync.Mutex - - disappearingMessagesManager *DisappearingMessagesManager -} - -var _ bridge.ChildOverride = (*SignalBridge)(nil) - -func (br *SignalBridge) GetExampleConfig() string { - return ExampleConfig -} - -func (br *SignalBridge) GetConfigPtr() interface{} { - br.Config = &config.Config{ - BaseConfig: &br.Bridge.Config, - } - br.Config.BaseConfig.Bridge = &br.Config.Bridge - return br.Config -} - -func (br *SignalBridge) Init() { - br.CommandProcessor = commands.NewProcessor(&br.Bridge) - br.RegisterCommands() - - signalmeow.SetLogger(br.ZLog.With().Str("component", "signalmeow").Logger()) - - br.DB = database.New(br.Bridge.DB) - br.MeowStore = store.NewStore(br.Bridge.DB, dbutil.ZeroLogger(br.ZLog.With().Str("db_section", "signalmeow").Logger())) - - ss := br.Config.Bridge.Provisioning.SharedSecret - if len(ss) > 0 && ss != "disable" { - br.provisioning = &ProvisioningAPI{bridge: br, log: br.ZLog.With().Str("component", "provisioning").Logger()} - } - br.disappearingMessagesManager = &DisappearingMessagesManager{ - DB: br.DB, - Log: br.ZLog.With().Str("component", "disappearing messages").Logger(), - Bridge: br, - } - - br.Metrics = NewMetricsHandler(br.Config.Metrics.Listen, br.ZLog.With().Str("component", "metrics").Logger(), br.DB) - br.MatrixHandler.TrackEventDuration = br.Metrics.TrackMatrixEvent - - signalFormatParams = &signalfmt.FormatParams{ - GetUserInfo: func(ctx context.Context, u uuid.UUID) signalfmt.UserInfo { - puppet := br.GetPuppetBySignalID(u) - if puppet == nil { - return signalfmt.UserInfo{} - } - user := br.GetUserBySignalID(u) - if user != nil { - return signalfmt.UserInfo{ - MXID: user.MXID, - Name: puppet.Name, - } - } - return signalfmt.UserInfo{ - MXID: puppet.MXID, - Name: puppet.Name, - } - }, - } - matrixFormatParams = &matrixfmt.HTMLParser{ - GetUUIDFromMXID: func(ctx context.Context, userID id.UserID) uuid.UUID { - parsed, ok := br.ParsePuppetMXID(userID) - if ok { - return parsed - } - user := br.GetUserByMXIDIfExists(userID) - if user != nil && user.SignalID != uuid.Nil { - return user.SignalID - } - return uuid.Nil - }, - } -} - -func (br *SignalBridge) logLostPortals(ctx context.Context) { - exists, err := br.DB.TableExists(ctx, "lost_portals") - if err != nil { - br.ZLog.Err(err).Msg("Failed to check if lost_portals table exists") - } else if !exists { - return - } - lostPortals, err := br.DB.LostPortal.GetAll(ctx) - if err != nil { - br.ZLog.Err(err).Msg("Failed to get lost portals") - return - } else if len(lostPortals) == 0 { - return - } - lostCountByReceiver := make(map[string]int) - for _, lost := range lostPortals { - lostCountByReceiver[lost.Receiver]++ - } - br.ZLog.Warn(). - Any("count_by_receiver", lostCountByReceiver). - Msg("Some portals were discarded due to the receiver not being logged into the bridge anymore. " + - "Use `!signal cleanup-lost-portals` to remove them from the database. " + - "Alternatively, you can re-insert the data into the portal table with the appropriate receiver column to restore the portals.") -} - -func (br *SignalBridge) Start() { - go br.logLostPortals(context.TODO()) - err := br.MeowStore.Upgrade(context.TODO()) - if err != nil { - br.ZLog.Fatal().Err(err).Msg("Failed to upgrade signalmeow database") - os.Exit(15) - } - if br.provisioning != nil { - br.ZLog.Debug().Msg("Initializing provisioning API") - br.provisioning.Init() - } - go br.StartUsers() - if br.Config.Metrics.Enabled { - go br.Metrics.Start() - } - go br.disappearingMessagesManager.StartDisappearingLoop(context.TODO()) -} - -func (br *SignalBridge) Stop() { - br.Metrics.Stop() - for _, user := range br.usersByMXID { - br.ZLog.Debug().Stringer("user_id", user.MXID).Msg("Disconnecting user") - user.Disconnect() - } -} - -func (br *SignalBridge) GetIPortal(mxid id.RoomID) bridge.Portal { - p := br.GetPortalByMXID(mxid) - if p == nil { - return nil - } - return p -} - -func (br *SignalBridge) GetIUser(mxid id.UserID, create bool) bridge.User { - p := br.GetUserByMXID(mxid) - if p == nil { - return nil - } - return p -} - -func (br *SignalBridge) IsGhost(mxid id.UserID) bool { - _, isGhost := br.ParsePuppetMXID(mxid) - return isGhost -} - -func (br *SignalBridge) GetIGhost(mxid id.UserID) bridge.Ghost { - p := br.GetPuppetByMXID(mxid) - if p == nil { - return nil - } - return p -} - -func (br *SignalBridge) CreatePrivatePortal(roomID id.RoomID, brInviter bridge.User, brGhost bridge.Ghost) { - inviter := brInviter.(*User) - puppet := brGhost.(*Puppet) - - log := br.ZLog.With(). - Str("action", "create private portal"). - Stringer("target_room_id", roomID). - Stringer("inviter_mxid", brInviter.GetMXID()). - Stringer("invitee_uuid", puppet.SignalID). - Logger() - log.Debug().Msg("Creating private chat portal") - - key := database.NewPortalKey(puppet.SignalID.String(), inviter.SignalID) - portal := br.GetPortalByChatID(key) - ctx := log.WithContext(context.TODO()) - - if len(portal.MXID) == 0 { - br.createPrivatePortalFromInvite(ctx, roomID, inviter, puppet, portal) - return - } - log.Debug(). - Stringer("existing_room_id", portal.MXID). - Msg("Existing private chat portal found, trying to invite user") - - ok := portal.ensureUserInvited(ctx, inviter) - if !ok { - log.Warn().Msg("Failed to invite user to existing private chat portal. Redirecting portal to new room") - br.createPrivatePortalFromInvite(ctx, roomID, inviter, puppet, portal) - return - } - intent := puppet.DefaultIntent() - errorMessage := fmt.Sprintf("You already have a private chat portal with me at [%[1]s](https://matrix.to/#/%[1]s)", portal.MXID) - errorContent := format.RenderMarkdown(errorMessage, true, false) - _, _ = intent.SendMessageEvent(ctx, roomID, event.EventMessage, errorContent) - log.Debug().Msg("Leaving ghost from private chat room after accepting invite because we already have a chat with the user") - _, _ = intent.LeaveRoom(ctx, roomID) -} - -func (br *SignalBridge) createPrivatePortalFromInvite(ctx context.Context, roomID id.RoomID, inviter *User, puppet *Puppet, portal *Portal) { - log := zerolog.Ctx(ctx) - log.Debug().Msg("Creating private portal from invite") - - // Check if room is already encrypted - var existingEncryption event.EncryptionEventContent - var encryptionEnabled bool - err := portal.MainIntent().StateEvent(ctx, roomID, event.StateEncryption, "", &existingEncryption) - if err != nil { - log.Err(err).Msg("Failed to check if encryption is enabled in private chat room") - } else { - encryptionEnabled = existingEncryption.Algorithm == id.AlgorithmMegolmV1 - } - portal.MXID = roomID - br.portalsLock.Lock() - br.portalsByMXID[portal.MXID] = portal - br.portalsLock.Unlock() - intent := puppet.DefaultIntent() - - if br.Config.Bridge.Encryption.Default || encryptionEnabled { - log.Debug().Msg("Adding bridge bot to new private chat portal as encryption is enabled") - _, err = intent.InviteUser(ctx, roomID, &mautrix.ReqInviteUser{UserID: br.Bot.UserID}) - if err != nil { - log.Err(err).Msg("Failed to invite bridge bot to enable e2be") - } - err = br.Bot.EnsureJoined(ctx, roomID) - if err != nil { - log.Err(err).Msg("Failed to join as bridge bot to enable e2be") - } - if !encryptionEnabled { - _, err = intent.SendStateEvent(ctx, roomID, event.StateEncryption, "", portal.getEncryptionEventContent()) - if err != nil { - log.Err(err).Msg("Failed to enable e2be") - } - } - br.AS.StateStore.SetMembership(ctx, roomID, inviter.MXID, event.MembershipJoin) - br.AS.StateStore.SetMembership(ctx, roomID, puppet.MXID, event.MembershipJoin) - br.AS.StateStore.SetMembership(ctx, roomID, br.Bot.UserID, event.MembershipJoin) - portal.Encrypted = true - } - portal.UpdateDMInfo(ctx, true) - _, _ = intent.SendNotice(ctx, roomID, "Private chat portal created") - log.Info().Msg("Created private chat portal after invite") -} - -func main() { - br := &SignalBridge{ - usersByMXID: make(map[id.UserID]*User), - usersBySignalID: make(map[uuid.UUID]*User), - - managementRooms: make(map[id.RoomID]*User), - - portalsByMXID: make(map[id.RoomID]*Portal), - portalsByID: make(map[database.PortalKey]*Portal), - - puppets: make(map[uuid.UUID]*Puppet), - puppetsByCustomMXID: make(map[id.UserID]*Puppet), - } - br.Bridge = bridge.Bridge{ - Name: "mautrix-signal", - URL: "https://github.com/mautrix/signal", - Description: "A Matrix-Signal puppeting bridge.", - Version: "0.6.3", - ProtocolName: "Signal", - BeeperServiceName: "signal", - BeeperNetworkName: "signal", - - CryptoPickleKey: "mautrix.bridge.e2ee", - - ConfigUpgrader: &configupgrade.StructUpgrader{ - SimpleUpgrader: configupgrade.SimpleUpgrader(config.DoUpgrade), - Blocks: config.SpacedBlocks, - Base: ExampleConfig, - }, - - Child: br, - } - br.InitVersion(Tag, Commit, BuildTime) - - br.Main() -} diff --git a/messagetracking.go b/messagetracking.go deleted file mode 100644 index e95abb4..0000000 --- a/messagetracking.go +++ /dev/null @@ -1,311 +0,0 @@ -// mautrix-signal - A Matrix-signal puppeting bridge. -// Copyright (C) 2023 Scott Weber -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see . - -package main - -import ( - "context" - "errors" - "fmt" - "sync" - "time" - - "github.com/rs/zerolog" - "maunium.net/go/mautrix" - "maunium.net/go/mautrix/bridge/status" - "maunium.net/go/mautrix/event" - "maunium.net/go/mautrix/id" - - "go.mau.fi/mautrix-signal/msgconv" -) - -var ( - errUserNotConnected = errors.New("you are not connected to Signal") - errDifferentUser = errors.New("user is not the recipient of this private chat portal") - errUserNotLoggedIn = errors.New("user is not logged in and chat has no relay bot") - errRelaybotNotLoggedIn = errors.New("neither user nor relay bot of chat are logged in") - errCantRelayReactions = errors.New("user is not logged in and reactions can't be relayed") - errMNoticeDisabled = errors.New("bridging m.notice messages is disabled") - errUnexpectedParsedContentType = errors.New("unexpected parsed content type") - - errRedactionTargetNotFound = errors.New("redaction target message was not found") - errRedactionTargetSentBySomeoneElse = errors.New("redaction target message was sent by someone else") - errUnreactTargetSentBySomeoneElse = errors.New("redaction target reaction was sent by someone else") - errReactionTargetNotFound = errors.New("reaction target message not found") - errEditUnknownTarget = errors.New("unknown edit target message") - errFailedToGetEditTarget = errors.New("failed to get edit target message") - errEditDifferentSender = errors.New("can't edit message sent by another user") - errEditTooOld = errors.New("message is too old to be edited") - - errMessageTakingLong = errors.New("bridging the message is taking longer than usual") - errTimeoutBeforeHandling = errors.New("message timed out before handling was started") -) - -func errorToStatusReason(err error) (reason event.MessageStatusReason, status event.MessageStatus, isCertain, sendNotice bool, humanMessage string) { - switch { - case errors.Is(err, errUnexpectedParsedContentType), - errors.Is(err, msgconv.ErrUnsupportedMsgType), - errors.Is(err, msgconv.ErrInvalidGeoURI): - return event.MessageStatusUnsupported, event.MessageStatusFail, true, true, "" - case errors.Is(err, errMNoticeDisabled): - return event.MessageStatusUnsupported, event.MessageStatusFail, true, false, "" - case errors.Is(err, errEditDifferentSender), - errors.Is(err, errEditTooOld), - errors.Is(err, errEditUnknownTarget): - return event.MessageStatusUnsupported, event.MessageStatusFail, true, true, err.Error() - case errors.Is(err, errTimeoutBeforeHandling): - return event.MessageStatusTooOld, event.MessageStatusRetriable, true, true, "the message was too old when it reached the bridge, so it was not handled" - case errors.Is(err, context.DeadlineExceeded): - return event.MessageStatusTooOld, event.MessageStatusRetriable, false, true, "handling the message took too long and was cancelled" - case errors.Is(err, errMessageTakingLong): - return event.MessageStatusTooOld, event.MessageStatusPending, false, true, err.Error() - case errors.Is(err, errRedactionTargetNotFound), - errors.Is(err, errReactionTargetNotFound), - errors.Is(err, errRedactionTargetSentBySomeoneElse), - errors.Is(err, errUnreactTargetSentBySomeoneElse): - return event.MessageStatusGenericError, event.MessageStatusFail, true, false, "" - case errors.Is(err, errUserNotConnected): - return event.MessageStatusGenericError, event.MessageStatusRetriable, true, true, "" - case errors.Is(err, errUserNotLoggedIn), - errors.Is(err, errDifferentUser), - errors.Is(err, errRelaybotNotLoggedIn): - return event.MessageStatusGenericError, event.MessageStatusRetriable, true, false, "" - default: - return event.MessageStatusGenericError, event.MessageStatusRetriable, false, true, "" - } -} - -func (portal *Portal) sendErrorMessage(ctx context.Context, evt *event.Event, err error, confirmed bool, editID id.EventID) id.EventID { - if !portal.bridge.Config.Bridge.MessageErrorNotices { - return "" - } - certainty := "may not have been" - if confirmed { - certainty = "was not" - } - var msgType string - switch evt.Type { - case event.EventMessage: - msgType = "message" - case event.EventReaction: - msgType = "reaction" - case event.EventRedaction: - msgType = "redaction" - //case TypeMSC3381PollResponse, TypeMSC3381V2PollResponse: - // msgType = "poll response" - //case TypeMSC3381PollStart: - // msgType = "poll start" - default: - msgType = "unknown event" - } - msg := fmt.Sprintf("\u26a0 Your %s %s bridged: %v", msgType, certainty, err) - if errors.Is(err, errMessageTakingLong) { - msg = fmt.Sprintf("\u26a0 Bridging your %s is taking longer than usual", msgType) - } - content := &event.MessageEventContent{ - MsgType: event.MsgNotice, - Body: msg, - } - if editID != "" { - content.SetEdit(editID) - } else { - content.SetReply(evt) - } - resp, err := portal.sendMainIntentMessage(ctx, content) - if err != nil { - portal.log.Err(err).Msg("Failed to send bridging error message") - return "" - } - return resp.EventID -} - -func (portal *Portal) sendStatusEvent(ctx context.Context, evtID, lastRetry id.EventID, err error, deliveredTo *[]id.UserID) { - if !portal.bridge.Config.Bridge.MessageStatusEvents { - return - } - if lastRetry == evtID { - lastRetry = "" - } - intent := portal.bridge.Bot - if !portal.Encrypted { - // Bridge bot isn't present in unencrypted DMs - intent = portal.MainIntent() - } - content := event.BeeperMessageStatusEventContent{ - Network: portal.getBridgeInfoStateKey(), - RelatesTo: event.RelatesTo{ - Type: event.RelReference, - EventID: evtID, - }, - DeliveredToUsers: deliveredTo, - LastRetry: lastRetry, - } - if err == nil { - content.Status = event.MessageStatusSuccess - } else { - content.Reason, content.Status, _, _, content.Message = errorToStatusReason(err) - content.Error = err.Error() - } - _, err = intent.SendMessageEvent(ctx, portal.MXID, event.BeeperMessageStatus, &content) - if err != nil { - portal.log.Err(err).Msg("Failed to send message status event") - } -} - -func (portal *Portal) sendDeliveryReceipt(ctx context.Context, eventID id.EventID) { - if portal.bridge.Config.Bridge.DeliveryReceipts { - err := portal.bridge.Bot.SendReceipt(ctx, portal.MXID, eventID, event.ReceiptTypeRead, nil) - if err != nil { - portal.log.Debug().Err(err).Stringer("event_id", eventID).Msg("Failed to send delivery receipt") - } - } -} - -func (portal *Portal) sendMessageMetrics(ctx context.Context, evt *event.Event, err error, part string, ms *metricSender) { - log := portal.log.With(). - Str("handling_step", part). - Str("event_type", evt.Type.String()). - Stringer("event_id", evt.ID). - Stringer("sender", evt.Sender). - Logger() - if evt.Type == event.EventRedaction { - log = log.With().Stringer("redacts", evt.Redacts).Logger() - } - ctx = log.WithContext(ctx) - - origEvtID := evt.ID - if retryMeta := evt.Content.AsMessage().MessageSendRetry; retryMeta != nil { - origEvtID = retryMeta.OriginalEventID - } - if err != nil { - logEvt := log.Error() - if part == "Ignoring" { - logEvt = log.Debug() - } - logEvt.Err(err).Msg("Sending message metrics for event") - reason, statusCode, isCertain, sendNotice, _ := errorToStatusReason(err) - checkpointStatus := status.ReasonToCheckpointStatus(reason, statusCode) - portal.bridge.SendMessageCheckpoint(evt, status.MsgStepRemote, err, checkpointStatus, ms.getRetryNum()) - if sendNotice { - ms.setNoticeID(portal.sendErrorMessage(ctx, evt, err, isCertain, ms.getNoticeID())) - } - portal.sendStatusEvent(ctx, origEvtID, evt.ID, err, nil) - } else { - log.Debug().Msg("Sending metrics for successfully handled Matrix event") - portal.sendDeliveryReceipt(ctx, evt.ID) - portal.bridge.SendMessageSuccessCheckpoint(evt, status.MsgStepRemote, ms.getRetryNum()) - var deliveredTo *[]id.UserID - if portal.IsPrivateChat() { - deliveredTo = &[]id.UserID{} - } - portal.sendStatusEvent(ctx, origEvtID, evt.ID, nil, deliveredTo) - if prevNotice := ms.popNoticeID(); prevNotice != "" { - _, _ = portal.MainIntent().RedactEvent(ctx, portal.MXID, prevNotice, mautrix.ReqRedact{ - Reason: "error resolved", - }) - } - } - if ms != nil { - log.Debug().Object("timings", ms.timings).Msg("Timings for event") - } -} - -type messageTimings struct { - initReceive time.Duration - decrypt time.Duration - implicitRR time.Duration - portalQueue time.Duration - totalReceive time.Duration - - preproc time.Duration - convert time.Duration - totalSend time.Duration -} - -func niceRound(dur time.Duration) time.Duration { - switch { - case dur < time.Millisecond: - return dur - case dur < time.Second: - return dur.Round(100 * time.Microsecond) - default: - return dur.Round(time.Millisecond) - } -} - -func (mt *messageTimings) MarshalZerologObject(evt *zerolog.Event) { - evt. - Dict("bridge", zerolog.Dict(). - Stringer("init_receive", niceRound(mt.initReceive)). - Stringer("decrypt", niceRound(mt.decrypt)). - Stringer("queue", niceRound(mt.portalQueue)). - Stringer("total_hs_to_portal", niceRound(mt.totalReceive))). - Dict("portal", zerolog.Dict(). - Stringer("implicit_rr", niceRound(mt.implicitRR)). - Stringer("preproc", niceRound(mt.preproc)). - Stringer("convert", niceRound(mt.convert)). - Stringer("total_send", niceRound(mt.totalSend))) -} - -type metricSender struct { - portal *Portal - previousNotice id.EventID - lock sync.Mutex - completed bool - retryNum int - timings *messageTimings - ctx context.Context -} - -func (ms *metricSender) getRetryNum() int { - if ms != nil { - return ms.retryNum - } - return 0 -} - -func (ms *metricSender) getNoticeID() id.EventID { - if ms == nil { - return "" - } - return ms.previousNotice -} - -func (ms *metricSender) popNoticeID() id.EventID { - if ms == nil { - return "" - } - evtID := ms.previousNotice - ms.previousNotice = "" - return evtID -} - -func (ms *metricSender) setNoticeID(evtID id.EventID) { - if ms != nil && ms.previousNotice == "" { - ms.previousNotice = evtID - } -} - -func (ms *metricSender) sendMessageMetrics(evt *event.Event, err error, part string, completed bool) { - ms.lock.Lock() - defer ms.lock.Unlock() - if !completed && ms.completed { - return - } - ms.portal.sendMessageMetrics(ms.ctx, evt, err, part, ms) - ms.retryNum++ - ms.completed = completed -} diff --git a/metrics.go b/metrics.go deleted file mode 100644 index 2e76a04..0000000 --- a/metrics.go +++ /dev/null @@ -1,281 +0,0 @@ -// mautrix-signal - A Matrix-signal puppeting bridge. -// Copyright (C) 2023 Element -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see . - -package main - -import ( - "context" - "net/http" - "runtime/debug" - "sync" - "time" - - "github.com/google/uuid" - "github.com/prometheus/client_golang/prometheus" - "github.com/prometheus/client_golang/prometheus/promauto" - "github.com/prometheus/client_golang/prometheus/promhttp" - "github.com/rs/zerolog" - "maunium.net/go/mautrix/event" - - "go.mau.fi/mautrix-signal/database" -) - -type MetricsHandler struct { - db *database.Database - server *http.Server - log zerolog.Logger - - running bool - ctx context.Context - stopRecorder func() - - matrixEventHandling *prometheus.HistogramVec - signalMessageAge prometheus.Histogram - signalMessageHandling *prometheus.HistogramVec - countCollection prometheus.Histogram - puppetCount prometheus.Gauge - userCount prometheus.Gauge - messageCount prometheus.Gauge - portalCount *prometheus.GaugeVec - encryptedGroupCount prometheus.Gauge - encryptedPrivateCount prometheus.Gauge - unencryptedGroupCount prometheus.Gauge - unencryptedPrivateCount prometheus.Gauge - - connected prometheus.Gauge - connectedState map[uuid.UUID]bool - connectedStateLock sync.Mutex - loggedIn prometheus.Gauge - loggedInState map[uuid.UUID]bool - loggedInStateLock sync.Mutex -} - -func NewMetricsHandler(address string, log zerolog.Logger, db *database.Database) *MetricsHandler { - portalCount := promauto.NewGaugeVec(prometheus.GaugeOpts{ - Name: "signal_portals_total", - Help: "Number of portal rooms on Matrix", - }, []string{"type", "encrypted"}) - return &MetricsHandler{ - db: db, - server: &http.Server{Addr: address, Handler: promhttp.Handler()}, - log: log, - running: false, - - matrixEventHandling: promauto.NewHistogramVec(prometheus.HistogramOpts{ - Name: "matrix_event", - Help: "Time spent processing Matrix events", - }, []string{"event_type"}), - signalMessageAge: promauto.NewHistogram(prometheus.HistogramOpts{ - Name: "remote_event_age", - Help: "Age of messages received from Signal", - Buckets: []float64{1, 2, 3, 5, 7.5, 10, 20, 30, 60}, - }), - signalMessageHandling: promauto.NewHistogramVec(prometheus.HistogramOpts{ - Name: "remote_event", - Help: "Time spent processing Signal messages", - }, []string{"message_type"}), - countCollection: promauto.NewHistogram(prometheus.HistogramOpts{ - Name: "signal_count_collection", - Help: "Time spent collecting the bridge_*_total metrics", - }), - puppetCount: promauto.NewGauge(prometheus.GaugeOpts{ - Name: "signal_puppets_total", - Help: "Number of Signal users bridged into Matrix", - }), - userCount: promauto.NewGauge(prometheus.GaugeOpts{ - Name: "signal_users_total", - Help: "Number of Matrix users using the bridge", - }), - messageCount: promauto.NewGauge(prometheus.GaugeOpts{ - Name: "signal_messages_total", - Help: "Number of messages bridged", - }), - portalCount: portalCount, - encryptedGroupCount: portalCount.With(prometheus.Labels{"type": "group", "encrypted": "true"}), - encryptedPrivateCount: portalCount.With(prometheus.Labels{"type": "private", "encrypted": "true"}), - unencryptedGroupCount: portalCount.With(prometheus.Labels{"type": "group", "encrypted": "false"}), - unencryptedPrivateCount: portalCount.With(prometheus.Labels{"type": "private", "encrypted": "false"}), - - loggedIn: promauto.NewGauge(prometheus.GaugeOpts{ - Name: "bridge_logged_in", - Help: "Bridge users logged into Signal", - }), - loggedInState: make(map[uuid.UUID]bool), - connected: promauto.NewGauge(prometheus.GaugeOpts{ - Name: "bridge_connected", - Help: "Bridge users connected to Signal", - }), - connectedState: make(map[uuid.UUID]bool), - } -} - -func noop() {} - -func (mh *MetricsHandler) TrackMatrixEvent(eventType event.Type) func() { - if !mh.running { - return noop - } - start := time.Now() - return func() { - duration := time.Since(start) - mh.matrixEventHandling. - With(prometheus.Labels{"event_type": eventType.Type}). - Observe(duration.Seconds()) - } -} - -func (mh *MetricsHandler) TrackSignalMessage(timestamp time.Time, messageType string) func() { - if !mh.running { - return noop - } - - start := time.Now() - return func() { - duration := time.Since(start) - mh.signalMessageHandling. - With(prometheus.Labels{"message_type": messageType}). - Observe(duration.Seconds()) - mh.signalMessageAge.Observe(time.Since(timestamp).Seconds()) - } -} - -func (mh *MetricsHandler) TrackLoginState(signalID uuid.UUID, loggedIn bool) { - if !mh.running { - return - } - mh.loggedInStateLock.Lock() - defer mh.loggedInStateLock.Unlock() - currentVal, ok := mh.loggedInState[signalID] - if !ok || currentVal != loggedIn { - mh.loggedInState[signalID] = loggedIn - if loggedIn { - mh.loggedIn.Inc() - } else if ok { - mh.loggedIn.Dec() - } - } -} - -func (mh *MetricsHandler) TrackConnectionState(signalID uuid.UUID, connected bool) { - if !mh.running { - return - } - mh.connectedStateLock.Lock() - defer mh.connectedStateLock.Unlock() - currentVal, ok := mh.connectedState[signalID] - if !ok || currentVal != connected { - mh.connectedState[signalID] = connected - if connected { - mh.connected.Inc() - } else if ok { - mh.connected.Dec() - } - } -} - -func (mh *MetricsHandler) updateStats() { - start := time.Now() - var puppetCount int - err := mh.db.QueryRow(mh.ctx, "SELECT COUNT(*) FROM puppet").Scan(&puppetCount) - if err != nil { - mh.log.Warn().Err(err).Msg("Failed to scan number of puppets") - } else { - mh.puppetCount.Set(float64(puppetCount)) - } - - var userCount int - err = mh.db.QueryRow(mh.ctx, `SELECT COUNT(*) FROM "user"`).Scan(&userCount) - if err != nil { - mh.log.Warn().Err(err).Msg("Failed to scan number of users:") - } else { - mh.userCount.Set(float64(userCount)) - } - - var messageCount int - err = mh.db.QueryRow(mh.ctx, "SELECT COUNT(*) FROM message").Scan(&messageCount) - if err != nil { - mh.log.Warn().Err(err).Msg("Failed to scan number of messages") - } else { - mh.messageCount.Set(float64(messageCount)) - } - - var encryptedGroupCount, encryptedPrivateCount, unencryptedGroupCount, unencryptedPrivateCount int - // TODO Use a more precise way to check if a chat_id is a UUID. - // It should also be compatible with both SQLite & Postgres. - err = mh.db.QueryRow(mh.ctx, ` - SELECT - COUNT(CASE WHEN chat_id NOT LIKE '%-%-%-%-%' AND encrypted THEN 1 END) AS encrypted_group_portals, - COUNT(CASE WHEN chat_id LIKE '%-%-%-%-%' AND encrypted THEN 1 END) AS encrypted_private_portals, - COUNT(CASE WHEN chat_id NOT LIKE '%-%-%-%-%' AND NOT encrypted THEN 1 END) AS unencrypted_group_portals, - COUNT(CASE WHEN chat_id LIKE '%-%-%-%-%' AND NOT encrypted THEN 1 END) AS unencrypted_private_portals - FROM portal WHERE mxid<>'' - `).Scan(&encryptedGroupCount, &encryptedPrivateCount, &unencryptedGroupCount, &unencryptedPrivateCount) - if err != nil { - mh.log.Warn().Err(err).Msg("Failed to scan number of portals") - } else { - mh.encryptedGroupCount.Set(float64(encryptedGroupCount)) - mh.encryptedPrivateCount.Set(float64(encryptedPrivateCount)) - mh.unencryptedGroupCount.Set(float64(unencryptedGroupCount)) - mh.unencryptedPrivateCount.Set(float64(encryptedPrivateCount)) - } - mh.countCollection.Observe(time.Since(start).Seconds()) -} - -func (mh *MetricsHandler) startUpdatingStats() { - defer func() { - r := recover() - if r != nil { - evt := mh.log.Fatal().Str("stack", string(debug.Stack())) - if err, ok := r.(error); ok { - evt = evt.Err(err) - } else { - evt = evt.Any("error", r) - } - evt.Msg("Panic in metric updater") - } - }() - ticker := time.Tick(10 * time.Second) - for { - mh.updateStats() - select { - case <-mh.ctx.Done(): - return - case <-ticker: - } - } -} - -func (mh *MetricsHandler) Start() { - mh.running = true - mh.ctx, mh.stopRecorder = context.WithCancel(context.Background()) - go mh.startUpdatingStats() - err := mh.server.ListenAndServe() - mh.running = false - if err != nil && err != http.ErrServerClosed { - mh.log.Fatal().Err(err).Msg("Error in metrics listener") - } -} - -func (mh *MetricsHandler) Stop() { - if !mh.running { - return - } - mh.stopRecorder() - err := mh.server.Close() - if err != nil { - mh.log.Err(err).Msg("Error closing metrics listener") - } -} diff --git a/msgconv/msgconv.go b/msgconv/msgconv.go deleted file mode 100644 index ee3ff55..0000000 --- a/msgconv/msgconv.go +++ /dev/null @@ -1,65 +0,0 @@ -// mautrix-signal - A Matrix-signal puppeting bridge. -// Copyright (C) 2024 Tulir Asokan -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see . - -package msgconv - -import ( - "context" - "time" - - "maunium.net/go/mautrix/event" - "maunium.net/go/mautrix/id" - - "go.mau.fi/mautrix-signal/database" - "go.mau.fi/mautrix-signal/msgconv/matrixfmt" - "go.mau.fi/mautrix-signal/msgconv/signalfmt" - "go.mau.fi/mautrix-signal/pkg/signalmeow" - signalpb "go.mau.fi/mautrix-signal/pkg/signalmeow/protobuf" -) - -type PortalMethods interface { - UploadMatrixMedia(ctx context.Context, data []byte, fileName, contentType string) (id.ContentURIString, error) - DownloadMatrixMedia(ctx context.Context, uri id.ContentURIString) ([]byte, error) - GetMatrixReply(ctx context.Context, msg *signalpb.DataMessage_Quote) (replyTo id.EventID, replyTargetSender id.UserID) - GetSignalReply(ctx context.Context, content *event.MessageEventContent) *signalpb.DataMessage_Quote - - GetClient(ctx context.Context) *signalmeow.Client - - GetData(ctx context.Context) *database.Portal -} - -type ExtendedPortalMethods interface { - QueueFileTransfer(ctx context.Context, msgTS uint64, fileName string, ap *signalpb.AttachmentPointer) (id.ContentURIString, error) -} - -type MessageConverter struct { - PortalMethods - - SignalFmtParams *signalfmt.FormatParams - MatrixFmtParams *matrixfmt.HTMLParser - - ConvertVoiceMessages bool - ConvertGIFToAPNG bool - MaxFileSize int64 - AsyncFiles bool - UpdateDisappearing func(ctx context.Context, newTimer time.Duration) - - LocationFormat string -} - -func (mc *MessageConverter) IsPrivateChat(ctx context.Context) bool { - return !mc.GetData(ctx).UserID().IsEmpty() -} diff --git a/pkg/connector/chatinfo.go b/pkg/connector/chatinfo.go index 732b0ae..a5d99c9 100644 --- a/pkg/connector/chatinfo.go +++ b/pkg/connector/chatinfo.go @@ -32,6 +32,7 @@ import ( "maunium.net/go/mautrix/event" "go.mau.fi/mautrix-signal/pkg/libsignalgo" + "go.mau.fi/mautrix-signal/pkg/signalid" "go.mau.fi/mautrix-signal/pkg/signalmeow/types" ) @@ -39,7 +40,7 @@ const PrivateChatTopic = "Signal private chat" const NoteToSelfName = "Signal Note to Self" func (s *SignalClient) GetUserInfo(ctx context.Context, ghost *bridgev2.Ghost) (*bridgev2.UserInfo, error) { - userID, err := parseUserID(ghost.ID) + userID, err := signalid.ParseUserID(ghost.ID) if err != nil { return nil, err } @@ -51,7 +52,7 @@ func (s *SignalClient) GetUserInfo(ctx context.Context, ghost *bridgev2.Ghost) ( } func (s *SignalClient) GetChatInfo(ctx context.Context, portal *bridgev2.Portal) (*bridgev2.ChatInfo, error) { - userID, groupID, err := parsePortalID(portal.ID) + userID, groupID, err := signalid.ParsePortalID(portal.ID) if err != nil { return nil, err } @@ -143,19 +144,19 @@ func (s *SignalClient) ResolveIdentifier(ctx context.Context, number string, cre // createChat is a no-op: chats don't need to be created, and we always return chat info if aci != uuid.Nil { - ghost, err := s.Main.Bridge.GetGhostByID(ctx, makeUserID(aci)) + ghost, err := s.Main.Bridge.GetGhostByID(ctx, signalid.MakeUserID(aci)) if err != nil { return nil, fmt.Errorf("failed to get ghost: %w", err) } return &bridgev2.ResolveIdentifierResponse{ - UserID: makeUserID(aci), + UserID: signalid.MakeUserID(aci), UserInfo: s.contactToUserInfo(recipient), Ghost: ghost, Chat: s.makeCreateDMResponse(recipient), }, nil } else { return &bridgev2.ResolveIdentifierResponse{ - UserID: makeUserIDFromServiceID(libsignalgo.NewPNIServiceID(pni)), + UserID: signalid.MakeUserIDFromServiceID(libsignalgo.NewPNIServiceID(pni)), UserInfo: s.contactToUserInfo(recipient), Chat: s.makeCreateDMResponse(recipient), }, nil @@ -179,14 +180,14 @@ func (s *SignalClient) GetContactList(ctx context.Context) ([]*bridgev2.ResolveI Chat: s.makeCreateDMResponse(recipient), } if recipient.ACI != uuid.Nil { - recipientResp.UserID = makeUserID(recipient.ACI) + recipientResp.UserID = signalid.MakeUserID(recipient.ACI) ghost, err := s.Main.Bridge.GetGhostByID(ctx, recipientResp.UserID) if err != nil { return nil, fmt.Errorf("failed to get ghost for %s: %w", recipient.ACI, err) } recipientResp.Ghost = ghost } else { - recipientResp.UserID = makeUserIDFromServiceID(libsignalgo.NewPNIServiceID(recipient.PNI)) + recipientResp.UserID = signalid.MakeUserIDFromServiceID(libsignalgo.NewPNIServiceID(recipient.PNI)) } resp[i] = recipientResp } @@ -215,7 +216,7 @@ func (s *SignalClient) makeCreateDMResponse(recipient *types.Recipient) *bridgev name = s.Main.Config.FormatDisplayname(recipient) serviceID = libsignalgo.NewPNIServiceID(recipient.PNI) } else { - members.OtherUserID = makeUserID(recipient.ACI) + members.OtherUserID = signalid.MakeUserID(recipient.ACI) if recipient.ACI == s.Client.Store.ACI { name = NoteToSelfName avatar = &bridgev2.Avatar{ diff --git a/pkg/connector/client.go b/pkg/connector/client.go index 838c0ee..56ab59a 100644 --- a/pkg/connector/client.go +++ b/pkg/connector/client.go @@ -11,6 +11,7 @@ import ( "maunium.net/go/mautrix/bridgev2" "maunium.net/go/mautrix/bridgev2/networkid" + "go.mau.fi/mautrix-signal/pkg/signalid" "go.mau.fi/mautrix-signal/pkg/signalmeow" ) @@ -112,7 +113,7 @@ func (s *SignalClient) IsThisUser(_ context.Context, userID networkid.UserID) bo if s.Client == nil { return false } - return userID == makeUserID(s.Client.Store.ACI) + return userID == signalid.MakeUserID(s.Client.Store.ACI) } func (s *SignalClient) bridgeStateLoop(statusChan <-chan signalmeow.SignalConnectionStatus) { diff --git a/pkg/connector/connector.go b/pkg/connector/connector.go index 4c36674..6a4e4dc 100644 --- a/pkg/connector/connector.go +++ b/pkg/connector/connector.go @@ -20,19 +20,12 @@ import ( "context" "fmt" "text/template" - "time" "github.com/google/uuid" - "github.com/rs/zerolog" "go.mau.fi/util/dbutil" "maunium.net/go/mautrix/bridgev2" - "maunium.net/go/mautrix/bridgev2/database" - "maunium.net/go/mautrix/bridgev2/networkid" - "maunium.net/go/mautrix/id" - "go.mau.fi/mautrix-signal/msgconv" - "go.mau.fi/mautrix-signal/msgconv/matrixfmt" - "go.mau.fi/mautrix-signal/msgconv/signalfmt" + "go.mau.fi/mautrix-signal/pkg/msgconv" "go.mau.fi/mautrix-signal/pkg/signalmeow" "go.mau.fi/mautrix-signal/pkg/signalmeow/store" ) @@ -82,65 +75,7 @@ func (s *SignalConnector) Init(bridge *bridgev2.Bridge) { } s.Store = store.NewStore(bridge.DB.Database, dbutil.ZeroLogger(bridge.Log.With().Str("db_section", "signalmeow").Logger())) s.Bridge = bridge - s.MsgConv = &msgconv.MessageConverter{ - PortalMethods: &msgconvPortalMethods{}, - SignalFmtParams: &signalfmt.FormatParams{ - GetUserInfo: func(ctx context.Context, uuid uuid.UUID) signalfmt.UserInfo { - ghost, err := s.Bridge.GetGhostByID(ctx, makeUserID(uuid)) - if err != nil { - // TODO log? - return signalfmt.UserInfo{} - } - userInfo := signalfmt.UserInfo{ - MXID: ghost.Intent.GetMXID(), - Name: ghost.Name, - } - userLogin := s.Bridge.GetCachedUserLoginByID(networkid.UserLoginID(uuid.String())) - if userLogin != nil { - userInfo.MXID = userLogin.UserMXID - // TODO find matrix user displayname? - } - return userInfo - }, - }, - MatrixFmtParams: &matrixfmt.HTMLParser{ - GetUUIDFromMXID: func(ctx context.Context, userID id.UserID) uuid.UUID { - parsed, ok := s.Bridge.Matrix.ParseGhostMXID(userID) - if ok { - u, _ := uuid.Parse(string(parsed)) - return u - } - user, _ := s.Bridge.GetExistingUserByMXID(ctx, userID) - // TODO log errors? - if user != nil { - preferredLogin, _, _ := ctx.Value(msgconvContextKey).(*msgconvContext).Portal.FindPreferredLogin(ctx, user, true) - if preferredLogin != nil { - u, _ := uuid.Parse(string(preferredLogin.ID)) - return u - } - } - return uuid.Nil - }, - }, - ConvertVoiceMessages: true, - ConvertGIFToAPNG: true, - MaxFileSize: 50 * 1024 * 1024, - AsyncFiles: true, - LocationFormat: s.Config.LocationFormat, - UpdateDisappearing: func(ctx context.Context, newTimer time.Duration) { - portal := ctx.Value(msgconvContextKey).(*msgconvContext).Portal - portal.Disappear.Timer = newTimer - if newTimer == 0 { - portal.Disappear.Type = "" - } else { - portal.Disappear.Type = database.DisappearingTypeAfterRead - } - err := portal.Save(ctx) - if err != nil { - zerolog.Ctx(ctx).Err(err).Msg("Failed to update portal disappearing timer in database") - } - }, - } + s.MsgConv = msgconv.NewMessageConverter(bridge, s.Config.LocationFormat) } func (s *SignalConnector) SetMaxFileSize(maxSize int64) { diff --git a/pkg/connector/dbmeta.go b/pkg/connector/dbmeta.go index 68e21d5..14f59f2 100644 --- a/pkg/connector/dbmeta.go +++ b/pkg/connector/dbmeta.go @@ -18,26 +18,20 @@ package connector import ( "maunium.net/go/mautrix/bridgev2/database" + + "go.mau.fi/mautrix-signal/pkg/signalid" ) func (s *SignalConnector) GetDBMetaTypes() database.MetaTypes { return database.MetaTypes{ Portal: func() any { - return &PortalMetadata{} + return &signalid.PortalMetadata{} }, Ghost: nil, Message: func() any { - return &MessageMetadata{} + return &signalid.MessageMetadata{} }, Reaction: nil, UserLogin: nil, } } - -type PortalMetadata struct { - Revision uint32 `json:"revision"` -} - -type MessageMetadata struct { - ContainsAttachments bool `json:"contains_attachments,omitempty"` -} diff --git a/pkg/connector/groupinfo.go b/pkg/connector/groupinfo.go index 6bea361..3bf809d 100644 --- a/pkg/connector/groupinfo.go +++ b/pkg/connector/groupinfo.go @@ -27,6 +27,7 @@ import ( "maunium.net/go/mautrix/event" "go.mau.fi/mautrix-signal/pkg/libsignalgo" + "go.mau.fi/mautrix-signal/pkg/signalid" "go.mau.fi/mautrix-signal/pkg/signalmeow" "go.mau.fi/mautrix-signal/pkg/signalmeow/types" ) @@ -174,7 +175,7 @@ func (s *SignalClient) makeGroupAvatar(meta signalmeow.GroupAvatarMeta) *bridgev func makeRevisionUpdater(rev uint32) func(ctx context.Context, portal *bridgev2.Portal) bool { return func(ctx context.Context, portal *bridgev2.Portal) bool { - meta := portal.Metadata.(*PortalMetadata) + meta := portal.Metadata.(*signalid.PortalMetadata) if meta.Revision < rev { meta.Revision = rev return true diff --git a/pkg/connector/handlematrix.go b/pkg/connector/handlematrix.go index 2f36ae7..9e8c353 100644 --- a/pkg/connector/handlematrix.go +++ b/pkg/connector/handlematrix.go @@ -32,12 +32,13 @@ import ( "maunium.net/go/mautrix/bridgev2/networkid" "go.mau.fi/mautrix-signal/pkg/libsignalgo" + "go.mau.fi/mautrix-signal/pkg/signalid" "go.mau.fi/mautrix-signal/pkg/signalmeow" signalpb "go.mau.fi/mautrix-signal/pkg/signalmeow/protobuf" ) func (s *SignalClient) sendMessage(ctx context.Context, portalID networkid.PortalID, content *signalpb.Content) error { - userID, groupID, err := parsePortalID(portalID) + userID, groupID, err := signalid.ParsePortalID(portalID) if err != nil { return err } @@ -77,15 +78,7 @@ func (s *SignalClient) sendMessage(ctx context.Context, portalID networkid.Porta } func (s *SignalClient) HandleMatrixMessage(ctx context.Context, msg *bridgev2.MatrixMessage) (message *bridgev2.MatrixMessageResponse, err error) { - mcCtx := &msgconvContext{ - Connector: s.Main, - Intent: nil, - Client: s, - Portal: msg.Portal, - ReplyTo: msg.ReplyTo, - } - ctx = context.WithValue(ctx, msgconvContextKey, mcCtx) - converted, err := s.Main.MsgConv.ToSignal(ctx, msg.Event, msg.Content, msg.OrigSender != nil) + converted, err := s.Main.MsgConv.ToSignal(ctx, s.Client, msg.Portal, msg.Event, msg.Content, msg.OrigSender != nil, msg.ReplyTo) if err != nil { return nil, err } @@ -94,10 +87,10 @@ func (s *SignalClient) HandleMatrixMessage(ctx context.Context, msg *bridgev2.Ma return nil, err } dbMsg := &database.Message{ - ID: makeMessageID(s.Client.Store.ACI, converted.GetTimestamp()), - SenderID: makeUserID(s.Client.Store.ACI), + ID: signalid.MakeMessageID(s.Client.Store.ACI, converted.GetTimestamp()), + SenderID: signalid.MakeUserID(s.Client.Store.ACI), Timestamp: time.UnixMilli(int64(converted.GetTimestamp())), - Metadata: &MessageMetadata{ + Metadata: &signalid.MessageMetadata{ ContainsAttachments: len(converted.Attachments) > 0, }, } @@ -107,27 +100,20 @@ func (s *SignalClient) HandleMatrixMessage(ctx context.Context, msg *bridgev2.Ma } func (s *SignalClient) HandleMatrixEdit(ctx context.Context, msg *bridgev2.MatrixEdit) error { - _, targetSentTimestamp, err := parseMessageID(msg.EditTarget.ID) + _, targetSentTimestamp, err := signalid.ParseMessageID(msg.EditTarget.ID) if err != nil { return fmt.Errorf("failed to parse target message ID: %w", err) - } else if msg.EditTarget.SenderID != makeUserID(s.Client.Store.ACI) { + } else if msg.EditTarget.SenderID != signalid.MakeUserID(s.Client.Store.ACI) { return fmt.Errorf("cannot edit other people's messages") } - mcCtx := &msgconvContext{ - Connector: s.Main, - Intent: nil, - Client: s, - Portal: msg.Portal, - } + var replyTo *database.Message if msg.EditTarget.ReplyTo.MessageID != "" { - var err error - mcCtx.ReplyTo, err = s.Main.Bridge.DB.Message.GetFirstOrSpecificPartByID(ctx, msg.Portal.Receiver, msg.EditTarget.ReplyTo) + replyTo, err = s.Main.Bridge.DB.Message.GetFirstOrSpecificPartByID(ctx, msg.Portal.Receiver, msg.EditTarget.ReplyTo) if err != nil { return fmt.Errorf("failed to get message reply target: %w", err) } } - ctx = context.WithValue(ctx, msgconvContextKey, mcCtx) - converted, err := s.Main.MsgConv.ToSignal(ctx, msg.Event, msg.Content, msg.OrigSender != nil) + converted, err := s.Main.MsgConv.ToSignal(ctx, s.Client, msg.Portal, msg.Event, msg.Content, msg.OrigSender != nil, replyTo) if err != nil { return err } @@ -138,22 +124,22 @@ func (s *SignalClient) HandleMatrixEdit(ctx context.Context, msg *bridgev2.Matri if err != nil { return err } - msg.EditTarget.ID = makeMessageID(s.Client.Store.ACI, converted.GetTimestamp()) - msg.EditTarget.Metadata = &MessageMetadata{ContainsAttachments: len(converted.Attachments) > 0} + msg.EditTarget.ID = signalid.MakeMessageID(s.Client.Store.ACI, converted.GetTimestamp()) + msg.EditTarget.Metadata = &signalid.MessageMetadata{ContainsAttachments: len(converted.Attachments) > 0} msg.EditTarget.EditCount++ return nil } func (s *SignalClient) PreHandleMatrixReaction(ctx context.Context, msg *bridgev2.MatrixReaction) (bridgev2.MatrixReactionPreResponse, error) { return bridgev2.MatrixReactionPreResponse{ - SenderID: makeUserID(s.Client.Store.ACI), + SenderID: signalid.MakeUserID(s.Client.Store.ACI), EmojiID: "", Emoji: variationselector.FullyQualify(msg.Content.RelatesTo.Key), }, nil } func (s *SignalClient) HandleMatrixReaction(ctx context.Context, msg *bridgev2.MatrixReaction) (reaction *database.Reaction, err error) { - targetAuthorACI, targetSentTimestamp, err := parseMessageID(msg.TargetMessage.ID) + targetAuthorACI, targetSentTimestamp, err := signalid.ParseMessageID(msg.TargetMessage.ID) if err != nil { return nil, fmt.Errorf("failed to parse target message ID: %w", err) } @@ -177,7 +163,7 @@ func (s *SignalClient) HandleMatrixReaction(ctx context.Context, msg *bridgev2.M } func (s *SignalClient) HandleMatrixReactionRemove(ctx context.Context, msg *bridgev2.MatrixReactionRemove) error { - targetAuthorACI, targetSentTimestamp, err := parseMessageID(msg.TargetReaction.MessageID) + targetAuthorACI, targetSentTimestamp, err := signalid.ParseMessageID(msg.TargetReaction.MessageID) if err != nil { return fmt.Errorf("failed to parse target message ID: %w", err) } @@ -201,10 +187,10 @@ func (s *SignalClient) HandleMatrixReactionRemove(ctx context.Context, msg *brid } func (s *SignalClient) HandleMatrixMessageRemove(ctx context.Context, msg *bridgev2.MatrixMessageRemove) error { - _, targetSentTimestamp, err := parseMessageID(msg.TargetMessage.ID) + _, targetSentTimestamp, err := signalid.ParseMessageID(msg.TargetMessage.ID) if err != nil { return fmt.Errorf("failed to parse target message ID: %w", err) - } else if msg.TargetMessage.SenderID != makeUserID(s.Client.Store.ACI) { + } else if msg.TargetMessage.SenderID != signalid.MakeUserID(s.Client.Store.ACI) { return fmt.Errorf("cannot delete other people's messages") } wrappedContent := &signalpb.Content{ @@ -237,7 +223,7 @@ func (s *SignalClient) HandleMatrixReadReceipt(ctx context.Context, receipt *bri } messagesToRead := map[uuid.UUID][]uint64{} for _, msg := range dbMessages { - userID, timestamp, err := parseMessageID(msg.ID) + userID, timestamp, err := signalid.ParseMessageID(msg.ID) if err != nil { return fmt.Errorf("failed to parse message ID %q: %w", msg.ID, err) } @@ -275,7 +261,7 @@ func (s *SignalClient) HandleMatrixReadReceipt(ctx context.Context, receipt *bri } func (s *SignalClient) HandleMatrixTyping(ctx context.Context, typing *bridgev2.MatrixTyping) error { - userID, _, err := parsePortalID(typing.Portal.ID) + userID, _, err := signalid.ParsePortalID(typing.Portal.ID) if err != nil { return err } @@ -292,11 +278,11 @@ func (s *SignalClient) HandleMatrixTyping(ctx context.Context, typing *bridgev2. } func (s *SignalClient) handleMatrixRoomMeta(ctx context.Context, portal *bridgev2.Portal, gc *signalmeow.GroupChange, postUpdatePortal func()) (bool, error) { - _, groupID, err := parsePortalID(portal.ID) + _, groupID, err := signalid.ParsePortalID(portal.ID) if err != nil || groupID == "" { return false, err } - gc.Revision = portal.Metadata.(*PortalMetadata).Revision + 1 + gc.Revision = portal.Metadata.(*signalid.PortalMetadata).Revision + 1 revision, err := s.Client.UpdateGroup(ctx, gc, groupID) if err != nil { return false, err @@ -316,7 +302,7 @@ func (s *SignalClient) handleMatrixRoomMeta(ctx context.Context, portal *bridgev if postUpdatePortal != nil { postUpdatePortal() } - portal.Metadata.(*PortalMetadata).Revision = revision + portal.Metadata.(*signalid.PortalMetadata).Revision = revision return true, nil } @@ -327,7 +313,7 @@ func (s *SignalClient) HandleMatrixRoomName(ctx context.Context, msg *bridgev2.M } func (s *SignalClient) HandleMatrixRoomAvatar(ctx context.Context, msg *bridgev2.MatrixRoomAvatar) (bool, error) { - _, groupID, err := parsePortalID(msg.Portal.ID) + _, groupID, err := signalid.ParsePortalID(msg.Portal.ID) if err != nil || groupID == "" { return false, err } diff --git a/pkg/connector/handlesignal.go b/pkg/connector/handlesignal.go index 169338d..2f6803d 100644 --- a/pkg/connector/handlesignal.go +++ b/pkg/connector/handlesignal.go @@ -30,6 +30,7 @@ import ( "maunium.net/go/mautrix/bridgev2/networkid" "maunium.net/go/mautrix/event" + "go.mau.fi/mautrix-signal/pkg/signalid" "go.mau.fi/mautrix-signal/pkg/signalmeow/events" signalpb "go.mau.fi/mautrix-signal/pkg/signalmeow/protobuf" ) @@ -63,7 +64,7 @@ func (s *SignalClient) wrapCallEvent(evt *events.Call) bridgev2.RemoteMessage { PortalKey: s.makePortalKey(evt.Info.ChatID), Data: evt, CreatePortal: true, - ID: makeMessageID(evt.Info.Sender, evt.Timestamp), + ID: signalid.MakeMessageID(evt.Info.Sender, evt.Timestamp), Sender: s.makeEventSender(evt.Info.Sender), Timestamp: time.UnixMilli(int64(evt.Timestamp)), ConvertMessageFunc: convertCallEvent, @@ -76,7 +77,7 @@ func convertCallEvent(ctx context.Context, portal *bridgev2.Portal, intent bridg } if data.IsRinging { content.Body = "Incoming call" - if userID, _, _ := parsePortalID(portal.ID); !userID.IsEmpty() { + if userID, _, _ := signalid.ParsePortalID(portal.ID); !userID.IsEmpty() { content.MsgType = event.MsgText } } else { @@ -152,7 +153,7 @@ func (evt *Bv2ChatEvent) PreHandle(ctx context.Context, portal *bridgev2.Portal) if !ok || dataMsg.GroupV2 == nil { return } - portalRev := portal.Metadata.(*PortalMetadata).Revision + portalRev := portal.Metadata.(*signalid.PortalMetadata).Revision if evt.Info.GroupRevision > portalRev { toRevision := evt.Info.GroupRevision if dataMsg.GetGroupV2().GetGroupChange() != nil { @@ -206,7 +207,7 @@ func (evt *Bv2ChatEvent) GetID() networkid.MessageID { if ts == 0 { panic(fmt.Errorf("GetID() called for non-DataMessage event")) } - return makeMessageID(evt.Info.Sender, ts) + return signalid.MakeMessageID(evt.Info.Sender, ts) } func (evt *Bv2ChatEvent) getDataMsgTimestamp() uint64 { @@ -251,7 +252,7 @@ func (evt *Bv2ChatEvent) GetTargetMessage() networkid.MessageID { if targetAuthorACI != "" { targetAuthorUUID, _ = uuid.Parse(targetAuthorACI) } - return makeMessageID(targetAuthorUUID, targetSentTS) + return signalid.MakeMessageID(targetAuthorUUID, targetSentTS) } func (evt *Bv2ChatEvent) GetReactionEmoji() (string, networkid.EmojiID) { @@ -267,82 +268,35 @@ func (evt *Bv2ChatEvent) GetRemovedEmojiID() networkid.EmojiID { } func (evt *Bv2ChatEvent) ConvertMessage(ctx context.Context, portal *bridgev2.Portal, intent bridgev2.MatrixAPI) (*bridgev2.ConvertedMessage, error) { - mcCtx := &msgconvContext{ - Connector: evt.s.Main, - Intent: intent, - Client: evt.s, - Portal: portal, - } - ctx = context.WithValue(ctx, msgconvContextKey, mcCtx) dataMsg, ok := evt.Event.(*signalpb.DataMessage) if !ok { return nil, fmt.Errorf("ConvertMessage() called for non-DataMessage event") } - converted := evt.s.Main.MsgConv.ToMatrix(ctx, dataMsg) - converted.MergeCaption() - var replyTo *networkid.MessageOptionalPartID - if dataMsg.GetQuote() != nil { - quoteAuthor, _ := uuid.Parse(dataMsg.Quote.GetAuthorAci()) - replyTo = &networkid.MessageOptionalPartID{ - MessageID: makeMessageID(quoteAuthor, dataMsg.Quote.GetId()), - } - } - convertedParts := make([]*bridgev2.ConvertedMessagePart, len(converted.Parts)) - for i, part := range converted.Parts { - convertedParts[i] = &bridgev2.ConvertedMessagePart{ - ID: makeMessagePartID(i), - Type: part.Type, - Content: part.Content, - Extra: part.Extra, - DBMetadata: &MessageMetadata{ContainsAttachments: len(dataMsg.GetAttachments()) > 0}, - } - } - var disappear database.DisappearingSetting - if converted.DisappearIn != 0 { - disappear = database.DisappearingSetting{ - Type: database.DisappearingTypeAfterRead, - Timer: time.Duration(converted.DisappearIn) * time.Second, - } - dataMsgTS := time.UnixMilli(int64(dataMsg.GetTimestamp())) + converted := evt.s.Main.MsgConv.ToMatrix(ctx, evt.s.Client, portal, intent, dataMsg) + if converted.Disappear.Type != "" { + evtTS := evt.GetTimestamp() + portal.UpdateDisappearingSetting(ctx, converted.Disappear, nil, evtTS, true, true) if evt.Info.Sender == evt.s.Client.Store.ACI { - disappear.DisappearAt = dataMsgTS.Add(disappear.Timer) + converted.Disappear.DisappearAt = evtTS.Add(converted.Disappear.Timer) } - portal.UpdateDisappearingSetting(ctx, disappear, nil, dataMsgTS, true, true) } - return &bridgev2.ConvertedMessage{ - ReplyTo: replyTo, - Parts: convertedParts, - Disappear: disappear, - }, nil + return converted, nil } func (evt *Bv2ChatEvent) ConvertEdit(ctx context.Context, portal *bridgev2.Portal, intent bridgev2.MatrixAPI, existing []*database.Message) (*bridgev2.ConvertedEdit, error) { - mcCtx := &msgconvContext{ - Connector: evt.s.Main, - Intent: intent, - Client: evt.s, - Portal: portal, - } - ctx = context.WithValue(ctx, msgconvContextKey, mcCtx) editMsg, ok := evt.Event.(*signalpb.EditMessage) if !ok { return nil, fmt.Errorf("ConvertEdit() called for non-EditMessage event") } // TODO tell converter about existing parts to avoid reupload? - converted := evt.s.Main.MsgConv.ToMatrix(ctx, editMsg.GetDataMessage()) - converted.MergeCaption() - convertedEdit := &bridgev2.ConvertedEdit{} + converted := evt.s.Main.MsgConv.ToMatrix(ctx, evt.s.Client, portal, intent, editMsg.GetDataMessage()) // TODO can anything other than the text be edited? - lastPart := converted.Parts[len(converted.Parts)-1] - convertedEdit.ModifiedParts = append(convertedEdit.ModifiedParts, &bridgev2.ConvertedEditPart{ - Part: existing[len(existing)-1], - Type: lastPart.Type, - Content: lastPart.Content, - Extra: lastPart.Extra, - }) - convertedEdit.ModifiedParts[0].Part.EditCount++ - convertedEdit.ModifiedParts[0].Part.ID = makeMessageID(evt.Info.Sender, editMsg.GetDataMessage().GetTimestamp()) - return convertedEdit, nil + editPart := converted.Parts[len(converted.Parts)-1].ToEditPart(existing[len(existing)-1]) + editPart.Part.EditCount++ + editPart.Part.ID = signalid.MakeMessageID(evt.Info.Sender, editMsg.GetDataMessage().GetTimestamp()) + return &bridgev2.ConvertedEdit{ + ModifiedParts: []*bridgev2.ConvertedEditPart{editPart}, + }, nil } type Bv2Receipt struct { @@ -438,7 +392,7 @@ func (s *SignalClient) handleSignalReceipt(evt *events.Receipt) { Logger() ctx := log.WithContext(context.TODO()) receipts := convertReceipts(ctx, evt.Content.Timestamp, func(ctx context.Context, msgTS uint64) (*database.Message, error) { - return s.Main.Bridge.DB.Message.GetFirstPartByID(ctx, s.UserLogin.ID, makeMessageID(s.Client.Store.ACI, msgTS)) + return s.Main.Bridge.DB.Message.GetFirstPartByID(ctx, s.UserLogin.ID, signalid.MakeMessageID(s.Client.Store.ACI, msgTS)) }) s.dispatchReceipts(evt.Sender, evt.Content.GetType(), receipts) } @@ -453,7 +407,7 @@ func (s *SignalClient) handleSignalReadSelf(evt *events.ReadSelf) { if err != nil { return nil, err } - return s.Main.Bridge.DB.Message.GetFirstPartByID(ctx, s.UserLogin.ID, makeMessageID(aciUUID, msgInfo.GetTimestamp())) + return s.Main.Bridge.DB.Message.GetFirstPartByID(ctx, s.UserLogin.ID, signalid.MakeMessageID(aciUUID, msgInfo.GetTimestamp())) }) s.dispatchReceipts(s.Client.Store.ACI, signalpb.ReceiptMessage_READ, receipts) } @@ -495,7 +449,7 @@ func (s *SignalClient) handleSignalContactList(evt *events.ContactList) { continue } fullContact.ContactAvatar = contact.ContactAvatar - ghost, err := s.Main.Bridge.GetGhostByID(ctx, makeUserID(contact.ACI)) + ghost, err := s.Main.Bridge.GetGhostByID(ctx, signalid.MakeUserID(contact.ACI)) if err != nil { log.Err(err).Msg("Failed to get ghost to update contact info") continue @@ -510,7 +464,7 @@ func (s *SignalClient) handleSignalContactList(evt *events.ContactList) { func (s *SignalClient) updateRemoteProfile(ctx context.Context, resendState bool) { var err error if s.Ghost == nil { - s.Ghost, err = s.Main.Bridge.GetGhostByID(ctx, makeUserID(s.Client.Store.ACI)) + s.Ghost, err = s.Main.Bridge.GetGhostByID(ctx, signalid.MakeUserID(s.Client.Store.ACI)) if err != nil { zerolog.Ctx(ctx).Err(err).Msg("Failed to get ghost for remote profile update") return diff --git a/pkg/connector/id.go b/pkg/connector/id.go index 6aa4f82..49cebe6 100644 --- a/pkg/connector/id.go +++ b/pkg/connector/id.go @@ -17,71 +17,14 @@ package connector import ( - "fmt" - "strconv" - "strings" - "github.com/google/uuid" "maunium.net/go/mautrix/bridgev2" "maunium.net/go/mautrix/bridgev2/networkid" "go.mau.fi/mautrix-signal/pkg/libsignalgo" - "go.mau.fi/mautrix-signal/pkg/signalmeow/types" + "go.mau.fi/mautrix-signal/pkg/signalid" ) -func parseUserID(userID networkid.UserID) (uuid.UUID, error) { - serviceID, err := parseUserIDAsServiceID(userID) - if err != nil { - return uuid.Nil, err - } else if serviceID.Type != libsignalgo.ServiceIDTypeACI { - return uuid.Nil, fmt.Errorf("invalid user ID: expected ACI type") - } else { - return serviceID.UUID, nil - } -} - -func parseUserIDAsServiceID(userID networkid.UserID) (libsignalgo.ServiceID, error) { - return libsignalgo.ServiceIDFromString(string(userID)) -} - -func parsePortalID(portalID networkid.PortalID) (userID libsignalgo.ServiceID, groupID types.GroupIdentifier, err error) { - if len(portalID) == 44 { - groupID = types.GroupIdentifier(portalID) - } else { - userID, err = libsignalgo.ServiceIDFromString(string(portalID)) - } - return -} - -func parseMessageID(messageID networkid.MessageID) (sender uuid.UUID, timestamp uint64, err error) { - parts := strings.Split(string(messageID), "|") - if len(parts) != 2 { - err = fmt.Errorf("invalid message ID: expected two pipe-separated parts") - return - } - sender, err = uuid.Parse(parts[0]) - if err != nil { - return - } - timestamp, err = strconv.ParseUint(parts[1], 10, 64) - return -} - -func makeGroupPortalID(groupID types.GroupIdentifier) networkid.PortalID { - return networkid.PortalID(groupID) -} - -func makeGroupPortalKey(groupID types.GroupIdentifier) networkid.PortalKey { - return networkid.PortalKey{ - ID: makeGroupPortalID(groupID), - Receiver: "", - } -} - -func makeDMPortalID(serviceID libsignalgo.ServiceID) networkid.PortalID { - return networkid.PortalID(serviceID.String()) -} - func (s *SignalClient) makePortalKey(chatID string) networkid.PortalKey { key := networkid.PortalKey{ID: networkid.PortalID(chatID)} // For non-group chats, add receiver @@ -93,38 +36,15 @@ func (s *SignalClient) makePortalKey(chatID string) networkid.PortalKey { func (s *SignalClient) makeDMPortalKey(serviceID libsignalgo.ServiceID) networkid.PortalKey { return networkid.PortalKey{ - ID: makeDMPortalID(serviceID), + ID: signalid.MakeDMPortalID(serviceID), Receiver: s.UserLogin.ID, } } -func makeMessageID(sender uuid.UUID, timestamp uint64) networkid.MessageID { - return networkid.MessageID(fmt.Sprintf("%s|%d", sender, timestamp)) -} - -func makeUserID(user uuid.UUID) networkid.UserID { - return networkid.UserID(user.String()) -} - -func makeUserIDFromServiceID(user libsignalgo.ServiceID) networkid.UserID { - return networkid.UserID(user.String()) -} - -func makeUserLoginID(user uuid.UUID) networkid.UserLoginID { - return networkid.UserLoginID(user.String()) -} - func (s *SignalClient) makeEventSender(sender uuid.UUID) bridgev2.EventSender { return bridgev2.EventSender{ IsFromMe: sender == s.Client.Store.ACI, - SenderLogin: makeUserLoginID(sender), - Sender: makeUserID(sender), + SenderLogin: signalid.MakeUserLoginID(sender), + Sender: signalid.MakeUserID(sender), } } - -func makeMessagePartID(index int) networkid.PartID { - if index == 0 { - return "" - } - return networkid.PartID(strconv.Itoa(index)) -} diff --git a/pkg/connector/login.go b/pkg/connector/login.go index 3acd926..2e79933 100644 --- a/pkg/connector/login.go +++ b/pkg/connector/login.go @@ -25,6 +25,7 @@ import ( "maunium.net/go/mautrix/bridgev2" "maunium.net/go/mautrix/bridgev2/database" + "go.mau.fi/mautrix-signal/pkg/signalid" "go.mau.fi/mautrix-signal/pkg/signalmeow" "go.mau.fi/mautrix-signal/pkg/signalmeow/store" ) @@ -144,7 +145,7 @@ func (qr *QRLogin) qrWait(ctx context.Context) (*bridgev2.LoginStep, error) { func (qr *QRLogin) processingWait(ctx context.Context) (*bridgev2.LoginStep, error) { defer qr.cancelChan() - newLoginID := makeUserLoginID(qr.ProvData.ACI) + newLoginID := signalid.MakeUserLoginID(qr.ProvData.ACI) select { case resp := <-qr.ProvChan: diff --git a/pkg/connector/msgconvproxy.go b/pkg/connector/msgconvproxy.go deleted file mode 100644 index 8dc2db8..0000000 --- a/pkg/connector/msgconvproxy.go +++ /dev/null @@ -1,117 +0,0 @@ -// mautrix-signal - A Matrix-Signal puppeting bridge. -// Copyright (C) 2024 Tulir Asokan -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see . - -package connector - -import ( - "context" - "strings" - - "google.golang.org/protobuf/proto" - "maunium.net/go/mautrix/bridgev2" - "maunium.net/go/mautrix/bridgev2/database" - "maunium.net/go/mautrix/event" - "maunium.net/go/mautrix/id" - - legacydb "go.mau.fi/mautrix-signal/database" - "go.mau.fi/mautrix-signal/msgconv" - "go.mau.fi/mautrix-signal/pkg/signalmeow" - signalpb "go.mau.fi/mautrix-signal/pkg/signalmeow/protobuf" -) - -type contextKey int - -var msgconvContextKey contextKey - -type msgconvContext struct { - Connector *SignalConnector - Intent bridgev2.MatrixAPI - Client *SignalClient - Portal *bridgev2.Portal - ReplyTo *database.Message -} - -type msgconvPortalMethods struct{} - -var _ msgconv.PortalMethods = (*msgconvPortalMethods)(nil) - -func (mpm *msgconvPortalMethods) UploadMatrixMedia(ctx context.Context, data []byte, fileName, contentType string) (id.ContentURIString, error) { - mcCtx := ctx.Value(msgconvContextKey).(*msgconvContext) - uri, _, err := mcCtx.Intent.UploadMedia(ctx, "", data, fileName, contentType) - return uri, err -} - -func (mpm *msgconvPortalMethods) DownloadMatrixMedia(ctx context.Context, uri id.ContentURIString) ([]byte, error) { - return ctx.Value(msgconvContextKey).(*msgconvContext).Connector.Bridge.Bot.DownloadMedia(ctx, uri, nil) -} - -func (mpm *msgconvPortalMethods) GetMatrixReply(ctx context.Context, msg *signalpb.DataMessage_Quote) (replyTo id.EventID, replyTargetSender id.UserID) { - // Matrix replies are handled in bridgev2 code - return "", "" -} - -func (mpm *msgconvPortalMethods) GetSignalReply(ctx context.Context, content *event.MessageEventContent) *signalpb.DataMessage_Quote { - mcCtx := ctx.Value(msgconvContextKey).(*msgconvContext) - if mcCtx.ReplyTo == nil { - return nil - } - quote := &signalpb.DataMessage_Quote{ - Id: proto.Uint64(uint64(mcCtx.ReplyTo.Timestamp.UnixMilli())), - AuthorAci: proto.String(string(mcCtx.ReplyTo.SenderID)), - Type: signalpb.DataMessage_Quote_NORMAL.Enum(), - } - if mcCtx.ReplyTo.Metadata.(*MessageMetadata).ContainsAttachments { - quote.Attachments = make([]*signalpb.DataMessage_Quote_QuotedAttachment, 1) - } - return quote -} - -func (mpm *msgconvPortalMethods) GetClient(ctx context.Context) *signalmeow.Client { - return ctx.Value(msgconvContextKey).(*msgconvContext).Client.Client -} - -func (mpm *msgconvPortalMethods) GetData(ctx context.Context) *legacydb.Portal { - mcCtx := ctx.Value(msgconvContextKey).(*msgconvContext) - portal := mcCtx.Portal - userID, groupID, _ := parsePortalID(portal.ID) - chatID := string(groupID) - if chatID == "" { - chatID = userID.String() - } - pk := legacydb.PortalKey{ - ChatID: chatID, - } - if len(chatID) != 44 { - pk.Receiver = mcCtx.Client.Client.Store.ACI - } - return &legacydb.Portal{ - PortalKey: pk, - MXID: portal.MXID, - Name: portal.Name, - Topic: portal.Topic, - //AvatarPath: "", - //AvatarHash: "", - //AvatarURL: id.ContentURI{}, - NameSet: portal.NameSet, - AvatarSet: portal.AvatarSet, - TopicSet: portal.TopicSet, - Revision: portal.Metadata.(*PortalMetadata).Revision, - // Hack to prevent encryption while using the bridge as a "local bridge" - Encrypted: !strings.HasSuffix(portal.Bridge.Matrix.ServerName(), ".localhost"), - //RelayUserID: portal.Relay.UserMXID, - ExpirationTime: uint32(portal.Disappear.Timer.Seconds()), - } -} diff --git a/msgconv/from-matrix.go b/pkg/msgconv/from-matrix.go similarity index 74% rename from msgconv/from-matrix.go rename to pkg/msgconv/from-matrix.go index 9a14ead..3b61b9f 100644 --- a/msgconv/from-matrix.go +++ b/pkg/msgconv/from-matrix.go @@ -18,35 +18,37 @@ package msgconv import ( "context" - "errors" "fmt" "strings" "time" "github.com/rs/zerolog" - "github.com/rs/zerolog/log" - "go.mau.fi/util/exerrors" "go.mau.fi/util/exmime" "go.mau.fi/util/ffmpeg" "go.mau.fi/util/variationselector" "golang.org/x/exp/constraints" "google.golang.org/protobuf/proto" + "maunium.net/go/mautrix/bridgev2" + "maunium.net/go/mautrix/bridgev2/database" "maunium.net/go/mautrix/event" - "go.mau.fi/mautrix-signal/msgconv/matrixfmt" + "go.mau.fi/mautrix-signal/pkg/msgconv/matrixfmt" + "go.mau.fi/mautrix-signal/pkg/signalid" + "go.mau.fi/mautrix-signal/pkg/signalmeow" signalpb "go.mau.fi/mautrix-signal/pkg/signalmeow/protobuf" ) -var ( - ErrUnsupportedMsgType = errors.New("unsupported msgtype") - ErrMediaDownloadFailed = errors.New("failed to download media") - ErrMediaDecryptFailed = errors.New("failed to decrypt media") - ErrMediaConvertFailed = errors.New("failed to convert") - ErrMediaUploadFailed = errors.New("failed to upload media") - ErrInvalidGeoURI = errors.New("invalid `geo:` URI in message") -) - -func (mc *MessageConverter) ToSignal(ctx context.Context, evt *event.Event, content *event.MessageEventContent, relaybotFormatted bool) (*signalpb.DataMessage, error) { +func (mc *MessageConverter) ToSignal( + ctx context.Context, + client *signalmeow.Client, + portal *bridgev2.Portal, + evt *event.Event, + content *event.MessageEventContent, + relaybotFormatted bool, + replyTo *database.Message, +) (*signalpb.DataMessage, error) { + ctx = context.WithValue(ctx, contextKeyClient, client) + ctx = context.WithValue(ctx, contextKeyPortal, portal) if evt.Type == event.EventSticker { content.MsgType = event.MessageType(event.EventSticker.Type) } @@ -59,11 +61,23 @@ func (mc *MessageConverter) ToSignal(ctx context.Context, evt *event.Event, cont } dm := &signalpb.DataMessage{ Timestamp: &ts, - Quote: mc.GetSignalReply(ctx, content), - Preview: mc.convertURLPreviewToSignal(ctx, evt), + Preview: mc.convertURLPreviewToSignal(ctx, content), } - if expirationTime := mc.GetData(ctx).ExpirationTime; expirationTime != 0 { - dm.ExpireTimer = proto.Uint32(uint32(expirationTime)) + if replyTo != nil { + authorACI, messageID, err := signalid.ParseMessageID(replyTo.ID) + if err == nil { + dm.Quote = &signalpb.DataMessage_Quote{ + Id: proto.Uint64(messageID), + AuthorAci: proto.String(authorACI.String()), + Type: signalpb.DataMessage_Quote_NORMAL.Enum(), + } + if replyTo.Metadata.(*signalid.MessageMetadata).ContainsAttachments { + dm.Quote.Attachments = make([]*signalpb.DataMessage_Quote_QuotedAttachment, 1) + } + } + } + if portal.Disappear.Timer > 0 { + dm.ExpireTimer = proto.Uint32(uint32(portal.Disappear.Timer.Seconds())) } if content.MsgType == event.MsgEmote && !relaybotFormatted { content.Body = "/me " + content.Body @@ -113,13 +127,13 @@ func (mc *MessageConverter) ToSignal(ctx context.Context, evt *event.Event, cont case event.MsgLocation: lat, lon, err := parseGeoURI(content.GeoURI) if err != nil { - log.Err(err).Msg("Invalid geo URI") + zerolog.Ctx(ctx).Err(err).Msg("Invalid geo URI") return nil, err } locationString := fmt.Sprintf(mc.LocationFormat, lat, lon) dm.Body = &locationString default: - return nil, fmt.Errorf("%w %s", ErrUnsupportedMsgType, content.MsgType) + return nil, fmt.Errorf("%w %s", bridgev2.ErrUnsupportedMessageType, content.MsgType) } return dm, nil } @@ -133,44 +147,33 @@ func maybeInt[T constraints.Integer](v T) *T { func (mc *MessageConverter) convertFileToSignal(ctx context.Context, evt *event.Event, content *event.MessageEventContent) (*signalpb.AttachmentPointer, error) { log := zerolog.Ctx(ctx) - mxc := content.URL - if content.File != nil { - mxc = content.File.URL - } - data, err := mc.DownloadMatrixMedia(ctx, mxc) + data, err := mc.Bridge.Bot.DownloadMedia(ctx, content.URL, content.File) if err != nil { - return nil, exerrors.NewDualError(ErrMediaDownloadFailed, err) - } - if content.File != nil { - err = content.File.DecryptInPlace(data) - if err != nil { - return nil, exerrors.NewDualError(ErrMediaDecryptFailed, err) - } + return nil, fmt.Errorf("%w: %w", bridgev2.ErrMediaDownloadFailed, err) } fileName := content.Body if content.FileName != "" { fileName = content.FileName } - _, isVoice := evt.Content.Raw["org.matrix.msc3245.voice"] mime := content.GetInfo().MimeType - if isVoice { + if content.MSC3245Voice != nil && ffmpeg.Supported() { data, err = ffmpeg.ConvertBytes(ctx, data, ".m4a", []string{}, []string{"-c:a", "aac"}, mime) if err != nil { return nil, err } mime = "audio/aac" fileName += ".m4a" - } else if evt.Type == event.EventSticker && mime != "image/webp" && mime != "image/png" && mime != "image/apng" { + } else if evt.Type == event.EventSticker { switch mime { case "image/webp", "image/png", "image/apng": // allowed case "image/gif": - if !mc.ConvertGIFToAPNG { + if !ffmpeg.Supported() { return nil, fmt.Errorf("converting gif stickers is not supported") } data, err = ffmpeg.ConvertBytes(ctx, data, ".apng", []string{}, []string{}, mime) if err != nil { - return nil, fmt.Errorf("%w gif to apng: %w", ErrMediaConvertFailed, err) + return nil, fmt.Errorf("%w (gif to apng): %w", bridgev2.ErrMediaConvertFailed, err) } fileName += ".apng" mime = "image/apng" @@ -178,12 +181,12 @@ func (mc *MessageConverter) convertFileToSignal(ctx context.Context, evt *event. return nil, fmt.Errorf("unsupported content type for sticker %s", mime) } } - att, err := mc.GetClient(ctx).UploadAttachment(ctx, data) + att, err := getClient(ctx).UploadAttachment(ctx, data) if err != nil { log.Err(err).Msg("Failed to upload file") - return nil, exerrors.NewDualError(ErrMediaUploadFailed, err) + return nil, fmt.Errorf("%w: %w", bridgev2.ErrMediaReuploadFailed, err) } - if isVoice { + if content.MSC3245Voice != nil && mime == "audio/aac" { att.Flags = proto.Uint32(uint32(signalpb.AttachmentPointer_VOICE_MESSAGE)) } att.ContentType = proto.String(mime) diff --git a/msgconv/from-signal.go b/pkg/msgconv/from-signal.go similarity index 72% rename from msgconv/from-signal.go rename to pkg/msgconv/from-signal.go index 918c749..e4ab6dc 100644 --- a/msgconv/from-signal.go +++ b/pkg/msgconv/from-signal.go @@ -26,49 +26,22 @@ import ( "time" "github.com/emersion/go-vcard" + "github.com/google/uuid" "github.com/rs/zerolog" "go.mau.fi/util/exfmt" "go.mau.fi/util/exmime" "go.mau.fi/util/ffmpeg" - "golang.org/x/exp/slices" - "maunium.net/go/mautrix/crypto/attachment" + "maunium.net/go/mautrix/bridgev2" + "maunium.net/go/mautrix/bridgev2/database" + "maunium.net/go/mautrix/bridgev2/networkid" "maunium.net/go/mautrix/event" - "go.mau.fi/mautrix-signal/msgconv/signalfmt" + "go.mau.fi/mautrix-signal/pkg/msgconv/signalfmt" + "go.mau.fi/mautrix-signal/pkg/signalid" "go.mau.fi/mautrix-signal/pkg/signalmeow" signalpb "go.mau.fi/mautrix-signal/pkg/signalmeow/protobuf" ) -type ConvertedMessage struct { - Parts []*ConvertedMessagePart - Timestamp uint64 - DisappearIn uint32 -} - -func (cm *ConvertedMessage) MergeCaption() { - if len(cm.Parts) != 2 || cm.Parts[1].Content.MsgType != event.MsgText { - return - } - switch cm.Parts[0].Content.MsgType { - case event.MsgImage, event.MsgVideo, event.MsgAudio, event.MsgFile: - default: - return - } - mediaContent := cm.Parts[0].Content - textContent := cm.Parts[1].Content - mediaContent.FileName = mediaContent.Body - mediaContent.Body = textContent.Body - mediaContent.Format = textContent.Format - mediaContent.FormattedBody = textContent.FormattedBody - cm.Parts = cm.Parts[:1] -} - -type ConvertedMessagePart struct { - Type event.Type - Content *event.MessageEventContent - Extra map[string]any -} - func calculateLength(dm *signalpb.DataMessage) int { if dm.GetFlags()&uint32(signalpb.DataMessage_EXPIRATION_TIMER_UPDATE) != 0 { return 1 @@ -96,19 +69,30 @@ func CanConvertSignal(dm *signalpb.DataMessage) bool { return calculateLength(dm) > 0 } -func (mc *MessageConverter) ToMatrix(ctx context.Context, dm *signalpb.DataMessage) *ConvertedMessage { - cm := &ConvertedMessage{ - Timestamp: dm.GetTimestamp(), - DisappearIn: dm.GetExpireTimer(), - Parts: make([]*ConvertedMessagePart, 0, calculateLength(dm)), +func (mc *MessageConverter) ToMatrix( + ctx context.Context, + client *signalmeow.Client, + portal *bridgev2.Portal, + intent bridgev2.MatrixAPI, + dm *signalpb.DataMessage, +) *bridgev2.ConvertedMessage { + ctx = context.WithValue(ctx, contextKeyClient, client) + ctx = context.WithValue(ctx, contextKeyPortal, portal) + ctx = context.WithValue(ctx, contextKeyIntent, intent) + cm := &bridgev2.ConvertedMessage{ + ReplyTo: nil, + ThreadRoot: nil, + Parts: make([]*bridgev2.ConvertedMessagePart, 0, calculateLength(dm)), } if dm.GetFlags()&uint32(signalpb.DataMessage_EXPIRATION_TIMER_UPDATE) != 0 { cm.Parts = append(cm.Parts, mc.ConvertDisappearingTimerChangeToMatrix(ctx, dm.GetExpireTimer(), true)) - // Don't disappear disappearing timer changes - cm.DisappearIn = 0 // Don't allow any other parts in a disappearing timer change message return cm } + if dm.GetExpireTimer() > 0 { + cm.Disappear.Type = database.DisappearingTypeAfterRead + cm.Disappear.Timer = time.Duration(dm.GetExpireTimer()) * time.Second + } if dm.Sticker != nil { cm.Parts = append(cm.Parts, mc.convertStickerToMatrix(ctx, dm.Sticker)) // Don't allow any other parts in a sticker message @@ -139,7 +123,7 @@ func (mc *MessageConverter) ToMatrix(ctx context.Context, dm *signalpb.DataMessa cm.Parts = append(cm.Parts, mc.convertTextToMatrix(ctx, dm)) } if len(cm.Parts) == 0 && dm.GetRequiredProtocolVersion() > uint32(signalpb.DataMessage_CURRENT) { - cm.Parts = append(cm.Parts, &ConvertedMessagePart{ + cm.Parts = append(cm.Parts, &bridgev2.ConvertedMessagePart{ Type: event.EventMessage, Content: &event.MessageEventContent{ MsgType: event.MsgNotice, @@ -147,23 +131,28 @@ func (mc *MessageConverter) ToMatrix(ctx context.Context, dm *signalpb.DataMessa }, }) } - replyTo, sender := mc.GetMatrixReply(ctx, dm.Quote) - for _, part := range cm.Parts { - if part.Content.Mentions == nil { - part.Content.Mentions = &event.Mentions{} + cm.MergeCaption() + for i, part := range cm.Parts { + part.ID = signalid.MakeMessagePartID(i) + part.DBMetadata = &signalid.MessageMetadata{ + ContainsAttachments: len(dm.GetAttachments()) > 0, } - if replyTo != "" { - part.Content.RelatesTo = (&event.RelatesTo{}).SetReplyTo(replyTo) - if !slices.Contains(part.Content.Mentions.UserIDs, sender) { - part.Content.Mentions.UserIDs = append(part.Content.Mentions.UserIDs, sender) + } + if dm.Quote != nil { + authorACI, err := uuid.Parse(dm.Quote.GetAuthorAci()) + if err != nil { + zerolog.Ctx(ctx).Err(err).Str("author_aci", dm.Quote.GetAuthorAci()).Msg("Failed to parse quote author ACI") + } else { + cm.ReplyTo = &networkid.MessageOptionalPartID{ + MessageID: signalid.MakeMessageID(authorACI, dm.Quote.GetId()), } } } return cm } -func (mc *MessageConverter) ConvertDisappearingTimerChangeToMatrix(ctx context.Context, timer uint32, updatePortal bool) *ConvertedMessagePart { - part := &ConvertedMessagePart{ +func (mc *MessageConverter) ConvertDisappearingTimerChangeToMatrix(ctx context.Context, timer uint32, updatePortal bool) *bridgev2.ConvertedMessagePart { + part := &bridgev2.ConvertedMessagePart{ Type: event.EventMessage, Content: &event.MessageEventContent{ MsgType: event.MsgNotice, @@ -174,35 +163,36 @@ func (mc *MessageConverter) ConvertDisappearingTimerChangeToMatrix(ctx context.C part.Content.Body = "Disappearing messages disabled" } if updatePortal { - if mc.UpdateDisappearing != nil { - mc.UpdateDisappearing(ctx, time.Duration(timer)*time.Second) + portal := getPortal(ctx) + portal.Disappear.Timer = time.Duration(timer) * time.Second + if timer == 0 { + portal.Disappear.Type = "" } else { - portal := mc.GetData(ctx) - portal.ExpirationTime = timer - err := portal.Update(ctx) - if err != nil { - zerolog.Ctx(ctx).Err(err).Msg("Failed to update portal disappearing timer in database") - } + portal.Disappear.Type = database.DisappearingTypeAfterRead + } + err := portal.Save(ctx) + if err != nil { + zerolog.Ctx(ctx).Err(err).Msg("Failed to update portal disappearing timer in database") } } return part } -func (mc *MessageConverter) convertTextToMatrix(ctx context.Context, dm *signalpb.DataMessage) *ConvertedMessagePart { +func (mc *MessageConverter) convertTextToMatrix(ctx context.Context, dm *signalpb.DataMessage) *bridgev2.ConvertedMessagePart { content := signalfmt.Parse(ctx, dm.GetBody(), dm.GetBodyRanges(), mc.SignalFmtParams) extra := map[string]any{} if len(dm.Preview) > 0 { - extra["com.beeper.linkpreviews"] = mc.convertURLPreviewsToBeeper(ctx, dm.Preview) + content.BeeperLinkPreviews = mc.convertURLPreviewsToBeeper(ctx, dm.Preview) } - return &ConvertedMessagePart{ + return &bridgev2.ConvertedMessagePart{ Type: event.EventMessage, Content: content, Extra: extra, } } -func (mc *MessageConverter) convertPaymentToMatrix(_ context.Context, payment *signalpb.DataMessage_Payment) *ConvertedMessagePart { - return &ConvertedMessagePart{ +func (mc *MessageConverter) convertPaymentToMatrix(_ context.Context, payment *signalpb.DataMessage_Payment) *bridgev2.ConvertedMessagePart { + return &bridgev2.ConvertedMessagePart{ Type: event.EventMessage, Content: &event.MessageEventContent{ MsgType: event.MsgNotice, @@ -214,8 +204,8 @@ func (mc *MessageConverter) convertPaymentToMatrix(_ context.Context, payment *s } } -func (mc *MessageConverter) convertGiftBadgeToMatrix(_ context.Context, giftBadge *signalpb.DataMessage_GiftBadge) *ConvertedMessagePart { - return &ConvertedMessagePart{ +func (mc *MessageConverter) convertGiftBadgeToMatrix(_ context.Context, giftBadge *signalpb.DataMessage_GiftBadge) *bridgev2.ConvertedMessagePart { + return &bridgev2.ConvertedMessagePart{ Type: event.EventMessage, Content: &event.MessageEventContent{ MsgType: event.MsgNotice, @@ -303,7 +293,7 @@ func (mc *MessageConverter) convertContactToVCard(ctx context.Context, contact * return card } -func (mc *MessageConverter) convertContactToMatrix(ctx context.Context, contact *signalpb.DataMessage_Contact) *ConvertedMessagePart { +func (mc *MessageConverter) convertContactToMatrix(ctx context.Context, contact *signalpb.DataMessage_Contact) *bridgev2.ConvertedMessagePart { card := mc.convertContactToVCard(ctx, contact) contact.Avatar = nil extraData := map[string]any{ @@ -313,7 +303,7 @@ func (mc *MessageConverter) convertContactToMatrix(ctx context.Context, contact err := vcard.NewEncoder(&buf).Encode(card) if err != nil { zerolog.Ctx(ctx).Err(err).Msg("Failed to encode vCard") - return &ConvertedMessagePart{ + return &bridgev2.ConvertedMessagePart{ Type: event.EventMessage, Content: &event.MessageEventContent{ MsgType: event.MsgNotice, @@ -323,30 +313,6 @@ func (mc *MessageConverter) convertContactToMatrix(ctx context.Context, contact } } data := buf.Bytes() - var file *event.EncryptedFileInfo - uploadMime := "text/vcard" - uploadFileName := "contact.vcf" - if mc.GetData(ctx).Encrypted { - file = &event.EncryptedFileInfo{ - EncryptedFile: *attachment.NewEncryptedFile(), - URL: "", - } - file.EncryptInPlace(data) - uploadMime = "application/octet-stream" - uploadFileName = "" - } - mxc, err := mc.UploadMatrixMedia(ctx, data, uploadFileName, uploadMime) - if err != nil { - zerolog.Ctx(ctx).Err(err).Msg("Failed to upload vCard") - return &ConvertedMessagePart{ - Type: event.EventMessage, - Content: &event.MessageEventContent{ - MsgType: event.MsgNotice, - Body: "Failed to upload vCard", - }, - Extra: extraData, - } - } displayName := contact.GetName().GetDisplayName() if displayName == "" { displayName = contact.GetName().GetGivenName() @@ -368,24 +334,30 @@ func (mc *MessageConverter) convertContactToMatrix(ctx context.Context, contact Size: len(data), }, } - if file != nil { - file.URL = mxc - content.File = file - } else { - content.URL = mxc + content.URL, content.File, err = getIntent(ctx).UploadMedia(ctx, getPortal(ctx).MXID, data, content.Info.MimeType, content.Body) + if err != nil { + zerolog.Ctx(ctx).Err(err).Msg("Failed to upload vCard") + return &bridgev2.ConvertedMessagePart{ + Type: event.EventMessage, + Content: &event.MessageEventContent{ + MsgType: event.MsgNotice, + Body: "Failed to upload vCard", + }, + Extra: extraData, + } } - return &ConvertedMessagePart{ + return &bridgev2.ConvertedMessagePart{ Type: event.EventMessage, Content: content, Extra: extraData, } } -func (mc *MessageConverter) convertAttachmentToMatrix(ctx context.Context, index int, att *signalpb.AttachmentPointer) *ConvertedMessagePart { +func (mc *MessageConverter) convertAttachmentToMatrix(ctx context.Context, index int, att *signalpb.AttachmentPointer) *bridgev2.ConvertedMessagePart { part, err := mc.reuploadAttachment(ctx, att) if err != nil { zerolog.Ctx(ctx).Err(err).Int("attachment_index", index).Msg("Failed to handle attachment") - return &ConvertedMessagePart{ + return &bridgev2.ConvertedMessagePart{ Type: event.EventMessage, Content: &event.MessageEventContent{ MsgType: event.MsgNotice, @@ -396,11 +368,11 @@ func (mc *MessageConverter) convertAttachmentToMatrix(ctx context.Context, index return part } -func (mc *MessageConverter) convertStickerToMatrix(ctx context.Context, sticker *signalpb.DataMessage_Sticker) *ConvertedMessagePart { +func (mc *MessageConverter) convertStickerToMatrix(ctx context.Context, sticker *signalpb.DataMessage_Sticker) *bridgev2.ConvertedMessagePart { converted, err := mc.reuploadAttachment(ctx, sticker.GetData()) if err != nil { zerolog.Ctx(ctx).Err(err).Msg("Failed to handle sticker") - return &ConvertedMessagePart{ + return &bridgev2.ConvertedMessagePart{ Type: event.EventMessage, Content: &event.MessageEventContent{ MsgType: event.MsgNotice, @@ -437,7 +409,7 @@ func (mc *MessageConverter) downloadSignalLongText(ctx context.Context, att *sig return &longBody, nil } -func (mc *MessageConverter) reuploadAttachment(ctx context.Context, att *signalpb.AttachmentPointer) (*ConvertedMessagePart, error) { +func (mc *MessageConverter) reuploadAttachment(ctx context.Context, att *signalpb.AttachmentPointer) (*bridgev2.ConvertedMessagePart, error) { data, err := signalmeow.DownloadAttachment(ctx, att) if err != nil { return nil, fmt.Errorf("failed to download attachment: %w", err) @@ -447,43 +419,28 @@ func (mc *MessageConverter) reuploadAttachment(ctx context.Context, att *signalp mimeType = http.DetectContentType(data) } fileName := att.GetFileName() - extra := map[string]any{} - if mc.ConvertVoiceMessages && att.GetFlags()&uint32(signalpb.AttachmentPointer_VOICE_MESSAGE) != 0 { + content := &event.MessageEventContent{ + Info: &event.FileInfo{ + Width: int(att.GetWidth()), + Height: int(att.GetHeight()), + Size: len(data), + }, + } + if att.GetFlags()&uint32(signalpb.AttachmentPointer_VOICE_MESSAGE) != 0 && ffmpeg.Supported() { data, err = ffmpeg.ConvertBytes(ctx, data, ".ogg", []string{}, []string{"-c:a", "libopus"}, mimeType) if err != nil { return nil, fmt.Errorf("failed to convert audio to ogg/opus: %w", err) } fileName += ".ogg" mimeType = "audio/ogg" - extra["org.matrix.msc3245.voice"] = map[string]any{} + content.MSC3245Voice = &event.MSC3245Voice{} // TODO include duration here (and in info) if there's some easy way to extract it with ffmpeg - //extra["org.matrix.msc1767.audio"] = map[string]any{"duration": ???} + //content.MSC1767Audio = &event.MSC1767Audio{} } - var file *event.EncryptedFileInfo - uploadMime := mimeType - uploadFileName := fileName - if mc.GetData(ctx).Encrypted { - file = &event.EncryptedFileInfo{ - EncryptedFile: *attachment.NewEncryptedFile(), - URL: "", - } - file.EncryptInPlace(data) - uploadMime = "application/octet-stream" - uploadFileName = "" - } - mxc, err := mc.UploadMatrixMedia(ctx, data, uploadFileName, uploadMime) + content.URL, content.File, err = getIntent(ctx).UploadMedia(ctx, getPortal(ctx).MXID, data, fileName, mimeType) if err != nil { return nil, err } - content := &event.MessageEventContent{ - Body: fileName, - Info: &event.FileInfo{ - MimeType: mimeType, - Width: int(att.GetWidth()), - Height: int(att.GetHeight()), - Size: len(data), - }, - } if att.GetBlurHash() != "" { content.Info.Blurhash = att.GetBlurHash() content.Info.AnoaBlurhash = att.GetBlurHash() @@ -498,18 +455,13 @@ func (mc *MessageConverter) reuploadAttachment(ctx context.Context, att *signalp default: content.MsgType = event.MsgFile } + content.Body = fileName + content.Info.MimeType = mimeType if content.Body == "" { content.Body = strings.TrimPrefix(string(content.MsgType), "m.") + exmime.ExtensionFromMimetype(mimeType) } - if file != nil { - file.URL = mxc - content.File = file - } else { - content.URL = mxc - } - return &ConvertedMessagePart{ + return &bridgev2.ConvertedMessagePart{ Type: event.EventMessage, Content: content, - Extra: extra, }, nil } diff --git a/msgconv/matrixfmt/convert.go b/pkg/msgconv/matrixfmt/convert.go similarity index 100% rename from msgconv/matrixfmt/convert.go rename to pkg/msgconv/matrixfmt/convert.go diff --git a/msgconv/matrixfmt/convert_test.go b/pkg/msgconv/matrixfmt/convert_test.go similarity index 97% rename from msgconv/matrixfmt/convert_test.go rename to pkg/msgconv/matrixfmt/convert_test.go index 6f9d66e..240ca98 100644 --- a/msgconv/matrixfmt/convert_test.go +++ b/pkg/msgconv/matrixfmt/convert_test.go @@ -10,8 +10,8 @@ import ( "maunium.net/go/mautrix/event" "maunium.net/go/mautrix/id" - "go.mau.fi/mautrix-signal/msgconv/matrixfmt" - "go.mau.fi/mautrix-signal/msgconv/signalfmt" + "go.mau.fi/mautrix-signal/pkg/msgconv/matrixfmt" + "go.mau.fi/mautrix-signal/pkg/msgconv/signalfmt" ) var formatParams = &matrixfmt.HTMLParser{ diff --git a/msgconv/matrixfmt/html.go b/pkg/msgconv/matrixfmt/html.go similarity index 99% rename from msgconv/matrixfmt/html.go rename to pkg/msgconv/matrixfmt/html.go index 94571da..1e3d249 100644 --- a/msgconv/matrixfmt/html.go +++ b/pkg/msgconv/matrixfmt/html.go @@ -13,7 +13,7 @@ import ( "maunium.net/go/mautrix/event" "maunium.net/go/mautrix/id" - "go.mau.fi/mautrix-signal/msgconv/signalfmt" + "go.mau.fi/mautrix-signal/pkg/msgconv/signalfmt" ) type EntityString struct { diff --git a/pkg/msgconv/msgconv.go b/pkg/msgconv/msgconv.go new file mode 100644 index 0000000..1d1fee8 --- /dev/null +++ b/pkg/msgconv/msgconv.go @@ -0,0 +1,107 @@ +// mautrix-signal - A Matrix-signal puppeting bridge. +// Copyright (C) 2024 Tulir Asokan +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +package msgconv + +import ( + "context" + + "github.com/google/uuid" + "maunium.net/go/mautrix/bridgev2" + "maunium.net/go/mautrix/bridgev2/networkid" + "maunium.net/go/mautrix/id" + + "go.mau.fi/mautrix-signal/pkg/msgconv/matrixfmt" + "go.mau.fi/mautrix-signal/pkg/msgconv/signalfmt" + "go.mau.fi/mautrix-signal/pkg/signalid" + "go.mau.fi/mautrix-signal/pkg/signalmeow" +) + +type contextKey int + +const ( + contextKeyPortal contextKey = iota + contextKeyClient + contextKeyIntent +) + +type MessageConverter struct { + Bridge *bridgev2.Bridge + + SignalFmtParams *signalfmt.FormatParams + MatrixFmtParams *matrixfmt.HTMLParser + + MaxFileSize int64 + LocationFormat string +} + +func NewMessageConverter(br *bridgev2.Bridge, locationFormat string) *MessageConverter { + return &MessageConverter{ + Bridge: br, + SignalFmtParams: &signalfmt.FormatParams{ + GetUserInfo: func(ctx context.Context, uuid uuid.UUID) signalfmt.UserInfo { + ghost, err := br.GetGhostByID(ctx, signalid.MakeUserID(uuid)) + if err != nil { + // TODO log? + return signalfmt.UserInfo{} + } + userInfo := signalfmt.UserInfo{ + MXID: ghost.Intent.GetMXID(), + Name: ghost.Name, + } + userLogin := br.GetCachedUserLoginByID(networkid.UserLoginID(uuid.String())) + if userLogin != nil { + userInfo.MXID = userLogin.UserMXID + // TODO find matrix user displayname? + } + return userInfo + }, + }, + MatrixFmtParams: &matrixfmt.HTMLParser{ + GetUUIDFromMXID: func(ctx context.Context, userID id.UserID) uuid.UUID { + parsed, ok := br.Matrix.ParseGhostMXID(userID) + if ok { + u, _ := uuid.Parse(string(parsed)) + return u + } + user, _ := br.GetExistingUserByMXID(ctx, userID) + // TODO log errors? + if user != nil { + preferredLogin, _, _ := getPortal(ctx).FindPreferredLogin(ctx, user, true) + if preferredLogin != nil { + u, _ := uuid.Parse(string(preferredLogin.ID)) + return u + } + } + return uuid.Nil + }, + }, + MaxFileSize: 50 * 1024 * 1024, + LocationFormat: locationFormat, + } +} + +func getClient(ctx context.Context) *signalmeow.Client { + return ctx.Value(contextKeyClient).(*signalmeow.Client) +} + +func getPortal(ctx context.Context) *bridgev2.Portal { + return ctx.Value(contextKeyPortal).(*bridgev2.Portal) +} + +func getIntent(ctx context.Context) bridgev2.MatrixAPI { + return ctx.Value(contextKeyIntent).(bridgev2.MatrixAPI) +} diff --git a/msgconv/signalfmt/convert.go b/pkg/msgconv/signalfmt/convert.go similarity index 100% rename from msgconv/signalfmt/convert.go rename to pkg/msgconv/signalfmt/convert.go diff --git a/msgconv/signalfmt/convert_test.go b/pkg/msgconv/signalfmt/convert_test.go similarity index 99% rename from msgconv/signalfmt/convert_test.go rename to pkg/msgconv/signalfmt/convert_test.go index 1b2d693..eb65542 100644 --- a/msgconv/signalfmt/convert_test.go +++ b/pkg/msgconv/signalfmt/convert_test.go @@ -26,7 +26,7 @@ import ( "maunium.net/go/mautrix/event" "maunium.net/go/mautrix/id" - "go.mau.fi/mautrix-signal/msgconv/signalfmt" + "go.mau.fi/mautrix-signal/pkg/msgconv/signalfmt" signalpb "go.mau.fi/mautrix-signal/pkg/signalmeow/protobuf" ) diff --git a/msgconv/signalfmt/html.go b/pkg/msgconv/signalfmt/html.go similarity index 100% rename from msgconv/signalfmt/html.go rename to pkg/msgconv/signalfmt/html.go diff --git a/msgconv/signalfmt/tags.go b/pkg/msgconv/signalfmt/tags.go similarity index 100% rename from msgconv/signalfmt/tags.go rename to pkg/msgconv/signalfmt/tags.go diff --git a/msgconv/signalfmt/tree.go b/pkg/msgconv/signalfmt/tree.go similarity index 100% rename from msgconv/signalfmt/tree.go rename to pkg/msgconv/signalfmt/tree.go diff --git a/msgconv/urlpreview.go b/pkg/msgconv/urlpreview.go similarity index 53% rename from msgconv/urlpreview.go rename to pkg/msgconv/urlpreview.go index 168dcb9..d2d3b23 100644 --- a/msgconv/urlpreview.go +++ b/pkg/msgconv/urlpreview.go @@ -18,37 +18,27 @@ package msgconv import ( "context" - "encoding/json" - "regexp" "time" "github.com/rs/zerolog" - "github.com/tidwall/gjson" "google.golang.org/protobuf/proto" - "maunium.net/go/mautrix" "maunium.net/go/mautrix/event" signalpb "go.mau.fi/mautrix-signal/pkg/signalmeow/protobuf" ) -type BeeperLinkPreview struct { - mautrix.RespPreviewURL - MatchedURL string `json:"matched_url"` - ImageEncryption *event.EncryptedFileInfo `json:"beeper:image:encryption,omitempty"` -} - -func (mc *MessageConverter) convertURLPreviewsToBeeper(ctx context.Context, preview []*signalpb.Preview) []*BeeperLinkPreview { - output := make([]*BeeperLinkPreview, len(preview)) +func (mc *MessageConverter) convertURLPreviewsToBeeper(ctx context.Context, preview []*signalpb.Preview) []*event.BeeperLinkPreview { + output := make([]*event.BeeperLinkPreview, len(preview)) for i, p := range preview { output[i] = mc.convertURLPreviewToBeeper(ctx, p) } return output } -func (mc *MessageConverter) convertURLPreviewToBeeper(ctx context.Context, preview *signalpb.Preview) *BeeperLinkPreview { - output := &BeeperLinkPreview{ +func (mc *MessageConverter) convertURLPreviewToBeeper(ctx context.Context, preview *signalpb.Preview) *event.BeeperLinkPreview { + output := &event.BeeperLinkPreview{ MatchedURL: preview.GetUrl(), - RespPreviewURL: mautrix.RespPreviewURL{ + LinkPreview: event.LinkPreview{ CanonicalURL: preview.GetUrl(), Title: preview.GetTitle(), Description: preview.GetDescription(), @@ -70,65 +60,34 @@ func (mc *MessageConverter) convertURLPreviewToBeeper(ctx context.Context, previ return output } -var URLRegex = regexp.MustCompile(`https?://[^\s/_*]+(?:/\S*)?`) - -func (mc *MessageConverter) convertURLPreviewToSignal(ctx context.Context, evt *event.Event) []*signalpb.Preview { - var previews []*BeeperLinkPreview - - log := zerolog.Ctx(ctx) - rawPreview := gjson.GetBytes(evt.Content.VeryRaw, `com\.beeper\.linkpreviews`) - if rawPreview.Exists() && rawPreview.IsArray() { - if err := json.Unmarshal([]byte(rawPreview.Raw), &previews); err != nil || len(previews) == 0 { - return nil - } - } /* else if portal.bridge.Config.Bridge.URLPreviews { - if matchedURL := URLRegex.FindString(evt.Content.AsMessage().Body); len(matchedURL) == 0 { - return nil - } else if parsed, err := url.Parse(matchedURL); err != nil { - return nil - } else if parsed.Host, err = idna.ToASCII(parsed.Host); err != nil { - return nil - } else if mxPreview, err := portal.MainIntent().GetURLPreview(parsed.String()); err != nil { - log.Err(err).Str("matched_url", matchedURL).Msg("Failed to fetch preview for URL found in message") - return nil - } else { - previews = []*BeeperLinkPreview{{ - RespPreviewURL: *mxPreview, - MatchedURL: matchedURL, - }} - } - }*/ - if len(previews) == 0 { +func (mc *MessageConverter) convertURLPreviewToSignal(ctx context.Context, content *event.MessageEventContent) []*signalpb.Preview { + if len(content.BeeperLinkPreviews) == 0 { return nil } - output := make([]*signalpb.Preview, len(previews)) - for i, preview := range previews { + output := make([]*signalpb.Preview, len(content.BeeperLinkPreviews)) + for i, preview := range content.BeeperLinkPreviews { output[i] = &signalpb.Preview{ Url: proto.String(preview.MatchedURL), Title: proto.String(preview.Title), Description: proto.String(preview.Description), Date: proto.Uint64(uint64(time.Now().UnixMilli())), } - imageMXC := preview.ImageURL - if preview.ImageEncryption != nil { - imageMXC = preview.ImageEncryption.URL - } - if imageMXC != "" { - data, err := mc.DownloadMatrixMedia(ctx, imageMXC) + if preview.ImageURL != "" || preview.ImageEncryption != nil { + data, err := mc.Bridge.Bot.DownloadMedia(ctx, preview.ImageURL, preview.ImageEncryption) if err != nil { - log.Err(err).Int("preview_index", i).Msg("Failed to download URL preview image") + zerolog.Ctx(ctx).Err(err).Int("preview_index", i).Msg("Failed to download URL preview image") continue } if preview.ImageEncryption != nil { err = preview.ImageEncryption.DecryptInPlace(data) if err != nil { - log.Err(err).Int("preview_index", i).Msg("Failed to decrypt URL preview image") + zerolog.Ctx(ctx).Err(err).Int("preview_index", i).Msg("Failed to decrypt URL preview image") continue } } - uploaded, err := mc.GetClient(ctx).UploadAttachment(ctx, data) + uploaded, err := getClient(ctx).UploadAttachment(ctx, data) if err != nil { - log.Err(err).Int("preview_index", i).Msg("Failed to reupload URL preview image") + zerolog.Ctx(ctx).Err(err).Int("preview_index", i).Msg("Failed to reupload URL preview image") continue } uploaded.ContentType = proto.String(preview.ImageType) diff --git a/database/upgrades/upgrades.go b/pkg/signalid/dbmeta.go similarity index 54% rename from database/upgrades/upgrades.go rename to pkg/signalid/dbmeta.go index 20f60f4..2d85a0c 100644 --- a/database/upgrades/upgrades.go +++ b/pkg/signalid/dbmeta.go @@ -1,5 +1,5 @@ // mautrix-signal - A Matrix-Signal puppeting bridge. -// Copyright (C) 2023 Tulir Asokan +// Copyright (C) 2024 Tulir Asokan // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU Affero General Public License as published by @@ -14,27 +14,12 @@ // You should have received a copy of the GNU Affero General Public License // along with this program. If not, see . -package upgrades +package signalid -import ( - "context" - "embed" - "errors" - - "go.mau.fi/util/dbutil" -) - -var Table dbutil.UpgradeTable - -//go:embed *.sql -var rawUpgrades embed.FS - -func init() { - Table.Register(-1, 12, 0, "Unsupported version", dbutil.TxnModeOff, func(ctx context.Context, database *dbutil.Database) error { - return errors.New("please upgrade to mautrix-signal v0.4.3 before upgrading to a newer version") - }) - Table.Register(1, 13, 0, "Jump to version 13", dbutil.TxnModeOff, func(ctx context.Context, database *dbutil.Database) error { - return nil - }) - Table.RegisterFS(rawUpgrades) +type PortalMetadata struct { + Revision uint32 `json:"revision"` +} + +type MessageMetadata struct { + ContainsAttachments bool `json:"contains_attachments,omitempty"` } diff --git a/pkg/signalid/ids.go b/pkg/signalid/ids.go new file mode 100644 index 0000000..f99bf9d --- /dev/null +++ b/pkg/signalid/ids.go @@ -0,0 +1,105 @@ +// mautrix-signal - A Matrix-Signal puppeting bridge. +// Copyright (C) 2024 Tulir Asokan +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +package signalid + +import ( + "fmt" + "strconv" + "strings" + + "github.com/google/uuid" + "maunium.net/go/mautrix/bridgev2/networkid" + + "go.mau.fi/mautrix-signal/pkg/libsignalgo" + "go.mau.fi/mautrix-signal/pkg/signalmeow/types" +) + +func ParseUserID(userID networkid.UserID) (uuid.UUID, error) { + serviceID, err := ParseUserIDAsServiceID(userID) + if err != nil { + return uuid.Nil, err + } else if serviceID.Type != libsignalgo.ServiceIDTypeACI { + return uuid.Nil, fmt.Errorf("invalid user ID: expected ACI type") + } else { + return serviceID.UUID, nil + } +} + +func ParseUserIDAsServiceID(userID networkid.UserID) (libsignalgo.ServiceID, error) { + return libsignalgo.ServiceIDFromString(string(userID)) +} + +func ParsePortalID(portalID networkid.PortalID) (userID libsignalgo.ServiceID, groupID types.GroupIdentifier, err error) { + if len(portalID) == 44 { + groupID = types.GroupIdentifier(portalID) + } else { + userID, err = libsignalgo.ServiceIDFromString(string(portalID)) + } + return +} + +func ParseMessageID(messageID networkid.MessageID) (sender uuid.UUID, timestamp uint64, err error) { + parts := strings.Split(string(messageID), "|") + if len(parts) != 2 { + err = fmt.Errorf("invalid message ID: expected two pipe-separated parts") + return + } + sender, err = uuid.Parse(parts[0]) + if err != nil { + return + } + timestamp, err = strconv.ParseUint(parts[1], 10, 64) + return +} + +func MakeGroupPortalID(groupID types.GroupIdentifier) networkid.PortalID { + return networkid.PortalID(groupID) +} + +func MakeGroupPortalKey(groupID types.GroupIdentifier) networkid.PortalKey { + return networkid.PortalKey{ + ID: MakeGroupPortalID(groupID), + Receiver: "", + } +} + +func MakeDMPortalID(serviceID libsignalgo.ServiceID) networkid.PortalID { + return networkid.PortalID(serviceID.String()) +} + +func MakeMessageID(sender uuid.UUID, timestamp uint64) networkid.MessageID { + return networkid.MessageID(fmt.Sprintf("%s|%d", sender, timestamp)) +} + +func MakeUserID(user uuid.UUID) networkid.UserID { + return networkid.UserID(user.String()) +} + +func MakeUserIDFromServiceID(user libsignalgo.ServiceID) networkid.UserID { + return networkid.UserID(user.String()) +} + +func MakeUserLoginID(user uuid.UUID) networkid.UserLoginID { + return networkid.UserLoginID(user.String()) +} + +func MakeMessagePartID(index int) networkid.PartID { + if index == 0 { + return "" + } + return networkid.PartID(strconv.Itoa(index)) +} diff --git a/portal.go b/portal.go deleted file mode 100644 index 37fabe6..0000000 --- a/portal.go +++ /dev/null @@ -1,3026 +0,0 @@ -// mautrix-signal - A Matrix-signal puppeting bridge. -// Copyright (C) 2023 Scott Weber, Tulir Asokan -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see . - -package main - -import ( - "context" - "crypto/sha256" - "encoding/hex" - "errors" - "fmt" - "net/http" - "reflect" - "strings" - "sync" - "time" - - "github.com/google/uuid" - "github.com/rs/zerolog" - "go.mau.fi/util/exfmt" - "go.mau.fi/util/jsontime" - "go.mau.fi/util/variationselector" - "google.golang.org/protobuf/proto" - "maunium.net/go/mautrix" - "maunium.net/go/mautrix/appservice" - "maunium.net/go/mautrix/bridge" - "maunium.net/go/mautrix/bridge/bridgeconfig" - "maunium.net/go/mautrix/bridge/status" - "maunium.net/go/mautrix/event" - "maunium.net/go/mautrix/id" - - "go.mau.fi/mautrix-signal/database" - "go.mau.fi/mautrix-signal/msgconv" - "go.mau.fi/mautrix-signal/msgconv/matrixfmt" - "go.mau.fi/mautrix-signal/msgconv/signalfmt" - "go.mau.fi/mautrix-signal/pkg/libsignalgo" - "go.mau.fi/mautrix-signal/pkg/signalmeow" - "go.mau.fi/mautrix-signal/pkg/signalmeow/events" - signalpb "go.mau.fi/mautrix-signal/pkg/signalmeow/protobuf" - "go.mau.fi/mautrix-signal/pkg/signalmeow/types" -) - -func (br *SignalBridge) GetPortalByMXID(mxid id.RoomID) *Portal { - br.portalsLock.Lock() - defer br.portalsLock.Unlock() - - portal, ok := br.portalsByMXID[mxid] - if !ok { - dbPortal, err := br.DB.Portal.GetByMXID(context.TODO(), mxid) - if err != nil { - br.ZLog.Err(err).Msg("Failed to get portal from database") - return nil - } - return br.loadPortal(context.TODO(), dbPortal, nil) - } - - return portal -} - -func (br *SignalBridge) GetPortalByChatID(key database.PortalKey) *Portal { - br.portalsLock.Lock() - defer br.portalsLock.Unlock() - return br.unlockedGetPortalByChatID(key, true) -} - -func (br *SignalBridge) GetPortalByChatIDIfExists(key database.PortalKey) *Portal { - br.portalsLock.Lock() - defer br.portalsLock.Unlock() - return br.unlockedGetPortalByChatID(key, false) -} - -func (br *SignalBridge) unlockedGetPortalByChatID(key database.PortalKey, createIfNotExists bool) *Portal { - // If this PortalKey is for a group, Receiver should be empty - if key.UserID().IsEmpty() { - key.Receiver = uuid.Nil - } - portal, ok := br.portalsByID[key] - if !ok { - dbPortal, err := br.DB.Portal.GetByChatID(context.TODO(), key) - if err != nil { - br.ZLog.Err(err).Msg("Failed to get portal from database") - return nil - } - keyIfNotExists := &key - if !createIfNotExists { - keyIfNotExists = nil - } - return br.loadPortal(context.TODO(), dbPortal, keyIfNotExists) - } - return portal -} - -func (br *SignalBridge) GetAllPortalsWithMXID() []*Portal { - portals, err := br.dbPortalsToPortals(br.DB.Portal.GetAllWithMXID(context.TODO())) - if err != nil { - br.ZLog.Err(err).Msg("Failed to get all portals with mxid") - return nil - } - return portals -} - -func (br *SignalBridge) FindPrivateChatPortalsWith(userID uuid.UUID) []*Portal { - portals, err := br.dbPortalsToPortals(br.DB.Portal.FindPrivateChatsWith(context.TODO(), userID)) - if err != nil { - br.ZLog.Err(err).Msg("Failed to get all DM portals with user") - return nil - } - return portals -} - -func (br *SignalBridge) GetAllIPortals() (iportals []bridge.Portal) { - portals, err := br.dbPortalsToPortals(br.DB.Portal.GetAllWithMXID(context.TODO())) - if err != nil { - br.ZLog.Err(err).Msg("Failed to get all portals with mxid") - return nil - } - iportals = make([]bridge.Portal, len(portals)) - for i, portal := range portals { - iportals[i] = portal - } - return iportals -} - -func (br *SignalBridge) loadPortal(ctx context.Context, dbPortal *database.Portal, key *database.PortalKey) *Portal { - if dbPortal == nil { - if key == nil { - return nil - } - - dbPortal = br.DB.Portal.New() - dbPortal.PortalKey = *key - err := dbPortal.Insert(ctx) - if err != nil { - br.ZLog.Err(err).Msg("Failed to insert new portal") - return nil - } - } - - portal := br.NewPortal(dbPortal) - - br.portalsByID[portal.PortalKey] = portal - if portal.MXID != "" { - br.portalsByMXID[portal.MXID] = portal - } - - return portal -} - -func (br *SignalBridge) dbPortalsToPortals(dbPortals []*database.Portal, err error) ([]*Portal, error) { - if err != nil { - return nil, err - } - br.portalsLock.Lock() - defer br.portalsLock.Unlock() - - output := make([]*Portal, len(dbPortals)) - for index, dbPortal := range dbPortals { - if dbPortal == nil { - continue - } - - portal, ok := br.portalsByID[dbPortal.PortalKey] - if !ok { - portal = br.loadPortal(context.TODO(), dbPortal, nil) - } - - output[index] = portal - } - - return output, nil -} - -type portalSignalMessage struct { - evt *events.ChatEvent - user *User -} - -type portalMatrixMessage struct { - evt *event.Event - user *User -} - -type Portal struct { - *database.Portal - - MsgConv *msgconv.MessageConverter - - bridge *SignalBridge - log zerolog.Logger - - roomCreateLock sync.Mutex - encryptLock sync.Mutex - - signalMessages chan portalSignalMessage - matrixMessages chan portalMatrixMessage - - currentlyTyping []id.UserID - currentlyTypingLock sync.Mutex - - relayUser *User -} - -var signalFormatParams *signalfmt.FormatParams -var matrixFormatParams *matrixfmt.HTMLParser - -func (br *SignalBridge) NewPortal(dbPortal *database.Portal) *Portal { - log := br.ZLog.With().Str("chat_id", dbPortal.ChatID).Logger() - if dbPortal.MXID != "" { - log = log.With().Stringer("room_id", dbPortal.MXID).Logger() - } - - portal := &Portal{ - Portal: dbPortal, - bridge: br, - log: log, - - signalMessages: make(chan portalSignalMessage, br.Config.Bridge.PortalMessageBuffer), - matrixMessages: make(chan portalMatrixMessage, br.Config.Bridge.PortalMessageBuffer), - } - portal.MsgConv = &msgconv.MessageConverter{ - PortalMethods: portal, - SignalFmtParams: signalFormatParams, - MatrixFmtParams: matrixFormatParams, - ConvertVoiceMessages: true, - MaxFileSize: br.MediaConfig.UploadSize, - LocationFormat: br.Config.Bridge.LocationFormat, - } - go portal.messageLoop() - - return portal -} - -func init() { - event.TypeMap[event.StateBridge] = reflect.TypeOf(CustomBridgeInfoContent{}) - event.TypeMap[event.StateHalfShotBridge] = reflect.TypeOf(CustomBridgeInfoContent{}) -} - -var ( - _ bridge.Portal = (*Portal)(nil) - _ bridge.ReadReceiptHandlingPortal = (*Portal)(nil) - _ bridge.TypingPortal = (*Portal)(nil) - _ bridge.DisappearingPortal = (*Portal)(nil) - //_ bridge.MembershipHandlingPortal = (*Portal)(nil) - //_ bridge.MetaHandlingPortal = (*Portal)(nil) -) - -func (portal *Portal) IsEncrypted() bool { - return portal.Encrypted -} - -func (portal *Portal) MarkEncrypted() { - portal.Encrypted = true - err := portal.Update(context.TODO()) - if err != nil { - portal.log.Err(err).Msg("Failed to update portal in database after marking as encrypted") - } -} - -func (portal *Portal) ReceiveMatrixEvent(user bridge.User, evt *event.Event) { - if user.GetPermissionLevel() >= bridgeconfig.PermissionLevelUser || portal.HasRelaybot() { - portal.matrixMessages <- portalMatrixMessage{user: user.(*User), evt: evt} - } -} - -func (portal *Portal) GetRelayUser() *User { - if !portal.HasRelaybot() { - return nil - } else if portal.relayUser == nil { - portal.relayUser = portal.bridge.GetUserByMXID(portal.RelayUserID) - } - return portal.relayUser -} - -func (portal *Portal) IsPrivateChat() bool { - return !portal.UserID().IsEmpty() -} - -func (portal *Portal) IsNoteToSelf() bool { - userID := portal.UserID() - return !userID.IsEmpty() && userID.UUID == portal.Receiver -} - -func (portal *Portal) MainIntent() *appservice.IntentAPI { - dmPuppet := portal.GetDMPuppet() - if dmPuppet != nil { - return dmPuppet.DefaultIntent() - } - - return portal.bridge.Bot -} - -type CustomBridgeInfoContent struct { - event.BridgeEventContent - RoomType string `json:"com.beeper.room_type,omitempty"` -} - -func (portal *Portal) getBridgeInfo() (string, CustomBridgeInfoContent) { - bridgeInfo := event.BridgeEventContent{ - BridgeBot: portal.bridge.Bot.UserID, - Creator: portal.MainIntent().UserID, - Protocol: event.BridgeInfoSection{ - ID: "signal", - DisplayName: "Signal", - AvatarURL: portal.bridge.Config.AppService.Bot.ParsedAvatar.CUString(), - ExternalURL: "https://signal.org/", - }, - Channel: event.BridgeInfoSection{ - ID: portal.ChatID, - DisplayName: portal.Name, - AvatarURL: portal.AvatarURL.CUString(), - }, - } - bridgeInfoStateKey := fmt.Sprintf("fi.mau.signal://signal/%s", portal.ChatID) - bridgeInfo.Channel.ExternalURL = fmt.Sprintf("https://signal.me/#p/%s", portal.ChatID) - var roomType string - if portal.IsPrivateChat() { - roomType = "dm" - } - return bridgeInfoStateKey, CustomBridgeInfoContent{bridgeInfo, roomType} -} - -func (portal *Portal) UpdateBridgeInfo(ctx context.Context) { - if len(portal.MXID) == 0 { - portal.log.Debug().Msg("Not updating bridge info: no Matrix room created") - return - } - portal.log.Debug().Msg("Updating bridge info...") - stateKey, content := portal.getBridgeInfo() - _, err := portal.MainIntent().SendStateEvent(ctx, portal.MXID, event.StateBridge, stateKey, content) - if err != nil { - portal.log.Warn().Err(err).Msg("Failed to update m.bridge") - } - // TODO remove this once https://github.com/matrix-org/matrix-doc/pull/2346 is in spec - _, err = portal.MainIntent().SendStateEvent(ctx, portal.MXID, event.StateHalfShotBridge, stateKey, content) - if err != nil { - portal.log.Warn().Err(err).Msg("Failed to update uk.half-shot.bridge") - } -} - -func (portal *Portal) messageLoop() { - for { - select { - case msg := <-portal.matrixMessages: - portal.handleMatrixMessages(msg) - case msg := <-portal.signalMessages: - portal.handleSignalMessage(msg) - } - } -} - -func (portal *Portal) handleMatrixMessages(msg portalMatrixMessage) { - log := portal.log.With(). - Str("action", "handle matrix event"). - Stringer("event_id", msg.evt.ID). - Str("event_type", msg.evt.Type.String()). - Logger() - ctx := log.WithContext(context.TODO()) - - switch msg.evt.Type { - case event.EventMessage, event.EventSticker: - portal.handleMatrixMessage(ctx, msg.user, msg.evt) - case event.EventRedaction: - portal.handleMatrixRedaction(ctx, msg.user, msg.evt) - case event.EventReaction: - portal.handleMatrixReaction(ctx, msg.user, msg.evt) - default: - log.Warn().Str("type", msg.evt.Type.Type).Msg("Unhandled matrix message type") - } -} - -func (portal *Portal) handleMatrixMessage(ctx context.Context, sender *User, evt *event.Event) { - log := zerolog.Ctx(ctx) - evtTS := time.UnixMilli(evt.Timestamp) - timings := messageTimings{ - initReceive: evt.Mautrix.ReceivedAt.Sub(evtTS), - decrypt: evt.Mautrix.DecryptionDuration, - totalReceive: time.Since(evtTS), - } - implicitRRStart := time.Now() - portal.handleMatrixReadReceipt(sender, "", uint64(evt.Timestamp), false) - timings.implicitRR = time.Since(implicitRRStart) - start := time.Now() - - messageAge := timings.totalReceive - ms := metricSender{portal: portal, timings: &timings, ctx: ctx} - log.Debug(). - Stringer("sender", evt.Sender). - Dur("age", messageAge). - Msg("Received message") - - errorAfter := portal.bridge.Config.Bridge.MessageHandlingTimeout.ErrorAfter - deadline := portal.bridge.Config.Bridge.MessageHandlingTimeout.Deadline - isScheduled, _ := evt.Content.Raw["com.beeper.scheduled"].(bool) - if isScheduled { - log.Debug().Msg("Message is a scheduled message, extending handling timeouts") - errorAfter *= 10 - deadline *= 10 - } - - if errorAfter > 0 { - remainingTime := errorAfter - messageAge - if remainingTime < 0 { - go ms.sendMessageMetrics(evt, errTimeoutBeforeHandling, "Timeout handling", true) - return - } else if remainingTime < 1*time.Second { - log.Warn(). - Dur("remaining_time", remainingTime). - Dur("max_timeout", errorAfter). - Msg("Message was delayed before reaching the bridge") - } - go func() { - time.Sleep(remainingTime) - ms.sendMessageMetrics(evt, errMessageTakingLong, "Timeout handling", false) - }() - } - - if deadline > 0 { - var cancel context.CancelFunc - ctx, cancel = context.WithTimeout(ctx, deadline) - defer cancel() - } - - timings.preproc = time.Since(start) - start = time.Now() - - content, ok := evt.Content.Parsed.(*event.MessageEventContent) - if !ok { - log.Error().Type("content_type", content).Msg("Unexpected parsed content type") - go ms.sendMessageMetrics(evt, fmt.Errorf("%w %T", errUnexpectedParsedContentType, evt.Content.Parsed), "Error converting", true) - return - } - - realSenderMXID := sender.MXID - isRelay := false - if !sender.IsLoggedIn() { - sender = portal.GetRelayUser() - if sender == nil { - go ms.sendMessageMetrics(evt, errUserNotLoggedIn, "Ignoring", true) - return - } else if !sender.IsLoggedIn() { - go ms.sendMessageMetrics(evt, errRelaybotNotLoggedIn, "Ignoring", true) - return - } - isRelay = true - } - - var editTargetMsg *database.Message - if editTarget := content.RelatesTo.GetReplaceID(); editTarget != "" { - var err error - editTargetMsg, err = portal.bridge.DB.Message.GetByMXID(ctx, editTarget) - if err != nil { - log.Err(err).Stringer("edit_target_mxid", editTarget).Msg("Failed to get edit target message") - go ms.sendMessageMetrics(evt, errFailedToGetEditTarget, "Error converting", true) - return - } else if editTargetMsg == nil { - log.Err(err).Stringer("edit_target_mxid", editTarget).Msg("Edit target message not found") - go ms.sendMessageMetrics(evt, errEditUnknownTarget, "Error converting", true) - return - } else if editTargetMsg.Sender != sender.SignalID { - go ms.sendMessageMetrics(evt, errEditDifferentSender, "Error converting", true) - return - } - if content.NewContent != nil { - content = content.NewContent - evt.Content.Parsed = content - } - } - - relaybotFormatted := isRelay && portal.addRelaybotFormat(ctx, realSenderMXID, evt, content) - if content.MsgType == event.MsgNotice && !portal.bridge.Config.Bridge.BridgeNotices { - go ms.sendMessageMetrics(evt, errMNoticeDisabled, "Error converting", true) - return - } - ctx = context.WithValue(ctx, msgconvContextKeyClient, sender.Client) - msg, err := portal.MsgConv.ToSignal(ctx, evt, content, relaybotFormatted) - if err != nil { - log.Err(err).Msg("Failed to convert message") - go ms.sendMessageMetrics(evt, err, "Error converting", true) - return - } - var wrappedMsg *signalpb.Content - if editTargetMsg == nil { - wrappedMsg = &signalpb.Content{ - DataMessage: msg, - } - } else { - wrappedMsg = &signalpb.Content{ - EditMessage: &signalpb.EditMessage{ - TargetSentTimestamp: proto.Uint64(editTargetMsg.Timestamp), - DataMessage: msg, - }, - } - } - - timings.convert = time.Since(start) - start = time.Now() - - err = portal.sendSignalMessage(ctx, wrappedMsg, sender, evt.ID) - - timings.totalSend = time.Since(start) - go ms.sendMessageMetrics(evt, err, "Error sending", true) - if err == nil { - if editTargetMsg != nil { - err = editTargetMsg.SetTimestamp(ctx, msg.GetTimestamp()) - if err != nil { - log.Err(err).Msg("Failed to update message timestamp in database after editing") - } - } else { - portal.storeMessageInDB(ctx, evt.ID, sender.SignalID, msg.GetTimestamp(), 0) - if portal.ExpirationTime > 0 { - portal.addDisappearingMessage(ctx, evt.ID, uint32(portal.ExpirationTime), true) - } - } - } -} - -func (portal *Portal) handleMatrixRedaction(ctx context.Context, sender *User, evt *event.Event) { - log := zerolog.Ctx(ctx) - // Find the original signal message based on eventID - dbMessage, err := portal.bridge.DB.Message.GetByMXID(ctx, evt.Redacts) - if err != nil { - log.Err(err).Msg("Failed to get redaction target message") - } - // Might be a reaction redaction, find the original message for the reaction - dbReaction, err := portal.bridge.DB.Reaction.GetByMXID(ctx, evt.Redacts) - if err != nil { - log.Err(err).Msg("Failed to get redaction target reaction") - } - - if !sender.IsLoggedIn() { - sender = portal.GetRelayUser() - if sender == nil { - portal.sendMessageStatusCheckpointFailed(ctx, evt, errUserNotLoggedIn) - return - } else if !sender.IsLoggedIn() { - portal.sendMessageStatusCheckpointFailed(ctx, evt, errRelaybotNotLoggedIn) - return - } - } - - if dbMessage != nil { - if dbMessage.Sender != sender.SignalID { - portal.sendMessageStatusCheckpointFailed(ctx, evt, errRedactionTargetSentBySomeoneElse) - return - } - msg := signalmeow.DataMessageForDelete(dbMessage.Timestamp) - err = portal.sendSignalMessage(ctx, msg, sender, evt.ID) - if err != nil { - portal.sendMessageStatusCheckpointFailed(ctx, evt, err) - log.Err(err).Msg("Failed to send message redaction to Signal") - return - } - err = dbMessage.Delete(ctx) - if err != nil { - log.Err(err).Msg("Failed to delete redacted message from database") - } else if otherParts, err := portal.bridge.DB.Message.GetAllPartsBySignalID(ctx, dbMessage.Sender, dbMessage.Timestamp, portal.Receiver); err != nil { - log.Err(err).Msg("Failed to get other parts of redacted message from database") - } else if len(otherParts) > 0 { - // If there are other parts of the message, send a redaction for each of them - for _, otherPart := range otherParts { - _, err = portal.MainIntent().RedactEvent(ctx, portal.MXID, otherPart.MXID, mautrix.ReqRedact{ - Reason: "Other part of Signal message redacted", - TxnID: "mxsg_partredact_" + otherPart.MXID.String(), - }) - if err != nil { - log.Err(err). - Stringer("part_event_id", otherPart.MXID). - Int("part_index", otherPart.PartIndex). - Msg("Failed to redact other part of redacted message") - } - err = otherPart.Delete(ctx) - if err != nil { - log.Err(err). - Stringer("part_event_id", otherPart.MXID). - Int("part_index", otherPart.PartIndex). - Msg("Failed to delete other part of redacted message from database") - } - } - } - portal.sendMessageStatusCheckpointSuccess(ctx, evt) - } else if dbReaction != nil { - if dbReaction.Author != sender.SignalID { - portal.sendMessageStatusCheckpointFailed(ctx, evt, errUnreactTargetSentBySomeoneElse) - return - } - msg := signalmeow.DataMessageForReaction(dbReaction.Emoji, dbReaction.MsgAuthor, dbReaction.MsgTimestamp, true) - err = portal.sendSignalMessage(ctx, msg, sender, evt.ID) - if err != nil { - portal.sendMessageStatusCheckpointFailed(ctx, evt, err) - log.Err(err).Msg("Failed to send reaction redaction to Signal") - return - } - err = dbReaction.Delete(ctx) - if err != nil { - log.Err(err).Msg("Failed to delete redacted reaction from database") - } - portal.sendMessageStatusCheckpointSuccess(ctx, evt) - } else { - portal.sendMessageStatusCheckpointFailed(ctx, evt, errRedactionTargetNotFound) - } -} - -func (portal *Portal) handleMatrixReaction(ctx context.Context, sender *User, evt *event.Event) { - log := zerolog.Ctx(ctx) - if !sender.IsLoggedIn() { - portal.sendMessageStatusCheckpointFailed(ctx, evt, errCantRelayReactions) - return - } - // Find the original signal message based on eventID - relatedEventID := evt.Content.AsReaction().RelatesTo.EventID - targetMsg, err := portal.bridge.DB.Message.GetByMXID(ctx, relatedEventID) - if err != nil { - portal.sendMessageStatusCheckpointFailed(ctx, evt, err) - log.Err(err).Msg("Failed to get reaction target message") - return - } else if targetMsg == nil { - portal.sendMessageStatusCheckpointFailed(ctx, evt, errReactionTargetNotFound) - log.Warn().Msg("Reaction target message not found") - return - } - emoji := evt.Content.AsReaction().RelatesTo.Key - signalEmoji := variationselector.FullyQualify(emoji) // Signal seems to require fully qualified emojis - msg := signalmeow.DataMessageForReaction(signalEmoji, targetMsg.Sender, targetMsg.Timestamp, false) - err = portal.sendSignalMessage(ctx, msg, sender, evt.ID) - if err != nil { - portal.sendMessageStatusCheckpointFailed(ctx, evt, err) - log.Error().Msg("Failed to send reaction") - return - } - - // Signal only allows one reaction from each user - // Check if there's an existing reaction in the database for this sender and redact/delete it - dbReaction, err := portal.bridge.DB.Reaction.GetBySignalID( - ctx, - targetMsg.Sender, - targetMsg.Timestamp, - sender.SignalID, - portal.Receiver, - ) - if err != nil { - log.Err(err).Msg("Failed to get existing reaction from database") - } else if dbReaction != nil { - log.Debug().Stringer("existing_event_id", dbReaction.MXID).Msg("Redacting existing reaction after sending new one") - _, err = portal.MainIntent().RedactEvent(ctx, portal.MXID, dbReaction.MXID) - if err != nil { - log.Err(err).Msg("Failed to redact existing reaction") - } - } - if dbReaction != nil { - dbReaction.MXID = evt.ID - dbReaction.Emoji = signalEmoji - err = dbReaction.Update(ctx) - if err != nil { - log.Err(err).Msg("Failed to update reaction in database") - } - } else { - dbReaction = portal.bridge.DB.Reaction.New() - dbReaction.MXID = evt.ID - dbReaction.RoomID = portal.MXID - dbReaction.SignalChatID = portal.ChatID - dbReaction.SignalReceiver = portal.Receiver - dbReaction.Author = sender.SignalID - dbReaction.MsgAuthor = targetMsg.Sender - dbReaction.MsgTimestamp = targetMsg.Timestamp - dbReaction.Emoji = signalEmoji - err = dbReaction.Insert(ctx) - if err != nil { - log.Err(err).Msg("Failed to insert reaction to database") - } - } - - portal.sendMessageStatusCheckpointSuccess(ctx, evt) -} - -func (portal *Portal) sendSignalMessage(ctx context.Context, msg *signalpb.Content, sender *User, evtID id.EventID) error { - log := zerolog.Ctx(ctx).With(). - Str("action", "send signal message"). - Stringer("event_id", evtID). - Str("portal_chat_id", portal.ChatID). - Logger() - ctx = log.WithContext(ctx) - - log.Debug().Msg("Sending event to Signal") - - // Check to see if portal.ChatID is a standard UUID (with dashes) - if portal.IsPrivateChat() { - // this is a 1:1 chat - result := sender.Client.SendMessage(ctx, portal.UserID(), msg) - if !result.WasSuccessful { - return result.Error - } - } else { - // this is a group chat - groupID := types.GroupIdentifier(portal.ChatID) - result, err := sender.Client.SendGroupMessage(ctx, groupID, msg) - if err != nil { - // check the start of the error string, see if it starts with "No group master key found for group identifier" - if strings.HasPrefix(err.Error(), "No group master key found for group identifier") { - portal.MainIntent().SendNotice(ctx, portal.MXID, "Missing group encryption key. Please ask a group member to send a message in this chat, then retry sending.") - } - log.Err(err).Msg("Error sending event to Signal group") - return err - } - totalRecipients := len(result.FailedToSendTo) + len(result.SuccessfullySentTo) - log = log.With(). - Int("total_recipients", totalRecipients). - Int("failed_to_send_to_count", len(result.FailedToSendTo)). - Int("successfully_sent_to_count", len(result.SuccessfullySentTo)). - Logger() - if len(result.FailedToSendTo) > 0 { - log.Error().Msg("Failed to send event to some members of Signal group") - } - if len(result.SuccessfullySentTo) == 0 && len(result.FailedToSendTo) == 0 { - log.Debug().Msg("No successes or failures - Probably sent to myself") - } else if len(result.SuccessfullySentTo) == 0 { - log.Error().Msg("Failed to send event to all members of Signal group") - return errors.New("failed to send to any members of Signal group") - - } else if len(result.SuccessfullySentTo) < totalRecipients { - log.Warn().Msg("Only sent event to some members of Signal group") - } else { - log.Debug().Msg("Sent event to all members of Signal group") - } - } - return nil -} - -func (portal *Portal) sendMessageStatusCheckpointSuccess(ctx context.Context, evt *event.Event) { - portal.sendDeliveryReceipt(ctx, evt.ID) - portal.bridge.SendMessageSuccessCheckpoint(evt, status.MsgStepRemote, 0) - - var deliveredTo *[]id.UserID - if portal.IsPrivateChat() { - deliveredTo = &[]id.UserID{} - } - portal.sendStatusEvent(ctx, evt.ID, "", nil, deliveredTo) -} - -func (portal *Portal) sendMessageStatusCheckpointFailed(ctx context.Context, evt *event.Event, err error) { - portal.sendDeliveryReceipt(ctx, evt.ID) - portal.bridge.SendMessageErrorCheckpoint(evt, status.MsgStepRemote, err, true, 0) - portal.sendStatusEvent(ctx, evt.ID, "", err, nil) -} - -type msgconvContextKey int - -const ( - msgconvContextKeyIntent msgconvContextKey = iota - msgconvContextKeyClient -) - -func (portal *Portal) UploadMatrixMedia(ctx context.Context, data []byte, fileName, contentType string) (id.ContentURIString, error) { - intent := ctx.Value(msgconvContextKeyIntent).(*appservice.IntentAPI) - req := mautrix.ReqUploadMedia{ - ContentBytes: data, - ContentType: contentType, - FileName: fileName, - } - if portal.bridge.Config.Homeserver.AsyncMedia { - uploaded, err := intent.UploadAsync(ctx, req) - if err != nil { - return "", err - } - return uploaded.ContentURI.CUString(), nil - } else { - uploaded, err := intent.UploadMedia(ctx, req) - if err != nil { - return "", err - } - return uploaded.ContentURI.CUString(), nil - } -} - -func (portal *Portal) DownloadMatrixMedia(ctx context.Context, uriString id.ContentURIString) ([]byte, error) { - parsedURI, err := uriString.Parse() - if err != nil { - return nil, fmt.Errorf("malformed content URI: %w", err) - } - return portal.MainIntent().DownloadBytes(ctx, parsedURI) -} - -func (portal *Portal) GetData(ctx context.Context) *database.Portal { - return portal.Portal -} - -func (portal *Portal) GetClient(ctx context.Context) *signalmeow.Client { - return ctx.Value(msgconvContextKeyClient).(*signalmeow.Client) -} - -func (portal *Portal) GetMatrixReply(ctx context.Context, msg *signalpb.DataMessage_Quote) (replyTo id.EventID, replyTargetSender id.UserID) { - if msg == nil { - return - } - log := zerolog.Ctx(ctx).With(). - Str("reply_target_author", msg.GetAuthorAci()). - Uint64("reply_target_ts", msg.GetId()). - Logger() - if senderUUID, err := uuid.Parse(msg.GetAuthorAci()); err != nil { - log.Err(err).Msg("Failed to parse sender UUID in Signal quote") - } else if message, err := portal.bridge.DB.Message.GetBySignalID(ctx, senderUUID, msg.GetId(), 0, portal.Receiver); err != nil { - log.Err(err).Msg("Failed to get reply target message from database") - } else if message == nil { - log.Warn().Msg("Reply target message not found") - } else { - replyTo = message.MXID - targetUser := portal.bridge.GetUserBySignalID(message.Sender) - if targetUser != nil { - replyTargetSender = targetUser.MXID - } else { - replyTargetSender = portal.bridge.FormatPuppetMXID(message.Sender) - } - } - return -} - -func (portal *Portal) GetSignalReply(ctx context.Context, content *event.MessageEventContent) *signalpb.DataMessage_Quote { - replyToID := content.RelatesTo.GetReplyTo() - if len(replyToID) == 0 { - return nil - } - replyToMsg, err := portal.bridge.DB.Message.GetByMXID(ctx, replyToID) - if err != nil { - zerolog.Ctx(ctx).Err(err). - Stringer("reply_to_mxid", replyToID). - Msg("Failed to get reply target message from database") - } else if replyToMsg == nil { - zerolog.Ctx(ctx).Warn(). - Stringer("reply_to_mxid", replyToID). - Msg("Reply target message not found") - } else { - return &signalpb.DataMessage_Quote{ - Id: proto.Uint64(replyToMsg.Timestamp), - AuthorAci: proto.String(replyToMsg.Sender.String()), - Type: signalpb.DataMessage_Quote_NORMAL.Enum(), - - // This is a hack to make Signal iOS and desktop render replies to file messages. - // Unfortunately it also makes Signal Desktop show a file icon on replies to text messages. - // TODO store file or text flag in database and fill this field only when replying to file messages. - Attachments: make([]*signalpb.DataMessage_Quote_QuotedAttachment, 1), - } - } - return nil -} - -func (portal *Portal) handleSignalMessage(portalMessage portalSignalMessage) { - sender := portal.bridge.GetPuppetBySignalID(portalMessage.evt.Info.Sender) - if sender == nil { - portal.log.Warn(). - Stringer("sender_uuid", portalMessage.evt.Info.Sender). - Msg("Couldn't get puppet for message") - return - } - var msgType string - var timestamp uint64 - switch typedEvt := portalMessage.evt.Event.(type) { - case *signalpb.DataMessage: - msgType = "data" - timestamp = typedEvt.GetTimestamp() - portal.handleSignalDataMessage(portalMessage.user, sender, typedEvt) - case *signalpb.TypingMessage: - msgType = "typing" - timestamp = typedEvt.GetTimestamp() - portal.handleSignalTypingMessage(sender, typedEvt) - case *signalpb.EditMessage: - msgType = "edit" - timestamp = typedEvt.GetTargetSentTimestamp() - portal.handleSignalEditMessage(sender, timestamp, typedEvt.GetDataMessage()) - default: - portal.log.Error(). - Type("data_type", typedEvt). - Msg("Invalid inner event type inside ChatEvent") - } - portal.bridge.Metrics.TrackSignalMessage(time.UnixMilli(int64(timestamp)), msgType) -} - -func (portal *Portal) handleSignalDataMessage(source *User, sender *Puppet, msg *signalpb.DataMessage) { - genericCtx := portal.log.With(). - Str("action", "handle signal data message"). - Uint64("msg_ts", msg.GetTimestamp()). - Logger().WithContext(context.TODO()) - // Always update sender info when we receive a message from them, there's caching inside the function - sender.UpdateInfo(genericCtx, source, nil) - // Handle earlier missed group changes here. - if msg.GetGroupV2() != nil { - requiredRevision := msg.GetGroupV2().GetRevision() - if msg.GetGroupV2().GetGroupChange() != nil { - requiredRevision = requiredRevision - 1 - } - if portal.Revision < requiredRevision { - err := portal.catchUpHistory(source, portal.Revision+1, requiredRevision, msg.GetTimestamp()) - if err != nil { - portal.log.Err(err).Msg("Failed to catch up group history, trying regular update") - portal.UpdateInfo(genericCtx, source, nil, msg.GetGroupV2().GetRevision()) - } - } - } else if portal.IsPrivateChat() && portal.UserID().UUID == portal.Receiver && portal.Name != NoteToSelfName { - // Slightly hacky way to make note to self names backfill - portal.UpdateDMInfo(genericCtx, false) - } - - switch { - case msgconv.CanConvertSignal(msg): - portal.handleSignalNormalDataMessage(source, sender, msg) - case msg.Reaction != nil: - portal.handleSignalReaction(sender, msg.Reaction, msg.GetTimestamp()) - case msg.Delete != nil: - portal.handleSignalDelete(sender, msg.Delete, msg.GetTimestamp()) - case msg.GetGroupV2().GetGroupChange() != nil: - portal.handleSignalGroupChange(source, sender, msg.GroupV2, msg.GetTimestamp()) - case msg.StoryContext != nil, msg.GroupCallUpdate != nil: - // ignore - default: - portal.log.Warn(). - Str("action", "handle signal message"). - Stringer("sender_uuid", sender.SignalID). - Uint64("msg_ts", msg.GetTimestamp()). - Msg("Unrecognized content in message") - } -} - -func (portal *Portal) catchUpHistory(source *User, fromRevision uint32, toRevision uint32, ts uint64) error { - log := portal.log.With(). - Str("action", "catchUpHistory"). - Stringer("source", source.MXID). - Uint32("from_revision", fromRevision). - Uint32("to_revision", toRevision). - Logger() - ctx := log.WithContext(context.TODO()) - groupChanges, err := source.Client.GetGroupHistoryPage(ctx, portal.GroupID(), fromRevision, false) - if err != nil { - log.Err(err).Msg("Failed to get GroupChanges") - return err - } - for _, groupChangeState := range groupChanges { - sender := portal.bridge.GetPuppetBySignalID(groupChangeState.GroupChange.SourceACI) - portal.applySignalGroupChange(ctx, source, sender, groupChangeState.GroupChange, ts) - // for revision > toRevision, we should have received a group change already - if groupChangeState.GroupChange.Revision == toRevision { - break - } - } - return nil -} - -func (portal *Portal) handleSignalGroupChange(source *User, sender *Puppet, groupMeta *signalpb.GroupContextV2, ts uint64) { - log := portal.log.With(). - Str("action", "handle signal group change"). - Stringer("sender_uuid", sender.SignalID). - Uint64("change_ts", ts). - Uint32("new_revision", groupMeta.GetRevision()). - Logger() - ctx := log.WithContext(context.TODO()) - groupChange, err := source.Client.DecryptGroupChange(ctx, groupMeta) - if err != nil { - log.Err(err).Msg("Handling GroupChange failed") - return - } - portal.applySignalGroupChange(ctx, source, sender, groupChange, ts) -} - -func (portal *Portal) applySignalGroupChange(ctx context.Context, source *User, sender *Puppet, groupChange *signalmeow.GroupChange, ts uint64) { - log := zerolog.Ctx(ctx) - if groupChange.Revision <= portal.Revision { - return - } - portal.Revision = groupChange.Revision - if groupChange.ModifyTitle != nil { - portal.updateName(ctx, *groupChange.ModifyTitle, sender) - } - if groupChange.ModifyDescription != nil { - portal.updateTopic(ctx, *groupChange.ModifyDescription, sender) - } - if groupChange.ModifyAvatar != nil { - portal.updateAvatarWithInfo(ctx, source, groupChange, sender) - } - if groupChange.ModifyDisappearingMessagesDuration != nil { - portal.updateExpirationTimer(ctx, *groupChange.ModifyDisappearingMessagesDuration) - } - intent := sender.IntentFor(portal) - modifyRoles := groupChange.ModifyMemberRoles - var err error - for _, deleteBannedMember := range groupChange.DeleteBannedMembers { - _, err := portal.sendMembershipForPuppetAndUser(ctx, sender, *&deleteBannedMember.UUID, event.MembershipLeave, "unbanned") - if err != nil { - log.Warn().Stringer("signal_user_id", deleteBannedMember).Msg("Couldn't get puppet for unban") - } - } - for _, addMember := range groupChange.AddMembers { - modifyRoles = append(modifyRoles, &signalmeow.RoleMember{ACI: addMember.ACI, Role: addMember.Role}) - var puppet *Puppet - if addMember.JoinFromInviteLink { - puppet = portal.bridge.GetPuppetBySignalID(addMember.ACI) - if puppet != nil { - if puppet.customIntent == nil { - user := portal.bridge.GetUserBySignalID(addMember.ACI) - if user != nil { - portal.MainIntent().SendCustomMembershipEvent(ctx, portal.MXID, user.MXID, event.MembershipInvite, "Joined via invite Link") - } - } - _, err = puppet.IntentFor(portal).SendCustomMembershipEvent(ctx, portal.MXID, puppet.IntentFor(portal).UserID, event.MembershipJoin, "") - if errors.Is(err, mautrix.MForbidden) { - _, err = portal.MainIntent().SendCustomMembershipEvent(ctx, portal.MXID, puppet.IntentFor(portal).UserID, event.MembershipInvite, "Joined via invite Link") - } else if err == nil { - continue - } - } - } else { - puppet, err = portal.sendMembershipForPuppetAndUser(ctx, sender, addMember.ACI, event.MembershipInvite, "added") - } - if err != nil { - log.Err(err).Stringer("signal_user_id", addMember.ACI).Msg("Couldn't get puppet for invite") - return - } - _, err = puppet.IntentFor(portal).SendCustomMembershipEvent(ctx, portal.MXID, puppet.IntentFor(portal).UserID, event.MembershipJoin, "") - if err != nil { - log.Err(err).Stringer("mxid", puppet.MXID).Msg("Failed to join user") - } - } - bannedMembers := make(map[uuid.UUID]bool) - for _, addBannedMember := range groupChange.AddBannedMembers { - if addBannedMember.ServiceID.Type == libsignalgo.ServiceIDTypePNI { - continue - } - bannedMembers[addBannedMember.ServiceID.UUID] = true - _, err := portal.sendMembershipForPuppetAndUser(ctx, sender, addBannedMember.ServiceID.UUID, event.MembershipBan, "banned") - if err != nil { - log.Warn().Stringer("signal_user_id", addBannedMember.ServiceID.UUID).Msg("Couldn't get puppet for ban") - } - } - for _, deleteMember := range groupChange.DeleteMembers { - if bannedMembers[*deleteMember] { - continue - } - _, err := portal.sendMembershipForPuppetAndUser(ctx, sender, *deleteMember, event.MembershipLeave, "deleted") - if err != nil { - log.Warn().Stringer("signal_user_id", deleteMember).Msg("Couldn't get puppet for removal") - } - } - for _, deletePendingMember := range groupChange.DeletePendingMembers { - if deletePendingMember.Type == libsignalgo.ServiceIDTypePNI { - continue - } - if bannedMembers[deletePendingMember.UUID] { - continue - } - _, err := portal.sendMembershipForPuppetAndUser(ctx, sender, deletePendingMember.UUID, event.MembershipLeave, "invite withdrawn") - if err != nil { - log.Warn().Stringer("signal_user_id", deletePendingMember).Msg("Couldn't get puppet for removal") - } - } - for _, deleteRequestingMember := range groupChange.DeleteRequestingMembers { - if bannedMembers[*deleteRequestingMember] { - continue - } - _, err := portal.sendMembershipForPuppetAndUser(ctx, sender, *deleteRequestingMember, event.MembershipLeave, "request rejected") - if err != nil { - log.Warn().Stringer("signal_user_id", deleteRequestingMember).Msg("Couldn't get puppet for removal") - } - } - for _, promotePendingMember := range groupChange.PromotePendingMembers { - puppet := portal.bridge.GetPuppetBySignalID(promotePendingMember.ACI) - if puppet == nil { - log.Warn().Stringer("signal_user_id", promotePendingMember.ACI).Msg("Couldn't get puppet for invite") - continue - } - puppet.IntentFor(portal).EnsureJoined(ctx, portal.MXID) - } - for _, promotePendingPniAciMember := range groupChange.PromotePendingPniAciMembers { - puppet := portal.bridge.GetPuppetBySignalID(promotePendingPniAciMember.ACI) - if puppet == nil { - log.Warn().Stringer("signal_user_id", promotePendingPniAciMember.ACI).Msg("Couldn't get puppet for invite") - continue - } - puppet.IntentFor(portal).EnsureJoined(ctx, portal.MXID) - } - for _, addPendingMember := range groupChange.AddPendingMembers { - if addPendingMember.ServiceID.Type == libsignalgo.ServiceIDTypePNI { - continue - } - _, err := portal.sendMembershipForPuppetAndUser(ctx, sender, addPendingMember.ServiceID.UUID, event.MembershipInvite, "invited") - if err != nil { - log.Warn().Stringer("signal_user_id", addPendingMember.ServiceID).Msg("Couldn't get puppet for invite") - } - modifyRoles = append(modifyRoles, &signalmeow.RoleMember{ACI: addPendingMember.ServiceID.UUID, Role: addPendingMember.Role}) - } - for _, promoteRequestingMember := range groupChange.PromoteRequestingMembers { - puppet, err := portal.sendMembershipForPuppetAndUser(ctx, sender, promoteRequestingMember.ACI, event.MembershipInvite, "accepted") - if err == nil { - err = puppet.IntentFor(portal).EnsureJoined(ctx, portal.MXID) - if err != nil { - log.Warn().Stringer("signal_user_id", promoteRequestingMember.ACI).Msg("failed to join puppet") - } - } else { - log.Warn().Stringer("signal_user_id", promoteRequestingMember.ACI).Msg("Couldn't get puppet for join") - } - modifyRoles = append(modifyRoles, &signalmeow.RoleMember{ACI: promoteRequestingMember.ACI, Role: promoteRequestingMember.Role}) - } - for _, addRequestingMember := range groupChange.AddRequestingMembers { - // sender and target should be the same SignalID - puppet := portal.bridge.GetPuppetBySignalID(addRequestingMember.ACI) - if puppet != nil { - portal.sendMembershipWithPuppet(ctx, sender, puppet.IntentFor(portal).UserID, event.MembershipKnock, "knocked") - } - } - - if groupChange.ModifyAttributesAccess != nil || groupChange.ModifyAnnouncementsOnly != nil || groupChange.ModifyMemberAccess != nil || len(modifyRoles) > 0 { - levels, err := portal.MainIntent().PowerLevels(ctx, portal.MXID) - if err != nil { - log.Err(err).Msg("Couldn't get power levels") - } else { - for _, modifyRole := range modifyRoles { - puppet := portal.bridge.GetPuppetBySignalID(modifyRole.ACI) - if puppet == nil { - log.Warn().Stringer("signal_user_id", modifyRole.ACI).Msg("Couldn't get puppet for power level change") - continue - } - powerLevel := 0 - if modifyRole.Role == signalmeow.GroupMember_ADMINISTRATOR { - powerLevel = 50 - } - levels.EnsureUserLevel(puppet.IntentFor(portal).UserID, powerLevel) - if puppet.customIntent == nil { - user := portal.bridge.GetUserBySignalID(modifyRole.ACI) - if user != nil { - levels.EnsureUserLevel(user.MXID, powerLevel) - } - } - } - if groupChange.ModifyAnnouncementsOnly != nil { - levels.EventsDefault = 0 - if *groupChange.ModifyAnnouncementsOnly { - levels.EventsDefault = 50 - } - } - if groupChange.ModifyAttributesAccess != nil { - level := 0 - if *groupChange.ModifyAttributesAccess == signalmeow.AccessControl_ADMINISTRATOR { - level = 50 - } - levels.StateDefaultPtr = &level - } - if groupChange.ModifyMemberAccess != nil { - level := 0 - if *groupChange.ModifyMemberAccess == signalmeow.AccessControl_ADMINISTRATOR { - level = 50 - } - levels.InvitePtr = &level - } - _, err = intent.SetPowerLevels(ctx, portal.MXID, levels) - if errors.Is(err, mautrix.MForbidden) { - _, err = portal.MainIntent().SetPowerLevels(ctx, portal.MXID, levels) - } - if err != nil { - log.Err(err).Msg("Couldn't set power levels") - } - } - } - if groupChange.ModifyAddFromInviteLinkAccess != nil { - joinRule := event.JoinRuleInvite - if *groupChange.ModifyAddFromInviteLinkAccess == signalmeow.AccessControl_ADMINISTRATOR { - joinRule = event.JoinRuleKnock - } else if *groupChange.ModifyAddFromInviteLinkAccess == signalmeow.AccessControl_ANY && portal.bridge.Config.Bridge.PublicPortals { - joinRule = event.JoinRulePublic - } - _, err = intent.SendMassagedStateEvent(ctx, portal.MXID, event.StateJoinRules, "", &event.JoinRulesEventContent{JoinRule: joinRule}, int64(ts)) - if errors.Is(err, mautrix.MForbidden) { - _, err = portal.MainIntent().SendMassagedStateEvent(ctx, portal.MXID, event.StateJoinRules, "", &event.JoinRulesEventContent{JoinRule: joinRule}, int64(ts)) - } - if err != nil { - log.Err(err).Msg("Couldn't set join rule") - } - } - err = portal.Update(ctx) - if err != nil { - log.Err(err).Msg("Failed to save portal in database after processing group change") - } - portal.UpdateBridgeInfo(ctx) -} - -func (portal *Portal) sendMembershipForPuppetAndUser(ctx context.Context, sender *Puppet, target uuid.UUID, membership event.Membership, action string) (puppet *Puppet, err error) { - puppet = portal.bridge.GetPuppetBySignalID(target) - if puppet == nil { - err = fmt.Errorf("couldn't get Puppet for Signal uuid %s", target) - return - } - err = portal.sendMembershipWithPuppet(ctx, sender, puppet.IntentFor(portal).UserID, membership, action) - if puppet.customIntent == nil { - user := portal.bridge.GetUserBySignalID(target) - if user != nil { - err = portal.sendMembershipWithPuppet(ctx, sender, user.MXID, membership, action) - } - } - return -} - -func (portal *Portal) sendMembershipWithPuppet(ctx context.Context, sender *Puppet, target id.UserID, membership event.Membership, action string) (err error) { - _, err = sender.IntentFor(portal).SendCustomMembershipEvent(ctx, portal.MXID, target, membership, "") - if errors.Is(err, mautrix.MForbidden) { - _, err = portal.MainIntent().SendCustomMembershipEvent(ctx, portal.MXID, target, membership, fmt.Sprintf("%s by %s", action, sender.GetDisplayname())) - } - if err != nil { - zerolog.Ctx(ctx).Warn().Stringer("Membership Action failed for user", target).Msg(action) - } - return -} - -func (portal *Portal) handleSignalReaction(sender *Puppet, react *signalpb.DataMessage_Reaction, ts uint64) { - log := portal.log.With(). - Str("action", "handle signal reaction"). - Stringer("sender_uuid", sender.SignalID). - Uint64("target_msg_ts", react.GetTargetSentTimestamp()). - Str("target_msg_sender", react.GetTargetAuthorAci()). - Bool("remove", react.GetRemove()). - Logger() - ctx := log.WithContext(context.TODO()) - targetSenderUUID, err := uuid.Parse(react.GetTargetAuthorAci()) - if err != nil { - log.Err(err).Msg("Failed to parse target message sender UUID") - return - } - targetMsg, err := portal.bridge.DB.Message.GetBySignalID(ctx, targetSenderUUID, react.GetTargetSentTimestamp(), 0, portal.Receiver) - if err != nil { - log.Err(err).Msg("Failed to get target message from database") - return - } else if targetMsg == nil { - log.Warn().Msg("Target message not found") - return - } - existingReaction, err := portal.bridge.DB.Reaction.GetBySignalID(ctx, targetMsg.Sender, targetMsg.Timestamp, sender.SignalID, portal.Receiver) - if err != nil { - log.Err(err).Msg("Failed to get existing reaction from database") - return - } else if existingReaction != nil && existingReaction.Emoji == react.GetEmoji() { - log.Debug().Msg("Ignoring duplicate reaction") - return - } - intent := sender.IntentFor(portal) - if existingReaction != nil { - _, err = intent.RedactEvent(ctx, portal.MXID, existingReaction.MXID, mautrix.ReqRedact{ - TxnID: "mxsg_unreact_" + existingReaction.MXID.String(), - }) - if errors.Is(err, mautrix.MForbidden) { - log.Debug().Err(err).Msg("Failed to redact reaction with ghost, retrying with main intent") - _, err = portal.MainIntent().RedactEvent(ctx, portal.MXID, existingReaction.MXID, mautrix.ReqRedact{ - TxnID: "mxsg_unreact_" + existingReaction.MXID.String(), - }) - } - if err != nil { - log.Err(err).Msg("Failed to redact reaction") - } - if react.GetRemove() { - err = existingReaction.Delete(ctx) - if err != nil { - log.Err(err).Msg("Failed to remove reaction from database after redacting") - } - return - } - } else if react.GetRemove() { - log.Warn().Msg("Existing reaction for removal not found") - return - } - // Create a new message event with the reaction - content := &event.ReactionEventContent{ - RelatesTo: event.RelatesTo{ - Type: event.RelAnnotation, - Key: variationselector.Add(react.GetEmoji()), - EventID: targetMsg.MXID, - }, - } - resp, err := portal.sendMatrixEvent(ctx, intent, event.EventReaction, content, nil, int64(ts)) - if err != nil { - log.Err(err).Msg("Failed to send reaction") - return - } - if existingReaction == nil { - dbReaction := portal.bridge.DB.Reaction.New() - dbReaction.MXID = resp.EventID - dbReaction.RoomID = portal.MXID - dbReaction.SignalChatID = portal.ChatID - dbReaction.SignalReceiver = portal.Receiver - dbReaction.Author = sender.SignalID - dbReaction.MsgAuthor = targetMsg.Sender - dbReaction.MsgTimestamp = targetMsg.Timestamp - dbReaction.Emoji = react.GetEmoji() - err = dbReaction.Insert(ctx) - if err != nil { - log.Err(err).Msg("Failed to insert reaction to database") - } - } else { - existingReaction.Emoji = react.GetEmoji() - existingReaction.MXID = resp.EventID - err = existingReaction.Update(ctx) - if err != nil { - log.Err(err).Msg("Failed to update reaction in database") - } - } -} - -func (portal *Portal) handleSignalDelete(sender *Puppet, delete *signalpb.DataMessage_Delete, ts uint64) { - log := portal.log.With(). - Str("action", "handle signal delete"). - Stringer("sender_uuid", sender.SignalID). - Uint64("target_msg_ts", delete.GetTargetSentTimestamp()). - Uint64("delete_ts", ts). - Logger() - ctx := log.WithContext(context.TODO()) - targetMsg, err := portal.bridge.DB.Message.GetAllPartsBySignalID(ctx, sender.SignalID, delete.GetTargetSentTimestamp(), portal.Receiver) - if err != nil { - log.Err(err).Msg("Failed to get target message from database") - return - } else if len(targetMsg) == 0 { - log.Warn().Msg("Target message not found") - return - } - intent := sender.IntentFor(portal) - for _, part := range targetMsg { - _, err = intent.RedactEvent(ctx, portal.MXID, part.MXID, mautrix.ReqRedact{ - TxnID: "mxsg_delete_" + part.MXID.String(), - }) - if err != nil { - log.Err(err). - Int("part_index", part.PartIndex). - Stringer("event_id", part.MXID). - Msg("Failed to redact message") - } - err = part.Delete(ctx) - if err != nil { - log.Err(err). - Int("part_index", part.PartIndex). - Msg("Failed to delete message from database") - } - } -} - -func (portal *Portal) handleSignalNormalDataMessage(source *User, sender *Puppet, msg *signalpb.DataMessage) { - log := portal.log.With(). - Str("action", "handle signal message"). - Stringer("sender_uuid", sender.SignalID). - Uint64("msg_ts", msg.GetTimestamp()). - Logger() - ctx := log.WithContext(context.TODO()) - if portal.MXID == "" { - log.Debug().Msg("Creating Matrix room from incoming message") - if err := portal.CreateMatrixRoom(ctx, source, msg.GetGroupV2().GetRevision()); err != nil { - log.Error().Err(err).Msg("Failed to create portal room") - return - } - } else if !portal.ensureUserInvited(ctx, source) { - log.Warn().Stringer("user_id", source.MXID).Msg("Failed to ensure source user is joined to portal") - } - - existingMessage, err := portal.bridge.DB.Message.GetBySignalID(ctx, sender.SignalID, msg.GetTimestamp(), 0, portal.Receiver) - if err != nil { - log.Err(err).Msg("Failed to check if message was already bridged") - return - } else if existingMessage != nil { - log.Debug().Msg("Ignoring duplicate message") - return - } - - intent := sender.IntentFor(portal) - ctx = context.WithValue(ctx, msgconvContextKeyIntent, intent) - converted := portal.MsgConv.ToMatrix(ctx, msg) - if portal.bridge.Config.Bridge.CaptionInMessage { - converted.MergeCaption() - } - for i, part := range converted.Parts { - resp, err := portal.sendMatrixEvent(ctx, intent, part.Type, part.Content, part.Extra, int64(converted.Timestamp)) - if err != nil { - log.Err(err).Int("part_index", i).Msg("Failed to send message to Matrix") - continue - } - portal.storeMessageInDB(ctx, resp.EventID, sender.SignalID, converted.Timestamp, i) - if converted.DisappearIn != 0 { - portal.addDisappearingMessage(ctx, resp.EventID, converted.DisappearIn, sender.SignalID == source.SignalID) - // Ensure portal expiration timer is correct in DMs - if portal.implicitlyUpdateExpirationTimer(ctx, converted.DisappearIn) { - log.Info().Uint32("new_time", converted.DisappearIn).Msg("Implicitly updated expiration timer") - err := portal.Update(ctx) - if err != nil { - log.Err(err).Msg("Failed to save portal in database after implicitly updating group info") - } - } - } - } -} - -func (portal *Portal) handleSignalEditMessage(sender *Puppet, timestamp uint64, msg *signalpb.DataMessage) { - log := portal.log.With(). - Str("action", "handle signal edit"). - Stringer("sender_uuid", sender.SignalID). - Uint64("target_msg_ts", timestamp). - Uint64("edit_msg_ts", msg.GetTimestamp()). - Logger() - if portal.MXID == "" { - log.Debug().Msg("Dropping edit message in chat with no portal") - return - } - ctx := log.WithContext(context.TODO()) - targetMessage, err := portal.bridge.DB.Message.GetAllPartsBySignalID(ctx, sender.SignalID, timestamp, portal.Receiver) - if err != nil { - log.Err(err).Msg("Failed to get target message") - return - } else if len(targetMessage) == 0 { - log.Debug().Msg("Target message not found (edit may have been already handled)") - return - } - - intent := sender.IntentFor(portal) - ctx = context.WithValue(ctx, msgconvContextKeyIntent, intent) - converted := portal.MsgConv.ToMatrix(ctx, msg) - if portal.bridge.Config.Bridge.CaptionInMessage { - converted.MergeCaption() - } - if len(converted.Parts) != len(targetMessage) { - log.Error(). - Int("target_parts", len(targetMessage)). - Int("new_parts", len(converted.Parts)). - Msg("Mismatched number of parts in edit") - return - } - for i, part := range converted.Parts { - part.Content.SetEdit(targetMessage[i].MXID) - if part.Extra != nil { - part.Extra = map[string]any{ - "m.new_content": part.Extra, - } - } - _, err = portal.sendMatrixEvent(ctx, intent, part.Type, part.Content, part.Extra, int64(converted.Timestamp)) - if err != nil { - log.Err(err).Int("part_index", i).Msg("Failed to send edit to Matrix") - } - } - err = targetMessage[0].SetTimestamp(ctx, msg.GetTimestamp()) - if err != nil { - log.Err(err).Msg("Failed to update message edit timestamp in database") - } -} - -const SignalTypingTimeout = 15 * time.Second - -func (portal *Portal) handleSignalTypingMessage(sender *Puppet, msg *signalpb.TypingMessage) { - if portal.MXID == "" { - portal.log.Debug().Msg("Dropping typing message in chat with no portal") - return - } - ctx := context.TODO() - intent := sender.IntentFor(portal) - // Don't bridge double puppeted typing notifications to avoid echoing - if intent.IsCustomPuppet { - return - } - var err error - switch msg.GetAction() { - case signalpb.TypingMessage_STARTED: - _, err = intent.UserTyping(ctx, portal.MXID, true, SignalTypingTimeout) - case signalpb.TypingMessage_STOPPED: - _, err = intent.UserTyping(ctx, portal.MXID, false, 0) - } - if err != nil { - portal.log.Err(err). - Stringer("user_id", sender.SignalID). - Msg("Failed to handle Signal typing notification") - } -} - -func (portal *Portal) storeMessageInDB(ctx context.Context, eventID id.EventID, senderSignalID uuid.UUID, timestamp uint64, partIndex int) { - dbMessage := portal.bridge.DB.Message.New() - dbMessage.MXID = eventID - dbMessage.RoomID = portal.MXID - dbMessage.Sender = senderSignalID - dbMessage.Timestamp = timestamp - dbMessage.PartIndex = partIndex - dbMessage.SignalChatID = portal.ChatID - dbMessage.SignalReceiver = portal.Receiver - err := dbMessage.Insert(ctx) - if err != nil { - portal.log.Err(err).Msg("Failed to insert message into database") - } -} - -func (portal *Portal) addDisappearingMessage(ctx context.Context, eventID id.EventID, expireInSeconds uint32, startTimerNow bool) { - portal.bridge.disappearingMessagesManager.AddDisappearingMessage(ctx, eventID, portal.MXID, time.Duration(expireInSeconds)*time.Second, startTimerNow) -} - -func (portal *Portal) MarkDelivered(ctx context.Context, msg *database.Message) { - if !portal.IsPrivateChat() { - return - } - portal.bridge.SendRawMessageCheckpoint(&status.MessageCheckpoint{ - EventID: msg.MXID, - RoomID: portal.MXID, - Step: status.MsgStepRemote, - Timestamp: jsontime.UnixMilliNow(), - Status: status.MsgStatusDelivered, - ReportedBy: status.MsgReportedByBridge, - }) - portal.sendStatusEvent(ctx, msg.MXID, "", nil, &[]id.UserID{portal.MainIntent().UserID}) -} - -type customReadReceipt struct { - Timestamp int64 `json:"ts,omitempty"` - DoublePuppetSource string `json:"fi.mau.double_puppet_source,omitempty"` -} - -type customReadMarkers struct { - mautrix.ReqSetReadMarkers - ReadExtra customReadReceipt `json:"com.beeper.read.extra"` - FullyReadExtra customReadReceipt `json:"com.beeper.fully_read.extra"` -} - -func (portal *Portal) SendReadReceipt(ctx context.Context, sender *Puppet, msg *database.Message) error { - intent := sender.IntentFor(portal) - if intent.IsCustomPuppet { - extra := customReadReceipt{DoublePuppetSource: portal.bridge.Name} - return intent.SetReadMarkers(ctx, portal.MXID, &customReadMarkers{ - ReqSetReadMarkers: mautrix.ReqSetReadMarkers{ - Read: msg.MXID, - FullyRead: msg.MXID, - }, - ReadExtra: extra, - FullyReadExtra: extra, - }) - } else { - return intent.MarkRead(ctx, portal.MXID, msg.MXID) - } -} - -func typingDiff(prev, new []id.UserID) (started, stopped []id.UserID) { -OuterNew: - for _, userID := range new { - for _, previousUserID := range prev { - if userID == previousUserID { - continue OuterNew - } - } - started = append(started, userID) - } -OuterPrev: - for _, userID := range prev { - for _, previousUserID := range new { - if userID == previousUserID { - continue OuterPrev - } - } - stopped = append(stopped, userID) - } - return -} - -func (portal *Portal) setTyping(userIDs []id.UserID, isTyping bool) { - for _, userID := range userIDs { - user := portal.bridge.GetUserByMXID(userID) - if user == nil || !user.IsLoggedIn() { - continue - } - - // Check to see if portal.ChatID is a standard UUID (with dashes) - // Note: not handling sending to a group right now, since that will - // require SenderKey sending to not be terrible - dmUserID := portal.UserID() - if !dmUserID.IsEmpty() && dmUserID.Type == libsignalgo.ServiceIDTypeACI { - // this is a 1:1 chat - portal.log.Debug().Msg("Sending Typing event to Signal") - ctx := context.TODO() - typingMessage := signalmeow.TypingMessage(isTyping) - result := user.Client.SendMessage(ctx, portal.UserID(), typingMessage) - if !result.WasSuccessful { - portal.log.Err(result.FailedSendResult.Error).Msg("Error sending event to Signal") - } - } - } -} - -func (portal *Portal) HandleMatrixTyping(newTyping []id.UserID) { - if portal.IsNoteToSelf() { - return - } - - portal.currentlyTypingLock.Lock() - defer portal.currentlyTypingLock.Unlock() - startedTyping, stoppedTyping := typingDiff(portal.currentlyTyping, newTyping) - portal.currentlyTyping = newTyping - portal.setTyping(startedTyping, true) - portal.setTyping(stoppedTyping, false) -} - -func (portal *Portal) HandleMatrixReadReceipt(brSender bridge.User, eventID id.EventID, receipt event.ReadReceipt) { - portal.handleMatrixReadReceipt(brSender.(*User), eventID, uint64(receipt.Timestamp.UnixMilli()), true) -} - -func (portal *Portal) handleMatrixReadReceipt(sender *User, eventID id.EventID, maxTimestamp uint64, isExplicit bool) { - if !sender.IsLoggedIn() { - return - } - logWith := portal.log.With(). - Stringer("event_id", eventID). - Stringer("sender", sender.MXID). - Bool("explicit", isExplicit) - if isExplicit { - logWith = logWith.Str("action", "handle matrix read receipt") - } - log := logWith.Logger() - log.Debug().Msg("Handling Matrix read receipt") - portal.ScheduleDisappearing() - ctx := log.WithContext(context.TODO()) - - if isExplicit { - dbMessage, _ := portal.bridge.DB.Message.GetByMXID(ctx, eventID) - if dbMessage != nil { - maxTimestamp = dbMessage.Timestamp - } - } - prevLastReadTS := sender.GetLastReadTS(ctx, portal.PortalKey) - if maxTimestamp <= prevLastReadTS { - log.Debug(). - Uint64("prev_last_read_ts", prevLastReadTS). - Uint64("max_timestamp", maxTimestamp). - Msg("Ignoring read receipt older than last read timestamp") - return - } - minTimestamp := prevLastReadTS - if minTimestamp == 0 { - minTimestamp = maxTimestamp - 2000 - } - dbMessages, err := portal.bridge.DB.Message.GetAllBetweenTimestamps(ctx, portal.PortalKey, minTimestamp, maxTimestamp) - if err != nil { - log.Err(err).Msg("Failed to get messages between timestamps to mark as read") - return - } - messagesToRead := map[uuid.UUID][]uint64{} - for _, msg := range dbMessages { - messagesToRead[msg.Sender] = append(messagesToRead[msg.Sender], msg.Timestamp) - } - // Always update last read ts for non-explicit read receipts, because that means there's a message about to be sent - if (len(dbMessages) > 0 || !isExplicit) && maxTimestamp != prevLastReadTS { - sender.SetLastReadTS(ctx, portal.PortalKey, maxTimestamp) - } - if isExplicit || len(messagesToRead) > 0 { - log.Debug(). - Any("targets", messagesToRead). - Uint64("prev_last_read_ts", prevLastReadTS). - Uint64("min_timestamp", minTimestamp). - Uint64("max_timestamp", maxTimestamp). - Msg("Collected read receipt target messages") - } - - // TODO send sync message manually containing all read receipts instead of a separate message for each recipient - - for destination, messages := range messagesToRead { - // Don't send read receipts for own messages - if destination == sender.SignalID { - continue - } - // Don't use portal.sendSignalMessage because we're sending this straight to - // who sent the original message, not the portal's ChatID - ctx, cancel := context.WithTimeout(ctx, 10*time.Second) - result := sender.Client.SendMessage(ctx, libsignalgo.NewACIServiceID(destination), signalmeow.ReadReceptMessageForTimestamps(messages)) - cancel() - if !result.WasSuccessful { - log.Err(result.FailedSendResult.Error). - Stringer("destination", destination). - Uints64("message_ids", messages). - Msg("Failed to send read receipt to Signal") - } else { - log.Debug(). - Stringer("destination", destination). - Uints64("message_ids", messages). - Msg("Sent read receipt to Signal") - } - } -} - -func (portal *Portal) sendMainIntentMessage(ctx context.Context, content *event.MessageEventContent) (*mautrix.RespSendEvent, error) { - return portal.sendMatrixEvent(ctx, portal.MainIntent(), event.EventMessage, content, nil, 0) -} - -func (portal *Portal) encrypt(ctx context.Context, intent *appservice.IntentAPI, content *event.Content, eventType event.Type) (event.Type, error) { - if !portal.Encrypted || portal.bridge.Crypto == nil { - return eventType, nil - } - intent.AddDoublePuppetValue(content) - // TODO maybe the locking should be inside mautrix-go? - portal.encryptLock.Lock() - defer portal.encryptLock.Unlock() - err := portal.bridge.Crypto.Encrypt(ctx, portal.MXID, eventType, content) - if err != nil { - return eventType, fmt.Errorf("failed to encrypt event: %w", err) - } - return event.EventEncrypted, nil -} - -func (portal *Portal) sendMatrixEvent(ctx context.Context, intent *appservice.IntentAPI, eventType event.Type, content any, extraContent map[string]any, timestamp int64) (*mautrix.RespSendEvent, error) { - wrappedContent := event.Content{Parsed: content, Raw: extraContent} - if eventType != event.EventReaction { - var err error - eventType, err = portal.encrypt(ctx, intent, &wrappedContent, eventType) - if err != nil { - return nil, err - } - } - - _, _ = intent.UserTyping(ctx, portal.MXID, false, 0) - return intent.SendMassagedMessageEvent(ctx, portal.MXID, eventType, &wrappedContent, timestamp) -} - -func (portal *Portal) getEncryptionEventContent() (evt *event.EncryptionEventContent) { - evt = &event.EncryptionEventContent{Algorithm: id.AlgorithmMegolmV1} - if rot := portal.bridge.Config.Bridge.Encryption.Rotation; rot.EnableCustom { - evt.RotationPeriodMillis = rot.Milliseconds - evt.RotationPeriodMessages = rot.Messages - } - return -} - -func (portal *Portal) shouldSetDMRoomMetadata() bool { - return !portal.IsPrivateChat() || - portal.bridge.Config.Bridge.PrivateChatPortalMeta == "always" || - (portal.IsEncrypted() && portal.bridge.Config.Bridge.PrivateChatPortalMeta != "never") -} - -func (portal *Portal) ensureUserInvited(ctx context.Context, user *User) bool { - return user.ensureInvited(ctx, portal.MainIntent(), portal.MXID, portal.IsPrivateChat()) -} - -func (portal *Portal) CreateMatrixRoom(ctx context.Context, user *User, groupRevision uint32) error { - portal.roomCreateLock.Lock() - defer portal.roomCreateLock.Unlock() - if portal.MXID != "" { - portal.log.Debug().Msg("Not creating room: already exists") - return nil - } - portal.log.Debug().Msg("Creating matrix room") - - intent := portal.MainIntent() - - if err := intent.EnsureRegistered(ctx); err != nil { - portal.log.Error().Err(err).Msg("failed to ensure registered") - return err - } - - bridgeInfoStateKey, bridgeInfo := portal.getBridgeInfo() - initialState := []*event.Event{{ - Type: event.StateBridge, - Content: event.Content{Parsed: bridgeInfo}, - StateKey: &bridgeInfoStateKey, - }, { - // TODO remove this once https://github.com/matrix-org/matrix-doc/pull/2346 is in spec - Type: event.StateHalfShotBridge, - Content: event.Content{Parsed: bridgeInfo}, - StateKey: &bridgeInfoStateKey, - }} - - if !portal.AvatarURL.IsEmpty() { - initialState = append(initialState, &event.Event{ - Type: event.StateRoomAvatar, - Content: event.Content{Parsed: &event.RoomAvatarEventContent{ - URL: portal.AvatarURL.CUString(), - }}, - }) - } - - creationContent := make(map[string]interface{}) - if !portal.bridge.Config.Bridge.FederateRooms { - creationContent["m.federate"] = false - } - - var invite []id.UserID - autoJoinInvites := portal.bridge.SpecVersions.Supports(mautrix.BeeperFeatureAutojoinInvites) - if autoJoinInvites { - invite = append(invite, user.MXID) - } - - if portal.bridge.Config.Bridge.Encryption.Default { - initialState = append(initialState, &event.Event{ - Type: event.StateEncryption, - Content: event.Content{ - Parsed: portal.getEncryptionEventContent(), - }, - }) - portal.Encrypted = true - - if portal.IsPrivateChat() && portal.MainIntent() != portal.bridge.Bot { - invite = append(invite, portal.bridge.Bot.UserID) - } - } - - var dmPuppet *Puppet - var groupInfo *signalmeow.Group - if portal.IsPrivateChat() { - dmPuppet = portal.GetDMPuppet() - if dmPuppet != nil { - dmPuppet.UpdateInfo(ctx, user, nil) - portal.UpdateDMInfo(ctx, false) - } else { - portal.UpdatePNIDMInfo(ctx, user) - } - } else { - groupInfo = portal.UpdateGroupInfo(ctx, user, nil, groupRevision, true) - if groupInfo == nil { - portal.log.Error().Msg("Didn't get group info after updating portal") - return errors.New("failed to get group info") - } - for member := range portal.SyncParticipants(ctx, user, groupInfo) { - invite = append(invite, member) - } - } - - req := &mautrix.ReqCreateRoom{ - Visibility: "private", - Name: portal.Name, - Topic: portal.Topic, - Invite: invite, - Preset: "private_chat", - IsDirect: portal.IsPrivateChat(), - InitialState: initialState, - CreationContent: creationContent, - - BeeperAutoJoinInvites: autoJoinInvites, - } - resp, err := intent.CreateRoom(ctx, req) - if err != nil { - portal.log.Warn().Err(err).Msg("failed to create room") - return err - } - portal.log = portal.log.With().Stringer("room_id", resp.RoomID).Logger() - - portal.NameSet = len(req.Name) > 0 - portal.TopicSet = len(req.Topic) > 0 - portal.AvatarSet = !portal.AvatarURL.IsEmpty() - portal.MXID = resp.RoomID - portal.bridge.portalsLock.Lock() - portal.bridge.portalsByMXID[portal.MXID] = portal - portal.bridge.portalsLock.Unlock() - err = portal.Update(ctx) - if err != nil { - portal.log.Err(err).Msg("Failed to save portal room ID") - return err - } - portal.log.Info().Msg("Created matrix room for portal") - - if !autoJoinInvites { - if !portal.IsPrivateChat() { - portal.SyncParticipants(ctx, user, groupInfo) - } else if portal.Encrypted { - err = portal.bridge.Bot.EnsureJoined(ctx, portal.MXID, appservice.EnsureJoinedParams{BotOverride: portal.MainIntent().Client}) - if err != nil { - portal.log.Error().Err(err).Msg("Failed to ensure bridge bot is joined to private chat portal") - } - } - user.ensureInvited(ctx, portal.MainIntent(), portal.MXID, portal.IsPrivateChat()) - } - user.syncChatDoublePuppetDetails(portal, true) - go portal.addToPersonalSpace(portal.log.WithContext(context.TODO()), user) - - if dmPuppet != nil { - user.UpdateDirectChats(ctx, map[id.UserID][]id.RoomID{ - dmPuppet.MXID: {portal.MXID}, - }) - } - - return nil -} - -func (portal *Portal) GetDMPuppet() *Puppet { - userID := portal.UserID() - if userID.IsEmpty() || userID.Type != libsignalgo.ServiceIDTypeACI { - return nil - } - return portal.bridge.GetPuppetBySignalID(userID.UUID) -} - -func (portal *Portal) UpdateInfo(ctx context.Context, source *User, groupInfo *signalmeow.Group, revision uint32) { - if portal.IsPrivateChat() { - portal.UpdateDMInfo(ctx, false) - return - } - groupInfo = portal.UpdateGroupInfo(ctx, source, groupInfo, revision, false) - if groupInfo != nil { - members := portal.SyncParticipants(ctx, source, groupInfo) - portal.updatePowerLevelsAndJoinRule(ctx, groupInfo, members) - } -} - -const PrivateChatTopic = "Signal private chat" -const NoteToSelfName = "Signal Note to Self" - -func (portal *Portal) PostReIDUpdate(ctx context.Context, user *User) { - _, err := portal.bridge.Bot.SetPowerLevel(ctx, portal.MXID, portal.MainIntent().UserID, 100) - if err != nil { - zerolog.Ctx(ctx).Err(err).Msg("Failed to update ghost power level after portal re-ID") - } - portal.GetDMPuppet().UpdateInfo(ctx, user, nil) - portal.UpdateDMInfo(ctx, true) - if !portal.Encrypted { - _, _ = portal.bridge.Bot.LeaveRoom(ctx, portal.MXID) - } -} - -func (portal *Portal) UpdateDMInfo(ctx context.Context, forceSave bool) { - log := zerolog.Ctx(ctx).With(). - Str("function", "UpdateDMInfo"). - Logger() - log.Trace().Msg("Updating portal info") - ctx = log.WithContext(ctx) - puppet := portal.GetDMPuppet() - - update := forceSave - if portal.UserID().UUID == portal.Receiver { - noteToSelfAvatar := portal.bridge.Config.Bridge.NoteToSelfAvatar.ParseOrIgnore() - avatarHash := sha256.Sum256([]byte(noteToSelfAvatar.String())) - - update = portal.updateName(ctx, NoteToSelfName, nil) || update - update = portal.updateAvatarWithMXC(ctx, "notetoself", hex.EncodeToString(avatarHash[:]), noteToSelfAvatar) || update - } else if portal.shouldSetDMRoomMetadata() { - update = portal.updateName(ctx, puppet.Name, nil) || update - update = portal.updateAvatarWithMXC(ctx, puppet.AvatarPath, puppet.AvatarHash, puppet.AvatarURL) || update - } else { - // Clear name/avatar if they're set in a DM that shouldn't have them set - if portal.Name != "" && portal.NameSet { - update = portal.updateName(ctx, "", nil) || update - } - // Avatar is currently never set in PNI portals - //if !portal.AvatarURL.IsEmpty() && portal.AvatarSet { - // update = true - // portal.AvatarURL = id.ContentURI{} - // portal.AvatarHash = "" - // portal.AvatarPath = "" - // portal.updateAvatarInRoom(ctx, nil) - //} - } - topic := PrivateChatTopic - if portal.bridge.Config.Bridge.NumberInTopic && puppet.Number != "" { - topic = fmt.Sprintf("%s with %s", topic, puppet.Number) - } - update = portal.updateTopic(ctx, topic, nil) || update - if update { - err := portal.Update(ctx) - if err != nil { - log.Err(err).Msg("Failed to save portal in database after updating group info") - } - portal.UpdateBridgeInfo(ctx) - } -} - -func (portal *Portal) UpdatePNIDMInfo(ctx context.Context, user *User) { - portalUserID := portal.UserID() - if portalUserID.Type != libsignalgo.ServiceIDTypePNI { - return - } - log := zerolog.Ctx(ctx) - update := false - recipient, err := user.Client.Store.RecipientStore.LoadAndUpdateRecipient(ctx, uuid.Nil, portalUserID.UUID, nil) - if err != nil { - log.Err(err).Msg("Failed to get PNI DM recipient entry") - } - if recipient == nil { - recipient = &types.Recipient{PNI: portalUserID.UUID} - } - topic := PrivateChatTopic - name := portalUserID.UUID.String() - if recipient.E164 != "" { - topic = fmt.Sprintf("%s with %s", topic, recipient.E164) - name = recipient.E164 - } - if recipient.ContactName != "" { - name = recipient.ContactName - } - update = portal.updateTopic(ctx, topic, nil) || update - update = portal.updateName(ctx, name, nil) || update - if update { - err = portal.Update(ctx) - if err != nil { - log.Err(err).Msg("Failed to save portal in database after updating group info") - } - portal.UpdateBridgeInfo(ctx) - } -} - -func (portal *Portal) updatePowerLevelsAndJoinRule(ctx context.Context, info *signalmeow.Group, members map[id.UserID]int) { - log := zerolog.Ctx(ctx).With(). - Str("function", "updatePowerLevelsAndJoinRule"). - Logger() - log.Trace().Msg("Updating power levels and join rule") - joinRuleContent := event.JoinRulesEventContent{} - err := portal.MainIntent().StateEvent(ctx, portal.MXID, event.StateJoinRules, "", &joinRuleContent) - if err != nil { - log.Err(err).Msg("Failed to get join rule") - return - } - joinRule := joinRuleContent.JoinRule - newJoinRule := event.JoinRuleInvite - levels, err := portal.MainIntent().PowerLevels(ctx, portal.MXID) - if err != nil { - log.Err(err).Msg("Failed to get power levels") - return - } - botLevel := levels.GetUserLevel(portal.MainIntent().UserID) - changed := false - for mxid, level := range members { - oldLevel := levels.GetUserLevel(mxid) - difference := oldLevel - level - if oldLevel < botLevel && (difference < 0 || difference > 49) { - changed = levels.EnsureUserLevel(mxid, level) || changed - } - } - newEventsDefault := 0 - if info.AnnouncementsOnly { - newEventsDefault = 50 - } - if newEventsDefault != levels.EventsDefault { - levels.EventsDefault = newEventsDefault - changed = true - } - if info.AccessControl != nil { - level := 0 - if info.AccessControl.Attributes == signalmeow.AccessControl_ADMINISTRATOR { - level = 50 - } - changed = levels.EnsureEventLevel(event.StateRoomName, level) || changed - changed = levels.EnsureEventLevel(event.StateTopic, level) || changed - changed = levels.EnsureEventLevel(event.StateRoomAvatar, level) || changed - level = 0 - if info.AccessControl.Members == signalmeow.AccessControl_ADMINISTRATOR { - level = 50 - } - if levels.InvitePtr == nil || *levels.InvitePtr != level { - levels.InvitePtr = &level - changed = true - } - if info.AccessControl.AddFromInviteLink == signalmeow.AccessControl_ADMINISTRATOR { - newJoinRule = event.JoinRuleKnock - } else if info.AccessControl.AddFromInviteLink == signalmeow.AccessControl_ANY && (portal.bridge.Config.Bridge.PublicPortals || joinRule == event.JoinRulePublic) { - newJoinRule = event.JoinRulePublic - } - } - if newJoinRule != joinRule { - _, err = portal.MainIntent().SendStateEvent(ctx, portal.MXID, event.StateJoinRules, "", &event.JoinRulesEventContent{JoinRule: joinRule}) - if err != nil { - log.Err(err).Msg("Failed to set join rule") - } - } - if changed { - _, err = portal.MainIntent().SetPowerLevels(ctx, portal.MXID, levels) - if err != nil { - log.Err(err).Msg("Failed to set power levels") - } - } -} - -func (portal *Portal) UpdateGroupInfo(ctx context.Context, source *User, info *signalmeow.Group, revision uint32, forceFetch bool) *signalmeow.Group { - logWith := zerolog.Ctx(ctx).With(). - Str("function", "UpdateGroupInfo"). - Uint32("revision", revision). - Stringer("source_user_mxid", source.MXID) - if info != nil { - logWith = logWith.Uint32("info_revision", info.Revision) - } - log := logWith.Logger() - if info == nil { - if revision <= portal.Revision && !forceFetch { - log.Debug().Msg("Not fetching group info to update portal: given revision is not newer") - return nil - } - log.Debug().Msg("Fetching group info to update portal") - var err error - info, err = source.Client.RetrieveGroupByID(ctx, portal.GroupID(), revision) - if err != nil { - log.Err(err). - Stringer("source_user_id", source.MXID). - Msg("Failed to fetch group info") - return nil - } - } - if portal.Revision > info.Revision { - log.Debug().Uint32("current_revision", portal.Revision).Msg("Not updating portal with data from older revision") - return info - } - logEvt := log.Trace() - if portal.Revision != info.Revision { - logEvt = log.Debug() - } - logEvt.Uint32("current_revision", portal.Revision).Msg("Updating portal info") - ctx = log.WithContext(ctx) - update := false - if portal.Revision < info.Revision { - portal.Revision = info.Revision - update = true - } - update = portal.updateName(ctx, info.Title, nil) || update - update = portal.updateTopic(ctx, info.Description, nil) || update - update = portal.updateAvatarWithInfo(ctx, source, info, nil) || update - update = portal.updateExpirationTimer(ctx, info.DisappearingMessagesDuration) || update - if update { - err := portal.Update(ctx) - if err != nil { - log.Err(err).Msg("Failed to save portal in database after updating group info") - } - portal.UpdateBridgeInfo(ctx) - } - return info -} - -func (portal *Portal) updateExpirationTimer(ctx context.Context, newExpirationTimer uint32) bool { - if portal.ExpirationTime == newExpirationTimer { - return false - } - portal.ExpirationTime = newExpirationTimer - if portal.MXID != "" { - msg := portal.MsgConv.ConvertDisappearingTimerChangeToMatrix(ctx, newExpirationTimer, false) - _, err := portal.sendMainIntentMessage(ctx, msg.Content) - if err != nil { - zerolog.Ctx(ctx).Err(err).Msg("Failed to send notice about disappearing message timer changing") - } - } - return true -} - -func (portal *Portal) implicitlyUpdateExpirationTimer(ctx context.Context, newExpirationTimer uint32) bool { - if portal.ExpirationTime == newExpirationTimer { - return false - } - portal.ExpirationTime = newExpirationTimer - if portal.MXID != "" { - msg := portal.MsgConv.ConvertDisappearingTimerChangeToMatrix(ctx, newExpirationTimer, false) - msg.Content.Body = fmt.Sprintf("Automatically enabled disappearing message timer (%s) because incoming message is disappearing", exfmt.Duration(time.Duration(newExpirationTimer)*time.Second)) - _, err := portal.sendMainIntentMessage(ctx, msg.Content) - if err != nil { - zerolog.Ctx(ctx).Err(err).Msg("Failed to send notice about disappearing message timer changing implicitly") - } - } - return true -} - -func (portal *Portal) updateName(ctx context.Context, newName string, sender *Puppet) bool { - if portal.Name == newName && (portal.NameSet || portal.MXID == "") { - return false - } - portal.Name = newName - portal.NameSet = false - if portal.MXID != "" { - intent := portal.MainIntent() - if sender != nil { - intent = sender.IntentFor(portal) - } - _, err := intent.SetRoomName(ctx, portal.MXID, portal.Name) - if errors.Is(err, mautrix.MForbidden) && intent != portal.MainIntent() { - _, err = portal.MainIntent().SetRoomName(ctx, portal.MXID, portal.Name) - } - if err != nil { - zerolog.Ctx(ctx).Err(err).Msg("Failed to update room name") - } else { - portal.NameSet = true - } - } - return true -} - -func (portal *Portal) updateTopic(ctx context.Context, newTopic string, sender *Puppet) bool { - if portal.Topic == newTopic && (portal.TopicSet || portal.MXID == "") { - return false - } - portal.Topic = newTopic - portal.TopicSet = false - if portal.MXID != "" { - intent := portal.MainIntent() - if sender != nil { - intent = sender.IntentFor(portal) - } - _, err := intent.SetRoomTopic(ctx, portal.MXID, portal.Topic) - if errors.Is(err, mautrix.MForbidden) && intent != portal.MainIntent() { - _, err = portal.MainIntent().SetRoomTopic(ctx, portal.MXID, portal.Topic) - } - if err != nil { - zerolog.Ctx(ctx).Err(err).Msg("Failed to update room topic") - } else { - portal.TopicSet = true - } - } - return true -} - -func (portal *Portal) updateAvatarWithInfo(ctx context.Context, source *User, group signalmeow.GroupAvatarMeta, sender *Puppet) bool { - // If the avatar path is different, the avatar probably changed - avatarPath := group.GetAvatarPath() - if avatarPath == nil { - return false - } - if portal.AvatarPath == *avatarPath && - // If the avatar mxc isn't set, we need to reupload it (except if the avatar is unset in Signal) - (!portal.AvatarURL.IsEmpty() || *avatarPath == "") && - // If the avatar isn't set in the room, we need to update the room state (except if there's no Matrix room yet) - (portal.AvatarSet || portal.MXID == "") { - return false - } - if *avatarPath == "" { - portal.AvatarPath = "" - portal.AvatarSet = false - portal.AvatarURL = id.ContentURI{} - portal.AvatarHash = "" - // Just clear the Matrix room avatar and return - portal.updateAvatarInRoom(ctx, sender) - return true - } - log := zerolog.Ctx(ctx) - log.Debug().Str("avatar_path", portal.AvatarPath).Msg("Downloading new group avatar from Signal") - avatarBytes, err := source.Client.DownloadGroupAvatar(ctx, group) - if err != nil { - log.Err(err).Msg("Failed to download new avatar for portal") - return true - } - hash := sha256.Sum256(avatarBytes) - newAvatarHash := hex.EncodeToString(hash[:]) - if portal.AvatarHash == newAvatarHash && (portal.AvatarSet || portal.MXID == "") { - // No need to change anything else, but save the new path to the database - return true - } - portal.AvatarPath = *avatarPath - portal.AvatarSet = false - portal.AvatarURL = id.ContentURI{} - portal.AvatarHash = newAvatarHash - log.Debug().Str("avatar_hash", portal.AvatarHash).Msg("Uploading new group avatar to Matrix") - resp, err := portal.MainIntent().UploadBytes(ctx, avatarBytes, http.DetectContentType(avatarBytes)) - if err != nil { - log.Err(err).Msg("Failed to upload new avatar for portal") - } else { - portal.AvatarURL = resp.ContentURI - portal.updateAvatarInRoom(ctx, sender) - } - return true -} - -func (portal *Portal) updateAvatarWithMXC(ctx context.Context, newAvatarPath, newAvatarHash string, newAvatarURI id.ContentURI) bool { - if portal.AvatarHash == newAvatarHash && (portal.AvatarSet || portal.MXID == "") { - return false - } - portal.AvatarPath = newAvatarPath - portal.AvatarHash = newAvatarHash - portal.AvatarURL = newAvatarURI - portal.AvatarSet = false - portal.updateAvatarInRoom(ctx, nil) - return true -} - -func (portal *Portal) updateAvatarInRoom(ctx context.Context, sender *Puppet) { - if portal.MXID == "" || portal.AvatarSet { - return - } - zerolog.Ctx(ctx).Debug(). - Str("avatar_path", portal.AvatarPath). - Str("avatar_hash", portal.AvatarHash). - Stringer("avatar_mxc", portal.AvatarURL). - Msg("Updating avatar in Matrix room") - intent := portal.MainIntent() - if sender != nil { - intent = sender.IntentFor(portal) - } - _, err := intent.SetRoomAvatar(ctx, portal.MXID, portal.AvatarURL) - if errors.Is(err, mautrix.MForbidden) && intent != portal.MainIntent() { - _, err = portal.MainIntent().SetRoomAvatar(ctx, portal.MXID, portal.AvatarURL) - } - if err != nil { - zerolog.Ctx(ctx).Err(err).Msg("Failed to update room avatar") - } else { - portal.AvatarSet = true - } -} - -func (portal *Portal) SyncParticipants(ctx context.Context, source *User, info *signalmeow.Group) map[id.UserID]int { - log := zerolog.Ctx(ctx) - userIDs := make(map[id.UserID]int) - currentMembers := make(map[id.UserID]event.Membership) - var err error - if portal.MXID != "" { - memberEventData, err := portal.MainIntent().Members(ctx, portal.MXID, mautrix.ReqMembers{}) - if err != nil { - log.Err(err).Msg("couldn't get portal members") - return nil - } - for _, evt := range memberEventData.Chunk { - evt.Content.ParseRaw(event.StateMember) - currentMembers[id.UserID(*evt.StateKey)] = evt.Content.AsMember().Membership - } - } - for _, member := range info.Members { - puppet := portal.bridge.GetPuppetBySignalID(member.ACI) - if puppet == nil { - log.Warn().Stringer("signal_user_id", member.ACI).Msg("Couldn't get puppet for group member") - continue - } - puppet.UpdateInfo(ctx, source, nil) - intent := puppet.IntentFor(portal) - if member.ACI != source.SignalID && portal.MXID != "" { - userIDs[intent.UserID] = ((int)(member.Role) >> 1) * 50 - } - delete(currentMembers, intent.UserID) - if portal.MXID != "" { - if currentMembers[intent.UserID] != event.MembershipJoin { - err := intent.EnsureJoined(ctx, portal.MXID) - if err != nil { - log.Err(err).Stringer("signal_user_id", member.ACI).Msg("Failed to ensure user is joined to portal") - } - } - if puppet.customIntent == nil { - user := portal.bridge.GetUserBySignalID(member.ACI) - if user != nil { - delete(currentMembers, user.MXID) - userIDs[user.MXID] = ((int)(member.Role) >> 1) * 50 - currentMembership := currentMembers[user.MXID] - if currentMembership == event.MembershipJoin || currentMembership == event.MembershipInvite { - continue - } - user.ensureInvited(ctx, intent, portal.MXID, false) - } - } - } - } - if portal.MXID == "" { - return userIDs - } - for _, pendingMember := range info.PendingMembers { - if pendingMember.ServiceID.Type == libsignalgo.ServiceIDTypePNI { - continue - } - puppet := portal.bridge.GetPuppetBySignalID(pendingMember.ServiceID.UUID) - if puppet == nil { - log.Warn().Stringer("signal_user_id", pendingMember.ServiceID.UUID).Msg("Couldn't get puppet for group member") - continue - } - mxid := puppet.IntentFor(portal).UserID - membership := currentMembers[mxid] - if membership == event.MembershipJoin || membership == event.MembershipBan { - _, err = portal.MainIntent().SendCustomMembershipEvent(ctx, portal.MXID, mxid, event.MembershipLeave, "") - if err != nil { - log.Err(err).Stringer("mxid", mxid).Msg("Couldn't change membership to leave") - } - } - if membership != event.MembershipInvite { - _, err = portal.MainIntent().SendCustomMembershipEvent(ctx, portal.MXID, mxid, event.MembershipInvite, "") - if err != nil { - log.Err(err).Stringer("mxid", mxid).Msg("Couldn't change membership to invite") - } - } - userIDs[mxid] = ((int)(pendingMember.Role) >> 1) * 50 - delete(currentMembers, mxid) - if puppet.customIntent == nil { - user := portal.bridge.GetUserBySignalID(pendingMember.ServiceID.UUID) - if user == nil { - continue - } - mxid = user.MXID - membership := currentMembers[mxid] - err = nil - if membership == event.MembershipJoin || membership == event.MembershipBan { - _, err = portal.MainIntent().SendCustomMembershipEvent(ctx, portal.MXID, mxid, event.MembershipLeave, "") - if err != nil { - log.Err(err).Stringer("mxid", mxid).Msg("Couldn't change membership to leave") - } - } - if membership != event.MembershipInvite { - _, err = portal.MainIntent().SendCustomMembershipEvent(ctx, portal.MXID, mxid, event.MembershipInvite, "") - if err != nil { - log.Err(err).Stringer("mxid", mxid).Msg("Couldn't change membership to invite") - } - } - userIDs[mxid] = ((int)(pendingMember.Role) >> 1) * 50 - delete(currentMembers, mxid) - } - } - for _, requestingMember := range info.RequestingMembers { - puppet := portal.bridge.GetPuppetBySignalID(requestingMember.ACI) - if puppet == nil { - log.Warn().Stringer("signal_user_id", requestingMember.ACI).Msg("Couldn't get puppet for group member") - continue - } - mxid := puppet.IntentFor(portal).UserID - membership := currentMembers[mxid] - if membership == event.MembershipJoin || membership == event.MembershipBan { - _, err = portal.MainIntent().SendCustomMembershipEvent(ctx, portal.MXID, mxid, event.MembershipLeave, "") - if err != nil { - log.Err(err).Stringer("mxid", mxid).Msg("Couldn't change membership to leave") - } - } - if membership != event.MembershipKnock { - _, err = puppet.IntentFor(portal).SendCustomMembershipEvent(ctx, portal.MXID, mxid, event.MembershipKnock, "") - if err != nil { - log.Err(err).Stringer("mxid", mxid).Msg("Couldn't change membership to knock") - } - } - delete(currentMembers, mxid) - } - for _, bannedMember := range info.BannedMembers { - if bannedMember.ServiceID.Type == libsignalgo.ServiceIDTypePNI { - continue - } - puppet := portal.bridge.GetPuppetBySignalID(bannedMember.ServiceID.UUID) - if puppet == nil { - log.Warn().Stringer("signal_user_id", bannedMember.ServiceID.UUID).Msg("Couldn't get puppet for group member") - continue - } - mxid := puppet.IntentFor(portal).UserID - if currentMembers[mxid] != event.MembershipBan { - _, err := portal.MainIntent().SendCustomMembershipEvent(ctx, portal.MXID, mxid, event.MembershipBan, "") - if err != nil { - log.Err(err).Stringer("mxid", mxid).Msg("Couldn't change membership to ban") - } - } - delete(currentMembers, mxid) - if puppet.customIntent == nil { - user := portal.bridge.GetUserBySignalID(bannedMember.ServiceID.UUID) - if user == nil { - continue - } - mxid = user.MXID - if currentMembers[mxid] != event.MembershipBan { - _, err = portal.MainIntent().SendCustomMembershipEvent(ctx, portal.MXID, mxid, event.MembershipBan, "") - if err != nil { - log.Err(err).Stringer("mxid", mxid).Msg("Couldn't change membership to ban") - } - } - delete(currentMembers, mxid) - } - } - for mxid, membership := range currentMembers { - if membership == event.MembershipLeave { - continue - } - puppet := portal.bridge.GetPuppetByMXID(mxid) - if puppet != nil { - _, err := portal.MainIntent().SendCustomMembershipEvent(ctx, portal.MXID, mxid, event.MembershipLeave, "") - if err != nil { - log.Err(err).Stringer("mxid", mxid).Msg("Couldn't change membership to leave") - } - } else { - user := portal.bridge.GetUserByMXIDIfExists(mxid) - if user != nil { - if user.IsLoggedIn() { - _, err := portal.MainIntent().SendCustomMembershipEvent(ctx, portal.MXID, mxid, event.MembershipLeave, "") - if err != nil { - log.Err(err).Stringer("mxid", mxid).Msg("Couldn't change membership to leave") - } - } - } - } - } - return userIDs -} - -func (portal *Portal) getBridgeInfoStateKey() string { - return fmt.Sprintf("net.maunium.signal://signal/%s", portal.ChatID) -} - -func (portal *Portal) ScheduleDisappearing() { - portal.bridge.disappearingMessagesManager.ScheduleDisappearingForRoom(context.TODO(), portal.MXID) -} - -func (portal *Portal) addToPersonalSpace(ctx context.Context, user *User) bool { - spaceID := user.GetSpaceRoom(ctx) - if len(spaceID) == 0 || user.IsInSpace(ctx, portal.PortalKey) { - return false - } - _, err := portal.bridge.Bot.SendStateEvent(ctx, spaceID, event.StateSpaceChild, portal.MXID.String(), &event.SpaceChildEventContent{ - Via: []string{portal.bridge.Config.Homeserver.Domain}, - }) - if err != nil { - zerolog.Ctx(ctx).Err(err). - Stringer("user_id", user.MXID). - Stringer("space_id", spaceID). - Msg("Failed to add room to user's personal filtering space") - return false - } else { - zerolog.Ctx(ctx).Debug(). - Stringer("user_id", user.MXID). - Stringer("space_id", spaceID). - Msg("Added room to user's personal filtering space") - user.MarkInSpace(ctx, portal.PortalKey) - return true - } -} - -func (portal *Portal) HasRelaybot() bool { - return portal.bridge.Config.Bridge.Relay.Enabled && len(portal.RelayUserID) > 0 -} - -func (portal *Portal) addRelaybotFormat(ctx context.Context, userID id.UserID, evt *event.Event, content *event.MessageEventContent) bool { - member := portal.MainIntent().Member(ctx, portal.MXID, userID) - if member == nil { - member = &event.MemberEventContent{} - } - // Stickers can't have captions, so force them into images when relaying - if evt.Type == event.EventSticker { - content.MsgType = event.MsgImage - evt.Type = event.EventMessage - } - content.EnsureHasHTML() - data, err := portal.bridge.Config.Bridge.Relay.FormatMessage(content, userID, *member) - if err != nil { - portal.log.Err(err).Msg("Failed to apply relaybot format") - } - content.FormattedBody = data - // Force FileName field so the formatted body is used as a caption - if content.FileName == "" { - content.FileName = content.Body - } - return true -} - -func (portal *Portal) Delete() { - err := portal.Portal.Delete(context.TODO()) - if err != nil { - portal.log.Err(err).Msg("Failed to delete portal from db") - } - portal.bridge.portalsLock.Lock() - portal.unlockedDeleteCache() - portal.bridge.portalsLock.Unlock() -} - -func (portal *Portal) unlockedDelete() { - err := portal.Portal.Delete(context.TODO()) - if err != nil { - portal.log.Err(err).Msg("Failed to delete portal from db") - } - portal.unlockedDeleteCache() -} - -func (portal *Portal) unlockedDeleteCache() { - delete(portal.bridge.portalsByID, portal.PortalKey) - if len(portal.MXID) > 0 { - delete(portal.bridge.portalsByMXID, portal.MXID) - } - if portal.Receiver == uuid.Nil { - portal.bridge.usersLock.Lock() - for _, user := range portal.bridge.usersBySignalID { - user.RemoveInSpaceCache(portal.PortalKey) - } - portal.bridge.usersLock.Unlock() - } else { - user := portal.bridge.GetUserBySignalID(portal.Receiver) - if user != nil { - user.RemoveInSpaceCache(portal.PortalKey) - } - } -} - -func (portal *Portal) Cleanup(ctx context.Context, puppetsOnly bool) { - portal.bridge.CleanupRoom(ctx, &portal.log, portal.MainIntent(), portal.MXID, puppetsOnly) -} - -func (br *SignalBridge) CleanupRoom(ctx context.Context, log *zerolog.Logger, intent *appservice.IntentAPI, mxid id.RoomID, puppetsOnly bool) { - if len(mxid) == 0 { - return - } - if br.SpecVersions.Supports(mautrix.BeeperFeatureRoomYeeting) { - err := intent.BeeperDeleteRoom(ctx, mxid) - if err == nil || errors.Is(err, mautrix.MNotFound) { - return - } - log.Warn().Err(err).Msg("Failed to delete room using beeper yeet endpoint, falling back to normal behavior") - } - members, err := intent.JoinedMembers(ctx, mxid) - if err != nil { - log.Err(err).Msg("Failed to get portal members for cleanup") - return - } - for member := range members.Joined { - if member == intent.UserID { - continue - } - puppet := br.GetPuppetByMXID(member) - if puppet != nil { - _, err = puppet.DefaultIntent().LeaveRoom(ctx, mxid) - if err != nil { - log.Err(err).Msg("Failed to leave as puppet while cleaning up portal") - } - } else if !puppetsOnly { - _, err = intent.KickUser(ctx, mxid, &mautrix.ReqKickUser{UserID: member, Reason: "Deleting portal"}) - if err != nil { - log.Err(err).Msg("Failed to kick user while cleaning up portal") - } - } - } - _, err = intent.LeaveRoom(ctx, mxid) - if err != nil { - log.Err(err).Msg("Failed to leave room while cleaning up portal") - } -} - -func (portal *Portal) HandleMatrixLeave(brSender bridge.User, evt *event.Event) { - log := portal.log.With(). - Str("action", "handle matrix leave"). - Stringer("event_id", evt.ID). - Str("event_type", evt.Type.String()). - Logger() - ctx := log.WithContext(context.TODO()) - sender := brSender.(*User) - if portal.IsPrivateChat() { - log.Info().Msg("User left private chat portal, cleaning up and deleting...") - portal.Delete() - portal.Cleanup(ctx, false) - return - } else if portal.bridge.Config.Bridge.BridgeMatrixLeave { - portal.deleteMember(sender, sender.SignalID, evt) - } - portal.CleanupIfEmpty(ctx) -} -func (portal *Portal) HandleMatrixKick(brSender bridge.User, ghost bridge.Ghost, evt *event.Event) { - portal.deleteMember(brSender.(*User), ghost.(*Puppet).SignalID, evt) -} -func (portal *Portal) deleteMember(sender *User, target uuid.UUID, evt *event.Event) { - log := portal.log.With(). - Str("action", "handle matrix kick/leave"). - Stringer("event_id", evt.ID). - Str("event_type", evt.Type.String()). - Logger() - ctx := log.WithContext(context.TODO()) - groupChange := &signalmeow.GroupChange{DeleteMembers: []*uuid.UUID{&target}} - revision, err := sender.Client.UpdateGroup(ctx, groupChange, portal.GroupID()) - if err != nil { - log.Err(err).Msg("Error deleting Member from Signal") - return - } - portal.Revision = revision - portal.Update(ctx) -} -func (portal *Portal) HandleMatrixInvite(brSender bridge.User, brGhost bridge.Ghost, evt *event.Event) { - log := portal.log.With(). - Str("action", "handle matrix invite"). - Stringer("event_id", evt.ID). - Str("event_type", evt.Type.String()). - Logger() - ctx := log.WithContext(context.TODO()) - sender := brSender.(*User) - puppet := brGhost.(*Puppet) - role := signalmeow.GroupMember_DEFAULT - levels, err := portal.MainIntent().PowerLevels(ctx, portal.MXID) - if err != nil { - log.Err(err).Msg("Couldn't get power levels") - if levels.GetUserLevel(puppet.IntentFor(portal).UserID) >= 50 { - role = signalmeow.GroupMember_ADMINISTRATOR - } - } - groupChange := &signalmeow.GroupChange{AddMembers: []*signalmeow.AddMember{{ - GroupMember: signalmeow.GroupMember{ - ACI: puppet.SignalID, - Role: role, - }, - }}} - revision, err := sender.Client.UpdateGroup(ctx, groupChange, portal.GroupID()) - if err != nil { - log.Err(err).Msg("Error inviting user on Signal") - } - puppet.IntentFor(portal).EnsureJoined(ctx, portal.MXID) - portal.Revision = revision - portal.Update(ctx) -} - -func (portal *Portal) HandleMatrixAcceptKnock(brSender bridge.User, brGhost bridge.Ghost, evt *event.Event) { - log := portal.log.With(). - Str("action", "handle matrix accept knock"). - Stringer("event_id", evt.ID). - Str("event_type", evt.Type.String()). - Logger() - ctx := log.WithContext(context.TODO()) - sender := brSender.(*User) - puppet := brGhost.(*Puppet) - role := signalmeow.GroupMember_DEFAULT - levels, err := portal.MainIntent().PowerLevels(ctx, portal.MXID) - if err != nil { - log.Err(err).Msg("Couldn't get power levels") - if levels.GetUserLevel(puppet.IntentFor(portal).UserID) >= 50 { - role = signalmeow.GroupMember_ADMINISTRATOR - } - } - groupChange := &signalmeow.GroupChange{PromoteRequestingMembers: []*signalmeow.RoleMember{{ - ACI: puppet.SignalID, - Role: role, - }}} - revision, err := sender.Client.UpdateGroup(ctx, groupChange, portal.GroupID()) - if err != nil { - log.Err(err).Msg("Error accepting join request on Signal") - } - portal.Revision = revision - portal.Update(ctx) -} - -func (portal *Portal) HandleMatrixRejectKnock(brSender bridge.User, brGhost bridge.Ghost, evt *event.Event) { - portal.removeRequestingMember(brSender.(*User), brGhost.(*Puppet).SignalID, evt) -} - -func (portal *Portal) HandleMatrixRetractKnock(brSender bridge.User, evt *event.Event) { - portal.removeRequestingMember(brSender.(*User), brSender.(*User).SignalID, evt) -} - -func (portal *Portal) removeRequestingMember(sender *User, target uuid.UUID, evt *event.Event) { - log := portal.log.With(). - Str("action", "handle matrix knock -> leave"). - Stringer("event_id", evt.ID). - Str("event_type", evt.Type.String()). - Logger() - ctx := log.WithContext(context.TODO()) - groupChange := &signalmeow.GroupChange{DeleteRequestingMembers: []*uuid.UUID{&target}} - revision, err := sender.Client.UpdateGroup(ctx, groupChange, portal.GroupID()) - if err != nil { - log.Err(err).Msg("Error removing requesting member") - } - portal.Revision = revision - portal.Update(ctx) -} - -func (portal *Portal) HandleMatrixKnock(brSender bridge.User, evt *event.Event) { - log := portal.log.With(). - Str("action", "handle matrix knock"). - Stringer("event_id", evt.ID). - Str("event_type", evt.Type.String()). - Logger() - log.Debug().Msg("Knocks aren't implemented yet :(") -} - -func (portal *Portal) HandleMatrixBan(brSender bridge.User, brGhost bridge.Ghost, evt *event.Event) { - log := portal.log.With(). - Str("action", "handle matrix ban"). - Stringer("event_id", evt.ID). - Str("event_type", evt.Type.String()). - Logger() - ctx := log.WithContext(context.TODO()) - sender := brSender.(*User) - puppet := brGhost.(*Puppet) - groupChange := &signalmeow.GroupChange{AddBannedMembers: []*signalmeow.BannedMember{{ - ServiceID: libsignalgo.NewACIServiceID(puppet.SignalID), - Timestamp: uint64(time.Now().UnixMilli()), - }}} - switch prevMembership := evt.Unsigned.PrevContent.AsMember().Membership; prevMembership { - case event.MembershipJoin: - groupChange.DeleteMembers = []*uuid.UUID{&puppet.SignalID} - case event.MembershipKnock: - groupChange.DeleteRequestingMembers = []*uuid.UUID{&puppet.SignalID} - case event.MembershipInvite: - serviceID := libsignalgo.NewACIServiceID(puppet.SignalID) - groupChange.DeletePendingMembers = []*libsignalgo.ServiceID{&serviceID} - } - revision, err := sender.Client.UpdateGroup(ctx, groupChange, portal.GroupID()) - if err != nil { - log.Err(err).Msg("Error banning on Signal") - } - portal.Revision = revision - portal.Update(ctx) -} - -func (portal *Portal) HandleMatrixUnban(brSender bridge.User, brGhost bridge.Ghost, evt *event.Event) { - log := portal.log.With(). - Str("action", "handle matrix unban"). - Stringer("event_id", evt.ID). - Str("event_type", evt.Type.String()). - Logger() - ctx := log.WithContext(context.TODO()) - sender := brSender.(*User) - puppet := brGhost.(*Puppet) - serviceID := libsignalgo.NewACIServiceID(puppet.SignalID) - groupChange := &signalmeow.GroupChange{DeleteBannedMembers: []*libsignalgo.ServiceID{&serviceID}} - revision, err := sender.Client.UpdateGroup(ctx, groupChange, portal.GroupID()) - if err != nil { - log.Err(err).Msg("Error unbanning on Signal") - } - portal.Revision = revision - portal.Update(ctx) -} - -func (portal *Portal) HandleMatrixPowerLevels(brSender bridge.User, evt *event.Event) { - log := portal.log.With(). - Str("action", "handle matrix power levels"). - Stringer("event_id", evt.ID). - Str("event_type", evt.Type.String()). - Logger() - ctx := log.WithContext(context.TODO()) - sender := brSender.(*User) - if !sender.IsLoggedIn() { - log.Warn().Msg("Can't change power levels: user is not logged in") - return - } - evt.Content.ParseRaw(event.StatePowerLevels) - levels := evt.Content.AsPowerLevels() - var prevLevels *event.PowerLevelsEventContent - if evt.Unsigned.PrevContent != nil { - evt.Unsigned.PrevContent.ParseRaw(event.StatePowerLevels) - prevLevels = evt.Unsigned.PrevContent.AsPowerLevels() - } else { - prevLevels = &event.PowerLevelsEventContent{} - } - groupChange := &signalmeow.GroupChange{} - var role signalmeow.GroupMemberRole - for user, level := range levels.Users { - prevLevel := prevLevels.GetUserLevel(user) - if (level >= 50 && prevLevel < 50) || (level < 50 && prevLevel >= 50) { - puppet := portal.bridge.GetPuppetByMXID(user) - if puppet == nil { - log.Warn().Stringer("mxid", user).Msg("Couldn't get puppet for power level change") - continue - } - role = signalmeow.GroupMember_DEFAULT - if level >= 50 { - role = signalmeow.GroupMember_ADMINISTRATOR - } - groupChange.ModifyMemberRoles = append(groupChange.ModifyMemberRoles, &signalmeow.RoleMember{ - ACI: puppet.SignalID, - Role: role, - }) - } - } - if levels.EventsDefault >= 50 && prevLevels.EventsDefault < 50 { - announcementsOnly := true - groupChange.ModifyAnnouncementsOnly = &announcementsOnly - } else if levels.EventsDefault < 50 && prevLevels.EventsDefault >= 50 { - announcementsOnly := false - groupChange.ModifyAnnouncementsOnly = &announcementsOnly - } - if levels.StateDefault() >= 50 && prevLevels.StateDefault() < 50 { - attributesAccess := signalmeow.AccessControl_ADMINISTRATOR - groupChange.ModifyAttributesAccess = &attributesAccess - } else if levels.StateDefault() < 50 && prevLevels.StateDefault() >= 50 { - attributesAccess := signalmeow.AccessControl_MEMBER - groupChange.ModifyAttributesAccess = &attributesAccess - } - if levels.Invite() >= 50 && prevLevels.Invite() < 50 { - memberAccess := signalmeow.AccessControl_ADMINISTRATOR - groupChange.ModifyMemberAccess = &memberAccess - } else if levels.Invite() < 50 && prevLevels.Invite() >= 50 { - memberAccess := signalmeow.AccessControl_MEMBER - groupChange.ModifyMemberAccess = &memberAccess - } - revision, err := sender.Client.UpdateGroup(ctx, groupChange, portal.GroupID()) - if err != nil { - log.Err(err).Msg("Error changing group access control") - return - } - portal.Revision = revision - portal.Update(ctx) -} - -func (portal *Portal) HandleMatrixJoinRule(brSender bridge.User, evt *event.Event) { - log := portal.log.With(). - Str("action", "handle matrix join rule"). - Stringer("event_id", evt.ID). - Str("event_type", evt.Type.String()). - Logger() - ctx := log.WithContext(context.TODO()) - sender := brSender.(*User) - if !sender.IsLoggedIn() { - log.Warn().Msg("Can't change join rule: user is not logged in") - return - } - evt.Content.ParseRaw(event.StateJoinRules) - joinRule := evt.Content.AsJoinRules().JoinRule - groupChange := &signalmeow.GroupChange{} - addFromInviteLinkAccess := signalmeow.AccessControl_UNSATISFIABLE - if joinRule == event.JoinRuleKnock { - addFromInviteLinkAccess = signalmeow.AccessControl_ADMINISTRATOR - } else if joinRule == event.JoinRulePublic { - addFromInviteLinkAccess = signalmeow.AccessControl_ANY - } - groupChange.ModifyAddFromInviteLinkAccess = &addFromInviteLinkAccess - revision, err := sender.Client.UpdateGroup(ctx, groupChange, portal.GroupID()) - if err != nil { - log.Err(err).Msg("Error updating group access control") - return - } - portal.Revision = revision - portal.Update(ctx) -} - -func (portal *Portal) HandleMatrixMeta(brSender bridge.User, evt *event.Event) { - log := portal.log.With(). - Str("action", "handle matrix meta"). - Stringer("event_id", evt.ID). - Str("event_type", evt.Type.String()). - Logger() - ctx := log.WithContext(context.TODO()) - sender := brSender.(*User) - if !sender.IsLoggedIn() { - log.Warn().Msg("Can't change room info: user is not logged in") - return - } - - var err error - groupChange := &signalmeow.GroupChange{Revision: portal.Revision + 1} - var avatarPath *string - var avatarHash string - var avatarURL id.ContentURI - var avatarChanged bool - switch content := evt.Content.Parsed.(type) { - case *event.RoomNameEventContent: - if content.Name == portal.Name { - return - } - portal.Name = content.Name - groupChange.ModifyTitle = &content.Name - case *event.TopicEventContent: - if content.Topic == portal.Topic { - return - } - portal.Topic = content.Topic - groupChange.ModifyDescription = &content.Topic - case *event.RoomAvatarEventContent: - url := content.URL.ParseOrIgnore() - if url == portal.AvatarURL { - return - } - var data []byte - if !url.IsEmpty() { - data, err = portal.MainIntent().DownloadBytes(ctx, url) - if err != nil { - log.Err(err).Stringer("Failed to download updated avatar %s", url) - return - } - log.Debug().Stringers("%s set the group avatar to %s", []fmt.Stringer{sender.MXID, url}) - } else { - log.Debug().Stringer("%s removed the group avatar", sender.MXID) - } - avatarPath, err = sender.Client.UploadGroupAvatar(ctx, data, portal.GroupID()) - if err != nil { - log.Err(err).Msg("Failed to upload group avatar") - return - } - groupChange.ModifyAvatar = avatarPath - hash := sha256.Sum256(data) - avatarHash = hex.EncodeToString(hash[:]) - avatarChanged = true - avatarURL = url - } - revision, err := sender.Client.UpdateGroup(ctx, groupChange, portal.GroupID()) - if err != nil { - log.Err(err).Msg("Error updating group attributes") - return - } - if avatarChanged { - log.Debug().Msg("Successfully updated group avatar") - portal.AvatarSet = true - portal.AvatarPath = *avatarPath - portal.AvatarHash = avatarHash - portal.AvatarURL = avatarURL - portal.UpdateBridgeInfo(ctx) - } - portal.Revision = revision - portal.Update(ctx) - log.Info().Msg("finished updating group") -} - -func (portal *Portal) CleanupIfEmpty(ctx context.Context) { - log := portal.log.With(). - Str("action", "Clean up if empty"). - Logger() - users, err := portal.GetMatrixUsers(ctx) - if err != nil { - log.Err(err).Msg("Failed to get Matrix user list to determine if portal needs to be cleaned up") - return - } - - if len(users) == 0 { - log.Info().Msg("Room seems to be empty, cleaning up...") - portal.Delete() - portal.Cleanup(ctx, false) - } -} - -func (portal *Portal) GetMatrixUsers(ctx context.Context) ([]id.UserID, error) { - members, err := portal.MainIntent().JoinedMembers(ctx, portal.MXID) - if err != nil { - return nil, fmt.Errorf("failed to get member list: %w", err) - } - var users []id.UserID - for userID := range members.Joined { - _, isPuppet := portal.bridge.ParsePuppetMXID(userID) - if !isPuppet && userID != portal.bridge.Bot.UserID { - users = append(users, userID) - } - } - return users, nil -} - -func (portal *Portal) GetInviteLink(ctx context.Context, source *User) (string, error) { - info, err := source.Client.RetrieveGroupByID(ctx, portal.GroupID(), portal.Revision) - if err != nil { - zerolog.Ctx(ctx).Err(err). - Stringer("source_user_id", source.MXID). - Msg("Failed to fetch group info") - return "", err - } - inviteLinkPassword, err := info.GetInviteLink() - if err != nil { - zerolog.Ctx(ctx).Err(err).Msg("Failed to get invite link") - } - return inviteLinkPassword, nil -} - -func (portal *Portal) ResetInviteLink(ctx context.Context, source *User) error { - inviteLinkPassword := signalmeow.GenerateInviteLinkPassword() - groupChange := &signalmeow.GroupChange{ModifyInviteLinkPassword: &inviteLinkPassword} - revision, err := source.Client.UpdateGroup(ctx, groupChange, portal.GroupID()) - if err != nil { - zerolog.Ctx(ctx).Err(err).Msg("Error setting invite link password") - return err - } - portal.Revision = revision - return portal.Update(ctx) -} - -func (portal *Portal) GetEncryptionEventContent() (evt *event.EncryptionEventContent) { - evt = &event.EncryptionEventContent{Algorithm: id.AlgorithmMegolmV1} - if rot := portal.bridge.Config.Bridge.Encryption.Rotation; rot.EnableCustom { - evt.RotationPeriodMillis = rot.Milliseconds - evt.RotationPeriodMessages = rot.Messages - } - return -} diff --git a/provisioning.go b/provisioning.go deleted file mode 100644 index 46b52d1..0000000 --- a/provisioning.go +++ /dev/null @@ -1,640 +0,0 @@ -// mautrix-signal - A Matrix-signal puppeting bridge. -// Copyright (C) 2023 Scott Weber -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see . - -package main - -import ( - "context" - "encoding/json" - "errors" - "fmt" - "net/http" - _ "net/http/pprof" - "strconv" - "strings" - "sync" - "time" - - "github.com/google/uuid" - "github.com/gorilla/mux" - "github.com/rs/zerolog" - "github.com/rs/zerolog/hlog" - "go.mau.fi/util/requestlog" - "maunium.net/go/mautrix" - "maunium.net/go/mautrix/id" - - "go.mau.fi/mautrix-signal/legacyprovision" - "go.mau.fi/mautrix-signal/pkg/libsignalgo" - "go.mau.fi/mautrix-signal/pkg/signalmeow" - "go.mau.fi/mautrix-signal/pkg/signalmeow/types" -) - -type provisioningContextKey int - -const ( - provisioningUserKey provisioningContextKey = iota -) - -type provisioningHandle struct { - id int - context context.Context - cancel context.CancelFunc - channel <-chan signalmeow.ProvisioningResponse -} - -type ProvisioningAPI struct { - bridge *SignalBridge - log zerolog.Logger - provisioningHandles []*provisioningHandle - provisioningUsers map[string]int - provisioningMutexes map[string]*sync.Mutex -} - -func (prov *ProvisioningAPI) Init() { - prov.log.Debug().Str("prefix", prov.bridge.Config.Bridge.Provisioning.Prefix).Msg("Enabling provisioning API") - prov.provisioningUsers = make(map[string]int) - prov.provisioningMutexes = make(map[string]*sync.Mutex) - r := prov.bridge.AS.Router.PathPrefix(prov.bridge.Config.Bridge.Provisioning.Prefix).Subrouter() - r.Use(hlog.NewHandler(prov.log)) - r.Use(requestlog.AccessLogger(true)) - r.Use(prov.AuthMiddleware) - r.HandleFunc("/v2/whoami", prov.WhoAmI).Methods(http.MethodGet) - r.HandleFunc("/v2/link/new", prov.LinkNew).Methods(http.MethodPost) - r.HandleFunc("/v2/link/wait/scan", prov.LinkWaitForScan).Methods(http.MethodPost) - r.HandleFunc("/v2/link/wait/account", prov.LinkWaitForAccount).Methods(http.MethodPost) - r.HandleFunc("/v2/logout", prov.Logout).Methods(http.MethodPost) - r.HandleFunc("/v2/resolve_identifier/{phonenum}", prov.ResolveIdentifier).Methods(http.MethodGet) - r.HandleFunc("/v2/pm/{phonenum}", prov.StartPM).Methods(http.MethodPost) - - if prov.bridge.Config.Bridge.Provisioning.DebugEndpoints { - prov.log.Debug().Msg("Enabling debug API at /debug") - r := prov.bridge.AS.Router.PathPrefix("/debug").Subrouter() - r.Use(prov.AuthMiddleware) - r.PathPrefix("/pprof").Handler(http.DefaultServeMux) - } -} - -func (prov *ProvisioningAPI) AuthMiddleware(h http.Handler) http.Handler { - return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - auth := strings.TrimPrefix(r.Header.Get("Authorization"), "Bearer ") - if auth != prov.bridge.Config.Bridge.Provisioning.SharedSecret { - zerolog.Ctx(r.Context()).Warn().Msg("Authentication token does not match shared secret") - legacyprovision.JSONResponse(w, http.StatusForbidden, &mautrix.RespError{ - Err: "Authentication token does not match shared secret", - ErrCode: mautrix.MForbidden.ErrCode, - }) - return - } - userID := r.URL.Query().Get("user_id") - user := prov.bridge.GetUserByMXID(id.UserID(userID)) - h.ServeHTTP(w, r.WithContext(context.WithValue(r.Context(), provisioningUserKey, user))) - }) -} - -func (prov *ProvisioningAPI) resolveIdentifier(ctx context.Context, user *User, inputPhone string) (int, *legacyprovision.ResolveIdentifierResponse, error) { - if user.Client == nil { - return http.StatusUnauthorized, nil, errors.New("not currently connected to Signal") - } - e164Number, err := strconv.ParseUint(numberCleaner.Replace(inputPhone), 10, 64) - if err != nil { - return http.StatusBadRequest, nil, fmt.Errorf("error parsing phone number: %w", err) - } - e164String := fmt.Sprintf("+%d", e164Number) - var aci, pni uuid.UUID - var recipient *types.Recipient - if recipient, err = user.Client.ContactByE164(ctx, e164String); err != nil { - return http.StatusInternalServerError, nil, fmt.Errorf("error looking up number in local contact list: %w", err) - } else if recipient != nil { - aci = recipient.ACI - pni = recipient.PNI - } else if resp, err := user.Client.LookupPhone(ctx, e164Number); err != nil { - return http.StatusInternalServerError, nil, fmt.Errorf("error looking up number on server: %w", err) - } else { - aci = resp[e164Number].ACI - pni = resp[e164Number].PNI - if aci == uuid.Nil && pni == uuid.Nil { - return http.StatusNotFound, nil, errors.New("user not found on Signal") - } - recipient, err = user.Client.Store.RecipientStore.UpdateRecipientE164(ctx, aci, pni, e164String) - if err != nil { - zerolog.Ctx(ctx).Err(err).Msg("Failed to save recipient entry after looking up phone") - } - aci, pni = recipient.ACI, recipient.PNI - } - zerolog.Ctx(ctx).Debug(). - Uint64("e164", e164Number). - Stringer("aci", aci). - Stringer("pni", pni). - Msg("Found DM target user") - - var targetServiceID libsignalgo.ServiceID - var otherUserInfo *legacyprovision.ResolveIdentifierResponseOtherUser - if aci != uuid.Nil { - targetServiceID = libsignalgo.NewACIServiceID(aci) - puppet := prov.bridge.GetPuppetBySignalID(aci) - otherUserInfo = &legacyprovision.ResolveIdentifierResponseOtherUser{ - MXID: puppet.MXID, - DisplayName: puppet.Name, - AvatarURL: puppet.AvatarURL, - } - } else { - targetServiceID = libsignalgo.NewPNIServiceID(pni) - // TODO fill other user displayname/avatar if there's a contact entry? - } - portal := user.GetPortalByChatID(targetServiceID.String()) - - return http.StatusOK, &legacyprovision.ResolveIdentifierResponse{ - RoomID: portal.MXID, - ChatID: legacyprovision.ResolveIdentifierResponseChatID{ - UUID: targetServiceID.String(), - Number: e164String, - }, - OtherUser: otherUserInfo, - }, nil -} - -func (prov *ProvisioningAPI) ResolveIdentifier(w http.ResponseWriter, r *http.Request) { - user := r.Context().Value(provisioningUserKey).(*User) - phoneNum := mux.Vars(r)["phonenum"] - - log := prov.log.With(). - Str("action", "resolve_identifier"). - Stringer("user_id", user.MXID). - Str("phone_num", phoneNum). - Logger() - ctx := log.WithContext(r.Context()) - log.Debug().Msg("resolving identifier") - - status, resp, err := prov.resolveIdentifier(ctx, user, phoneNum) - if err != nil { - errCode := "M_INTERNAL" - if status == http.StatusNotFound { - log.Debug().Msg("contact not found") - errCode = "M_NOT_FOUND" - } else { - log.Err(err).Msg("error looking up contact") - } - legacyprovision.JSONResponse(w, status, legacyprovision.Error{ - Success: false, - Error: err.Error(), - ErrCode: errCode, - }) - return - } - legacyprovision.JSONResponse(w, status, legacyprovision.Response{ - Success: true, - Status: "ok", - ResolveIdentifierResponse: resp, - }) -} - -func (prov *ProvisioningAPI) StartPM(w http.ResponseWriter, r *http.Request) { - user := r.Context().Value(provisioningUserKey).(*User) - phoneNum := mux.Vars(r)["phonenum"] - - log := prov.log.With(). - Str("action", "start_pm"). - Stringer("user_id", user.MXID). - Str("phone_num", phoneNum). - Logger() - ctx := log.WithContext(r.Context()) - log.Debug().Msg("starting private message") - - status, resp, err := prov.resolveIdentifier(ctx, user, phoneNum) - if err != nil { - errCode := "M_INTERNAL" - if status == http.StatusNotFound { - log.Debug().Msg("contact not found") - errCode = "M_NOT_FOUND" - } else { - log.Err(err).Msg("error looking up contact") - } - legacyprovision.JSONResponse(w, status, legacyprovision.Error{ - Success: false, - Error: err.Error(), - ErrCode: errCode, - }) - return - } - - portal := user.GetPortalByChatID(resp.ChatID.UUID) - if portal.MXID == "" { - if err := portal.CreateMatrixRoom(r.Context(), user, 0); err != nil { - log.Err(err).Msg("error looking up contact") - legacyprovision.JSONResponse(w, http.StatusInternalServerError, legacyprovision.Error{ - Success: false, - Error: "Error creating Matrix room", - ErrCode: "M_INTERNAL", - }) - return - } - resp.JustCreated = true - resp.RoomID = portal.MXID - } - if resp.JustCreated { - status = http.StatusCreated - } - - legacyprovision.JSONResponse(w, status, legacyprovision.Response{ - Success: true, - Status: "ok", - ResolveIdentifierResponse: resp, - }) -} - -func (prov *ProvisioningAPI) mutexForUser(user *User) *sync.Mutex { - if _, ok := prov.provisioningMutexes[user.MXID.String()]; !ok { - prov.provisioningMutexes[user.MXID.String()] = &sync.Mutex{} - } - return prov.provisioningMutexes[user.MXID.String()] -} - -func (prov *ProvisioningAPI) newOrExistingSession(user *User) (newSessionLoggedIn bool, handle *provisioningHandle, err error) { - prov.mutexForUser(user).Lock() - defer prov.mutexForUser(user).Unlock() - - if existingSessionID, ok := prov.provisioningUsers[user.MXID.String()]; ok { - provisioningHandle := prov.provisioningHandles[existingSessionID] - return false, provisioningHandle, nil - } - - provChan, err := user.Login() - if err != nil { - return false, nil, fmt.Errorf("Error logging in: %w", err) - } - provisioningCtx, cancel := context.WithCancel(context.TODO()) - handle = &provisioningHandle{ - context: provisioningCtx, - cancel: cancel, - channel: provChan, - } - prov.provisioningHandles = append(prov.provisioningHandles, handle) - handle.id = len(prov.provisioningHandles) - 1 - prov.provisioningUsers[user.MXID.String()] = handle.id - return true, handle, nil -} - -func (prov *ProvisioningAPI) existingSession(user *User) (handle *provisioningHandle) { - prov.mutexForUser(user).Lock() - defer prov.mutexForUser(user).Unlock() - - if existingSessionID, ok := prov.provisioningUsers[user.MXID.String()]; ok { - provisioningHandle := prov.provisioningHandles[existingSessionID] - return provisioningHandle - } - return nil -} - -func (prov *ProvisioningAPI) clearSession(ctx context.Context, user *User) { - log := zerolog.Ctx(ctx).With().Str("function", "clearSession").Logger() - prov.mutexForUser(user).Lock() - defer prov.mutexForUser(user).Unlock() - - if existingSessionID, ok := prov.provisioningUsers[user.MXID.String()]; ok { - log.Debug().Int("existing_session_id", existingSessionID).Msg("clearing existing session") - if existingSessionID >= len(prov.provisioningHandles) { - log.Warn().Msg("session does not exist") - return - } - if prov.provisioningHandles[existingSessionID].cancel != nil { - prov.provisioningHandles[existingSessionID].cancel() - } - prov.provisioningHandles[existingSessionID] = nil - delete(prov.provisioningUsers, user.MXID.String()) - } else { - prov.log.Debug().Msg("no session found") - } -} - -func (prov *ProvisioningAPI) loginOrSendError(ctx context.Context, w http.ResponseWriter, user *User) (*provisioningHandle, error) { - newSessionLoggedIn, handle, err := prov.newOrExistingSession(user) - if err != nil { - return nil, err - } - if !newSessionLoggedIn { - zerolog.Ctx(ctx).Debug(). - Int("existing_provisioning_handle", handle.id). - Msg("user already has pending provisioning request, cancelling") - prov.clearSession(ctx, user) - _, handle, err = prov.newOrExistingSession(user) - if err != nil { - return nil, fmt.Errorf("error logging in after cancelling existing session: %w", err) - } - } - return handle, nil -} - -func (prov *ProvisioningAPI) checkSessionAndReturnHandle(ctx context.Context, w http.ResponseWriter, currentSession int) *provisioningHandle { - log := zerolog.Ctx(ctx).With().Str("function", "checkSessionAndReturnHandle").Logger() - user := ctx.Value(provisioningUserKey).(*User) - handle := prov.existingSession(user) - if handle == nil { - log.Warn().Msg("no session found") - legacyprovision.JSONResponse(w, http.StatusNotFound, legacyprovision.Error{ - Success: false, - Error: "No session found", - ErrCode: "M_NOT_FOUND", - }) - return nil - } - if handle.id != currentSession { - log.Warn(). - Int("handle_id", handle.id). - Int("current_session", currentSession). - Msg("session_id does not match user's session_id") - legacyprovision.JSONResponse(w, http.StatusBadRequest, legacyprovision.Error{ - Success: false, - Error: "session_id does not match user's session_id", - ErrCode: "M_BAD_JSON", - }) - return nil - } - return handle -} - -func (prov *ProvisioningAPI) WhoAmI(w http.ResponseWriter, r *http.Request) { - user := r.Context().Value(provisioningUserKey).(*User) - log := prov.log.With(). - Str("action", "whoami"). - Stringer("user_id", user.MXID). - Logger() - log.Debug().Msg("getting whoami") - - data := legacyprovision.WhoAmIResponse{ - Permissions: int(user.PermissionLevel), - MXID: user.MXID.String(), - } - if user.IsLoggedIn() { - data.Signal = &legacyprovision.WhoAmIResponseSignal{ - Number: user.SignalUsername, - UUID: user.SignalID.String(), - Ok: user.Client.IsConnected(), - } - puppet := user.bridge.GetPuppetBySignalID(user.SignalID) - if puppet != nil { - data.Signal.Name = puppet.Name - } - } - legacyprovision.JSONResponse(w, http.StatusOK, data) -} - -func (prov *ProvisioningAPI) LinkNew(w http.ResponseWriter, r *http.Request) { - user := r.Context().Value(provisioningUserKey).(*User) - log := prov.log.With(). - Str("action", "link_new"). - Stringer("user_id", user.MXID). - Logger() - ctx := log.WithContext(r.Context()) - log.Debug().Msg("starting login") - - handle, err := prov.loginOrSendError(ctx, w, user) - if err != nil { - legacyprovision.JSONResponse(w, http.StatusInternalServerError, legacyprovision.Error{ - Success: false, - Error: err.Error(), - ErrCode: "M_INTERNAL", - }) - return - } - - log = log.With().Int("session_id", handle.id).Logger() - log.Debug().Msg("waiting for provisioning response") - - select { - case resp := <-handle.channel: - if resp.Err != nil || resp.State == signalmeow.StateProvisioningError { - log.Err(resp.Err).Msg("Error getting provisioning URL") - legacyprovision.JSONResponse(w, http.StatusInternalServerError, legacyprovision.Error{ - Success: false, - Error: resp.Err.Error(), - ErrCode: "M_INTERNAL", - }) - return - } - if resp.State != signalmeow.StateProvisioningURLReceived { - log.Err(resp.Err).Stringer("state", resp.State).Msg("unexpected state") - legacyprovision.JSONResponse(w, http.StatusInternalServerError, legacyprovision.Error{ - Success: false, - Error: fmt.Sprintf("Unexpected state %s", resp.State.String()), - ErrCode: "M_INTERNAL", - }) - return - } - - log.Debug().Str("provisioning_url", resp.ProvisioningURL).Msg("provisioning URL received") - legacyprovision.JSONResponse(w, http.StatusOK, legacyprovision.Response{ - Success: true, - Status: "provisioning_url_received", - SessionID: fmt.Sprintf("%d", handle.id), - URI: resp.ProvisioningURL, - }) - case <-time.After(30 * time.Second): - log.Warn().Msg("Timeout waiting for provisioning response (new)") - legacyprovision.JSONResponse(w, http.StatusGatewayTimeout, legacyprovision.Error{ - Success: false, - Error: "Timeout waiting for provisioning response (new)", - ErrCode: "M_TIMEOUT", - }) - } -} - -func (prov *ProvisioningAPI) LinkWaitForScan(w http.ResponseWriter, r *http.Request) { - user := r.Context().Value(provisioningUserKey).(*User) - - var body legacyprovision.LinkWaitForScanRequest - err := json.NewDecoder(r.Body).Decode(&body) - if err != nil { - legacyprovision.JSONResponse(w, http.StatusBadRequest, legacyprovision.Error{ - Success: false, - Error: "Error decoding JSON body", - ErrCode: "M_BAD_JSON", - }) - return - } - sessionID, err := strconv.Atoi(body.SessionID) - if err != nil { - legacyprovision.JSONResponse(w, http.StatusBadRequest, legacyprovision.Error{ - Success: false, - Error: "Error decoding session ID in JSON body", - ErrCode: "M_BAD_JSON", - }) - return - } - - log := prov.log.With(). - Str("action", "link_wait_for_scan"). - Stringer("user_id", user.MXID). - Str("session_id", body.SessionID). - Logger() - ctx := log.WithContext(r.Context()) - log.Debug().Msg("waiting for scan") - - handle := prov.checkSessionAndReturnHandle(ctx, w, sessionID) - if handle == nil { - return - } - - select { - case resp := <-handle.channel: - if resp.Err != nil || resp.State == signalmeow.StateProvisioningError { - log.Err(resp.Err).Msg("Error waiting for scan") - // If context was cancelled be chill - if errors.Is(resp.Err, context.Canceled) { - log.Debug().Msg("Context cancelled waiting for scan") - return - } - // If we error waiting for the scan, treat it as a normal error not 5xx - // so that the client will retry quietly. Also, it's really not an internal - // error, sitting with a WS open waiting for a scan is inherently flaky. - legacyprovision.JSONResponse(w, http.StatusBadRequest, legacyprovision.Error{ - Success: false, - Error: resp.Err.Error(), - ErrCode: "M_INTERNAL", - }) - return - } - if resp.State != signalmeow.StateProvisioningDataReceived { - log.Err(resp.Err).Stringer("state", resp.State).Msg("unexpected state") - legacyprovision.JSONResponse(w, http.StatusInternalServerError, legacyprovision.Error{ - Success: false, - Error: fmt.Sprintf("Unexpected state %s", resp.State.String()), - ErrCode: "M_INTERNAL", - }) - return - } - log.Debug().Msg("provisioning data received") - legacyprovision.JSONResponse(w, http.StatusOK, legacyprovision.Response{ - Success: true, - Status: "provisioning_data_received", - }) - - // Update user with SignalID - if resp.ProvisioningData.ACI != uuid.Nil { - user.saveSignalID(ctx, resp.ProvisioningData.ACI, resp.ProvisioningData.Number) - } - return - case <-time.After(45 * time.Second): - log.Warn().Msg("Timeout waiting for provisioning response (scan)") - // Using 400 here to match the old bridge - legacyprovision.JSONResponse(w, http.StatusBadRequest, legacyprovision.Error{ - Success: false, - Error: "Timeout waiting for QR code scan", - ErrCode: "M_BAD_REQUEST", - }) - return - } -} - -func (prov *ProvisioningAPI) LinkWaitForAccount(w http.ResponseWriter, r *http.Request) { - user := r.Context().Value(provisioningUserKey).(*User) - - var body legacyprovision.LinkWaitForAccountRequest - err := json.NewDecoder(r.Body).Decode(&body) - if err != nil { - legacyprovision.JSONResponse(w, http.StatusBadRequest, legacyprovision.Error{ - Success: false, - Error: "Error decoding JSON body", - ErrCode: "M_BAD_JSON", - }) - return - } - sessionID, err := strconv.Atoi(body.SessionID) - if err != nil { - legacyprovision.JSONResponse(w, http.StatusBadRequest, legacyprovision.Error{ - Success: false, - Error: "Error decoding session ID in JSON body", - ErrCode: "M_BAD_JSON", - }) - return - } - deviceName := body.DeviceName - - log := prov.log.With(). - Str("action", "link_wait_for_account"). - Stringer("user_id", user.MXID). - Int("session_id", sessionID). - Str("device_name", deviceName). - Logger() - ctx := log.WithContext(r.Context()) - log.Debug().Msg("waiting for account") - - handle := prov.checkSessionAndReturnHandle(ctx, w, sessionID) - if handle == nil { - return - } - - select { - case resp := <-handle.channel: - if resp.Err != nil || resp.State == signalmeow.StateProvisioningError { - log.Err(resp.Err).Msg("Error waiting for account") - legacyprovision.JSONResponse(w, http.StatusInternalServerError, legacyprovision.Error{ - Success: false, - Error: resp.Err.Error(), - ErrCode: "M_INTERNAL", - }) - return - } - if resp.State != signalmeow.StateProvisioningPreKeysRegistered { - log.Err(resp.Err).Stringer("state", resp.State).Msg("unexpected state") - legacyprovision.JSONResponse(w, http.StatusInternalServerError, legacyprovision.Error{ - Success: false, - Error: fmt.Sprintf("Unexpected state %s", resp.State.String()), - ErrCode: "M_INTERNAL", - }) - return - } - - log.Debug().Msg("prekeys registered") - legacyprovision.JSONResponse(w, http.StatusOK, legacyprovision.Response{ - Success: true, - Status: "prekeys_registered", - UUID: user.SignalID.String(), - Number: user.SignalUsername, - }) - - // Connect to Signal!! - user.Connect() - return - case <-time.After(30 * time.Second): - log.Warn().Msg("Timeout waiting for provisioning response (account)") - legacyprovision.JSONResponse(w, http.StatusGatewayTimeout, legacyprovision.Error{ - Success: false, - Error: "Timeout waiting for provisioning response (account)", - ErrCode: "M_TIMEOUT", - }) - return - } -} - -func (prov *ProvisioningAPI) Logout(w http.ResponseWriter, r *http.Request) { - user := r.Context().Value(provisioningUserKey).(*User) - log := prov.log.With(). - Str("action", "logout"). - Stringer("user_id", user.MXID). - Logger() - ctx := log.WithContext(r.Context()) - log.Debug().Msg("Logout called (but not logging out)") - - prov.clearSession(ctx, user) - - // For now do nothing - we need this API to return 200 to be compatible with - // the old Signal bridge, which needed a call to Logout before allowing LinkNew - // to be called, but we don't actually want to logout, we want to allow a reconnect. - legacyprovision.JSONResponse(w, http.StatusOK, legacyprovision.Response{ - Success: true, - Status: "logged_out", - }) -} diff --git a/puppet.go b/puppet.go deleted file mode 100644 index 857312e..0000000 --- a/puppet.go +++ /dev/null @@ -1,411 +0,0 @@ -// mautrix-signal - A Matrix-signal puppeting bridge. -// Copyright (C) 2023 Scott Weber -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see . - -package main - -import ( - "context" - "crypto/sha256" - "encoding/hex" - "fmt" - "net/http" - "regexp" - - "github.com/google/uuid" - "github.com/rs/zerolog" - "maunium.net/go/mautrix" - "maunium.net/go/mautrix/appservice" - "maunium.net/go/mautrix/bridge" - "maunium.net/go/mautrix/id" - - "go.mau.fi/mautrix-signal/database" - "go.mau.fi/mautrix-signal/pkg/signalmeow/types" -) - -func (br *SignalBridge) GetPuppetByMXID(mxid id.UserID) *Puppet { - signalID, ok := br.ParsePuppetMXID(mxid) - if !ok { - return nil - } - - return br.GetPuppetBySignalID(signalID) -} - -func (br *SignalBridge) GetPuppetBySignalIDString(id string) *Puppet { - parsed, err := uuid.Parse(id) - if err != nil { - return nil - } - return br.GetPuppetBySignalID(parsed) -} - -func (br *SignalBridge) GetPuppetBySignalID(id uuid.UUID) *Puppet { - if id == uuid.Nil { - br.ZLog.Warn().Msg("Trying to get puppet with empty signal_user_id") - return nil - } - - br.puppetsLock.Lock() - defer br.puppetsLock.Unlock() - - puppet, ok := br.puppets[id] - if !ok { - dbPuppet, err := br.DB.Puppet.GetBySignalID(context.TODO(), id) - if err != nil { - br.ZLog.Err(err).Msg("Failed to get puppet from database") - return nil - } - return br.loadPuppet(context.TODO(), dbPuppet, &id) - } - return puppet -} - -func (br *SignalBridge) GetPuppetByCustomMXID(mxid id.UserID) *Puppet { - br.puppetsLock.Lock() - defer br.puppetsLock.Unlock() - - puppet, ok := br.puppetsByCustomMXID[mxid] - if !ok { - dbPuppet, err := br.DB.Puppet.GetByCustomMXID(context.TODO(), mxid) - if err != nil { - br.ZLog.Err(err).Msg("Failed to get puppet from database") - return nil - } - return br.loadPuppet(context.TODO(), dbPuppet, nil) - } - return puppet -} - -func (br *SignalBridge) GetAllPuppetsWithCustomMXID() []*Puppet { - puppets, err := br.DB.Puppet.GetAllWithCustomMXID(context.TODO()) - if err != nil { - br.ZLog.Error().Err(err).Msg("Failed to get all puppets with custom MXID") - return nil - } - return br.dbPuppetsToPuppets(puppets) -} - -func (br *SignalBridge) FormatPuppetMXID(u uuid.UUID) id.UserID { - return id.NewUserID( - br.Config.Bridge.FormatUsername(u.String()), - br.Config.Homeserver.Domain, - ) -} - -func (br *SignalBridge) loadPuppet(ctx context.Context, dbPuppet *database.Puppet, u *uuid.UUID) *Puppet { - if dbPuppet == nil { - if u == nil { - return nil - } - dbPuppet = br.DB.Puppet.New() - dbPuppet.SignalID = *u - err := dbPuppet.Insert(ctx) - if err != nil { - br.ZLog.Error().Err(err).Stringer("signal_user_id", *u).Msg("Failed to insert new puppet") - return nil - } - } - - puppet := br.NewPuppet(dbPuppet) - br.puppets[puppet.SignalID] = puppet - if puppet.CustomMXID != "" { - br.puppetsByCustomMXID[puppet.CustomMXID] = puppet - } - return puppet -} - -func (br *SignalBridge) dbPuppetsToPuppets(dbPuppets []*database.Puppet) []*Puppet { - br.puppetsLock.Lock() - defer br.puppetsLock.Unlock() - - output := make([]*Puppet, len(dbPuppets)) - for index, dbPuppet := range dbPuppets { - if dbPuppet == nil { - continue - } - puppet, ok := br.puppets[dbPuppet.SignalID] - if !ok { - puppet = br.loadPuppet(context.TODO(), dbPuppet, nil) - } - output[index] = puppet - } - return output -} - -func (br *SignalBridge) NewPuppet(dbPuppet *database.Puppet) *Puppet { - return &Puppet{ - Puppet: dbPuppet, - bridge: br, - log: br.ZLog.With().Stringer("signal_user_id", dbPuppet.SignalID).Logger(), - - MXID: br.FormatPuppetMXID(dbPuppet.SignalID), - } -} - -func (br *SignalBridge) ParsePuppetMXID(mxid id.UserID) (uuid.UUID, bool) { - if userIDRegex == nil { - pattern := fmt.Sprintf( - "^@%s:%s$", - // The "SignalID" portion of the MXID is a (lowercase) UUID - br.Config.Bridge.FormatUsername("([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})"), - br.Config.Homeserver.Domain, - ) - br.ZLog.Debug().Str("pattern", pattern).Msg("Compiling userIDRegex") - - userIDRegex = regexp.MustCompile(pattern) - } - - match := userIDRegex.FindStringSubmatch(string(mxid)) - if len(match) == 2 { - parsed, err := uuid.Parse(match[1]) - if err != nil { - return uuid.Nil, false - } - return parsed, true - } - - return uuid.Nil, false -} - -type Puppet struct { - *database.Puppet - - bridge *SignalBridge - log zerolog.Logger - - MXID id.UserID - - customIntent *appservice.IntentAPI - customUser *User -} - -var userIDRegex *regexp.Regexp - -var ( - _ bridge.Ghost = (*Puppet)(nil) - _ bridge.GhostWithProfile = (*Puppet)(nil) -) - -func (puppet *Puppet) GetMXID() id.UserID { - return puppet.MXID -} - -func (puppet *Puppet) DefaultIntent() *appservice.IntentAPI { - return puppet.bridge.AS.Intent(puppet.MXID) -} - -func (puppet *Puppet) CustomIntent() *appservice.IntentAPI { - if puppet == nil { - return nil - } - return puppet.customIntent -} - -func (puppet *Puppet) IntentFor(portal *Portal) *appservice.IntentAPI { - if puppet != nil { - if puppet.customIntent == nil || portal.UserID().UUID == puppet.SignalID { - return puppet.DefaultIntent() - } - return puppet.customIntent - } - return nil -} - -func (puppet *Puppet) GetDisplayname() string { - return puppet.Name -} - -func (puppet *Puppet) GetAvatarURL() id.ContentURI { - return puppet.AvatarURL -} - -func (puppet *Puppet) UpdateInfo(ctx context.Context, source *User, contactAvatar *types.ContactAvatar) { - log := zerolog.Ctx(ctx).With(). - Str("function", "Puppet.UpdateInfo"). - Stringer("signal_user_id", puppet.SignalID). - Logger() - ctx = log.WithContext(ctx) - var err error - log.Debug().Msg("Fetching contact info to update puppet") - info, err := source.Client.ContactByACI(ctx, puppet.SignalID) - if err != nil { - log.Err(err).Msg("Failed to fetch contact info") - return - } - if !puppet.bridge.Config.Bridge.UseOutdatedProfiles && puppet.ProfileFetchedAt.After(info.Profile.FetchedAt) { - log.Debug(). - Time("contact_profile_fetched_at", info.Profile.FetchedAt). - Time("puppet_profile_fetched_at", puppet.ProfileFetchedAt). - Msg("Ignoring outdated contact info") - return - } - if contactAvatar != nil { - info.ContactAvatar = *contactAvatar - } - - log.Trace().Msg("Updating puppet info") - - update := false - if puppet.ProfileFetchedAt.IsZero() && !info.Profile.FetchedAt.IsZero() { - update = true - } - puppet.ProfileFetchedAt = info.Profile.FetchedAt - if info.E164 != "" && puppet.Number != info.E164 { - puppet.Number = info.E164 - update = true - } - update = puppet.updateName(ctx, info) || update - update = puppet.updateAvatar(ctx, source, info) || update - if update { - puppet.ContactInfoSet = false - puppet.UpdateContactInfo(ctx) - err = puppet.Update(ctx) - if err != nil { - log.Err(err).Msg("Failed to save puppet to database after updating") - } - go puppet.updatePortalMeta(ctx) - log.Debug().Msg("Puppet info updated") - } -} -func (puppet *Puppet) UpdateContactInfo(ctx context.Context) { - if !puppet.bridge.SpecVersions.Supports(mautrix.BeeperFeatureArbitraryProfileMeta) || puppet.ContactInfoSet { - return - } - - identifiers := []string{ - fmt.Sprintf("signal:%s", puppet.SignalID), - } - if puppet.Number != "" { - identifiers = append(identifiers, fmt.Sprintf("tel:%s", puppet.Number)) - } - contactInfo := map[string]any{ - "com.beeper.bridge.identifiers": identifiers, - "com.beeper.bridge.remote_id": puppet.SignalID.String(), - "com.beeper.bridge.service": "signal", - "com.beeper.bridge.network": "signal", - } - err := puppet.DefaultIntent().BeeperUpdateProfile(ctx, contactInfo) - if err != nil { - zerolog.Ctx(ctx).Err(err).Msg("Failed to store custom contact info in profile") - } else { - puppet.ContactInfoSet = true - } -} - -func (puppet *Puppet) updatePortalMeta(ctx context.Context) { - for _, portal := range puppet.bridge.FindPrivateChatPortalsWith(puppet.SignalID) { - // Get room create lock to prevent races between receiving contact info and room creation. - portal.roomCreateLock.Lock() - portal.UpdateDMInfo(ctx, false) - portal.roomCreateLock.Unlock() - } -} - -func (puppet *Puppet) updateAvatar(ctx context.Context, source *User, info *types.Recipient) bool { - var avatarData []byte - var avatarContentType string - log := zerolog.Ctx(ctx) - if puppet.bridge.Config.Bridge.UseContactAvatars && info.ContactAvatar.Hash != "" { - if puppet.AvatarHash == info.ContactAvatar.Hash && puppet.AvatarSet { - return false - } - avatarData = info.ContactAvatar.Image - avatarContentType = info.ContactAvatar.ContentType - if avatarData == nil { - // TODO what to do? 🤔 - return false - } - puppet.AvatarSet = false - puppet.AvatarPath = "" - } else { - if puppet.AvatarPath == info.Profile.AvatarPath && puppet.AvatarSet { - return false - } - if info.Profile.AvatarPath == "" { - puppet.AvatarURL = id.ContentURI{} - puppet.AvatarPath = "" - puppet.AvatarHash = "" - puppet.AvatarSet = false - err := puppet.DefaultIntent().SetAvatarURL(ctx, puppet.AvatarURL) - if err != nil { - log.Err(err).Msg("Failed to remove user avatar") - return true - } - log.Debug().Msg("Avatar removed") - puppet.AvatarSet = true - return true - } - var err error - avatarData, err = source.Client.DownloadUserAvatar(ctx, info.Profile.AvatarPath, info.Profile.Key) - if err != nil { - log.Err(err). - Str("profile_avatar_path", info.Profile.AvatarPath). - Msg("Failed to download new user avatar") - return true - } - avatarContentType = http.DetectContentType(avatarData) - } - hash := sha256.Sum256(avatarData) - newHash := hex.EncodeToString(hash[:]) - if puppet.AvatarHash == newHash && puppet.AvatarSet { - log.Debug(). - Str("avatar_hash", newHash). - Str("new_avatar_path", puppet.AvatarPath). - Msg("Avatar path changed, but hash didn't") - // Path changed, but actual avatar didn't - return true - } - puppet.AvatarPath = info.Profile.AvatarPath - puppet.AvatarHash = newHash - puppet.AvatarSet = false - puppet.AvatarURL = id.ContentURI{} - resp, err := puppet.DefaultIntent().UploadBytes(ctx, avatarData, avatarContentType) - if err != nil { - log.Err(err). - Str("avatar_hash", puppet.AvatarHash). - Msg("Failed to upload new user avatar") - return true - } - puppet.AvatarURL = resp.ContentURI - err = puppet.DefaultIntent().SetAvatarURL(ctx, puppet.AvatarURL) - if err != nil { - log.Err(err).Msg("Failed to update user avatar") - return true - } - log.Debug(). - Str("avatar_hash", newHash). - Stringer("avatar_mxc", resp.ContentURI). - Msg("Avatar updated successfully") - puppet.AvatarSet = true - return true -} - -func (puppet *Puppet) updateName(ctx context.Context, contact *types.Recipient) bool { - // TODO set name quality - newName := puppet.bridge.Config.Bridge.FormatDisplayname(contact) - if puppet.NameSet && puppet.Name == newName { - return false - } - puppet.Name = newName - puppet.NameSet = false - err := puppet.DefaultIntent().SetDisplayName(ctx, newName) - if err != nil { - zerolog.Ctx(ctx).Err(err).Msg("Failed to update user displayname") - } else { - puppet.NameSet = true - } - return true -} diff --git a/user.go b/user.go deleted file mode 100644 index dc16f98..0000000 --- a/user.go +++ /dev/null @@ -1,1020 +0,0 @@ -// mautrix-signal - A Matrix-signal puppeting bridge. -// Copyright (C) 2023 Scott Weber -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see . - -package main - -import ( - "context" - "errors" - "fmt" - "net/http" - "strings" - "sync" - "time" - - "github.com/google/uuid" - "github.com/rs/zerolog" - "golang.org/x/exp/maps" - "maunium.net/go/mautrix" - "maunium.net/go/mautrix/appservice" - "maunium.net/go/mautrix/bridge" - "maunium.net/go/mautrix/bridge/bridgeconfig" - "maunium.net/go/mautrix/bridge/status" - "maunium.net/go/mautrix/event" - "maunium.net/go/mautrix/id" - - "go.mau.fi/mautrix-signal/database" - "go.mau.fi/mautrix-signal/pkg/libsignalgo" - "go.mau.fi/mautrix-signal/pkg/signalmeow" - "go.mau.fi/mautrix-signal/pkg/signalmeow/events" - signalpb "go.mau.fi/mautrix-signal/pkg/signalmeow/protobuf" -) - -var ( - ErrNotConnected = errors.New("not connected") - ErrNotLoggedIn = errors.New("not logged in") -) - -func (br *SignalBridge) GetUserByMXID(userID id.UserID) *User { - return br.maybeGetUserByMXID(userID, &userID) -} - -func (br *SignalBridge) GetUserByMXIDIfExists(userID id.UserID) *User { - return br.maybeGetUserByMXID(userID, nil) -} - -func (br *SignalBridge) maybeGetUserByMXID(userID id.UserID, userIDPtr *id.UserID) *User { - if userID == br.Bot.UserID || br.IsGhost(userID) { - return nil - } - br.usersLock.Lock() - defer br.usersLock.Unlock() - - user, ok := br.usersByMXID[userID] - if !ok { - dbUser, err := br.DB.User.GetByMXID(context.TODO(), userID) - if err != nil { - br.ZLog.Err(err).Msg("Failed to get user from database") - return nil - } - return br.loadUser(context.TODO(), dbUser, userIDPtr) - } - return user -} - -func (br *SignalBridge) GetUserBySignalID(id uuid.UUID) *User { - br.usersLock.Lock() - defer br.usersLock.Unlock() - return br.unlockedGetUserBySignalID(id) -} - -func (br *SignalBridge) unlockedGetUserBySignalID(id uuid.UUID) *User { - user, ok := br.usersBySignalID[id] - if !ok { - dbUser, err := br.DB.User.GetBySignalID(context.TODO(), id) - if err != nil { - br.ZLog.Err(err).Msg("Failed to get user from database") - return nil - } - return br.loadUser(context.TODO(), dbUser, nil) - } - return user -} - -func (br *SignalBridge) GetAllLoggedInUsers() []*User { - br.usersLock.Lock() - defer br.usersLock.Unlock() - - dbUsers, err := br.DB.User.GetAllLoggedIn(context.TODO()) - if err != nil { - br.ZLog.Err(err).Msg("Error getting all logged in users") - return nil - } - users := make([]*User, len(dbUsers)) - - for idx, dbUser := range dbUsers { - user, ok := br.usersByMXID[dbUser.MXID] - if !ok { - user = br.loadUser(context.TODO(), dbUser, nil) - } - users[idx] = user - } - return users -} - -func (br *SignalBridge) loadUser(ctx context.Context, dbUser *database.User, mxid *id.UserID) *User { - if dbUser == nil { - if mxid == nil { - return nil - } - dbUser = br.DB.User.New() - dbUser.MXID = *mxid - err := dbUser.Insert(ctx) - if err != nil { - br.ZLog.Err(err).Msg("Error creating user %s") - return nil - } - } - - user := br.NewUser(dbUser) - br.usersByMXID[user.MXID] = user - if user.SignalID != uuid.Nil { - br.usersBySignalID[user.SignalID] = user - } - if user.ManagementRoom != "" { - br.managementRoomsLock.Lock() - br.managementRooms[user.ManagementRoom] = user - br.managementRoomsLock.Unlock() - } - return user -} - -func (br *SignalBridge) NewUser(dbUser *database.User) *User { - user := &User{ - User: dbUser, - bridge: br, - log: br.ZLog.With().Stringer("user_id", dbUser.MXID).Logger(), - - PermissionLevel: br.Config.Bridge.Permissions.Get(dbUser.MXID), - } - user.Admin = user.PermissionLevel >= bridgeconfig.PermissionLevelAdmin - user.BridgeState = br.NewBridgeStateQueue(user) - return user -} - -type User struct { - *database.User - - sync.Mutex - - bridge *SignalBridge - log zerolog.Logger - - Admin bool - PermissionLevel bridgeconfig.PermissionLevel - - Client *signalmeow.Client - - BridgeState *bridge.BridgeStateQueue - - spaceMembershipChecked bool - spaceCreateLock sync.Mutex -} - -var ( - _ bridge.User = (*User)(nil) - _ status.BridgeStateFiller = (*User)(nil) -) - -func (user *User) GetPermissionLevel() bridgeconfig.PermissionLevel { - return user.PermissionLevel -} - -func (user *User) IsLoggedIn() bool { - user.Lock() - defer user.Unlock() - - return user.Client != nil && user.Client.IsLoggedIn() -} - -func (user *User) GetManagementRoomID() id.RoomID { - return user.ManagementRoom -} - -func (user *User) SetManagementRoom(roomID id.RoomID) { - user.bridge.managementRoomsLock.Lock() - defer user.bridge.managementRoomsLock.Unlock() - - existing, ok := user.bridge.managementRooms[roomID] - if ok { - existing.ManagementRoom = "" - err := existing.Update(context.TODO()) - if err != nil { - existing.log.Err(err).Msg("Failed to update user when removing management room") - } - } - - user.ManagementRoom = roomID - user.bridge.managementRooms[user.ManagementRoom] = user - err := user.Update(context.TODO()) - if err != nil { - user.log.Error().Err(err).Msg("Error setting management room") - } -} - -func (user *User) GetIDoublePuppet() bridge.DoublePuppet { - p := user.bridge.GetPuppetByCustomMXID(user.MXID) - if p == nil || p.CustomIntent() == nil { - return nil - } - return p -} - -func (user *User) GetIGhost() bridge.Ghost { - p := user.bridge.GetPuppetBySignalID(user.SignalID) - if p == nil { - return nil - } - return p -} - -func (user *User) ensureInvited(ctx context.Context, intent *appservice.IntentAPI, roomID id.RoomID, isDirect bool) (ok bool) { - log := user.log.With().Str("action", "ensure_invited").Stringer("room_id", roomID).Logger() - if user.bridge.StateStore.IsMembership(ctx, roomID, user.MXID, event.MembershipJoin) { - ok = true - return - } - extraContent := make(map[string]interface{}) - if isDirect { - extraContent["is_direct"] = true - } - customPuppet := user.bridge.GetPuppetByCustomMXID(user.MXID) - if customPuppet != nil && customPuppet.CustomIntent() != nil { - extraContent["fi.mau.will_auto_accept"] = true - } - _, err := intent.InviteUser(ctx, roomID, &mautrix.ReqInviteUser{UserID: user.MXID}, extraContent) - var httpErr mautrix.HTTPError - if err != nil && errors.As(err, &httpErr) && httpErr.RespError != nil && strings.Contains(httpErr.RespError.Err, "is already in the room") { - err = user.bridge.StateStore.SetMembership(ctx, roomID, user.MXID, event.MembershipJoin) - if err != nil { - log.Warn().Err(err).Msg("Failed to update membership in state store") - } - ok = true - return - } else if err != nil { - log.Warn().Err(err).Msg("Failed to invite user to room") - } else { - ok = true - } - - if customPuppet != nil && customPuppet.CustomIntent() != nil { - err = customPuppet.CustomIntent().EnsureJoined(ctx, roomID, appservice.EnsureJoinedParams{IgnoreCache: true}) - if err != nil { - log.Warn().Err(err).Msg("Failed to auto-join custom puppet") - ok = false - } else { - ok = true - } - } - return -} - -func (user *User) GetSpaceRoom(ctx context.Context) id.RoomID { - if !user.bridge.Config.Bridge.PersonalFilteringSpaces { - return "" - } - - if len(user.SpaceRoom) == 0 { - user.spaceCreateLock.Lock() - defer user.spaceCreateLock.Unlock() - if len(user.SpaceRoom) > 0 { - return user.SpaceRoom - } - - resp, err := user.bridge.Bot.CreateRoom(ctx, &mautrix.ReqCreateRoom{ - Visibility: "private", - Name: "Signal", - Topic: "Your Signal bridged chats", - InitialState: []*event.Event{{ - Type: event.StateRoomAvatar, - Content: event.Content{ - Parsed: &event.RoomAvatarEventContent{ - URL: user.bridge.Config.AppService.Bot.ParsedAvatar.CUString(), - }, - }, - }}, - CreationContent: map[string]interface{}{ - "type": event.RoomTypeSpace, - }, - PowerLevelOverride: &event.PowerLevelsEventContent{ - Users: map[id.UserID]int{ - user.bridge.Bot.UserID: 9001, - user.MXID: 50, - }, - }, - }) - - if err != nil { - user.log.Err(err).Msg("Failed to auto-create space room") - } else { - user.SpaceRoom = resp.RoomID - err = user.Update(context.TODO()) - if err != nil { - user.log.Err(err).Msg("Failed to save user in database after creating space room") - } - user.ensureInvited(ctx, user.bridge.Bot, user.SpaceRoom, false) - } - } else if !user.spaceMembershipChecked { - user.ensureInvited(ctx, user.bridge.Bot, user.SpaceRoom, false) - } - user.spaceMembershipChecked = true - - return user.SpaceRoom -} - -func (user *User) syncChatDoublePuppetDetails(portal *Portal, justCreated bool) { - doublePuppet := portal.bridge.GetPuppetByCustomMXID(user.MXID) - if doublePuppet == nil { - return - } - if doublePuppet == nil || doublePuppet.CustomIntent() == nil || len(portal.MXID) == 0 { - return - } - - // TODO: Get chat setting from Signal and sync them here - //if justCreated || !user.bridge.Config.Bridge.TagOnlyOnCreate { - // chat, err := user.Client.Store.ChatSettings.GetChatSettings(portal.Key().ChatID) - // if err != nil { - // user.log.Warn().Err(err).Msgf("Failed to get settings of %s", portal.Key().ChatID) - // return - // } - // intent := doublePuppet.CustomIntent() - // if portal.Key.JID == types.StatusBroadcastJID && justCreated { - // if user.bridge.Config.Bridge.MuteStatusBroadcast { - // user.updateChatMute(intent, portal, time.Now().Add(365*24*time.Hour)) - // } - // if len(user.bridge.Config.Bridge.StatusBroadcastTag) > 0 { - // user.updateChatTag(intent, portal, user.bridge.Config.Bridge.StatusBroadcastTag, true) - // } - // return - // } else if !chat.Found { - // return - // } - // user.updateChatMute(intent, portal, chat.MutedUntil) - // user.updateChatTag(intent, portal, user.bridge.Config.Bridge.ArchiveTag, chat.Archived) - // user.updateChatTag(intent, portal, user.bridge.Config.Bridge.PinnedTag, chat.Pinned) - //} -} - -func (user *User) GetMXID() id.UserID { - return user.MXID -} -func (user *User) GetRemoteID() string { - return user.SignalID.String() -} -func (user *User) GetRemoteName() string { - return user.SignalUsername -} - -func (user *User) startupTryConnect(retryCount int) { - user.BridgeState.Send(status.BridgeState{StateEvent: status.StateConnecting}) - - // Make sure user has the Signal device populated - user.populateSignalDevice() - - user.log.Debug().Msg("Connecting to Signal") - ctx := user.log.WithContext(context.Background()) - statusChan, err := user.Client.StartReceiveLoops(ctx) - - if err != nil { - user.log.Error().Err(err).Msg("Error connecting on startup") - if errors.Is(err, ErrNotLoggedIn) { - user.log.Warn().Msg("Not logged in, clearing Signal device keys") - user.BridgeState.Send(status.BridgeState{StateEvent: status.StateBadCredentials, Message: "You have been logged out of Signal, please reconnect"}) - user.clearKeysAndDisconnect() - } else if retryCount < 6 { - user.BridgeState.Send(status.BridgeState{StateEvent: status.StateTransientDisconnect, Error: "unknown-websocket-error", Message: err.Error()}) - retryInSeconds := 2 << retryCount - user.log.Debug().Int("retry_in_seconds", retryInSeconds).Msg("Sleeping and retrying connection") - time.Sleep(time.Duration(retryInSeconds) * time.Second) - user.startupTryConnect(retryCount + 1) - } else { - user.BridgeState.Send(status.BridgeState{StateEvent: status.StateUnknownError, Error: "unknown-websocket-error", Message: err.Error()}) - } - } - - if statusChan == nil { - user.log.Error().Msg("statusChan is nil after Connect") - return - } - // After Connect returns, all bridge states are triggered by events on the statusChan - go func() { - var peekedConnectionStatus signalmeow.SignalConnectionStatus - for { - var connectionStatus signalmeow.SignalConnectionStatus - if peekedConnectionStatus.Event != signalmeow.SignalConnectionEventNone { - user.log.Debug(). - Stringer("peeked_connection_status_event", peekedConnectionStatus.Event). - Msg("Using peeked connectionStatus event") - connectionStatus = peekedConnectionStatus - peekedConnectionStatus = signalmeow.SignalConnectionStatus{} - } else { - var ok bool - connectionStatus, ok = <-statusChan - if !ok { - user.log.Debug().Msg("statusChan channel closed") - return - } - } - - err := connectionStatus.Err - switch connectionStatus.Event { - case signalmeow.SignalConnectionEventConnected: - user.log.Debug().Msg("Sending Connected BridgeState") - user.BridgeState.Send(status.BridgeState{StateEvent: status.StateConnected}) - user.bridge.Metrics.TrackConnectionState(user.SignalID, true) - user.bridge.Metrics.TrackLoginState(user.SignalID, true) - - case signalmeow.SignalConnectionEventDisconnected: - user.log.Debug().Msg("Received SignalConnectionEventDisconnected") - - // Debounce: wait 7s before sending TransientDisconnect, in case we get a reconnect - // We should wait until the next message comes in, or 7 seconds has passed. - // - If a disconnected event comes in, just loop again, unless it's been more than 7 seconds. - // - If a non-disconnected event comes in, store it in peekedConnectionStatus, - // break out of this loop and go back to the top of the goroutine to handle it in the switch. - // - If 7 seconds passes without any non-disconnect messages, send the TransientDisconnect. - // (Why 7 seconds? It was 5 at first, but websockets min retry is 5 seconds, - // so it would send TransientDisconnect right before reconnecting. 7 seems to work well.) - debounceTimer := time.NewTimer(7 * time.Second) - PeekLoop: - for { - var ok bool - select { - case peekedConnectionStatus, ok = <-statusChan: - // Handle channel closing - if !ok { - user.log.Debug().Msg("connectionStatus channel closed") - return - } - // If it's another Disconnected event, just keep looping - if peekedConnectionStatus.Event == signalmeow.SignalConnectionEventDisconnected { - peekedConnectionStatus = signalmeow.SignalConnectionStatus{} - continue - } - // If it's a non-disconnect event, break out of the PeekLoop and handle it in the switch - break PeekLoop - case <-debounceTimer.C: - // Time is up, so break out of the loop and send the TransientDisconnect - break PeekLoop - } - } - // We're out of the PeekLoop, so either we got a non-disconnect event, or it's been 7 seconds (or both). - // We want to send TransientDisconnect if it's been 7 seconds, but not if the latest event was something - // other than Disconnected - if !debounceTimer.Stop() { // If the timer has already expired - // Send TransientDisconnect only if the latest event is a disconnect or no event - // (peekedConnectionStatus could be something else if the timer and the event race) - if peekedConnectionStatus.Event == signalmeow.SignalConnectionEventDisconnected || - peekedConnectionStatus.Event == signalmeow.SignalConnectionEventNone { - user.log.Debug().Msg("Sending TransientDisconnect BridgeState") - if err == nil { - user.BridgeState.Send(status.BridgeState{StateEvent: status.StateTransientDisconnect}) - } else { - user.BridgeState.Send(status.BridgeState{StateEvent: status.StateTransientDisconnect, Error: "unknown-websocket-error", Message: err.Error()}) - } - user.bridge.Metrics.TrackConnectionState(user.SignalID, false) - } - } - - case signalmeow.SignalConnectionEventLoggedOut: - user.log.Debug().Msg("Sending BadCredentials BridgeState") - if err == nil { - user.BridgeState.Send(status.BridgeState{StateEvent: status.StateBadCredentials, Message: "You have been logged out of Signal, please reconnect"}) - } else { - user.BridgeState.Send(status.BridgeState{StateEvent: status.StateBadCredentials, Message: err.Error()}) - } - user.bridge.Metrics.TrackConnectionState(user.SignalID, false) - user.bridge.Metrics.TrackLoginState(user.SignalID, false) - user.clearKeysAndDisconnect() - if managementRoom := user.GetManagementRoomID(); managementRoom != "" { - _, _ = user.bridge.Bot.SendText(ctx, managementRoom, "You've been logged out of Signal") - } - - case signalmeow.SignalConnectionEventError: - user.log.Debug().Msg("Sending UnknownError BridgeState") - user.BridgeState.Send(status.BridgeState{StateEvent: status.StateUnknownError, Error: "unknown-websocket-error", Message: err.Error()}) - user.bridge.Metrics.TrackConnectionState(user.SignalID, false) - - case signalmeow.SignalConnectionCleanShutdown: - if user.Client.IsLoggedIn() { - user.log.Debug().Msg("Clean Shutdown - sending no BridgeState") - } else { - user.log.Debug().Msg("Clean Shutdown, but logged out - Sending BadCredentials BridgeState") - user.BridgeState.Send(status.BridgeState{StateEvent: status.StateBadCredentials, Message: "You have been logged out of Signal, please reconnect"}) - } - user.bridge.Metrics.TrackConnectionState(user.SignalID, false) - } - } - }() -} - -func (user *User) clearKeysAndDisconnect() { - // We need to clear out keys associated with the Signal device that no longer has valid credentials - user.log.Debug().Msg("Clearing out Signal device keys") - err := user.Client.ClearKeysAndDisconnect(context.TODO()) - if err != nil { - user.log.Err(err).Msg("Error clearing device keys") - } -} - -func (br *SignalBridge) StartUsers() { - br.ZLog.Debug().Msg("Starting users") - - usersWithToken := br.GetAllLoggedInUsers() - for _, u := range usersWithToken { - device := u.populateSignalDevice() - if device == nil || !device.IsLoggedIn() { - br.ZLog.Warn().Stringer("user_id", u.MXID).Msg("No device found for user, skipping Connect and sending BadCredentials BridgeState") - u.BridgeState.Send(status.BridgeState{StateEvent: status.StateBadCredentials, Message: "You have been logged out of Signal, please reconnect"}) - continue - } - go u.Connect() - } - if len(usersWithToken) == 0 { - br.SendGlobalBridgeState(status.BridgeState{StateEvent: status.StateUnconfigured}.Fill(nil)) - } - - br.ZLog.Debug().Msg("Starting custom puppets") - for _, customPuppet := range br.GetAllPuppetsWithCustomMXID() { - go func(puppet *Puppet) { - br.ZLog.Debug().Stringer("user_id", puppet.CustomMXID).Msg("Starting custom puppet") - - if err := puppet.StartCustomMXID(true); err != nil { - puppet.log.Error().Err(err).Msg("Failed to start custom puppet") - } - }(customPuppet) - } -} - -func (user *User) Login() (<-chan signalmeow.ProvisioningResponse, error) { - user.Lock() - defer user.Unlock() - - provChan := signalmeow.PerformProvisioning(context.TODO(), user.bridge.MeowStore, user.bridge.Config.Signal.DeviceName) - - return provChan, nil -} - -func (user *User) Connect() { - user.startupTryConnect(0) -} - -func (user *User) saveSignalID(ctx context.Context, id uuid.UUID, number string) { - user.bridge.usersLock.Lock() - defer user.bridge.usersLock.Unlock() - if user.SignalID == id && user.SignalUsername == number { - return - } - if user.SignalID != id { - existingUser := user.bridge.unlockedGetUserBySignalID(id) - if existingUser != nil { - // TODO this doesn't clear the signal store properly - // the store also only has the uuid as primary key, even though it should have uuid + device id - zerolog.Ctx(ctx).Warn(). - Stringer("previous_user", existingUser.MXID). - Stringer("signal_uuid", id). - Msg("Another user is already logged in with same UUID, logging out previous user") - existingUser.bridge.Metrics.TrackLoginState(user.SignalID, false) - _ = existingUser.Disconnect() - existingUser.SignalID = uuid.Nil - existingUser.SignalUsername = "" - err := existingUser.Update(ctx) - if err != nil { - zerolog.Ctx(ctx).Err(err).Msg("Failed to clear previous user's signal UUID") - } - } - } - user.SignalID = id - user.SignalUsername = number - user.bridge.usersBySignalID[id] = user - err := user.Update(ctx) - if err != nil { - zerolog.Ctx(ctx).Err(err).Msg("Failed to save user's signal UUID") - } -} - -func (user *User) populateSignalDevice() *signalmeow.Client { - user.Lock() - defer user.Unlock() - log := user.log.With(). - Str("action", "populate signal device"). - Stringer("signal_id", user.SignalID). - Logger() - - if user.SignalID == uuid.Nil { - return nil - } - // TODO clear client on logout properly so that populating can skip creating if it already exists - /*else if user.Client != nil { - return user.Client - }*/ - - device, err := user.bridge.MeowStore.DeviceByACI(context.TODO(), user.SignalID) - if err != nil { - log.Err(err).Msg("Failed to get device from database") - return nil - } else if device == nil { - log.Err(ErrNotLoggedIn).Msg("No device found for user") - return nil - } - - user.Client = &signalmeow.Client{ - Store: device, - EventHandler: user.eventHandler, - } - go user.tryAutomaticDoublePuppeting() - return user.Client -} - -func (user *User) handleReceipt(evt *events.Receipt) { - log := user.log.With(). - Str("action", "handle receipt"). - Stringer("receipt_type", evt.Content.GetType()). - Stringer("sender_uuid", evt.Sender). - Logger() - ctx := log.WithContext(context.TODO()) - messages, err := user.bridge.DB.Message.GetManyBySignalID(ctx, user.SignalID, evt.Content.GetTimestamp(), user.SignalID, false) - if err != nil { - log.Err(err).Msg("Failed to get receipt target messages from database") - return - } - sender := user.bridge.GetPuppetBySignalID(evt.Sender) - missingMessageIDMap := make(map[uint64]struct{}, len(evt.Content.GetTimestamp())) - for _, msg := range evt.Content.GetTimestamp() { - missingMessageIDMap[msg] = struct{}{} - } - foundMessageIDs := make([]uint64, len(messages)) - switch evt.Content.GetType() { - case signalpb.ReceiptMessage_READ: - messageMap := make(map[string]*database.Message) - for i, msg := range messages { - foundMessageIDs[i] = msg.Timestamp - delete(missingMessageIDMap, msg.Timestamp) - // The database returns messages from newest to oldest, so only include the first message per chat - _, ok := messageMap[msg.SignalChatID] - if !ok { - messageMap[msg.SignalChatID] = msg - } - } - log.Debug(). - Uints64("found_message_ids", foundMessageIDs). - Uints64("not_found_message_ids", maps.Keys(missingMessageIDMap)). - Int("chat_count", len(messageMap)). - Msg("Received read receipt") - for _, msg := range messageMap { - portal := user.GetPortalByChatID(msg.SignalChatID) - if portal == nil { - continue - } - err = portal.SendReadReceipt(ctx, sender, msg) - if err != nil { - log.Err(err).Msg("Failed to send read receipt") - } - } - case signalpb.ReceiptMessage_DELIVERY: - messageMap := make(map[string][]*database.Message) - for i, msg := range messages { - foundMessageIDs[i] = msg.Timestamp - delete(missingMessageIDMap, msg.Timestamp) - messageMap[msg.SignalChatID] = append(messageMap[msg.SignalChatID], msg) - } - log.Debug(). - Uints64("found_message_ids", foundMessageIDs). - Uints64("not_found_message_ids", maps.Keys(missingMessageIDMap)). - Int("chat_count", len(messageMap)). - Msg("Received delivery receipt") - for _, msgs := range messageMap { - portal := user.GetPortalByChatID(msgs[0].SignalChatID) - if portal == nil { - continue - } - // There should always only be 1 part, but use the last part to be safe - portal.MarkDelivered(ctx, msgs[len(msgs)-1]) - } - } -} - -func (user *User) handleReadSelf(evt *events.ReadSelf) { - ctx := context.TODO() - messagesByChat := map[string]*database.Message{} - for _, part := range evt.Messages { - log := user.log.With(). - Str("action", "handle read self"). - Str("sender_uuid", part.GetSenderAci()). - Uint64("msg_timestamp", part.GetTimestamp()). - Logger() - ctx := log.WithContext(context.TODO()) - if senderUUID, err := uuid.Parse(part.GetSenderAci()); err != nil { - log.Err(err).Msg("Failed to parse sender UUID") - } else if msg, err := user.bridge.DB.Message.GetLastPartBySignalIDWithUnknownReceiver(ctx, senderUUID, part.GetTimestamp(), user.SignalID); err != nil { - log.Err(err).Msg("Failed to get message from database") - } else if msg == nil { - log.Warn().Msg("Message not found in database") - } else if existingMsg, ok := messagesByChat[msg.SignalChatID]; ok && existingMsg.Timestamp > msg.Timestamp { - log.Trace(). - Str("chat_id", msg.SignalChatID). - Uint64("newer_msg", existingMsg.Timestamp). - Msg("Receipt event contains a newer message, skipping this one") - } else { - log.Trace().Str("chat_id", msg.SignalChatID).Msg("Received own read receipt") - messagesByChat[msg.SignalChatID] = msg - } - } - puppet := user.bridge.GetPuppetBySignalID(user.SignalID) - for _, msg := range messagesByChat { - portal := user.GetPortalByChatID(msg.SignalChatID) - if portal == nil { - continue - } - user.log.Debug(). - Str("action", "handle read self"). - Str("chat_id", msg.SignalChatID). - Uint64("msg_timestamp", msg.Timestamp). - Stringer("msg_mxid", msg.MXID). - Msg("Bridging own read receipt") - portal.ScheduleDisappearing() - user.SetLastReadTS(ctx, portal.PortalKey, msg.Timestamp) - err := portal.SendReadReceipt(ctx, puppet, msg) - if err != nil { - user.log.Err(err).Stringer("mxid", msg.MXID).Msg("Failed to send read receipt") - } - } -} - -func (user *User) handleContactList(evt *events.ContactList) { - ctx := user.log.With().Str("action", "handle contact list").Logger().WithContext(context.TODO()) - for _, contact := range evt.Contacts { - if contact.ACI == uuid.Nil { - continue - } - puppet := user.bridge.GetPuppetBySignalID(contact.ACI) - if puppet == nil { - continue - } - puppet.UpdateInfo(ctx, user, &contact.ContactAvatar) - } -} - -func (user *User) handleACIFound(evt *events.ACIFound) { - log := user.log.With(). - Str("action", "handle aci found"). - Stringer("aci", evt.ACI.UUID). - Stringer("pni", evt.PNI.UUID). - Logger() - log.Debug().Msg("Handling ACI found event") - defer func() { - log.Debug().Msg("Finished handling ACI found event") - }() - ctx := log.WithContext(context.TODO()) - user.bridge.portalsLock.Lock() - defer user.bridge.portalsLock.Unlock() - pniPortal := user.bridge.unlockedGetPortalByChatID(database.PortalKey{ - ChatID: evt.PNI.String(), - Receiver: user.SignalID, - }, false) - if pniPortal == nil { - log.Debug().Msg("PNI portal doesn't exist, ignoring event") - return - } - pniPortal.roomCreateLock.Lock() - defer pniPortal.roomCreateLock.Unlock() - if pniPortal.MXID == "" { - log.Info().Msg("PNI portal doesn't have Matrix room, deleting row") - pniPortal.unlockedDelete() - return - } - log.UpdateContext(func(c zerolog.Context) zerolog.Context { - return c.Stringer("pni_portal_mxid", pniPortal.MXID) - }) - aciPortal := user.bridge.unlockedGetPortalByChatID(database.PortalKey{ - ChatID: evt.ACI.String(), - Receiver: user.SignalID, - }, false) - if aciPortal == nil { - log.Info().Msg("ACI portal doesn't exist, re-ID'ing PNI portal") - err := pniPortal.unlockedReID(ctx, evt.ACI.String()) - if err != nil { - log.Err(err).Msg("Failed to re-ID PNI portal") - } else { - go pniPortal.PostReIDUpdate(ctx, user) - } - return - } - aciPortal.roomCreateLock.Lock() - defer aciPortal.roomCreateLock.Unlock() - if aciPortal.MXID == "" { - log.Info().Msg("ACI portal row exists, but doesn't have a Matrix room. Deleting ACI portal row and re-ID'ing PNI portal") - aciPortal.unlockedDelete() - err := pniPortal.unlockedReID(ctx, evt.ACI.String()) - if err != nil { - log.Err(err).Msg("Failed to re-ID PNI portal") - } else { - go pniPortal.PostReIDUpdate(ctx, user) - } - } else { - log.UpdateContext(func(c zerolog.Context) zerolog.Context { - return c.Stringer("aci_portal_mxid", aciPortal.MXID) - }) - log.Info().Msg("Both ACI and PNI portal have Matrix room, tombstoning PNI portal") - pniPortal.unlockedDelete() - go func() { - _, err := pniPortal.MainIntent().SendStateEvent(ctx, pniPortal.MXID, event.StateTombstone, "", &event.TombstoneEventContent{ - Body: fmt.Sprintf("This room has been merged"), - ReplacementRoom: aciPortal.MXID, - }) - if err != nil { - log.Err(err).Msg("Failed to send tombstone to PNI portal") - } - pniPortal.Cleanup(ctx, err == nil) - }() - } -} - -func (portal *Portal) unlockedReID(ctx context.Context, newID string) error { - err := portal.Portal.ReID(ctx, newID) - if err != nil { - return err - } - delete(portal.bridge.portalsByID, portal.PortalKey) - portal.PortalKey.ChatID = newID - portal.bridge.portalsByID[portal.PortalKey] = portal - err = portal.MainIntent().EnsureJoined(ctx, portal.MXID, appservice.EnsureJoinedParams{IgnoreCache: true}) - if err != nil { - return fmt.Errorf("failed to ensure ghost is joined to portal: %w", err) - } - return nil -} - -func (user *User) eventHandler(rawEvt events.SignalEvent) { - switch evt := rawEvt.(type) { - case *events.ChatEvent: - portal := user.GetPortalByChatID(evt.Info.ChatID) - if portal != nil { - portal.signalMessages <- portalSignalMessage{user: user, evt: evt} - } else { - user.log.Warn().Str("chat_id", evt.Info.ChatID).Msg("Couldn't get portal, dropping message") - } - case *events.DecryptionError: - portal := user.GetPortalByChatID(evt.Sender.String()) - if portal == nil { - user.log.Warn().Stringer("chat_id", evt.Sender).Msg("Couldn't get portal for decryption error") - return - } - content := &event.MessageEventContent{MsgType: event.MsgNotice} - name := user.bridge.GetPuppetBySignalID(evt.Sender).Name - if name == "" { - name = "This user" - } - content.Body = fmt.Sprintf("%s sent a message that couldn't be decrypted. It may have been in this chat or a group chat. Please check your Signal app", name) - portal.sendMainIntentMessage(context.TODO(), content) - case *events.Receipt: - user.handleReceipt(evt) - case *events.ReadSelf: - user.handleReadSelf(evt) - case *events.Call: - portal := user.GetPortalByChatID(evt.Info.ChatID) - content := &event.MessageEventContent{MsgType: event.MsgNotice} - if evt.IsRinging { - content.Body = "Incoming call" - if portal.IsPrivateChat() { - content.MsgType = event.MsgText - } - } else { - content.Body = "Call ended" - } - portal.sendMainIntentMessage(context.TODO(), content) - case *events.ContactList: - user.handleContactList(evt) - case *events.ACIFound: - user.handleACIFound(evt) - default: - user.log.Warn().Type("event_type", evt).Msg("Unrecognized event type from signalmeow") - } -} - -func (user *User) GetPortalByChatID(signalID string) *Portal { - return user.bridge.GetPortalByChatID(database.PortalKey{ - ChatID: signalID, - Receiver: user.SignalID, - }) -} - -func (user *User) GetPortalByChatIDIfExists(signalID string) *Portal { - return user.bridge.GetPortalByChatIDIfExists(database.PortalKey{ - ChatID: signalID, - Receiver: user.SignalID, - }) -} - -func (user *User) disconnectNoLock() (*signalmeow.Client, error) { - if user.Client == nil { - return nil, ErrNotConnected - } - - disconnectedDevice := user.Client - err := user.Client.StopReceiveLoops() - user.Client = nil - return disconnectedDevice, err -} - -func (user *User) Disconnect() error { - user.Lock() - defer user.Unlock() - user.log.Info().Msg("Disconnecting session manually") - _, err := user.disconnectNoLock() - return err -} - -func (user *User) Logout() error { - user.Lock() - defer user.Unlock() - user.log.Info().Msg("Logging out of session") - loggedOutDevice, err := user.disconnectNoLock() - user.bridge.MeowStore.DeleteDevice(context.TODO(), &loggedOutDevice.Store.DeviceData) - user.bridge.GetPuppetByCustomMXID(user.MXID).ClearCustomMXID() - user.bridge.Metrics.TrackLoginState(user.SignalID, false) - return err -} - -func (user *User) UpdateDirectChats(ctx context.Context, chats map[id.UserID][]id.RoomID) { - if !user.bridge.Config.Bridge.SyncDirectChatList { - return - } - - puppet := user.bridge.GetPuppetByMXID(user.MXID) - if puppet == nil { - return - } - - intent := puppet.CustomIntent() - if intent == nil { - return - } - - method := http.MethodPatch - if chats == nil { - chats = user.getDirectChats() - method = http.MethodPut - } - - user.log.Debug().Msg("Updating m.direct list on homeserver") - - var err error - if user.bridge.Config.Homeserver.Software == bridgeconfig.SoftwareAsmux { - urlPath := intent.BuildURL(mautrix.ClientURLPath{"unstable", "com.beeper.asmux", "dms"}) - _, err = intent.MakeFullRequest(ctx, mautrix.FullRequest{ - Method: method, - URL: urlPath, - Headers: http.Header{"X-Asmux-Auth": {user.bridge.AS.Registration.AppToken}}, - RequestJSON: chats, - }) - } else { - existingChats := map[id.UserID][]id.RoomID{} - - err = intent.GetAccountData(ctx, event.AccountDataDirectChats.Type, &existingChats) - if err != nil { - user.log.Warn().Err(err).Msg("Failed to get m.direct event to update it") - return - } - - for userID, rooms := range existingChats { - if _, ok := user.bridge.ParsePuppetMXID(userID); !ok { - // This is not a ghost user, include it in the new list - chats[userID] = rooms - } else if _, ok := chats[userID]; !ok && method == http.MethodPatch { - // This is a ghost user, but we're not replacing the whole list, so include it too - chats[userID] = rooms - } - } - - err = intent.SetAccountData(ctx, event.AccountDataDirectChats.Type, &chats) - } - - if err != nil { - user.log.Warn().Err(err).Msg("Failed to update m.direct event") - } -} - -func (user *User) getDirectChats() map[id.UserID][]id.RoomID { - chats := map[id.UserID][]id.RoomID{} - - privateChats, err := user.bridge.DB.Portal.FindPrivateChatsOf(context.TODO(), user.SignalID) - if err != nil { - user.log.Err(err).Msg("Failed to get private chats") - return chats - } - for _, portal := range privateChats { - portalUserID := portal.UserID() - if portal.MXID != "" && portalUserID.Type == libsignalgo.ServiceIDTypeACI { - puppetMXID := user.bridge.FormatPuppetMXID(portalUserID.UUID) - - chats[puppetMXID] = []id.RoomID{portal.MXID} - } - } - - return chats -} From ca53ff0e6310a5f48785e7b55722e1f6c291050b Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Wed, 7 Aug 2024 02:22:41 +0300 Subject: [PATCH 128/580] ci: remove v2 prefix --- .gitlab-ci.yml | 5 ++--- Dockerfile | 14 +++++++------- Dockerfile.v2.ci => Dockerfile.ci | 0 build-v2.sh => build.sh | 0 4 files changed, 9 insertions(+), 10 deletions(-) rename Dockerfile.v2.ci => Dockerfile.ci (100%) rename build-v2.sh => build.sh (100%) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 952dabc..6420bf8 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1,12 +1,11 @@ include: - project: 'mautrix/ci' - file: '/gov2.yml' + file: '/gov2-as-default.yml' variables: BUILDER_IMAGE: dock.mau.dev/tulir/gomuks-build-docker/signal - BINARY_NAME_V2: mautrix-signal # 32-bit arm builds aren't supported -build arm v2: +build arm: rules: - when: never diff --git a/Dockerfile b/Dockerfile index de716c5..16c7d5b 100644 --- a/Dockerfile +++ b/Dockerfile @@ -11,7 +11,7 @@ ARG DBG=0 RUN ./build-rust.sh # -- Build mautrix-signal (with Go) -- -FROM golang:1-alpine3.19 AS go-builder +FROM golang:1-alpine3.20 AS go-builder RUN apk add --no-cache git ca-certificates build-base olm-dev WORKDIR /build @@ -20,9 +20,10 @@ COPY *.go go.* *.yaml *.sh ./ COPY pkg/signalmeow/. pkg/signalmeow/. COPY pkg/libsignalgo/* pkg/libsignalgo/ COPY pkg/libsignalgo/resources/. pkg/libsignalgo/resources/. -COPY config/. config/. -COPY database/. database/. -COPY msgconv/. msgconv/. +COPY pkg/msgconv/. pkg/msgconv/. +COPY pkg/signalid/. pkg/signalid/. +COPY pkg/connector/. pkg/connector/. +COPY cmd/. cmd/. COPY .git .git ARG DBG=0 @@ -38,15 +39,14 @@ EOF RUN ./build-go.sh # -- Run mautrix-signal -- -FROM alpine:3.19 +FROM alpine:3.20 ENV UID=1337 \ GID=1337 -RUN apk add --no-cache ffmpeg su-exec ca-certificates bash jq curl yq olm +RUN apk add --no-cache ffmpeg su-exec ca-certificates bash jq curl yq-go olm COPY --from=go-builder /build/mautrix-signal /usr/bin/mautrix-signal -COPY --from=go-builder /build/example-config.yaml /opt/mautrix-signal/example-config.yaml COPY --from=go-builder /build/docker-run.sh /docker-run.sh COPY --from=go-builder /go/bin/dlv /usr/bin/dlv VOLUME /data diff --git a/Dockerfile.v2.ci b/Dockerfile.ci similarity index 100% rename from Dockerfile.v2.ci rename to Dockerfile.ci diff --git a/build-v2.sh b/build.sh similarity index 100% rename from build-v2.sh rename to build.sh From b21e6575778201725888e175781964ea215d19ad Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Wed, 7 Aug 2024 16:29:39 +0300 Subject: [PATCH 129/580] ci: fix executable name in Dockerfile.ci --- Dockerfile.ci | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile.ci b/Dockerfile.ci index 0ff0c8c..e98ad03 100644 --- a/Dockerfile.ci +++ b/Dockerfile.ci @@ -5,7 +5,7 @@ ENV UID=1337 \ RUN apk add --no-cache ffmpeg su-exec ca-certificates bash jq curl yq-go -ARG EXECUTABLE=./mautrix-signal-v2 +ARG EXECUTABLE=./mautrix-signal COPY $EXECUTABLE /usr/bin/mautrix-signal COPY ./docker-run.sh /docker-run.sh ENV BRIDGEV2=1 From 9a1d3853c8d11bf58972feb737ce5852e7af4c31 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Wed, 7 Aug 2024 20:50:25 +0300 Subject: [PATCH 130/580] legacymigrate: ignore invalid disappearing_message rows [skip cd] --- cmd/mautrix-signal/legacymigrate.sql | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/cmd/mautrix-signal/legacymigrate.sql b/cmd/mautrix-signal/legacymigrate.sql index 9266e9d..258194f 100644 --- a/cmd/mautrix-signal/legacymigrate.sql +++ b/cmd/mautrix-signal/legacymigrate.sql @@ -128,7 +128,8 @@ SELECT 'after_read', -- type expiration_seconds * 1000000000, -- timer CASE WHEN expiration_ts IS NOT NULL THEN expiration_ts * 1000000000 END -- disappear_at -FROM disappearing_message_old; +FROM disappearing_message_old +WHERE expiration_ts < 9000000000; INSERT INTO reaction ( bridge_id, message_id, message_part_id, sender_id, emoji_id, emoji, From 24ca68af284968dd3edf1a4e6fabb149aa0e5d34 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Wed, 7 Aug 2024 23:14:15 +0300 Subject: [PATCH 131/580] legacymigrate: maybe fix migrating relay users [skip cd] --- cmd/mautrix-signal/legacymigrate.sql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/mautrix-signal/legacymigrate.sql b/cmd/mautrix-signal/legacymigrate.sql index 258194f..806fcc2 100644 --- a/cmd/mautrix-signal/legacymigrate.sql +++ b/cmd/mautrix-signal/legacymigrate.sql @@ -35,7 +35,7 @@ SELECT NULL, -- parent_id '', -- parent_receiver CASE WHEN portal_old.relay_user_id<>'' THEN '' END, -- relay_bridge_id - CASE WHEN portal_old.relay_user_id<>'' THEN portal_old.relay_user_id END, -- relay_login_id + CASE WHEN portal_old.relay_user_id<>'' THEN (SELECT id FROM user_login WHERE user_mxid=portal_old.relay_user_id) END, -- relay_login_id CASE WHEN LENGTH(chat_id)=44 THEN NULL ELSE chat_id END, -- other_user_id name, topic, From eeffb0d7e5dcef3b5a434c056d35b07db2286273 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Thu, 8 Aug 2024 01:31:16 +0300 Subject: [PATCH 132/580] chatinfo: allow passing service IDs to ResolveIdentifier --- pkg/connector/chatinfo.go | 60 +++++++++++++++++++++++---------------- 1 file changed, 35 insertions(+), 25 deletions(-) diff --git a/pkg/connector/chatinfo.go b/pkg/connector/chatinfo.go index a5d99c9..8051344 100644 --- a/pkg/connector/chatinfo.go +++ b/pkg/connector/chatinfo.go @@ -106,35 +106,45 @@ func (s *SignalClient) contactToUserInfo(contact *types.Recipient) *bridgev2.Use } func (s *SignalClient) ResolveIdentifier(ctx context.Context, number string, createChat bool) (*bridgev2.ResolveIdentifierResponse, error) { - number, err := bridgev2.CleanPhoneNumber(number) - if err != nil { - return nil, err - } - e164Number, err := strconv.ParseUint(strings.TrimPrefix(number, "+"), 10, 64) - if err != nil { - return nil, fmt.Errorf("error parsing phone number: %w", err) - } - e164String := fmt.Sprintf("+%d", e164Number) var aci, pni uuid.UUID + var e164Number uint64 var recipient *types.Recipient - if recipient, err = s.Client.ContactByE164(ctx, e164String); err != nil { - return nil, fmt.Errorf("error looking up number in local contact list: %w", err) - } else if recipient != nil { - aci = recipient.ACI - pni = recipient.PNI - } else if resp, err := s.Client.LookupPhone(ctx, e164Number); err != nil { - return nil, fmt.Errorf("error looking up number on server: %w", err) - } else { - aci = resp[e164Number].ACI - pni = resp[e164Number].PNI - if aci == uuid.Nil && pni == uuid.Nil { - return nil, nil - } - recipient, err = s.Client.Store.RecipientStore.UpdateRecipientE164(ctx, aci, pni, e164String) + serviceID, err := libsignalgo.ServiceIDFromString(number) + if err != nil { + number, err = bridgev2.CleanPhoneNumber(number) if err != nil { - zerolog.Ctx(ctx).Err(err).Msg("Failed to save recipient entry after looking up phone") + return nil, err + } + e164Number, err = strconv.ParseUint(strings.TrimPrefix(number, "+"), 10, 64) + if err != nil { + return nil, fmt.Errorf("error parsing phone number: %w", err) + } + e164String := fmt.Sprintf("+%d", e164Number) + if recipient, err = s.Client.ContactByE164(ctx, e164String); err != nil { + return nil, fmt.Errorf("error looking up number in local contact list: %w", err) + } else if recipient != nil { + aci = recipient.ACI + pni = recipient.PNI + } else if resp, err := s.Client.LookupPhone(ctx, e164Number); err != nil { + return nil, fmt.Errorf("error looking up number on server: %w", err) + } else { + aci = resp[e164Number].ACI + pni = resp[e164Number].PNI + if aci == uuid.Nil && pni == uuid.Nil { + return nil, nil + } + recipient, err = s.Client.Store.RecipientStore.UpdateRecipientE164(ctx, aci, pni, e164String) + if err != nil { + zerolog.Ctx(ctx).Err(err).Msg("Failed to save recipient entry after looking up phone") + } + aci, pni = recipient.ACI, recipient.PNI + } + } else { + aci, pni = serviceID.ToACIAndPNI() + recipient, err = s.Client.Store.RecipientStore.LoadAndUpdateRecipient(ctx, aci, pni, nil) + if err != nil { + return nil, fmt.Errorf("error loading recipient: %w", err) } - aci, pni = recipient.ACI, recipient.PNI } zerolog.Ctx(ctx).Debug(). Uint64("e164", e164Number). From fd4b7366e15cd6fd03e294023b7bd5b654412e5e Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Thu, 8 Aug 2024 23:31:40 +0300 Subject: [PATCH 133/580] legacymigrate: ignore user_portal rows whose user isn't logged in --- cmd/mautrix-signal/legacymigrate.sql | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/cmd/mautrix-signal/legacymigrate.sql b/cmd/mautrix-signal/legacymigrate.sql index 806fcc2..1895bfd 100644 --- a/cmd/mautrix-signal/legacymigrate.sql +++ b/cmd/mautrix-signal/legacymigrate.sql @@ -168,7 +168,8 @@ SELECT false, -- preferred CASE WHEN last_read_ts = 0 THEN NULL ELSE last_read_ts * 1000000 END -- last_read FROM user_portal_old -LEFT JOIN user_old ON user_old.mxid = user_portal_old.user_mxid; +LEFT JOIN user_old ON user_old.mxid = user_portal_old.user_mxid +WHERE user_old.uuid IS NOT NULL; DROP TABLE disappearing_message_old; DROP TABLE reaction_old; From b7a5bb74b35e876a0a9d309364ff25ca9c45ef3f Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Thu, 8 Aug 2024 23:32:48 +0300 Subject: [PATCH 134/580] chatinfo: implement ValidateUserID --- go.mod | 21 +++++++-------------- go.sum | 21 +++++++-------------- pkg/connector/chatinfo.go | 7 +++++++ 3 files changed, 21 insertions(+), 28 deletions(-) diff --git a/go.mod b/go.mod index 45187a6..ac5eeba 100644 --- a/go.mod +++ b/go.mod @@ -6,12 +6,8 @@ require ( github.com/emersion/go-vcard v0.0.0-20230815062825-8fda7d206ec9 github.com/google/uuid v1.6.0 github.com/gorilla/mux v1.8.0 - github.com/lib/pq v1.10.9 github.com/mattn/go-pointer v0.0.1 - github.com/mattn/go-sqlite3 v1.14.22 - github.com/prometheus/client_golang v1.19.1 github.com/rs/zerolog v1.33.0 - github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e github.com/stretchr/testify v1.9.0 github.com/tidwall/gjson v1.17.3 go.mau.fi/util v0.6.1-0.20240802175451-b430ebbffc98 @@ -19,24 +15,23 @@ require ( golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 golang.org/x/net v0.27.0 google.golang.org/protobuf v1.34.2 - maunium.net/go/mautrix v0.19.1-0.20240806214251-e0f58dccf432 + maunium.net/go/mautrix v0.19.1-0.20240808174455-5edfcff2b7b6 nhooyr.io/websocket v1.8.11 ) require ( - github.com/beorn7/perks v1.0.1 // indirect - github.com/cespare/xxhash/v2 v2.2.0 // indirect github.com/coreos/go-systemd/v22 v22.5.0 // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/gorilla/websocket v1.5.0 // indirect - github.com/kr/text v0.2.0 // indirect + github.com/kr/pretty v0.3.1 // indirect + github.com/lib/pq v1.10.9 // indirect github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-isatty v0.0.19 // indirect + github.com/mattn/go-sqlite3 v1.14.22 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect - github.com/prometheus/client_model v0.5.0 // indirect - github.com/prometheus/common v0.48.0 // indirect - github.com/prometheus/procfs v0.12.0 // indirect + github.com/rogpeppe/go-internal v1.10.0 // indirect github.com/rs/xid v1.5.0 // indirect + github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e // indirect github.com/tidwall/match v1.1.1 // indirect github.com/tidwall/pretty v1.2.0 // indirect github.com/tidwall/sjson v1.2.5 // indirect @@ -44,10 +39,8 @@ require ( go.mau.fi/zeroconfig v0.1.3 // indirect golang.org/x/sys v0.22.0 // indirect golang.org/x/text v0.16.0 // indirect + gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect gopkg.in/natefinch/lumberjack.v2 v2.2.1 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect maunium.net/go/mauflag v1.0.0 // indirect ) - -//replace maunium.net/go/mautrix => ../mautrix-go -//replace go.mau.fi/util => ../../Go/go-util diff --git a/go.sum b/go.sum index 50a5dcc..11d927a 100644 --- a/go.sum +++ b/go.sum @@ -1,9 +1,5 @@ github.com/DATA-DOG/go-sqlmock v1.5.2 h1:OcvFkGmslmlZibjAjaHm3L//6LiuBgolP7OputlJIzU= github.com/DATA-DOG/go-sqlmock v1.5.2/go.mod h1:88MAG/4G7SMwSE3CeA0ZKzrT5CiOU3OJ+JlNzwDqpNU= -github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= -github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= -github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= -github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/coreos/go-systemd/v22 v22.5.0 h1:RrqgGjYQKalulkV8NGVIfkXQf6YYmOyiJKk8iXXhfZs= github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= @@ -20,8 +16,11 @@ github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI= github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc= github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= +github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw= @@ -35,17 +34,11 @@ github.com/mattn/go-pointer v0.0.1 h1:n+XhsuGeVO6MEAp7xyEukFINEa+Quek5psIR/ylA6o github.com/mattn/go-pointer v0.0.1/go.mod h1:2zXcozF6qYGgmsG+SeTZz3oAbFLdD3OWqnUbNvJZAlc= github.com/mattn/go-sqlite3 v1.14.22 h1:2gZY6PC6kBnID23Tichd1K+Z0oS6nE/XwU+Vz/5o4kU= github.com/mattn/go-sqlite3 v1.14.22/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y= +github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/prometheus/client_golang v1.19.1 h1:wZWJDwK+NameRJuPGDhlnFgx8e8HN3XHQeLaYJFJBOE= -github.com/prometheus/client_golang v1.19.1/go.mod h1:mP78NwGzrVks5S2H6ab8+ZZGJLZUq1hoULYBAYBw1Ho= -github.com/prometheus/client_model v0.5.0 h1:VQw1hfvPvk3Uv6Qf29VrPF32JB6rtbgI6cYPYQjL0Qw= -github.com/prometheus/client_model v0.5.0/go.mod h1:dTiFglRmd66nLR9Pv9f0mZi7B7fk5Pm3gvsjB5tr+kI= -github.com/prometheus/common v0.48.0 h1:QO8U2CdOzSn1BBsmXJXduaaW+dY/5QLjfB8svtSzKKE= -github.com/prometheus/common v0.48.0/go.mod h1:0/KsvlIEfPQCQ5I2iNSAWKPZziNCvRs5EC6ILDTlAPc= -github.com/prometheus/procfs v0.12.0 h1:jluTpSng7V9hY0O2R9DzzJHYb2xULk9VTR1V1R/k6Bo= -github.com/prometheus/procfs v0.12.0/go.mod h1:pcuDEFsWDnvcgNzo4EEweacyhjeA9Zk3cnaOZAZEfOo= +github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog= github.com/rs/xid v1.5.0 h1:mKX4bl4iPYJtEIxp6CYiUuLQ/8DYMoz0PUdtGgMFRVc= @@ -95,7 +88,7 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= maunium.net/go/mauflag v1.0.0 h1:YiaRc0tEI3toYtJMRIfjP+jklH45uDHtT80nUamyD4M= maunium.net/go/mauflag v1.0.0/go.mod h1:nLivPOpTpHnpzEh8jEdSL9UqO9+/KBJFmNRlwKfkPeA= -maunium.net/go/mautrix v0.19.1-0.20240806214251-e0f58dccf432 h1:Gz1nMg/s4B0VZD4e31wfaghR5cSk2NQVuQkxdCBuI7o= -maunium.net/go/mautrix v0.19.1-0.20240806214251-e0f58dccf432/go.mod h1:ZWyxoQxRTBxzWIMs0kQCVogZIY0clTu33h102veCT/Q= +maunium.net/go/mautrix v0.19.1-0.20240808174455-5edfcff2b7b6 h1:OGskR/suV/6OGgURhucS8eH5QRyRzw7Wkpf8exrOakk= +maunium.net/go/mautrix v0.19.1-0.20240808174455-5edfcff2b7b6/go.mod h1:ZWyxoQxRTBxzWIMs0kQCVogZIY0clTu33h102veCT/Q= nhooyr.io/websocket v1.8.11 h1:f/qXNc2/3DpoSZkHt1DQu6rj4zGC8JmkkLkWss0MgN0= nhooyr.io/websocket v1.8.11/go.mod h1:rN9OFWIUwuxg4fR5tELlYC04bXYowCP9GX47ivo2l+c= diff --git a/pkg/connector/chatinfo.go b/pkg/connector/chatinfo.go index 8051344..7083701 100644 --- a/pkg/connector/chatinfo.go +++ b/pkg/connector/chatinfo.go @@ -105,6 +105,13 @@ func (s *SignalClient) contactToUserInfo(contact *types.Recipient) *bridgev2.Use return ui } +var _ bridgev2.IdentifierValidatingNetwork = (*SignalConnector)(nil) + +func (s *SignalConnector) ValidateUserID(id networkid.UserID) bool { + _, err := signalid.ParseUserIDAsServiceID(id) + return err == nil +} + func (s *SignalClient) ResolveIdentifier(ctx context.Context, number string, createChat bool) (*bridgev2.ResolveIdentifierResponse, error) { var aci, pni uuid.UUID var e164Number uint64 From f3a286f68a91ef593bccb71db433472c7d8072f4 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Fri, 9 Aug 2024 01:59:13 +0300 Subject: [PATCH 135/580] build: always update submodules [skip ci] --- build-rust.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/build-rust.sh b/build-rust.sh index 4201bb4..c7954a2 100755 --- a/build-rust.sh +++ b/build-rust.sh @@ -6,4 +6,5 @@ # RUST_PROFILE=dev #fi RUST_PROFILE=release +git submodule update --init cd pkg/libsignalgo/libsignal && RUSTFLAGS="-Ctarget-feature=-crt-static" RUSTC_WRAPPER="" cargo build -p libsignal-ffi --profile=$RUST_PROFILE From 77cf7e79854ae7bffecbc0f9f48fee06bacf6572 Mon Sep 17 00:00:00 2001 From: Malte E <97891689+maltee1@users.noreply.github.com> Date: Fri, 9 Aug 2024 12:03:50 +0200 Subject: [PATCH 136/580] groupinfo: look up ACI from local devices when receiving PNI group member (#528) --- pkg/connector/groupinfo.go | 42 ++++++++++++++++++++++--------- pkg/signalmeow/store/container.go | 10 ++++++++ 2 files changed, 40 insertions(+), 12 deletions(-) diff --git a/pkg/connector/groupinfo.go b/pkg/connector/groupinfo.go index 3bf809d..db06b95 100644 --- a/pkg/connector/groupinfo.go +++ b/pkg/connector/groupinfo.go @@ -20,6 +20,7 @@ import ( "context" "time" + "github.com/google/uuid" "github.com/rs/zerolog" "go.mau.fi/util/ptr" "maunium.net/go/mautrix/bridgev2" @@ -120,11 +121,12 @@ func (s *SignalClient) getGroupInfo(ctx context.Context, groupID types.GroupIden } } for _, member := range groupInfo.PendingMembers { - if member.ServiceID.Type != libsignalgo.ServiceIDTypeACI { + aci := s.maybeResolvePNItoACI(ctx, &member.ServiceID) + if aci == nil { continue } members.Members = append(members.Members, bridgev2.ChatMember{ - EventSender: s.makeEventSender(member.ServiceID.UUID), + EventSender: s.makeEventSender(*aci), PowerLevel: roleToPL(member.Role), Membership: event.MembershipInvite, }) @@ -136,11 +138,12 @@ func (s *SignalClient) getGroupInfo(ctx context.Context, groupID types.GroupIden }) } for _, member := range groupInfo.BannedMembers { - if member.ServiceID.Type != libsignalgo.ServiceIDTypeACI { + aci := s.maybeResolvePNItoACI(ctx, &member.ServiceID) + if aci == nil { continue } members.Members = append(members.Members, bridgev2.ChatMember{ - EventSender: s.makeEventSender(member.ServiceID.UUID), + EventSender: s.makeEventSender(*aci), Membership: event.MembershipBan, }) } @@ -243,21 +246,23 @@ func (s *SignalClient) groupChangeToChatInfoChange(ctx context.Context, rev uint }) } for _, member := range groupChange.AddPendingMembers { - if member.ServiceID.Type != libsignalgo.ServiceIDTypeACI { + aci := s.maybeResolvePNItoACI(ctx, &member.ServiceID) + if aci == nil { continue } mc = append(mc, bridgev2.ChatMember{ - EventSender: s.makeEventSender(member.ServiceID.UUID), + EventSender: s.makeEventSender(*aci), PowerLevel: roleToPL(member.Role), Membership: event.MembershipInvite, }) } for _, memberServiceID := range groupChange.DeletePendingMembers { - if memberServiceID.Type != libsignalgo.ServiceIDTypeACI { + aci := s.maybeResolvePNItoACI(ctx, memberServiceID) + if aci == nil { continue } mc = append(mc, bridgev2.ChatMember{ - EventSender: s.makeEventSender(memberServiceID.UUID), + EventSender: s.makeEventSender(*aci), Membership: event.MembershipLeave, PrevMembership: event.MembershipInvite, }) @@ -276,20 +281,22 @@ func (s *SignalClient) groupChangeToChatInfoChange(ctx context.Context, rev uint }) } for _, member := range groupChange.AddBannedMembers { - if member.ServiceID.Type != libsignalgo.ServiceIDTypeACI { + aci := s.maybeResolvePNItoACI(ctx, &member.ServiceID) + if aci == nil { continue } mc = append(mc, bridgev2.ChatMember{ - EventSender: s.makeEventSender(member.ServiceID.UUID), + EventSender: s.makeEventSender(*aci), Membership: event.MembershipBan, }) } for _, memberServiceID := range groupChange.DeleteBannedMembers { - if memberServiceID.Type != libsignalgo.ServiceIDTypeACI { + aci := s.maybeResolvePNItoACI(ctx, memberServiceID) + if aci == nil { continue } mc = append(mc, bridgev2.ChatMember{ - EventSender: s.makeEventSender(memberServiceID.UUID), + EventSender: s.makeEventSender(*aci), Membership: event.MembershipLeave, PrevMembership: event.MembershipBan, }) @@ -300,6 +307,17 @@ func (s *SignalClient) groupChangeToChatInfoChange(ctx context.Context, rev uint return ic } +func (s *SignalClient) maybeResolvePNItoACI(ctx context.Context, serviceID *libsignalgo.ServiceID) *uuid.UUID { + if serviceID.Type == libsignalgo.ServiceIDTypeACI { + return &serviceID.UUID + } + device, err := s.Client.Store.DeviceStore.DeviceByPNI(ctx, serviceID.UUID) + if err != nil || device == nil { + return nil + } + return &device.ACI +} + func (s *SignalClient) catchUpGroup(ctx context.Context, portal *bridgev2.Portal, fromRevision, toRevision uint32, ts uint64) { if fromRevision >= toRevision { return diff --git a/pkg/signalmeow/store/container.go b/pkg/signalmeow/store/container.go index 9edafef..a08b42d 100644 --- a/pkg/signalmeow/store/container.go +++ b/pkg/signalmeow/store/container.go @@ -19,6 +19,7 @@ var _ DeviceStore = (*Container)(nil) type DeviceStore interface { PutDevice(ctx context.Context, dd *DeviceData) error DeviceByACI(ctx context.Context, aci uuid.UUID) (*Device, error) + DeviceByPNI(ctx context.Context, pni uuid.UUID) (*Device, error) } // Container is a wrapper for a SQL database that can contain multiple signalmeow sessions. @@ -39,6 +40,7 @@ FROM signalmeow_device ` const getDeviceQuery = getAllDevicesQuery + " WHERE aci_uuid=$1" +const deviceByPNIQuery = getAllDevicesQuery + "WHERE pni_uuid=$1" func (c *Container) Upgrade(ctx context.Context) error { return c.db.Upgrade(ctx) @@ -122,6 +124,14 @@ func (c *Container) DeviceByACI(ctx context.Context, aci uuid.UUID) (*Device, er return sess, err } +func (c *Container) DeviceByPNI(ctx context.Context, pni uuid.UUID) (*Device, error) { + sess, err := c.scanDevice(c.db.QueryRow(ctx, deviceByPNIQuery, pni)) + if errors.Is(err, sql.ErrNoRows) { + return nil, nil + } + return sess, err +} + const ( insertDeviceQuery = ` INSERT INTO signalmeow_device ( From c3fd55cf3872b75118f0a8aca0609b9c70aa5061 Mon Sep 17 00:00:00 2001 From: Malte E <97891689+maltee1@users.noreply.github.com> Date: Fri, 9 Aug 2024 22:42:34 +0200 Subject: [PATCH 137/580] handlematrix: add support for most membership changes (#527) Missing knocks and joins [skip cd] --- go.mod | 2 +- go.sum | 4 +- pkg/connector/groupinfo.go | 4 +- pkg/connector/handlematrix.go | 128 ++++++++++++++++++++++++++++++++++ pkg/signalid/ids.go | 8 +++ pkg/signalmeow/groups.go | 14 ++-- 6 files changed, 149 insertions(+), 11 deletions(-) diff --git a/go.mod b/go.mod index ac5eeba..c49fa0f 100644 --- a/go.mod +++ b/go.mod @@ -15,7 +15,7 @@ require ( golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 golang.org/x/net v0.27.0 google.golang.org/protobuf v1.34.2 - maunium.net/go/mautrix v0.19.1-0.20240808174455-5edfcff2b7b6 + maunium.net/go/mautrix v0.19.1-0.20240809135320-eb84187368b7 nhooyr.io/websocket v1.8.11 ) diff --git a/go.sum b/go.sum index 11d927a..4972d7b 100644 --- a/go.sum +++ b/go.sum @@ -88,7 +88,7 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= maunium.net/go/mauflag v1.0.0 h1:YiaRc0tEI3toYtJMRIfjP+jklH45uDHtT80nUamyD4M= maunium.net/go/mauflag v1.0.0/go.mod h1:nLivPOpTpHnpzEh8jEdSL9UqO9+/KBJFmNRlwKfkPeA= -maunium.net/go/mautrix v0.19.1-0.20240808174455-5edfcff2b7b6 h1:OGskR/suV/6OGgURhucS8eH5QRyRzw7Wkpf8exrOakk= -maunium.net/go/mautrix v0.19.1-0.20240808174455-5edfcff2b7b6/go.mod h1:ZWyxoQxRTBxzWIMs0kQCVogZIY0clTu33h102veCT/Q= +maunium.net/go/mautrix v0.19.1-0.20240809135320-eb84187368b7 h1:xAq4d1rW/5WN7szBtxHNY/63EPNdji+h7FXlLGBUfJU= +maunium.net/go/mautrix v0.19.1-0.20240809135320-eb84187368b7/go.mod h1:ZWyxoQxRTBxzWIMs0kQCVogZIY0clTu33h102veCT/Q= nhooyr.io/websocket v1.8.11 h1:f/qXNc2/3DpoSZkHt1DQu6rj4zGC8JmkkLkWss0MgN0= nhooyr.io/websocket v1.8.11/go.mod h1:rN9OFWIUwuxg4fR5tELlYC04bXYowCP9GX47ivo2l+c= diff --git a/pkg/connector/groupinfo.go b/pkg/connector/groupinfo.go index db06b95..5c25942 100644 --- a/pkg/connector/groupinfo.go +++ b/pkg/connector/groupinfo.go @@ -345,7 +345,9 @@ func (s *SignalClient) catchUpGroup(ctx context.Context, portal *bridgev2.Portal for _, gc := range groupChanges { log.Debug().Uint32("current_rev", gc.GroupChange.Revision).Msg("Processing group change") chatInfoChange := s.groupChangeToChatInfoChange(ctx, gc.GroupChange.Revision, gc.GroupChange) - portal.ProcessChatInfoChange(ctx, s.makeEventSender(gc.GroupChange.SourceACI), s.UserLogin, chatInfoChange, time.UnixMilli(int64(ts))) + if gc.GroupChange.SourceServiceID.Type == libsignalgo.ServiceIDTypeACI { + portal.ProcessChatInfoChange(ctx, s.makeEventSender(gc.GroupChange.SourceServiceID.UUID), s.UserLogin, chatInfoChange, time.UnixMilli(int64(ts))) + } if gc.GroupChange.Revision == toRevision { break } diff --git a/pkg/connector/handlematrix.go b/pkg/connector/handlematrix.go index 9e8c353..2b8ca26 100644 --- a/pkg/connector/handlematrix.go +++ b/pkg/connector/handlematrix.go @@ -30,6 +30,7 @@ import ( "maunium.net/go/mautrix/bridgev2" "maunium.net/go/mautrix/bridgev2/database" "maunium.net/go/mautrix/bridgev2/networkid" + "maunium.net/go/mautrix/event" "go.mau.fi/mautrix-signal/pkg/libsignalgo" "go.mau.fi/mautrix-signal/pkg/signalid" @@ -344,3 +345,130 @@ func (s *SignalClient) HandleMatrixRoomTopic(ctx context.Context, msg *bridgev2. ModifyDescription: &msg.Content.Topic, }, nil) } + +func (s *SignalClient) HandleMatrixMembership(ctx context.Context, msg *bridgev2.MatrixMembershipChange) (bool, error) { + var targetIntent bridgev2.MatrixAPI + var targetSignalID uuid.UUID + var err error + if msg.Portal.RoomType == database.RoomTypeDM { + //TODO: this probably needs to revert some changes and clean up the portal on leaves + switch msg.Type { + case bridgev2.Invite: + return false, fmt.Errorf("cannot invite additional user to dm") + default: + return false, nil + } + } + if msg.TargetGhost != nil { + targetIntent = msg.TargetGhost.Intent + targetSignalID, err = signalid.ParseUserID(msg.TargetGhost.ID) + if err != nil { + return false, fmt.Errorf("failed to parse target ghost signal id: %w", err) + } + } else if msg.TargetUserLogin != nil { + targetSignalID, err = signalid.ParseUserLoginID(msg.TargetUserLogin.ID) + if err != nil { + return false, fmt.Errorf("failed to parse target user signal id: %w", err) + } + targetIntent = msg.TargetUserLogin.User.DoublePuppet(ctx) + if targetIntent == nil { + ghost, err := s.Main.Bridge.GetGhostByID(ctx, networkid.UserID(msg.TargetUserLogin.ID)) + if err != nil { + return false, fmt.Errorf("failed to get ghost for user: %w", err) + } + targetIntent = ghost.Intent + } + } + log := zerolog.Ctx(ctx).With(). + Str("From Membership", string(msg.Type.From)). + Str("To Membership", string(msg.Type.To)). + Logger() + gc := &signalmeow.GroupChange{} + role := signalmeow.GroupMember_DEFAULT + if msg.Type.To == event.MembershipInvite || msg.Type == bridgev2.AcceptKnock { + levels, err := msg.Portal.Bridge.Matrix.GetPowerLevels(ctx, msg.Portal.MXID) + if err != nil { + log.Err(err).Msg("Couldn't get power levels") + if levels.GetUserLevel(targetIntent.GetMXID()) >= 50 { + role = signalmeow.GroupMember_ADMINISTRATOR + } + } + } + switch msg.Type { + case bridgev2.AcceptInvite: + gc.PromotePendingMembers = []*signalmeow.PromotePendingMember{{ + ACI: targetSignalID, + }} + case bridgev2.RevokeInvite, bridgev2.RejectInvite: + deletePendingMember := libsignalgo.NewACIServiceID(targetSignalID) + gc.DeletePendingMembers = []*libsignalgo.ServiceID{&deletePendingMember} + case bridgev2.Leave, bridgev2.Kick: + gc.DeleteMembers = []*uuid.UUID{&targetSignalID} + case bridgev2.Invite: + gc.AddMembers = []*signalmeow.AddMember{{ + GroupMember: signalmeow.GroupMember{ + ACI: targetSignalID, + Role: role, + }, + }} + // TODO: joining and knocking requires a way to obtain the invite link + // because the joining/knocking member doesn't have the GroupMasterKey yet + // case bridgev2.Join: + // gc.AddMembers = []*signalmeow.AddMember{{ + // GroupMember: signalmeow.GroupMember{ + // ACI: targetSignalID, + // Role: role, + // }, + // JoinFromInviteLink: true, + // }} + // case bridgev2.Knock: + // gc.AddRequestingMembers = []*signalmeow.RequestingMember{{ + // ACI: targetSignalID, + // Timestamp: uint64(time.Now().UnixMilli()), + // }} + case bridgev2.AcceptKnock: + gc.PromoteRequestingMembers = []*signalmeow.RoleMember{{ + ACI: targetSignalID, + Role: role, + }} + case bridgev2.RetractKnock, bridgev2.RejectKnock: + gc.DeleteRequestingMembers = []*uuid.UUID{&targetSignalID} + case bridgev2.BanKnocked, bridgev2.BanInvited, bridgev2.BanJoined, bridgev2.BanLeft: + gc.AddBannedMembers = []*signalmeow.BannedMember{{ + ServiceID: libsignalgo.NewACIServiceID(targetSignalID), + Timestamp: uint64(time.Now().UnixMilli()), + }} + switch msg.Type { + case bridgev2.BanJoined: + gc.DeleteMembers = []*uuid.UUID{&targetSignalID} + case bridgev2.BanInvited: + deletePendingMember := libsignalgo.NewACIServiceID(targetSignalID) + gc.DeletePendingMembers = []*libsignalgo.ServiceID{&deletePendingMember} + case bridgev2.BanKnocked: + gc.DeleteRequestingMembers = []*uuid.UUID{&targetSignalID} + } + case bridgev2.Unban: + unbanUser := libsignalgo.NewACIServiceID(targetSignalID) + gc.DeleteBannedMembers = []*libsignalgo.ServiceID{&unbanUser} + default: + log.Debug().Msg("unsupported membership change") + return false, nil + } + _, groupID, err := signalid.ParsePortalID(msg.Portal.ID) + if err != nil || groupID == "" { + return false, err + } + gc.Revision = msg.Portal.Metadata.(*signalid.PortalMetadata).Revision + 1 + revision, err := s.Client.UpdateGroup(ctx, gc, groupID) + if err != nil { + return false, err + } + if msg.Type == bridgev2.Invite { + err = targetIntent.EnsureJoined(ctx, msg.Portal.MXID) + if err != nil { + return false, err + } + } + msg.Portal.Metadata.(*signalid.PortalMetadata).Revision = revision + return true, nil +} diff --git a/pkg/signalid/ids.go b/pkg/signalid/ids.go index f99bf9d..99ef7b3 100644 --- a/pkg/signalid/ids.go +++ b/pkg/signalid/ids.go @@ -39,6 +39,14 @@ func ParseUserID(userID networkid.UserID) (uuid.UUID, error) { } } +func ParseUserLoginID(userLoginID networkid.UserLoginID) (uuid.UUID, error) { + userID, err := uuid.Parse(string(userLoginID)) + if err != nil { + return uuid.Nil, err + } + return userID, nil +} + func ParseUserIDAsServiceID(userID networkid.UserID) (libsignalgo.ServiceID, error) { return libsignalgo.ServiceIDFromString(string(userID)) } diff --git a/pkg/signalmeow/groups.go b/pkg/signalmeow/groups.go index 0a67ef6..9031194 100644 --- a/pkg/signalmeow/groups.go +++ b/pkg/signalmeow/groups.go @@ -154,7 +154,7 @@ type RequestingMember struct { Timestamp uint64 } -type PromotePendingMembers struct { +type PromotePendingMember struct { ACI uuid.UUID ProfileKey libsignalgo.ProfileKey } @@ -178,7 +178,7 @@ type BannedMember struct { type GroupChange struct { groupMasterKey types.SerializedGroupMasterKey - SourceACI uuid.UUID + SourceServiceID libsignalgo.ServiceID Revision uint32 AddMembers []*AddMember DeleteMembers []*uuid.UUID @@ -186,7 +186,7 @@ type GroupChange struct { ModifyMemberProfileKeys []*ProfileKeyMember AddPendingMembers []*PendingMember DeletePendingMembers []*libsignalgo.ServiceID - PromotePendingMembers []*GroupMember + PromotePendingMembers []*PromotePendingMember ModifyTitle *string ModifyAvatar *string ModifyDisappearingMessagesDuration *uint32 @@ -862,9 +862,9 @@ func (cli *Client) decryptGroupChange(ctx context.Context, encryptedGroupChange return nil, fmt.Errorf("wrong serviceid kind: expected aci, got pni") } decryptedGroupChange := &GroupChange{ - groupMasterKey: groupMasterKey, - Revision: encryptedActions.Revision, - SourceACI: sourceServiceID.UUID, + groupMasterKey: groupMasterKey, + Revision: encryptedActions.Revision, + SourceServiceID: sourceServiceID, } if encryptedActions.ModifyTitle != nil { @@ -992,7 +992,7 @@ func (cli *Client) decryptGroupChange(ctx context.Context, encryptedGroupChange if err != nil { return nil, err } - decryptedGroupChange.PromotePendingMembers = append(decryptedGroupChange.PromotePendingMembers, &GroupMember{ + decryptedGroupChange.PromotePendingMembers = append(decryptedGroupChange.PromotePendingMembers, &PromotePendingMember{ ACI: *aci, ProfileKey: *profileKey, }) From 4ba7ef744254083389b9be70b51d488c21eb22ed Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Fri, 9 Aug 2024 22:18:26 +0300 Subject: [PATCH 138/580] signalmeow: make sync contacts call on connect optional --- pkg/connector/config.go | 16 +++++++++------- pkg/connector/connector.go | 2 ++ pkg/connector/example-config.yaml | 2 ++ pkg/signalmeow/client.go | 1 + pkg/signalmeow/receiving.go | 4 +++- 5 files changed, 17 insertions(+), 8 deletions(-) diff --git a/pkg/connector/config.go b/pkg/connector/config.go index 20fb6e8..0d98583 100644 --- a/pkg/connector/config.go +++ b/pkg/connector/config.go @@ -31,13 +31,14 @@ import ( var ExampleConfig string type SignalConfig struct { - DisplaynameTemplate string `yaml:"displayname_template"` - UseContactAvatars bool `yaml:"use_contact_avatars"` - UseOutdatedProfiles bool `yaml:"use_outdated_profiles"` - NumberInTopic bool `yaml:"number_in_topic"` - DeviceName string `yaml:"device_name"` - NoteToSelfAvatar id.ContentURIString `yaml:"note_to_self_avatar"` - LocationFormat string `yaml:"location_format"` + DisplaynameTemplate string `yaml:"displayname_template"` + UseContactAvatars bool `yaml:"use_contact_avatars"` + SyncContactsOnStartup bool `yaml:"sync_contacts_on_startup"` + UseOutdatedProfiles bool `yaml:"use_outdated_profiles"` + NumberInTopic bool `yaml:"number_in_topic"` + DeviceName string `yaml:"device_name"` + NoteToSelfAvatar id.ContentURIString `yaml:"note_to_self_avatar"` + LocationFormat string `yaml:"location_format"` displaynameTemplate *template.Template `yaml:"-"` } @@ -74,6 +75,7 @@ func (c *SignalConfig) FormatDisplayname(contact *types.Recipient) string { func upgradeConfig(helper up.Helper) { helper.Copy(up.Str, "displayname_template") helper.Copy(up.Bool, "use_contact_avatars") + helper.Copy(up.Bool, "sync_contacts_on_startup") helper.Copy(up.Bool, "use_outdated_profiles") helper.Copy(up.Bool, "number_in_topic") helper.Copy(up.Str, "device_name") diff --git a/pkg/connector/connector.go b/pkg/connector/connector.go index 6a4e4dc..bb98238 100644 --- a/pkg/connector/connector.go +++ b/pkg/connector/connector.go @@ -107,6 +107,8 @@ func (s *SignalConnector) LoadUserLogin(ctx context.Context, login *bridgev2.Use sc.Client = &signalmeow.Client{ Store: device, EventHandler: sc.handleSignalEvent, + + SyncContactsOnConnect: s.Config.SyncContactsOnStartup, } } login.Client = sc diff --git a/pkg/connector/example-config.yaml b/pkg/connector/example-config.yaml index 4c399b3..eea81f2 100644 --- a/pkg/connector/example-config.yaml +++ b/pkg/connector/example-config.yaml @@ -7,6 +7,8 @@ displayname_template: '{{or .ProfileName .PhoneNumber "Unknown user"}}' # Should avatars from the user's contact list be used? This is not safe on multi-user instances. use_contact_avatars: false +# Should the bridge request the user's contact list from the phone on startup? +sync_contacts_on_startup: true # Should the bridge sync ghost user info even if profile fetching fails? This is not safe on multi-user instances. use_outdated_profiles: false # Should the Signal user's phone number be included in the room topic in private chat portal rooms? diff --git a/pkg/signalmeow/client.go b/pkg/signalmeow/client.go index f311e9a..128e6db 100644 --- a/pkg/signalmeow/client.go +++ b/pkg/signalmeow/client.go @@ -40,6 +40,7 @@ type Client struct { ProfileCache *ProfileCache GroupCallCache *map[string]bool LastContactRequestTime time.Time + SyncContactsOnConnect bool encryptionLock sync.Mutex diff --git a/pkg/signalmeow/receiving.go b/pkg/signalmeow/receiving.go index b28a992..bfceca6 100644 --- a/pkg/signalmeow/receiving.go +++ b/pkg/signalmeow/receiving.go @@ -188,7 +188,9 @@ func (cli *Client) StartReceiveLoops(ctx context.Context) (chan SignalConnection case <-initialConnectChan: log.Info().Msg("Both websockets connected, sending contacts sync request") // TODO hacky - cli.SendContactSyncRequest(ctx) + if cli.SyncContactsOnConnect { + cli.SendContactSyncRequest(ctx) + } if cli.Store.MasterKey == nil { cli.SendStorageMasterKeyRequest(ctx) } From 610626578785f371a90c061a8aa38f9fb7195af0 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Fri, 9 Aug 2024 23:41:02 +0300 Subject: [PATCH 139/580] dbmeta: don't save revision for DMs --- pkg/signalid/dbmeta.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/signalid/dbmeta.go b/pkg/signalid/dbmeta.go index 2d85a0c..2b5a164 100644 --- a/pkg/signalid/dbmeta.go +++ b/pkg/signalid/dbmeta.go @@ -17,7 +17,7 @@ package signalid type PortalMetadata struct { - Revision uint32 `json:"revision"` + Revision uint32 `json:"revision,omitempty"` } type MessageMetadata struct { From 5d19a74fb0714891a3e1caa320673c03d3b2df17 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Fri, 9 Aug 2024 23:43:15 +0300 Subject: [PATCH 140/580] dependencies: update mautrix-go --- ROADMAP.md | 8 ++++---- go.mod | 2 +- go.sum | 4 ++-- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/ROADMAP.md b/ROADMAP.md index 9c0cedb..1695ea0 100644 --- a/ROADMAP.md +++ b/ROADMAP.md @@ -22,9 +22,9 @@ * [x] Topic * [ ] Membership actions * [ ] Join (accepting invites) - * [ ] Invite - * [ ] Leave - * [ ] Kick/Ban/Unban + * [x] Invite + * [x] Leave + * [x] Kick/Ban/Unban * [x] Group permissions * [x] Typing notifications * [x] Read receipts @@ -70,5 +70,5 @@ * [x] When receiving message * [x] Linking as secondary device * [ ] Registering as primary device - * [ ] Private chat/group creation by inviting Matrix puppet of Signal user to new room + * [x] Private chat/group creation by inviting Matrix puppet of Signal user to new room * [x] Option to use own Matrix account for messages sent from other Signal clients diff --git a/go.mod b/go.mod index c49fa0f..5aed753 100644 --- a/go.mod +++ b/go.mod @@ -15,7 +15,7 @@ require ( golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 golang.org/x/net v0.27.0 google.golang.org/protobuf v1.34.2 - maunium.net/go/mautrix v0.19.1-0.20240809135320-eb84187368b7 + maunium.net/go/mautrix v0.19.1-0.20240809204656-49b1f240edfe nhooyr.io/websocket v1.8.11 ) diff --git a/go.sum b/go.sum index 4972d7b..9a4fbef 100644 --- a/go.sum +++ b/go.sum @@ -88,7 +88,7 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= maunium.net/go/mauflag v1.0.0 h1:YiaRc0tEI3toYtJMRIfjP+jklH45uDHtT80nUamyD4M= maunium.net/go/mauflag v1.0.0/go.mod h1:nLivPOpTpHnpzEh8jEdSL9UqO9+/KBJFmNRlwKfkPeA= -maunium.net/go/mautrix v0.19.1-0.20240809135320-eb84187368b7 h1:xAq4d1rW/5WN7szBtxHNY/63EPNdji+h7FXlLGBUfJU= -maunium.net/go/mautrix v0.19.1-0.20240809135320-eb84187368b7/go.mod h1:ZWyxoQxRTBxzWIMs0kQCVogZIY0clTu33h102veCT/Q= +maunium.net/go/mautrix v0.19.1-0.20240809204656-49b1f240edfe h1:tM92VT4DcjnzqHCPFnEj6xwYJ2r2cj9zc6c1mXcSXPk= +maunium.net/go/mautrix v0.19.1-0.20240809204656-49b1f240edfe/go.mod h1:ZWyxoQxRTBxzWIMs0kQCVogZIY0clTu33h102veCT/Q= nhooyr.io/websocket v1.8.11 h1:f/qXNc2/3DpoSZkHt1DQu6rj4zGC8JmkkLkWss0MgN0= nhooyr.io/websocket v1.8.11/go.mod h1:rN9OFWIUwuxg4fR5tELlYC04bXYowCP9GX47ivo2l+c= From bf4cedb7fafddbab6e6463ecca4a91fa08f4cbb6 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Sat, 10 Aug 2024 01:40:15 +0300 Subject: [PATCH 141/580] libsignal: update to v0.55.0 --- CHANGELOG.md | 6 ++++-- pkg/libsignalgo/libsignal | 2 +- pkg/libsignalgo/libsignal-ffi.h | 7 +++++-- pkg/libsignalgo/version.go | 2 +- 4 files changed, 11 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f0c11f6..2804eb4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,8 +1,10 @@ # v0.7.0 (unreleased) -* Updated to libsignal v0.54.0. +* Updated to libsignal v0.55.0. * Rewrote bridge using bridgev2 architecture. - * It is recommended to check the config file after upgrading. + * It is recommended to check the config file after upgrading. If you have + prevented the bridge from writing to the config, you should update it + manually. # v0.6.3 (2024-07-16) diff --git a/pkg/libsignalgo/libsignal b/pkg/libsignalgo/libsignal index b86d58e..a8bc95b 160000 --- a/pkg/libsignalgo/libsignal +++ b/pkg/libsignalgo/libsignal @@ -1 +1 @@ -Subproject commit b86d58e8d61e2d6f1687bfd30bd143e3eeeaaf6f +Subproject commit a8bc95bc7ebad76ee0bd467ece3321b886cbaef7 diff --git a/pkg/libsignalgo/libsignal-ffi.h b/pkg/libsignalgo/libsignal-ffi.h index 0292867..8c443ac 100644 --- a/pkg/libsignalgo/libsignal-ffi.h +++ b/pkg/libsignalgo/libsignal-ffi.h @@ -575,7 +575,6 @@ typedef struct { } SignalCPromiseFfiCdsiLookupResponse; typedef struct { - uint32_t reconnect_count; uint8_t raw_ip_type; double duration_secs; const char *connection_info; @@ -1521,6 +1520,8 @@ SignalFfiError *signal_connection_manager_set_proxy(const SignalConnectionManage SignalFfiError *signal_connection_manager_clear_proxy(const SignalConnectionManager *connection_manager); +SignalFfiError *signal_connection_manager_on_network_change(const SignalConnectionManager *connection_manager); + SignalFfiError *signal_create_otp(const char **out, const char *username, SignalBorrowedBuffer secret); SignalFfiError *signal_create_otp_from_base64(const char **out, const char *username, const char *secret); @@ -1581,7 +1582,9 @@ SignalFfiError *signal_chat_service_auth_send(SignalCPromiseFfiChatResponse *pro SignalFfiError *signal_chat_service_auth_send_and_debug(SignalCPromiseFfiResponseAndDebugInfo *promise, const SignalTokioAsyncContext *async_runtime, const SignalChat *chat, const SignalHttpRequest *http_request, uint32_t timeout_millis); -SignalFfiError *signal_chat_server_set_listener(const SignalTokioAsyncContext *runtime, const SignalChat *chat, const SignalFfiMakeChatListenerStruct *make_listener); +SignalFfiError *signal_chat_service_set_listener_auth(const SignalTokioAsyncContext *runtime, const SignalChat *chat, const SignalFfiMakeChatListenerStruct *make_listener); + +SignalFfiError *signal_chat_service_set_listener_unauth(const SignalTokioAsyncContext *runtime, const SignalChat *chat, const SignalFfiMakeChatListenerStruct *make_listener); SignalFfiError *signal_testing_chat_service_inject_raw_server_request(const SignalChat *chat, SignalBorrowedBuffer bytes); diff --git a/pkg/libsignalgo/version.go b/pkg/libsignalgo/version.go index 59cbbd7..cb4bd77 100644 --- a/pkg/libsignalgo/version.go +++ b/pkg/libsignalgo/version.go @@ -2,4 +2,4 @@ package libsignalgo -const Version = "v0.54.0" +const Version = "v0.55.0" From efe80989af613a51d3f423e86815bea54b04b974 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Sat, 10 Aug 2024 23:31:12 +0300 Subject: [PATCH 142/580] handlematrix: return wrapped errors in some handlers This enables error notices for signalmeow send errors and better HTTP responses for start chat API requests. --- go.mod | 2 +- go.sum | 4 ++-- pkg/connector/chatinfo.go | 5 +++-- pkg/connector/handlematrix.go | 4 ++-- 4 files changed, 8 insertions(+), 7 deletions(-) diff --git a/go.mod b/go.mod index 5aed753..9bd76e8 100644 --- a/go.mod +++ b/go.mod @@ -15,7 +15,7 @@ require ( golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 golang.org/x/net v0.27.0 google.golang.org/protobuf v1.34.2 - maunium.net/go/mautrix v0.19.1-0.20240809204656-49b1f240edfe + maunium.net/go/mautrix v0.19.1-0.20240810203007-48b08ad8e91d nhooyr.io/websocket v1.8.11 ) diff --git a/go.sum b/go.sum index 9a4fbef..06bbcc3 100644 --- a/go.sum +++ b/go.sum @@ -88,7 +88,7 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= maunium.net/go/mauflag v1.0.0 h1:YiaRc0tEI3toYtJMRIfjP+jklH45uDHtT80nUamyD4M= maunium.net/go/mauflag v1.0.0/go.mod h1:nLivPOpTpHnpzEh8jEdSL9UqO9+/KBJFmNRlwKfkPeA= -maunium.net/go/mautrix v0.19.1-0.20240809204656-49b1f240edfe h1:tM92VT4DcjnzqHCPFnEj6xwYJ2r2cj9zc6c1mXcSXPk= -maunium.net/go/mautrix v0.19.1-0.20240809204656-49b1f240edfe/go.mod h1:ZWyxoQxRTBxzWIMs0kQCVogZIY0clTu33h102veCT/Q= +maunium.net/go/mautrix v0.19.1-0.20240810203007-48b08ad8e91d h1:YDx2k0hFQFoSy7u+dEZv3HsKYvDwVTaPHJHjwXBIwzk= +maunium.net/go/mautrix v0.19.1-0.20240810203007-48b08ad8e91d/go.mod h1:ZWyxoQxRTBxzWIMs0kQCVogZIY0clTu33h102veCT/Q= nhooyr.io/websocket v1.8.11 h1:f/qXNc2/3DpoSZkHt1DQu6rj4zGC8JmkkLkWss0MgN0= nhooyr.io/websocket v1.8.11/go.mod h1:rN9OFWIUwuxg4fR5tELlYC04bXYowCP9GX47ivo2l+c= diff --git a/pkg/connector/chatinfo.go b/pkg/connector/chatinfo.go index 7083701..69af735 100644 --- a/pkg/connector/chatinfo.go +++ b/pkg/connector/chatinfo.go @@ -26,6 +26,7 @@ import ( "github.com/google/uuid" "github.com/rs/zerolog" "go.mau.fi/util/ptr" + "maunium.net/go/mautrix" "maunium.net/go/mautrix/bridgev2" "maunium.net/go/mautrix/bridgev2/database" "maunium.net/go/mautrix/bridgev2/networkid" @@ -120,11 +121,11 @@ func (s *SignalClient) ResolveIdentifier(ctx context.Context, number string, cre if err != nil { number, err = bridgev2.CleanPhoneNumber(number) if err != nil { - return nil, err + return nil, bridgev2.WrapRespErr(err, mautrix.MInvalidParam) } e164Number, err = strconv.ParseUint(strings.TrimPrefix(number, "+"), 10, 64) if err != nil { - return nil, fmt.Errorf("error parsing phone number: %w", err) + return nil, bridgev2.WrapRespErr(fmt.Errorf("error parsing phone number: %w", err), mautrix.MInvalidParam) } e164String := fmt.Sprintf("+%d", e164Number) if recipient, err = s.Client.ContactByE164(ctx, e164String); err != nil { diff --git a/pkg/connector/handlematrix.go b/pkg/connector/handlematrix.go index 2b8ca26..888d702 100644 --- a/pkg/connector/handlematrix.go +++ b/pkg/connector/handlematrix.go @@ -85,7 +85,7 @@ func (s *SignalClient) HandleMatrixMessage(ctx context.Context, msg *bridgev2.Ma } err = s.sendMessage(ctx, msg.Portal.ID, &signalpb.Content{DataMessage: converted}) if err != nil { - return nil, err + return nil, bridgev2.WrapErrorInStatus(err).WithSendNotice(true) } dbMsg := &database.Message{ ID: signalid.MakeMessageID(s.Client.Store.ACI, converted.GetTimestamp()), @@ -123,7 +123,7 @@ func (s *SignalClient) HandleMatrixEdit(ctx context.Context, msg *bridgev2.Matri DataMessage: converted, }}) if err != nil { - return err + return bridgev2.WrapErrorInStatus(err).WithSendNotice(true) } msg.EditTarget.ID = signalid.MakeMessageID(s.Client.Store.ACI, converted.GetTimestamp()) msg.EditTarget.Metadata = &signalid.MessageMetadata{ContainsAttachments: len(converted.Attachments) > 0} From 6f4781fcaa9f006f03d1bd1b67a167567b4634e3 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Sat, 10 Aug 2024 23:36:19 +0300 Subject: [PATCH 143/580] signalmeow: only apply provisioning timeout to websocket step --- pkg/signalmeow/provisioning.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/pkg/signalmeow/provisioning.go b/pkg/signalmeow/provisioning.go index 1aff0cd..f3abb2c 100644 --- a/pkg/signalmeow/provisioning.go +++ b/pkg/signalmeow/provisioning.go @@ -85,9 +85,9 @@ func PerformProvisioning(ctx context.Context, deviceStore store.DeviceStore, dev go func() { defer close(c) - ctx, cancel := context.WithTimeout(ctx, 2*time.Minute) + timeoutCtx, cancel := context.WithTimeout(ctx, 2*time.Minute) defer cancel() - ws, resp, err := web.OpenWebsocket(ctx, web.WebsocketProvisioningPath) + ws, resp, err := web.OpenWebsocket(timeoutCtx, web.WebsocketProvisioningPath) if err != nil { log.Err(err).Any("resp", resp).Msg("error opening provisioning websocket") c <- ProvisioningResponse{State: StateProvisioningError, Err: err} @@ -96,7 +96,7 @@ func PerformProvisioning(ctx context.Context, deviceStore store.DeviceStore, dev defer ws.Close(websocket.StatusInternalError, "Websocket StatusInternalError") provisioningCipher := NewProvisioningCipher() - provisioningURL, err := startProvisioning(ctx, ws, provisioningCipher) + provisioningURL, err := startProvisioning(timeoutCtx, ws, provisioningCipher) if err != nil { log.Err(err).Msg("startProvisioning error") c <- ProvisioningResponse{State: StateProvisioningError, Err: err} @@ -104,7 +104,7 @@ func PerformProvisioning(ctx context.Context, deviceStore store.DeviceStore, dev } c <- ProvisioningResponse{State: StateProvisioningURLReceived, ProvisioningURL: provisioningURL, Err: err} - provisioningMessage, err := continueProvisioning(ctx, ws, provisioningCipher) + provisioningMessage, err := continueProvisioning(timeoutCtx, ws, provisioningCipher) if err != nil { log.Err(err).Msg("continueProvisioning error") c <- ProvisioningResponse{State: StateProvisioningError, Err: err} From 94ae69047b9de6b48173eda30179915e37793658 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Sun, 11 Aug 2024 17:01:05 +0300 Subject: [PATCH 144/580] msgconv/from-signal: fix panic bridging stickers --- pkg/msgconv/from-signal.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/pkg/msgconv/from-signal.go b/pkg/msgconv/from-signal.go index e4ab6dc..4b09e80 100644 --- a/pkg/msgconv/from-signal.go +++ b/pkg/msgconv/from-signal.go @@ -388,6 +388,9 @@ func (mc *MessageConverter) convertStickerToMatrix(ctx context.Context, sticker converted.Content.Body = sticker.GetEmoji() converted.Type = event.EventSticker converted.Content.MsgType = "" + if converted.Extra == nil { + converted.Extra = map[string]any{} + } // TODO fetch full pack metadata like the old bridge did? converted.Extra["fi.mau.signal.sticker"] = map[string]any{ "id": sticker.GetStickerId(), From 77c150f784ddf715f9515c444d13696ed7759bd0 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Sun, 11 Aug 2024 21:55:21 +0300 Subject: [PATCH 145/580] dependencies: update --- go.mod | 15 ++++++++------- go.sum | 30 ++++++++++++++++-------------- 2 files changed, 24 insertions(+), 21 deletions(-) diff --git a/go.mod b/go.mod index 9bd76e8..96d2b8f 100644 --- a/go.mod +++ b/go.mod @@ -10,12 +10,12 @@ require ( github.com/rs/zerolog v1.33.0 github.com/stretchr/testify v1.9.0 github.com/tidwall/gjson v1.17.3 - go.mau.fi/util v0.6.1-0.20240802175451-b430ebbffc98 - golang.org/x/crypto v0.25.0 - golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 - golang.org/x/net v0.27.0 + go.mau.fi/util v0.6.1-0.20240811184504-b00aa5c5af3a + golang.org/x/crypto v0.26.0 + golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa + golang.org/x/net v0.28.0 google.golang.org/protobuf v1.34.2 - maunium.net/go/mautrix v0.19.1-0.20240810203007-48b08ad8e91d + maunium.net/go/mautrix v0.19.1-0.20240811184947-e13771ff615e nhooyr.io/websocket v1.8.11 ) @@ -28,6 +28,7 @@ require ( github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-isatty v0.0.19 // indirect github.com/mattn/go-sqlite3 v1.14.22 // indirect + github.com/petermattis/goid v0.0.0-20240716203034-badd1c0974d6 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/rogpeppe/go-internal v1.10.0 // indirect github.com/rs/xid v1.5.0 // indirect @@ -37,8 +38,8 @@ require ( github.com/tidwall/sjson v1.2.5 // indirect github.com/yuin/goldmark v1.7.4 // indirect go.mau.fi/zeroconfig v0.1.3 // indirect - golang.org/x/sys v0.22.0 // indirect - golang.org/x/text v0.16.0 // indirect + golang.org/x/sys v0.24.0 // indirect + golang.org/x/text v0.17.0 // indirect gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect gopkg.in/natefinch/lumberjack.v2 v2.2.1 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect diff --git a/go.sum b/go.sum index 06bbcc3..cc932c2 100644 --- a/go.sum +++ b/go.sum @@ -34,6 +34,8 @@ github.com/mattn/go-pointer v0.0.1 h1:n+XhsuGeVO6MEAp7xyEukFINEa+Quek5psIR/ylA6o github.com/mattn/go-pointer v0.0.1/go.mod h1:2zXcozF6qYGgmsG+SeTZz3oAbFLdD3OWqnUbNvJZAlc= github.com/mattn/go-sqlite3 v1.14.22 h1:2gZY6PC6kBnID23Tichd1K+Z0oS6nE/XwU+Vz/5o4kU= github.com/mattn/go-sqlite3 v1.14.22/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y= +github.com/petermattis/goid v0.0.0-20240716203034-badd1c0974d6 h1:DUDJI8T/9NcGbbL+AWk6vIYlmQ8ZBS8LZqVre6zbkPQ= +github.com/petermattis/goid v0.0.0-20240716203034-badd1c0974d6/go.mod h1:pxMtw7cyUw6B2bRH0ZBANSPg+AoSud1I1iyJHI69jH4= github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= @@ -60,23 +62,23 @@ github.com/tidwall/sjson v1.2.5 h1:kLy8mja+1c9jlljvWTlSazM7cKDRfJuR/bOJhcY5NcY= github.com/tidwall/sjson v1.2.5/go.mod h1:Fvgq9kS/6ociJEDnK0Fk1cpYF4FIW6ZF7LAe+6jwd28= github.com/yuin/goldmark v1.7.4 h1:BDXOHExt+A7gwPCJgPIIq7ENvceR7we7rOS9TNoLZeg= github.com/yuin/goldmark v1.7.4/go.mod h1:uzxRWxtg69N339t3louHJ7+O03ezfj6PlliRlaOzY1E= -go.mau.fi/util v0.6.1-0.20240802175451-b430ebbffc98 h1:gJ0peWecBm6TtlxKFVIc1KbooXSCHtPfsfb2Eha5A0A= -go.mau.fi/util v0.6.1-0.20240802175451-b430ebbffc98/go.mod h1:S1juuPWGau2GctPY3FR/4ec/MDLhAG2QPhdnUwpzWIo= +go.mau.fi/util v0.6.1-0.20240811184504-b00aa5c5af3a h1:A6AeueGxoDjSSf2X8Tz8X9nQ2S65uYWGVwlvTZa7Bjs= +go.mau.fi/util v0.6.1-0.20240811184504-b00aa5c5af3a/go.mod h1:ZRiX8FK4CsqVINI+3YK50nHnc+dKhfTZNf38zI31S/0= go.mau.fi/zeroconfig v0.1.3 h1:As9wYDKmktjmNZW5i1vn8zvJlmGKHeVxHVIBMXsm4kM= go.mau.fi/zeroconfig v0.1.3/go.mod h1:NcSJkf180JT+1IId76PcMuLTNa1CzsFFZ0nBygIQM70= -golang.org/x/crypto v0.25.0 h1:ypSNr+bnYL2YhwoMt2zPxHFmbAN1KZs/njMG3hxUp30= -golang.org/x/crypto v0.25.0/go.mod h1:T+wALwcMOSE0kXgUAnPAHqTLW+XHgcELELW8VaDgm/M= -golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 h1:2dVuKD2vS7b0QIHQbpyTISPd0LeHDbnYEryqj5Q1ug8= -golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY= -golang.org/x/net v0.27.0 h1:5K3Njcw06/l2y9vpGCSdcxWOYHOUk3dVNGDXN+FvAys= -golang.org/x/net v0.27.0/go.mod h1:dDi0PyhWNoiUOrAS8uXv/vnScO4wnHQO4mj9fn/RytE= +golang.org/x/crypto v0.26.0 h1:RrRspgV4mU+YwB4FYnuBoKsUapNIL5cohGAmSH3azsw= +golang.org/x/crypto v0.26.0/go.mod h1:GY7jblb9wI+FOo5y8/S2oY4zWP07AkOJ4+jxCqdqn54= +golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa h1:ELnwvuAXPNtPk1TJRuGkI9fDTwym6AYBu0qzT8AcHdI= +golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa/go.mod h1:akd2r19cwCdwSwWeIdzYQGa/EZZyqcOdwWiwj5L5eKQ= +golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE= +golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI= -golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= -golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= +golang.org/x/sys v0.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg= +golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/text v0.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc= +golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= @@ -88,7 +90,7 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= maunium.net/go/mauflag v1.0.0 h1:YiaRc0tEI3toYtJMRIfjP+jklH45uDHtT80nUamyD4M= maunium.net/go/mauflag v1.0.0/go.mod h1:nLivPOpTpHnpzEh8jEdSL9UqO9+/KBJFmNRlwKfkPeA= -maunium.net/go/mautrix v0.19.1-0.20240810203007-48b08ad8e91d h1:YDx2k0hFQFoSy7u+dEZv3HsKYvDwVTaPHJHjwXBIwzk= -maunium.net/go/mautrix v0.19.1-0.20240810203007-48b08ad8e91d/go.mod h1:ZWyxoQxRTBxzWIMs0kQCVogZIY0clTu33h102veCT/Q= +maunium.net/go/mautrix v0.19.1-0.20240811184947-e13771ff615e h1:Hd3zTiI/xdCsKcpn4SbEqxNYtpFM2YNEj19zQiMcb1U= +maunium.net/go/mautrix v0.19.1-0.20240811184947-e13771ff615e/go.mod h1:GtFIC8z1F1EmpwYIG2QOhhg7/TwxeTX82OBhegABr9s= nhooyr.io/websocket v1.8.11 h1:f/qXNc2/3DpoSZkHt1DQu6rj4zGC8JmkkLkWss0MgN0= nhooyr.io/websocket v1.8.11/go.mod h1:rN9OFWIUwuxg4fR5tELlYC04bXYowCP9GX47ivo2l+c= From 3c483d16f372abd8bfd082ea66c430e12ad45f94 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Tue, 13 Aug 2024 01:23:18 +0300 Subject: [PATCH 146/580] signalmeow: use go:embed for protobuf compiling --- .gitattributes | 2 + .../protobuf/ContactDiscovery.pb.go | 41 +- .../protobuf/ContactDiscovery.pb.raw | 15 + pkg/signalmeow/protobuf/DeviceName.pb.go | 22 +- pkg/signalmeow/protobuf/DeviceName.pb.raw | 9 + pkg/signalmeow/protobuf/Groups.pb.go | 552 +------ pkg/signalmeow/protobuf/Groups.pb.raw | Bin 0 -> 7313 bytes pkg/signalmeow/protobuf/Provisioning.pb.go | 67 +- pkg/signalmeow/protobuf/Provisioning.pb.raw | Bin 0 -> 804 bytes pkg/signalmeow/protobuf/SignalService.pb.go | 1386 ++--------------- pkg/signalmeow/protobuf/SignalService.pb.raw | Bin 0 -> 19040 bytes pkg/signalmeow/protobuf/SignalService.proto | 3 +- .../protobuf/StickerResources.pb.go | 37 +- .../protobuf/StickerResources.pb.raw | 12 + pkg/signalmeow/protobuf/StorageService.pb.go | 401 +---- pkg/signalmeow/protobuf/StorageService.pb.raw | Bin 0 -> 5605 bytes .../protobuf/UnidentifiedDelivery.pb.go | 96 +- .../protobuf/UnidentifiedDelivery.pb.raw | Bin 0 -> 1172 bytes .../protobuf/WebSocketResources.pb.go | 57 +- .../protobuf/WebSocketResources.pb.raw | Bin 0 -> 645 bytes pkg/signalmeow/protobuf/build-protos.sh | 20 +- pkg/signalmeow/protobuf/update-protos.sh | 4 +- 22 files changed, 275 insertions(+), 2449 deletions(-) create mode 100644 .gitattributes create mode 100644 pkg/signalmeow/protobuf/ContactDiscovery.pb.raw create mode 100644 pkg/signalmeow/protobuf/DeviceName.pb.raw create mode 100644 pkg/signalmeow/protobuf/Groups.pb.raw create mode 100644 pkg/signalmeow/protobuf/Provisioning.pb.raw create mode 100644 pkg/signalmeow/protobuf/SignalService.pb.raw create mode 100644 pkg/signalmeow/protobuf/StickerResources.pb.raw create mode 100644 pkg/signalmeow/protobuf/StorageService.pb.raw create mode 100644 pkg/signalmeow/protobuf/UnidentifiedDelivery.pb.raw create mode 100644 pkg/signalmeow/protobuf/WebSocketResources.pb.raw diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..dfb4b8b --- /dev/null +++ b/.gitattributes @@ -0,0 +1,2 @@ +*.pb.go linguist-generated=true +*.pb.raw binary linguist-generated=true diff --git a/pkg/signalmeow/protobuf/ContactDiscovery.pb.go b/pkg/signalmeow/protobuf/ContactDiscovery.pb.go index b252d37..f15eba4 100644 --- a/pkg/signalmeow/protobuf/ContactDiscovery.pb.go +++ b/pkg/signalmeow/protobuf/ContactDiscovery.pb.go @@ -1,6 +1,6 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.34.1 +// protoc-gen-go v1.34.2 // protoc v3.21.12 // source: ContactDiscovery.proto @@ -16,6 +16,8 @@ import ( sync "sync" ) +import _ "embed" + const ( // Verify that this generated code is sufficiently up-to-date. _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) @@ -210,35 +212,8 @@ func (x *CDSClientResponse) GetToken() []byte { var File_ContactDiscovery_proto protoreflect.FileDescriptor -var file_ContactDiscovery_proto_rawDesc = []byte{ - 0x0a, 0x16, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x63, 0x74, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, - 0x72, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0d, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x6c, - 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x22, 0x9e, 0x02, 0x0a, 0x10, 0x43, 0x44, 0x53, 0x43, - 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x22, 0x0a, 0x0d, - 0x61, 0x63, 0x69, 0x5f, 0x75, 0x61, 0x6b, 0x5f, 0x70, 0x61, 0x69, 0x72, 0x73, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x0c, 0x52, 0x0b, 0x61, 0x63, 0x69, 0x55, 0x61, 0x6b, 0x50, 0x61, 0x69, 0x72, 0x73, - 0x12, 0x1d, 0x0a, 0x0a, 0x70, 0x72, 0x65, 0x76, 0x5f, 0x65, 0x31, 0x36, 0x34, 0x73, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x70, 0x72, 0x65, 0x76, 0x45, 0x31, 0x36, 0x34, 0x73, 0x12, - 0x1b, 0x0a, 0x09, 0x6e, 0x65, 0x77, 0x5f, 0x65, 0x31, 0x36, 0x34, 0x73, 0x18, 0x03, 0x20, 0x01, - 0x28, 0x0c, 0x52, 0x08, 0x6e, 0x65, 0x77, 0x45, 0x31, 0x36, 0x34, 0x73, 0x12, 0x23, 0x0a, 0x0d, - 0x64, 0x69, 0x73, 0x63, 0x61, 0x72, 0x64, 0x5f, 0x65, 0x31, 0x36, 0x34, 0x73, 0x18, 0x04, 0x20, - 0x01, 0x28, 0x0c, 0x52, 0x0c, 0x64, 0x69, 0x73, 0x63, 0x61, 0x72, 0x64, 0x45, 0x31, 0x36, 0x34, - 0x73, 0x12, 0x19, 0x0a, 0x08, 0x68, 0x61, 0x73, 0x5f, 0x6d, 0x6f, 0x72, 0x65, 0x18, 0x05, 0x20, - 0x01, 0x28, 0x08, 0x52, 0x07, 0x68, 0x61, 0x73, 0x4d, 0x6f, 0x72, 0x65, 0x12, 0x14, 0x0a, 0x05, - 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x74, 0x6f, 0x6b, - 0x65, 0x6e, 0x12, 0x1b, 0x0a, 0x09, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x5f, 0x61, 0x63, 0x6b, 0x18, - 0x07, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x41, 0x63, 0x6b, 0x12, - 0x37, 0x0a, 0x18, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x5f, 0x61, 0x63, 0x69, 0x73, 0x5f, 0x77, - 0x69, 0x74, 0x68, 0x6f, 0x75, 0x74, 0x5f, 0x75, 0x61, 0x6b, 0x73, 0x18, 0x08, 0x20, 0x01, 0x28, - 0x08, 0x52, 0x15, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x41, 0x63, 0x69, 0x73, 0x57, 0x69, 0x74, - 0x68, 0x6f, 0x75, 0x74, 0x55, 0x61, 0x6b, 0x73, 0x22, 0x5a, 0x0a, 0x11, 0x43, 0x44, 0x53, 0x43, - 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2f, 0x0a, - 0x14, 0x65, 0x31, 0x36, 0x34, 0x5f, 0x70, 0x6e, 0x69, 0x5f, 0x61, 0x63, 0x69, 0x5f, 0x74, 0x72, - 0x69, 0x70, 0x6c, 0x65, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x11, 0x65, 0x31, 0x36, - 0x34, 0x50, 0x6e, 0x69, 0x41, 0x63, 0x69, 0x54, 0x72, 0x69, 0x70, 0x6c, 0x65, 0x73, 0x12, 0x14, - 0x0a, 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x74, - 0x6f, 0x6b, 0x65, 0x6e, -} +//go:embed ContactDiscovery.pb.raw +var file_ContactDiscovery_proto_rawDesc []byte var ( file_ContactDiscovery_proto_rawDescOnce sync.Once @@ -253,7 +228,7 @@ func file_ContactDiscovery_proto_rawDescGZIP() []byte { } var file_ContactDiscovery_proto_msgTypes = make([]protoimpl.MessageInfo, 2) -var file_ContactDiscovery_proto_goTypes = []interface{}{ +var file_ContactDiscovery_proto_goTypes = []any{ (*CDSClientRequest)(nil), // 0: signalservice.CDSClientRequest (*CDSClientResponse)(nil), // 1: signalservice.CDSClientResponse } @@ -271,7 +246,7 @@ func file_ContactDiscovery_proto_init() { return } if !protoimpl.UnsafeEnabled { - file_ContactDiscovery_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + file_ContactDiscovery_proto_msgTypes[0].Exporter = func(v any, i int) any { switch v := v.(*CDSClientRequest); i { case 0: return &v.state @@ -283,7 +258,7 @@ func file_ContactDiscovery_proto_init() { return nil } } - file_ContactDiscovery_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + file_ContactDiscovery_proto_msgTypes[1].Exporter = func(v any, i int) any { switch v := v.(*CDSClientResponse); i { case 0: return &v.state diff --git a/pkg/signalmeow/protobuf/ContactDiscovery.pb.raw b/pkg/signalmeow/protobuf/ContactDiscovery.pb.raw new file mode 100644 index 0000000..c98f8c4 --- /dev/null +++ b/pkg/signalmeow/protobuf/ContactDiscovery.pb.raw @@ -0,0 +1,15 @@ + +ContactDiscovery.proto signalservice"ž +CDSClientRequest" + aci_uak_pairs ( R aciUakPairs + +prev_e164s ( R prevE164s + new_e164s ( RnewE164s# + discard_e164s ( R discardE164s +has_more (RhasMore +token ( Rtoken + token_ack (RtokenAck7 +return_acis_without_uaks (RreturnAcisWithoutUaks"Z +CDSClientResponse/ +e164_pni_aci_triples ( Re164PniAciTriples +token ( Rtoken \ No newline at end of file diff --git a/pkg/signalmeow/protobuf/DeviceName.pb.go b/pkg/signalmeow/protobuf/DeviceName.pb.go index 2cdca84..27dada3 100644 --- a/pkg/signalmeow/protobuf/DeviceName.pb.go +++ b/pkg/signalmeow/protobuf/DeviceName.pb.go @@ -1,6 +1,6 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.34.1 +// protoc-gen-go v1.34.2 // protoc v3.21.12 // source: DeviceName.proto @@ -16,6 +16,8 @@ import ( sync "sync" ) +import _ "embed" + const ( // Verify that this generated code is sufficiently up-to-date. _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) @@ -88,18 +90,8 @@ func (x *DeviceName) GetCiphertext() []byte { var File_DeviceName_proto protoreflect.FileDescriptor -var file_DeviceName_proto_rawDesc = []byte{ - 0x0a, 0x10, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x2e, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x12, 0x0d, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x6c, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, - 0x65, 0x22, 0x78, 0x0a, 0x0a, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, - 0x28, 0x0a, 0x0f, 0x65, 0x70, 0x68, 0x65, 0x6d, 0x65, 0x72, 0x61, 0x6c, 0x50, 0x75, 0x62, 0x6c, - 0x69, 0x63, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0f, 0x65, 0x70, 0x68, 0x65, 0x6d, 0x65, - 0x72, 0x61, 0x6c, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x12, 0x20, 0x0a, 0x0b, 0x73, 0x79, 0x6e, - 0x74, 0x68, 0x65, 0x74, 0x69, 0x63, 0x49, 0x76, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0b, - 0x73, 0x79, 0x6e, 0x74, 0x68, 0x65, 0x74, 0x69, 0x63, 0x49, 0x76, 0x12, 0x1e, 0x0a, 0x0a, 0x63, - 0x69, 0x70, 0x68, 0x65, 0x72, 0x74, 0x65, 0x78, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, - 0x0a, 0x63, 0x69, 0x70, 0x68, 0x65, 0x72, 0x74, 0x65, 0x78, 0x74, -} +//go:embed DeviceName.pb.raw +var file_DeviceName_proto_rawDesc []byte var ( file_DeviceName_proto_rawDescOnce sync.Once @@ -114,7 +106,7 @@ func file_DeviceName_proto_rawDescGZIP() []byte { } var file_DeviceName_proto_msgTypes = make([]protoimpl.MessageInfo, 1) -var file_DeviceName_proto_goTypes = []interface{}{ +var file_DeviceName_proto_goTypes = []any{ (*DeviceName)(nil), // 0: signalservice.DeviceName } var file_DeviceName_proto_depIdxs = []int32{ @@ -131,7 +123,7 @@ func file_DeviceName_proto_init() { return } if !protoimpl.UnsafeEnabled { - file_DeviceName_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + file_DeviceName_proto_msgTypes[0].Exporter = func(v any, i int) any { switch v := v.(*DeviceName); i { case 0: return &v.state diff --git a/pkg/signalmeow/protobuf/DeviceName.pb.raw b/pkg/signalmeow/protobuf/DeviceName.pb.raw new file mode 100644 index 0000000..b8aca07 --- /dev/null +++ b/pkg/signalmeow/protobuf/DeviceName.pb.raw @@ -0,0 +1,9 @@ + +DeviceName.proto signalservice"x + +DeviceName( +ephemeralPublic ( RephemeralPublic + syntheticIv ( R syntheticIv + +ciphertext ( R +ciphertext \ No newline at end of file diff --git a/pkg/signalmeow/protobuf/Groups.pb.go b/pkg/signalmeow/protobuf/Groups.pb.go index ae4b64b..e76b7c1 100644 --- a/pkg/signalmeow/protobuf/Groups.pb.go +++ b/pkg/signalmeow/protobuf/Groups.pb.go @@ -5,7 +5,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.34.1 +// protoc-gen-go v1.34.2 // protoc v3.21.12 // source: Groups.proto @@ -18,6 +18,8 @@ import ( sync "sync" ) +import _ "embed" + const ( // Verify that this generated code is sufficiently up-to-date. _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) @@ -2709,466 +2711,8 @@ func (x *GroupInviteLink_GroupInviteLinkContentsV1) GetInviteLinkPassword() []by var File_Groups_proto protoreflect.FileDescriptor -var file_Groups_proto_rawDesc = []byte{ - 0x0a, 0x0c, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xc4, - 0x01, 0x0a, 0x16, 0x41, 0x76, 0x61, 0x74, 0x61, 0x72, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x41, - 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x1e, 0x0a, 0x0a, 0x63, - 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x0a, 0x63, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x12, 0x10, 0x0a, 0x03, 0x61, - 0x63, 0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x61, 0x63, 0x6c, 0x12, 0x1c, 0x0a, - 0x09, 0x61, 0x6c, 0x67, 0x6f, 0x72, 0x69, 0x74, 0x68, 0x6d, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x09, 0x61, 0x6c, 0x67, 0x6f, 0x72, 0x69, 0x74, 0x68, 0x6d, 0x12, 0x12, 0x0a, 0x04, 0x64, - 0x61, 0x74, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x64, 0x61, 0x74, 0x65, 0x12, - 0x16, 0x0a, 0x06, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x06, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x12, 0x1c, 0x0a, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, - 0x74, 0x75, 0x72, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x73, 0x69, 0x67, 0x6e, - 0x61, 0x74, 0x75, 0x72, 0x65, 0x22, 0xe7, 0x01, 0x0a, 0x06, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, - 0x12, 0x16, 0x0a, 0x06, 0x75, 0x73, 0x65, 0x72, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, - 0x52, 0x06, 0x75, 0x73, 0x65, 0x72, 0x49, 0x64, 0x12, 0x20, 0x0a, 0x04, 0x72, 0x6f, 0x6c, 0x65, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x0c, 0x2e, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x2e, - 0x52, 0x6f, 0x6c, 0x65, 0x52, 0x04, 0x72, 0x6f, 0x6c, 0x65, 0x12, 0x1e, 0x0a, 0x0a, 0x70, 0x72, - 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x4b, 0x65, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0a, - 0x70, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x4b, 0x65, 0x79, 0x12, 0x22, 0x0a, 0x0c, 0x70, 0x72, - 0x65, 0x73, 0x65, 0x6e, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, - 0x52, 0x0c, 0x70, 0x72, 0x65, 0x73, 0x65, 0x6e, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x2a, - 0x0a, 0x10, 0x6a, 0x6f, 0x69, 0x6e, 0x65, 0x64, 0x41, 0x74, 0x52, 0x65, 0x76, 0x69, 0x73, 0x69, - 0x6f, 0x6e, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x10, 0x6a, 0x6f, 0x69, 0x6e, 0x65, 0x64, - 0x41, 0x74, 0x52, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0x33, 0x0a, 0x04, 0x52, 0x6f, - 0x6c, 0x65, 0x12, 0x0b, 0x0a, 0x07, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x00, 0x12, - 0x0b, 0x0a, 0x07, 0x44, 0x45, 0x46, 0x41, 0x55, 0x4c, 0x54, 0x10, 0x01, 0x12, 0x11, 0x0a, 0x0d, - 0x41, 0x44, 0x4d, 0x49, 0x4e, 0x49, 0x53, 0x54, 0x52, 0x41, 0x54, 0x4f, 0x52, 0x10, 0x02, 0x22, - 0x74, 0x0a, 0x0d, 0x50, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, - 0x12, 0x1f, 0x0a, 0x06, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x07, 0x2e, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x52, 0x06, 0x6d, 0x65, 0x6d, 0x62, 0x65, - 0x72, 0x12, 0x24, 0x0a, 0x0d, 0x61, 0x64, 0x64, 0x65, 0x64, 0x42, 0x79, 0x55, 0x73, 0x65, 0x72, - 0x49, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0d, 0x61, 0x64, 0x64, 0x65, 0x64, 0x42, - 0x79, 0x55, 0x73, 0x65, 0x72, 0x49, 0x64, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, - 0x74, 0x61, 0x6d, 0x70, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, - 0x73, 0x74, 0x61, 0x6d, 0x70, 0x22, 0x8c, 0x01, 0x0a, 0x10, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x69, 0x6e, 0x67, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x12, 0x16, 0x0a, 0x06, 0x75, 0x73, - 0x65, 0x72, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x75, 0x73, 0x65, 0x72, - 0x49, 0x64, 0x12, 0x1e, 0x0a, 0x0a, 0x70, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x4b, 0x65, 0x79, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0a, 0x70, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x4b, - 0x65, 0x79, 0x12, 0x22, 0x0a, 0x0c, 0x70, 0x72, 0x65, 0x73, 0x65, 0x6e, 0x74, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0c, 0x70, 0x72, 0x65, 0x73, 0x65, 0x6e, - 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, - 0x61, 0x6d, 0x70, 0x18, 0x04, 0x20, 0x01, 0x28, 0x04, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, - 0x74, 0x61, 0x6d, 0x70, 0x22, 0x44, 0x0a, 0x0c, 0x42, 0x61, 0x6e, 0x6e, 0x65, 0x64, 0x4d, 0x65, - 0x6d, 0x62, 0x65, 0x72, 0x12, 0x16, 0x0a, 0x06, 0x75, 0x73, 0x65, 0x72, 0x49, 0x64, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x75, 0x73, 0x65, 0x72, 0x49, 0x64, 0x12, 0x1c, 0x0a, 0x09, - 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, - 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x22, 0xae, 0x02, 0x0a, 0x0d, 0x41, - 0x63, 0x63, 0x65, 0x73, 0x73, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x12, 0x3d, 0x0a, 0x0a, - 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, - 0x32, 0x1d, 0x2e, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, - 0x2e, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x52, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x52, - 0x0a, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x12, 0x37, 0x0a, 0x07, 0x6d, - 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1d, 0x2e, 0x41, - 0x63, 0x63, 0x65, 0x73, 0x73, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x2e, 0x41, 0x63, 0x63, - 0x65, 0x73, 0x73, 0x52, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x52, 0x07, 0x6d, 0x65, 0x6d, - 0x62, 0x65, 0x72, 0x73, 0x12, 0x4b, 0x0a, 0x11, 0x61, 0x64, 0x64, 0x46, 0x72, 0x6f, 0x6d, 0x49, - 0x6e, 0x76, 0x69, 0x74, 0x65, 0x4c, 0x69, 0x6e, 0x6b, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, - 0x1d, 0x2e, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x2e, - 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x52, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x52, 0x11, - 0x61, 0x64, 0x64, 0x46, 0x72, 0x6f, 0x6d, 0x49, 0x6e, 0x76, 0x69, 0x74, 0x65, 0x4c, 0x69, 0x6e, - 0x6b, 0x22, 0x58, 0x0a, 0x0e, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x52, 0x65, 0x71, 0x75, 0x69, - 0x72, 0x65, 0x64, 0x12, 0x0b, 0x0a, 0x07, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x00, - 0x12, 0x07, 0x0a, 0x03, 0x41, 0x4e, 0x59, 0x10, 0x01, 0x12, 0x0a, 0x0a, 0x06, 0x4d, 0x45, 0x4d, - 0x42, 0x45, 0x52, 0x10, 0x02, 0x12, 0x11, 0x0a, 0x0d, 0x41, 0x44, 0x4d, 0x49, 0x4e, 0x49, 0x53, - 0x54, 0x52, 0x41, 0x54, 0x4f, 0x52, 0x10, 0x03, 0x12, 0x11, 0x0a, 0x0d, 0x55, 0x4e, 0x53, 0x41, - 0x54, 0x49, 0x53, 0x46, 0x49, 0x41, 0x42, 0x4c, 0x45, 0x10, 0x04, 0x22, 0xb4, 0x04, 0x0a, 0x05, - 0x47, 0x72, 0x6f, 0x75, 0x70, 0x12, 0x1c, 0x0a, 0x09, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, - 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, - 0x4b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x0c, 0x52, 0x05, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x61, 0x76, 0x61, - 0x74, 0x61, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x61, 0x76, 0x61, 0x74, 0x61, - 0x72, 0x12, 0x3c, 0x0a, 0x19, 0x64, 0x69, 0x73, 0x61, 0x70, 0x70, 0x65, 0x61, 0x72, 0x69, 0x6e, - 0x67, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x54, 0x69, 0x6d, 0x65, 0x72, 0x18, 0x04, - 0x20, 0x01, 0x28, 0x0c, 0x52, 0x19, 0x64, 0x69, 0x73, 0x61, 0x70, 0x70, 0x65, 0x61, 0x72, 0x69, - 0x6e, 0x67, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x54, 0x69, 0x6d, 0x65, 0x72, 0x12, - 0x34, 0x0a, 0x0d, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, - 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x43, - 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x52, 0x0d, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x43, 0x6f, - 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x12, 0x1a, 0x0a, 0x08, 0x72, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, - 0x6e, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x08, 0x72, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, - 0x6e, 0x12, 0x21, 0x0a, 0x07, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x18, 0x07, 0x20, 0x03, - 0x28, 0x0b, 0x32, 0x07, 0x2e, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x52, 0x07, 0x6d, 0x65, 0x6d, - 0x62, 0x65, 0x72, 0x73, 0x12, 0x36, 0x0a, 0x0e, 0x70, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x4d, - 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x18, 0x08, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x50, - 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x52, 0x0e, 0x70, 0x65, - 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x12, 0x3f, 0x0a, 0x11, - 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, - 0x73, 0x18, 0x09, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x69, 0x6e, 0x67, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x52, 0x11, 0x72, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x12, 0x2e, 0x0a, - 0x12, 0x69, 0x6e, 0x76, 0x69, 0x74, 0x65, 0x4c, 0x69, 0x6e, 0x6b, 0x50, 0x61, 0x73, 0x73, 0x77, - 0x6f, 0x72, 0x64, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x12, 0x69, 0x6e, 0x76, 0x69, 0x74, - 0x65, 0x4c, 0x69, 0x6e, 0x6b, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x12, 0x20, 0x0a, - 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x0b, 0x20, 0x01, - 0x28, 0x0c, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, - 0x2c, 0x0a, 0x11, 0x61, 0x6e, 0x6e, 0x6f, 0x75, 0x6e, 0x63, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, - 0x4f, 0x6e, 0x6c, 0x79, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x08, 0x52, 0x11, 0x61, 0x6e, 0x6e, 0x6f, - 0x75, 0x6e, 0x63, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x4f, 0x6e, 0x6c, 0x79, 0x12, 0x33, 0x0a, - 0x0d, 0x62, 0x61, 0x6e, 0x6e, 0x65, 0x64, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x18, 0x0d, - 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x42, 0x61, 0x6e, 0x6e, 0x65, 0x64, 0x4d, 0x65, 0x6d, - 0x62, 0x65, 0x72, 0x52, 0x0d, 0x62, 0x61, 0x6e, 0x6e, 0x65, 0x64, 0x4d, 0x65, 0x6d, 0x62, 0x65, - 0x72, 0x73, 0x22, 0xcc, 0x21, 0x0a, 0x0b, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x43, 0x68, 0x61, 0x6e, - 0x67, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x0c, 0x52, 0x07, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x28, 0x0a, 0x0f, - 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0f, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x53, 0x69, 0x67, - 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, - 0x45, 0x70, 0x6f, 0x63, 0x68, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0b, 0x63, 0x68, 0x61, - 0x6e, 0x67, 0x65, 0x45, 0x70, 0x6f, 0x63, 0x68, 0x1a, 0xd6, 0x20, 0x0a, 0x07, 0x41, 0x63, 0x74, - 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x28, 0x0a, 0x0f, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x53, 0x65, - 0x72, 0x76, 0x69, 0x63, 0x65, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0f, 0x73, - 0x6f, 0x75, 0x72, 0x63, 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x49, 0x64, 0x12, 0x1a, - 0x0a, 0x08, 0x72, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, - 0x52, 0x08, 0x72, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x44, 0x0a, 0x0a, 0x61, 0x64, - 0x64, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x24, - 0x2e, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x2e, 0x41, 0x63, 0x74, - 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x41, 0x64, 0x64, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x41, 0x63, - 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0a, 0x61, 0x64, 0x64, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, - 0x12, 0x4d, 0x0a, 0x0d, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, - 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x43, - 0x68, 0x61, 0x6e, 0x67, 0x65, 0x2e, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x44, 0x65, - 0x6c, 0x65, 0x74, 0x65, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, - 0x52, 0x0d, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x12, - 0x59, 0x0a, 0x11, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x52, - 0x6f, 0x6c, 0x65, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x47, 0x72, 0x6f, - 0x75, 0x70, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x2e, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, - 0x2e, 0x4d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x52, 0x6f, 0x6c, - 0x65, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x11, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x4d, - 0x65, 0x6d, 0x62, 0x65, 0x72, 0x52, 0x6f, 0x6c, 0x65, 0x73, 0x12, 0x6b, 0x0a, 0x17, 0x6d, 0x6f, - 0x64, 0x69, 0x66, 0x79, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, - 0x65, 0x4b, 0x65, 0x79, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x31, 0x2e, 0x47, 0x72, - 0x6f, 0x75, 0x70, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x2e, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, - 0x73, 0x2e, 0x4d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x50, 0x72, - 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x4b, 0x65, 0x79, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x17, - 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x50, 0x72, 0x6f, 0x66, - 0x69, 0x6c, 0x65, 0x4b, 0x65, 0x79, 0x73, 0x12, 0x59, 0x0a, 0x11, 0x61, 0x64, 0x64, 0x50, 0x65, - 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x18, 0x07, 0x20, 0x03, - 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, - 0x2e, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x41, 0x64, 0x64, 0x50, 0x65, 0x6e, 0x64, - 0x69, 0x6e, 0x67, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, - 0x11, 0x61, 0x64, 0x64, 0x50, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x4d, 0x65, 0x6d, 0x62, 0x65, - 0x72, 0x73, 0x12, 0x62, 0x0a, 0x14, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x50, 0x65, 0x6e, 0x64, - 0x69, 0x6e, 0x67, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x18, 0x08, 0x20, 0x03, 0x28, 0x0b, - 0x32, 0x2e, 0x2e, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x2e, 0x41, - 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x50, 0x65, 0x6e, - 0x64, 0x69, 0x6e, 0x67, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, - 0x52, 0x14, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x50, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x4d, - 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x12, 0x65, 0x0a, 0x15, 0x70, 0x72, 0x6f, 0x6d, 0x6f, 0x74, - 0x65, 0x50, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x18, - 0x09, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2f, 0x2e, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x43, 0x68, 0x61, - 0x6e, 0x67, 0x65, 0x2e, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x50, 0x72, 0x6f, 0x6d, - 0x6f, 0x74, 0x65, 0x50, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, - 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x15, 0x70, 0x72, 0x6f, 0x6d, 0x6f, 0x74, 0x65, 0x50, - 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x12, 0x48, 0x0a, - 0x0b, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x54, 0x69, 0x74, 0x6c, 0x65, 0x18, 0x0a, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x26, 0x2e, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, - 0x2e, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x4d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x54, - 0x69, 0x74, 0x6c, 0x65, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0b, 0x6d, 0x6f, 0x64, 0x69, - 0x66, 0x79, 0x54, 0x69, 0x74, 0x6c, 0x65, 0x12, 0x4b, 0x0a, 0x0c, 0x6d, 0x6f, 0x64, 0x69, 0x66, - 0x79, 0x41, 0x76, 0x61, 0x74, 0x61, 0x72, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x27, 0x2e, - 0x47, 0x72, 0x6f, 0x75, 0x70, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x2e, 0x41, 0x63, 0x74, 0x69, - 0x6f, 0x6e, 0x73, 0x2e, 0x4d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x41, 0x76, 0x61, 0x74, 0x61, 0x72, - 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0c, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x41, 0x76, - 0x61, 0x74, 0x61, 0x72, 0x12, 0x84, 0x01, 0x0a, 0x1f, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x44, - 0x69, 0x73, 0x61, 0x70, 0x70, 0x65, 0x61, 0x72, 0x69, 0x6e, 0x67, 0x4d, 0x65, 0x73, 0x73, 0x61, - 0x67, 0x65, 0x73, 0x54, 0x69, 0x6d, 0x65, 0x72, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x3a, - 0x2e, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x2e, 0x41, 0x63, 0x74, - 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x4d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x44, 0x69, 0x73, 0x61, 0x70, - 0x70, 0x65, 0x61, 0x72, 0x69, 0x6e, 0x67, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x54, - 0x69, 0x6d, 0x65, 0x72, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x1f, 0x6d, 0x6f, 0x64, 0x69, - 0x66, 0x79, 0x44, 0x69, 0x73, 0x61, 0x70, 0x70, 0x65, 0x61, 0x72, 0x69, 0x6e, 0x67, 0x4d, 0x65, - 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x54, 0x69, 0x6d, 0x65, 0x72, 0x12, 0x70, 0x0a, 0x16, 0x6d, - 0x6f, 0x64, 0x69, 0x66, 0x79, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x41, - 0x63, 0x63, 0x65, 0x73, 0x73, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x38, 0x2e, 0x47, 0x72, - 0x6f, 0x75, 0x70, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x2e, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, - 0x73, 0x2e, 0x4d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, - 0x65, 0x73, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x41, - 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x16, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x41, 0x74, 0x74, - 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x12, 0x65, 0x0a, - 0x12, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x41, 0x63, 0x63, - 0x65, 0x73, 0x73, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x35, 0x2e, 0x47, 0x72, 0x6f, 0x75, - 0x70, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x2e, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, - 0x4d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x41, 0x63, 0x63, - 0x65, 0x73, 0x73, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, - 0x52, 0x12, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x41, 0x63, - 0x63, 0x65, 0x73, 0x73, 0x12, 0x85, 0x01, 0x0a, 0x1d, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x41, - 0x64, 0x64, 0x46, 0x72, 0x6f, 0x6d, 0x49, 0x6e, 0x76, 0x69, 0x74, 0x65, 0x4c, 0x69, 0x6e, 0x6b, - 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x3f, 0x2e, 0x47, - 0x72, 0x6f, 0x75, 0x70, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x2e, 0x41, 0x63, 0x74, 0x69, 0x6f, - 0x6e, 0x73, 0x2e, 0x4d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x41, 0x64, 0x64, 0x46, 0x72, 0x6f, 0x6d, - 0x49, 0x6e, 0x76, 0x69, 0x74, 0x65, 0x4c, 0x69, 0x6e, 0x6b, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, - 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x1d, 0x6d, - 0x6f, 0x64, 0x69, 0x66, 0x79, 0x41, 0x64, 0x64, 0x46, 0x72, 0x6f, 0x6d, 0x49, 0x6e, 0x76, 0x69, - 0x74, 0x65, 0x4c, 0x69, 0x6e, 0x6b, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x12, 0x62, 0x0a, 0x14, - 0x61, 0x64, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x4d, 0x65, 0x6d, - 0x62, 0x65, 0x72, 0x73, 0x18, 0x10, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2e, 0x2e, 0x47, 0x72, 0x6f, - 0x75, 0x70, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x2e, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, - 0x2e, 0x41, 0x64, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x4d, 0x65, - 0x6d, 0x62, 0x65, 0x72, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x14, 0x61, 0x64, 0x64, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, - 0x12, 0x6b, 0x0a, 0x17, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x69, 0x6e, 0x67, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x18, 0x11, 0x20, 0x03, 0x28, - 0x0b, 0x32, 0x31, 0x2e, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x2e, - 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x41, 0x63, - 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x17, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x12, 0x6e, 0x0a, - 0x18, 0x70, 0x72, 0x6f, 0x6d, 0x6f, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x69, - 0x6e, 0x67, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x18, 0x12, 0x20, 0x03, 0x28, 0x0b, 0x32, - 0x32, 0x2e, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x2e, 0x41, 0x63, - 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x50, 0x72, 0x6f, 0x6d, 0x6f, 0x74, 0x65, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x41, 0x63, 0x74, - 0x69, 0x6f, 0x6e, 0x52, 0x18, 0x70, 0x72, 0x6f, 0x6d, 0x6f, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x12, 0x6f, 0x0a, - 0x18, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x49, 0x6e, 0x76, 0x69, 0x74, 0x65, 0x4c, 0x69, 0x6e, - 0x6b, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x18, 0x13, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x33, 0x2e, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x2e, 0x41, 0x63, - 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x4d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x49, 0x6e, 0x76, 0x69, - 0x74, 0x65, 0x4c, 0x69, 0x6e, 0x6b, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x41, 0x63, - 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x18, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x49, 0x6e, 0x76, 0x69, - 0x74, 0x65, 0x4c, 0x69, 0x6e, 0x6b, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x12, 0x5a, - 0x0a, 0x11, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, - 0x69, 0x6f, 0x6e, 0x18, 0x14, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2c, 0x2e, 0x47, 0x72, 0x6f, 0x75, - 0x70, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x2e, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, - 0x4d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, - 0x6e, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x11, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x44, - 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x6c, 0x0a, 0x17, 0x6d, 0x6f, - 0x64, 0x69, 0x66, 0x79, 0x41, 0x6e, 0x6e, 0x6f, 0x75, 0x6e, 0x63, 0x65, 0x6d, 0x65, 0x6e, 0x74, - 0x73, 0x4f, 0x6e, 0x6c, 0x79, 0x18, 0x15, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x32, 0x2e, 0x47, 0x72, - 0x6f, 0x75, 0x70, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x2e, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, - 0x73, 0x2e, 0x4d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x41, 0x6e, 0x6e, 0x6f, 0x75, 0x6e, 0x63, 0x65, - 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x4f, 0x6e, 0x6c, 0x79, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, - 0x17, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x41, 0x6e, 0x6e, 0x6f, 0x75, 0x6e, 0x63, 0x65, 0x6d, - 0x65, 0x6e, 0x74, 0x73, 0x4f, 0x6e, 0x6c, 0x79, 0x12, 0x56, 0x0a, 0x10, 0x61, 0x64, 0x64, 0x42, - 0x61, 0x6e, 0x6e, 0x65, 0x64, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x18, 0x16, 0x20, 0x03, - 0x28, 0x0b, 0x32, 0x2a, 0x2e, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, - 0x2e, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x41, 0x64, 0x64, 0x42, 0x61, 0x6e, 0x6e, - 0x65, 0x64, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x10, - 0x61, 0x64, 0x64, 0x42, 0x61, 0x6e, 0x6e, 0x65, 0x64, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, - 0x12, 0x5f, 0x0a, 0x13, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x42, 0x61, 0x6e, 0x6e, 0x65, 0x64, - 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x18, 0x17, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2d, 0x2e, - 0x47, 0x72, 0x6f, 0x75, 0x70, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x2e, 0x41, 0x63, 0x74, 0x69, - 0x6f, 0x6e, 0x73, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x42, 0x61, 0x6e, 0x6e, 0x65, 0x64, - 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x13, 0x64, 0x65, - 0x6c, 0x65, 0x74, 0x65, 0x42, 0x61, 0x6e, 0x6e, 0x65, 0x64, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, - 0x73, 0x12, 0x81, 0x01, 0x0a, 0x1b, 0x70, 0x72, 0x6f, 0x6d, 0x6f, 0x74, 0x65, 0x50, 0x65, 0x6e, - 0x64, 0x69, 0x6e, 0x67, 0x50, 0x6e, 0x69, 0x41, 0x63, 0x69, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, - 0x73, 0x18, 0x18, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x3f, 0x2e, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x43, - 0x68, 0x61, 0x6e, 0x67, 0x65, 0x2e, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x50, 0x72, - 0x6f, 0x6d, 0x6f, 0x74, 0x65, 0x50, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x50, 0x6e, 0x69, 0x41, - 0x63, 0x69, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x4b, - 0x65, 0x79, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x1b, 0x70, 0x72, 0x6f, 0x6d, 0x6f, 0x74, - 0x65, 0x50, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x50, 0x6e, 0x69, 0x41, 0x63, 0x69, 0x4d, 0x65, - 0x6d, 0x62, 0x65, 0x72, 0x73, 0x1a, 0x60, 0x0a, 0x0f, 0x41, 0x64, 0x64, 0x4d, 0x65, 0x6d, 0x62, - 0x65, 0x72, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1d, 0x0a, 0x05, 0x61, 0x64, 0x64, 0x65, - 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x07, 0x2e, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, - 0x52, 0x05, 0x61, 0x64, 0x64, 0x65, 0x64, 0x12, 0x2e, 0x0a, 0x12, 0x6a, 0x6f, 0x69, 0x6e, 0x46, - 0x72, 0x6f, 0x6d, 0x49, 0x6e, 0x76, 0x69, 0x74, 0x65, 0x4c, 0x69, 0x6e, 0x6b, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x08, 0x52, 0x12, 0x6a, 0x6f, 0x69, 0x6e, 0x46, 0x72, 0x6f, 0x6d, 0x49, 0x6e, 0x76, - 0x69, 0x74, 0x65, 0x4c, 0x69, 0x6e, 0x6b, 0x1a, 0x3a, 0x0a, 0x12, 0x44, 0x65, 0x6c, 0x65, 0x74, - 0x65, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x24, 0x0a, - 0x0d, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x55, 0x73, 0x65, 0x72, 0x49, 0x64, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0d, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x55, 0x73, 0x65, - 0x72, 0x49, 0x64, 0x1a, 0x52, 0x0a, 0x16, 0x4d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x4d, 0x65, 0x6d, - 0x62, 0x65, 0x72, 0x52, 0x6f, 0x6c, 0x65, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x16, 0x0a, - 0x06, 0x75, 0x73, 0x65, 0x72, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x75, - 0x73, 0x65, 0x72, 0x49, 0x64, 0x12, 0x20, 0x0a, 0x04, 0x72, 0x6f, 0x6c, 0x65, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x0e, 0x32, 0x0c, 0x2e, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x2e, 0x52, 0x6f, 0x6c, - 0x65, 0x52, 0x04, 0x72, 0x6f, 0x6c, 0x65, 0x1a, 0x7c, 0x0a, 0x1c, 0x4d, 0x6f, 0x64, 0x69, 0x66, - 0x79, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x4b, 0x65, - 0x79, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x22, 0x0a, 0x0c, 0x70, 0x72, 0x65, 0x73, 0x65, - 0x6e, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0c, 0x70, - 0x72, 0x65, 0x73, 0x65, 0x6e, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x17, 0x0a, 0x07, 0x75, - 0x73, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x75, 0x73, - 0x65, 0x72, 0x49, 0x64, 0x12, 0x1f, 0x0a, 0x0b, 0x70, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x5f, - 0x6b, 0x65, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0a, 0x70, 0x72, 0x6f, 0x66, 0x69, - 0x6c, 0x65, 0x4b, 0x65, 0x79, 0x1a, 0x3e, 0x0a, 0x16, 0x41, 0x64, 0x64, 0x50, 0x65, 0x6e, 0x64, - 0x69, 0x6e, 0x67, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, - 0x24, 0x0a, 0x05, 0x61, 0x64, 0x64, 0x65, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, - 0x2e, 0x50, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x52, 0x05, - 0x61, 0x64, 0x64, 0x65, 0x64, 0x1a, 0x41, 0x0a, 0x19, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x50, - 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x41, 0x63, 0x74, 0x69, - 0x6f, 0x6e, 0x12, 0x24, 0x0a, 0x0d, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x55, 0x73, 0x65, - 0x72, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0d, 0x64, 0x65, 0x6c, 0x65, 0x74, - 0x65, 0x64, 0x55, 0x73, 0x65, 0x72, 0x49, 0x64, 0x1a, 0x7a, 0x0a, 0x1a, 0x50, 0x72, 0x6f, 0x6d, - 0x6f, 0x74, 0x65, 0x50, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, - 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x22, 0x0a, 0x0c, 0x70, 0x72, 0x65, 0x73, 0x65, 0x6e, - 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0c, 0x70, 0x72, - 0x65, 0x73, 0x65, 0x6e, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x17, 0x0a, 0x07, 0x75, 0x73, - 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x75, 0x73, 0x65, - 0x72, 0x49, 0x64, 0x12, 0x1f, 0x0a, 0x0b, 0x70, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x5f, 0x6b, - 0x65, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0a, 0x70, 0x72, 0x6f, 0x66, 0x69, 0x6c, - 0x65, 0x4b, 0x65, 0x79, 0x1a, 0x9a, 0x01, 0x0a, 0x2a, 0x50, 0x72, 0x6f, 0x6d, 0x6f, 0x74, 0x65, - 0x50, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x50, 0x6e, 0x69, 0x41, 0x63, 0x69, 0x4d, 0x65, 0x6d, - 0x62, 0x65, 0x72, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x4b, 0x65, 0x79, 0x41, 0x63, 0x74, - 0x69, 0x6f, 0x6e, 0x12, 0x22, 0x0a, 0x0c, 0x70, 0x72, 0x65, 0x73, 0x65, 0x6e, 0x74, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0c, 0x70, 0x72, 0x65, 0x73, 0x65, - 0x6e, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x16, 0x0a, 0x06, 0x75, 0x73, 0x65, 0x72, 0x49, - 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x75, 0x73, 0x65, 0x72, 0x49, 0x64, 0x12, - 0x10, 0x0a, 0x03, 0x70, 0x6e, 0x69, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x03, 0x70, 0x6e, - 0x69, 0x12, 0x1e, 0x0a, 0x0a, 0x70, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x4b, 0x65, 0x79, 0x18, - 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0a, 0x70, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x4b, 0x65, - 0x79, 0x1a, 0x44, 0x0a, 0x19, 0x41, 0x64, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x69, - 0x6e, 0x67, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x27, - 0x0a, 0x05, 0x61, 0x64, 0x64, 0x65, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, - 0x52, 0x05, 0x61, 0x64, 0x64, 0x65, 0x64, 0x1a, 0x44, 0x0a, 0x1c, 0x44, 0x65, 0x6c, 0x65, 0x74, - 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x4d, 0x65, 0x6d, 0x62, 0x65, - 0x72, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x24, 0x0a, 0x0d, 0x64, 0x65, 0x6c, 0x65, 0x74, - 0x65, 0x64, 0x55, 0x73, 0x65, 0x72, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0d, - 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x55, 0x73, 0x65, 0x72, 0x49, 0x64, 0x1a, 0x59, 0x0a, - 0x1d, 0x50, 0x72, 0x6f, 0x6d, 0x6f, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x69, - 0x6e, 0x67, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x16, - 0x0a, 0x06, 0x75, 0x73, 0x65, 0x72, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, - 0x75, 0x73, 0x65, 0x72, 0x49, 0x64, 0x12, 0x20, 0x0a, 0x04, 0x72, 0x6f, 0x6c, 0x65, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x0e, 0x32, 0x0c, 0x2e, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x2e, 0x52, 0x6f, - 0x6c, 0x65, 0x52, 0x04, 0x72, 0x6f, 0x6c, 0x65, 0x1a, 0x3c, 0x0a, 0x15, 0x41, 0x64, 0x64, 0x42, - 0x61, 0x6e, 0x6e, 0x65, 0x64, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x41, 0x63, 0x74, 0x69, 0x6f, - 0x6e, 0x12, 0x23, 0x0a, 0x05, 0x61, 0x64, 0x64, 0x65, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x0d, 0x2e, 0x42, 0x61, 0x6e, 0x6e, 0x65, 0x64, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x52, - 0x05, 0x61, 0x64, 0x64, 0x65, 0x64, 0x1a, 0x40, 0x0a, 0x18, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, - 0x42, 0x61, 0x6e, 0x6e, 0x65, 0x64, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x41, 0x63, 0x74, 0x69, - 0x6f, 0x6e, 0x12, 0x24, 0x0a, 0x0d, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x55, 0x73, 0x65, - 0x72, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0d, 0x64, 0x65, 0x6c, 0x65, 0x74, - 0x65, 0x64, 0x55, 0x73, 0x65, 0x72, 0x49, 0x64, 0x1a, 0x29, 0x0a, 0x11, 0x4d, 0x6f, 0x64, 0x69, - 0x66, 0x79, 0x54, 0x69, 0x74, 0x6c, 0x65, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x14, 0x0a, - 0x05, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x74, 0x69, - 0x74, 0x6c, 0x65, 0x1a, 0x3b, 0x0a, 0x17, 0x4d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x44, 0x65, 0x73, - 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x20, - 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x0c, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, - 0x1a, 0x2c, 0x0a, 0x12, 0x4d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x41, 0x76, 0x61, 0x74, 0x61, 0x72, - 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x16, 0x0a, 0x06, 0x61, 0x76, 0x61, 0x74, 0x61, 0x72, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x61, 0x76, 0x61, 0x74, 0x61, 0x72, 0x1a, 0x3d, - 0x0a, 0x25, 0x4d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x44, 0x69, 0x73, 0x61, 0x70, 0x70, 0x65, 0x61, - 0x72, 0x69, 0x6e, 0x67, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x54, 0x69, 0x6d, 0x65, - 0x72, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x69, 0x6d, 0x65, 0x72, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x74, 0x69, 0x6d, 0x65, 0x72, 0x1a, 0x70, 0x0a, - 0x23, 0x4d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, - 0x73, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x41, 0x63, - 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x49, 0x0a, 0x10, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, - 0x65, 0x73, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1d, - 0x2e, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x2e, 0x41, - 0x63, 0x63, 0x65, 0x73, 0x73, 0x52, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x52, 0x10, 0x61, - 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x1a, - 0x67, 0x0a, 0x20, 0x4d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, - 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x41, 0x63, 0x74, - 0x69, 0x6f, 0x6e, 0x12, 0x43, 0x0a, 0x0d, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x41, 0x63, - 0x63, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1d, 0x2e, 0x41, 0x63, 0x63, - 0x65, 0x73, 0x73, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x2e, 0x41, 0x63, 0x63, 0x65, 0x73, - 0x73, 0x52, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x52, 0x0d, 0x6d, 0x65, 0x6d, 0x62, 0x65, - 0x72, 0x73, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x1a, 0x85, 0x01, 0x0a, 0x2a, 0x4d, 0x6f, 0x64, - 0x69, 0x66, 0x79, 0x41, 0x64, 0x64, 0x46, 0x72, 0x6f, 0x6d, 0x49, 0x6e, 0x76, 0x69, 0x74, 0x65, - 0x4c, 0x69, 0x6e, 0x6b, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x6f, - 0x6c, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x57, 0x0a, 0x17, 0x61, 0x64, 0x64, 0x46, 0x72, - 0x6f, 0x6d, 0x49, 0x6e, 0x76, 0x69, 0x74, 0x65, 0x4c, 0x69, 0x6e, 0x6b, 0x41, 0x63, 0x63, 0x65, - 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1d, 0x2e, 0x41, 0x63, 0x63, 0x65, 0x73, - 0x73, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x2e, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x52, - 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x52, 0x17, 0x61, 0x64, 0x64, 0x46, 0x72, 0x6f, 0x6d, - 0x49, 0x6e, 0x76, 0x69, 0x74, 0x65, 0x4c, 0x69, 0x6e, 0x6b, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, - 0x1a, 0x50, 0x0a, 0x1e, 0x4d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x49, 0x6e, 0x76, 0x69, 0x74, 0x65, - 0x4c, 0x69, 0x6e, 0x6b, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x41, 0x63, 0x74, 0x69, - 0x6f, 0x6e, 0x12, 0x2e, 0x0a, 0x12, 0x69, 0x6e, 0x76, 0x69, 0x74, 0x65, 0x4c, 0x69, 0x6e, 0x6b, - 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x12, - 0x69, 0x6e, 0x76, 0x69, 0x74, 0x65, 0x4c, 0x69, 0x6e, 0x6b, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, - 0x72, 0x64, 0x1a, 0x4d, 0x0a, 0x1d, 0x4d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x41, 0x6e, 0x6e, 0x6f, - 0x75, 0x6e, 0x63, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x4f, 0x6e, 0x6c, 0x79, 0x41, 0x63, 0x74, - 0x69, 0x6f, 0x6e, 0x12, 0x2c, 0x0a, 0x11, 0x61, 0x6e, 0x6e, 0x6f, 0x75, 0x6e, 0x63, 0x65, 0x6d, - 0x65, 0x6e, 0x74, 0x73, 0x4f, 0x6e, 0x6c, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x11, - 0x61, 0x6e, 0x6e, 0x6f, 0x75, 0x6e, 0x63, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x4f, 0x6e, 0x6c, - 0x79, 0x22, 0x73, 0x0a, 0x0d, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x12, 0x1c, 0x0a, 0x05, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x06, 0x2e, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x52, 0x05, 0x67, 0x72, 0x6f, 0x75, 0x70, - 0x12, 0x44, 0x0a, 0x1d, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x53, 0x65, 0x6e, 0x64, 0x45, 0x6e, 0x64, - 0x6f, 0x72, 0x73, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x1d, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x53, 0x65, - 0x6e, 0x64, 0x45, 0x6e, 0x64, 0x6f, 0x72, 0x73, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x84, 0x02, 0x0a, 0x0c, 0x47, 0x72, 0x6f, 0x75, 0x70, - 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x12, 0x42, 0x0a, 0x0c, 0x67, 0x72, 0x6f, 0x75, 0x70, - 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1e, 0x2e, - 0x47, 0x72, 0x6f, 0x75, 0x70, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x2e, 0x47, 0x72, 0x6f, - 0x75, 0x70, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x0c, 0x67, - 0x72, 0x6f, 0x75, 0x70, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x12, 0x44, 0x0a, 0x1d, 0x67, - 0x72, 0x6f, 0x75, 0x70, 0x53, 0x65, 0x6e, 0x64, 0x45, 0x6e, 0x64, 0x6f, 0x72, 0x73, 0x65, 0x6d, - 0x65, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x0c, 0x52, 0x1d, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x53, 0x65, 0x6e, 0x64, 0x45, 0x6e, 0x64, - 0x6f, 0x72, 0x73, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x1a, 0x6a, 0x0a, 0x10, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, - 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x2e, 0x0a, 0x0b, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x43, 0x68, - 0x61, 0x6e, 0x67, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x47, 0x72, 0x6f, - 0x75, 0x70, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x52, 0x0b, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x43, - 0x68, 0x61, 0x6e, 0x67, 0x65, 0x12, 0x26, 0x0a, 0x0a, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x53, 0x74, - 0x61, 0x74, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x06, 0x2e, 0x47, 0x72, 0x6f, 0x75, - 0x70, 0x52, 0x0a, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x53, 0x74, 0x61, 0x74, 0x65, 0x22, 0x8b, 0x01, - 0x0a, 0x13, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2e, 0x0a, 0x0b, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x43, 0x68, - 0x61, 0x6e, 0x67, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x47, 0x72, 0x6f, - 0x75, 0x70, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x52, 0x0b, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x43, - 0x68, 0x61, 0x6e, 0x67, 0x65, 0x12, 0x44, 0x0a, 0x1d, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x53, 0x65, - 0x6e, 0x64, 0x45, 0x6e, 0x64, 0x6f, 0x72, 0x73, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x1d, 0x67, 0x72, - 0x6f, 0x75, 0x70, 0x53, 0x65, 0x6e, 0x64, 0x45, 0x6e, 0x64, 0x6f, 0x72, 0x73, 0x65, 0x6d, 0x65, - 0x6e, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0xbb, 0x01, 0x0a, 0x12, - 0x47, 0x72, 0x6f, 0x75, 0x70, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x42, 0x6c, - 0x6f, 0x62, 0x12, 0x16, 0x0a, 0x05, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x09, 0x48, 0x00, 0x52, 0x05, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x12, 0x18, 0x0a, 0x06, 0x61, 0x76, - 0x61, 0x74, 0x61, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x48, 0x00, 0x52, 0x06, 0x61, 0x76, - 0x61, 0x74, 0x61, 0x72, 0x12, 0x44, 0x0a, 0x1c, 0x64, 0x69, 0x73, 0x61, 0x70, 0x70, 0x65, 0x61, - 0x72, 0x69, 0x6e, 0x67, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x44, 0x75, 0x72, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x48, 0x00, 0x52, 0x1c, 0x64, 0x69, - 0x73, 0x61, 0x70, 0x70, 0x65, 0x61, 0x72, 0x69, 0x6e, 0x67, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, - 0x65, 0x73, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x22, 0x0a, 0x0b, 0x64, 0x65, - 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x48, - 0x00, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x42, 0x09, - 0x0a, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x22, 0xe0, 0x01, 0x0a, 0x0f, 0x47, 0x72, - 0x6f, 0x75, 0x70, 0x49, 0x6e, 0x76, 0x69, 0x74, 0x65, 0x4c, 0x69, 0x6e, 0x6b, 0x12, 0x4c, 0x0a, - 0x0a, 0x76, 0x31, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x2a, 0x2e, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x49, 0x6e, 0x76, 0x69, 0x74, 0x65, 0x4c, - 0x69, 0x6e, 0x6b, 0x2e, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x49, 0x6e, 0x76, 0x69, 0x74, 0x65, 0x4c, - 0x69, 0x6e, 0x6b, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x73, 0x56, 0x31, 0x48, 0x00, 0x52, - 0x0a, 0x76, 0x31, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x73, 0x1a, 0x73, 0x0a, 0x19, 0x47, - 0x72, 0x6f, 0x75, 0x70, 0x49, 0x6e, 0x76, 0x69, 0x74, 0x65, 0x4c, 0x69, 0x6e, 0x6b, 0x43, 0x6f, - 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x73, 0x56, 0x31, 0x12, 0x26, 0x0a, 0x0e, 0x67, 0x72, 0x6f, 0x75, - 0x70, 0x4d, 0x61, 0x73, 0x74, 0x65, 0x72, 0x4b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, - 0x52, 0x0e, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x4d, 0x61, 0x73, 0x74, 0x65, 0x72, 0x4b, 0x65, 0x79, - 0x12, 0x2e, 0x0a, 0x12, 0x69, 0x6e, 0x76, 0x69, 0x74, 0x65, 0x4c, 0x69, 0x6e, 0x6b, 0x50, 0x61, - 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x12, 0x69, 0x6e, - 0x76, 0x69, 0x74, 0x65, 0x4c, 0x69, 0x6e, 0x6b, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, - 0x42, 0x0a, 0x0a, 0x08, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x73, 0x22, 0xbc, 0x02, 0x0a, - 0x0d, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x4a, 0x6f, 0x69, 0x6e, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x1c, - 0x0a, 0x09, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x0c, 0x52, 0x09, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, - 0x74, 0x69, 0x74, 0x6c, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x74, 0x69, 0x74, - 0x6c, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x61, 0x76, 0x61, 0x74, 0x61, 0x72, 0x18, 0x03, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x06, 0x61, 0x76, 0x61, 0x74, 0x61, 0x72, 0x12, 0x20, 0x0a, 0x0b, 0x6d, 0x65, - 0x6d, 0x62, 0x65, 0x72, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0d, 0x52, - 0x0b, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x4b, 0x0a, 0x11, - 0x61, 0x64, 0x64, 0x46, 0x72, 0x6f, 0x6d, 0x49, 0x6e, 0x76, 0x69, 0x74, 0x65, 0x4c, 0x69, 0x6e, - 0x6b, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1d, 0x2e, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, - 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x2e, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x52, 0x65, - 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x52, 0x11, 0x61, 0x64, 0x64, 0x46, 0x72, 0x6f, 0x6d, 0x49, - 0x6e, 0x76, 0x69, 0x74, 0x65, 0x4c, 0x69, 0x6e, 0x6b, 0x12, 0x1a, 0x0a, 0x08, 0x72, 0x65, 0x76, - 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x08, 0x72, 0x65, 0x76, - 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x32, 0x0a, 0x14, 0x70, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, - 0x41, 0x64, 0x6d, 0x69, 0x6e, 0x41, 0x70, 0x70, 0x72, 0x6f, 0x76, 0x61, 0x6c, 0x18, 0x07, 0x20, - 0x01, 0x28, 0x08, 0x52, 0x14, 0x70, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x41, 0x64, 0x6d, 0x69, - 0x6e, 0x41, 0x70, 0x70, 0x72, 0x6f, 0x76, 0x61, 0x6c, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, - 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0b, - 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x2f, 0x0a, 0x17, 0x47, - 0x72, 0x6f, 0x75, 0x70, 0x45, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x43, 0x72, 0x65, 0x64, - 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x42, 0x2b, 0x0a, 0x27, - 0x6f, 0x72, 0x67, 0x2e, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x6c, 0x2e, 0x73, 0x74, 0x6f, 0x72, 0x61, - 0x67, 0x65, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, - 0x2e, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x50, 0x01, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x33, -} +//go:embed Groups.pb.raw +var file_Groups_proto_rawDesc []byte var ( file_Groups_proto_rawDescOnce sync.Once @@ -3184,7 +2728,7 @@ func file_Groups_proto_rawDescGZIP() []byte { var file_Groups_proto_enumTypes = make([]protoimpl.EnumInfo, 2) var file_Groups_proto_msgTypes = make([]protoimpl.MessageInfo, 40) -var file_Groups_proto_goTypes = []interface{}{ +var file_Groups_proto_goTypes = []any{ (Member_Role)(0), // 0: Member.Role (AccessControl_AccessRequired)(0), // 1: AccessControl.AccessRequired (*AvatarUploadAttributes)(nil), // 2: AvatarUploadAttributes @@ -3290,7 +2834,7 @@ func file_Groups_proto_init() { return } if !protoimpl.UnsafeEnabled { - file_Groups_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + file_Groups_proto_msgTypes[0].Exporter = func(v any, i int) any { switch v := v.(*AvatarUploadAttributes); i { case 0: return &v.state @@ -3302,7 +2846,7 @@ func file_Groups_proto_init() { return nil } } - file_Groups_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + file_Groups_proto_msgTypes[1].Exporter = func(v any, i int) any { switch v := v.(*Member); i { case 0: return &v.state @@ -3314,7 +2858,7 @@ func file_Groups_proto_init() { return nil } } - file_Groups_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + file_Groups_proto_msgTypes[2].Exporter = func(v any, i int) any { switch v := v.(*PendingMember); i { case 0: return &v.state @@ -3326,7 +2870,7 @@ func file_Groups_proto_init() { return nil } } - file_Groups_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { + file_Groups_proto_msgTypes[3].Exporter = func(v any, i int) any { switch v := v.(*RequestingMember); i { case 0: return &v.state @@ -3338,7 +2882,7 @@ func file_Groups_proto_init() { return nil } } - file_Groups_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { + file_Groups_proto_msgTypes[4].Exporter = func(v any, i int) any { switch v := v.(*BannedMember); i { case 0: return &v.state @@ -3350,7 +2894,7 @@ func file_Groups_proto_init() { return nil } } - file_Groups_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { + file_Groups_proto_msgTypes[5].Exporter = func(v any, i int) any { switch v := v.(*AccessControl); i { case 0: return &v.state @@ -3362,7 +2906,7 @@ func file_Groups_proto_init() { return nil } } - file_Groups_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { + file_Groups_proto_msgTypes[6].Exporter = func(v any, i int) any { switch v := v.(*Group); i { case 0: return &v.state @@ -3374,7 +2918,7 @@ func file_Groups_proto_init() { return nil } } - file_Groups_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { + file_Groups_proto_msgTypes[7].Exporter = func(v any, i int) any { switch v := v.(*GroupChange); i { case 0: return &v.state @@ -3386,7 +2930,7 @@ func file_Groups_proto_init() { return nil } } - file_Groups_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { + file_Groups_proto_msgTypes[8].Exporter = func(v any, i int) any { switch v := v.(*GroupResponse); i { case 0: return &v.state @@ -3398,7 +2942,7 @@ func file_Groups_proto_init() { return nil } } - file_Groups_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { + file_Groups_proto_msgTypes[9].Exporter = func(v any, i int) any { switch v := v.(*GroupChanges); i { case 0: return &v.state @@ -3410,7 +2954,7 @@ func file_Groups_proto_init() { return nil } } - file_Groups_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} { + file_Groups_proto_msgTypes[10].Exporter = func(v any, i int) any { switch v := v.(*GroupChangeResponse); i { case 0: return &v.state @@ -3422,7 +2966,7 @@ func file_Groups_proto_init() { return nil } } - file_Groups_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} { + file_Groups_proto_msgTypes[11].Exporter = func(v any, i int) any { switch v := v.(*GroupAttributeBlob); i { case 0: return &v.state @@ -3434,7 +2978,7 @@ func file_Groups_proto_init() { return nil } } - file_Groups_proto_msgTypes[12].Exporter = func(v interface{}, i int) interface{} { + file_Groups_proto_msgTypes[12].Exporter = func(v any, i int) any { switch v := v.(*GroupInviteLink); i { case 0: return &v.state @@ -3446,7 +2990,7 @@ func file_Groups_proto_init() { return nil } } - file_Groups_proto_msgTypes[13].Exporter = func(v interface{}, i int) interface{} { + file_Groups_proto_msgTypes[13].Exporter = func(v any, i int) any { switch v := v.(*GroupJoinInfo); i { case 0: return &v.state @@ -3458,7 +3002,7 @@ func file_Groups_proto_init() { return nil } } - file_Groups_proto_msgTypes[14].Exporter = func(v interface{}, i int) interface{} { + file_Groups_proto_msgTypes[14].Exporter = func(v any, i int) any { switch v := v.(*GroupExternalCredential); i { case 0: return &v.state @@ -3470,7 +3014,7 @@ func file_Groups_proto_init() { return nil } } - file_Groups_proto_msgTypes[15].Exporter = func(v interface{}, i int) interface{} { + file_Groups_proto_msgTypes[15].Exporter = func(v any, i int) any { switch v := v.(*GroupChange_Actions); i { case 0: return &v.state @@ -3482,7 +3026,7 @@ func file_Groups_proto_init() { return nil } } - file_Groups_proto_msgTypes[16].Exporter = func(v interface{}, i int) interface{} { + file_Groups_proto_msgTypes[16].Exporter = func(v any, i int) any { switch v := v.(*GroupChange_Actions_AddMemberAction); i { case 0: return &v.state @@ -3494,7 +3038,7 @@ func file_Groups_proto_init() { return nil } } - file_Groups_proto_msgTypes[17].Exporter = func(v interface{}, i int) interface{} { + file_Groups_proto_msgTypes[17].Exporter = func(v any, i int) any { switch v := v.(*GroupChange_Actions_DeleteMemberAction); i { case 0: return &v.state @@ -3506,7 +3050,7 @@ func file_Groups_proto_init() { return nil } } - file_Groups_proto_msgTypes[18].Exporter = func(v interface{}, i int) interface{} { + file_Groups_proto_msgTypes[18].Exporter = func(v any, i int) any { switch v := v.(*GroupChange_Actions_ModifyMemberRoleAction); i { case 0: return &v.state @@ -3518,7 +3062,7 @@ func file_Groups_proto_init() { return nil } } - file_Groups_proto_msgTypes[19].Exporter = func(v interface{}, i int) interface{} { + file_Groups_proto_msgTypes[19].Exporter = func(v any, i int) any { switch v := v.(*GroupChange_Actions_ModifyMemberProfileKeyAction); i { case 0: return &v.state @@ -3530,7 +3074,7 @@ func file_Groups_proto_init() { return nil } } - file_Groups_proto_msgTypes[20].Exporter = func(v interface{}, i int) interface{} { + file_Groups_proto_msgTypes[20].Exporter = func(v any, i int) any { switch v := v.(*GroupChange_Actions_AddPendingMemberAction); i { case 0: return &v.state @@ -3542,7 +3086,7 @@ func file_Groups_proto_init() { return nil } } - file_Groups_proto_msgTypes[21].Exporter = func(v interface{}, i int) interface{} { + file_Groups_proto_msgTypes[21].Exporter = func(v any, i int) any { switch v := v.(*GroupChange_Actions_DeletePendingMemberAction); i { case 0: return &v.state @@ -3554,7 +3098,7 @@ func file_Groups_proto_init() { return nil } } - file_Groups_proto_msgTypes[22].Exporter = func(v interface{}, i int) interface{} { + file_Groups_proto_msgTypes[22].Exporter = func(v any, i int) any { switch v := v.(*GroupChange_Actions_PromotePendingMemberAction); i { case 0: return &v.state @@ -3566,7 +3110,7 @@ func file_Groups_proto_init() { return nil } } - file_Groups_proto_msgTypes[23].Exporter = func(v interface{}, i int) interface{} { + file_Groups_proto_msgTypes[23].Exporter = func(v any, i int) any { switch v := v.(*GroupChange_Actions_PromotePendingPniAciMemberProfileKeyAction); i { case 0: return &v.state @@ -3578,7 +3122,7 @@ func file_Groups_proto_init() { return nil } } - file_Groups_proto_msgTypes[24].Exporter = func(v interface{}, i int) interface{} { + file_Groups_proto_msgTypes[24].Exporter = func(v any, i int) any { switch v := v.(*GroupChange_Actions_AddRequestingMemberAction); i { case 0: return &v.state @@ -3590,7 +3134,7 @@ func file_Groups_proto_init() { return nil } } - file_Groups_proto_msgTypes[25].Exporter = func(v interface{}, i int) interface{} { + file_Groups_proto_msgTypes[25].Exporter = func(v any, i int) any { switch v := v.(*GroupChange_Actions_DeleteRequestingMemberAction); i { case 0: return &v.state @@ -3602,7 +3146,7 @@ func file_Groups_proto_init() { return nil } } - file_Groups_proto_msgTypes[26].Exporter = func(v interface{}, i int) interface{} { + file_Groups_proto_msgTypes[26].Exporter = func(v any, i int) any { switch v := v.(*GroupChange_Actions_PromoteRequestingMemberAction); i { case 0: return &v.state @@ -3614,7 +3158,7 @@ func file_Groups_proto_init() { return nil } } - file_Groups_proto_msgTypes[27].Exporter = func(v interface{}, i int) interface{} { + file_Groups_proto_msgTypes[27].Exporter = func(v any, i int) any { switch v := v.(*GroupChange_Actions_AddBannedMemberAction); i { case 0: return &v.state @@ -3626,7 +3170,7 @@ func file_Groups_proto_init() { return nil } } - file_Groups_proto_msgTypes[28].Exporter = func(v interface{}, i int) interface{} { + file_Groups_proto_msgTypes[28].Exporter = func(v any, i int) any { switch v := v.(*GroupChange_Actions_DeleteBannedMemberAction); i { case 0: return &v.state @@ -3638,7 +3182,7 @@ func file_Groups_proto_init() { return nil } } - file_Groups_proto_msgTypes[29].Exporter = func(v interface{}, i int) interface{} { + file_Groups_proto_msgTypes[29].Exporter = func(v any, i int) any { switch v := v.(*GroupChange_Actions_ModifyTitleAction); i { case 0: return &v.state @@ -3650,7 +3194,7 @@ func file_Groups_proto_init() { return nil } } - file_Groups_proto_msgTypes[30].Exporter = func(v interface{}, i int) interface{} { + file_Groups_proto_msgTypes[30].Exporter = func(v any, i int) any { switch v := v.(*GroupChange_Actions_ModifyDescriptionAction); i { case 0: return &v.state @@ -3662,7 +3206,7 @@ func file_Groups_proto_init() { return nil } } - file_Groups_proto_msgTypes[31].Exporter = func(v interface{}, i int) interface{} { + file_Groups_proto_msgTypes[31].Exporter = func(v any, i int) any { switch v := v.(*GroupChange_Actions_ModifyAvatarAction); i { case 0: return &v.state @@ -3674,7 +3218,7 @@ func file_Groups_proto_init() { return nil } } - file_Groups_proto_msgTypes[32].Exporter = func(v interface{}, i int) interface{} { + file_Groups_proto_msgTypes[32].Exporter = func(v any, i int) any { switch v := v.(*GroupChange_Actions_ModifyDisappearingMessagesTimerAction); i { case 0: return &v.state @@ -3686,7 +3230,7 @@ func file_Groups_proto_init() { return nil } } - file_Groups_proto_msgTypes[33].Exporter = func(v interface{}, i int) interface{} { + file_Groups_proto_msgTypes[33].Exporter = func(v any, i int) any { switch v := v.(*GroupChange_Actions_ModifyAttributesAccessControlAction); i { case 0: return &v.state @@ -3698,7 +3242,7 @@ func file_Groups_proto_init() { return nil } } - file_Groups_proto_msgTypes[34].Exporter = func(v interface{}, i int) interface{} { + file_Groups_proto_msgTypes[34].Exporter = func(v any, i int) any { switch v := v.(*GroupChange_Actions_ModifyMembersAccessControlAction); i { case 0: return &v.state @@ -3710,7 +3254,7 @@ func file_Groups_proto_init() { return nil } } - file_Groups_proto_msgTypes[35].Exporter = func(v interface{}, i int) interface{} { + file_Groups_proto_msgTypes[35].Exporter = func(v any, i int) any { switch v := v.(*GroupChange_Actions_ModifyAddFromInviteLinkAccessControlAction); i { case 0: return &v.state @@ -3722,7 +3266,7 @@ func file_Groups_proto_init() { return nil } } - file_Groups_proto_msgTypes[36].Exporter = func(v interface{}, i int) interface{} { + file_Groups_proto_msgTypes[36].Exporter = func(v any, i int) any { switch v := v.(*GroupChange_Actions_ModifyInviteLinkPasswordAction); i { case 0: return &v.state @@ -3734,7 +3278,7 @@ func file_Groups_proto_init() { return nil } } - file_Groups_proto_msgTypes[37].Exporter = func(v interface{}, i int) interface{} { + file_Groups_proto_msgTypes[37].Exporter = func(v any, i int) any { switch v := v.(*GroupChange_Actions_ModifyAnnouncementsOnlyAction); i { case 0: return &v.state @@ -3746,7 +3290,7 @@ func file_Groups_proto_init() { return nil } } - file_Groups_proto_msgTypes[38].Exporter = func(v interface{}, i int) interface{} { + file_Groups_proto_msgTypes[38].Exporter = func(v any, i int) any { switch v := v.(*GroupChanges_GroupChangeState); i { case 0: return &v.state @@ -3758,7 +3302,7 @@ func file_Groups_proto_init() { return nil } } - file_Groups_proto_msgTypes[39].Exporter = func(v interface{}, i int) interface{} { + file_Groups_proto_msgTypes[39].Exporter = func(v any, i int) any { switch v := v.(*GroupInviteLink_GroupInviteLinkContentsV1); i { case 0: return &v.state @@ -3771,13 +3315,13 @@ func file_Groups_proto_init() { } } } - file_Groups_proto_msgTypes[11].OneofWrappers = []interface{}{ + file_Groups_proto_msgTypes[11].OneofWrappers = []any{ (*GroupAttributeBlob_Title)(nil), (*GroupAttributeBlob_Avatar)(nil), (*GroupAttributeBlob_DisappearingMessagesDuration)(nil), (*GroupAttributeBlob_Description)(nil), } - file_Groups_proto_msgTypes[12].OneofWrappers = []interface{}{ + file_Groups_proto_msgTypes[12].OneofWrappers = []any{ (*GroupInviteLink_V1Contents)(nil), } type x struct{} diff --git a/pkg/signalmeow/protobuf/Groups.pb.raw b/pkg/signalmeow/protobuf/Groups.pb.raw new file mode 100644 index 0000000000000000000000000000000000000000..7549d560184e776c7a26830944fac136320946a9 GIT binary patch literal 7313 zcmb_hOLrSd6&}S8*;kS+R}#C^#EC~UOhP7TP842em|>7ChcSsApSC?i*o3xJQF{Wz95$RYtl$^$BUrJ617}gKPZk)1#jc-lXGv|S-)s|>hfzQ1TsX^WRewoI zBIt#FGK#rVBuV3i+J6eLe82~1JeC4Rg2($^b@H;Ozt|2e#!;WEW3M&Jbt12OxaO%H zX&yS|RnX^8(Qau)*)vvH4a&oq3pC$Pf+$q>ls#*WJ%H+0Q4n%;q{q(#A?c)f6>n<2 z_81nWc2EYAE=U*OH-;p2fy(i7nXD8JH+ki^5eXxJHe|+LKPo8_#YqbO_M?CBX zVNct87nTRga%FF+QPh@sdYQcs6~Ei%-PXk^`9%h$inK;&Q+E8x!A$s|em|IfhK`beMy@u}Xbhr?^ zQJ7$IuulQ}aRDfQt~Ivn7LERr&Iqs;JcEJ#5Q-EEp|k7~-jtd>g$)eRlQsP(}}hqmrf6lnPokX#? zvvA+2sByf00Bb|D2!*qvDA(#%ZF(6h_8Dx%nJN;_s$$)!XY0$Gre$?t!8k*Xd?9`l z#a#zf0CIM)>6N-%bmCyBI#x*$noH~g+AlLy^y1dU5PQ6QDic3NFas{;wN-fLgW-nl45OsrB7bH$z zC<1Fhiu^EF^u$rawovhFMuiqKHt-vY6S|1-MJn+A}-3>?x(j z$8*j)lUM7!Oa&XlrnYH(iPKGpZAvQt(H!NI!IxO{NT5~Ekc(kwq>-vmYg<#=zCTBs zuKhe!IRe=q3$U#%%Z>?J<+@V&*&LNvFZO_ur+mH^SxH!4*^5dzRaK|?m4te;4BDx= zvSinxYRz&9XJby+p@PlwXic*uvJf0ywpmW$Fr}@L>r!30SthM+rc4%rLvftUdE;CB zx(earTzvJ#)?w&ZY{{gIq%}?@VGXeo6*=3D+s#Olsk5Dbe4}6-~Kj(rf8? zlGq;#@GbjpI0}PiCrIyqM`_A0UHgVG`EW;EQ5<9S99JdX(FgE$Eo87a+lk+Om5o*J2iqH%}R}0b$*w%iUA!cGWMJP4FnFlPf znGaa^AuwV#=Tif0kSwd71{>T@;oDl(tU*;PRv3mvAjT)f4|fRfX=RxS(;64qKHgOs zf~%oPQ*3Szc1R9I?J zt6ALc5!|6;%$jy)fFKm791z4kfNgD9c23c;&c#5aygUq~CZM9;{2muW#4tF5VM{%U zsVlda8p|{@c(lmcu&s8F5ir^dyHP9%Xi3@i)iR%`_VqO&;GQrP!CFvOV)ZxbmQUq7 z=DZ@zk7ER_xo7dbouj#5K~?#KPNMW+h)Txkv}4NVc|4PVeE>jClBZN2nfTGzsr{({ z*9~Q<5C3OG3ax(rP6~iJV*pfLVYrb(pm>?&L7?qX zO#d{<0i%NSbE)teH5()S-GWT!VrvzO9R#}(>8t&_0PE`XlR{(90L~xDUM8VH9X35) zPpBx2lkb%Ni$|!<;CBVw$|#tSV#wEevT6=|k??qeBWG4;R67j;In~|*SkV@W+CLEC zS10&6jlSWARNhV zgh?i|8EN&LXrWlzV>fX4=Z==sFvG&FylI`%q{L~*MJ(-Er$2WJC(m6fZ!#Y?C?DT; zPiRYvkPe4mgi3YNtE4V4J>>=A(FMxGj}+i zxX$N9VtzAm4>sP|_)NC=+F_*Yq2KMWgFaIAbUq{YXXC}R@0v;KgM&1XQ!);A3L>L> zR$Z>Du?WCZ3E#mfVCHupxoxi=n#L++^|SAKI|6REj(4XobvHM~OnvVJqYE|qzD5hcSi#O>ddVrW=#YFT zF`q76X<*LFVtY0pPj3!#{3vz9c~fMk?qod0UN1Z2r|#(B9zJJe3|jcz4Ur(ZowV3J zYdmT+-*4nzaaB-0*{OZCliP4|BJ-&BxLf;bg2YaSH=CaM!i~Vbm~X-TD9A*HL5k4+i_kI_gW{VdV?c(D^2|0=;V@x zL~=K``)(q+ncKp@Te$@O-BFPJTn@jT-2K8oZHwKCCbsj7B0cEMd#CPf*1OaUl`iIE z3{?$#NV_|+XE&q1kG%=fEMvFB9@6ek?0#=J^s%>AVpqZ*((X>|(IUi7ti*1FJ*3^; zsqtL^7297JIme;0=G29W_e)MuIcKJ~E1eF_NO-!BG#tU@zlrGx9OIz&M)J#lj;55yk6iXmG2BwRJ*f_1_o^lmB&(7sE%Q|^>>=&$ zh5t;7w8b_c&i44p6L+e_WxDuAY*kj*!zTMl-QD@J*y)XC9{^D^_9xdMmQ+V+5OAg` z$j-9~?v{J7^~M&K|EV?Db-%9+(VQ=c#KmHEqhw{e_=z>>WptCOGuM388(l6YN^Yl% z>(=~Gb(97HO69&K)V1`7njlN;$yJ{?*?7|X#=Tl~p2+gA9tl6w%WhteS9PgeMnk5=t*`3I3=O2g! zPdGk8{+~C*jy}WqC+8hQL^5u+_~sfS>H%yj=0$R#R6h=%yV{dMyD%}7gxaD8J8N|t zO?g@(8SjgI11eQ2wN|HAg~AJg)mr7G-T-jZ*%xWkvwYTm42_o;5B$+;&~dGrJgv9e z^=2cN$o~O0sd>k7M1s0X@k&Oj-%dsBDxKcHQI|AZ{HZm2)#DtV(Fo|@NFTHCIp}N+ zbM{24Dx0lVsSI8GlJh_~SQ+$kw|;tBtJX`M+R5YG295^@gMYPZP3BUC|Je|!@_29~ zaj9HwO!TI6wbnfv6KG(xouNCroL{N6?n%>f-Vov%W(h=hsqZP8ryjl}Ef_`EY<@Fz z56IZr;_Ixa@*y5V!t<=jr$(t+u*!6T)2h5E{L>c zDDbo{Ko3QM6r>Y=LoB9y^Lej-#qG{O1q#NvJT3)2T4N6;;Z)j4&KJe*<#fE5oEH!F zL5yXUeax@QzIi@BFG{~R&*aIlcR5ou#F?lDXrFeUPrRv1J8`On?H<%g2%-TBi~NZ< zbfKURsNgfwf>LYij^J!4!(3VrSSZP@ zR=|BV`)6b5_UxK*0}L4-f@d`8-SF-lysSoBcSbGU6DO>HIFF32XRgMOuUU|? z`%HIZ_n8(AoJ;S?yxbeWYj~hWiW@kQt@(Xrh?f8REwQb5eo1}7SL`k3SK}$=A=P6_ zh5$;Ix%+&s1tt7j{C3(=$&yfK_4ze>QxoeeHwYz8RMbSzf9FG-zi-4)94s3#Hf8iW zLQg&admAFBfY!1orTW@qV^1SfZ4h*5k|L_nyLOd!Ny(t?{1RO6tHt%jsOJq8)t2Q@ zNCIEzhA4%C(fUvrfx3rldt5*2bjzhG99e2axSaX#3GG@^2K|CajJO(_cIo0eJ|j~B z4{FyaJ>7%!<#v}Oi8V{S^cCWc%%?o!KpvL}EqdD)2-QHj@ zg<}j3qzL`oU6wG0rXQ9xp7aNBO7J9}!E~7_^^smOQf!9scT-Xb@F>*(49kqCm%Wkq zO%-!d=6y;=VEMm95P~$MO1ku(xg*65q(AOY0HDZy(!2JCH|jG@#FVrkG*h5Fo_NpA z4KppmXNxC<(+WvR)8cs7-e6#uPhVFHLgpQKv&pchC!_{VA&wA&lsBMGk4pL(%?ZQe zx&iuWpFo?lKYN#hATQWfEe0O;E?mw3DXANUqTy^9MGu>&;A0v^r_C}9As9t~zTcFO zU=aaYIcs;Cr?5!rx+qTh$QG+c`@dQ2-)$nmWHY5xH?-8T!=JwkEp7aj%hWuiX{y*{ zK6PDRK<^-=fflJX8DETj?$HhM^~m)uuP(;ZtMPbXqR!?+ zpo|4G>K5hT1ncdO2ioL<9Q4~d$ha8I5#*y+o1(p>nuRx)_`pB=P3!Ep^1lX8P~XQd z1y@?jw-;Nn{!PZ^^k%S z*W+jYE^$O`F=7i*cYUSCUm4w)|g+?oq(Fb^9R8hpXXFiukln$zH7ULLL@U0f$o{Xt6s5`EKf zi2U!vLoZ$PB01;K1mg?vbp@WAQT%V+VZj>x@HD_x?r+e_zbQocO|ie%9|NMMNPzuy zvz+u-lK_Ki_ASD#e%D24K@8w0C*s;0HyQW#*6Y0(rfku*a zJbHI0`Geiuf9&R;3lWmsIf_W_;vE(qB3mLmFy&N|;k~n3yMvGbocmIxQ$I&^195@! zj!4w!?lo5O@4LAl>;@}(Po$20JKm{^kDCot;PipBz1|Q`C3!q#*Nj}>sc=kTPQ^#*SMQ zK5H~0mS3%%)X!`3u?`-A4kma+GBKc6_~Q++7fEqM$JW9&oD819j%IcxezHp*ePpad zGV*u?Lshhb+Ug*rN8T>{>!y*~CQ}iM?r^Em z=*}0!wi@3^%6NWAs|vbiD%hm^!gt70yN6EIUA->Iy%?r*EV3Nj8cVD1_)0pFP8=wT zMh%46!uW%kbSFd4rCY;9XA~HVd3*?;x151u2|{;;KY|@&f=ozzZY`!m#mXtkpVX*x zZ*J@#XjIi;l+(Lr8d9eMUu>Z0?#jV%XZ2diju=>}~} zH7%pLTj+0E6g)8ZJ@SF}+c#whD7@!~!yyx@wWHG63DqAOvUYrSQj*XHet3M-NuhI1 z){nIN*RDur2_q~+Yl(*E;A}juNOkg%I~V>8bOmQ2V)qTc?pL5F~i7Y8{*+XdvHHH z!0s}F>^v0dC+@s|bpkF17cke5UP^b`V;zOPrHx8%c~uu^IWUd|76 z$|Rmwu-C-=is~yvH0M2$fFiFfTp{Q zAd_izMhaU0)X$#8b+0{^j%BFch?}Y$m1^XFxGNGAs0^uCs;2h&x8E|>Rvdh5>7I_F z-Jx_($1N;t{w=XT~VQMppvXg!axg6ts>1yrV*Cw`2#)m!ENYD462 zr|PX7M_VQ(S92Vq!uAO(^B^fBFkSNoeWi;~>y`yYD?cMq^S0`%wqWotOKbjQL%gz* zRJX2Ly9TRQ%?c{3fbRsq>jPcpkU|C3@+arBBInIY^vc{pXH3WJMqQ$$T!Lf8>0Bn? z7fIg|Vmuedh>n8YC8ei&JD;T4bv;ojabD(tkppnPEq0CVLTf=M)Mk(6|7*!rmwc(wVFX%-+#d*Q@urPUl!KZOJeOJ`WJo8xn0Ss8Qst$yg629w- zPu$56%G!hrX3Db0PHdRDuYa*2US4Hu(jR0F$G%TL9djz|%~)9W9?rr&gm(&c zV7Nr3ldcK2;$op#62Uad0P1O}Q9oh;d6QM@?X$9Wkr}Q95jtmW)B_-FO>>#9F!dQ? zJLa)~;#QQ=N1;5%>)s4CUrOR5V16`^}qqT5)x#?Z$wdRDtL{!f|5;;OrWOv*+q?E*K|L*^i7wc-l}csyz0ydO!E@NT4w>x_-q z8g9*y)Ak6)!@2*7p^>ks)hhUPQZ+; z_*cOK#Engps($FAj%liNUOdgX@*4%Bg#)SRK38HZA(!Ba`Qf_GaTDqcZ_eQRZ^1yx z&LU8b2^Vj&n70-eL$A+^gQ`LHT!NSP#ok2MbyeMY&l~3dk*SZUcSWzj3M{pHo-TpU z$T*l1c!uXjtlm>qj-+q~C0`Z{*2XJC+)Z3OJcoI7gW4R^S({s{Kk5fGmo$BprEjA4 zdwfY@LzSK3exN)T9lzZj>1O^r36To?JdTHG2#ofbKOXfSh#7^Nk}}OHEGv&>J2ZD# zKFn7l!r(=YqVfT)`|q5H)Bv@QDnX&bui4_^8i5k*=CJBx$#4MFK5e_o|D~IeEw1yY z!;#dQkeVi9;jxiNFm8-A?{*%ySpAD|o>ly=!h2TP`zF61qvp4zi{rPLmn&7f51SPY zNEA>@7A%^Nko@thbv#;P&I^;k7OOWZ&C`107_two=2_>s$<}7!Ol+&AQnvZHISU4zR~P-1BfccFj8_$4O>Ql_8c}|BLC;ei;)JP zp@x~C4Y%7c1R`wn;6)DT8)t9)*5Gyk0|%EiM_hVwO%HBkf&)$Yc6Ozr?L*16 z^Ej@!7pCO=J?nbNFWzzTF#ltAygXw54>!aEdz;!9M`&gWowl!yv6w-EL{a<$MEjoZ zd#qhXeJ{~73Pxf>=zdCDkb~88i4ex5j8=SH15;6su`zlVL;sB$m!|7=RxB;{fm3Rb znv(ZQO&P+L>wC10iPrb9KtLPoCsnE#zE;n+v1Z{3fBn4WO1Q8_7L zB#->3mmdL_tQge!4e{}Css>)H^0^IS1?CuaQujwX$MxgW0`O)>cpR+BYhrE@SpGLR z#K+c%-XFt}z}M5S0Pp3T!ha>iz3`5iDt(oHAB>Efx1-YUY{K~2=?_LUZum%w!pgLn z7KTXROM9wv<1yPHmTNo(qUL%2~BZ|!&cj|#L45Iz~8BR|lWLqC`@ zEnXgP)JGvG=I;$pdwrGUfdvwU@FNKI6fIqFX*k9zy7(M)(i{wFLSJ z7z6Ub6EHwO@CJC5r=Pm&26u49!sNLMhoizkw`f-Od%DmhP12%>ST{NI#c(lIcbu6> zlpgzSx?+pTaNHY&?j<50Kp>Eq(ZU-@3a7%C{USQVYtEbX z3PLlw#tp_d?D=w2;!g&g0E9@*uGqq}4OED$!%-jx{oYxUieG(BvPen&9$~ch3{^`dD4{_I+`#e_v<*nnhWLix<%Q5puZ`f z=TDMD9it%!f8&sRGV^d(ynT;Mb{Ko=g8QgTigX}AHzKtY`ta^hJAuL@1e|Ywy9wG@ zPd(Ke&DiTtRLyxKyjs8`3RP8Pq(Kx&`uC>&DZhiP70sM*w0J+mD}`En z{Y2@O8k`7n?4Ik1NXqxc^J#v>56+{alIWgU49f0#k7L51`X!G@>uyt;$B!~@6QTi_RKRl zEp_}RB@*L<$h}Xs8IeJL%mm|c~le@aT# H!q5H}`Y4T= literal 0 HcmV?d00001 diff --git a/pkg/signalmeow/protobuf/SignalService.proto b/pkg/signalmeow/protobuf/SignalService.proto index 30127a1..1e2332b 100644 --- a/pkg/signalmeow/protobuf/SignalService.proto +++ b/pkg/signalmeow/protobuf/SignalService.proto @@ -37,7 +37,8 @@ message Envelope { reserved /*updatedPni*/ 15; // Not used presently, may be used in the future optional bool story = 16; optional bytes reportingToken = 17; - // NEXT ID: 18 + reserved 18; // internal server use + // NEXT ID: 19 } message Content { diff --git a/pkg/signalmeow/protobuf/StickerResources.pb.go b/pkg/signalmeow/protobuf/StickerResources.pb.go index e9c864a..b64f824 100644 --- a/pkg/signalmeow/protobuf/StickerResources.pb.go +++ b/pkg/signalmeow/protobuf/StickerResources.pb.go @@ -5,7 +5,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.34.1 +// protoc-gen-go v1.34.2 // protoc v3.21.12 // source: StickerResources.proto @@ -18,6 +18,8 @@ import ( sync "sync" ) +import _ "embed" + const ( // Verify that this generated code is sufficiently up-to-date. _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) @@ -161,31 +163,8 @@ func (x *Pack_Sticker) GetContentType() string { var File_StickerResources_proto protoreflect.FileDescriptor -var file_StickerResources_proto_rawDesc = []byte{ - 0x0a, 0x16, 0x53, 0x74, 0x69, 0x63, 0x6b, 0x65, 0x72, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, - 0x65, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0d, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x6c, - 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x22, 0xf3, 0x01, 0x0a, 0x04, 0x50, 0x61, 0x63, 0x6b, - 0x12, 0x14, 0x0a, 0x05, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x05, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x12, 0x31, - 0x0a, 0x05, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, - 0x73, 0x69, 0x67, 0x6e, 0x61, 0x6c, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x50, 0x61, - 0x63, 0x6b, 0x2e, 0x53, 0x74, 0x69, 0x63, 0x6b, 0x65, 0x72, 0x52, 0x05, 0x63, 0x6f, 0x76, 0x65, - 0x72, 0x12, 0x37, 0x0a, 0x08, 0x73, 0x74, 0x69, 0x63, 0x6b, 0x65, 0x72, 0x73, 0x18, 0x04, 0x20, - 0x03, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x6c, 0x73, 0x65, 0x72, 0x76, - 0x69, 0x63, 0x65, 0x2e, 0x50, 0x61, 0x63, 0x6b, 0x2e, 0x53, 0x74, 0x69, 0x63, 0x6b, 0x65, 0x72, - 0x52, 0x08, 0x73, 0x74, 0x69, 0x63, 0x6b, 0x65, 0x72, 0x73, 0x1a, 0x51, 0x0a, 0x07, 0x53, 0x74, - 0x69, 0x63, 0x6b, 0x65, 0x72, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x0d, 0x52, 0x02, 0x69, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x6d, 0x6f, 0x6a, 0x69, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, 0x6d, 0x6f, 0x6a, 0x69, 0x12, 0x20, 0x0a, 0x0b, 0x63, - 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x0b, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x42, 0x42, 0x0a, - 0x31, 0x6f, 0x72, 0x67, 0x2e, 0x77, 0x68, 0x69, 0x73, 0x70, 0x65, 0x72, 0x73, 0x79, 0x73, 0x74, - 0x65, 0x6d, 0x73, 0x2e, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x6c, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, - 0x65, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x73, 0x74, 0x69, 0x63, 0x6b, - 0x65, 0x72, 0x42, 0x0d, 0x53, 0x74, 0x69, 0x63, 0x6b, 0x65, 0x72, 0x50, 0x72, 0x6f, 0x74, 0x6f, - 0x73, -} +//go:embed StickerResources.pb.raw +var file_StickerResources_proto_rawDesc []byte var ( file_StickerResources_proto_rawDescOnce sync.Once @@ -200,7 +179,7 @@ func file_StickerResources_proto_rawDescGZIP() []byte { } var file_StickerResources_proto_msgTypes = make([]protoimpl.MessageInfo, 2) -var file_StickerResources_proto_goTypes = []interface{}{ +var file_StickerResources_proto_goTypes = []any{ (*Pack)(nil), // 0: signalservice.Pack (*Pack_Sticker)(nil), // 1: signalservice.Pack.Sticker } @@ -220,7 +199,7 @@ func file_StickerResources_proto_init() { return } if !protoimpl.UnsafeEnabled { - file_StickerResources_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + file_StickerResources_proto_msgTypes[0].Exporter = func(v any, i int) any { switch v := v.(*Pack); i { case 0: return &v.state @@ -232,7 +211,7 @@ func file_StickerResources_proto_init() { return nil } } - file_StickerResources_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + file_StickerResources_proto_msgTypes[1].Exporter = func(v any, i int) any { switch v := v.(*Pack_Sticker); i { case 0: return &v.state diff --git a/pkg/signalmeow/protobuf/StickerResources.pb.raw b/pkg/signalmeow/protobuf/StickerResources.pb.raw new file mode 100644 index 0000000..03768ca --- /dev/null +++ b/pkg/signalmeow/protobuf/StickerResources.pb.raw @@ -0,0 +1,12 @@ + +StickerResources.proto signalservice"ó +Pack +title ( Rtitle +author ( Rauthor1 +cover ( 2.signalservice.Pack.StickerRcover7 +stickers ( 2.signalservice.Pack.StickerRstickersQ +Sticker +id ( Rid +emoji ( Remoji + contentType ( R contentTypeBB +1org.whispersystems.signalservice.internal.stickerB StickerProtos \ No newline at end of file diff --git a/pkg/signalmeow/protobuf/StorageService.pb.go b/pkg/signalmeow/protobuf/StorageService.pb.go index aeb2cbd..5f88b50 100644 --- a/pkg/signalmeow/protobuf/StorageService.pb.go +++ b/pkg/signalmeow/protobuf/StorageService.pb.go @@ -5,7 +5,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.34.1 +// protoc-gen-go v1.34.2 // protoc v3.21.12 // source: StorageService.proto @@ -18,6 +18,8 @@ import ( sync "sync" ) +import _ "embed" + const ( // Verify that this generated code is sufficiently up-to-date. _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) @@ -1992,359 +1994,8 @@ func (x *AccountRecord_PinnedConversation_Contact) GetE164() string { var File_StorageService_proto protoreflect.FileDescriptor -var file_StorageService_proto_rawDesc = []byte{ - 0x0a, 0x14, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, - 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0d, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x6c, 0x73, 0x65, - 0x72, 0x76, 0x69, 0x63, 0x65, 0x22, 0x41, 0x0a, 0x0f, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, - 0x4d, 0x61, 0x6e, 0x69, 0x66, 0x65, 0x73, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, - 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, - 0x6f, 0x6e, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x0c, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x35, 0x0a, 0x0b, 0x53, 0x74, 0x6f, 0x72, - 0x61, 0x67, 0x65, 0x49, 0x74, 0x65, 0x6d, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x0c, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, - 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, - 0x40, 0x0a, 0x0c, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x49, 0x74, 0x65, 0x6d, 0x73, 0x12, - 0x30, 0x0a, 0x05, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1a, - 0x2e, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x6c, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x53, - 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x49, 0x74, 0x65, 0x6d, 0x52, 0x05, 0x69, 0x74, 0x65, 0x6d, - 0x73, 0x22, 0x29, 0x0a, 0x0d, 0x52, 0x65, 0x61, 0x64, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x12, 0x18, 0x0a, 0x07, 0x72, 0x65, 0x61, 0x64, 0x4b, 0x65, 0x79, 0x18, 0x01, 0x20, - 0x03, 0x28, 0x0c, 0x52, 0x07, 0x72, 0x65, 0x61, 0x64, 0x4b, 0x65, 0x79, 0x22, 0xc2, 0x01, 0x0a, - 0x0e, 0x57, 0x72, 0x69, 0x74, 0x65, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, - 0x3a, 0x0a, 0x08, 0x6d, 0x61, 0x6e, 0x69, 0x66, 0x65, 0x73, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x1e, 0x2e, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x6c, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, - 0x65, 0x2e, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x4d, 0x61, 0x6e, 0x69, 0x66, 0x65, 0x73, - 0x74, 0x52, 0x08, 0x6d, 0x61, 0x6e, 0x69, 0x66, 0x65, 0x73, 0x74, 0x12, 0x3a, 0x0a, 0x0a, 0x69, - 0x6e, 0x73, 0x65, 0x72, 0x74, 0x49, 0x74, 0x65, 0x6d, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, - 0x1a, 0x2e, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x6c, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, - 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x49, 0x74, 0x65, 0x6d, 0x52, 0x0a, 0x69, 0x6e, 0x73, - 0x65, 0x72, 0x74, 0x49, 0x74, 0x65, 0x6d, 0x12, 0x1c, 0x0a, 0x09, 0x64, 0x65, 0x6c, 0x65, 0x74, - 0x65, 0x4b, 0x65, 0x79, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x09, 0x64, 0x65, 0x6c, 0x65, - 0x74, 0x65, 0x4b, 0x65, 0x79, 0x12, 0x1a, 0x0a, 0x08, 0x63, 0x6c, 0x65, 0x61, 0x72, 0x41, 0x6c, - 0x6c, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x63, 0x6c, 0x65, 0x61, 0x72, 0x41, 0x6c, - 0x6c, 0x22, 0xe4, 0x02, 0x0a, 0x0e, 0x4d, 0x61, 0x6e, 0x69, 0x66, 0x65, 0x73, 0x74, 0x52, 0x65, - 0x63, 0x6f, 0x72, 0x64, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x22, - 0x0a, 0x0c, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x18, 0x03, - 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0c, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x44, 0x65, 0x76, 0x69, - 0x63, 0x65, 0x12, 0x4a, 0x0a, 0x0b, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, - 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x28, 0x2e, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x6c, - 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x4d, 0x61, 0x6e, 0x69, 0x66, 0x65, 0x73, 0x74, - 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x2e, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, - 0x72, 0x52, 0x0b, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x73, 0x1a, 0xc7, - 0x01, 0x0a, 0x0a, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x12, 0x10, 0x0a, - 0x03, 0x72, 0x61, 0x77, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x03, 0x72, 0x61, 0x77, 0x12, - 0x41, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x2d, 0x2e, - 0x73, 0x69, 0x67, 0x6e, 0x61, 0x6c, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x4d, 0x61, - 0x6e, 0x69, 0x66, 0x65, 0x73, 0x74, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x2e, 0x49, 0x64, 0x65, - 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x2e, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, - 0x70, 0x65, 0x22, 0x64, 0x0a, 0x04, 0x54, 0x79, 0x70, 0x65, 0x12, 0x0b, 0x0a, 0x07, 0x55, 0x4e, - 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x00, 0x12, 0x0b, 0x0a, 0x07, 0x43, 0x4f, 0x4e, 0x54, 0x41, - 0x43, 0x54, 0x10, 0x01, 0x12, 0x0b, 0x0a, 0x07, 0x47, 0x52, 0x4f, 0x55, 0x50, 0x56, 0x31, 0x10, - 0x02, 0x12, 0x0b, 0x0a, 0x07, 0x47, 0x52, 0x4f, 0x55, 0x50, 0x56, 0x32, 0x10, 0x03, 0x12, 0x0b, - 0x0a, 0x07, 0x41, 0x43, 0x43, 0x4f, 0x55, 0x4e, 0x54, 0x10, 0x04, 0x12, 0x1b, 0x0a, 0x17, 0x53, - 0x54, 0x4f, 0x52, 0x59, 0x5f, 0x44, 0x49, 0x53, 0x54, 0x52, 0x49, 0x42, 0x55, 0x54, 0x49, 0x4f, - 0x4e, 0x5f, 0x4c, 0x49, 0x53, 0x54, 0x10, 0x05, 0x22, 0xe5, 0x02, 0x0a, 0x0d, 0x53, 0x74, 0x6f, - 0x72, 0x61, 0x67, 0x65, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x12, 0x38, 0x0a, 0x07, 0x63, 0x6f, - 0x6e, 0x74, 0x61, 0x63, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x73, 0x69, - 0x67, 0x6e, 0x61, 0x6c, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x43, 0x6f, 0x6e, 0x74, - 0x61, 0x63, 0x74, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x48, 0x00, 0x52, 0x07, 0x63, 0x6f, 0x6e, - 0x74, 0x61, 0x63, 0x74, 0x12, 0x38, 0x0a, 0x07, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x56, 0x31, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x6c, 0x73, 0x65, - 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x56, 0x31, 0x52, 0x65, 0x63, - 0x6f, 0x72, 0x64, 0x48, 0x00, 0x52, 0x07, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x56, 0x31, 0x12, 0x38, - 0x0a, 0x07, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x56, 0x32, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x1c, 0x2e, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x6c, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, - 0x47, 0x72, 0x6f, 0x75, 0x70, 0x56, 0x32, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x48, 0x00, 0x52, - 0x07, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x56, 0x32, 0x12, 0x38, 0x0a, 0x07, 0x61, 0x63, 0x63, 0x6f, - 0x75, 0x6e, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x73, 0x69, 0x67, 0x6e, - 0x61, 0x6c, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, - 0x74, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x48, 0x00, 0x52, 0x07, 0x61, 0x63, 0x63, 0x6f, 0x75, - 0x6e, 0x74, 0x12, 0x62, 0x0a, 0x15, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x44, 0x69, 0x73, 0x74, 0x72, - 0x69, 0x62, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x4c, 0x69, 0x73, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x2a, 0x2e, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x6c, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, - 0x65, 0x2e, 0x53, 0x74, 0x6f, 0x72, 0x79, 0x44, 0x69, 0x73, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, - 0x69, 0x6f, 0x6e, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x48, 0x00, 0x52, - 0x15, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x44, 0x69, 0x73, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x69, - 0x6f, 0x6e, 0x4c, 0x69, 0x73, 0x74, 0x42, 0x08, 0x0a, 0x06, 0x72, 0x65, 0x63, 0x6f, 0x72, 0x64, - 0x22, 0xca, 0x07, 0x0a, 0x0d, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x63, 0x74, 0x52, 0x65, 0x63, 0x6f, - 0x72, 0x64, 0x12, 0x10, 0x0a, 0x03, 0x61, 0x63, 0x69, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x03, 0x61, 0x63, 0x69, 0x12, 0x12, 0x0a, 0x04, 0x65, 0x31, 0x36, 0x34, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x04, 0x65, 0x31, 0x36, 0x34, 0x12, 0x10, 0x0a, 0x03, 0x70, 0x6e, 0x69, 0x18, - 0x0f, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x70, 0x6e, 0x69, 0x12, 0x1e, 0x0a, 0x0a, 0x70, 0x72, - 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x4b, 0x65, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0a, - 0x70, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x4b, 0x65, 0x79, 0x12, 0x20, 0x0a, 0x0b, 0x69, 0x64, - 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x4b, 0x65, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, - 0x0b, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x4b, 0x65, 0x79, 0x12, 0x50, 0x0a, 0x0d, - 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x53, 0x74, 0x61, 0x74, 0x65, 0x18, 0x05, 0x20, - 0x01, 0x28, 0x0e, 0x32, 0x2a, 0x2e, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x6c, 0x73, 0x65, 0x72, 0x76, - 0x69, 0x63, 0x65, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x63, 0x74, 0x52, 0x65, 0x63, 0x6f, 0x72, - 0x64, 0x2e, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, - 0x0d, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x1c, - 0x0a, 0x09, 0x67, 0x69, 0x76, 0x65, 0x6e, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x09, 0x67, 0x69, 0x76, 0x65, 0x6e, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1e, 0x0a, 0x0a, - 0x66, 0x61, 0x6d, 0x69, 0x6c, 0x79, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x0a, 0x66, 0x61, 0x6d, 0x69, 0x6c, 0x79, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1a, 0x0a, 0x08, - 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, - 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x62, 0x6c, 0x6f, 0x63, - 0x6b, 0x65, 0x64, 0x18, 0x09, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x62, 0x6c, 0x6f, 0x63, 0x6b, - 0x65, 0x64, 0x12, 0x20, 0x0a, 0x0b, 0x77, 0x68, 0x69, 0x74, 0x65, 0x6c, 0x69, 0x73, 0x74, 0x65, - 0x64, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, 0x77, 0x68, 0x69, 0x74, 0x65, 0x6c, 0x69, - 0x73, 0x74, 0x65, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x61, 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, 0x64, - 0x18, 0x0b, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x61, 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, 0x64, - 0x12, 0x22, 0x0a, 0x0c, 0x6d, 0x61, 0x72, 0x6b, 0x65, 0x64, 0x55, 0x6e, 0x72, 0x65, 0x61, 0x64, - 0x18, 0x0c, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0c, 0x6d, 0x61, 0x72, 0x6b, 0x65, 0x64, 0x55, 0x6e, - 0x72, 0x65, 0x61, 0x64, 0x12, 0x30, 0x0a, 0x13, 0x6d, 0x75, 0x74, 0x65, 0x64, 0x55, 0x6e, 0x74, - 0x69, 0x6c, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x0d, 0x20, 0x01, 0x28, - 0x04, 0x52, 0x13, 0x6d, 0x75, 0x74, 0x65, 0x64, 0x55, 0x6e, 0x74, 0x69, 0x6c, 0x54, 0x69, 0x6d, - 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x1c, 0x0a, 0x09, 0x68, 0x69, 0x64, 0x65, 0x53, 0x74, - 0x6f, 0x72, 0x79, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x68, 0x69, 0x64, 0x65, 0x53, - 0x74, 0x6f, 0x72, 0x79, 0x12, 0x38, 0x0a, 0x17, 0x75, 0x6e, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, - 0x65, 0x72, 0x65, 0x64, 0x41, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, - 0x10, 0x20, 0x01, 0x28, 0x04, 0x52, 0x17, 0x75, 0x6e, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, - 0x72, 0x65, 0x64, 0x41, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x28, - 0x0a, 0x0f, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x47, 0x69, 0x76, 0x65, 0x6e, 0x4e, 0x61, 0x6d, - 0x65, 0x18, 0x11, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x47, - 0x69, 0x76, 0x65, 0x6e, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x2a, 0x0a, 0x10, 0x73, 0x79, 0x73, 0x74, - 0x65, 0x6d, 0x46, 0x61, 0x6d, 0x69, 0x6c, 0x79, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x12, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x10, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x46, 0x61, 0x6d, 0x69, 0x6c, 0x79, - 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x26, 0x0a, 0x0e, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x4e, 0x69, - 0x63, 0x6b, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x13, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x73, 0x79, - 0x73, 0x74, 0x65, 0x6d, 0x4e, 0x69, 0x63, 0x6b, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x16, 0x0a, 0x06, - 0x68, 0x69, 0x64, 0x64, 0x65, 0x6e, 0x18, 0x14, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x68, 0x69, - 0x64, 0x64, 0x65, 0x6e, 0x12, 0x32, 0x0a, 0x14, 0x70, 0x6e, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x61, - 0x74, 0x75, 0x72, 0x65, 0x56, 0x65, 0x72, 0x69, 0x66, 0x69, 0x65, 0x64, 0x18, 0x15, 0x20, 0x01, - 0x28, 0x08, 0x52, 0x14, 0x70, 0x6e, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, - 0x56, 0x65, 0x72, 0x69, 0x66, 0x69, 0x65, 0x64, 0x12, 0x3d, 0x0a, 0x08, 0x6e, 0x69, 0x63, 0x6b, - 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x16, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x73, 0x69, 0x67, - 0x6e, 0x61, 0x6c, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x61, - 0x63, 0x74, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x2e, 0x4e, 0x61, 0x6d, 0x65, 0x52, 0x08, 0x6e, - 0x69, 0x63, 0x6b, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x6f, 0x74, 0x65, 0x18, - 0x17, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x6f, 0x74, 0x65, 0x1a, 0x34, 0x0a, 0x04, 0x4e, - 0x61, 0x6d, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x67, 0x69, 0x76, 0x65, 0x6e, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x05, 0x67, 0x69, 0x76, 0x65, 0x6e, 0x12, 0x16, 0x0a, 0x06, 0x66, 0x61, 0x6d, - 0x69, 0x6c, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x66, 0x61, 0x6d, 0x69, 0x6c, - 0x79, 0x22, 0x3a, 0x0a, 0x0d, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x53, 0x74, 0x61, - 0x74, 0x65, 0x12, 0x0b, 0x0a, 0x07, 0x44, 0x45, 0x46, 0x41, 0x55, 0x4c, 0x54, 0x10, 0x00, 0x12, - 0x0c, 0x0a, 0x08, 0x56, 0x45, 0x52, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x01, 0x12, 0x0e, 0x0a, - 0x0a, 0x55, 0x4e, 0x56, 0x45, 0x52, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x02, 0x22, 0xcd, 0x01, - 0x0a, 0x0d, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x56, 0x31, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x12, - 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x02, 0x69, 0x64, 0x12, - 0x18, 0x0a, 0x07, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x65, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, - 0x52, 0x07, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x65, 0x64, 0x12, 0x20, 0x0a, 0x0b, 0x77, 0x68, 0x69, - 0x74, 0x65, 0x6c, 0x69, 0x73, 0x74, 0x65, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, - 0x77, 0x68, 0x69, 0x74, 0x65, 0x6c, 0x69, 0x73, 0x74, 0x65, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x61, - 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x61, - 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, 0x64, 0x12, 0x22, 0x0a, 0x0c, 0x6d, 0x61, 0x72, 0x6b, 0x65, - 0x64, 0x55, 0x6e, 0x72, 0x65, 0x61, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0c, 0x6d, - 0x61, 0x72, 0x6b, 0x65, 0x64, 0x55, 0x6e, 0x72, 0x65, 0x61, 0x64, 0x12, 0x30, 0x0a, 0x13, 0x6d, - 0x75, 0x74, 0x65, 0x64, 0x55, 0x6e, 0x74, 0x69, 0x6c, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, - 0x6d, 0x70, 0x18, 0x06, 0x20, 0x01, 0x28, 0x04, 0x52, 0x13, 0x6d, 0x75, 0x74, 0x65, 0x64, 0x55, - 0x6e, 0x74, 0x69, 0x6c, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x22, 0xce, 0x03, - 0x0a, 0x0d, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x56, 0x32, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x12, - 0x1c, 0x0a, 0x09, 0x6d, 0x61, 0x73, 0x74, 0x65, 0x72, 0x4b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x0c, 0x52, 0x09, 0x6d, 0x61, 0x73, 0x74, 0x65, 0x72, 0x4b, 0x65, 0x79, 0x12, 0x18, 0x0a, - 0x07, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x65, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, - 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x65, 0x64, 0x12, 0x20, 0x0a, 0x0b, 0x77, 0x68, 0x69, 0x74, 0x65, - 0x6c, 0x69, 0x73, 0x74, 0x65, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, 0x77, 0x68, - 0x69, 0x74, 0x65, 0x6c, 0x69, 0x73, 0x74, 0x65, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x61, 0x72, 0x63, - 0x68, 0x69, 0x76, 0x65, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x61, 0x72, 0x63, - 0x68, 0x69, 0x76, 0x65, 0x64, 0x12, 0x22, 0x0a, 0x0c, 0x6d, 0x61, 0x72, 0x6b, 0x65, 0x64, 0x55, - 0x6e, 0x72, 0x65, 0x61, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0c, 0x6d, 0x61, 0x72, - 0x6b, 0x65, 0x64, 0x55, 0x6e, 0x72, 0x65, 0x61, 0x64, 0x12, 0x30, 0x0a, 0x13, 0x6d, 0x75, 0x74, - 0x65, 0x64, 0x55, 0x6e, 0x74, 0x69, 0x6c, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, - 0x18, 0x06, 0x20, 0x01, 0x28, 0x04, 0x52, 0x13, 0x6d, 0x75, 0x74, 0x65, 0x64, 0x55, 0x6e, 0x74, - 0x69, 0x6c, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x42, 0x0a, 0x1c, 0x64, - 0x6f, 0x6e, 0x74, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x79, 0x46, 0x6f, 0x72, 0x4d, 0x65, 0x6e, 0x74, - 0x69, 0x6f, 0x6e, 0x73, 0x49, 0x66, 0x4d, 0x75, 0x74, 0x65, 0x64, 0x18, 0x07, 0x20, 0x01, 0x28, - 0x08, 0x52, 0x1c, 0x64, 0x6f, 0x6e, 0x74, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x79, 0x46, 0x6f, 0x72, - 0x4d, 0x65, 0x6e, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x49, 0x66, 0x4d, 0x75, 0x74, 0x65, 0x64, 0x12, - 0x1c, 0x0a, 0x09, 0x68, 0x69, 0x64, 0x65, 0x53, 0x74, 0x6f, 0x72, 0x79, 0x18, 0x08, 0x20, 0x01, - 0x28, 0x08, 0x52, 0x09, 0x68, 0x69, 0x64, 0x65, 0x53, 0x74, 0x6f, 0x72, 0x79, 0x12, 0x50, 0x0a, - 0x0d, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x53, 0x65, 0x6e, 0x64, 0x4d, 0x6f, 0x64, 0x65, 0x18, 0x0a, - 0x20, 0x01, 0x28, 0x0e, 0x32, 0x2a, 0x2e, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x6c, 0x73, 0x65, 0x72, - 0x76, 0x69, 0x63, 0x65, 0x2e, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x56, 0x32, 0x52, 0x65, 0x63, 0x6f, - 0x72, 0x64, 0x2e, 0x53, 0x74, 0x6f, 0x72, 0x79, 0x53, 0x65, 0x6e, 0x64, 0x4d, 0x6f, 0x64, 0x65, - 0x52, 0x0d, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x53, 0x65, 0x6e, 0x64, 0x4d, 0x6f, 0x64, 0x65, 0x22, - 0x37, 0x0a, 0x0d, 0x53, 0x74, 0x6f, 0x72, 0x79, 0x53, 0x65, 0x6e, 0x64, 0x4d, 0x6f, 0x64, 0x65, - 0x12, 0x0b, 0x0a, 0x07, 0x44, 0x45, 0x46, 0x41, 0x55, 0x4c, 0x54, 0x10, 0x00, 0x12, 0x0c, 0x0a, - 0x08, 0x44, 0x49, 0x53, 0x41, 0x42, 0x4c, 0x45, 0x44, 0x10, 0x01, 0x12, 0x0b, 0x0a, 0x07, 0x45, - 0x4e, 0x41, 0x42, 0x4c, 0x45, 0x44, 0x10, 0x02, 0x4a, 0x04, 0x08, 0x09, 0x10, 0x0a, 0x22, 0x3e, - 0x0a, 0x08, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x65, 0x6e, - 0x61, 0x62, 0x6c, 0x65, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x65, 0x6e, 0x61, - 0x62, 0x6c, 0x65, 0x64, 0x12, 0x18, 0x0a, 0x07, 0x65, 0x6e, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x65, 0x6e, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x22, 0x9a, - 0x12, 0x0a, 0x0d, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, - 0x12, 0x1e, 0x0a, 0x0a, 0x70, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x4b, 0x65, 0x79, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0a, 0x70, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x4b, 0x65, 0x79, - 0x12, 0x1c, 0x0a, 0x09, 0x67, 0x69, 0x76, 0x65, 0x6e, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x09, 0x67, 0x69, 0x76, 0x65, 0x6e, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1e, - 0x0a, 0x0a, 0x66, 0x61, 0x6d, 0x69, 0x6c, 0x79, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x0a, 0x66, 0x61, 0x6d, 0x69, 0x6c, 0x79, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x24, - 0x0a, 0x0d, 0x61, 0x76, 0x61, 0x74, 0x61, 0x72, 0x55, 0x72, 0x6c, 0x50, 0x61, 0x74, 0x68, 0x18, - 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x61, 0x76, 0x61, 0x74, 0x61, 0x72, 0x55, 0x72, 0x6c, - 0x50, 0x61, 0x74, 0x68, 0x12, 0x2e, 0x0a, 0x12, 0x6e, 0x6f, 0x74, 0x65, 0x54, 0x6f, 0x53, 0x65, - 0x6c, 0x66, 0x41, 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, - 0x52, 0x12, 0x6e, 0x6f, 0x74, 0x65, 0x54, 0x6f, 0x53, 0x65, 0x6c, 0x66, 0x41, 0x72, 0x63, 0x68, - 0x69, 0x76, 0x65, 0x64, 0x12, 0x22, 0x0a, 0x0c, 0x72, 0x65, 0x61, 0x64, 0x52, 0x65, 0x63, 0x65, - 0x69, 0x70, 0x74, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0c, 0x72, 0x65, 0x61, 0x64, - 0x52, 0x65, 0x63, 0x65, 0x69, 0x70, 0x74, 0x73, 0x12, 0x36, 0x0a, 0x16, 0x73, 0x65, 0x61, 0x6c, - 0x65, 0x64, 0x53, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x49, 0x6e, 0x64, 0x69, 0x63, 0x61, 0x74, 0x6f, - 0x72, 0x73, 0x18, 0x07, 0x20, 0x01, 0x28, 0x08, 0x52, 0x16, 0x73, 0x65, 0x61, 0x6c, 0x65, 0x64, - 0x53, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x49, 0x6e, 0x64, 0x69, 0x63, 0x61, 0x74, 0x6f, 0x72, 0x73, - 0x12, 0x2a, 0x0a, 0x10, 0x74, 0x79, 0x70, 0x69, 0x6e, 0x67, 0x49, 0x6e, 0x64, 0x69, 0x63, 0x61, - 0x74, 0x6f, 0x72, 0x73, 0x18, 0x08, 0x20, 0x01, 0x28, 0x08, 0x52, 0x10, 0x74, 0x79, 0x70, 0x69, - 0x6e, 0x67, 0x49, 0x6e, 0x64, 0x69, 0x63, 0x61, 0x74, 0x6f, 0x72, 0x73, 0x12, 0x36, 0x0a, 0x16, - 0x6e, 0x6f, 0x74, 0x65, 0x54, 0x6f, 0x53, 0x65, 0x6c, 0x66, 0x4d, 0x61, 0x72, 0x6b, 0x65, 0x64, - 0x55, 0x6e, 0x72, 0x65, 0x61, 0x64, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x08, 0x52, 0x16, 0x6e, 0x6f, - 0x74, 0x65, 0x54, 0x6f, 0x53, 0x65, 0x6c, 0x66, 0x4d, 0x61, 0x72, 0x6b, 0x65, 0x64, 0x55, 0x6e, - 0x72, 0x65, 0x61, 0x64, 0x12, 0x22, 0x0a, 0x0c, 0x6c, 0x69, 0x6e, 0x6b, 0x50, 0x72, 0x65, 0x76, - 0x69, 0x65, 0x77, 0x73, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0c, 0x6c, 0x69, 0x6e, 0x6b, - 0x50, 0x72, 0x65, 0x76, 0x69, 0x65, 0x77, 0x73, 0x12, 0x6b, 0x0a, 0x16, 0x70, 0x68, 0x6f, 0x6e, - 0x65, 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x53, 0x68, 0x61, 0x72, 0x69, 0x6e, 0x67, 0x4d, 0x6f, - 0x64, 0x65, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x33, 0x2e, 0x73, 0x69, 0x67, 0x6e, 0x61, - 0x6c, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, - 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x2e, 0x50, 0x68, 0x6f, 0x6e, 0x65, 0x4e, 0x75, 0x6d, 0x62, - 0x65, 0x72, 0x53, 0x68, 0x61, 0x72, 0x69, 0x6e, 0x67, 0x4d, 0x6f, 0x64, 0x65, 0x52, 0x16, 0x70, - 0x68, 0x6f, 0x6e, 0x65, 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x53, 0x68, 0x61, 0x72, 0x69, 0x6e, - 0x67, 0x4d, 0x6f, 0x64, 0x65, 0x12, 0x30, 0x0a, 0x13, 0x75, 0x6e, 0x6c, 0x69, 0x73, 0x74, 0x65, - 0x64, 0x50, 0x68, 0x6f, 0x6e, 0x65, 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x18, 0x0d, 0x20, 0x01, - 0x28, 0x08, 0x52, 0x13, 0x75, 0x6e, 0x6c, 0x69, 0x73, 0x74, 0x65, 0x64, 0x50, 0x68, 0x6f, 0x6e, - 0x65, 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x12, 0x61, 0x0a, 0x13, 0x70, 0x69, 0x6e, 0x6e, 0x65, - 0x64, 0x43, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x0e, - 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2f, 0x2e, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x6c, 0x73, 0x65, 0x72, - 0x76, 0x69, 0x63, 0x65, 0x2e, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x52, 0x65, 0x63, 0x6f, - 0x72, 0x64, 0x2e, 0x50, 0x69, 0x6e, 0x6e, 0x65, 0x64, 0x43, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x13, 0x70, 0x69, 0x6e, 0x6e, 0x65, 0x64, 0x43, 0x6f, 0x6e, - 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x32, 0x0a, 0x14, 0x70, 0x72, - 0x65, 0x66, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x63, 0x74, 0x41, 0x76, 0x61, 0x74, 0x61, - 0x72, 0x73, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x08, 0x52, 0x14, 0x70, 0x72, 0x65, 0x66, 0x65, 0x72, - 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x63, 0x74, 0x41, 0x76, 0x61, 0x74, 0x61, 0x72, 0x73, 0x12, 0x33, - 0x0a, 0x08, 0x70, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x10, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x17, 0x2e, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x6c, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, - 0x2e, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x08, 0x70, 0x61, 0x79, 0x6d, 0x65, - 0x6e, 0x74, 0x73, 0x12, 0x32, 0x0a, 0x14, 0x75, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x61, 0x6c, - 0x45, 0x78, 0x70, 0x69, 0x72, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x72, 0x18, 0x11, 0x20, 0x01, 0x28, - 0x0d, 0x52, 0x14, 0x75, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x61, 0x6c, 0x45, 0x78, 0x70, 0x69, - 0x72, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x72, 0x12, 0x28, 0x0a, 0x0f, 0x70, 0x72, 0x69, 0x6d, 0x61, - 0x72, 0x79, 0x53, 0x65, 0x6e, 0x64, 0x73, 0x53, 0x6d, 0x73, 0x18, 0x12, 0x20, 0x01, 0x28, 0x08, - 0x52, 0x0f, 0x70, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x53, 0x65, 0x6e, 0x64, 0x73, 0x53, 0x6d, - 0x73, 0x12, 0x12, 0x0a, 0x04, 0x65, 0x31, 0x36, 0x34, 0x18, 0x13, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x04, 0x65, 0x31, 0x36, 0x34, 0x12, 0x36, 0x0a, 0x16, 0x70, 0x72, 0x65, 0x66, 0x65, 0x72, 0x72, - 0x65, 0x64, 0x52, 0x65, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x6d, 0x6f, 0x6a, 0x69, 0x18, - 0x14, 0x20, 0x03, 0x28, 0x09, 0x52, 0x16, 0x70, 0x72, 0x65, 0x66, 0x65, 0x72, 0x72, 0x65, 0x64, - 0x52, 0x65, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x6d, 0x6f, 0x6a, 0x69, 0x12, 0x22, 0x0a, - 0x0c, 0x73, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x72, 0x49, 0x64, 0x18, 0x15, 0x20, - 0x01, 0x28, 0x0c, 0x52, 0x0c, 0x73, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x72, 0x49, - 0x64, 0x12, 0x36, 0x0a, 0x16, 0x73, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x72, 0x43, - 0x75, 0x72, 0x72, 0x65, 0x6e, 0x63, 0x79, 0x43, 0x6f, 0x64, 0x65, 0x18, 0x16, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x16, 0x73, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x72, 0x43, 0x75, 0x72, - 0x72, 0x65, 0x6e, 0x63, 0x79, 0x43, 0x6f, 0x64, 0x65, 0x12, 0x36, 0x0a, 0x16, 0x64, 0x69, 0x73, - 0x70, 0x6c, 0x61, 0x79, 0x42, 0x61, 0x64, 0x67, 0x65, 0x73, 0x4f, 0x6e, 0x50, 0x72, 0x6f, 0x66, - 0x69, 0x6c, 0x65, 0x18, 0x17, 0x20, 0x01, 0x28, 0x08, 0x52, 0x16, 0x64, 0x69, 0x73, 0x70, 0x6c, - 0x61, 0x79, 0x42, 0x61, 0x64, 0x67, 0x65, 0x73, 0x4f, 0x6e, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, - 0x65, 0x12, 0x44, 0x0a, 0x1d, 0x73, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, - 0x6e, 0x4d, 0x61, 0x6e, 0x75, 0x61, 0x6c, 0x6c, 0x79, 0x43, 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x6c, - 0x65, 0x64, 0x18, 0x18, 0x20, 0x01, 0x28, 0x08, 0x52, 0x1d, 0x73, 0x75, 0x62, 0x73, 0x63, 0x72, - 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x4d, 0x61, 0x6e, 0x75, 0x61, 0x6c, 0x6c, 0x79, 0x43, 0x61, - 0x6e, 0x63, 0x65, 0x6c, 0x6c, 0x65, 0x64, 0x12, 0x36, 0x0a, 0x16, 0x6b, 0x65, 0x65, 0x70, 0x4d, - 0x75, 0x74, 0x65, 0x64, 0x43, 0x68, 0x61, 0x74, 0x73, 0x41, 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, - 0x64, 0x18, 0x19, 0x20, 0x01, 0x28, 0x08, 0x52, 0x16, 0x6b, 0x65, 0x65, 0x70, 0x4d, 0x75, 0x74, - 0x65, 0x64, 0x43, 0x68, 0x61, 0x74, 0x73, 0x41, 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, 0x64, 0x12, - 0x36, 0x0a, 0x16, 0x68, 0x61, 0x73, 0x53, 0x65, 0x74, 0x4d, 0x79, 0x53, 0x74, 0x6f, 0x72, 0x69, - 0x65, 0x73, 0x50, 0x72, 0x69, 0x76, 0x61, 0x63, 0x79, 0x18, 0x1a, 0x20, 0x01, 0x28, 0x08, 0x52, - 0x16, 0x68, 0x61, 0x73, 0x53, 0x65, 0x74, 0x4d, 0x79, 0x53, 0x74, 0x6f, 0x72, 0x69, 0x65, 0x73, - 0x50, 0x72, 0x69, 0x76, 0x61, 0x63, 0x79, 0x12, 0x3a, 0x0a, 0x18, 0x68, 0x61, 0x73, 0x56, 0x69, - 0x65, 0x77, 0x65, 0x64, 0x4f, 0x6e, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x69, 0x6e, 0x67, 0x53, 0x74, - 0x6f, 0x72, 0x79, 0x18, 0x1b, 0x20, 0x01, 0x28, 0x08, 0x52, 0x18, 0x68, 0x61, 0x73, 0x56, 0x69, - 0x65, 0x77, 0x65, 0x64, 0x4f, 0x6e, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x69, 0x6e, 0x67, 0x53, 0x74, - 0x6f, 0x72, 0x79, 0x12, 0x28, 0x0a, 0x0f, 0x73, 0x74, 0x6f, 0x72, 0x69, 0x65, 0x73, 0x44, 0x69, - 0x73, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x18, 0x1d, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0f, 0x73, 0x74, - 0x6f, 0x72, 0x69, 0x65, 0x73, 0x44, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x12, 0x57, 0x0a, - 0x18, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x56, 0x69, 0x65, 0x77, 0x52, 0x65, 0x63, 0x65, 0x69, 0x70, - 0x74, 0x73, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x18, 0x1e, 0x20, 0x01, 0x28, 0x0e, 0x32, - 0x1b, 0x2e, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x6c, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, - 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x42, 0x6f, 0x6f, 0x6c, 0x52, 0x18, 0x73, 0x74, - 0x6f, 0x72, 0x79, 0x56, 0x69, 0x65, 0x77, 0x52, 0x65, 0x63, 0x65, 0x69, 0x70, 0x74, 0x73, 0x45, - 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x12, 0x48, 0x0a, 0x1f, 0x68, 0x61, 0x73, 0x53, 0x65, 0x65, - 0x6e, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x53, 0x74, 0x6f, 0x72, 0x79, 0x45, 0x64, 0x75, 0x63, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x68, 0x65, 0x65, 0x74, 0x18, 0x20, 0x20, 0x01, 0x28, 0x08, 0x52, - 0x1f, 0x68, 0x61, 0x73, 0x53, 0x65, 0x65, 0x6e, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x53, 0x74, 0x6f, - 0x72, 0x79, 0x45, 0x64, 0x75, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x68, 0x65, 0x65, 0x74, - 0x12, 0x1a, 0x0a, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x21, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x46, 0x0a, 0x1e, - 0x68, 0x61, 0x73, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x55, 0x73, 0x65, 0x72, - 0x6e, 0x61, 0x6d, 0x65, 0x4f, 0x6e, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x69, 0x6e, 0x67, 0x18, 0x22, - 0x20, 0x01, 0x28, 0x08, 0x52, 0x1e, 0x68, 0x61, 0x73, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, - 0x65, 0x64, 0x55, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x4f, 0x6e, 0x62, 0x6f, 0x61, 0x72, - 0x64, 0x69, 0x6e, 0x67, 0x12, 0x4d, 0x0a, 0x0c, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, - 0x4c, 0x69, 0x6e, 0x6b, 0x18, 0x23, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x73, 0x69, 0x67, - 0x6e, 0x61, 0x6c, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x41, 0x63, 0x63, 0x6f, 0x75, - 0x6e, 0x74, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, - 0x65, 0x4c, 0x69, 0x6e, 0x6b, 0x52, 0x0c, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x4c, - 0x69, 0x6e, 0x6b, 0x1a, 0x86, 0x02, 0x0a, 0x12, 0x50, 0x69, 0x6e, 0x6e, 0x65, 0x64, 0x43, 0x6f, - 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x53, 0x0a, 0x07, 0x63, 0x6f, - 0x6e, 0x74, 0x61, 0x63, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x37, 0x2e, 0x73, 0x69, - 0x67, 0x6e, 0x61, 0x6c, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x41, 0x63, 0x63, 0x6f, - 0x75, 0x6e, 0x74, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x2e, 0x50, 0x69, 0x6e, 0x6e, 0x65, 0x64, - 0x43, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x43, 0x6f, 0x6e, - 0x74, 0x61, 0x63, 0x74, 0x48, 0x00, 0x52, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x63, 0x74, 0x12, - 0x26, 0x0a, 0x0d, 0x6c, 0x65, 0x67, 0x61, 0x63, 0x79, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x49, 0x64, - 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x48, 0x00, 0x52, 0x0d, 0x6c, 0x65, 0x67, 0x61, 0x63, 0x79, - 0x47, 0x72, 0x6f, 0x75, 0x70, 0x49, 0x64, 0x12, 0x28, 0x0a, 0x0e, 0x67, 0x72, 0x6f, 0x75, 0x70, - 0x4d, 0x61, 0x73, 0x74, 0x65, 0x72, 0x4b, 0x65, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x48, - 0x00, 0x52, 0x0e, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x4d, 0x61, 0x73, 0x74, 0x65, 0x72, 0x4b, 0x65, - 0x79, 0x1a, 0x3b, 0x0a, 0x07, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x63, 0x74, 0x12, 0x1c, 0x0a, 0x09, - 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x09, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x49, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x65, 0x31, - 0x36, 0x34, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x65, 0x31, 0x36, 0x34, 0x42, 0x0c, - 0x0a, 0x0a, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x1a, 0xf8, 0x01, 0x0a, - 0x0c, 0x55, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x4c, 0x69, 0x6e, 0x6b, 0x12, 0x18, 0x0a, - 0x07, 0x65, 0x6e, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, - 0x65, 0x6e, 0x74, 0x72, 0x6f, 0x70, 0x79, 0x12, 0x1a, 0x0a, 0x08, 0x73, 0x65, 0x72, 0x76, 0x65, - 0x72, 0x49, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, 0x73, 0x65, 0x72, 0x76, 0x65, - 0x72, 0x49, 0x64, 0x12, 0x45, 0x0a, 0x05, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x18, 0x03, 0x20, 0x01, - 0x28, 0x0e, 0x32, 0x2f, 0x2e, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x6c, 0x73, 0x65, 0x72, 0x76, 0x69, - 0x63, 0x65, 0x2e, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, - 0x2e, 0x55, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x4c, 0x69, 0x6e, 0x6b, 0x2e, 0x43, 0x6f, - 0x6c, 0x6f, 0x72, 0x52, 0x05, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x22, 0x6b, 0x0a, 0x05, 0x43, 0x6f, - 0x6c, 0x6f, 0x72, 0x12, 0x0b, 0x0a, 0x07, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x00, - 0x12, 0x08, 0x0a, 0x04, 0x42, 0x4c, 0x55, 0x45, 0x10, 0x01, 0x12, 0x09, 0x0a, 0x05, 0x57, 0x48, - 0x49, 0x54, 0x45, 0x10, 0x02, 0x12, 0x08, 0x0a, 0x04, 0x47, 0x52, 0x45, 0x59, 0x10, 0x03, 0x12, - 0x09, 0x0a, 0x05, 0x4f, 0x4c, 0x49, 0x56, 0x45, 0x10, 0x04, 0x12, 0x09, 0x0a, 0x05, 0x47, 0x52, - 0x45, 0x45, 0x4e, 0x10, 0x05, 0x12, 0x0a, 0x0a, 0x06, 0x4f, 0x52, 0x41, 0x4e, 0x47, 0x45, 0x10, - 0x06, 0x12, 0x08, 0x0a, 0x04, 0x50, 0x49, 0x4e, 0x4b, 0x10, 0x07, 0x12, 0x0a, 0x0a, 0x06, 0x50, - 0x55, 0x52, 0x50, 0x4c, 0x45, 0x10, 0x08, 0x22, 0x40, 0x0a, 0x16, 0x50, 0x68, 0x6f, 0x6e, 0x65, - 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x53, 0x68, 0x61, 0x72, 0x69, 0x6e, 0x67, 0x4d, 0x6f, 0x64, - 0x65, 0x12, 0x0b, 0x0a, 0x07, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x00, 0x12, 0x0d, - 0x0a, 0x09, 0x45, 0x56, 0x45, 0x52, 0x59, 0x42, 0x4f, 0x44, 0x59, 0x10, 0x01, 0x12, 0x0a, 0x0a, - 0x06, 0x4e, 0x4f, 0x42, 0x4f, 0x44, 0x59, 0x10, 0x02, 0x4a, 0x04, 0x08, 0x09, 0x10, 0x0a, 0x4a, - 0x04, 0x08, 0x1c, 0x10, 0x1d, 0x4a, 0x04, 0x08, 0x1f, 0x10, 0x20, 0x22, 0xfb, 0x01, 0x0a, 0x1b, - 0x53, 0x74, 0x6f, 0x72, 0x79, 0x44, 0x69, 0x73, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x69, 0x6f, - 0x6e, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x12, 0x1e, 0x0a, 0x0a, 0x69, - 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, - 0x0a, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x12, 0x12, 0x0a, 0x04, 0x6e, - 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, - 0x30, 0x0a, 0x13, 0x72, 0x65, 0x63, 0x69, 0x70, 0x69, 0x65, 0x6e, 0x74, 0x53, 0x65, 0x72, 0x76, - 0x69, 0x63, 0x65, 0x49, 0x64, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x13, 0x72, 0x65, - 0x63, 0x69, 0x70, 0x69, 0x65, 0x6e, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x49, 0x64, - 0x73, 0x12, 0x2e, 0x0a, 0x12, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x41, 0x74, 0x54, 0x69, - 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x04, 0x20, 0x01, 0x28, 0x04, 0x52, 0x12, 0x64, - 0x65, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x41, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, - 0x70, 0x12, 0x24, 0x0a, 0x0d, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x73, 0x52, 0x65, 0x70, 0x6c, 0x69, - 0x65, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0d, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x73, - 0x52, 0x65, 0x70, 0x6c, 0x69, 0x65, 0x73, 0x12, 0x20, 0x0a, 0x0b, 0x69, 0x73, 0x42, 0x6c, 0x6f, - 0x63, 0x6b, 0x4c, 0x69, 0x73, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, 0x69, 0x73, - 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x4c, 0x69, 0x73, 0x74, 0x2a, 0x34, 0x0a, 0x0c, 0x4f, 0x70, 0x74, - 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x42, 0x6f, 0x6f, 0x6c, 0x12, 0x09, 0x0a, 0x05, 0x55, 0x4e, 0x53, - 0x45, 0x54, 0x10, 0x00, 0x12, 0x0b, 0x0a, 0x07, 0x45, 0x4e, 0x41, 0x42, 0x4c, 0x45, 0x44, 0x10, - 0x01, 0x12, 0x0c, 0x0a, 0x08, 0x44, 0x49, 0x53, 0x41, 0x42, 0x4c, 0x45, 0x44, 0x10, 0x02, 0x42, - 0x3c, 0x0a, 0x38, 0x6f, 0x72, 0x67, 0x2e, 0x77, 0x68, 0x69, 0x73, 0x70, 0x65, 0x72, 0x73, 0x79, - 0x73, 0x74, 0x65, 0x6d, 0x73, 0x2e, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x6c, 0x73, 0x65, 0x72, 0x76, - 0x69, 0x63, 0x65, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x73, 0x74, 0x6f, - 0x72, 0x61, 0x67, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x50, 0x01, 0x62, 0x06, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x33, -} +//go:embed StorageService.pb.raw +var file_StorageService_proto_rawDesc []byte var ( file_StorageService_proto_rawDescOnce sync.Once @@ -2360,7 +2011,7 @@ func file_StorageService_proto_rawDescGZIP() []byte { var file_StorageService_proto_enumTypes = make([]protoimpl.EnumInfo, 6) var file_StorageService_proto_msgTypes = make([]protoimpl.MessageInfo, 18) -var file_StorageService_proto_goTypes = []interface{}{ +var file_StorageService_proto_goTypes = []any{ (OptionalBool)(0), // 0: signalservice.OptionalBool (ManifestRecord_Identifier_Type)(0), // 1: signalservice.ManifestRecord.Identifier.Type (ContactRecord_IdentityState)(0), // 2: signalservice.ContactRecord.IdentityState @@ -2420,7 +2071,7 @@ func file_StorageService_proto_init() { return } if !protoimpl.UnsafeEnabled { - file_StorageService_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + file_StorageService_proto_msgTypes[0].Exporter = func(v any, i int) any { switch v := v.(*StorageManifest); i { case 0: return &v.state @@ -2432,7 +2083,7 @@ func file_StorageService_proto_init() { return nil } } - file_StorageService_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + file_StorageService_proto_msgTypes[1].Exporter = func(v any, i int) any { switch v := v.(*StorageItem); i { case 0: return &v.state @@ -2444,7 +2095,7 @@ func file_StorageService_proto_init() { return nil } } - file_StorageService_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + file_StorageService_proto_msgTypes[2].Exporter = func(v any, i int) any { switch v := v.(*StorageItems); i { case 0: return &v.state @@ -2456,7 +2107,7 @@ func file_StorageService_proto_init() { return nil } } - file_StorageService_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { + file_StorageService_proto_msgTypes[3].Exporter = func(v any, i int) any { switch v := v.(*ReadOperation); i { case 0: return &v.state @@ -2468,7 +2119,7 @@ func file_StorageService_proto_init() { return nil } } - file_StorageService_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { + file_StorageService_proto_msgTypes[4].Exporter = func(v any, i int) any { switch v := v.(*WriteOperation); i { case 0: return &v.state @@ -2480,7 +2131,7 @@ func file_StorageService_proto_init() { return nil } } - file_StorageService_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { + file_StorageService_proto_msgTypes[5].Exporter = func(v any, i int) any { switch v := v.(*ManifestRecord); i { case 0: return &v.state @@ -2492,7 +2143,7 @@ func file_StorageService_proto_init() { return nil } } - file_StorageService_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { + file_StorageService_proto_msgTypes[6].Exporter = func(v any, i int) any { switch v := v.(*StorageRecord); i { case 0: return &v.state @@ -2504,7 +2155,7 @@ func file_StorageService_proto_init() { return nil } } - file_StorageService_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { + file_StorageService_proto_msgTypes[7].Exporter = func(v any, i int) any { switch v := v.(*ContactRecord); i { case 0: return &v.state @@ -2516,7 +2167,7 @@ func file_StorageService_proto_init() { return nil } } - file_StorageService_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { + file_StorageService_proto_msgTypes[8].Exporter = func(v any, i int) any { switch v := v.(*GroupV1Record); i { case 0: return &v.state @@ -2528,7 +2179,7 @@ func file_StorageService_proto_init() { return nil } } - file_StorageService_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { + file_StorageService_proto_msgTypes[9].Exporter = func(v any, i int) any { switch v := v.(*GroupV2Record); i { case 0: return &v.state @@ -2540,7 +2191,7 @@ func file_StorageService_proto_init() { return nil } } - file_StorageService_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} { + file_StorageService_proto_msgTypes[10].Exporter = func(v any, i int) any { switch v := v.(*Payments); i { case 0: return &v.state @@ -2552,7 +2203,7 @@ func file_StorageService_proto_init() { return nil } } - file_StorageService_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} { + file_StorageService_proto_msgTypes[11].Exporter = func(v any, i int) any { switch v := v.(*AccountRecord); i { case 0: return &v.state @@ -2564,7 +2215,7 @@ func file_StorageService_proto_init() { return nil } } - file_StorageService_proto_msgTypes[12].Exporter = func(v interface{}, i int) interface{} { + file_StorageService_proto_msgTypes[12].Exporter = func(v any, i int) any { switch v := v.(*StoryDistributionListRecord); i { case 0: return &v.state @@ -2576,7 +2227,7 @@ func file_StorageService_proto_init() { return nil } } - file_StorageService_proto_msgTypes[13].Exporter = func(v interface{}, i int) interface{} { + file_StorageService_proto_msgTypes[13].Exporter = func(v any, i int) any { switch v := v.(*ManifestRecord_Identifier); i { case 0: return &v.state @@ -2588,7 +2239,7 @@ func file_StorageService_proto_init() { return nil } } - file_StorageService_proto_msgTypes[14].Exporter = func(v interface{}, i int) interface{} { + file_StorageService_proto_msgTypes[14].Exporter = func(v any, i int) any { switch v := v.(*ContactRecord_Name); i { case 0: return &v.state @@ -2600,7 +2251,7 @@ func file_StorageService_proto_init() { return nil } } - file_StorageService_proto_msgTypes[15].Exporter = func(v interface{}, i int) interface{} { + file_StorageService_proto_msgTypes[15].Exporter = func(v any, i int) any { switch v := v.(*AccountRecord_PinnedConversation); i { case 0: return &v.state @@ -2612,7 +2263,7 @@ func file_StorageService_proto_init() { return nil } } - file_StorageService_proto_msgTypes[16].Exporter = func(v interface{}, i int) interface{} { + file_StorageService_proto_msgTypes[16].Exporter = func(v any, i int) any { switch v := v.(*AccountRecord_UsernameLink); i { case 0: return &v.state @@ -2624,7 +2275,7 @@ func file_StorageService_proto_init() { return nil } } - file_StorageService_proto_msgTypes[17].Exporter = func(v interface{}, i int) interface{} { + file_StorageService_proto_msgTypes[17].Exporter = func(v any, i int) any { switch v := v.(*AccountRecord_PinnedConversation_Contact); i { case 0: return &v.state @@ -2637,14 +2288,14 @@ func file_StorageService_proto_init() { } } } - file_StorageService_proto_msgTypes[6].OneofWrappers = []interface{}{ + file_StorageService_proto_msgTypes[6].OneofWrappers = []any{ (*StorageRecord_Contact)(nil), (*StorageRecord_GroupV1)(nil), (*StorageRecord_GroupV2)(nil), (*StorageRecord_Account)(nil), (*StorageRecord_StoryDistributionList)(nil), } - file_StorageService_proto_msgTypes[15].OneofWrappers = []interface{}{ + file_StorageService_proto_msgTypes[15].OneofWrappers = []any{ (*AccountRecord_PinnedConversation_Contact_)(nil), (*AccountRecord_PinnedConversation_LegacyGroupId)(nil), (*AccountRecord_PinnedConversation_GroupMasterKey)(nil), diff --git a/pkg/signalmeow/protobuf/StorageService.pb.raw b/pkg/signalmeow/protobuf/StorageService.pb.raw new file mode 100644 index 0000000000000000000000000000000000000000..bd966cb8940f6481e516cf67d985ee329185222f GIT binary patch literal 5605 zcmdT|+ioMr5j7=B8a6LW_sZId_Tu%}FysZyWVsvL*j!+eqO|l%B+(?b*e7GeX;Bjm zXNaDmHv9p9gg+-Q0Rkjnk^Dn|yrimouDodd>KB4tm+tDCsybCo_6LC{%n2WGachrx zZ6>_Hqh;ToxTfPPqR}AtLa}qxwXe7zP@U}Ea^c&atLL8Pj`A#8(tWaXYdUkTZvnl; z)WY~ZDTZ5g0zRcxvVFrBQnkeJ?*_H+Nhzh~)8COD8}xn9+&(JS4{I4iYbjZ#1dXpq znQ_zV&A2cFFc&QsKzJjM-v$e#rSZ2Msk{}iec8w?VbU5&}IW+SuWyXgH3Z2QOFDYYReF{x@;B#$dvBzvRon{MxIxB3w-TD|VD(Hd5B zxHx6KQUBt3bt_ratJ}C}v|7DUcUaBShvdOv*kkX0JnjsJtkWC~JH76YXRxU582{NK z>yKC@PC;`by!q_nxy+ejeOdEVaTCo@JkhMn zPq#_4zN}eCO>;c<=58P(XjQYJxQS*cPA|zPKGclGvF!)KzMNxHoxy*72ZEY?Jfk}sXRf?ill4zflRVDFSK68o(Bdm|YC8+b-jnPU1WhoYn&if7%=t^l8{cqCF91tp z(Gu_Z{u+v$1K$j|L~_$4+}9N2YcR~xi;^9$DO8N9DPY@?i&a!FNq&X~Mf(194ttNF zXgEWA3V2~oXL=b#^K2ap{csJgm9e5%gximuS0si&Zd1Tn{4lfizV9 zKYU5@D22!?gD^}fwLs%l@P%m=u8dcttSWdI(pWQ(+b50D*%0b%iD(yX);a04kD<_3 z2pM(b^_KC^94TjN8Axo|RtNy_FCDhnK5PzKL@JGK4BHSDqcC0xTdY+Y`$b`kX}LaZ zjel)N_X#U32J+OzFjegZmXL(->$)9nl1COmR@VdQUz~X29Gd{o^*dMRnB6)SB#qrE zlTB=_Q5s7nHWX9|B?InS=bpu7Fgg0Br+<*=e6mV($Oi4Kd zoJ**K8)Z=^g8&%v1-20ZFy;#^jR0SevUzI;rWgsQZwA*AwF)dtq%}e@`G?+sJ6DaU zva1wW!@*?1+72Mi?OEVUV1i^x)95$kz~?472fqXt9oMqQCP2L(hQ$Uh)>&xqYP96dYit9T9+Su6jx)Rl3|e#3aTYDp9dieZlP>*ow-BCw!}&}W?$)&# z_;DHdja1*jMZIg&AMoHDT3%1s-0utf)*LVNL#4N#3$w2doC`=lZuQ(t&lDEqm+J2x zO3jUY*|e#%V8l=b__0*EhhPCFL}dDw=n_BhoTys0!0MgK^vQo@C6Gt zM(71>jR|q#P@pRdN3#S^Hu2NN;eT_al=f2^_!W{zz>l99ca~KHH!QJuP1|H=>^Yv0 zcdLA$dZ*6=hk+VX+Qtppk!x&el7|hAvh((JXV``}4IrMf_B(jc0AlZ~ zbJ2$94EPJgcDK4i3EAzjM)$N`-9_1cr~9V5ht&Rv_0QT>&G?=iq>w5FkJ;19q|k=` z{#~Zj9lAaFKWwO=t$I{_48NaNpBn$mk%uyqmR}CkYXG)NiSxsmAVrZg434_t z2gAV&krf^a?3oQ6*g(Bjb}Sz}jb(lv3!5SJvX+@6F`Dvh4ToZjcXGrx2VOU^=lA(zBPOlrBE_IY!+<8;7P;BbvhrD(+FYntvqUd16w7 mf!&7(Of_}-OL=FzFmJ$XZ4GN7Jmso4T)&^Y+?B7nFa8hxW5W*s literal 0 HcmV?d00001 diff --git a/pkg/signalmeow/protobuf/UnidentifiedDelivery.pb.go b/pkg/signalmeow/protobuf/UnidentifiedDelivery.pb.go index fbfebf5..97d1b46 100644 --- a/pkg/signalmeow/protobuf/UnidentifiedDelivery.pb.go +++ b/pkg/signalmeow/protobuf/UnidentifiedDelivery.pb.go @@ -1,6 +1,6 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.34.1 +// protoc-gen-go v1.34.2 // protoc v3.21.12 // source: UnidentifiedDelivery.proto @@ -16,6 +16,8 @@ import ( sync "sync" ) +import _ "embed" + const ( // Verify that this generated code is sufficiently up-to-date. _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) @@ -543,82 +545,8 @@ func (x *UnidentifiedSenderMessage_Message) GetGroupId() []byte { var File_UnidentifiedDelivery_proto protoreflect.FileDescriptor -var file_UnidentifiedDelivery_proto_rawDesc = []byte{ - 0x0a, 0x1a, 0x55, 0x6e, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x64, 0x44, 0x65, - 0x6c, 0x69, 0x76, 0x65, 0x72, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0d, 0x73, 0x69, - 0x67, 0x6e, 0x61, 0x6c, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x22, 0x84, 0x01, 0x0a, 0x11, - 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, - 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0b, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, - 0x61, 0x74, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, - 0x65, 0x1a, 0x2f, 0x0a, 0x0b, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, - 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x02, 0x69, 0x64, - 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x03, 0x6b, - 0x65, 0x79, 0x22, 0xbd, 0x02, 0x0a, 0x11, 0x53, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x43, 0x65, 0x72, - 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x63, 0x65, 0x72, 0x74, - 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0b, 0x63, - 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x73, 0x69, - 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x73, - 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x1a, 0xe7, 0x01, 0x0a, 0x0b, 0x43, 0x65, 0x72, - 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x12, 0x1e, 0x0a, 0x0a, 0x73, 0x65, 0x6e, 0x64, - 0x65, 0x72, 0x45, 0x31, 0x36, 0x34, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x73, 0x65, - 0x6e, 0x64, 0x65, 0x72, 0x45, 0x31, 0x36, 0x34, 0x12, 0x1e, 0x0a, 0x0a, 0x73, 0x65, 0x6e, 0x64, - 0x65, 0x72, 0x55, 0x75, 0x69, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x73, 0x65, - 0x6e, 0x64, 0x65, 0x72, 0x55, 0x75, 0x69, 0x64, 0x12, 0x22, 0x0a, 0x0c, 0x73, 0x65, 0x6e, 0x64, - 0x65, 0x72, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0c, - 0x73, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x12, 0x18, 0x0a, 0x07, - 0x65, 0x78, 0x70, 0x69, 0x72, 0x65, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x06, 0x52, 0x07, 0x65, - 0x78, 0x70, 0x69, 0x72, 0x65, 0x73, 0x12, 0x20, 0x0a, 0x0b, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, - 0x74, 0x79, 0x4b, 0x65, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0b, 0x69, 0x64, 0x65, - 0x6e, 0x74, 0x69, 0x74, 0x79, 0x4b, 0x65, 0x79, 0x12, 0x38, 0x0a, 0x06, 0x73, 0x69, 0x67, 0x6e, - 0x65, 0x72, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x73, 0x69, 0x67, 0x6e, 0x61, - 0x6c, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x43, - 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x52, 0x06, 0x73, 0x69, 0x67, 0x6e, - 0x65, 0x72, 0x22, 0xe7, 0x04, 0x0a, 0x19, 0x55, 0x6e, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, - 0x69, 0x65, 0x64, 0x53, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, - 0x12, 0x28, 0x0a, 0x0f, 0x65, 0x70, 0x68, 0x65, 0x6d, 0x65, 0x72, 0x61, 0x6c, 0x50, 0x75, 0x62, - 0x6c, 0x69, 0x63, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0f, 0x65, 0x70, 0x68, 0x65, 0x6d, - 0x65, 0x72, 0x61, 0x6c, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x12, 0x28, 0x0a, 0x0f, 0x65, 0x6e, - 0x63, 0x72, 0x79, 0x70, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x69, 0x63, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x0c, 0x52, 0x0f, 0x65, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x65, 0x64, 0x53, 0x74, - 0x61, 0x74, 0x69, 0x63, 0x12, 0x2a, 0x0a, 0x10, 0x65, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x65, - 0x64, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x10, - 0x65, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x65, 0x64, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, - 0x1a, 0xc9, 0x03, 0x0a, 0x07, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x49, 0x0a, 0x04, - 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x35, 0x2e, 0x73, 0x69, 0x67, - 0x6e, 0x61, 0x6c, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x55, 0x6e, 0x69, 0x64, 0x65, - 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x64, 0x53, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x4d, 0x65, 0x73, - 0x73, 0x61, 0x67, 0x65, 0x2e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x54, 0x79, 0x70, - 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x4e, 0x0a, 0x11, 0x73, 0x65, 0x6e, 0x64, 0x65, - 0x72, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x6c, 0x73, 0x65, 0x72, 0x76, 0x69, - 0x63, 0x65, 0x2e, 0x53, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, - 0x63, 0x61, 0x74, 0x65, 0x52, 0x11, 0x73, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x43, 0x65, 0x72, 0x74, - 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, - 0x6e, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, - 0x74, 0x12, 0x5e, 0x0a, 0x0b, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x48, 0x69, 0x6e, 0x74, - 0x18, 0x04, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x3c, 0x2e, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x6c, 0x73, - 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x55, 0x6e, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, - 0x69, 0x65, 0x64, 0x53, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, - 0x2e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, - 0x48, 0x69, 0x6e, 0x74, 0x52, 0x0b, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x48, 0x69, 0x6e, - 0x74, 0x12, 0x18, 0x0a, 0x07, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x49, 0x64, 0x18, 0x05, 0x20, 0x01, - 0x28, 0x0c, 0x52, 0x07, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x49, 0x64, 0x22, 0x55, 0x0a, 0x04, 0x54, - 0x79, 0x70, 0x65, 0x12, 0x12, 0x0a, 0x0e, 0x50, 0x52, 0x45, 0x4b, 0x45, 0x59, 0x5f, 0x4d, 0x45, - 0x53, 0x53, 0x41, 0x47, 0x45, 0x10, 0x01, 0x12, 0x0b, 0x0a, 0x07, 0x4d, 0x45, 0x53, 0x53, 0x41, - 0x47, 0x45, 0x10, 0x02, 0x12, 0x15, 0x0a, 0x11, 0x53, 0x45, 0x4e, 0x44, 0x45, 0x52, 0x4b, 0x45, - 0x59, 0x5f, 0x4d, 0x45, 0x53, 0x53, 0x41, 0x47, 0x45, 0x10, 0x07, 0x12, 0x15, 0x0a, 0x11, 0x50, - 0x4c, 0x41, 0x49, 0x4e, 0x54, 0x45, 0x58, 0x54, 0x5f, 0x43, 0x4f, 0x4e, 0x54, 0x45, 0x4e, 0x54, - 0x10, 0x08, 0x22, 0x38, 0x0a, 0x0b, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x48, 0x69, 0x6e, - 0x74, 0x12, 0x0b, 0x0a, 0x07, 0x44, 0x45, 0x46, 0x41, 0x55, 0x4c, 0x54, 0x10, 0x00, 0x12, 0x0e, - 0x0a, 0x0a, 0x52, 0x45, 0x53, 0x45, 0x4e, 0x44, 0x41, 0x42, 0x4c, 0x45, 0x10, 0x01, 0x12, 0x0c, - 0x0a, 0x08, 0x49, 0x4d, 0x50, 0x4c, 0x49, 0x43, 0x49, 0x54, 0x10, 0x02, 0x42, 0x36, 0x0a, 0x25, - 0x6f, 0x72, 0x67, 0x2e, 0x77, 0x68, 0x69, 0x73, 0x70, 0x65, 0x72, 0x73, 0x79, 0x73, 0x74, 0x65, - 0x6d, 0x73, 0x2e, 0x6c, 0x69, 0x62, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x6c, 0x2e, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x42, 0x0d, 0x57, 0x68, 0x69, 0x73, 0x70, 0x65, 0x72, 0x50, 0x72, - 0x6f, 0x74, 0x6f, 0x73, -} +//go:embed UnidentifiedDelivery.pb.raw +var file_UnidentifiedDelivery_proto_rawDesc []byte var ( file_UnidentifiedDelivery_proto_rawDescOnce sync.Once @@ -634,7 +562,7 @@ func file_UnidentifiedDelivery_proto_rawDescGZIP() []byte { var file_UnidentifiedDelivery_proto_enumTypes = make([]protoimpl.EnumInfo, 2) var file_UnidentifiedDelivery_proto_msgTypes = make([]protoimpl.MessageInfo, 6) -var file_UnidentifiedDelivery_proto_goTypes = []interface{}{ +var file_UnidentifiedDelivery_proto_goTypes = []any{ (UnidentifiedSenderMessage_Message_Type)(0), // 0: signalservice.UnidentifiedSenderMessage.Message.Type (UnidentifiedSenderMessage_Message_ContentHint)(0), // 1: signalservice.UnidentifiedSenderMessage.Message.ContentHint (*ServerCertificate)(nil), // 2: signalservice.ServerCertificate @@ -662,7 +590,7 @@ func file_UnidentifiedDelivery_proto_init() { return } if !protoimpl.UnsafeEnabled { - file_UnidentifiedDelivery_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + file_UnidentifiedDelivery_proto_msgTypes[0].Exporter = func(v any, i int) any { switch v := v.(*ServerCertificate); i { case 0: return &v.state @@ -674,7 +602,7 @@ func file_UnidentifiedDelivery_proto_init() { return nil } } - file_UnidentifiedDelivery_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + file_UnidentifiedDelivery_proto_msgTypes[1].Exporter = func(v any, i int) any { switch v := v.(*SenderCertificate); i { case 0: return &v.state @@ -686,7 +614,7 @@ func file_UnidentifiedDelivery_proto_init() { return nil } } - file_UnidentifiedDelivery_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + file_UnidentifiedDelivery_proto_msgTypes[2].Exporter = func(v any, i int) any { switch v := v.(*UnidentifiedSenderMessage); i { case 0: return &v.state @@ -698,7 +626,7 @@ func file_UnidentifiedDelivery_proto_init() { return nil } } - file_UnidentifiedDelivery_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { + file_UnidentifiedDelivery_proto_msgTypes[3].Exporter = func(v any, i int) any { switch v := v.(*ServerCertificate_Certificate); i { case 0: return &v.state @@ -710,7 +638,7 @@ func file_UnidentifiedDelivery_proto_init() { return nil } } - file_UnidentifiedDelivery_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { + file_UnidentifiedDelivery_proto_msgTypes[4].Exporter = func(v any, i int) any { switch v := v.(*SenderCertificate_Certificate); i { case 0: return &v.state @@ -722,7 +650,7 @@ func file_UnidentifiedDelivery_proto_init() { return nil } } - file_UnidentifiedDelivery_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { + file_UnidentifiedDelivery_proto_msgTypes[5].Exporter = func(v any, i int) any { switch v := v.(*UnidentifiedSenderMessage_Message); i { case 0: return &v.state diff --git a/pkg/signalmeow/protobuf/UnidentifiedDelivery.pb.raw b/pkg/signalmeow/protobuf/UnidentifiedDelivery.pb.raw new file mode 100644 index 0000000000000000000000000000000000000000..7d8db350b01354f7b5508c6ea3789823fdc2239c GIT binary patch literal 1172 zcmb_c%Wl&^6eSOm_U2J{B%}}_R9Ql*ShymBstY!G7_gdzXyORiP^I=I9pT#6*eQ6= zZ}9Wxv6DCnERa}v?zyjX@0l^QXFhY$kJ%T7?f^Y@hdePt9>f7@L~P;Dy$Jao zb5Q?Lfa9q+Bkv=Z3C=u5asoAHW3~z>h0{9CL*xk@szULSW2>nA8=!p#wS2iI6q&24 zG^jWc4N6}z$8{6pj#MeK^4D;jAPU)i2@b6GUZZJRpR7QOkYlynuEv%ROC{Tw;l>-t#e{* ziDm2wMYDMQz6_7^qNlqYVHC|5NKWAh!yCLsKKCZeYmYgZq`R<+^c|jrF}l-u9*f9S z+#}qE$#c-wP}WBcT&H_@`&S97D=rq4<0M2ypxJq~GvQxnFtU8Z7RgkVAY(XA<;dMN zMfXpe+qqkGKUGTS1b!?YPBzKPB%j55NImbE@Ji{Lo!9@&y}zj;Uem^qofkYBp#4C9+)&AQFRnxzW6L`JGhcsj&e>>4{Z((U# literal 0 HcmV?d00001 diff --git a/pkg/signalmeow/protobuf/WebSocketResources.pb.go b/pkg/signalmeow/protobuf/WebSocketResources.pb.go index df73711..cf124d4 100644 --- a/pkg/signalmeow/protobuf/WebSocketResources.pb.go +++ b/pkg/signalmeow/protobuf/WebSocketResources.pb.go @@ -5,7 +5,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.34.1 +// protoc-gen-go v1.34.2 // protoc v3.21.12 // source: WebSocketResources.proto @@ -18,6 +18,8 @@ import ( sync "sync" ) +import _ "embed" + const ( // Verify that this generated code is sufficiently up-to-date. _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) @@ -307,49 +309,8 @@ func (x *WebSocketMessage) GetResponse() *WebSocketResponseMessage { var File_WebSocketResources_proto protoreflect.FileDescriptor -var file_WebSocketResources_proto_rawDesc = []byte{ - 0x0a, 0x18, 0x57, 0x65, 0x62, 0x53, 0x6f, 0x63, 0x6b, 0x65, 0x74, 0x52, 0x65, 0x73, 0x6f, 0x75, - 0x72, 0x63, 0x65, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0d, 0x73, 0x69, 0x67, 0x6e, - 0x61, 0x6c, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x22, 0x7f, 0x0a, 0x17, 0x57, 0x65, 0x62, - 0x53, 0x6f, 0x63, 0x6b, 0x65, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x4d, 0x65, 0x73, - 0x73, 0x61, 0x67, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x76, 0x65, 0x72, 0x62, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x04, 0x76, 0x65, 0x72, 0x62, 0x12, 0x12, 0x0a, 0x04, 0x70, 0x61, 0x74, 0x68, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x70, 0x61, 0x74, 0x68, 0x12, 0x12, 0x0a, 0x04, - 0x62, 0x6f, 0x64, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x62, 0x6f, 0x64, 0x79, - 0x12, 0x18, 0x0a, 0x07, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, - 0x09, 0x52, 0x07, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, - 0x18, 0x04, 0x20, 0x01, 0x28, 0x04, 0x52, 0x02, 0x69, 0x64, 0x22, 0x8a, 0x01, 0x0a, 0x18, 0x57, - 0x65, 0x62, 0x53, 0x6f, 0x63, 0x6b, 0x65, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x04, 0x52, 0x02, 0x69, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, - 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, - 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x68, 0x65, 0x61, - 0x64, 0x65, 0x72, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x09, 0x52, 0x07, 0x68, 0x65, 0x61, 0x64, - 0x65, 0x72, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x62, 0x6f, 0x64, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, - 0x0c, 0x52, 0x04, 0x62, 0x6f, 0x64, 0x79, 0x22, 0x83, 0x02, 0x0a, 0x10, 0x57, 0x65, 0x62, 0x53, - 0x6f, 0x63, 0x6b, 0x65, 0x74, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x38, 0x0a, 0x04, - 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x24, 0x2e, 0x73, 0x69, 0x67, - 0x6e, 0x61, 0x6c, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x57, 0x65, 0x62, 0x53, 0x6f, - 0x63, 0x6b, 0x65, 0x74, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x54, 0x79, 0x70, 0x65, - 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x40, 0x0a, 0x07, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x26, 0x2e, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x6c, - 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x57, 0x65, 0x62, 0x53, 0x6f, 0x63, 0x6b, 0x65, - 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, - 0x07, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x43, 0x0a, 0x08, 0x72, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x73, 0x69, 0x67, - 0x6e, 0x61, 0x6c, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x57, 0x65, 0x62, 0x53, 0x6f, - 0x63, 0x6b, 0x65, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x4d, 0x65, 0x73, 0x73, - 0x61, 0x67, 0x65, 0x52, 0x08, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x2e, 0x0a, - 0x04, 0x54, 0x79, 0x70, 0x65, 0x12, 0x0b, 0x0a, 0x07, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, - 0x10, 0x00, 0x12, 0x0b, 0x0a, 0x07, 0x52, 0x45, 0x51, 0x55, 0x45, 0x53, 0x54, 0x10, 0x01, 0x12, - 0x0c, 0x0a, 0x08, 0x52, 0x45, 0x53, 0x50, 0x4f, 0x4e, 0x53, 0x45, 0x10, 0x02, 0x42, 0x46, 0x0a, - 0x33, 0x6f, 0x72, 0x67, 0x2e, 0x77, 0x68, 0x69, 0x73, 0x70, 0x65, 0x72, 0x73, 0x79, 0x73, 0x74, - 0x65, 0x6d, 0x73, 0x2e, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x6c, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, - 0x65, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x77, 0x65, 0x62, 0x73, 0x6f, - 0x63, 0x6b, 0x65, 0x74, 0x42, 0x0f, 0x57, 0x65, 0x62, 0x53, 0x6f, 0x63, 0x6b, 0x65, 0x74, 0x50, - 0x72, 0x6f, 0x74, 0x6f, 0x73, -} +//go:embed WebSocketResources.pb.raw +var file_WebSocketResources_proto_rawDesc []byte var ( file_WebSocketResources_proto_rawDescOnce sync.Once @@ -365,7 +326,7 @@ func file_WebSocketResources_proto_rawDescGZIP() []byte { var file_WebSocketResources_proto_enumTypes = make([]protoimpl.EnumInfo, 1) var file_WebSocketResources_proto_msgTypes = make([]protoimpl.MessageInfo, 3) -var file_WebSocketResources_proto_goTypes = []interface{}{ +var file_WebSocketResources_proto_goTypes = []any{ (WebSocketMessage_Type)(0), // 0: signalservice.WebSocketMessage.Type (*WebSocketRequestMessage)(nil), // 1: signalservice.WebSocketRequestMessage (*WebSocketResponseMessage)(nil), // 2: signalservice.WebSocketResponseMessage @@ -388,7 +349,7 @@ func file_WebSocketResources_proto_init() { return } if !protoimpl.UnsafeEnabled { - file_WebSocketResources_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + file_WebSocketResources_proto_msgTypes[0].Exporter = func(v any, i int) any { switch v := v.(*WebSocketRequestMessage); i { case 0: return &v.state @@ -400,7 +361,7 @@ func file_WebSocketResources_proto_init() { return nil } } - file_WebSocketResources_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + file_WebSocketResources_proto_msgTypes[1].Exporter = func(v any, i int) any { switch v := v.(*WebSocketResponseMessage); i { case 0: return &v.state @@ -412,7 +373,7 @@ func file_WebSocketResources_proto_init() { return nil } } - file_WebSocketResources_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + file_WebSocketResources_proto_msgTypes[2].Exporter = func(v any, i int) any { switch v := v.(*WebSocketMessage); i { case 0: return &v.state diff --git a/pkg/signalmeow/protobuf/WebSocketResources.pb.raw b/pkg/signalmeow/protobuf/WebSocketResources.pb.raw new file mode 100644 index 0000000000000000000000000000000000000000..a521defa0604210f4e9dc97d2d2b08983e362deb GIT binary patch literal 645 zcmaKq%}>HW5XEh&g3E`^9<)c&81>WxUOXC1y%-B_A)H&7K%>yQvp{*VJ`ngOnS%R8uKq|r*MQ;`5TiLz zN~{g=*fF}s-8s{>nq`q#IA$?ZwVK80EO%;h)?&J*4yi97ngK`Wv|E$*s-+!bCNsy9 zT8qib{V~WMY?iJNDuhC;0JNB1k~0*MSfd7Lv$9j`mIbw@kn76!ACL-Lp_JI}w@K_> z92LX^u|%GM&Y{!0_Vxnw4&~lRYMFM>M^fjYGu6D!-pw&HD`e$LR@vwiX>dTDiT<)? z@Ami;g|2#IXLLPcDJa?`^>OeL3?_knq8jGEjs0+B8?;3l%nyfyAoOjs|4i;vKKHhZ h1T*;ua}=<|gSE*@0GD^ literal 0 HcmV?d00001 diff --git a/pkg/signalmeow/protobuf/build-protos.sh b/pkg/signalmeow/protobuf/build-protos.sh index 60b622b..7e32899 100755 --- a/pkg/signalmeow/protobuf/build-protos.sh +++ b/pkg/signalmeow/protobuf/build-protos.sh @@ -1,17 +1,11 @@ -#!/usr/bin/env bash - -# This script is used to generate the protobuf files for the project. -# It is assumed that the protoc compiler is installed and available on the path. - -# The script will generate the protobuf files for the following languages: -# - Go - +#!/bin/sh PKG_IMPORT_PATH="go.mau.fi/mautrix-signal/pkg/signalmeow/signalpb" - for file in *.proto do - protoc --go_out=. \ - --go_opt=M${file}=$PKG_IMPORT_PATH \ - --go_opt=paths=source_relative \ - $file + # Requires https://go-review.googlesource.com/c/protobuf/+/369634 + protoc --go_out=. \ + --go_opt=M${file}=$PKG_IMPORT_PATH \ + --go_opt=paths=source_relative \ + --go_opt=embed_raw=true \ + $file done diff --git a/pkg/signalmeow/protobuf/update-protos.sh b/pkg/signalmeow/protobuf/update-protos.sh index e6d0ea3..9735ecf 100755 --- a/pkg/signalmeow/protobuf/update-protos.sh +++ b/pkg/signalmeow/protobuf/update-protos.sh @@ -1,8 +1,8 @@ #!/bin/bash set -euo pipefail -ANDROID_GIT_REVISION=${1:-6c302b708a6980041ff57271f800c0b092e74ef9} -DESKTOP_GIT_REVISION=${1:-b34f2fbb99d68bd462715f8519524100580fb372} +ANDROID_GIT_REVISION=${1:-68c7ce582378b5f752e5971007b2c203e81cecbd} +DESKTOP_GIT_REVISION=${1:-faea93e5cea24893a8976dc6329faa751f59df5c} update_proto() { case "$1" in From abc6c1fa0289d9531dd93a7fa16a8dd267d02991 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Thu, 15 Aug 2024 14:15:06 +0300 Subject: [PATCH 147/580] main: drop support for Go 1.21 --- .github/workflows/go.yml | 8 ++++---- go.mod | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml index 558ac4f..4e0b362 100644 --- a/.github/workflows/go.yml +++ b/.github/workflows/go.yml @@ -8,8 +8,8 @@ jobs: strategy: fail-fast: false matrix: - go-version: ["1.21", "1.22"] - name: Lint ${{ matrix.go-version == '1.22' && '(latest)' || '(old)' }} + go-version: ["1.22", "1.23"] + name: Lint ${{ matrix.go-version == '1.23' && '(latest)' || '(old)' }} steps: - uses: actions/checkout@v4 @@ -37,8 +37,8 @@ jobs: strategy: fail-fast: false matrix: - go-version: ["1.21", "1.22"] - name: Test ${{ matrix.go-version == '1.22' && '(latest)' || '(old)' }} + go-version: ["1.22", "1.23"] + name: Test ${{ matrix.go-version == '1.23' && '(latest)' || '(old)' }} steps: - uses: actions/checkout@v4 diff --git a/go.mod b/go.mod index 96d2b8f..1f52f2e 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module go.mau.fi/mautrix-signal -go 1.21 +go 1.22 require ( github.com/emersion/go-vcard v0.0.0-20230815062825-8fda7d206ec9 From ab36759bddde65c7cf4ddc3217ebb212ac12d428 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Thu, 15 Aug 2024 14:16:54 +0300 Subject: [PATCH 148/580] dependencies: update --- go.mod | 8 ++++---- go.sum | 16 ++++++++-------- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/go.mod b/go.mod index 1f52f2e..7d25ca5 100644 --- a/go.mod +++ b/go.mod @@ -10,13 +10,13 @@ require ( github.com/rs/zerolog v1.33.0 github.com/stretchr/testify v1.9.0 github.com/tidwall/gjson v1.17.3 - go.mau.fi/util v0.6.1-0.20240811184504-b00aa5c5af3a + go.mau.fi/util v0.6.1-0.20240815104112-77362c9b05dd golang.org/x/crypto v0.26.0 golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa golang.org/x/net v0.28.0 google.golang.org/protobuf v1.34.2 - maunium.net/go/mautrix v0.19.1-0.20240811184947-e13771ff615e - nhooyr.io/websocket v1.8.11 + maunium.net/go/mautrix v0.19.1-0.20240815104211-9e031496a01c + nhooyr.io/websocket v1.8.17 ) require ( @@ -28,7 +28,7 @@ require ( github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-isatty v0.0.19 // indirect github.com/mattn/go-sqlite3 v1.14.22 // indirect - github.com/petermattis/goid v0.0.0-20240716203034-badd1c0974d6 // indirect + github.com/petermattis/goid v0.0.0-20240813172612-4fcff4a6cae7 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/rogpeppe/go-internal v1.10.0 // indirect github.com/rs/xid v1.5.0 // indirect diff --git a/go.sum b/go.sum index cc932c2..586fff1 100644 --- a/go.sum +++ b/go.sum @@ -34,8 +34,8 @@ github.com/mattn/go-pointer v0.0.1 h1:n+XhsuGeVO6MEAp7xyEukFINEa+Quek5psIR/ylA6o github.com/mattn/go-pointer v0.0.1/go.mod h1:2zXcozF6qYGgmsG+SeTZz3oAbFLdD3OWqnUbNvJZAlc= github.com/mattn/go-sqlite3 v1.14.22 h1:2gZY6PC6kBnID23Tichd1K+Z0oS6nE/XwU+Vz/5o4kU= github.com/mattn/go-sqlite3 v1.14.22/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y= -github.com/petermattis/goid v0.0.0-20240716203034-badd1c0974d6 h1:DUDJI8T/9NcGbbL+AWk6vIYlmQ8ZBS8LZqVre6zbkPQ= -github.com/petermattis/goid v0.0.0-20240716203034-badd1c0974d6/go.mod h1:pxMtw7cyUw6B2bRH0ZBANSPg+AoSud1I1iyJHI69jH4= +github.com/petermattis/goid v0.0.0-20240813172612-4fcff4a6cae7 h1:Dx7Ovyv/SFnMFw3fD4oEoeorXc6saIiQ23LrGLth0Gw= +github.com/petermattis/goid v0.0.0-20240813172612-4fcff4a6cae7/go.mod h1:pxMtw7cyUw6B2bRH0ZBANSPg+AoSud1I1iyJHI69jH4= github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= @@ -62,8 +62,8 @@ github.com/tidwall/sjson v1.2.5 h1:kLy8mja+1c9jlljvWTlSazM7cKDRfJuR/bOJhcY5NcY= github.com/tidwall/sjson v1.2.5/go.mod h1:Fvgq9kS/6ociJEDnK0Fk1cpYF4FIW6ZF7LAe+6jwd28= github.com/yuin/goldmark v1.7.4 h1:BDXOHExt+A7gwPCJgPIIq7ENvceR7we7rOS9TNoLZeg= github.com/yuin/goldmark v1.7.4/go.mod h1:uzxRWxtg69N339t3louHJ7+O03ezfj6PlliRlaOzY1E= -go.mau.fi/util v0.6.1-0.20240811184504-b00aa5c5af3a h1:A6AeueGxoDjSSf2X8Tz8X9nQ2S65uYWGVwlvTZa7Bjs= -go.mau.fi/util v0.6.1-0.20240811184504-b00aa5c5af3a/go.mod h1:ZRiX8FK4CsqVINI+3YK50nHnc+dKhfTZNf38zI31S/0= +go.mau.fi/util v0.6.1-0.20240815104112-77362c9b05dd h1:rDu4R3axIbNzv/c2Izri81dMcDXOklQil7tUGivvfNs= +go.mau.fi/util v0.6.1-0.20240815104112-77362c9b05dd/go.mod h1:bWYreIoTULL/UiRbZdfddPh7uWDFW5yX4YCv5FB0eE0= go.mau.fi/zeroconfig v0.1.3 h1:As9wYDKmktjmNZW5i1vn8zvJlmGKHeVxHVIBMXsm4kM= go.mau.fi/zeroconfig v0.1.3/go.mod h1:NcSJkf180JT+1IId76PcMuLTNa1CzsFFZ0nBygIQM70= golang.org/x/crypto v0.26.0 h1:RrRspgV4mU+YwB4FYnuBoKsUapNIL5cohGAmSH3azsw= @@ -90,7 +90,7 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= maunium.net/go/mauflag v1.0.0 h1:YiaRc0tEI3toYtJMRIfjP+jklH45uDHtT80nUamyD4M= maunium.net/go/mauflag v1.0.0/go.mod h1:nLivPOpTpHnpzEh8jEdSL9UqO9+/KBJFmNRlwKfkPeA= -maunium.net/go/mautrix v0.19.1-0.20240811184947-e13771ff615e h1:Hd3zTiI/xdCsKcpn4SbEqxNYtpFM2YNEj19zQiMcb1U= -maunium.net/go/mautrix v0.19.1-0.20240811184947-e13771ff615e/go.mod h1:GtFIC8z1F1EmpwYIG2QOhhg7/TwxeTX82OBhegABr9s= -nhooyr.io/websocket v1.8.11 h1:f/qXNc2/3DpoSZkHt1DQu6rj4zGC8JmkkLkWss0MgN0= -nhooyr.io/websocket v1.8.11/go.mod h1:rN9OFWIUwuxg4fR5tELlYC04bXYowCP9GX47ivo2l+c= +maunium.net/go/mautrix v0.19.1-0.20240815104211-9e031496a01c h1:OgbLNfOibiz+nUWvqpo3dfD+4uuRekRLOynQbFq7VYU= +maunium.net/go/mautrix v0.19.1-0.20240815104211-9e031496a01c/go.mod h1:BGpUGMF+TTNyJ7s6hyZzyNYIAedqIooxHn4+YUi11Ts= +nhooyr.io/websocket v1.8.17 h1:KEVeLJkUywCKVsnLIDlD/5gtayKp8VoCkksHCGGfT9Y= +nhooyr.io/websocket v1.8.17/go.mod h1:rN9OFWIUwuxg4fR5tELlYC04bXYowCP9GX47ivo2l+c= From 30dd472ed808eaaaa61f41616a74301cad6a47db Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Thu, 15 Aug 2024 16:56:25 +0300 Subject: [PATCH 149/580] changelog: update --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2804eb4..9b29904 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,6 @@ # v0.7.0 (unreleased) +* Bumped minimum Go version to 1.22. * Updated to libsignal v0.55.0. * Rewrote bridge using bridgev2 architecture. * It is recommended to check the config file after upgrading. If you have From 3a32a7f46e7524220e2a10057b572c271d526a92 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Thu, 15 Aug 2024 16:56:34 +0300 Subject: [PATCH 150/580] signalmeow: move keepalive log to trace level --- pkg/signalmeow/web/signalwebsocket.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/signalmeow/web/signalwebsocket.go b/pkg/signalmeow/web/signalwebsocket.go index 0b97b8a..8b9698b 100644 --- a/pkg/signalmeow/web/signalwebsocket.go +++ b/pkg/signalmeow/web/signalwebsocket.go @@ -300,7 +300,7 @@ func (s *SignalWebsocket) connectLoop( loopCancel(err) return } - log.Debug().Msg("Sent keepalive") + log.Trace().Msg("Sent keepalive") case <-loopCtx.Done(): return } From f43307b546e70342f3839b51499c27dbc8036c6c Mon Sep 17 00:00:00 2001 From: Malte E <97891689+maltee1@users.noreply.github.com> Date: Fri, 16 Aug 2024 10:34:05 +0200 Subject: [PATCH 151/580] groupinfo: handle promote pending/requesting member changes (#529) --- pkg/connector/groupinfo.go | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/pkg/connector/groupinfo.go b/pkg/connector/groupinfo.go index 5c25942..d0ecdd4 100644 --- a/pkg/connector/groupinfo.go +++ b/pkg/connector/groupinfo.go @@ -301,6 +301,27 @@ func (s *SignalClient) groupChangeToChatInfoChange(ctx context.Context, rev uint PrevMembership: event.MembershipBan, }) } + for _, member := range groupChange.PromotePendingMembers { + mc = append(mc, bridgev2.ChatMember{ + EventSender: s.makeEventSender(member.ACI), + Membership: event.MembershipJoin, + PrevMembership: event.MembershipInvite, + }) + } + for _, member := range groupChange.PromotePendingPniAciMembers { + mc = append(mc, bridgev2.ChatMember{ + EventSender: s.makeEventSender(member.ACI), + Membership: event.MembershipJoin, + PrevMembership: event.MembershipInvite, + }) + } + for _, member := range groupChange.PromoteRequestingMembers { + mc = append(mc, bridgev2.ChatMember{ + EventSender: s.makeEventSender(member.ACI), + Membership: event.MembershipJoin, + PrevMembership: event.MembershipKnock, + }) + } if len(mc) > 0 || pls != nil { ic.MemberChanges = &bridgev2.ChatMemberList{Members: mc, PowerLevels: pls} } From ec9fea1f044507999c6b20a8c041d40670940e3c Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Fri, 16 Aug 2024 15:15:08 +0300 Subject: [PATCH 152/580] Bump version to v0.7.0 --- CHANGELOG.md | 2 +- go.mod | 4 ++-- go.sum | 8 ++++---- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9b29904..9c429db 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,4 @@ -# v0.7.0 (unreleased) +# v0.7.0 (2024-08-16) * Bumped minimum Go version to 1.22. * Updated to libsignal v0.55.0. diff --git a/go.mod b/go.mod index 7d25ca5..e6f6a8e 100644 --- a/go.mod +++ b/go.mod @@ -10,12 +10,12 @@ require ( github.com/rs/zerolog v1.33.0 github.com/stretchr/testify v1.9.0 github.com/tidwall/gjson v1.17.3 - go.mau.fi/util v0.6.1-0.20240815104112-77362c9b05dd + go.mau.fi/util v0.7.0 golang.org/x/crypto v0.26.0 golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa golang.org/x/net v0.28.0 google.golang.org/protobuf v1.34.2 - maunium.net/go/mautrix v0.19.1-0.20240815104211-9e031496a01c + maunium.net/go/mautrix v0.20.0 nhooyr.io/websocket v1.8.17 ) diff --git a/go.sum b/go.sum index 586fff1..c9c1c81 100644 --- a/go.sum +++ b/go.sum @@ -62,8 +62,8 @@ github.com/tidwall/sjson v1.2.5 h1:kLy8mja+1c9jlljvWTlSazM7cKDRfJuR/bOJhcY5NcY= github.com/tidwall/sjson v1.2.5/go.mod h1:Fvgq9kS/6ociJEDnK0Fk1cpYF4FIW6ZF7LAe+6jwd28= github.com/yuin/goldmark v1.7.4 h1:BDXOHExt+A7gwPCJgPIIq7ENvceR7we7rOS9TNoLZeg= github.com/yuin/goldmark v1.7.4/go.mod h1:uzxRWxtg69N339t3louHJ7+O03ezfj6PlliRlaOzY1E= -go.mau.fi/util v0.6.1-0.20240815104112-77362c9b05dd h1:rDu4R3axIbNzv/c2Izri81dMcDXOklQil7tUGivvfNs= -go.mau.fi/util v0.6.1-0.20240815104112-77362c9b05dd/go.mod h1:bWYreIoTULL/UiRbZdfddPh7uWDFW5yX4YCv5FB0eE0= +go.mau.fi/util v0.7.0 h1:l31z+ivrSQw+cv/9eFebEqtQW2zhxivGypn+JT0h/ws= +go.mau.fi/util v0.7.0/go.mod h1:bWYreIoTULL/UiRbZdfddPh7uWDFW5yX4YCv5FB0eE0= go.mau.fi/zeroconfig v0.1.3 h1:As9wYDKmktjmNZW5i1vn8zvJlmGKHeVxHVIBMXsm4kM= go.mau.fi/zeroconfig v0.1.3/go.mod h1:NcSJkf180JT+1IId76PcMuLTNa1CzsFFZ0nBygIQM70= golang.org/x/crypto v0.26.0 h1:RrRspgV4mU+YwB4FYnuBoKsUapNIL5cohGAmSH3azsw= @@ -90,7 +90,7 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= maunium.net/go/mauflag v1.0.0 h1:YiaRc0tEI3toYtJMRIfjP+jklH45uDHtT80nUamyD4M= maunium.net/go/mauflag v1.0.0/go.mod h1:nLivPOpTpHnpzEh8jEdSL9UqO9+/KBJFmNRlwKfkPeA= -maunium.net/go/mautrix v0.19.1-0.20240815104211-9e031496a01c h1:OgbLNfOibiz+nUWvqpo3dfD+4uuRekRLOynQbFq7VYU= -maunium.net/go/mautrix v0.19.1-0.20240815104211-9e031496a01c/go.mod h1:BGpUGMF+TTNyJ7s6hyZzyNYIAedqIooxHn4+YUi11Ts= +maunium.net/go/mautrix v0.20.0 h1:bzQnVQR+LvQxV1YlAr7BSWCS8AWa0Ov0lyPhbbChM0o= +maunium.net/go/mautrix v0.20.0/go.mod h1:V725r8w7oddsS7CxnmTAp634A4nwJCFY7J3jiTMUz2c= nhooyr.io/websocket v1.8.17 h1:KEVeLJkUywCKVsnLIDlD/5gtayKp8VoCkksHCGGfT9Y= nhooyr.io/websocket v1.8.17/go.mod h1:rN9OFWIUwuxg4fR5tELlYC04bXYowCP9GX47ivo2l+c= From 49831b6a77877f5ea50eecc4c2b7c4da233fa296 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Fri, 16 Aug 2024 15:18:55 +0300 Subject: [PATCH 153/580] changelog: update --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9c429db..3c14528 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,8 @@ * It is recommended to check the config file after upgrading. If you have prevented the bridge from writing to the config, you should update it manually. + * Thanks to [@maltee1] for reimplementing Matrix -> Signal membership + handling in the rewrite. # v0.6.3 (2024-07-16) From 39b408ddf147bfdc1c3673e1c9241e97d63dba10 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Sat, 17 Aug 2024 14:13:39 +0300 Subject: [PATCH 154/580] signalmeow: don't use embedded pointers in SendMessageResult Fixes #533 --- go.mod | 2 +- go.sum | 4 ++-- pkg/connector/handlematrix.go | 2 +- pkg/signalmeow/sending.go | 18 +++++++++--------- 4 files changed, 13 insertions(+), 13 deletions(-) diff --git a/go.mod b/go.mod index e6f6a8e..3ea65bd 100644 --- a/go.mod +++ b/go.mod @@ -15,7 +15,7 @@ require ( golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa golang.org/x/net v0.28.0 google.golang.org/protobuf v1.34.2 - maunium.net/go/mautrix v0.20.0 + maunium.net/go/mautrix v0.20.1-0.20240817111253-2355d70426f4 nhooyr.io/websocket v1.8.17 ) diff --git a/go.sum b/go.sum index c9c1c81..3cabb48 100644 --- a/go.sum +++ b/go.sum @@ -90,7 +90,7 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= maunium.net/go/mauflag v1.0.0 h1:YiaRc0tEI3toYtJMRIfjP+jklH45uDHtT80nUamyD4M= maunium.net/go/mauflag v1.0.0/go.mod h1:nLivPOpTpHnpzEh8jEdSL9UqO9+/KBJFmNRlwKfkPeA= -maunium.net/go/mautrix v0.20.0 h1:bzQnVQR+LvQxV1YlAr7BSWCS8AWa0Ov0lyPhbbChM0o= -maunium.net/go/mautrix v0.20.0/go.mod h1:V725r8w7oddsS7CxnmTAp634A4nwJCFY7J3jiTMUz2c= +maunium.net/go/mautrix v0.20.1-0.20240817111253-2355d70426f4 h1:S4+mHwQC2CiCTl0cn21zd4V8JiqGYMYlsde2v7jC8bE= +maunium.net/go/mautrix v0.20.1-0.20240817111253-2355d70426f4/go.mod h1:V725r8w7oddsS7CxnmTAp634A4nwJCFY7J3jiTMUz2c= nhooyr.io/websocket v1.8.17 h1:KEVeLJkUywCKVsnLIDlD/5gtayKp8VoCkksHCGGfT9Y= nhooyr.io/websocket v1.8.17/go.mod h1:rN9OFWIUwuxg4fR5tELlYC04bXYowCP9GX47ivo2l+c= diff --git a/pkg/connector/handlematrix.go b/pkg/connector/handlematrix.go index 888d702..87cebe2 100644 --- a/pkg/connector/handlematrix.go +++ b/pkg/connector/handlematrix.go @@ -247,7 +247,7 @@ func (s *SignalClient) HandleMatrixReadReceipt(ctx context.Context, receipt *bri result := s.Client.SendMessage(ctx, libsignalgo.NewACIServiceID(destination), signalmeow.ReadReceptMessageForTimestamps(messages)) cancel() if !result.WasSuccessful { - zerolog.Ctx(ctx).Err(result.FailedSendResult.Error). + zerolog.Ctx(ctx).Err(result.Error). Stringer("destination", destination). Uints64("message_ids", messages). Msg("Failed to send read receipt to Signal") diff --git a/pkg/signalmeow/sending.go b/pkg/signalmeow/sending.go index 053e335..cc156c9 100644 --- a/pkg/signalmeow/sending.go +++ b/pkg/signalmeow/sending.go @@ -296,8 +296,8 @@ type FailedSendResult struct { } type SendMessageResult struct { WasSuccessful bool - *SuccessfulSendResult - *FailedSendResult + SuccessfulSendResult + FailedSendResult } type GroupMessageSendResult struct { SuccessfullySentTo []SuccessfulSendResult @@ -717,21 +717,21 @@ func (cli *Client) SendMessage(ctx context.Context, recipientID libsignalgo.Serv // Treat needs PNI signature as "this is a message request" and don't send receipts/typing if needsPNISignature && (content.TypingMessage != nil || content.ReceiptMessage != nil) { zerolog.Ctx(ctx).Debug().Msg("Not sending typing/receipt message to recipient as needs PNI signature flag is set") - res := &SuccessfulSendResult{Recipient: recipientID} + res := SuccessfulSendResult{Recipient: recipientID} if content.GetReceiptMessage().GetType() == signalpb.ReceiptMessage_READ { // Still send sync messages for read receipts - cli.sendSyncCopy(ctx, content, messageTimestamp, res) + cli.sendSyncCopy(ctx, content, messageTimestamp, &res) } return SendMessageResult{WasSuccessful: true, SuccessfulSendResult: res} } isDeliveryReceipt := content.ReceiptMessage != nil && content.GetReceiptMessage().GetType() == signalpb.ReceiptMessage_DELIVERY if recipientID == cli.Store.ACIServiceID() && !isDeliveryReceipt { - res := &SuccessfulSendResult{ + res := SuccessfulSendResult{ Recipient: recipientID, Unidentified: false, } - ok := cli.sendSyncCopy(ctx, content, messageTimestamp, res) + ok := cli.sendSyncCopy(ctx, content, messageTimestamp, &res) return SendMessageResult{ WasSuccessful: ok, SuccessfulSendResult: res, @@ -743,7 +743,7 @@ func (cli *Client) SendMessage(ctx context.Context, recipientID libsignalgo.Serv if err != nil { return SendMessageResult{ WasSuccessful: false, - FailedSendResult: &FailedSendResult{ + FailedSendResult: FailedSendResult{ Recipient: recipientID, Error: err, }, @@ -751,7 +751,7 @@ func (cli *Client) SendMessage(ctx context.Context, recipientID libsignalgo.Serv } result := SendMessageResult{ WasSuccessful: true, - SuccessfulSendResult: &SuccessfulSendResult{ + SuccessfulSendResult: SuccessfulSendResult{ Recipient: recipientID, Unidentified: sentUnidentified, }, @@ -768,7 +768,7 @@ func (cli *Client) SendMessage(ctx context.Context, recipientID libsignalgo.Serv } } - cli.sendSyncCopy(ctx, content, messageTimestamp, result.SuccessfulSendResult) + cli.sendSyncCopy(ctx, content, messageTimestamp, &result.SuccessfulSendResult) return result } From 31a4522ee66e5b1d52055ea5fd093602bb7d243e Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Sat, 17 Aug 2024 23:26:25 +0300 Subject: [PATCH 155/580] legacyprovision: log out other logins when logging into new one --- cmd/mautrix-signal/legacyprovision.go | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/cmd/mautrix-signal/legacyprovision.go b/cmd/mautrix-signal/legacyprovision.go index 8e8e752..013d1bd 100644 --- a/cmd/mautrix-signal/legacyprovision.go +++ b/cmd/mautrix-signal/legacyprovision.go @@ -17,6 +17,7 @@ package main import ( + "context" "encoding/json" "fmt" "net/http" @@ -27,6 +28,7 @@ import ( "github.com/gorilla/mux" "github.com/rs/zerolog" "maunium.net/go/mautrix" + "maunium.net/go/mautrix/bridge/status" "maunium.net/go/mautrix/bridgev2" "maunium.net/go/mautrix/id" @@ -188,10 +190,20 @@ func legacyProvLinkWaitAccount(w http.ResponseWriter, r *http.Request) { UUID: string(res.CompleteParams.UserLogin.ID), Number: res.CompleteParams.UserLogin.RemoteName, }) + go handleLoginComplete(r.Context(), login.User, res.CompleteParams.UserLogin) } login.Delete() } +func handleLoginComplete(ctx context.Context, user *bridgev2.User, newLogin *bridgev2.UserLogin) { + allLogins := user.GetCachedUserLogins() + for _, login := range allLogins { + if login.ID != newLogin.ID { + login.Delete(ctx, status.BridgeState{StateEvent: status.StateLoggedOut, Reason: "LOGIN_OVERRIDDEN"}, bridgev2.DeleteOpts{}) + } + } +} + func legacyProvLogout(w http.ResponseWriter, r *http.Request) { // No-op for backwards compatibility JSONResponse(w, http.StatusOK, nil) From 7ad59f26948cead67371cf2e58c157da2d80cbc1 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Wed, 21 Aug 2024 13:20:05 +0300 Subject: [PATCH 156/580] userinfo: implement `use_outdated_profiles` config option Fixes #538 --- pkg/connector/chatinfo.go | 12 ++++++++++++ pkg/connector/dbmeta.go | 4 +++- pkg/signalid/dbmeta.go | 8 ++++++++ 3 files changed, 23 insertions(+), 1 deletion(-) diff --git a/pkg/connector/chatinfo.go b/pkg/connector/chatinfo.go index 69af735..7bd392f 100644 --- a/pkg/connector/chatinfo.go +++ b/pkg/connector/chatinfo.go @@ -49,6 +49,10 @@ func (s *SignalClient) GetUserInfo(ctx context.Context, ghost *bridgev2.Ghost) ( if err != nil { return nil, err } + meta := ghost.Metadata.(*signalid.GhostMetadata) + if !s.Main.Config.UseOutdatedProfiles && meta.ProfileFetchedAt.After(contact.Profile.FetchedAt) { + return nil, nil + } return s.contactToUserInfo(contact), nil } @@ -74,6 +78,14 @@ func (s *SignalClient) contactToUserInfo(contact *types.Recipient) *bridgev2.Use ui := &bridgev2.UserInfo{ IsBot: &isBot, Identifiers: []string{}, + ExtraUpdates: func(ctx context.Context, ghost *bridgev2.Ghost) (changed bool) { + meta := ghost.Metadata.(*signalid.GhostMetadata) + if meta.ProfileFetchedAt.Before(contact.Profile.FetchedAt) { + changed = meta.ProfileFetchedAt.IsZero() && !contact.Profile.FetchedAt.IsZero() + meta.ProfileFetchedAt.Time = contact.Profile.FetchedAt + } + return false + }, } if contact.E164 != "" { ui.Identifiers = append(ui.Identifiers, "tel:"+contact.E164) diff --git a/pkg/connector/dbmeta.go b/pkg/connector/dbmeta.go index 14f59f2..4ee3b08 100644 --- a/pkg/connector/dbmeta.go +++ b/pkg/connector/dbmeta.go @@ -27,7 +27,9 @@ func (s *SignalConnector) GetDBMetaTypes() database.MetaTypes { Portal: func() any { return &signalid.PortalMetadata{} }, - Ghost: nil, + Ghost: func() any { + return &signalid.GhostMetadata{} + }, Message: func() any { return &signalid.MessageMetadata{} }, diff --git a/pkg/signalid/dbmeta.go b/pkg/signalid/dbmeta.go index 2b5a164..5a96b07 100644 --- a/pkg/signalid/dbmeta.go +++ b/pkg/signalid/dbmeta.go @@ -16,6 +16,10 @@ package signalid +import ( + "go.mau.fi/util/jsontime" +) + type PortalMetadata struct { Revision uint32 `json:"revision,omitempty"` } @@ -23,3 +27,7 @@ type PortalMetadata struct { type MessageMetadata struct { ContainsAttachments bool `json:"contains_attachments,omitempty"` } + +type GhostMetadata struct { + ProfileFetchedAt jsontime.UnixMilli `json:"profile_fetched_at"` +} From 162cfdba68bf26fbcee1d9614ce2e2173b18964f Mon Sep 17 00:00:00 2001 From: Malte E <97891689+maltee1@users.noreply.github.com> Date: Wed, 21 Aug 2024 20:42:59 +0200 Subject: [PATCH 157/580] handlematrix: add support for power levels (#531) --- pkg/connector/handlematrix.go | 93 +++++++++++++++++++++++++++++------ pkg/signalid/ids.go | 12 +++++ 2 files changed, 91 insertions(+), 14 deletions(-) diff --git a/pkg/connector/handlematrix.go b/pkg/connector/handlematrix.go index 87cebe2..4984b25 100644 --- a/pkg/connector/handlematrix.go +++ b/pkg/connector/handlematrix.go @@ -359,25 +359,24 @@ func (s *SignalClient) HandleMatrixMembership(ctx context.Context, msg *bridgev2 return false, nil } } - if msg.TargetGhost != nil { - targetIntent = msg.TargetGhost.Intent - targetSignalID, err = signalid.ParseUserID(msg.TargetGhost.ID) - if err != nil { - return false, fmt.Errorf("failed to parse target ghost signal id: %w", err) - } - } else if msg.TargetUserLogin != nil { - targetSignalID, err = signalid.ParseUserLoginID(msg.TargetUserLogin.ID) - if err != nil { - return false, fmt.Errorf("failed to parse target user signal id: %w", err) - } - targetIntent = msg.TargetUserLogin.User.DoublePuppet(ctx) + targetSignalID, err = signalid.ParseGhostOrUserLoginID(msg.Target) + if err != nil { + return false, fmt.Errorf("failed to parse target signal id: %w", err) + } + switch target := msg.Target.(type) { + case *bridgev2.Ghost: + targetIntent = target.Intent + case *bridgev2.UserLogin: + targetIntent = target.User.DoublePuppet(ctx) if targetIntent == nil { - ghost, err := s.Main.Bridge.GetGhostByID(ctx, networkid.UserID(msg.TargetUserLogin.ID)) + ghost, err := s.Main.Bridge.GetGhostByID(ctx, networkid.UserID(target.ID)) if err != nil { return false, fmt.Errorf("failed to get ghost for user: %w", err) } targetIntent = ghost.Intent } + default: + return false, fmt.Errorf("cannot get target intent: unknown type: %T", target) } log := zerolog.Ctx(ctx).With(). Str("From Membership", string(msg.Type.From)). @@ -389,7 +388,7 @@ func (s *SignalClient) HandleMatrixMembership(ctx context.Context, msg *bridgev2 levels, err := msg.Portal.Bridge.Matrix.GetPowerLevels(ctx, msg.Portal.MXID) if err != nil { log.Err(err).Msg("Couldn't get power levels") - if levels.GetUserLevel(targetIntent.GetMXID()) >= 50 { + if levels.GetUserLevel(targetIntent.GetMXID()) >= moderatorPL { role = signalmeow.GroupMember_ADMINISTRATOR } } @@ -472,3 +471,69 @@ func (s *SignalClient) HandleMatrixMembership(ctx context.Context, msg *bridgev2 msg.Portal.Metadata.(*signalid.PortalMetadata).Revision = revision return true, nil } + +func plToRole(pl int) signalmeow.GroupMemberRole { + if pl >= moderatorPL { + return signalmeow.GroupMember_ADMINISTRATOR + } else { + return signalmeow.GroupMember_DEFAULT + } +} + +func plToAccessControl(pl int) *signalmeow.AccessControl { + var accessControl signalmeow.AccessControl + if pl >= moderatorPL { + accessControl = signalmeow.AccessControl_ADMINISTRATOR + } else { + accessControl = signalmeow.AccessControl_MEMBER + } + return &accessControl +} + +func hasAdminChanged(plc *bridgev2.SinglePowerLevelChange) bool { + if plc == nil { + return false + } + return (plc.NewLevel < moderatorPL) != (plc.OrigLevel < moderatorPL) +} + +func (s *SignalClient) HandleMatrixPowerLevels(ctx context.Context, msg *bridgev2.MatrixPowerLevelChange) (bool, error) { + if msg.Portal.RoomType == database.RoomTypeDM { + return false, nil + } + log := zerolog.Ctx(ctx) + gc := &signalmeow.GroupChange{} + for _, plc := range msg.Users { + if !hasAdminChanged(&plc.SinglePowerLevelChange) { + continue + } + aci, err := signalid.ParseGhostOrUserLoginID(plc.Target) + if err != nil { + log.Err(err).Msg("Couldn't parse user id") + } + gc.ModifyMemberRoles = append(gc.ModifyMemberRoles, &signalmeow.RoleMember{ + ACI: aci, + Role: plToRole(plc.NewLevel), + }) + } + if hasAdminChanged(msg.EventsDefault) { + announcementsOnly := msg.EventsDefault.NewLevel >= moderatorPL + gc.ModifyAnnouncementsOnly = &announcementsOnly + } + if hasAdminChanged(msg.StateDefault) { + gc.ModifyAttributesAccess = plToAccessControl(msg.StateDefault.NewLevel) + } + if hasAdminChanged(msg.Invite) { + gc.ModifyMemberAccess = plToAccessControl(msg.Invite.NewLevel) + } + _, groupID, err := signalid.ParsePortalID(msg.Portal.ID) + if err != nil || groupID == "" { + return false, err + } + revision, err := s.Client.UpdateGroup(ctx, gc, groupID) + if err != nil { + return false, err + } + msg.Portal.Metadata.(*signalid.PortalMetadata).Revision = revision + return true, nil +} diff --git a/pkg/signalid/ids.go b/pkg/signalid/ids.go index 99ef7b3..ec002ce 100644 --- a/pkg/signalid/ids.go +++ b/pkg/signalid/ids.go @@ -22,6 +22,7 @@ import ( "strings" "github.com/google/uuid" + "maunium.net/go/mautrix/bridgev2" "maunium.net/go/mautrix/bridgev2/networkid" "go.mau.fi/mautrix-signal/pkg/libsignalgo" @@ -47,6 +48,17 @@ func ParseUserLoginID(userLoginID networkid.UserLoginID) (uuid.UUID, error) { return userID, nil } +func ParseGhostOrUserLoginID(ghostOrUserLogin bridgev2.GhostOrUserLogin) (uuid.UUID, error) { + switch ghostOrUserLogin := ghostOrUserLogin.(type) { + case *bridgev2.UserLogin: + return ParseUserLoginID(ghostOrUserLogin.ID) + case *bridgev2.Ghost: + return ParseUserID(ghostOrUserLogin.ID) + default: + return uuid.Nil, fmt.Errorf("cannot parse ID: unknown type: %T", ghostOrUserLogin) + } +} + func ParseUserIDAsServiceID(userID networkid.UserID) (libsignalgo.ServiceID, error) { return libsignalgo.ServiceIDFromString(string(userID)) } From 460379b7d93c43a8664edcac284b039fb6d1a5c0 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Fri, 23 Aug 2024 18:07:58 +0300 Subject: [PATCH 158/580] signalmeow: log all profile fetch errors at debug level --- pkg/signalmeow/contact.go | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/pkg/signalmeow/contact.go b/pkg/signalmeow/contact.go index a8e8285..fdea194 100644 --- a/pkg/signalmeow/contact.go +++ b/pkg/signalmeow/contact.go @@ -22,7 +22,6 @@ import ( "crypto/sha256" "encoding/binary" "encoding/hex" - "errors" "fmt" "net/http" "strings" @@ -82,11 +81,7 @@ func (cli *Client) fetchContactThenTryAndUpdateWithProfile(ctx context.Context, profile, err := cli.RetrieveProfileByID(ctx, aci) if err != nil { - logLevel := zerolog.ErrorLevel - if errors.Is(err, errProfileKeyNotFound) { - logLevel = zerolog.DebugLevel - } - log.WithLevel(logLevel).Err(err).Msg("Failed to fetch profile") + log.Debug().Err(err).Msg("Failed to fetch profile") // Continue to return contact without profile } return cli.Store.RecipientStore.LoadAndUpdateRecipient(ctx, aci, uuid.Nil, func(recipient *types.Recipient) (changed bool, err error) { From e74b5cc243e16d03adc71d77e4732a75957dbc16 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Tue, 27 Aug 2024 22:14:35 +0300 Subject: [PATCH 159/580] dependencies: update mautrix-go --- go.mod | 6 ++++-- go.sum | 12 ++++++++---- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/go.mod b/go.mod index 3ea65bd..5a7fd59 100644 --- a/go.mod +++ b/go.mod @@ -10,16 +10,17 @@ require ( github.com/rs/zerolog v1.33.0 github.com/stretchr/testify v1.9.0 github.com/tidwall/gjson v1.17.3 - go.mau.fi/util v0.7.0 + go.mau.fi/util v0.7.1-0.20240827112829-84c63841c264 golang.org/x/crypto v0.26.0 golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa golang.org/x/net v0.28.0 google.golang.org/protobuf v1.34.2 - maunium.net/go/mautrix v0.20.1-0.20240817111253-2355d70426f4 + maunium.net/go/mautrix v0.20.1-0.20240827191023-f56905a27645 nhooyr.io/websocket v1.8.17 ) require ( + filippo.io/edwards25519 v1.1.0 // indirect github.com/coreos/go-systemd/v22 v22.5.0 // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/gorilla/websocket v1.5.0 // indirect @@ -38,6 +39,7 @@ require ( github.com/tidwall/sjson v1.2.5 // indirect github.com/yuin/goldmark v1.7.4 // indirect go.mau.fi/zeroconfig v0.1.3 // indirect + golang.org/x/sync v0.8.0 // indirect golang.org/x/sys v0.24.0 // indirect golang.org/x/text v0.17.0 // indirect gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect diff --git a/go.sum b/go.sum index 3cabb48..026d636 100644 --- a/go.sum +++ b/go.sum @@ -1,3 +1,5 @@ +filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA= +filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4= github.com/DATA-DOG/go-sqlmock v1.5.2 h1:OcvFkGmslmlZibjAjaHm3L//6LiuBgolP7OputlJIzU= github.com/DATA-DOG/go-sqlmock v1.5.2/go.mod h1:88MAG/4G7SMwSE3CeA0ZKzrT5CiOU3OJ+JlNzwDqpNU= github.com/coreos/go-systemd/v22 v22.5.0 h1:RrqgGjYQKalulkV8NGVIfkXQf6YYmOyiJKk8iXXhfZs= @@ -62,8 +64,8 @@ github.com/tidwall/sjson v1.2.5 h1:kLy8mja+1c9jlljvWTlSazM7cKDRfJuR/bOJhcY5NcY= github.com/tidwall/sjson v1.2.5/go.mod h1:Fvgq9kS/6ociJEDnK0Fk1cpYF4FIW6ZF7LAe+6jwd28= github.com/yuin/goldmark v1.7.4 h1:BDXOHExt+A7gwPCJgPIIq7ENvceR7we7rOS9TNoLZeg= github.com/yuin/goldmark v1.7.4/go.mod h1:uzxRWxtg69N339t3louHJ7+O03ezfj6PlliRlaOzY1E= -go.mau.fi/util v0.7.0 h1:l31z+ivrSQw+cv/9eFebEqtQW2zhxivGypn+JT0h/ws= -go.mau.fi/util v0.7.0/go.mod h1:bWYreIoTULL/UiRbZdfddPh7uWDFW5yX4YCv5FB0eE0= +go.mau.fi/util v0.7.1-0.20240827112829-84c63841c264 h1:mWujT3q8pxyJc/3BvWTgTN4+k41d1pBCvwxH56prqQA= +go.mau.fi/util v0.7.1-0.20240827112829-84c63841c264/go.mod h1:WuAOOV0O/otkxGkFUvfv/XE2ztegaoyM15ovS6SYbf4= go.mau.fi/zeroconfig v0.1.3 h1:As9wYDKmktjmNZW5i1vn8zvJlmGKHeVxHVIBMXsm4kM= go.mau.fi/zeroconfig v0.1.3/go.mod h1:NcSJkf180JT+1IId76PcMuLTNa1CzsFFZ0nBygIQM70= golang.org/x/crypto v0.26.0 h1:RrRspgV4mU+YwB4FYnuBoKsUapNIL5cohGAmSH3azsw= @@ -72,6 +74,8 @@ golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa h1:ELnwvuAXPNtPk1TJRuGkI9fDT golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa/go.mod h1:akd2r19cwCdwSwWeIdzYQGa/EZZyqcOdwWiwj5L5eKQ= golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE= golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg= +golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= +golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -90,7 +94,7 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= maunium.net/go/mauflag v1.0.0 h1:YiaRc0tEI3toYtJMRIfjP+jklH45uDHtT80nUamyD4M= maunium.net/go/mauflag v1.0.0/go.mod h1:nLivPOpTpHnpzEh8jEdSL9UqO9+/KBJFmNRlwKfkPeA= -maunium.net/go/mautrix v0.20.1-0.20240817111253-2355d70426f4 h1:S4+mHwQC2CiCTl0cn21zd4V8JiqGYMYlsde2v7jC8bE= -maunium.net/go/mautrix v0.20.1-0.20240817111253-2355d70426f4/go.mod h1:V725r8w7oddsS7CxnmTAp634A4nwJCFY7J3jiTMUz2c= +maunium.net/go/mautrix v0.20.1-0.20240827191023-f56905a27645 h1:44YDJap8wHIHJV3dt4ZIojQnnlIEd60Beh8fFP7Xsz4= +maunium.net/go/mautrix v0.20.1-0.20240827191023-f56905a27645/go.mod h1:7hh/Hx5W9lUcqL0hkSw52kMyY+6nMUPTtdDN0qVEXwI= nhooyr.io/websocket v1.8.17 h1:KEVeLJkUywCKVsnLIDlD/5gtayKp8VoCkksHCGGfT9Y= nhooyr.io/websocket v1.8.17/go.mod h1:rN9OFWIUwuxg4fR5tELlYC04bXYowCP9GX47ivo2l+c= From 4d46dd703f7385b1eabf1fb950f11c18800028a7 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Mon, 2 Sep 2024 12:24:56 +0300 Subject: [PATCH 160/580] dependencies: update libsignal and others --- go.mod | 8 +- go.sum | 15 +-- pkg/libsignalgo/libsignal | 2 +- pkg/libsignalgo/libsignal-ffi.h | 163 +------------------------------- pkg/libsignalgo/version.go | 2 +- 5 files changed, 16 insertions(+), 174 deletions(-) diff --git a/go.mod b/go.mod index 5a7fd59..e4c6005 100644 --- a/go.mod +++ b/go.mod @@ -10,12 +10,12 @@ require ( github.com/rs/zerolog v1.33.0 github.com/stretchr/testify v1.9.0 github.com/tidwall/gjson v1.17.3 - go.mau.fi/util v0.7.1-0.20240827112829-84c63841c264 + go.mau.fi/util v0.7.1-0.20240901193650-bf007b10eaf6 golang.org/x/crypto v0.26.0 - golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa + golang.org/x/exp v0.0.0-20240823005443-9b4947da3948 golang.org/x/net v0.28.0 google.golang.org/protobuf v1.34.2 - maunium.net/go/mautrix v0.20.1-0.20240827191023-f56905a27645 + maunium.net/go/mautrix v0.20.1-0.20240902092346-6f1a3878c452 nhooyr.io/websocket v1.8.17 ) @@ -32,7 +32,7 @@ require ( github.com/petermattis/goid v0.0.0-20240813172612-4fcff4a6cae7 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/rogpeppe/go-internal v1.10.0 // indirect - github.com/rs/xid v1.5.0 // indirect + github.com/rs/xid v1.6.0 // indirect github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e // indirect github.com/tidwall/match v1.1.1 // indirect github.com/tidwall/pretty v1.2.0 // indirect diff --git a/go.sum b/go.sum index 026d636..2d7ba8f 100644 --- a/go.sum +++ b/go.sum @@ -45,8 +45,9 @@ github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZN github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog= -github.com/rs/xid v1.5.0 h1:mKX4bl4iPYJtEIxp6CYiUuLQ/8DYMoz0PUdtGgMFRVc= github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= +github.com/rs/xid v1.6.0 h1:fV591PaemRlL6JfRxGDEPl69wICngIQ3shQtzfy2gxU= +github.com/rs/xid v1.6.0/go.mod h1:7XoLgs4eV+QndskICGsho+ADou8ySMSjJKDIan90Nz0= github.com/rs/zerolog v1.33.0 h1:1cU2KZkvPxNyfgEmhHAz/1A9Bz+llsdYzklWFzgp0r8= github.com/rs/zerolog v1.33.0/go.mod h1:/7mN4D5sKwJLZQ2b/znpjC3/GQWY/xaDXUM0kKWRHss= github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e h1:MRM5ITcdelLK2j1vwZ3Je0FKVCfqOLp5zO6trqMLYs0= @@ -64,14 +65,14 @@ github.com/tidwall/sjson v1.2.5 h1:kLy8mja+1c9jlljvWTlSazM7cKDRfJuR/bOJhcY5NcY= github.com/tidwall/sjson v1.2.5/go.mod h1:Fvgq9kS/6ociJEDnK0Fk1cpYF4FIW6ZF7LAe+6jwd28= github.com/yuin/goldmark v1.7.4 h1:BDXOHExt+A7gwPCJgPIIq7ENvceR7we7rOS9TNoLZeg= github.com/yuin/goldmark v1.7.4/go.mod h1:uzxRWxtg69N339t3louHJ7+O03ezfj6PlliRlaOzY1E= -go.mau.fi/util v0.7.1-0.20240827112829-84c63841c264 h1:mWujT3q8pxyJc/3BvWTgTN4+k41d1pBCvwxH56prqQA= -go.mau.fi/util v0.7.1-0.20240827112829-84c63841c264/go.mod h1:WuAOOV0O/otkxGkFUvfv/XE2ztegaoyM15ovS6SYbf4= +go.mau.fi/util v0.7.1-0.20240901193650-bf007b10eaf6 h1:cSLCabMKbR6rTPYRGWD2XaHo210BK3BtPg+CRC4A4og= +go.mau.fi/util v0.7.1-0.20240901193650-bf007b10eaf6/go.mod h1:WuAOOV0O/otkxGkFUvfv/XE2ztegaoyM15ovS6SYbf4= go.mau.fi/zeroconfig v0.1.3 h1:As9wYDKmktjmNZW5i1vn8zvJlmGKHeVxHVIBMXsm4kM= go.mau.fi/zeroconfig v0.1.3/go.mod h1:NcSJkf180JT+1IId76PcMuLTNa1CzsFFZ0nBygIQM70= golang.org/x/crypto v0.26.0 h1:RrRspgV4mU+YwB4FYnuBoKsUapNIL5cohGAmSH3azsw= golang.org/x/crypto v0.26.0/go.mod h1:GY7jblb9wI+FOo5y8/S2oY4zWP07AkOJ4+jxCqdqn54= -golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa h1:ELnwvuAXPNtPk1TJRuGkI9fDTwym6AYBu0qzT8AcHdI= -golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa/go.mod h1:akd2r19cwCdwSwWeIdzYQGa/EZZyqcOdwWiwj5L5eKQ= +golang.org/x/exp v0.0.0-20240823005443-9b4947da3948 h1:kx6Ds3MlpiUHKj7syVnbp57++8WpuKPcR5yjLBjvLEA= +golang.org/x/exp v0.0.0-20240823005443-9b4947da3948/go.mod h1:akd2r19cwCdwSwWeIdzYQGa/EZZyqcOdwWiwj5L5eKQ= golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE= golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg= golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= @@ -94,7 +95,7 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= maunium.net/go/mauflag v1.0.0 h1:YiaRc0tEI3toYtJMRIfjP+jklH45uDHtT80nUamyD4M= maunium.net/go/mauflag v1.0.0/go.mod h1:nLivPOpTpHnpzEh8jEdSL9UqO9+/KBJFmNRlwKfkPeA= -maunium.net/go/mautrix v0.20.1-0.20240827191023-f56905a27645 h1:44YDJap8wHIHJV3dt4ZIojQnnlIEd60Beh8fFP7Xsz4= -maunium.net/go/mautrix v0.20.1-0.20240827191023-f56905a27645/go.mod h1:7hh/Hx5W9lUcqL0hkSw52kMyY+6nMUPTtdDN0qVEXwI= +maunium.net/go/mautrix v0.20.1-0.20240902092346-6f1a3878c452 h1:Yq7qZMP3y/BJ7/5aaDVPkRs9vZjtfwhcbDJuLWR8cVs= +maunium.net/go/mautrix v0.20.1-0.20240902092346-6f1a3878c452/go.mod h1:IXDDoX+dqBkNnrjDMouE3FUExiR+hhmaEFsvXG3HzfQ= nhooyr.io/websocket v1.8.17 h1:KEVeLJkUywCKVsnLIDlD/5gtayKp8VoCkksHCGGfT9Y= nhooyr.io/websocket v1.8.17/go.mod h1:rN9OFWIUwuxg4fR5tELlYC04bXYowCP9GX47ivo2l+c= diff --git a/pkg/libsignalgo/libsignal b/pkg/libsignalgo/libsignal index a8bc95b..e46841e 160000 --- a/pkg/libsignalgo/libsignal +++ b/pkg/libsignalgo/libsignal @@ -1 +1 @@ -Subproject commit a8bc95bc7ebad76ee0bd467ece3321b886cbaef7 +Subproject commit e46841ea2c1ad03bc5113eba267ac1543689d031 diff --git a/pkg/libsignalgo/libsignal-ffi.h b/pkg/libsignalgo/libsignal-ffi.h index 8c443ac..c089648 100644 --- a/pkg/libsignalgo/libsignal-ffi.h +++ b/pkg/libsignalgo/libsignal-ffi.h @@ -20,8 +20,6 @@ SPDX-License-Identifier: AGPL-3.0-only */ #define SignalFourCC_ENCODED_LEN 4 -#define SignalBoxHeader_MAX_SIZE 32 - #define SignalNUM_AUTH_CRED_ATTRIBUTES 3 #define SignalNUM_PROFILE_KEY_CRED_ATTRIBUTES 4 @@ -240,10 +238,6 @@ typedef struct SignalMessageBackupKey SignalMessageBackupKey; typedef struct SignalMessageBackupValidationOutcome SignalMessageBackupValidationOutcome; -typedef struct SignalNonSuspendingBackgroundThreadRuntime SignalNonSuspendingBackgroundThreadRuntime; - -typedef struct SignalOtherTestingHandleType SignalOtherTestingHandleType; - typedef struct SignalPinHash SignalPinHash; typedef struct SignalPlaintextContent SignalPlaintextContent; @@ -263,10 +257,9 @@ typedef struct SignalProtocolAddress SignalProtocolAddress; typedef struct SignalPublicKey SignalPublicKey; -/** - * Sanitized metadata returned by the sanitizer. - */ +#if defined(SIGNAL_MEDIA_SUPPORTED) typedef struct SignalSanitizedMetadata SignalSanitizedMetadata; +#endif typedef struct SignalSenderCertificate SignalSenderCertificate; @@ -305,8 +298,6 @@ typedef struct SignalMessage SignalMessage; typedef struct SignalSignedPreKeyRecord SignalSignedPreKeyRecord; -typedef struct SignalTestingHandleType SignalTestingHandleType; - typedef struct SignalTokioAsyncContext SignalTokioAsyncContext; typedef struct SignalUnidentifiedSenderMessageContent SignalUnidentifiedSenderMessageContent; @@ -674,66 +665,6 @@ typedef struct { typedef SignalInputStream SignalSyncInputStream; -/** - * A C callback used to report the results of Rust futures. - * - * cbindgen will produce independent C types like `SignalCPromisei32` and - * `SignalCPromiseProtocolAddress`. - * - * This derives Copy because it behaves like a C type; nevertheless, a promise should still only be - * completed once. - */ -typedef struct { - void (*complete)(SignalFfiError *error, const int32_t *result, const void *context); - const void *context; - SignalCancellationId cancellation_id; -} SignalCPromisei32; - -/** - * A C callback used to report the results of Rust futures. - * - * cbindgen will produce independent C types like `SignalCPromisei32` and - * `SignalCPromiseProtocolAddress`. - * - * This derives Copy because it behaves like a C type; nevertheless, a promise should still only be - * completed once. - */ -typedef struct { - void (*complete)(SignalFfiError *error, SignalTestingHandleType *const *result, const void *context); - const void *context; - SignalCancellationId cancellation_id; -} SignalCPromiseTestingHandleType; - -/** - * A C callback used to report the results of Rust futures. - * - * cbindgen will produce independent C types like `SignalCPromisei32` and - * `SignalCPromiseProtocolAddress`. - * - * This derives Copy because it behaves like a C type; nevertheless, a promise should still only be - * completed once. - */ -typedef struct { - void (*complete)(SignalFfiError *error, SignalOtherTestingHandleType *const *result, const void *context); - const void *context; - SignalCancellationId cancellation_id; -} SignalCPromiseOtherTestingHandleType; - -/** - * A C callback used to report the results of Rust futures. - * - * cbindgen will produce independent C types like `SignalCPromisei32` and - * `SignalCPromiseProtocolAddress`. - * - * This derives Copy because it behaves like a C type; nevertheless, a promise should still only be - * completed once. - */ -typedef struct { - void (*complete)(SignalFfiError *error, const void *const *result, const void *context); - const void *context; - SignalCancellationId cancellation_id; -} SignalCPromiseRawPointer; - typedef uint8_t SignalRandomnessBytes[SignalRANDOMNESS_LEN]; void signal_print_ptr(const void *p); @@ -1586,10 +1517,6 @@ SignalFfiError *signal_chat_service_set_listener_auth(const SignalTokioAsyncCont SignalFfiError *signal_chat_service_set_listener_unauth(const SignalTokioAsyncContext *runtime, const SignalChat *chat, const SignalFfiMakeChatListenerStruct *make_listener); -SignalFfiError *signal_testing_chat_service_inject_raw_server_request(const SignalChat *chat, SignalBorrowedBuffer bytes); - -SignalFfiError *signal_testing_chat_service_inject_connection_interrupted(const SignalChat *chat); - SignalFfiError *signal_server_message_ack_destroy(SignalServerMessageAck *p); SignalFfiError *signal_server_message_ack_send(SignalCPromisebool *promise, const SignalTokioAsyncContext *async_runtime, const SignalServerMessageAck *ack); @@ -1694,90 +1621,4 @@ SignalFfiError *signal_sanitized_metadata_get_data_offset(uint64_t *out, const S SignalFfiError *signal_sanitized_metadata_get_data_len(uint64_t *out, const SignalSanitizedMetadata *sanitized); #endif -SignalFfiError *signal_testing_NonSuspendingBackgroundThreadRuntime_destroy(SignalNonSuspendingBackgroundThreadRuntime *p); - -SignalFfiError *signal_testing_future_success(SignalCPromisei32 *promise, const SignalNonSuspendingBackgroundThreadRuntime *async_runtime, uint8_t input); - -SignalFfiError *signal_testing_future_failure(SignalCPromisei32 *promise, const SignalNonSuspendingBackgroundThreadRuntime *async_runtime, uint8_t _input); - -SignalFfiError *signal_testing_handle_type_destroy(SignalTestingHandleType *p); - -SignalFfiError *signal_testing_handle_type_clone(SignalTestingHandleType **new_obj, const SignalTestingHandleType *obj); - -SignalFfiError *signal_testing_testing_handle_type_get_value(uint8_t *out, const SignalTestingHandleType *handle); - -SignalFfiError *signal_testing_future_produces_pointer_type(SignalCPromiseTestingHandleType *promise, const SignalNonSuspendingBackgroundThreadRuntime *async_runtime, uint8_t input); - -SignalFfiError *signal_other_testing_handle_type_destroy(SignalOtherTestingHandleType *p); - -SignalFfiError *signal_other_testing_handle_type_clone(SignalOtherTestingHandleType **new_obj, const SignalOtherTestingHandleType *obj); - -SignalFfiError *signal_testing_other_testing_handle_type_get_value(const char **out, const SignalOtherTestingHandleType *handle); - -SignalFfiError *signal_testing_future_produces_other_pointer_type(SignalCPromiseOtherTestingHandleType *promise, const SignalNonSuspendingBackgroundThreadRuntime *async_runtime, const char *input); - -SignalFfiError *signal_testing_panic_on_borrow_sync(const void *_input); - -SignalFfiError *signal_testing_panic_on_borrow_async(const void *_input); - -SignalFfiError *signal_testing_panic_on_borrow_io(SignalCPromisebool *promise, const SignalNonSuspendingBackgroundThreadRuntime *async_runtime, const void *_input); - -SignalFfiError *signal_testing_error_on_borrow_sync(const void *_input); - -SignalFfiError *signal_testing_error_on_borrow_async(const void *_input); - -SignalFfiError *signal_testing_error_on_borrow_io(SignalCPromisebool *promise, const SignalNonSuspendingBackgroundThreadRuntime *async_runtime, const void *_input); - -SignalFfiError *signal_testing_panic_on_load_sync(const void *_needs_cleanup, const void *_input); - -SignalFfiError *signal_testing_panic_on_load_async(const void *_needs_cleanup, const void *_input); - -SignalFfiError *signal_testing_panic_on_load_io(SignalCPromisebool *promise, const SignalNonSuspendingBackgroundThreadRuntime *async_runtime, const void *_needs_cleanup, const void *_input); - -SignalFfiError *signal_testing_panic_in_body_sync(const void *_input); - -SignalFfiError *signal_testing_panic_in_body_async(const void *_input); - -SignalFfiError *signal_testing_panic_in_body_io(SignalCPromisebool *promise, const SignalNonSuspendingBackgroundThreadRuntime *async_runtime, const void *_input); - -SignalFfiError *signal_testing_panic_on_return_sync(const void **out, const void *_needs_cleanup); - -SignalFfiError *signal_testing_panic_on_return_async(const void **out, const void *_needs_cleanup); - -SignalFfiError *signal_testing_panic_on_return_io(SignalCPromiseRawPointer *promise, const SignalNonSuspendingBackgroundThreadRuntime *async_runtime, const void *_needs_cleanup); - -SignalFfiError *signal_testing_error_on_return_sync(const void **out, const void *_needs_cleanup); - -SignalFfiError *signal_testing_error_on_return_async(const void **out, const void *_needs_cleanup); - -SignalFfiError *signal_testing_error_on_return_io(SignalCPromiseRawPointer *promise, const SignalNonSuspendingBackgroundThreadRuntime *async_runtime, const void *_needs_cleanup); - -SignalFfiError *signal_testing_return_string_array(SignalStringArray *out); - -SignalFfiError *signal_testing_process_bytestring_array(SignalBytestringArray *out, SignalBorrowedSliceOfBuffers input); - -SignalFfiError *signal_testing_input_stream_read_into_zero_length_slice(SignalOwnedBuffer *out, const SignalInputStream *caps_alphabet_input); - -SignalFfiError *signal_testing_cdsi_lookup_response_convert(SignalCPromiseFfiCdsiLookupResponse *promise, const SignalTokioAsyncContext *async_runtime); - -SignalFfiError *signal_testing_only_completes_by_cancellation(SignalCPromisebool *promise, const SignalTokioAsyncContext *async_runtime); - -SignalFfiError *signal_testing_cdsi_lookup_error_convert(const char *error_description); - -SignalFfiError *signal_testing_chat_service_error_convert(const char *error_description); - -SignalFfiError *signal_testing_chat_service_response_convert(SignalFfiChatResponse *out, bool body_present); - -SignalFfiError *signal_testing_chat_service_debug_info_convert(SignalFfiChatServiceDebugInfo *out); - -SignalFfiError *signal_testing_chat_service_response_and_debug_info_convert(SignalFfiResponseAndDebugInfo *out); - -SignalFfiError *signal_testing_chat_request_get_method(const char **out, const SignalHttpRequest *request); - -SignalFfiError *signal_testing_chat_request_get_path(const char **out, const SignalHttpRequest *request); - -SignalFfiError *signal_testing_chat_request_get_header_value(const char **out, const SignalHttpRequest *request, const char *header_name); - -SignalFfiError *signal_testing_chat_request_get_body(SignalOwnedBuffer *out, const SignalHttpRequest *request); - #endif /* SIGNAL_FFI_H_ */ diff --git a/pkg/libsignalgo/version.go b/pkg/libsignalgo/version.go index cb4bd77..e36a12a 100644 --- a/pkg/libsignalgo/version.go +++ b/pkg/libsignalgo/version.go @@ -2,4 +2,4 @@ package libsignalgo -const Version = "v0.55.0" +const Version = "v0.56.1" From 33496974088feaeef0a50b3f127a8d09f5045149 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Tue, 3 Sep 2024 02:45:38 +0300 Subject: [PATCH 161/580] msgconv/from-matrix: convert voice messages to raw aac instead of m4a Apparently Signal iOS doesn't like ffmpeg's m4a's, but is fine with aac? --- pkg/msgconv/from-matrix.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkg/msgconv/from-matrix.go b/pkg/msgconv/from-matrix.go index 3b61b9f..2a282fc 100644 --- a/pkg/msgconv/from-matrix.go +++ b/pkg/msgconv/from-matrix.go @@ -157,12 +157,12 @@ func (mc *MessageConverter) convertFileToSignal(ctx context.Context, evt *event. } mime := content.GetInfo().MimeType if content.MSC3245Voice != nil && ffmpeg.Supported() { - data, err = ffmpeg.ConvertBytes(ctx, data, ".m4a", []string{}, []string{"-c:a", "aac"}, mime) + data, err = ffmpeg.ConvertBytes(ctx, data, ".aac", []string{}, []string{"-c:a", "aac"}, mime) if err != nil { return nil, err } mime = "audio/aac" - fileName += ".m4a" + fileName += ".aac" } else if evt.Type == event.EventSticker { switch mime { case "image/webp", "image/png", "image/apng": From e36642bab8764f97c5ea16548c5e1a102c1fae1c Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Tue, 3 Sep 2024 03:02:50 +0300 Subject: [PATCH 162/580] signalmeow/sending: always include expiration start in sync messages --- pkg/signalmeow/sending.go | 33 +++++++++++++++++++-------------- 1 file changed, 19 insertions(+), 14 deletions(-) diff --git a/pkg/signalmeow/sending.go b/pkg/signalmeow/sending.go index cc156c9..20be143 100644 --- a/pkg/signalmeow/sending.go +++ b/pkg/signalmeow/sending.go @@ -30,6 +30,7 @@ import ( "github.com/google/uuid" "github.com/rs/zerolog" "go.mau.fi/util/exfmt" + "go.mau.fi/util/ptr" "google.golang.org/protobuf/proto" "go.mau.fi/mautrix-signal/pkg/libsignalgo" @@ -327,9 +328,10 @@ func syncMessageFromGroupDataMessage(dataMessage *signalpb.DataMessage, results return &signalpb.Content{ SyncMessage: &signalpb.SyncMessage{ Sent: &signalpb.SyncMessage_Sent{ - Message: dataMessage, - Timestamp: dataMessage.Timestamp, - UnidentifiedStatus: unidentifiedStatuses, + Message: dataMessage, + Timestamp: dataMessage.Timestamp, + UnidentifiedStatus: unidentifiedStatuses, + ExpirationStartTimestamp: ptr.Ptr(uint64(time.Now().UnixMilli())), }, }, } @@ -345,9 +347,10 @@ func syncMessageFromGroupEditMessage(editMessage *signalpb.EditMessage, results return &signalpb.Content{ SyncMessage: &signalpb.SyncMessage{ Sent: &signalpb.SyncMessage_Sent{ - EditMessage: editMessage, - Timestamp: editMessage.GetDataMessage().Timestamp, - UnidentifiedStatus: unidentifiedStatuses, + EditMessage: editMessage, + Timestamp: editMessage.GetDataMessage().Timestamp, + UnidentifiedStatus: unidentifiedStatuses, + ExpirationStartTimestamp: ptr.Ptr(uint64(time.Now().UnixMilli())), }, }, } @@ -357,10 +360,11 @@ func syncMessageFromSoloDataMessage(dataMessage *signalpb.DataMessage, result Su return &signalpb.Content{ SyncMessage: &signalpb.SyncMessage{ Sent: &signalpb.SyncMessage_Sent{ - Message: dataMessage, - DestinationE164: result.RecipientE164, - DestinationServiceId: proto.String(result.Recipient.String()), - Timestamp: dataMessage.Timestamp, + Message: dataMessage, + DestinationE164: result.RecipientE164, + DestinationServiceId: proto.String(result.Recipient.String()), + Timestamp: dataMessage.Timestamp, + ExpirationStartTimestamp: ptr.Ptr(uint64(time.Now().UnixMilli())), UnidentifiedStatus: []*signalpb.SyncMessage_Sent_UnidentifiedDeliveryStatus{ { DestinationServiceId: proto.String(result.Recipient.String()), @@ -377,10 +381,11 @@ func syncMessageFromSoloEditMessage(editMessage *signalpb.EditMessage, result Su return &signalpb.Content{ SyncMessage: &signalpb.SyncMessage{ Sent: &signalpb.SyncMessage_Sent{ - EditMessage: editMessage, - DestinationE164: result.RecipientE164, - DestinationServiceId: proto.String(result.Recipient.String()), - Timestamp: editMessage.DataMessage.Timestamp, + EditMessage: editMessage, + DestinationE164: result.RecipientE164, + DestinationServiceId: proto.String(result.Recipient.String()), + Timestamp: editMessage.DataMessage.Timestamp, + ExpirationStartTimestamp: ptr.Ptr(uint64(time.Now().UnixMilli())), UnidentifiedStatus: []*signalpb.SyncMessage_Sent_UnidentifiedDeliveryStatus{ { DestinationServiceId: proto.String(result.Recipient.String()), From bf63aa1aa63e049373df7a62866eab6b8dfb25a0 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Tue, 3 Sep 2024 03:03:37 +0300 Subject: [PATCH 163/580] signalmeow: adjust raw data logs --- pkg/signalmeow/receiving.go | 2 +- pkg/signalmeow/sending.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pkg/signalmeow/receiving.go b/pkg/signalmeow/receiving.go index bfceca6..6f40a7f 100644 --- a/pkg/signalmeow/receiving.go +++ b/pkg/signalmeow/receiving.go @@ -643,10 +643,10 @@ func (cli *Client) handleDecryptedResult( } content := result.Content - log.Trace().Any("raw_data", content).Msg("Raw event data") name, _ := result.SenderAddress.Name() deviceId, _ := result.SenderAddress.DeviceID() + log.Trace().Any("raw_data", content).Str("sender", name).Uint("sender_device", deviceId).Msg("Raw event data") newLog := log.With(). Str("sender_name", name). Uint("sender_device_id", deviceId). diff --git a/pkg/signalmeow/sending.go b/pkg/signalmeow/sending.go index 20be143..0236331 100644 --- a/pkg/signalmeow/sending.go +++ b/pkg/signalmeow/sending.go @@ -797,7 +797,7 @@ func (cli *Client) sendContent( Logger() ctx = log.WithContext(ctx) printContentFieldString(ctx, content, "Outgoing message") - log.Trace().Any("raw_content", content).Msg("Raw data of outgoing message") + log.Trace().Any("raw_content", content).Stringer("recipient", recipient).Msg("Raw data of outgoing message") // If it's a data message, add our profile key if content.DataMessage != nil { From b1bd303b0e8d75a88b69adf02348dfdcac8e336c Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Tue, 3 Sep 2024 20:12:28 +0300 Subject: [PATCH 164/580] client: register capabilities on connect --- pkg/connector/client.go | 6 ++++++ pkg/signalmeow/provisioning.go | 29 ++++++++++++++++++++++++++--- 2 files changed, 32 insertions(+), 3 deletions(-) diff --git a/pkg/connector/client.go b/pkg/connector/client.go index 56ab59a..ebd2def 100644 --- a/pkg/connector/client.go +++ b/pkg/connector/client.go @@ -240,6 +240,12 @@ func (s *SignalClient) Disconnect() { } func (s *SignalClient) tryConnect(ctx context.Context, retryCount int) { + err := s.Client.RegisterCapabilities(ctx) + if err != nil { + zerolog.Ctx(ctx).Err(err).Msg("Failed to register capabilities") + } else { + zerolog.Ctx(ctx).Debug().Msg("Successfully registered capabilities") + } ch, err := s.Client.StartReceiveLoops(ctx) if err != nil { zerolog.Ctx(ctx).Err(err).Msg("Failed to start receive loops") diff --git a/pkg/signalmeow/provisioning.go b/pkg/signalmeow/provisioning.go index f3abb2c..160bdec 100644 --- a/pkg/signalmeow/provisioning.go +++ b/pkg/signalmeow/provisioning.go @@ -330,6 +330,31 @@ func continueProvisioning(ctx context.Context, ws *websocket.Conn, provisioningC return provisioningMessage, err } +var signalCapabilities = map[string]any{ + "deleteSync": true, +} + +var signalCapabilitiesBody = exerrors.Must(json.Marshal(signalCapabilities)) + +func (cli *Client) RegisterCapabilities(ctx context.Context) error { + username, password := cli.Store.BasicAuthCreds() + resp, err := web.SendHTTPRequest(ctx, http.MethodPut, "/v1/devices/capabilities", &web.HTTPReqOpt{ + Body: signalCapabilitiesBody, + Username: &username, + Password: &password, + ContentType: web.ContentTypeJSON, + }) + if resp != nil { + _ = resp.Body.Close() + } + if err != nil { + return err + } else if resp.StatusCode >= 400 { + return fmt.Errorf("unexpected status code %d", resp.StatusCode) + } + return nil +} + func confirmDevice( ctx context.Context, username string, @@ -383,9 +408,7 @@ func confirmDevice( "name": encryptedDeviceName, "registrationId": aciRegistrationID, "pniRegistrationId": pniRegistrationID, - "capabilities": map[string]any{ - "deleteSync": true, - }, + "capabilities": signalCapabilities, }, "aciSignedPreKey": aciSignedPreKeyJson, "pniSignedPreKey": pniSignedPreKeyJson, From 81841f4a822881cace1a8e527d23843a9292faaf Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Tue, 3 Sep 2024 20:22:42 +0300 Subject: [PATCH 165/580] dbmeta: add support for expiration timer versions --- pkg/msgconv/from-matrix.go | 4 +++ pkg/msgconv/from-signal.go | 18 ++++++++-- pkg/signalid/dbmeta.go | 3 +- pkg/signalmeow/protobuf/SignalService.pb.go | 36 +++++++++++++------ pkg/signalmeow/protobuf/SignalService.pb.raw | Bin 19040 -> 19136 bytes pkg/signalmeow/protobuf/SignalService.proto | 24 +++++++------ pkg/signalmeow/protobuf/update-protos.sh | 4 +-- pkg/signalmeow/provisioning.go | 3 +- 8 files changed, 65 insertions(+), 27 deletions(-) diff --git a/pkg/msgconv/from-matrix.go b/pkg/msgconv/from-matrix.go index 2a282fc..cb938e7 100644 --- a/pkg/msgconv/from-matrix.go +++ b/pkg/msgconv/from-matrix.go @@ -78,6 +78,10 @@ func (mc *MessageConverter) ToSignal( } if portal.Disappear.Timer > 0 { dm.ExpireTimer = proto.Uint32(uint32(portal.Disappear.Timer.Seconds())) + timerVersion := portal.Metadata.(*signalid.PortalMetadata).ExpirationTimerVersion + if timerVersion > 0 { + dm.ExpireTimerVersion = &timerVersion + } } if content.MsgType == event.MsgEmote && !relaybotFormatted { content.Body = "/me " + content.Body diff --git a/pkg/msgconv/from-signal.go b/pkg/msgconv/from-signal.go index 4b09e80..20dd39b 100644 --- a/pkg/msgconv/from-signal.go +++ b/pkg/msgconv/from-signal.go @@ -85,7 +85,7 @@ func (mc *MessageConverter) ToMatrix( Parts: make([]*bridgev2.ConvertedMessagePart, 0, calculateLength(dm)), } if dm.GetFlags()&uint32(signalpb.DataMessage_EXPIRATION_TIMER_UPDATE) != 0 { - cm.Parts = append(cm.Parts, mc.ConvertDisappearingTimerChangeToMatrix(ctx, dm.GetExpireTimer(), true)) + cm.Parts = append(cm.Parts, mc.ConvertDisappearingTimerChangeToMatrix(ctx, dm.GetExpireTimer(), dm.ExpireTimerVersion, true)) // Don't allow any other parts in a disappearing timer change message return cm } @@ -151,7 +151,7 @@ func (mc *MessageConverter) ToMatrix( return cm } -func (mc *MessageConverter) ConvertDisappearingTimerChangeToMatrix(ctx context.Context, timer uint32, updatePortal bool) *bridgev2.ConvertedMessagePart { +func (mc *MessageConverter) ConvertDisappearingTimerChangeToMatrix(ctx context.Context, timer uint32, timerVersion *uint32, updatePortal bool) *bridgev2.ConvertedMessagePart { part := &bridgev2.ConvertedMessagePart{ Type: event.EventMessage, Content: &event.MessageEventContent{ @@ -164,12 +164,26 @@ func (mc *MessageConverter) ConvertDisappearingTimerChangeToMatrix(ctx context.C } if updatePortal { portal := getPortal(ctx) + portalMeta := portal.Metadata.(*signalid.PortalMetadata) + if timerVersion != nil && portalMeta.ExpirationTimerVersion > *timerVersion { + zerolog.Ctx(ctx).Warn(). + Uint32("current_version", portalMeta.ExpirationTimerVersion). + Uint32("new_version", *timerVersion). + Msg("Ignoring outdated disappearing timer change") + part.Content.Body += " (change ignored)" + return part + } portal.Disappear.Timer = time.Duration(timer) * time.Second if timer == 0 { portal.Disappear.Type = "" } else { portal.Disappear.Type = database.DisappearingTypeAfterRead } + if timerVersion != nil { + portalMeta.ExpirationTimerVersion = *timerVersion + } else { + portalMeta.ExpirationTimerVersion = 1 + } err := portal.Save(ctx) if err != nil { zerolog.Ctx(ctx).Err(err).Msg("Failed to update portal disappearing timer in database") diff --git a/pkg/signalid/dbmeta.go b/pkg/signalid/dbmeta.go index 5a96b07..f3811af 100644 --- a/pkg/signalid/dbmeta.go +++ b/pkg/signalid/dbmeta.go @@ -21,7 +21,8 @@ import ( ) type PortalMetadata struct { - Revision uint32 `json:"revision,omitempty"` + Revision uint32 `json:"revision,omitempty"` + ExpirationTimerVersion uint32 `json:"expiration_timer_version,omitempty"` } type MessageMetadata struct { diff --git a/pkg/signalmeow/protobuf/SignalService.pb.go b/pkg/signalmeow/protobuf/SignalService.pb.go index f382b8b..f524c90 100644 --- a/pkg/signalmeow/protobuf/SignalService.pb.go +++ b/pkg/signalmeow/protobuf/SignalService.pb.go @@ -2163,6 +2163,7 @@ type DataMessage struct { GroupV2 *GroupContextV2 `protobuf:"bytes,15,opt,name=groupV2" json:"groupV2,omitempty"` Flags *uint32 `protobuf:"varint,4,opt,name=flags" json:"flags,omitempty"` ExpireTimer *uint32 `protobuf:"varint,5,opt,name=expireTimer" json:"expireTimer,omitempty"` + ExpireTimerVersion *uint32 `protobuf:"varint,23,opt,name=expireTimerVersion" json:"expireTimerVersion,omitempty"` ProfileKey []byte `protobuf:"bytes,6,opt,name=profileKey" json:"profileKey,omitempty"` Timestamp *uint64 `protobuf:"varint,7,opt,name=timestamp" json:"timestamp,omitempty"` Quote *DataMessage_Quote `protobuf:"bytes,8,opt,name=quote" json:"quote,omitempty"` @@ -2247,6 +2248,13 @@ func (x *DataMessage) GetExpireTimer() uint32 { return 0 } +func (x *DataMessage) GetExpireTimerVersion() uint32 { + if x != nil && x.ExpireTimerVersion != nil { + return *x.ExpireTimerVersion + } + return 0 +} + func (x *DataMessage) GetProfileKey() []byte { if x != nil { return x.ProfileKey @@ -3464,16 +3472,17 @@ type ContactDetails struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Number *string `protobuf:"bytes,1,opt,name=number" json:"number,omitempty"` - Aci *string `protobuf:"bytes,9,opt,name=aci" json:"aci,omitempty"` - Name *string `protobuf:"bytes,2,opt,name=name" json:"name,omitempty"` - Avatar *ContactDetails_Avatar `protobuf:"bytes,3,opt,name=avatar" json:"avatar,omitempty"` - Color *string `protobuf:"bytes,4,opt,name=color" json:"color,omitempty"` - Verified *Verified `protobuf:"bytes,5,opt,name=verified" json:"verified,omitempty"` - ProfileKey []byte `protobuf:"bytes,6,opt,name=profileKey" json:"profileKey,omitempty"` - ExpireTimer *uint32 `protobuf:"varint,8,opt,name=expireTimer" json:"expireTimer,omitempty"` - InboxPosition *uint32 `protobuf:"varint,10,opt,name=inboxPosition" json:"inboxPosition,omitempty"` - Archived *bool `protobuf:"varint,11,opt,name=archived" json:"archived,omitempty"` + Number *string `protobuf:"bytes,1,opt,name=number" json:"number,omitempty"` + Aci *string `protobuf:"bytes,9,opt,name=aci" json:"aci,omitempty"` + Name *string `protobuf:"bytes,2,opt,name=name" json:"name,omitempty"` + Avatar *ContactDetails_Avatar `protobuf:"bytes,3,opt,name=avatar" json:"avatar,omitempty"` + Color *string `protobuf:"bytes,4,opt,name=color" json:"color,omitempty"` + Verified *Verified `protobuf:"bytes,5,opt,name=verified" json:"verified,omitempty"` + ProfileKey []byte `protobuf:"bytes,6,opt,name=profileKey" json:"profileKey,omitempty"` + ExpireTimer *uint32 `protobuf:"varint,8,opt,name=expireTimer" json:"expireTimer,omitempty"` + ExpireTimerVersion *uint32 `protobuf:"varint,12,opt,name=expireTimerVersion" json:"expireTimerVersion,omitempty"` + InboxPosition *uint32 `protobuf:"varint,10,opt,name=inboxPosition" json:"inboxPosition,omitempty"` + Archived *bool `protobuf:"varint,11,opt,name=archived" json:"archived,omitempty"` } func (x *ContactDetails) Reset() { @@ -3564,6 +3573,13 @@ func (x *ContactDetails) GetExpireTimer() uint32 { return 0 } +func (x *ContactDetails) GetExpireTimerVersion() uint32 { + if x != nil && x.ExpireTimerVersion != nil { + return *x.ExpireTimerVersion + } + return 0 +} + func (x *ContactDetails) GetInboxPosition() uint32 { if x != nil && x.InboxPosition != nil { return *x.InboxPosition diff --git a/pkg/signalmeow/protobuf/SignalService.pb.raw b/pkg/signalmeow/protobuf/SignalService.pb.raw index 2ca3d164ba21b6b1ed160d649962a9e9d2aaeb9c..bc9a4d57969c32e0c0d280ef3808c2a3c4c70bbb 100644 GIT binary patch delta 128 zcmaDbh4H{t#tp}~7++03&UHgyk4q@Eq9C&b37uWoK~k!Hl9mj|cbIj%=o02{F{IsgCw delta 32 qcmV+*0N?+>l>y+C0kFmj0lJgN3fQyH3*tBdrL(d`8v(QZMZ*ODbPo{# diff --git a/pkg/signalmeow/protobuf/SignalService.proto b/pkg/signalmeow/protobuf/SignalService.proto index 1e2332b..c516a1b 100644 --- a/pkg/signalmeow/protobuf/SignalService.proto +++ b/pkg/signalmeow/protobuf/SignalService.proto @@ -332,6 +332,7 @@ message DataMessage { optional GroupContextV2 groupV2 = 15; optional uint32 flags = 4; optional uint32 expireTimer = 5; + optional uint32 expireTimerVersion = 23; optional bytes profileKey = 6; optional uint64 timestamp = 7; optional Quote quote = 8; @@ -793,17 +794,18 @@ message ContactDetails { optional uint32 length = 2; } - optional string number = 1; - optional string aci = 9; - optional string name = 2; - optional Avatar avatar = 3; - optional string color = 4; - optional Verified verified = 5; - optional bytes profileKey = 6; - reserved /*blocked*/ 7; - optional uint32 expireTimer = 8; - optional uint32 inboxPosition = 10; - optional bool archived = 11; + optional string number = 1; + optional string aci = 9; + optional string name = 2; + optional Avatar avatar = 3; + optional string color = 4; + optional Verified verified = 5; + optional bytes profileKey = 6; + reserved /*blocked*/ 7; + optional uint32 expireTimer = 8; + optional uint32 expireTimerVersion = 12; + optional uint32 inboxPosition = 10; + optional bool archived = 11; } message GroupDetails { diff --git a/pkg/signalmeow/protobuf/update-protos.sh b/pkg/signalmeow/protobuf/update-protos.sh index 9735ecf..43790f4 100755 --- a/pkg/signalmeow/protobuf/update-protos.sh +++ b/pkg/signalmeow/protobuf/update-protos.sh @@ -1,8 +1,8 @@ #!/bin/bash set -euo pipefail -ANDROID_GIT_REVISION=${1:-68c7ce582378b5f752e5971007b2c203e81cecbd} -DESKTOP_GIT_REVISION=${1:-faea93e5cea24893a8976dc6329faa751f59df5c} +ANDROID_GIT_REVISION=${1:-ab7bdc3c03ecda2d746fd56cfd747f56feab7b17} +DESKTOP_GIT_REVISION=${1:-1898e964adcfc8a9096b4aaebff895813fb4f35c} update_proto() { case "$1" in diff --git a/pkg/signalmeow/provisioning.go b/pkg/signalmeow/provisioning.go index 160bdec..5c09457 100644 --- a/pkg/signalmeow/provisioning.go +++ b/pkg/signalmeow/provisioning.go @@ -331,7 +331,8 @@ func continueProvisioning(ctx context.Context, ws *websocket.Conn, provisioningC } var signalCapabilities = map[string]any{ - "deleteSync": true, + "deleteSync": true, + "versionedExpirationTimer": true, } var signalCapabilitiesBody = exerrors.Must(json.Marshal(signalCapabilities)) From 92d338b8ad41a2f808914b8f75dbae0bf22dbc44 Mon Sep 17 00:00:00 2001 From: 1Conan Date: Wed, 4 Sep 2024 22:52:12 +0800 Subject: [PATCH 166/580] add iOS to serviceid --- pkg/libsignalgo/serviceid_clang.go | 2 +- pkg/libsignalgo/serviceid_gcc.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pkg/libsignalgo/serviceid_clang.go b/pkg/libsignalgo/serviceid_clang.go index 067d9d1..3e9ae17 100644 --- a/pkg/libsignalgo/serviceid_clang.go +++ b/pkg/libsignalgo/serviceid_clang.go @@ -1,4 +1,4 @@ -//go:build darwin || android +//go:build darwin || android || ios package libsignalgo diff --git a/pkg/libsignalgo/serviceid_gcc.go b/pkg/libsignalgo/serviceid_gcc.go index 0d0f5c8..9ff97bc 100644 --- a/pkg/libsignalgo/serviceid_gcc.go +++ b/pkg/libsignalgo/serviceid_gcc.go @@ -1,4 +1,4 @@ -//go:build !(darwin || android) +//go:build !(darwin || android || ios) package libsignalgo From ea8208b9e0aeb1623eb8efe9caed2e636be4a165 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Fri, 6 Sep 2024 14:04:29 +0300 Subject: [PATCH 167/580] dependencies: update mautrix-go --- go.mod | 10 +++++----- go.sum | 20 ++++++++++---------- pkg/connector/handlematrix.go | 7 +++++-- 3 files changed, 20 insertions(+), 17 deletions(-) diff --git a/go.mod b/go.mod index e4c6005..664b59e 100644 --- a/go.mod +++ b/go.mod @@ -10,12 +10,12 @@ require ( github.com/rs/zerolog v1.33.0 github.com/stretchr/testify v1.9.0 github.com/tidwall/gjson v1.17.3 - go.mau.fi/util v0.7.1-0.20240901193650-bf007b10eaf6 + go.mau.fi/util v0.7.1-0.20240904173517-ca3b3fe376c2 golang.org/x/crypto v0.26.0 golang.org/x/exp v0.0.0-20240823005443-9b4947da3948 golang.org/x/net v0.28.0 google.golang.org/protobuf v1.34.2 - maunium.net/go/mautrix v0.20.1-0.20240902092346-6f1a3878c452 + maunium.net/go/mautrix v0.20.1-0.20240906105454-33d724bf4c78 nhooyr.io/websocket v1.8.17 ) @@ -28,7 +28,7 @@ require ( github.com/lib/pq v1.10.9 // indirect github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-isatty v0.0.19 // indirect - github.com/mattn/go-sqlite3 v1.14.22 // indirect + github.com/mattn/go-sqlite3 v1.14.23 // indirect github.com/petermattis/goid v0.0.0-20240813172612-4fcff4a6cae7 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/rogpeppe/go-internal v1.10.0 // indirect @@ -40,8 +40,8 @@ require ( github.com/yuin/goldmark v1.7.4 // indirect go.mau.fi/zeroconfig v0.1.3 // indirect golang.org/x/sync v0.8.0 // indirect - golang.org/x/sys v0.24.0 // indirect - golang.org/x/text v0.17.0 // indirect + golang.org/x/sys v0.25.0 // indirect + golang.org/x/text v0.18.0 // indirect gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect gopkg.in/natefinch/lumberjack.v2 v2.2.1 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect diff --git a/go.sum b/go.sum index 2d7ba8f..1f7751c 100644 --- a/go.sum +++ b/go.sum @@ -34,8 +34,8 @@ github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APP github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mattn/go-pointer v0.0.1 h1:n+XhsuGeVO6MEAp7xyEukFINEa+Quek5psIR/ylA6o0= github.com/mattn/go-pointer v0.0.1/go.mod h1:2zXcozF6qYGgmsG+SeTZz3oAbFLdD3OWqnUbNvJZAlc= -github.com/mattn/go-sqlite3 v1.14.22 h1:2gZY6PC6kBnID23Tichd1K+Z0oS6nE/XwU+Vz/5o4kU= -github.com/mattn/go-sqlite3 v1.14.22/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y= +github.com/mattn/go-sqlite3 v1.14.23 h1:gbShiuAP1W5j9UOksQ06aiiqPMxYecovVGwmTxWtuw0= +github.com/mattn/go-sqlite3 v1.14.23/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y= github.com/petermattis/goid v0.0.0-20240813172612-4fcff4a6cae7 h1:Dx7Ovyv/SFnMFw3fD4oEoeorXc6saIiQ23LrGLth0Gw= github.com/petermattis/goid v0.0.0-20240813172612-4fcff4a6cae7/go.mod h1:pxMtw7cyUw6B2bRH0ZBANSPg+AoSud1I1iyJHI69jH4= github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= @@ -65,8 +65,8 @@ github.com/tidwall/sjson v1.2.5 h1:kLy8mja+1c9jlljvWTlSazM7cKDRfJuR/bOJhcY5NcY= github.com/tidwall/sjson v1.2.5/go.mod h1:Fvgq9kS/6ociJEDnK0Fk1cpYF4FIW6ZF7LAe+6jwd28= github.com/yuin/goldmark v1.7.4 h1:BDXOHExt+A7gwPCJgPIIq7ENvceR7we7rOS9TNoLZeg= github.com/yuin/goldmark v1.7.4/go.mod h1:uzxRWxtg69N339t3louHJ7+O03ezfj6PlliRlaOzY1E= -go.mau.fi/util v0.7.1-0.20240901193650-bf007b10eaf6 h1:cSLCabMKbR6rTPYRGWD2XaHo210BK3BtPg+CRC4A4og= -go.mau.fi/util v0.7.1-0.20240901193650-bf007b10eaf6/go.mod h1:WuAOOV0O/otkxGkFUvfv/XE2ztegaoyM15ovS6SYbf4= +go.mau.fi/util v0.7.1-0.20240904173517-ca3b3fe376c2 h1:VZQlKBbeJ7KOlYSh6BnN5uWQTY/ypn/bJv0YyEd+pXc= +go.mau.fi/util v0.7.1-0.20240904173517-ca3b3fe376c2/go.mod h1:WgYvbt9rVmoFeajP97NunQU7AjgvTPiNExN3oTHeePs= go.mau.fi/zeroconfig v0.1.3 h1:As9wYDKmktjmNZW5i1vn8zvJlmGKHeVxHVIBMXsm4kM= go.mau.fi/zeroconfig v0.1.3/go.mod h1:NcSJkf180JT+1IId76PcMuLTNa1CzsFFZ0nBygIQM70= golang.org/x/crypto v0.26.0 h1:RrRspgV4mU+YwB4FYnuBoKsUapNIL5cohGAmSH3azsw= @@ -80,10 +80,10 @@ golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg= -golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/text v0.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc= -golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= +golang.org/x/sys v0.25.0 h1:r+8e+loiHxRqhXVl6ML1nO3l1+oFoWbnlu2Ehimmi34= +golang.org/x/sys v0.25.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/text v0.18.0 h1:XvMDiNzPAl0jr17s6W9lcaIhGUfUORdGCNsuLmPG224= +golang.org/x/text v0.18.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= @@ -95,7 +95,7 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= maunium.net/go/mauflag v1.0.0 h1:YiaRc0tEI3toYtJMRIfjP+jklH45uDHtT80nUamyD4M= maunium.net/go/mauflag v1.0.0/go.mod h1:nLivPOpTpHnpzEh8jEdSL9UqO9+/KBJFmNRlwKfkPeA= -maunium.net/go/mautrix v0.20.1-0.20240902092346-6f1a3878c452 h1:Yq7qZMP3y/BJ7/5aaDVPkRs9vZjtfwhcbDJuLWR8cVs= -maunium.net/go/mautrix v0.20.1-0.20240902092346-6f1a3878c452/go.mod h1:IXDDoX+dqBkNnrjDMouE3FUExiR+hhmaEFsvXG3HzfQ= +maunium.net/go/mautrix v0.20.1-0.20240906105454-33d724bf4c78 h1:F8ls6UNW8QlTpQ2QAnPuCN5gVB30Y3ojBYfXb9T6U64= +maunium.net/go/mautrix v0.20.1-0.20240906105454-33d724bf4c78/go.mod h1:l6nYvD5/FMSrAZ/IP1AqJV0b47SRl/0uQNRiy4CcSVk= nhooyr.io/websocket v1.8.17 h1:KEVeLJkUywCKVsnLIDlD/5gtayKp8VoCkksHCGGfT9Y= nhooyr.io/websocket v1.8.17/go.mod h1:rN9OFWIUwuxg4fR5tELlYC04bXYowCP9GX47ivo2l+c= diff --git a/pkg/connector/handlematrix.go b/pkg/connector/handlematrix.go index 4984b25..fb3b1d9 100644 --- a/pkg/connector/handlematrix.go +++ b/pkg/connector/handlematrix.go @@ -83,12 +83,14 @@ func (s *SignalClient) HandleMatrixMessage(ctx context.Context, msg *bridgev2.Ma if err != nil { return nil, err } + msgID := signalid.MakeMessageID(s.Client.Store.ACI, converted.GetTimestamp()) + msg.AddPendingToIgnore(networkid.TransactionID(msgID)) err = s.sendMessage(ctx, msg.Portal.ID, &signalpb.Content{DataMessage: converted}) if err != nil { return nil, bridgev2.WrapErrorInStatus(err).WithSendNotice(true) } dbMsg := &database.Message{ - ID: signalid.MakeMessageID(s.Client.Store.ACI, converted.GetTimestamp()), + ID: msgID, SenderID: signalid.MakeUserID(s.Client.Store.ACI), Timestamp: time.UnixMilli(int64(converted.GetTimestamp())), Metadata: &signalid.MessageMetadata{ @@ -96,7 +98,8 @@ func (s *SignalClient) HandleMatrixMessage(ctx context.Context, msg *bridgev2.Ma }, } return &bridgev2.MatrixMessageResponse{ - DB: dbMsg, + DB: dbMsg, + RemovePending: networkid.TransactionID(msgID), }, nil } From 798ebb689ff9642920871b5761533d0cf7b0a442 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Mon, 9 Sep 2024 19:25:08 +0300 Subject: [PATCH 168/580] handlesignal: bridge decryption errors --- pkg/connector/handlesignal.go | 61 +++++++++++++++++++++++++------- pkg/signalmeow/events/message.go | 5 +-- pkg/signalmeow/receiving.go | 11 +++--- 3 files changed, 59 insertions(+), 18 deletions(-) diff --git a/pkg/connector/handlesignal.go b/pkg/connector/handlesignal.go index 2f6803d..7275905 100644 --- a/pkg/connector/handlesignal.go +++ b/pkg/connector/handlesignal.go @@ -28,6 +28,7 @@ import ( "maunium.net/go/mautrix/bridgev2" "maunium.net/go/mautrix/bridgev2/database" "maunium.net/go/mautrix/bridgev2/networkid" + "maunium.net/go/mautrix/bridgev2/simplevent" "maunium.net/go/mautrix/event" "go.mau.fi/mautrix-signal/pkg/signalid" @@ -40,6 +41,7 @@ func (s *SignalClient) handleSignalEvent(rawEvt events.SignalEvent) { case *events.ChatEvent: s.Main.Bridge.QueueRemoteEvent(s.UserLogin, &Bv2ChatEvent{ChatEvent: evt, s: s}) case *events.DecryptionError: + s.Main.Bridge.QueueRemoteEvent(s.UserLogin, s.wrapDecryptionError(evt)) case *events.Receipt: s.handleSignalReceipt(evt) case *events.ReadSelf: @@ -54,19 +56,22 @@ func (s *SignalClient) handleSignalEvent(rawEvt events.SignalEvent) { } func (s *SignalClient) wrapCallEvent(evt *events.Call) bridgev2.RemoteMessage { - return &bridgev2.SimpleRemoteEvent[*events.Call]{ - Type: bridgev2.RemoteEventMessage, - LogContext: func(c zerolog.Context) zerolog.Context { - c = c.Stringer("sender_id", evt.Info.Sender) - c = c.Uint64("message_ts", evt.Timestamp) - return c + return &simplevent.Message[*events.Call]{ + EventMeta: simplevent.EventMeta{ + Type: bridgev2.RemoteEventMessage, + LogContext: func(c zerolog.Context) zerolog.Context { + c = c.Stringer("sender_id", evt.Info.Sender) + c = c.Uint64("message_ts", evt.Timestamp) + return c + }, + PortalKey: s.makePortalKey(evt.Info.ChatID), + CreatePortal: true, + Sender: s.makeEventSender(evt.Info.Sender), + Timestamp: time.UnixMilli(int64(evt.Timestamp)), }, - PortalKey: s.makePortalKey(evt.Info.ChatID), - Data: evt, - CreatePortal: true, - ID: signalid.MakeMessageID(evt.Info.Sender, evt.Timestamp), - Sender: s.makeEventSender(evt.Info.Sender), - Timestamp: time.UnixMilli(int64(evt.Timestamp)), + Data: evt, + ID: signalid.MakeMessageID(evt.Info.Sender, evt.Timestamp), + ConvertMessageFunc: convertCallEvent, } } @@ -91,6 +96,38 @@ func convertCallEvent(ctx context.Context, portal *bridgev2.Portal, intent bridg }, nil } +func (s *SignalClient) wrapDecryptionError(evt *events.DecryptionError) bridgev2.RemoteMessage { + return &simplevent.Message[*events.DecryptionError]{ + EventMeta: simplevent.EventMeta{ + Type: bridgev2.RemoteEventMessage, + LogContext: func(c zerolog.Context) zerolog.Context { + c = c.Stringer("sender_id", evt.Sender) + return c + }, + PortalKey: s.makePortalKey(evt.Sender.String()), + CreatePortal: true, + Sender: s.makeEventSender(evt.Sender), + Timestamp: time.UnixMilli(int64(evt.Timestamp)), + }, + Data: evt, + ID: "decrypterr|" + signalid.MakeMessageID(evt.Sender, evt.Timestamp), + + ConvertMessageFunc: convertDecryptionError, + } +} + +func convertDecryptionError(_ context.Context, _ *bridgev2.Portal, _ bridgev2.MatrixAPI, _ *events.DecryptionError) (*bridgev2.ConvertedMessage, error) { + return &bridgev2.ConvertedMessage{ + Parts: []*bridgev2.ConvertedMessagePart{{ + Type: event.EventMessage, + Content: &event.MessageEventContent{ + MsgType: event.MsgNotice, + Body: "Message couldn't be decrypted. It may have been in this chat or a group chat. Please check your Signal app.", + }, + }}, + }, nil +} + type Bv2ChatEvent struct { *events.ChatEvent s *SignalClient diff --git a/pkg/signalmeow/events/message.go b/pkg/signalmeow/events/message.go index 0db0f24..a6fcc7f 100644 --- a/pkg/signalmeow/events/message.go +++ b/pkg/signalmeow/events/message.go @@ -49,8 +49,9 @@ type ChatEvent struct { } type DecryptionError struct { - Sender uuid.UUID - Err error + Sender uuid.UUID + Err error + Timestamp uint64 } type Receipt struct { diff --git a/pkg/signalmeow/receiving.go b/pkg/signalmeow/receiving.go index 6f40a7f..850e204 100644 --- a/pkg/signalmeow/receiving.go +++ b/pkg/signalmeow/receiving.go @@ -276,6 +276,7 @@ func (cli *Client) incomingAPIMessageHandler(ctx context.Context, req *signalpb. destinationServiceID, err := libsignalgo.ServiceIDFromString(envelope.GetDestinationServiceId()) log.Trace(). Uint64("timestamp", envelope.GetTimestamp()). + Uint64("server_timestamp", envelope.GetServerTimestamp()). Str("destination_service_id", envelope.GetDestinationServiceId()). Str("source_service_id", envelope.GetSourceServiceId()). Uint32("source_device_id", envelope.GetSourceDevice()). @@ -286,7 +287,7 @@ func (cli *Client) incomingAPIMessageHandler(ctx context.Context, req *signalpb. result := cli.decryptEnvelope(ctx, envelope) - err = cli.handleDecryptedResult(ctx, result, destinationServiceID) + err = cli.handleDecryptedResult(ctx, result, destinationServiceID, envelope.GetServerTimestamp()) if err != nil { log.Err(err).Msg("handleDecryptedResult error") return nil, err @@ -613,6 +614,7 @@ func (cli *Client) handleDecryptedResult( ctx context.Context, result DecryptionResult, destinationServiceID libsignalgo.ServiceID, + serverTimestamp uint64, ) error { log := zerolog.Ctx(ctx) if result.Content == nil { @@ -623,19 +625,20 @@ func (cli *Client) handleDecryptedResult( // result.Err is set if there was an error during decryption and we // should notifiy the user that the message could not be decrypted if result.Err != nil { - log.Err(result.Err).Bool("urgent", result.Urgent).Msg("Decryption error") theirServiceID, err := result.SenderAddress.NameServiceID() if err != nil { log.Err(err).Msg("Name error handling decryption error") } else if theirServiceID.Type != libsignalgo.ServiceIDTypeACI { log.Warn().Any("their_service_id", theirServiceID).Msg("Sender ServiceID is not an ACI") } + log.Err(result.Err).Stringer("sender", theirServiceID).Bool("urgent", result.Urgent).Msg("Decryption error") // Only send decryption error event if the message was urgent, // to prevent spamming errors for typing notifications and whatnot if result.Urgent { cli.handleEvent(&events.DecryptionError{ - Sender: theirServiceID.UUID, - Err: result.Err, + Sender: theirServiceID.UUID, + Err: result.Err, + Timestamp: serverTimestamp, }) } // Intentionally not returning here. In most cases there's nothing besides the error so From ffd1ba34c0ff4bf6ebdf5dff3692ec74de081641 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Mon, 9 Sep 2024 20:55:43 +0300 Subject: [PATCH 169/580] signalmeow: clean up decryption code --- pkg/connector/handlesignal.go | 3 +- pkg/libsignalgo/sealedsender.go | 5 +- pkg/libsignalgo/session_test.go | 2 +- pkg/signalmeow/receiving.go | 302 +++++++++++++++----------------- 4 files changed, 148 insertions(+), 164 deletions(-) diff --git a/pkg/connector/handlesignal.go b/pkg/connector/handlesignal.go index 7275905..b39f202 100644 --- a/pkg/connector/handlesignal.go +++ b/pkg/connector/handlesignal.go @@ -110,7 +110,8 @@ func (s *SignalClient) wrapDecryptionError(evt *events.DecryptionError) bridgev2 Timestamp: time.UnixMilli(int64(evt.Timestamp)), }, Data: evt, - ID: "decrypterr|" + signalid.MakeMessageID(evt.Sender, evt.Timestamp), + // TODO use main message id and edit it if it later becomes decryptable? + ID: "decrypterr|" + signalid.MakeMessageID(evt.Sender, evt.Timestamp), ConvertMessageFunc: convertDecryptionError, } diff --git a/pkg/libsignalgo/sealedsender.go b/pkg/libsignalgo/sealedsender.go index f747b35..253e512 100644 --- a/pkg/libsignalgo/sealedsender.go +++ b/pkg/libsignalgo/sealedsender.go @@ -24,7 +24,6 @@ import "C" import ( "context" "runtime" - "time" "github.com/google/uuid" ) @@ -113,7 +112,7 @@ func SealedSenderDecrypt( ciphertext []byte, localAddress *SealedSenderAddress, trustRoot *PublicKey, - timestamp time.Time, + timestamp uint64, sessionStore SessionStore, identityStore IdentityKeyStore, preKeyStore PreKeyStore, @@ -134,7 +133,7 @@ func SealedSenderDecrypt( &senderDeviceID, BytesToBuffer(ciphertext), trustRoot.ptr, - C.uint64_t(timestamp.UnixMilli()), + C.uint64_t(timestamp), C.CString(localAddress.E164), C.CString(localAddress.UUID.String()), C.uint32_t(localAddress.DeviceID), diff --git a/pkg/libsignalgo/session_test.go b/pkg/libsignalgo/session_test.go index 17ea8c9..9d108d5 100644 --- a/pkg/libsignalgo/session_test.go +++ b/pkg/libsignalgo/session_test.go @@ -294,7 +294,7 @@ func TestSealedSenderSession(t *testing.T) { ciphertext, recipientAddress, trustRoot.GetPublicKey(), - time.UnixMilli(31335), + 31335, bobStore, bobStore, bobStore, diff --git a/pkg/signalmeow/receiving.go b/pkg/signalmeow/receiving.go index 850e204..8a40a16 100644 --- a/pkg/signalmeow/receiving.go +++ b/pkg/signalmeow/receiving.go @@ -22,7 +22,6 @@ import ( "fmt" "net/http" "strings" - "time" "github.com/google/uuid" "github.com/rs/zerolog" @@ -287,9 +286,9 @@ func (cli *Client) incomingAPIMessageHandler(ctx context.Context, req *signalpb. result := cli.decryptEnvelope(ctx, envelope) - err = cli.handleDecryptedResult(ctx, result, destinationServiceID, envelope.GetServerTimestamp()) + err = cli.handleDecryptedResult(ctx, result, envelope, destinationServiceID) if err != nil { - log.Err(err).Msg("handleDecryptedResult error") + log.Err(err).Msg("Error handling decrypted result") return nil, err } @@ -307,17 +306,17 @@ func (cli *Client) decryptEnvelope( destinationServiceID, err := libsignalgo.ServiceIDFromString(envelope.GetDestinationServiceId()) if err != nil { log.Err(err).Str("destination_service_id", envelope.GetDestinationServiceId()).Msg("Failed to parse destination service ID") - return DecryptionResult{Err: err, Urgent: envelope.GetUrgent()} + return DecryptionResult{Err: fmt.Errorf("failed to parse destination service ID: %w", err)} } - var result *DecryptionResult switch *envelope.Type { case signalpb.Envelope_UNIDENTIFIED_SENDER: - result, err = cli.decryptUnidentifiedSenderEnvelope(ctx, destinationServiceID, envelope) + result, err := cli.decryptUnidentifiedSenderEnvelope(ctx, destinationServiceID, envelope) if err != nil { - log.Err(err).Msg("decryptUnidentifiedSenderEnvelope error") - return DecryptionResult{Err: err, Urgent: envelope.GetUrgent()} + log.Err(err).Msg("Failed to decrypt sealed sender message") + result.Err = fmt.Errorf("failed to decrypt unidentified sender envelope: %w", err) } + return result case signalpb.Envelope_PREKEY_BUNDLE: sender, err := libsignalgo.NewUUIDAddressFromString( @@ -325,44 +324,50 @@ func (cli *Client) decryptEnvelope( uint(*envelope.SourceDevice), ) if err != nil { - return DecryptionResult{Err: fmt.Errorf("NewAddress error: %v", err), Urgent: envelope.GetUrgent()} + return DecryptionResult{Err: fmt.Errorf("failed to wrap address: %v", err)} } - result, err = cli.prekeyDecrypt(ctx, destinationServiceID, sender, envelope.Content) + result, err := cli.prekeyDecrypt(ctx, destinationServiceID, sender, envelope.Content) if err != nil { - log.Err(err).Msg("Prekey bundle decryption error") - } else { - log.Trace(). - Any("sender_address", result.SenderAddress). - Any("content", result.Content). - Msg("Prekey bundle decryption result") + log.Err(err).Msg("Failed to decrypt prekey bundle message") + return DecryptionResult{Err: fmt.Errorf("failed to decrypt prekey bundle envelope: %w", err), SenderAddress: sender} } + log.Trace(). + Any("sender_address", result.SenderAddress). + Any("content", result.Content). + Msg("Prekey bundle decryption result") + return *result case signalpb.Envelope_PLAINTEXT_CONTENT: + return DecryptionResult{Err: fmt.Errorf("plaintext messages are not supported")} case signalpb.Envelope_CIPHERTEXT: - message, err := libsignalgo.DeserializeMessage(envelope.Content) - if err != nil { - log.Err(err).Msg("DeserializeMessage error") - } senderAddress, err := libsignalgo.NewUUIDAddressFromString( *envelope.SourceServiceId, uint(*envelope.SourceDevice), ) if err != nil { - return DecryptionResult{Err: fmt.Errorf("NewAddress error: %v", err), Urgent: envelope.GetUrgent()} + return DecryptionResult{Err: fmt.Errorf("failed to wrap address: %w", err)} + } + message, err := libsignalgo.DeserializeMessage(envelope.Content) + if err != nil { + log.Err(err).Msg("Failed to deserialize ciphertext message") + return DecryptionResult{ + Err: fmt.Errorf("failed to deserialize message: %w", err), + SenderAddress: senderAddress, + } } sessionStore := cli.Store.SessionStore(destinationServiceID) if sessionStore == nil { return DecryptionResult{ - Err: fmt.Errorf("no session store for destination service ID %s", destinationServiceID), - Urgent: envelope.GetUrgent(), + Err: fmt.Errorf("no session store for destination service ID %s", destinationServiceID), + SenderAddress: senderAddress, } } identityStore := cli.Store.IdentityStore(destinationServiceID) if identityStore == nil { return DecryptionResult{ - Err: fmt.Errorf("no identity store for destination service ID %s", destinationServiceID), - Urgent: envelope.GetUrgent(), + Err: fmt.Errorf("no identity store for destination service ID %s", destinationServiceID), + SenderAddress: senderAddress, } } decryptedText, err := libsignalgo.Decrypt( @@ -374,105 +379,93 @@ func (cli *Client) decryptEnvelope( ) if err != nil { if strings.Contains(err.Error(), "message with old counter") { - log.Info().Msg("Duplicate message, ignoring") + log.Warn().Err(err).Msg("Duplicate message error while decrypting whisper ciphertext") } else { - log.Err(err).Msg("Whisper Decryption error") - } - } else { - err = stripPadding(&decryptedText) - if err != nil { - return DecryptionResult{Err: fmt.Errorf("stripPadding error: %v", err), Urgent: envelope.GetUrgent()} - } - content := signalpb.Content{} - err = proto.Unmarshal(decryptedText, &content) - if err != nil { - log.Err(err).Msg("Unmarshal error") - } - result = &DecryptionResult{ - SenderAddress: senderAddress, - Content: &content, + log.Err(err).Msg("Failed to decrypt whisper ciphertext message") } + return DecryptionResult{Err: fmt.Errorf("failed to decrypt ciphertext message: %w", err), SenderAddress: senderAddress} + } + err = stripPadding(&decryptedText) + if err != nil { + return DecryptionResult{Err: fmt.Errorf("failed to strip padding: %w", err), SenderAddress: senderAddress} + } + content := signalpb.Content{} + err = proto.Unmarshal(decryptedText, &content) + if err != nil { + return DecryptionResult{Err: fmt.Errorf("failed to unmarshal decrypted message: %w", err), SenderAddress: senderAddress} + } + return DecryptionResult{ + SenderAddress: senderAddress, + Content: &content, } case signalpb.Envelope_RECEIPT: - log.Warn().Msg("Received RECEIPT envelope, not yet implemented") - // TODO: handle receipt + return DecryptionResult{Err: fmt.Errorf("receipt envelopes are not yet supported")} case signalpb.Envelope_KEY_EXCHANGE: - log.Warn().Msg("Received KEY_EXCHANGE envelope, not supported") + return DecryptionResult{Err: fmt.Errorf("key exchange envelopes are not yet supported")} case signalpb.Envelope_UNKNOWN: - log.Warn().Msg("Received UNKNOWN envelope, not supported") + return DecryptionResult{Err: fmt.Errorf("unknown envelope type")} default: - log.Warn().Msg("Received actual unknown envelope type") + return DecryptionResult{Err: fmt.Errorf("unrecognized envelope type")} } - if result == nil { - log.Warn().Msg("Decryption result is nil") - return DecryptionResult{ - Err: fmt.Errorf("decryption result is nil"), - Urgent: envelope.GetUrgent(), - } - } - result.Urgent = envelope.GetUrgent() - return *result } -func (cli *Client) decryptUnidentifiedSenderEnvelope(ctx context.Context, destinationServiceID libsignalgo.ServiceID, envelope *signalpb.Envelope) (*DecryptionResult, error) { +func (cli *Client) decryptUnidentifiedSenderEnvelope(ctx context.Context, destinationServiceID libsignalgo.ServiceID, envelope *signalpb.Envelope) (result DecryptionResult, err error) { log := zerolog.Ctx(ctx) - var result *DecryptionResult if destinationServiceID != cli.Store.ACIServiceID() { log.Warn().Stringer("destination_service_id", destinationServiceID). Msg("Received UNIDENTIFIED_SENDER envelope for non-ACI destination") - // Return nil, nil to skip the rest of the handling and return 200 OK to the server - return nil, nil + return result, fmt.Errorf("received unidentified sender envelope for non-ACI destination") } usmc, err := libsignalgo.SealedSenderDecryptToUSMC( ctx, envelope.GetContent(), cli.Store.ACIIdentityStore, ) - if err != nil || usmc == nil { - if err == nil { - err = fmt.Errorf("usmc is nil") - } - log.Err(err).Msg("SealedSenderDecryptToUSMC error") - return nil, err + if err != nil { + return result, fmt.Errorf("failed to decrypt to USMC: %w", err) + } else if usmc == nil { + return result, fmt.Errorf("decrypting to USMC returned nil") } messageType, err := usmc.GetMessageType() if err != nil { - log.Err(err).Msg("GetMessageType error") + return result, fmt.Errorf("failed to get message type: %w", err) } senderCertificate, err := usmc.GetSenderCertificate() if err != nil { - log.Err(err).Msg("GetSenderCertificate error") + return result, fmt.Errorf("failed to get sender certificate: %w", err) } senderUUID, err := senderCertificate.GetSenderUUID() if err != nil { - log.Err(err).Msg("GetSenderUUID error") + return result, fmt.Errorf("failed to get sender UUID: %w", err) } senderDeviceID, err := senderCertificate.GetDeviceID() if err != nil { - log.Err(err).Msg("GetDeviceID error") + return result, fmt.Errorf("failed to get sender device ID: %w", err) } senderAddress, err := libsignalgo.NewACIServiceID(senderUUID).Address(uint(senderDeviceID)) if err != nil { - log.Err(err).Msg("NewAddress error") + return result, fmt.Errorf("failed to create sender address: %w", err) } + result.SenderAddress = senderAddress senderE164, err := senderCertificate.GetSenderE164() if err != nil { - log.Err(err).Msg("GetSenderE164 error") + return result, fmt.Errorf("failed to get sender E164: %w", err) } usmcContents, err := usmc.GetContents() if err != nil { - log.Err(err).Msg("GetContents error") + return result, fmt.Errorf("failed to get USMC contents: %w", err) } newLog := log.With(). Stringer("sender_uuid", senderUUID). Uint32("sender_device_id", senderDeviceID). Str("sender_e164", senderE164). + Uint8("sealed_sender_type", uint8(messageType)). Logger() log = &newLog ctx = log.WithContext(ctx) @@ -487,7 +480,6 @@ func (cli *Client) decryptUnidentifiedSenderEnvelope(ctx context.Context, destin switch messageType { case libsignalgo.CiphertextMessageTypeSenderKey: - log.Trace().Msg("SealedSender messageType is CiphertextMessageTypeSenderKey") decryptedText, err := libsignalgo.GroupDecrypt( ctx, usmcContents, @@ -496,39 +488,37 @@ func (cli *Client) decryptUnidentifiedSenderEnvelope(ctx context.Context, destin ) if err != nil { if strings.Contains(err.Error(), "message with old counter") { - log.Warn().Msg("Duplicate message, ignoring") - } else { - log.Err(err).Msg("GroupDecrypt error") - } - } else { - err = stripPadding(&decryptedText) - if err != nil { - return nil, fmt.Errorf("stripPadding error: %v", err) - } - content := signalpb.Content{} - err = proto.Unmarshal(decryptedText, &content) - if err != nil { - log.Err(err).Msg("Unmarshal error") - } - result = &DecryptionResult{ - SenderAddress: senderAddress, - Content: &content, - SealedSender: true, + log.Warn().Err(err).Msg("Duplicate message error while decrypting sealed sender sender key") + return result, err } + log.Err(err).Msg("Failed to decrypt sealed sender sender key message, trying generic function") + return cli.fallbackDecryptSealedSender(ctx, result, envelope) } + err = stripPadding(&decryptedText) + if err != nil { + return result, fmt.Errorf("failed to strip padding: %w", err) + } + content := signalpb.Content{} + err = proto.Unmarshal(decryptedText, &content) + if err != nil { + return result, fmt.Errorf("failed to unmarshal decrypted sender key message: %w", err) + } + result.Content = &content + return result, nil case libsignalgo.CiphertextMessageTypePreKey: - log.Trace().Msg("SealedSender messageType is CiphertextMessageTypePreKey") - result, err = cli.prekeyDecrypt(ctx, destinationServiceID, senderAddress, usmcContents) + var resultPtr *DecryptionResult + resultPtr, err = cli.prekeyDecrypt(ctx, destinationServiceID, senderAddress, usmcContents) if err != nil { - log.Err(err).Msg("Sealed sender prekey ciphertext decryption error") + log.Err(err).Msg("Failed to decrypt sealed sender prekey message, trying generic function") + return cli.fallbackDecryptSealedSender(ctx, result, envelope) } + return *resultPtr, nil case libsignalgo.CiphertextMessageTypeWhisper: - log.Trace().Msg("SealedSender messageType is CiphertextMessageTypeWhisper") message, err := libsignalgo.DeserializeMessage(usmcContents) if err != nil { - log.Err(err).Msg("Sealed sender whisper deserialize error") + return result, fmt.Errorf("failed to deserialize whisper message: %w", err) } decryptedText, err := libsignalgo.Decrypt( ctx, @@ -538,26 +528,23 @@ func (cli *Client) decryptUnidentifiedSenderEnvelope(ctx context.Context, destin cli.Store.ACIIdentityStore, ) if err != nil { - log.Err(err).Msg("Sealed sender whisper decryption error") - } else { - err = stripPadding(&decryptedText) - if err != nil { - return nil, fmt.Errorf("stripPadding error: %v", err) - } - content := signalpb.Content{} - err = proto.Unmarshal(decryptedText, &content) - if err != nil { - log.Err(err).Msg("Unmarshal error") - } - result = &DecryptionResult{ - SenderAddress: senderAddress, - Content: &content, - SealedSender: true, - } + log.Err(err).Msg("Failed to decrypt whisper message, trying generic function") + return cli.fallbackDecryptSealedSender(ctx, result, envelope) } + err = stripPadding(&decryptedText) + if err != nil { + return result, fmt.Errorf("failed to strip padding: %w", err) + } + content := signalpb.Content{} + err = proto.Unmarshal(decryptedText, &content) + if err != nil { + return result, fmt.Errorf("failed to unmarshal decrypted whisper message: %w", err) + } + result.Content = &content + return result, nil case libsignalgo.CiphertextMessageTypePlaintext: - log.Debug().Msg("SealedSender messageType is CiphertextMessageTypePlaintext") + log.Warn().Msg("Unsupported plaintext sealed sender message") // TODO: handle plaintext (usually DecryptionErrorMessage) and retries // when implementing SenderKey groups @@ -580,47 +567,42 @@ func (cli *Client) decryptUnidentifiedSenderEnvelope(ctx context.Context, destin // SealedSender: true, //} - return nil, nil + return result, fmt.Errorf("plaintext sealed sender messages are not supported") default: - log.Warn().Msg("SealedSender messageType is unknown") + log.Warn().Msg("Unrecognized sealed sender message type") + return cli.fallbackDecryptSealedSender(ctx, result, envelope) } +} - // If we couldn't decrypt with specific decryption methods, try sealedSenderDecrypt - if result == nil { - log.Debug().Msg("Didn't decrypt with specific methods, trying sealedSenderDecrypt") - var err error - result, err = cli.sealedSenderDecrypt(ctx, envelope) - if err != nil { - if strings.Contains(err.Error(), "self send of a sealed sender message") { - log.Debug().Msg("Message sent by us, ignoring") - } else if strings.Contains(err.Error(), "message with old counter") { - log.Info().Msg("Duplicate message, ignoring (sealedSenderDecrypt)") - } else { - log.Err(err).Msg("sealedSenderDecrypt error") - } +func (cli *Client) fallbackDecryptSealedSender(ctx context.Context, fallbackResult DecryptionResult, envelope *signalpb.Envelope) (DecryptionResult, error) { + log := zerolog.Ctx(ctx) + result, err := cli.sealedSenderDecrypt(ctx, envelope) + if err != nil { + if strings.Contains(err.Error(), "self send of a sealed sender message") { + log.Debug().Msg("Message sent by us, ignoring") + } else if strings.Contains(err.Error(), "message with old counter") { + log.Info().Msg("Duplicate message, ignoring (sealedSenderDecrypt)") } else { - log.Trace(). - Any("sender_address", result.SenderAddress). - Any("content", result.Content). - Msg("SealedSender decrypt result") + log.Err(err).Msg("Failed to decrypt sealed sender message with fallback method") } + return fallbackResult, fmt.Errorf("failed to decrypt unrecognized sealed sender message: %w", err) } - return result, nil + log.Trace(). + Any("sender_address", result.SenderAddress). + Any("content", result.Content). + Msg("SealedSender decrypt result") + return *result, nil } // TODO: we should split this up into multiple functions func (cli *Client) handleDecryptedResult( ctx context.Context, result DecryptionResult, + envelope *signalpb.Envelope, destinationServiceID libsignalgo.ServiceID, - serverTimestamp uint64, ) error { log := zerolog.Ctx(ctx) - if result.Content == nil { - log.Warn().Msg("Decrypted content is nil") - return nil - } // result.Err is set if there was an error during decryption and we // should notifiy the user that the message could not be decrypted @@ -631,21 +613,29 @@ func (cli *Client) handleDecryptedResult( } else if theirServiceID.Type != libsignalgo.ServiceIDTypeACI { log.Warn().Any("their_service_id", theirServiceID).Msg("Sender ServiceID is not an ACI") } - log.Err(result.Err).Stringer("sender", theirServiceID).Bool("urgent", result.Urgent).Msg("Decryption error") + log.Err(result.Err). + Stringer("sender", theirServiceID). + Bool("urgent", envelope.GetUrgent()). + Uint64("server_ts", envelope.GetServerTimestamp()). + Uint64("client_ts", envelope.GetTimestamp()). + Msg("Decryption error") // Only send decryption error event if the message was urgent, // to prevent spamming errors for typing notifications and whatnot - if result.Urgent { + if envelope.GetUrgent() { cli.handleEvent(&events.DecryptionError{ Sender: theirServiceID.UUID, Err: result.Err, - Timestamp: serverTimestamp, + Timestamp: envelope.GetTimestamp(), }) } - // Intentionally not returning here. In most cases there's nothing besides the error so - // nothing else will happen, but if there is content we still want to do what we can with it + // TODO there are probably no cases with both content and an error } content := result.Content + if content == nil { + log.Warn().Msg("Decrypted content is nil") + return nil + } name, _ := result.SenderAddress.Name() deviceId, _ := result.SenderAddress.DeviceID() @@ -1055,7 +1045,6 @@ type DecryptionResult struct { Content *signalpb.Content SealedSender bool Err error - Urgent bool } const prodServerTrustRootStr = "BXu6QIKVz5MA8gstzfOgRQGqyLqOwNKHL6INkv3IHWMF" @@ -1074,35 +1063,34 @@ func (cli *Client) sealedSenderDecrypt(ctx context.Context, envelope *signalpb.E cli.Store.ACI, uint32(cli.Store.DeviceID), ) - timestamp := time.Unix(0, int64(*envelope.Timestamp)) result, err := libsignalgo.SealedSenderDecrypt( ctx, envelope.Content, localAddress, prodServerTrustRootKey, - timestamp, + envelope.GetTimestamp(), cli.Store.ACISessionStore, cli.Store.ACIIdentityStore, cli.Store.ACIPreKeyStore, cli.Store.ACIPreKeyStore, ) if err != nil { - return nil, fmt.Errorf("SealedSenderDecrypt error: %w", err) + return nil, err } msg := result.Message err = stripPadding(&msg) if err != nil { - return nil, fmt.Errorf("stripPadding error: %w", err) + return nil, fmt.Errorf("failed to strip padding: %w", err) } address, err := libsignalgo.NewACIServiceID(result.Sender.UUID).Address(uint(result.Sender.DeviceID)) if err != nil { - return nil, fmt.Errorf("NewAddress error: %w", err) + return nil, fmt.Errorf("failed to wrap sender address: %w", err) } content := &signalpb.Content{} err = proto.Unmarshal(msg, content) if err != nil { - return nil, fmt.Errorf("Unmarshal error: %w", err) + return nil, fmt.Errorf("failed to unmarshal decrypted content: %w", err) } return &DecryptionResult{ SenderAddress: address, @@ -1141,25 +1129,21 @@ func (cli *Client) prekeyDecrypt(ctx context.Context, destination libsignalgo.Se pks, ) if err != nil { - err = fmt.Errorf("DecryptPreKey error: %v", err) - return nil, err + return nil, fmt.Errorf("failed to decrypt prekey message: %w", err) } err = stripPadding(&data) if err != nil { - err = fmt.Errorf("stripPadding error: %v", err) - return nil, err + return nil, fmt.Errorf("failed to strip padding: %w", err) } content := &signalpb.Content{} err = proto.Unmarshal(data, content) if err != nil { - err = fmt.Errorf("Unmarshal error: %v", err) - return nil, err + return nil, fmt.Errorf("failed to unmarshal decrypted prekey message: %w", err) } - DecryptionResult := &DecryptionResult{ + return &DecryptionResult{ SenderAddress: sender, Content: content, - } - return DecryptionResult, nil + }, nil } func stripPadding(contents *[]byte) error { From 58416d1d167bfef2953472b112e494c9e2e6b28c Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Mon, 9 Sep 2024 20:56:34 +0300 Subject: [PATCH 170/580] signalmeow/web: fix unnecessary NewBuffer use --- pkg/signalmeow/web/web.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/signalmeow/web/web.go b/pkg/signalmeow/web/web.go index e72570a..7bcc035 100644 --- a/pkg/signalmeow/web/web.go +++ b/pkg/signalmeow/web/web.go @@ -134,7 +134,7 @@ func SendHTTPRequest(ctx context.Context, method string, path string, opt *HTTPR Logger() ctx = log.WithContext(ctx) - req, err := http.NewRequestWithContext(ctx, method, urlStr, bytes.NewBuffer(opt.Body)) + req, err := http.NewRequestWithContext(ctx, method, urlStr, bytes.NewReader(opt.Body)) if err != nil { log.Err(err).Msg("Error creating request") return nil, err From fed58c6635874d57a0c7f0ef68037d706907d5cd Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Tue, 10 Sep 2024 13:45:22 +0300 Subject: [PATCH 171/580] handlematrix: ignore unsupported message IDs when sending read receipts --- pkg/connector/handlematrix.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/connector/handlematrix.go b/pkg/connector/handlematrix.go index fb3b1d9..a329c0c 100644 --- a/pkg/connector/handlematrix.go +++ b/pkg/connector/handlematrix.go @@ -229,7 +229,7 @@ func (s *SignalClient) HandleMatrixReadReceipt(ctx context.Context, receipt *bri for _, msg := range dbMessages { userID, timestamp, err := signalid.ParseMessageID(msg.ID) if err != nil { - return fmt.Errorf("failed to parse message ID %q: %w", msg.ID, err) + continue } messagesToRead[userID] = append(messagesToRead[userID], timestamp) } From c3ac2bc0d13fe7d2f657dc7b716e1ca259c8480c Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Tue, 10 Sep 2024 21:22:18 +0300 Subject: [PATCH 172/580] config: remove pointer --- cmd/mautrix-signal/main.go | 2 +- pkg/connector/config.go | 2 +- pkg/connector/connector.go | 8 +------- 3 files changed, 3 insertions(+), 9 deletions(-) diff --git a/cmd/mautrix-signal/main.go b/cmd/mautrix-signal/main.go index 5fe7117..93a03c7 100644 --- a/cmd/mautrix-signal/main.go +++ b/cmd/mautrix-signal/main.go @@ -40,7 +40,7 @@ var m = mxmain.BridgeMain{ Description: "A Matrix-Signal puppeting bridge.", Version: "0.7.0", - Connector: connector.NewConnector(), + Connector: &connector.SignalConnector{}, } func main() { diff --git a/pkg/connector/config.go b/pkg/connector/config.go index 0d98583..ec47f34 100644 --- a/pkg/connector/config.go +++ b/pkg/connector/config.go @@ -84,5 +84,5 @@ func upgradeConfig(helper up.Helper) { } func (s *SignalConnector) GetConfig() (string, any, up.Upgrader) { - return ExampleConfig, s.Config, up.SimpleUpgrader(upgradeConfig) + return ExampleConfig, &s.Config, up.SimpleUpgrader(upgradeConfig) } diff --git a/pkg/connector/connector.go b/pkg/connector/connector.go index bb98238..e5995ad 100644 --- a/pkg/connector/connector.go +++ b/pkg/connector/connector.go @@ -34,18 +34,12 @@ type SignalConnector struct { MsgConv *msgconv.MessageConverter Store *store.Container Bridge *bridgev2.Bridge - Config *SignalConfig + Config SignalConfig } var _ bridgev2.NetworkConnector = (*SignalConnector)(nil) var _ bridgev2.MaxFileSizeingNetwork = (*SignalConnector)(nil) -func NewConnector() *SignalConnector { - return &SignalConnector{ - Config: &SignalConfig{}, - } -} - var signalGeneralCaps = &bridgev2.NetworkGeneralCapabilities{ DisappearingMessages: true, AggressiveUpdateInfo: true, From a4301347ded63e6ccaefa5b71cd5019773608c3c Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Tue, 10 Sep 2024 22:20:44 +0300 Subject: [PATCH 173/580] signalmeow/receiving: don't panic on decryption errors with unknown sender Fixes #546 --- pkg/signalmeow/receiving.go | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/pkg/signalmeow/receiving.go b/pkg/signalmeow/receiving.go index 8a40a16..9b36b84 100644 --- a/pkg/signalmeow/receiving.go +++ b/pkg/signalmeow/receiving.go @@ -607,18 +607,21 @@ func (cli *Client) handleDecryptedResult( // result.Err is set if there was an error during decryption and we // should notifiy the user that the message could not be decrypted if result.Err != nil { + logEvt := log.Err(result.Err). + Bool("urgent", envelope.GetUrgent()). + Uint64("server_ts", envelope.GetServerTimestamp()). + Uint64("client_ts", envelope.GetTimestamp()) + if result.SenderAddress == nil { + logEvt.Msg("Decryption error with unknown sender") + return nil + } theirServiceID, err := result.SenderAddress.NameServiceID() if err != nil { log.Err(err).Msg("Name error handling decryption error") } else if theirServiceID.Type != libsignalgo.ServiceIDTypeACI { log.Warn().Any("their_service_id", theirServiceID).Msg("Sender ServiceID is not an ACI") } - log.Err(result.Err). - Stringer("sender", theirServiceID). - Bool("urgent", envelope.GetUrgent()). - Uint64("server_ts", envelope.GetServerTimestamp()). - Uint64("client_ts", envelope.GetTimestamp()). - Msg("Decryption error") + logEvt.Stringer("sender", theirServiceID).Msg("Decryption error with known sender") // Only send decryption error event if the message was urgent, // to prevent spamming errors for typing notifications and whatnot if envelope.GetUrgent() { From 53dcfc52f93649b35c592e6e74989333fd17901f Mon Sep 17 00:00:00 2001 From: Brad Murray Date: Thu, 12 Sep 2024 07:18:15 -0400 Subject: [PATCH 174/580] legacyprovision: fix start new chat for Beeper iOS clients (#547) --- .gitignore | 2 ++ cmd/mautrix-signal/legacyprovision.go | 5 +++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/.gitignore b/.gitignore index ab00deb..7766014 100644 --- a/.gitignore +++ b/.gitignore @@ -8,3 +8,5 @@ /mautrix-signal /start /libsignal_ffi.a + +.idea diff --git a/cmd/mautrix-signal/legacyprovision.go b/cmd/mautrix-signal/legacyprovision.go index 013d1bd..43d6947 100644 --- a/cmd/mautrix-signal/legacyprovision.go +++ b/cmd/mautrix-signal/legacyprovision.go @@ -215,7 +215,8 @@ func legacyResolveIdentifierOrStartChat(w http.ResponseWriter, r *http.Request, return } api := login.Client.(bridgev2.IdentifierResolvingNetworkAPI) - resp, err := api.ResolveIdentifier(r.Context(), mux.Vars(r)["phonenum"], create) + phonenum := mux.Vars(r)["phonenum"] + resp, err := api.ResolveIdentifier(r.Context(), phonenum, create) if err != nil { zerolog.Ctx(r.Context()).Err(err).Msg("Failed to resolve identifier") JSONResponse(w, http.StatusInternalServerError, &Error{ @@ -234,7 +235,7 @@ func legacyResolveIdentifierOrStartChat(w http.ResponseWriter, r *http.Request, apiResp := &ResolveIdentifierResponse{ ChatID: ResolveIdentifierResponseChatID{ UUID: string(resp.UserID), - Number: "", + Number: phonenum, }, } if resp.Ghost != nil { From ac5fc5fb115ceca8ea3113c1807a025cf1a8c76d Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Fri, 13 Sep 2024 12:23:03 +0300 Subject: [PATCH 175/580] libsignal: update to v0.57.1 --- pkg/libsignalgo/libsignal | 2 +- pkg/libsignalgo/libsignal-ffi.h | 42 +++++++++++++++++---------------- pkg/libsignalgo/version.go | 2 +- 3 files changed, 24 insertions(+), 22 deletions(-) diff --git a/pkg/libsignalgo/libsignal b/pkg/libsignalgo/libsignal index e46841e..3917f60 160000 --- a/pkg/libsignalgo/libsignal +++ b/pkg/libsignalgo/libsignal @@ -1 +1 @@ -Subproject commit e46841ea2c1ad03bc5113eba267ac1543689d031 +Subproject commit 3917f60919a987573e0599d414bb5d9d6f155fe4 diff --git a/pkg/libsignalgo/libsignal-ffi.h b/pkg/libsignalgo/libsignal-ffi.h index c089648..3ed14d2 100644 --- a/pkg/libsignalgo/libsignal-ffi.h +++ b/pkg/libsignalgo/libsignal-ffi.h @@ -175,26 +175,28 @@ typedef enum { SignalErrorCodeUsernameTooLong = 126, SignalErrorCodeUsernameLinkInvalidEntropyDataLength = 127, SignalErrorCodeUsernameLinkInvalid = 128, - SignalErrorCodeUsernameDiscriminatorCannotBeEmpty = 140, - SignalErrorCodeUsernameDiscriminatorCannotBeZero = 141, - SignalErrorCodeUsernameDiscriminatorCannotBeSingleDigit = 142, - SignalErrorCodeUsernameDiscriminatorCannotHaveLeadingZeros = 143, - SignalErrorCodeUsernameDiscriminatorTooLarge = 144, - SignalErrorCodeIoError = 130, - SignalErrorCodeInvalidMediaInput = 131, - SignalErrorCodeUnsupportedMediaInput = 132, - SignalErrorCodeConnectionTimedOut = 133, - SignalErrorCodeNetworkProtocol = 134, - SignalErrorCodeRateLimited = 135, - SignalErrorCodeWebSocket = 136, - SignalErrorCodeCdsiInvalidToken = 137, - SignalErrorCodeConnectionFailed = 138, - SignalErrorCodeChatServiceInactive = 139, - SignalErrorCodeSvrDataMissing = 150, - SignalErrorCodeSvrRestoreFailed = 151, - SignalErrorCodeAppExpired = 160, - SignalErrorCodeDeviceDeregistered = 161, - SignalErrorCodeBackupValidation = 170, + SignalErrorCodeUsernameDiscriminatorCannotBeEmpty = 130, + SignalErrorCodeUsernameDiscriminatorCannotBeZero = 131, + SignalErrorCodeUsernameDiscriminatorCannotBeSingleDigit = 132, + SignalErrorCodeUsernameDiscriminatorCannotHaveLeadingZeros = 133, + SignalErrorCodeUsernameDiscriminatorTooLarge = 134, + SignalErrorCodeIoError = 140, + SignalErrorCodeInvalidMediaInput = 141, + SignalErrorCodeUnsupportedMediaInput = 142, + SignalErrorCodeConnectionTimedOut = 143, + SignalErrorCodeNetworkProtocol = 144, + SignalErrorCodeRateLimited = 145, + SignalErrorCodeWebSocket = 146, + SignalErrorCodeCdsiInvalidToken = 147, + SignalErrorCodeConnectionFailed = 148, + SignalErrorCodeChatServiceInactive = 149, + SignalErrorCodeChatServiceIntentionallyDisconnected = 150, + SignalErrorCodeSvrDataMissing = 160, + SignalErrorCodeSvrRestoreFailed = 161, + SignalErrorCodeSvrRotationMachineTooManySteps = 162, + SignalErrorCodeAppExpired = 170, + SignalErrorCodeDeviceDeregistered = 171, + SignalErrorCodeBackupValidation = 180, } SignalErrorCode; /** diff --git a/pkg/libsignalgo/version.go b/pkg/libsignalgo/version.go index e36a12a..c8272f5 100644 --- a/pkg/libsignalgo/version.go +++ b/pkg/libsignalgo/version.go @@ -2,4 +2,4 @@ package libsignalgo -const Version = "v0.56.1" +const Version = "v0.57.1" From 2ab0e9e4fe8fd6d71b27a98f9e74624c2dc21ad8 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Fri, 13 Sep 2024 12:24:50 +0300 Subject: [PATCH 176/580] dependencies: update --- go.mod | 14 ++++++++------ go.sum | 20 ++++++++++---------- 2 files changed, 18 insertions(+), 16 deletions(-) diff --git a/go.mod b/go.mod index 664b59e..b8ef281 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,8 @@ module go.mau.fi/mautrix-signal -go 1.22 +go 1.22.0 + +toolchain go1.23.1 require ( github.com/emersion/go-vcard v0.0.0-20230815062825-8fda7d206ec9 @@ -10,12 +12,12 @@ require ( github.com/rs/zerolog v1.33.0 github.com/stretchr/testify v1.9.0 github.com/tidwall/gjson v1.17.3 - go.mau.fi/util v0.7.1-0.20240904173517-ca3b3fe376c2 - golang.org/x/crypto v0.26.0 - golang.org/x/exp v0.0.0-20240823005443-9b4947da3948 - golang.org/x/net v0.28.0 + go.mau.fi/util v0.7.1-0.20240913091524-7617daa66719 + golang.org/x/crypto v0.27.0 + golang.org/x/exp v0.0.0-20240909161429-701f63a606c0 + golang.org/x/net v0.29.0 google.golang.org/protobuf v1.34.2 - maunium.net/go/mautrix v0.20.1-0.20240906105454-33d724bf4c78 + maunium.net/go/mautrix v0.20.1-0.20240913091647-96e68fb485d2 nhooyr.io/websocket v1.8.17 ) diff --git a/go.sum b/go.sum index 1f7751c..16e07ab 100644 --- a/go.sum +++ b/go.sum @@ -65,16 +65,16 @@ github.com/tidwall/sjson v1.2.5 h1:kLy8mja+1c9jlljvWTlSazM7cKDRfJuR/bOJhcY5NcY= github.com/tidwall/sjson v1.2.5/go.mod h1:Fvgq9kS/6ociJEDnK0Fk1cpYF4FIW6ZF7LAe+6jwd28= github.com/yuin/goldmark v1.7.4 h1:BDXOHExt+A7gwPCJgPIIq7ENvceR7we7rOS9TNoLZeg= github.com/yuin/goldmark v1.7.4/go.mod h1:uzxRWxtg69N339t3louHJ7+O03ezfj6PlliRlaOzY1E= -go.mau.fi/util v0.7.1-0.20240904173517-ca3b3fe376c2 h1:VZQlKBbeJ7KOlYSh6BnN5uWQTY/ypn/bJv0YyEd+pXc= -go.mau.fi/util v0.7.1-0.20240904173517-ca3b3fe376c2/go.mod h1:WgYvbt9rVmoFeajP97NunQU7AjgvTPiNExN3oTHeePs= +go.mau.fi/util v0.7.1-0.20240913091524-7617daa66719 h1:sg1P/f4RHY1JuAwsPOjTCsZr8ROzR9bRTtnvvBu42d4= +go.mau.fi/util v0.7.1-0.20240913091524-7617daa66719/go.mod h1:1Ixb8HWoVbl3rT6nAX6nV4iMkzn7KU/KXwE0Rn5RmsQ= go.mau.fi/zeroconfig v0.1.3 h1:As9wYDKmktjmNZW5i1vn8zvJlmGKHeVxHVIBMXsm4kM= go.mau.fi/zeroconfig v0.1.3/go.mod h1:NcSJkf180JT+1IId76PcMuLTNa1CzsFFZ0nBygIQM70= -golang.org/x/crypto v0.26.0 h1:RrRspgV4mU+YwB4FYnuBoKsUapNIL5cohGAmSH3azsw= -golang.org/x/crypto v0.26.0/go.mod h1:GY7jblb9wI+FOo5y8/S2oY4zWP07AkOJ4+jxCqdqn54= -golang.org/x/exp v0.0.0-20240823005443-9b4947da3948 h1:kx6Ds3MlpiUHKj7syVnbp57++8WpuKPcR5yjLBjvLEA= -golang.org/x/exp v0.0.0-20240823005443-9b4947da3948/go.mod h1:akd2r19cwCdwSwWeIdzYQGa/EZZyqcOdwWiwj5L5eKQ= -golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE= -golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg= +golang.org/x/crypto v0.27.0 h1:GXm2NjJrPaiv/h1tb2UH8QfgC/hOf/+z0p6PT8o1w7A= +golang.org/x/crypto v0.27.0/go.mod h1:1Xngt8kV6Dvbssa53Ziq6Eqn0HqbZi5Z6R0ZpwQzt70= +golang.org/x/exp v0.0.0-20240909161429-701f63a606c0 h1:e66Fs6Z+fZTbFBAxKfP3PALWBtpfqks2bwGcexMxgtk= +golang.org/x/exp v0.0.0-20240909161429-701f63a606c0/go.mod h1:2TbTHSBQa924w8M6Xs1QcRcFwyucIwBGpK1p2f1YFFY= +golang.org/x/net v0.29.0 h1:5ORfpBpCs4HzDYoodCDBbwHzdR5UrLBZ3sOnUJmFoHo= +golang.org/x/net v0.29.0/go.mod h1:gLkgy8jTGERgjzMic6DS9+SP0ajcu6Xu3Orq/SpETg0= golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -95,7 +95,7 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= maunium.net/go/mauflag v1.0.0 h1:YiaRc0tEI3toYtJMRIfjP+jklH45uDHtT80nUamyD4M= maunium.net/go/mauflag v1.0.0/go.mod h1:nLivPOpTpHnpzEh8jEdSL9UqO9+/KBJFmNRlwKfkPeA= -maunium.net/go/mautrix v0.20.1-0.20240906105454-33d724bf4c78 h1:F8ls6UNW8QlTpQ2QAnPuCN5gVB30Y3ojBYfXb9T6U64= -maunium.net/go/mautrix v0.20.1-0.20240906105454-33d724bf4c78/go.mod h1:l6nYvD5/FMSrAZ/IP1AqJV0b47SRl/0uQNRiy4CcSVk= +maunium.net/go/mautrix v0.20.1-0.20240913091647-96e68fb485d2 h1:po9hbdGRCQq2Sb3+f5ED/TxA1RpUstmwRLTyX4ecjW4= +maunium.net/go/mautrix v0.20.1-0.20240913091647-96e68fb485d2/go.mod h1:amzKPIZVO7v1piD2JhKG1RvGZoV+5wEZfoHaEXOjjqA= nhooyr.io/websocket v1.8.17 h1:KEVeLJkUywCKVsnLIDlD/5gtayKp8VoCkksHCGGfT9Y= nhooyr.io/websocket v1.8.17/go.mod h1:rN9OFWIUwuxg4fR5tELlYC04bXYowCP9GX47ivo2l+c= From 4ede5dc9e183a7703468c0207af7ce4db73f3d67 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Fri, 13 Sep 2024 12:27:26 +0300 Subject: [PATCH 177/580] dependencies: switch to new import path for websocket library --- go.mod | 2 +- go.sum | 4 ++-- pkg/signalmeow/contactdiscovery.go | 2 +- pkg/signalmeow/provisioning.go | 2 +- pkg/signalmeow/web/signalwebsocket.go | 2 +- pkg/signalmeow/wspb/wspb.go | 2 +- 6 files changed, 7 insertions(+), 7 deletions(-) diff --git a/go.mod b/go.mod index b8ef281..5f8253b 100644 --- a/go.mod +++ b/go.mod @@ -5,6 +5,7 @@ go 1.22.0 toolchain go1.23.1 require ( + github.com/coder/websocket v1.8.12 github.com/emersion/go-vcard v0.0.0-20230815062825-8fda7d206ec9 github.com/google/uuid v1.6.0 github.com/gorilla/mux v1.8.0 @@ -18,7 +19,6 @@ require ( golang.org/x/net v0.29.0 google.golang.org/protobuf v1.34.2 maunium.net/go/mautrix v0.20.1-0.20240913091647-96e68fb485d2 - nhooyr.io/websocket v1.8.17 ) require ( diff --git a/go.sum b/go.sum index 16e07ab..feffeab 100644 --- a/go.sum +++ b/go.sum @@ -2,6 +2,8 @@ filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA= filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4= github.com/DATA-DOG/go-sqlmock v1.5.2 h1:OcvFkGmslmlZibjAjaHm3L//6LiuBgolP7OputlJIzU= github.com/DATA-DOG/go-sqlmock v1.5.2/go.mod h1:88MAG/4G7SMwSE3CeA0ZKzrT5CiOU3OJ+JlNzwDqpNU= +github.com/coder/websocket v1.8.12 h1:5bUXkEPPIbewrnkU8LTCLVaxi4N4J8ahufH2vlo4NAo= +github.com/coder/websocket v1.8.12/go.mod h1:LNVeNrXQZfe5qhS9ALED3uA+l5pPqvwXg3CKoDBB2gs= github.com/coreos/go-systemd/v22 v22.5.0 h1:RrqgGjYQKalulkV8NGVIfkXQf6YYmOyiJKk8iXXhfZs= github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= @@ -97,5 +99,3 @@ maunium.net/go/mauflag v1.0.0 h1:YiaRc0tEI3toYtJMRIfjP+jklH45uDHtT80nUamyD4M= maunium.net/go/mauflag v1.0.0/go.mod h1:nLivPOpTpHnpzEh8jEdSL9UqO9+/KBJFmNRlwKfkPeA= maunium.net/go/mautrix v0.20.1-0.20240913091647-96e68fb485d2 h1:po9hbdGRCQq2Sb3+f5ED/TxA1RpUstmwRLTyX4ecjW4= maunium.net/go/mautrix v0.20.1-0.20240913091647-96e68fb485d2/go.mod h1:amzKPIZVO7v1piD2JhKG1RvGZoV+5wEZfoHaEXOjjqA= -nhooyr.io/websocket v1.8.17 h1:KEVeLJkUywCKVsnLIDlD/5gtayKp8VoCkksHCGGfT9Y= -nhooyr.io/websocket v1.8.17/go.mod h1:rN9OFWIUwuxg4fR5tELlYC04bXYowCP9GX47ivo2l+c= diff --git a/pkg/signalmeow/contactdiscovery.go b/pkg/signalmeow/contactdiscovery.go index 660439c..b732339 100644 --- a/pkg/signalmeow/contactdiscovery.go +++ b/pkg/signalmeow/contactdiscovery.go @@ -27,12 +27,12 @@ import ( "sync" "time" + "github.com/coder/websocket" "github.com/google/uuid" "github.com/rs/zerolog" "github.com/tidwall/gjson" "go.mau.fi/util/exerrors" "google.golang.org/protobuf/proto" - "nhooyr.io/websocket" "go.mau.fi/mautrix-signal/pkg/libsignalgo" signalpb "go.mau.fi/mautrix-signal/pkg/signalmeow/protobuf" diff --git a/pkg/signalmeow/provisioning.go b/pkg/signalmeow/provisioning.go index 5c09457..213c246 100644 --- a/pkg/signalmeow/provisioning.go +++ b/pkg/signalmeow/provisioning.go @@ -26,12 +26,12 @@ import ( "net/url" "time" + "github.com/coder/websocket" "github.com/google/uuid" "github.com/rs/zerolog" "go.mau.fi/util/exerrors" "go.mau.fi/util/random" "google.golang.org/protobuf/proto" - "nhooyr.io/websocket" "go.mau.fi/mautrix-signal/pkg/libsignalgo" signalpb "go.mau.fi/mautrix-signal/pkg/signalmeow/protobuf" diff --git a/pkg/signalmeow/web/signalwebsocket.go b/pkg/signalmeow/web/signalwebsocket.go index 8b9698b..986e17c 100644 --- a/pkg/signalmeow/web/signalwebsocket.go +++ b/pkg/signalmeow/web/signalwebsocket.go @@ -25,8 +25,8 @@ import ( "strings" "time" + "github.com/coder/websocket" "github.com/rs/zerolog" - "nhooyr.io/websocket" signalpb "go.mau.fi/mautrix-signal/pkg/signalmeow/protobuf" "go.mau.fi/mautrix-signal/pkg/signalmeow/wspb" diff --git a/pkg/signalmeow/wspb/wspb.go b/pkg/signalmeow/wspb/wspb.go index c58628f..2c2ccd8 100644 --- a/pkg/signalmeow/wspb/wspb.go +++ b/pkg/signalmeow/wspb/wspb.go @@ -8,8 +8,8 @@ import ( "fmt" "sync" + "github.com/coder/websocket" "google.golang.org/protobuf/proto" - "nhooyr.io/websocket" ) // Read reads a protobuf message from c into v. From adee82100658dcdf7ad37372ac122ce1b5788cb6 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Fri, 13 Sep 2024 12:32:04 +0300 Subject: [PATCH 178/580] msgconv/matrixfmt: fix trimming space from whitespace-only string --- pkg/msgconv/matrixfmt/convert_test.go | 7 +++++++ pkg/msgconv/matrixfmt/html.go | 14 +++++++++----- 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/pkg/msgconv/matrixfmt/convert_test.go b/pkg/msgconv/matrixfmt/convert_test.go index 240ca98..1ade316 100644 --- a/pkg/msgconv/matrixfmt/convert_test.go +++ b/pkg/msgconv/matrixfmt/convert_test.go @@ -65,6 +65,13 @@ func TestParse_HTML(t *testing.T) { Length: 5, Value: signalfmt.StyleBold, }}}, + {name: "UnnecessaryWhitespace", in: " Hello , World!", out: "Hello, World!", ent: signalfmt.BodyRangeList{{ + Start: 0, + Length: 5, + Value: signalfmt.StyleBold, + }}}, + {name: "UnnecessaryWhitespaceParagraph", in: "

Hello

", out: "Hello"}, + {name: "EmptyParagraph", in: "

Hello

", out: "Hello"}, { name: "MultiBasic", in: "Hello, World!", diff --git a/pkg/msgconv/matrixfmt/html.go b/pkg/msgconv/matrixfmt/html.go index 1e3d249..5c4a37f 100644 --- a/pkg/msgconv/matrixfmt/html.go +++ b/pkg/msgconv/matrixfmt/html.go @@ -81,22 +81,26 @@ func (es *EntityString) TrimSpace() *EntityString { return nil } DebugLog("TRIMSPACE %q %+v\n", es.String, es.Entities) - var cutEnd, cutStart int - for cutStart = 0; cutStart < len(es.String); cutStart++ { + cutStart := 0 + for ; cutStart < len(es.String); cutStart++ { switch es.String[cutStart] { case '\t', '\n', '\v', '\f', '\r', ' ', 0x85, 0xA0: continue } break } - for cutEnd = len(es.String) - 1; cutEnd >= 0; cutEnd-- { - switch es.String[cutEnd] { + cutEnd := len(es.String) + for ; cutEnd > cutStart; cutEnd-- { + switch es.String[cutEnd-1] { case '\t', '\n', '\v', '\f', '\r', ' ', 0x85, 0xA0: continue } break } - cutEnd++ + if cutEnd == cutStart { + DebugLog(" -> EMPTY\n") + return NewEntityString("") + } if cutStart == 0 && cutEnd == len(es.String) { DebugLog(" -> NOOP\n") return es From 1dc480b9a097d6b321267e0168055edd6c2b271b Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Fri, 13 Sep 2024 12:56:01 +0300 Subject: [PATCH 179/580] dependencies: update mautrix-go --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 5f8253b..3213204 100644 --- a/go.mod +++ b/go.mod @@ -18,7 +18,7 @@ require ( golang.org/x/exp v0.0.0-20240909161429-701f63a606c0 golang.org/x/net v0.29.0 google.golang.org/protobuf v1.34.2 - maunium.net/go/mautrix v0.20.1-0.20240913091647-96e68fb485d2 + maunium.net/go/mautrix v0.20.1-0.20240913095532-e12ecbe82d36 ) require ( diff --git a/go.sum b/go.sum index feffeab..fe10324 100644 --- a/go.sum +++ b/go.sum @@ -97,5 +97,5 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= maunium.net/go/mauflag v1.0.0 h1:YiaRc0tEI3toYtJMRIfjP+jklH45uDHtT80nUamyD4M= maunium.net/go/mauflag v1.0.0/go.mod h1:nLivPOpTpHnpzEh8jEdSL9UqO9+/KBJFmNRlwKfkPeA= -maunium.net/go/mautrix v0.20.1-0.20240913091647-96e68fb485d2 h1:po9hbdGRCQq2Sb3+f5ED/TxA1RpUstmwRLTyX4ecjW4= -maunium.net/go/mautrix v0.20.1-0.20240913091647-96e68fb485d2/go.mod h1:amzKPIZVO7v1piD2JhKG1RvGZoV+5wEZfoHaEXOjjqA= +maunium.net/go/mautrix v0.20.1-0.20240913095532-e12ecbe82d36 h1:XKDqeDfRHmgke2N16A41eOckQQqezosxaEyehG/rupM= +maunium.net/go/mautrix v0.20.1-0.20240913095532-e12ecbe82d36/go.mod h1:amzKPIZVO7v1piD2JhKG1RvGZoV+5wEZfoHaEXOjjqA= From 89373f335bea2b76da59a2c299c799d476167b43 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Fri, 13 Sep 2024 13:12:16 +0300 Subject: [PATCH 180/580] ci: don't allow go to update itself [skip cd] --- .github/workflows/go.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml index 4e0b362..76b76a1 100644 --- a/.github/workflows/go.yml +++ b/.github/workflows/go.yml @@ -2,6 +2,9 @@ name: Go on: [push, pull_request] +env: + GOTOOLCHAIN: local + jobs: lint: runs-on: ubuntu-latest From 4b7b3c5ec349198c1f16d333bce2b31b1803555f Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Sat, 14 Sep 2024 12:47:40 +0300 Subject: [PATCH 181/580] ids: add support for split portals --- go.mod | 2 +- go.sum | 4 ++-- pkg/connector/id.go | 2 +- pkg/signalid/ids.go | 7 ------- 4 files changed, 4 insertions(+), 11 deletions(-) diff --git a/go.mod b/go.mod index 3213204..fe20f9b 100644 --- a/go.mod +++ b/go.mod @@ -18,7 +18,7 @@ require ( golang.org/x/exp v0.0.0-20240909161429-701f63a606c0 golang.org/x/net v0.29.0 google.golang.org/protobuf v1.34.2 - maunium.net/go/mautrix v0.20.1-0.20240913095532-e12ecbe82d36 + maunium.net/go/mautrix v0.20.1-0.20240914094516-d89dac594db0 ) require ( diff --git a/go.sum b/go.sum index fe10324..2ada990 100644 --- a/go.sum +++ b/go.sum @@ -97,5 +97,5 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= maunium.net/go/mauflag v1.0.0 h1:YiaRc0tEI3toYtJMRIfjP+jklH45uDHtT80nUamyD4M= maunium.net/go/mauflag v1.0.0/go.mod h1:nLivPOpTpHnpzEh8jEdSL9UqO9+/KBJFmNRlwKfkPeA= -maunium.net/go/mautrix v0.20.1-0.20240913095532-e12ecbe82d36 h1:XKDqeDfRHmgke2N16A41eOckQQqezosxaEyehG/rupM= -maunium.net/go/mautrix v0.20.1-0.20240913095532-e12ecbe82d36/go.mod h1:amzKPIZVO7v1piD2JhKG1RvGZoV+5wEZfoHaEXOjjqA= +maunium.net/go/mautrix v0.20.1-0.20240914094516-d89dac594db0 h1:fTX1P8TPv+oUqHGu08jj6FYH+Q/fC9jtmvkXcAw+KTo= +maunium.net/go/mautrix v0.20.1-0.20240914094516-d89dac594db0/go.mod h1:amzKPIZVO7v1piD2JhKG1RvGZoV+5wEZfoHaEXOjjqA= diff --git a/pkg/connector/id.go b/pkg/connector/id.go index 49cebe6..16cb7dc 100644 --- a/pkg/connector/id.go +++ b/pkg/connector/id.go @@ -28,7 +28,7 @@ import ( func (s *SignalClient) makePortalKey(chatID string) networkid.PortalKey { key := networkid.PortalKey{ID: networkid.PortalID(chatID)} // For non-group chats, add receiver - if len(chatID) != 44 { + if s.Main.Bridge.Config.SplitPortals || len(chatID) != 44 { key.Receiver = s.UserLogin.ID } return key diff --git a/pkg/signalid/ids.go b/pkg/signalid/ids.go index ec002ce..79ba90f 100644 --- a/pkg/signalid/ids.go +++ b/pkg/signalid/ids.go @@ -90,13 +90,6 @@ func MakeGroupPortalID(groupID types.GroupIdentifier) networkid.PortalID { return networkid.PortalID(groupID) } -func MakeGroupPortalKey(groupID types.GroupIdentifier) networkid.PortalKey { - return networkid.PortalKey{ - ID: MakeGroupPortalID(groupID), - Receiver: "", - } -} - func MakeDMPortalID(serviceID libsignalgo.ServiceID) networkid.PortalID { return networkid.PortalID(serviceID.String()) } From 09f854e86051951755b92876de6caa396dfe1032 Mon Sep 17 00:00:00 2001 From: Malte E <97891689+maltee1@users.noreply.github.com> Date: Sat, 14 Sep 2024 12:06:37 +0200 Subject: [PATCH 182/580] groupinfo: skip unnecessary membership changes when banning (#537) --- pkg/connector/groupinfo.go | 31 +++++++++++++++++++++---------- 1 file changed, 21 insertions(+), 10 deletions(-) diff --git a/pkg/connector/groupinfo.go b/pkg/connector/groupinfo.go index d0ecdd4..843a18e 100644 --- a/pkg/connector/groupinfo.go +++ b/pkg/connector/groupinfo.go @@ -238,7 +238,22 @@ func (s *SignalClient) groupChangeToChatInfoChange(ctx context.Context, rev uint Membership: event.MembershipJoin, }) } + bannedMembers := make(map[libsignalgo.ServiceID]bool) + for _, member := range groupChange.AddBannedMembers { + aci := s.maybeResolvePNItoACI(ctx, &member.ServiceID) + if aci == nil { + continue + } + bannedMembers[member.ServiceID] = true + mc = append(mc, bridgev2.ChatMember{ + EventSender: s.makeEventSender(*aci), + Membership: event.MembershipBan, + }) + } for _, memberACI := range groupChange.DeleteMembers { + if bannedMembers[libsignalgo.NewACIServiceID(*memberACI)] { + continue + } mc = append(mc, bridgev2.ChatMember{ EventSender: s.makeEventSender(*memberACI), Membership: event.MembershipLeave, @@ -257,6 +272,9 @@ func (s *SignalClient) groupChangeToChatInfoChange(ctx context.Context, rev uint }) } for _, memberServiceID := range groupChange.DeletePendingMembers { + if bannedMembers[*memberServiceID] { + continue + } aci := s.maybeResolvePNItoACI(ctx, memberServiceID) if aci == nil { continue @@ -274,22 +292,15 @@ func (s *SignalClient) groupChangeToChatInfoChange(ctx context.Context, rev uint }) } for _, memberACI := range groupChange.DeleteRequestingMembers { + if bannedMembers[libsignalgo.NewACIServiceID(*memberACI)] { + continue + } mc = append(mc, bridgev2.ChatMember{ EventSender: s.makeEventSender(*memberACI), Membership: event.MembershipLeave, PrevMembership: event.MembershipKnock, }) } - for _, member := range groupChange.AddBannedMembers { - aci := s.maybeResolvePNItoACI(ctx, &member.ServiceID) - if aci == nil { - continue - } - mc = append(mc, bridgev2.ChatMember{ - EventSender: s.makeEventSender(*aci), - Membership: event.MembershipBan, - }) - } for _, memberServiceID := range groupChange.DeleteBannedMembers { aci := s.maybeResolvePNItoACI(ctx, memberServiceID) if aci == nil { From 99ecf9fa6c6c76491aa580478c6395adfe2cebff Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Sat, 14 Sep 2024 14:33:54 +0300 Subject: [PATCH 183/580] dependencies: update mautrix-go --- cmd/mautrix-signal/main.go | 2 +- go.mod | 2 +- go.sum | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/cmd/mautrix-signal/main.go b/cmd/mautrix-signal/main.go index 93a03c7..280e97f 100644 --- a/cmd/mautrix-signal/main.go +++ b/cmd/mautrix-signal/main.go @@ -51,7 +51,7 @@ func main() { 20, "v0.5.1", "v0.7.0", - m.LegacyMigrateSimple(legacyMigrateRenameTables, legacyMigrateCopyData, 14), + m.LegacyMigrateSimple(legacyMigrateRenameTables, legacyMigrateCopyData, 18), true, ) } diff --git a/go.mod b/go.mod index fe20f9b..e8bf58a 100644 --- a/go.mod +++ b/go.mod @@ -18,7 +18,7 @@ require ( golang.org/x/exp v0.0.0-20240909161429-701f63a606c0 golang.org/x/net v0.29.0 google.golang.org/protobuf v1.34.2 - maunium.net/go/mautrix v0.20.1-0.20240914094516-d89dac594db0 + maunium.net/go/mautrix v0.20.1-0.20240914113211-d86913bd5c51 ) require ( diff --git a/go.sum b/go.sum index 2ada990..0900e9c 100644 --- a/go.sum +++ b/go.sum @@ -97,5 +97,5 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= maunium.net/go/mauflag v1.0.0 h1:YiaRc0tEI3toYtJMRIfjP+jklH45uDHtT80nUamyD4M= maunium.net/go/mauflag v1.0.0/go.mod h1:nLivPOpTpHnpzEh8jEdSL9UqO9+/KBJFmNRlwKfkPeA= -maunium.net/go/mautrix v0.20.1-0.20240914094516-d89dac594db0 h1:fTX1P8TPv+oUqHGu08jj6FYH+Q/fC9jtmvkXcAw+KTo= -maunium.net/go/mautrix v0.20.1-0.20240914094516-d89dac594db0/go.mod h1:amzKPIZVO7v1piD2JhKG1RvGZoV+5wEZfoHaEXOjjqA= +maunium.net/go/mautrix v0.20.1-0.20240914113211-d86913bd5c51 h1:RN8jP+q35kH/8pbLeGP/UZRerJdA2ptb8I+2V49N7Jk= +maunium.net/go/mautrix v0.20.1-0.20240914113211-d86913bd5c51/go.mod h1:amzKPIZVO7v1piD2JhKG1RvGZoV+5wEZfoHaEXOjjqA= From 7688e744d883ee355f5f011a38379b0ed289d131 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Sat, 14 Sep 2024 14:34:06 +0300 Subject: [PATCH 184/580] changelog: update --- CHANGELOG.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3c14528..5080e8e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,15 @@ +# v0.7.1 (unreleased) + +* Updated to libsignal v0.57.1. +* Added support for Matrix->Signal power level bridging (thanks to [@maltee1] in [#531]) +* Changed voice message conversion to convert to aac instead of m4a, + because Signal iOS doesn't appear to like ffmpeg's m4a files. +* Fixed outgoing sync messages not including disappearing start timestamp, + which would cause native clients to disappear messages at the wrong time. +* Re-added notices about decryption errors. + +[#531]: https://github.com/mautrix/signal/pull/531 + # v0.7.0 (2024-08-16) * Bumped minimum Go version to 1.22. From 11686cbe9606be666b1ab7da0fe19f985fd55ce4 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Sat, 14 Sep 2024 19:41:01 +0300 Subject: [PATCH 185/580] signalmeow/web: log attachment download http status --- pkg/signalmeow/attachments.go | 9 +++++++++ pkg/signalmeow/web/web.go | 5 ++++- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/pkg/signalmeow/attachments.go b/pkg/signalmeow/attachments.go index 64054dd..c0859b7 100644 --- a/pkg/signalmeow/attachments.go +++ b/pkg/signalmeow/attachments.go @@ -23,6 +23,7 @@ import ( "crypto/cipher" "crypto/hmac" "crypto/sha256" + "encoding/json" "errors" "fmt" "io" @@ -72,6 +73,14 @@ func DownloadAttachment(ctx context.Context, a *signalpb.AttachmentPointer) ([]b if err != nil { return nil, err } + if resp.StatusCode > 400 { + if json.Valid(body) && len(body) < 4096 { + zerolog.Ctx(ctx).Debug().RawJSON("response_data", body).Msg("Failed download response json") + } else if len(body) < 1024 { + zerolog.Ctx(ctx).Debug().Bytes("response_data", body).Msg("Failed download response data") + } + return nil, fmt.Errorf("unexpected status code %d", resp.StatusCode) + } return decryptAttachment(body, a.Key, a.Digest, *a.Size) } diff --git a/pkg/signalmeow/web/web.go b/pkg/signalmeow/web/web.go index 7bcc035..1119128 100644 --- a/pkg/signalmeow/web/web.go +++ b/pkg/signalmeow/web/web.go @@ -243,7 +243,10 @@ func GetAttachment(ctx context.Context, path string, cdnNumber uint32, opt *HTTP if err != nil { return nil, err } - log.Debug().Msg("Received Attachment HTTP response") + log.Debug(). + Int("status_code", resp.StatusCode). + Int64("content_length", resp.ContentLength). + Msg("Received Attachment HTTP response") return resp, err } From d144a21502a79346f644f3aa23497d5ffe79210b Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Mon, 16 Sep 2024 14:06:28 +0300 Subject: [PATCH 186/580] Bump version to v0.7.1 --- CHANGELOG.md | 6 ++++-- cmd/mautrix-signal/main.go | 2 +- go.mod | 4 ++-- go.sum | 8 ++++---- 4 files changed, 11 insertions(+), 9 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5080e8e..3e780d7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,7 +1,9 @@ -# v0.7.1 (unreleased) +# v0.7.1 (2024-09-16) * Updated to libsignal v0.57.1. -* Added support for Matrix->Signal power level bridging (thanks to [@maltee1] in [#531]) +* Dropped support for unauthenticated media on Matrix. +* Added support for Matrix->Signal power level bridging + (thanks to [@maltee1] in [#531]). * Changed voice message conversion to convert to aac instead of m4a, because Signal iOS doesn't appear to like ffmpeg's m4a files. * Fixed outgoing sync messages not including disappearing start timestamp, diff --git a/cmd/mautrix-signal/main.go b/cmd/mautrix-signal/main.go index 280e97f..9bd9e23 100644 --- a/cmd/mautrix-signal/main.go +++ b/cmd/mautrix-signal/main.go @@ -38,7 +38,7 @@ var m = mxmain.BridgeMain{ Name: "mautrix-signal", URL: "https://github.com/mautrix/signal", Description: "A Matrix-Signal puppeting bridge.", - Version: "0.7.0", + Version: "0.7.1", Connector: &connector.SignalConnector{}, } diff --git a/go.mod b/go.mod index e8bf58a..6fa4954 100644 --- a/go.mod +++ b/go.mod @@ -13,12 +13,12 @@ require ( github.com/rs/zerolog v1.33.0 github.com/stretchr/testify v1.9.0 github.com/tidwall/gjson v1.17.3 - go.mau.fi/util v0.7.1-0.20240913091524-7617daa66719 + go.mau.fi/util v0.8.0 golang.org/x/crypto v0.27.0 golang.org/x/exp v0.0.0-20240909161429-701f63a606c0 golang.org/x/net v0.29.0 google.golang.org/protobuf v1.34.2 - maunium.net/go/mautrix v0.20.1-0.20240914113211-d86913bd5c51 + maunium.net/go/mautrix v0.21.0 ) require ( diff --git a/go.sum b/go.sum index 0900e9c..e0eda49 100644 --- a/go.sum +++ b/go.sum @@ -67,8 +67,8 @@ github.com/tidwall/sjson v1.2.5 h1:kLy8mja+1c9jlljvWTlSazM7cKDRfJuR/bOJhcY5NcY= github.com/tidwall/sjson v1.2.5/go.mod h1:Fvgq9kS/6ociJEDnK0Fk1cpYF4FIW6ZF7LAe+6jwd28= github.com/yuin/goldmark v1.7.4 h1:BDXOHExt+A7gwPCJgPIIq7ENvceR7we7rOS9TNoLZeg= github.com/yuin/goldmark v1.7.4/go.mod h1:uzxRWxtg69N339t3louHJ7+O03ezfj6PlliRlaOzY1E= -go.mau.fi/util v0.7.1-0.20240913091524-7617daa66719 h1:sg1P/f4RHY1JuAwsPOjTCsZr8ROzR9bRTtnvvBu42d4= -go.mau.fi/util v0.7.1-0.20240913091524-7617daa66719/go.mod h1:1Ixb8HWoVbl3rT6nAX6nV4iMkzn7KU/KXwE0Rn5RmsQ= +go.mau.fi/util v0.8.0 h1:MiSny8jgQq4XtCLAT64gDJhZVhqiDeMVIEBDFVw+M0g= +go.mau.fi/util v0.8.0/go.mod h1:1Ixb8HWoVbl3rT6nAX6nV4iMkzn7KU/KXwE0Rn5RmsQ= go.mau.fi/zeroconfig v0.1.3 h1:As9wYDKmktjmNZW5i1vn8zvJlmGKHeVxHVIBMXsm4kM= go.mau.fi/zeroconfig v0.1.3/go.mod h1:NcSJkf180JT+1IId76PcMuLTNa1CzsFFZ0nBygIQM70= golang.org/x/crypto v0.27.0 h1:GXm2NjJrPaiv/h1tb2UH8QfgC/hOf/+z0p6PT8o1w7A= @@ -97,5 +97,5 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= maunium.net/go/mauflag v1.0.0 h1:YiaRc0tEI3toYtJMRIfjP+jklH45uDHtT80nUamyD4M= maunium.net/go/mauflag v1.0.0/go.mod h1:nLivPOpTpHnpzEh8jEdSL9UqO9+/KBJFmNRlwKfkPeA= -maunium.net/go/mautrix v0.20.1-0.20240914113211-d86913bd5c51 h1:RN8jP+q35kH/8pbLeGP/UZRerJdA2ptb8I+2V49N7Jk= -maunium.net/go/mautrix v0.20.1-0.20240914113211-d86913bd5c51/go.mod h1:amzKPIZVO7v1piD2JhKG1RvGZoV+5wEZfoHaEXOjjqA= +maunium.net/go/mautrix v0.21.0 h1:Z6nVu+clkJgj6ANwFYQQ1BtYeVXZPZ9lRgwuFN57gOY= +maunium.net/go/mautrix v0.21.0/go.mod h1:qm9oDhcHxF/Xby5RUuONIGpXw1SXXqLZj/GgvMxJxu0= From ebd8114db1c6c66a440e516f59dc994e65308da4 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Mon, 23 Sep 2024 20:44:50 +0300 Subject: [PATCH 187/580] signalmeow/receiving: actually ignore old counter decryption erorrs Might fix #552 --- pkg/signalmeow/receiving.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/signalmeow/receiving.go b/pkg/signalmeow/receiving.go index 9b36b84..cf716d2 100644 --- a/pkg/signalmeow/receiving.go +++ b/pkg/signalmeow/receiving.go @@ -624,7 +624,7 @@ func (cli *Client) handleDecryptedResult( logEvt.Stringer("sender", theirServiceID).Msg("Decryption error with known sender") // Only send decryption error event if the message was urgent, // to prevent spamming errors for typing notifications and whatnot - if envelope.GetUrgent() { + if envelope.GetUrgent() && !strings.Contains(result.Err.Error(), "message with old counter") { cli.handleEvent(&events.DecryptionError{ Sender: theirServiceID.UUID, Err: result.Err, From ce665b23a4b517843fbc163660fa13ce5799f2de Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Tue, 24 Sep 2024 17:19:17 +0300 Subject: [PATCH 188/580] signalmeow/receiving: don't send decryption error notice if content hint is implicit --- pkg/signalmeow/receiving.go | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/pkg/signalmeow/receiving.go b/pkg/signalmeow/receiving.go index cf716d2..ecd33f7 100644 --- a/pkg/signalmeow/receiving.go +++ b/pkg/signalmeow/receiving.go @@ -440,6 +440,11 @@ func (cli *Client) decryptUnidentifiedSenderEnvelope(ctx context.Context, destin if err != nil { return result, fmt.Errorf("failed to get sender certificate: %w", err) } + contentHint, err := usmc.GetContentHint() + if err != nil { + return result, fmt.Errorf("failed to get content hint: %w", err) + } + result.ContentHint = signalpb.UnidentifiedSenderMessage_Message_ContentHint(contentHint) senderUUID, err := senderCertificate.GetSenderUUID() if err != nil { return result, fmt.Errorf("failed to get sender UUID: %w", err) @@ -609,6 +614,7 @@ func (cli *Client) handleDecryptedResult( if result.Err != nil { logEvt := log.Err(result.Err). Bool("urgent", envelope.GetUrgent()). + Stringer("content_hint", result.ContentHint). Uint64("server_ts", envelope.GetServerTimestamp()). Uint64("client_ts", envelope.GetTimestamp()) if result.SenderAddress == nil { @@ -624,7 +630,9 @@ func (cli *Client) handleDecryptedResult( logEvt.Stringer("sender", theirServiceID).Msg("Decryption error with known sender") // Only send decryption error event if the message was urgent, // to prevent spamming errors for typing notifications and whatnot - if envelope.GetUrgent() && !strings.Contains(result.Err.Error(), "message with old counter") { + if envelope.GetUrgent() && + result.ContentHint != signalpb.UnidentifiedSenderMessage_Message_IMPLICIT && + !strings.Contains(result.Err.Error(), "message with old counter") { cli.handleEvent(&events.DecryptionError{ Sender: theirServiceID.UUID, Err: result.Err, @@ -1046,6 +1054,7 @@ func (cli *Client) sendDeliveryReceipts(ctx context.Context, deliveredTimestamps type DecryptionResult struct { SenderAddress *libsignalgo.Address Content *signalpb.Content + ContentHint signalpb.UnidentifiedSenderMessage_Message_ContentHint SealedSender bool Err error } From 4727da48fa0b651b9dd6d55f986287280db80b44 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Tue, 24 Sep 2024 17:22:43 +0300 Subject: [PATCH 189/580] signalmeow/sending: set urgent flag and content hint properly --- pkg/libsignalgo/sealedsender.go | 4 ++-- pkg/libsignalgo/session_test.go | 4 ++-- pkg/signalmeow/sending.go | 34 ++++++++++++++++++++++++++++----- 3 files changed, 33 insertions(+), 9 deletions(-) diff --git a/pkg/libsignalgo/sealedsender.go b/pkg/libsignalgo/sealedsender.go index 253e512..0d12b74 100644 --- a/pkg/libsignalgo/sealedsender.go +++ b/pkg/libsignalgo/sealedsender.go @@ -42,7 +42,7 @@ func NewSealedSenderAddress(e164 string, uuid uuid.UUID, deviceID uint32) *Seale } } -func SealedSenderEncryptPlaintext(ctx context.Context, message []byte, forAddress *Address, fromSenderCert *SenderCertificate, sessionStore SessionStore, identityStore IdentityKeyStore) ([]byte, error) { +func SealedSenderEncryptPlaintext(ctx context.Context, message []byte, contentHint UnidentifiedSenderMessageContentHint, forAddress *Address, fromSenderCert *SenderCertificate, sessionStore SessionStore, identityStore IdentityKeyStore) ([]byte, error) { ciphertextMessage, err := Encrypt(ctx, message, forAddress, sessionStore, identityStore) if err != nil { return nil, err @@ -51,7 +51,7 @@ func SealedSenderEncryptPlaintext(ctx context.Context, message []byte, forAddres usmc, err := NewUnidentifiedSenderMessageContent( ciphertextMessage, fromSenderCert, - UnidentifiedSenderMessageContentHintDefault, + contentHint, nil, ) if err != nil { diff --git a/pkg/libsignalgo/session_test.go b/pkg/libsignalgo/session_test.go index 9d108d5..1840fc3 100644 --- a/pkg/libsignalgo/session_test.go +++ b/pkg/libsignalgo/session_test.go @@ -241,7 +241,7 @@ func TestSealedSenderEncrypt_Repeated(t *testing.T) { }() for i := 0; i < 100; i++ { message := []byte(fmt.Sprintf("%04d vision", i)) - ciphertext, err := libsignalgo.SealedSenderEncryptPlaintext(ctx, message, bobAddress, senderCert, aliceStore, aliceStore) + ciphertext, err := libsignalgo.SealedSenderEncryptPlaintext(ctx, message, libsignalgo.UnidentifiedSenderMessageContentHintDefault, bobAddress, senderCert, aliceStore, aliceStore) require.NoError(t, err) assert.NotNil(t, ciphertext) } @@ -279,7 +279,7 @@ func TestSealedSenderSession(t *testing.T) { assert.NoError(t, err) message := []byte("2020 vision") - ciphertext, err := libsignalgo.SealedSenderEncryptPlaintext(ctx, message, bobAddress, senderCert, aliceStore, aliceStore) + ciphertext, err := libsignalgo.SealedSenderEncryptPlaintext(ctx, message, libsignalgo.UnidentifiedSenderMessageContentHintDefault, bobAddress, senderCert, aliceStore, aliceStore) require.NoError(t, err) assert.NotNil(t, ciphertext) diff --git a/pkg/signalmeow/sending.go b/pkg/signalmeow/sending.go index 0236331..49b13a0 100644 --- a/pkg/signalmeow/sending.go +++ b/pkg/signalmeow/sending.go @@ -83,7 +83,7 @@ type MyMessage struct { } type MyMessages struct { - Timestamp int64 `json:"timestamp"` + Timestamp uint64 `json:"timestamp"` Online bool `json:"online"` Urgent bool `json:"urgent"` Messages []MyMessage `json:"messages"` @@ -212,7 +212,7 @@ func (cli *Client) buildMessagesToSend(ctx context.Context, recipient libsignalg var envelopeType int var encryptedPayload []byte if unauthenticated { - envelopeType, encryptedPayload, err = cli.buildSSMessageToSend(ctx, recipientAddress, paddedMessage) + envelopeType, encryptedPayload, err = cli.buildSSMessageToSend(ctx, recipientAddress, paddedMessage, getContentHint(content)) } else { envelopeType, encryptedPayload, err = cli.buildAuthedMessageToSend(ctx, recipientAddress, paddedMessage) } @@ -264,7 +264,7 @@ func (cli *Client) buildAuthedMessageToSend(ctx context.Context, recipientAddres return envelopeType, encryptedPayload, nil } -func (cli *Client) buildSSMessageToSend(ctx context.Context, recipientAddress *libsignalgo.Address, paddedMessage []byte) (envelopeType int, encryptedPayload []byte, err error) { +func (cli *Client) buildSSMessageToSend(ctx context.Context, recipientAddress *libsignalgo.Address, paddedMessage []byte, contentHint libsignalgo.UnidentifiedSenderMessageContentHint) (envelopeType int, encryptedPayload []byte, err error) { cert, err := cli.senderCertificate(ctx) if err != nil { return 0, nil, err @@ -272,6 +272,7 @@ func (cli *Client) buildSSMessageToSend(ctx context.Context, recipientAddress *l encryptedPayload, err = libsignalgo.SealedSenderEncryptPlaintext( ctx, paddedMessage, + contentHint, recipientAddress, cert, cli.Store.ACISessionStore, @@ -782,6 +783,29 @@ func currentMessageTimestamp() uint64 { return uint64(time.Now().UnixMilli()) } +func isSyncMessageUrgent(content *signalpb.SyncMessage) bool { + return content.Sent != nil || content.Request != nil +} + +func isUrgent(content *signalpb.Content) bool { + return content.DataMessage != nil || + content.CallMessage != nil || + content.StoryMessage != nil || + content.EditMessage != nil || + (content.SyncMessage != nil && isSyncMessageUrgent(content.SyncMessage)) +} + +func getContentHint(content *signalpb.Content) libsignalgo.UnidentifiedSenderMessageContentHint { + if content.DataMessage != nil || content.EditMessage != nil { + // TODO add support for resending before setting this + //return libsignalgo.UnidentifiedSenderMessageContentHintResendable + } + if content.TypingMessage != nil || content.ReceiptMessage != nil { + return libsignalgo.UnidentifiedSenderMessageContentHintImplicit + } + return libsignalgo.UnidentifiedSenderMessageContentHintDefault +} + func (cli *Client) sendContent( ctx context.Context, recipient libsignalgo.ServiceID, @@ -845,9 +869,9 @@ func (cli *Client) sendContent( } outgoingMessages := MyMessages{ - Timestamp: int64(messageTimestamp), + Timestamp: messageTimestamp, Online: false, - Urgent: true, + Urgent: isUrgent(content), Messages: messages, } jsonBytes, err := json.Marshal(outgoingMessages) From 5d43fce26dacc1ae2316cad5d4f9bd3dfe85d113 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Tue, 24 Sep 2024 20:02:33 +0300 Subject: [PATCH 190/580] ci: lock closed issues automatically after 90 days [skip ci] --- .github/workflows/stale.yml | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 .github/workflows/stale.yml diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml new file mode 100644 index 0000000..dfd6cbb --- /dev/null +++ b/.github/workflows/stale.yml @@ -0,0 +1,22 @@ +name: 'Lock old issues' + +on: + schedule: + - cron: '0 * * * *' + workflow_dispatch: + +permissions: + issues: write +# pull-requests: write +# discussions: write + +concurrency: + group: lock-threads + +jobs: + action: + runs-on: ubuntu-latest + steps: + - uses: dessant/lock-threads@v5 + issue-inactive-days: 90 + process-only: issues From 4efc7a7dc391f65b8e45b8f54afe7288dc77cc2c Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Tue, 24 Sep 2024 20:04:48 +0300 Subject: [PATCH 191/580] ci: fix workflow parameters [skip ci] --- .github/workflows/stale.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml index dfd6cbb..0388eaf 100644 --- a/.github/workflows/stale.yml +++ b/.github/workflows/stale.yml @@ -18,5 +18,6 @@ jobs: runs-on: ubuntu-latest steps: - uses: dessant/lock-threads@v5 - issue-inactive-days: 90 - process-only: issues + with: + issue-inactive-days: 90 + process-only: issues From 500a629e5759d1610e8c569d3e9618f86ebb5b30 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Tue, 24 Sep 2024 20:13:28 +0300 Subject: [PATCH 192/580] ci: log locked issues [skip ci] --- .github/workflows/stale.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml index 0388eaf..ee34b76 100644 --- a/.github/workflows/stale.yml +++ b/.github/workflows/stale.yml @@ -18,6 +18,12 @@ jobs: runs-on: ubuntu-latest steps: - uses: dessant/lock-threads@v5 + id: lock with: issue-inactive-days: 90 process-only: issues + - name: Log processed threads + run: | + if [ '${{ steps.lock.outputs.issues }}' ]; then + echo "Issues:" && echo '${{ steps.lock.outputs.issues }}' | jq . + fi From 33d3cbf10a77f9df1ca02a279d90bb7807ae7468 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Tue, 24 Sep 2024 20:17:34 +0300 Subject: [PATCH 193/580] ci: make lock output nicer [skip ci] --- .github/workflows/stale.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml index ee34b76..d354d3a 100644 --- a/.github/workflows/stale.yml +++ b/.github/workflows/stale.yml @@ -25,5 +25,5 @@ jobs: - name: Log processed threads run: | if [ '${{ steps.lock.outputs.issues }}' ]; then - echo "Issues:" && echo '${{ steps.lock.outputs.issues }}' | jq . + echo "Issues:" && echo '${{ steps.lock.outputs.issues }}' | jq -r '.[] | "https://github.com/\(.owner)/\(.repo)/issues/\(.issue_number)"' fi From 84e513a2a72dade747dfeafa2ae558850f422056 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Tue, 24 Sep 2024 20:34:03 +0300 Subject: [PATCH 194/580] ci: rename action and reduce interval [skip ci] --- .github/workflows/stale.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml index d354d3a..4ad4d79 100644 --- a/.github/workflows/stale.yml +++ b/.github/workflows/stale.yml @@ -2,7 +2,7 @@ name: 'Lock old issues' on: schedule: - - cron: '0 * * * *' + - cron: '0 0 * * *' workflow_dispatch: permissions: @@ -14,7 +14,7 @@ concurrency: group: lock-threads jobs: - action: + lock-stale: runs-on: ubuntu-latest steps: - uses: dessant/lock-threads@v5 From aee07ca536bccb4a187ec769c76a8c74b0a2c363 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Wed, 25 Sep 2024 16:15:35 +0300 Subject: [PATCH 195/580] msgconv/from-signal: use mautrix-go function for disappearing timer change notice --- go.mod | 2 +- go.sum | 4 ++-- pkg/msgconv/from-signal.go | 11 ++--------- 3 files changed, 5 insertions(+), 12 deletions(-) diff --git a/go.mod b/go.mod index 6fa4954..ab19dbc 100644 --- a/go.mod +++ b/go.mod @@ -18,7 +18,7 @@ require ( golang.org/x/exp v0.0.0-20240909161429-701f63a606c0 golang.org/x/net v0.29.0 google.golang.org/protobuf v1.34.2 - maunium.net/go/mautrix v0.21.0 + maunium.net/go/mautrix v0.21.1-0.20240925131409-0c7f701828f0 ) require ( diff --git a/go.sum b/go.sum index e0eda49..1d1e9cf 100644 --- a/go.sum +++ b/go.sum @@ -97,5 +97,5 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= maunium.net/go/mauflag v1.0.0 h1:YiaRc0tEI3toYtJMRIfjP+jklH45uDHtT80nUamyD4M= maunium.net/go/mauflag v1.0.0/go.mod h1:nLivPOpTpHnpzEh8jEdSL9UqO9+/KBJFmNRlwKfkPeA= -maunium.net/go/mautrix v0.21.0 h1:Z6nVu+clkJgj6ANwFYQQ1BtYeVXZPZ9lRgwuFN57gOY= -maunium.net/go/mautrix v0.21.0/go.mod h1:qm9oDhcHxF/Xby5RUuONIGpXw1SXXqLZj/GgvMxJxu0= +maunium.net/go/mautrix v0.21.1-0.20240925131409-0c7f701828f0 h1:nX8gIPDHf2UXkcGMX982mtdTFXgbXtJGIDUQta+mRbE= +maunium.net/go/mautrix v0.21.1-0.20240925131409-0c7f701828f0/go.mod h1:qm9oDhcHxF/Xby5RUuONIGpXw1SXXqLZj/GgvMxJxu0= diff --git a/pkg/msgconv/from-signal.go b/pkg/msgconv/from-signal.go index 20dd39b..4645dd0 100644 --- a/pkg/msgconv/from-signal.go +++ b/pkg/msgconv/from-signal.go @@ -28,7 +28,6 @@ import ( "github.com/emersion/go-vcard" "github.com/google/uuid" "github.com/rs/zerolog" - "go.mau.fi/util/exfmt" "go.mau.fi/util/exmime" "go.mau.fi/util/ffmpeg" "maunium.net/go/mautrix/bridgev2" @@ -153,14 +152,8 @@ func (mc *MessageConverter) ToMatrix( func (mc *MessageConverter) ConvertDisappearingTimerChangeToMatrix(ctx context.Context, timer uint32, timerVersion *uint32, updatePortal bool) *bridgev2.ConvertedMessagePart { part := &bridgev2.ConvertedMessagePart{ - Type: event.EventMessage, - Content: &event.MessageEventContent{ - MsgType: event.MsgNotice, - Body: fmt.Sprintf("Disappearing messages set to %s", exfmt.Duration(time.Duration(timer)*time.Second)), - }, - } - if timer == 0 { - part.Content.Body = "Disappearing messages disabled" + Type: event.EventMessage, + Content: bridgev2.DisappearingMessageNotice(time.Duration(timer)*time.Second, false), } if updatePortal { portal := getPortal(ctx) From 889c0dbcfa8e92550a32af1856df33feae90a1d7 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Sat, 28 Sep 2024 18:16:39 +0300 Subject: [PATCH 196/580] ci: change cron schedule --- .github/workflows/stale.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml index 4ad4d79..c2003f3 100644 --- a/.github/workflows/stale.yml +++ b/.github/workflows/stale.yml @@ -2,7 +2,7 @@ name: 'Lock old issues' on: schedule: - - cron: '0 0 * * *' + - cron: '0 12 * * *' workflow_dispatch: permissions: From d799a2b89549d2e31b6bec4323dc783fdba03b8c Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Mon, 30 Sep 2024 21:11:41 +0300 Subject: [PATCH 197/580] msgconv/urlpreview: don't try to re-decrypt preview images --- pkg/msgconv/urlpreview.go | 7 ------- 1 file changed, 7 deletions(-) diff --git a/pkg/msgconv/urlpreview.go b/pkg/msgconv/urlpreview.go index d2d3b23..5731a0b 100644 --- a/pkg/msgconv/urlpreview.go +++ b/pkg/msgconv/urlpreview.go @@ -78,13 +78,6 @@ func (mc *MessageConverter) convertURLPreviewToSignal(ctx context.Context, conte zerolog.Ctx(ctx).Err(err).Int("preview_index", i).Msg("Failed to download URL preview image") continue } - if preview.ImageEncryption != nil { - err = preview.ImageEncryption.DecryptInPlace(data) - if err != nil { - zerolog.Ctx(ctx).Err(err).Int("preview_index", i).Msg("Failed to decrypt URL preview image") - continue - } - } uploaded, err := getClient(ctx).UploadAttachment(ctx, data) if err != nil { zerolog.Ctx(ctx).Err(err).Int("preview_index", i).Msg("Failed to reupload URL preview image") From 922c6d1a2cf2e04bfc1d80dbb6248fc346d0211e Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Mon, 30 Sep 2024 21:12:30 +0300 Subject: [PATCH 198/580] dependencies: update mautrix-go --- go.mod | 4 ++-- go.sum | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/go.mod b/go.mod index ab19dbc..876e05f 100644 --- a/go.mod +++ b/go.mod @@ -13,12 +13,12 @@ require ( github.com/rs/zerolog v1.33.0 github.com/stretchr/testify v1.9.0 github.com/tidwall/gjson v1.17.3 - go.mau.fi/util v0.8.0 + go.mau.fi/util v0.8.1-0.20240927174413-000d30f9a02a golang.org/x/crypto v0.27.0 golang.org/x/exp v0.0.0-20240909161429-701f63a606c0 golang.org/x/net v0.29.0 google.golang.org/protobuf v1.34.2 - maunium.net/go/mautrix v0.21.1-0.20240925131409-0c7f701828f0 + maunium.net/go/mautrix v0.21.1-0.20240930142122-741b4e823ffb ) require ( diff --git a/go.sum b/go.sum index 1d1e9cf..d76e998 100644 --- a/go.sum +++ b/go.sum @@ -67,8 +67,8 @@ github.com/tidwall/sjson v1.2.5 h1:kLy8mja+1c9jlljvWTlSazM7cKDRfJuR/bOJhcY5NcY= github.com/tidwall/sjson v1.2.5/go.mod h1:Fvgq9kS/6ociJEDnK0Fk1cpYF4FIW6ZF7LAe+6jwd28= github.com/yuin/goldmark v1.7.4 h1:BDXOHExt+A7gwPCJgPIIq7ENvceR7we7rOS9TNoLZeg= github.com/yuin/goldmark v1.7.4/go.mod h1:uzxRWxtg69N339t3louHJ7+O03ezfj6PlliRlaOzY1E= -go.mau.fi/util v0.8.0 h1:MiSny8jgQq4XtCLAT64gDJhZVhqiDeMVIEBDFVw+M0g= -go.mau.fi/util v0.8.0/go.mod h1:1Ixb8HWoVbl3rT6nAX6nV4iMkzn7KU/KXwE0Rn5RmsQ= +go.mau.fi/util v0.8.1-0.20240927174413-000d30f9a02a h1:4TrWJ0ooHT9YssDBUgXNU8FiR2cwi9jEAjtaVur4f0M= +go.mau.fi/util v0.8.1-0.20240927174413-000d30f9a02a/go.mod h1:1Ixb8HWoVbl3rT6nAX6nV4iMkzn7KU/KXwE0Rn5RmsQ= go.mau.fi/zeroconfig v0.1.3 h1:As9wYDKmktjmNZW5i1vn8zvJlmGKHeVxHVIBMXsm4kM= go.mau.fi/zeroconfig v0.1.3/go.mod h1:NcSJkf180JT+1IId76PcMuLTNa1CzsFFZ0nBygIQM70= golang.org/x/crypto v0.27.0 h1:GXm2NjJrPaiv/h1tb2UH8QfgC/hOf/+z0p6PT8o1w7A= @@ -97,5 +97,5 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= maunium.net/go/mauflag v1.0.0 h1:YiaRc0tEI3toYtJMRIfjP+jklH45uDHtT80nUamyD4M= maunium.net/go/mauflag v1.0.0/go.mod h1:nLivPOpTpHnpzEh8jEdSL9UqO9+/KBJFmNRlwKfkPeA= -maunium.net/go/mautrix v0.21.1-0.20240925131409-0c7f701828f0 h1:nX8gIPDHf2UXkcGMX982mtdTFXgbXtJGIDUQta+mRbE= -maunium.net/go/mautrix v0.21.1-0.20240925131409-0c7f701828f0/go.mod h1:qm9oDhcHxF/Xby5RUuONIGpXw1SXXqLZj/GgvMxJxu0= +maunium.net/go/mautrix v0.21.1-0.20240930142122-741b4e823ffb h1:X19nOFvy3GINE6TbSshH5OiOgqbZqEgfu8e0Nsi2iAk= +maunium.net/go/mautrix v0.21.1-0.20240930142122-741b4e823ffb/go.mod h1:qN4yYKm3brOUWN8dlR0KPbKwSBGXQ4am/kzSQt/kLmY= From b943ce71dd4633ea26cc9d1745b794b364e4fcc0 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Mon, 30 Sep 2024 23:26:14 +0300 Subject: [PATCH 199/580] legacyprovision: fix context in login complete handler --- cmd/mautrix-signal/legacyprovision.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/mautrix-signal/legacyprovision.go b/cmd/mautrix-signal/legacyprovision.go index 43d6947..177d4a5 100644 --- a/cmd/mautrix-signal/legacyprovision.go +++ b/cmd/mautrix-signal/legacyprovision.go @@ -190,7 +190,7 @@ func legacyProvLinkWaitAccount(w http.ResponseWriter, r *http.Request) { UUID: string(res.CompleteParams.UserLogin.ID), Number: res.CompleteParams.UserLogin.RemoteName, }) - go handleLoginComplete(r.Context(), login.User, res.CompleteParams.UserLogin) + go handleLoginComplete(context.WithoutCancel(r.Context()), login.User, res.CompleteParams.UserLogin) } login.Delete() } From da8c612034d6999fbc3f03f3fe08e1ed0010d806 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Wed, 2 Oct 2024 20:39:47 +0300 Subject: [PATCH 200/580] signalmeow: use correct sender certificate based on account settings --- pkg/signalmeow/client.go | 15 ++--- pkg/signalmeow/sending.go | 59 ++++++++++++------- pkg/signalmeow/storageservice.go | 8 ++- pkg/signalmeow/store/container.go | 29 +++++++-- pkg/signalmeow/store/device.go | 2 + pkg/signalmeow/store/upgrades/00-latest.sql | 5 +- .../upgrades/17-store-account-record.sql | 2 + 7 files changed, 85 insertions(+), 35 deletions(-) create mode 100644 pkg/signalmeow/store/upgrades/17-store-account-record.sql diff --git a/pkg/signalmeow/client.go b/pkg/signalmeow/client.go index 128e6db..14db3b7 100644 --- a/pkg/signalmeow/client.go +++ b/pkg/signalmeow/client.go @@ -34,13 +34,14 @@ import ( type Client struct { Store *store.Device - SenderCertificate *libsignalgo.SenderCertificate - GroupCredentials *GroupCredentials - GroupCache *GroupCache - ProfileCache *ProfileCache - GroupCallCache *map[string]bool - LastContactRequestTime time.Time - SyncContactsOnConnect bool + SenderCertificateWithE164 *libsignalgo.SenderCertificate + SenderCertificateNoE164 *libsignalgo.SenderCertificate + GroupCredentials *GroupCredentials + GroupCache *GroupCache + ProfileCache *ProfileCache + GroupCallCache *map[string]bool + LastContactRequestTime time.Time + SyncContactsOnConnect bool encryptionLock sync.Mutex diff --git a/pkg/signalmeow/sending.go b/pkg/signalmeow/sending.go index 49b13a0..902818d 100644 --- a/pkg/signalmeow/sending.go +++ b/pkg/signalmeow/sending.go @@ -41,16 +41,27 @@ import ( // Sending -func (cli *Client) senderCertificate(ctx context.Context) (*libsignalgo.SenderCertificate, error) { - if cli.SenderCertificate != nil { - expiry, err := cli.SenderCertificate.GetExpiration() +func (cli *Client) senderCertificate(ctx context.Context, e164 bool) (*libsignalgo.SenderCertificate, error) { + cached := cli.SenderCertificateNoE164 + if e164 { + cached = cli.SenderCertificateWithE164 + } + setCache := func(val *libsignalgo.SenderCertificate) { + if e164 { + cli.SenderCertificateWithE164 = val + } else { + cli.SenderCertificateNoE164 = val + } + } + if cached != nil { + expiry, err := cached.GetExpiration() if err != nil { zerolog.Ctx(ctx).Err(err).Msg("Failed to check sender certificate expiry") } else if time.Until(expiry) < 1*exfmt.Day { zerolog.Ctx(ctx).Debug().Msg("Sender certificate expired, fetching new one") - cli.SenderCertificate = nil + setCache(nil) } else { - return cli.SenderCertificate, nil + return cached, nil } } @@ -61,7 +72,11 @@ func (cli *Client) senderCertificate(ctx context.Context) (*libsignalgo.SenderCe username, password := cli.Store.BasicAuthCreds() opts := &web.HTTPReqOpt{Username: &username, Password: &password} - resp, err := web.SendHTTPRequest(ctx, http.MethodGet, "/v1/certificate/delivery", opts) + var query string + if !e164 { + query = "?includeE164=false" + } + resp, err := web.SendHTTPRequest(ctx, http.MethodGet, "/v1/certificate/delivery"+query, opts) if err != nil { return nil, err } @@ -71,7 +86,7 @@ func (cli *Client) senderCertificate(ctx context.Context) (*libsignalgo.SenderCe } cert, err := libsignalgo.DeserializeSenderCertificate(r.Certificate) - cli.SenderCertificate = cert + setCache(cert) return cert, err } @@ -164,7 +179,7 @@ func (cli *Client) howManyOtherDevicesDoWeHave(ctx context.Context) int { return otherDevices } -func (cli *Client) buildMessagesToSend(ctx context.Context, recipient libsignalgo.ServiceID, content *signalpb.Content, unauthenticated bool) ([]MyMessage, error) { +func (cli *Client) buildMessagesToSend(ctx context.Context, recipient libsignalgo.ServiceID, content *signalpb.Content, unauthenticated, isGroup bool) ([]MyMessage, error) { // We need to prevent multiple encryption operations from happening at once, or else ratchets can race cli.encryptionLock.Lock() defer cli.encryptionLock.Unlock() @@ -212,7 +227,10 @@ func (cli *Client) buildMessagesToSend(ctx context.Context, recipient libsignalg var envelopeType int var encryptedPayload []byte if unauthenticated { - envelopeType, encryptedPayload, err = cli.buildSSMessageToSend(ctx, recipientAddress, paddedMessage, getContentHint(content)) + includeE164 := !isGroup && cli.Store.AccountRecord.GetPhoneNumberSharingMode() == signalpb.AccountRecord_EVERYBODY + envelopeType, encryptedPayload, err = cli.buildSSMessageToSend( + ctx, recipientAddress, paddedMessage, getContentHint(content), includeE164, + ) } else { envelopeType, encryptedPayload, err = cli.buildAuthedMessageToSend(ctx, recipientAddress, paddedMessage) } @@ -264,8 +282,8 @@ func (cli *Client) buildAuthedMessageToSend(ctx context.Context, recipientAddres return envelopeType, encryptedPayload, nil } -func (cli *Client) buildSSMessageToSend(ctx context.Context, recipientAddress *libsignalgo.Address, paddedMessage []byte, contentHint libsignalgo.UnidentifiedSenderMessageContentHint) (envelopeType int, encryptedPayload []byte, err error) { - cert, err := cli.senderCertificate(ctx) +func (cli *Client) buildSSMessageToSend(ctx context.Context, recipientAddress *libsignalgo.Address, paddedMessage []byte, contentHint libsignalgo.UnidentifiedSenderMessageContentHint, includeE164 bool) (envelopeType int, encryptedPayload []byte, err error) { + cert, err := cli.senderCertificate(ctx, includeE164) if err != nil { return 0, nil, err } @@ -444,7 +462,7 @@ func (cli *Client) SendContactSyncRequest(ctx context.Context) error { Type: signalpb.SyncMessage_Request_CONTACTS.Enum(), }, }, - }, 0, false) + }, 0, false, false) if err != nil { log.Err(err).Msg("Failed to send contact sync request message to myself") return err @@ -464,7 +482,7 @@ func (cli *Client) SendStorageMasterKeyRequest(ctx context.Context) error { Type: signalpb.SyncMessage_Request_KEYS.Enum(), }, }, - }, 0, false) + }, 0, false, false) if err != nil { log.Err(err).Msg("Failed to send key sync request message to myself") return err @@ -617,7 +635,7 @@ func (cli *Client) sendToGroup(ctx context.Context, recipients []*libsignalgo.Se } log := zerolog.Ctx(ctx).With().Stringer("member", *recipient).Logger() ctx := log.WithContext(ctx) - sentUnidentified, err := cli.sendContent(ctx, *recipient, messageTimestamp, content, 0, true) + sentUnidentified, err := cli.sendContent(ctx, *recipient, messageTimestamp, content, 0, true, true) if err != nil { result.FailedToSendTo = append(result.FailedToSendTo, FailedSendResult{ Recipient: *recipient, @@ -641,7 +659,7 @@ func (cli *Client) sendToGroup(ctx context.Context, recipients []*libsignalgo.Se } else if content.GetEditMessage() != nil { syncContent = syncMessageFromGroupEditMessage(content.EditMessage, result.SuccessfullySentTo) } - _, selfSendErr := cli.sendContent(ctx, cli.Store.ACIServiceID(), messageTimestamp, syncContent, 0, true) + _, selfSendErr := cli.sendContent(ctx, cli.Store.ACIServiceID(), messageTimestamp, syncContent, 0, true, true) if selfSendErr != nil { zerolog.Ctx(ctx).Err(selfSendErr).Msg("Failed to send sync message to myself") } @@ -670,7 +688,7 @@ func (cli *Client) sendSyncCopy(ctx context.Context, content *signalpb.Content, syncContent = syncMessageFromReadReceiptMessage(ctx, content.ReceiptMessage, result.Recipient) } if syncContent != nil { - _, selfSendErr := cli.sendContent(ctx, cli.Store.ACIServiceID(), messageTS, syncContent, 0, true) + _, selfSendErr := cli.sendContent(ctx, cli.Store.ACIServiceID(), messageTS, syncContent, 0, true, false) if selfSendErr != nil { zerolog.Ctx(ctx).Err(selfSendErr).Msg("Failed to send sync message to myself") } else { @@ -745,7 +763,7 @@ func (cli *Client) SendMessage(ctx context.Context, recipientID libsignalgo.Serv } // Send to the recipient - sentUnidentified, err := cli.sendContent(ctx, recipientID, messageTimestamp, content, 0, true) + sentUnidentified, err := cli.sendContent(ctx, recipientID, messageTimestamp, content, 0, true, false) if err != nil { return SendMessageResult{ WasSuccessful: false, @@ -813,6 +831,7 @@ func (cli *Client) sendContent( content *signalpb.Content, retryCount int, useUnidentifiedSender bool, + isGroup bool, ) (sentUnidentified bool, err error) { log := zerolog.Ctx(ctx).With(). Str("action", "send content"). @@ -862,7 +881,7 @@ func (cli *Client) sendContent( } var messages []MyMessage - messages, err = cli.buildMessagesToSend(ctx, recipient, content, useUnidentifiedSender) + messages, err = cli.buildMessagesToSend(ctx, recipient, content, useUnidentifiedSender, isGroup) if err != nil { log.Err(err).Msg("Error building messages to send") return false, err @@ -931,7 +950,7 @@ func (cli *Client) sendContent( return false, err } // Try to send again (**RECURSIVELY**) - sentUnidentified, err = cli.sendContent(ctx, recipient, messageTimestamp, content, retryCount+1, sentUnidentified) + sentUnidentified, err = cli.sendContent(ctx, recipient, messageTimestamp, content, retryCount+1, sentUnidentified, isGroup) if err != nil { log.Err(err).Msg("2nd try sendMessage error") return sentUnidentified, err @@ -939,7 +958,7 @@ func (cli *Client) sendContent( } else if *response.Status == 401 && useUnidentifiedSender { log.Debug().Msg("Retrying send without sealed sender") // Try to send again (**RECURSIVELY**) - sentUnidentified, err = cli.sendContent(ctx, recipient, messageTimestamp, content, retryCount+1, false) + sentUnidentified, err = cli.sendContent(ctx, recipient, messageTimestamp, content, retryCount+1, false, isGroup) if err != nil { log.Err(err).Msg("2nd try sendMessage error") return sentUnidentified, err diff --git a/pkg/signalmeow/storageservice.go b/pkg/signalmeow/storageservice.go index a78f964..fab5eed 100644 --- a/pkg/signalmeow/storageservice.go +++ b/pkg/signalmeow/storageservice.go @@ -102,7 +102,13 @@ func (cli *Client) SyncStorage(ctx context.Context) { } case *signalpb.StorageRecord_Account: log.Trace().Any("account_record", data.Account).Msg("Found account record") - // There's probably some useful data here + cli.Store.AccountRecord = data.Account + err = cli.Store.DeviceStore.PutDevice(ctx, &cli.Store.DeviceData) + if err != nil { + log.Err(err).Msg("Failed to save device after receiving account record") + } else { + log.Debug().Msg("Saved device after receiving account record") + } case *signalpb.StorageRecord_GroupV1, *signalpb.StorageRecord_StoryDistributionList: // irrelevant data default: diff --git a/pkg/signalmeow/store/container.go b/pkg/signalmeow/store/container.go index a08b42d..8f81490 100644 --- a/pkg/signalmeow/store/container.go +++ b/pkg/signalmeow/store/container.go @@ -9,8 +9,10 @@ import ( "github.com/google/uuid" "github.com/rs/zerolog" "go.mau.fi/util/dbutil" + "google.golang.org/protobuf/proto" "go.mau.fi/mautrix-signal/pkg/libsignalgo" + signalpb "go.mau.fi/mautrix-signal/pkg/signalmeow/protobuf" "go.mau.fi/mautrix-signal/pkg/signalmeow/store/upgrades" ) @@ -35,7 +37,7 @@ const getAllDevicesQuery = ` SELECT aci_uuid, aci_identity_key_pair, registration_id, pni_uuid, pni_identity_key_pair, pni_registration_id, - device_id, number, password, master_key + device_id, number, password, master_key, account_record FROM signalmeow_device ` @@ -48,12 +50,13 @@ func (c *Container) Upgrade(ctx context.Context) error { func (c *Container) scanDevice(row dbutil.Scannable) (*Device, error) { var device Device - var aciIdentityKeyPair, pniIdentityKeyPair []byte + var aciIdentityKeyPair, pniIdentityKeyPair, accountRecordBytes []byte err := row.Scan( &device.ACI, &aciIdentityKeyPair, &device.ACIRegistrationID, &device.PNI, &pniIdentityKeyPair, &device.PNIRegistrationID, &device.DeviceID, &device.Number, &device.Password, &device.MasterKey, + &accountRecordBytes, ) if err != nil { return nil, fmt.Errorf("failed to scan session: %w", err) @@ -70,6 +73,13 @@ func (c *Container) scanDevice(row dbutil.Scannable) (*Device, error) { if len(device.MasterKey) == 0 { device.MasterKey = nil } + if len(accountRecordBytes) > 0 { + device.AccountRecord = &signalpb.AccountRecord{} + err = proto.Unmarshal(accountRecordBytes, device.AccountRecord) + if err != nil { + return nil, fmt.Errorf("failed to unmarshal account record: %w", err) + } + } baseStore := &sqlStore{Container: c, AccountID: device.ACI} aciStore := &scopedSQLStore{Container: c, AccountID: device.ACI, ServiceID: device.ACIServiceID()} pniStore := &scopedSQLStore{Container: c, AccountID: device.ACI, ServiceID: device.PNIServiceID()} @@ -137,9 +147,9 @@ const ( INSERT INTO signalmeow_device ( aci_uuid, aci_identity_key_pair, registration_id, pni_uuid, pni_identity_key_pair, pni_registration_id, - device_id, number, password, master_key + device_id, number, password, master_key, account_record ) - VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10) + VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11) ON CONFLICT (aci_uuid) DO UPDATE SET aci_identity_key_pair=excluded.aci_identity_key_pair, registration_id=excluded.registration_id, @@ -149,7 +159,8 @@ const ( device_id=excluded.device_id, number=excluded.number, password=excluded.password, - master_key=excluded.master_key + master_key=excluded.master_key, + account_record=excluded.account_record ` deleteDeviceQuery = `DELETE FROM signalmeow_device WHERE aci_uuid=$1` ) @@ -172,10 +183,18 @@ func (c *Container) PutDevice(ctx context.Context, device *DeviceData) error { zerolog.Ctx(ctx).Err(err).Msg("failed to serialize pni identity key pair") return err } + var accountRecordBytes []byte + if device.AccountRecord != nil { + accountRecordBytes, err = proto.Marshal(device.AccountRecord) + if err != nil { + return fmt.Errorf("failed to marshal account record: %w", err) + } + } _, err = c.db.Exec(ctx, insertDeviceQuery, device.ACI, aciIdentityKeyPair, device.ACIRegistrationID, device.PNI, pniIdentityKeyPair, device.PNIRegistrationID, device.DeviceID, device.Number, device.Password, device.MasterKey, + accountRecordBytes, ) if err != nil { zerolog.Ctx(ctx).Err(err).Msg("failed to insert device") diff --git a/pkg/signalmeow/store/device.go b/pkg/signalmeow/store/device.go index 2c8d54a..eb823c8 100644 --- a/pkg/signalmeow/store/device.go +++ b/pkg/signalmeow/store/device.go @@ -9,6 +9,7 @@ import ( "github.com/rs/zerolog" "go.mau.fi/mautrix-signal/pkg/libsignalgo" + signalpb "go.mau.fi/mautrix-signal/pkg/signalmeow/protobuf" ) type sqlStore struct { @@ -35,6 +36,7 @@ type DeviceData struct { Number string Password string MasterKey []byte + AccountRecord *signalpb.AccountRecord } func (d *DeviceData) ACIServiceID() libsignalgo.ServiceID { diff --git a/pkg/signalmeow/store/upgrades/00-latest.sql b/pkg/signalmeow/store/upgrades/00-latest.sql index 40afbfb..38ed5b2 100644 --- a/pkg/signalmeow/store/upgrades/00-latest.sql +++ b/pkg/signalmeow/store/upgrades/00-latest.sql @@ -1,4 +1,4 @@ --- v0 -> v16 (compatible with v13+): Latest revision +-- v0 -> v17 (compatible with v13+): Latest revision CREATE TABLE signalmeow_device ( aci_uuid TEXT PRIMARY KEY, @@ -13,7 +13,8 @@ CREATE TABLE signalmeow_device ( number TEXT NOT NULL DEFAULT '', password TEXT NOT NULL DEFAULT '', - master_key bytea + master_key bytea, + account_record bytea ); CREATE TABLE signalmeow_pre_keys ( diff --git a/pkg/signalmeow/store/upgrades/17-store-account-record.sql b/pkg/signalmeow/store/upgrades/17-store-account-record.sql new file mode 100644 index 0000000..6d8b0db --- /dev/null +++ b/pkg/signalmeow/store/upgrades/17-store-account-record.sql @@ -0,0 +1,2 @@ +-- v17 (compatible with v13+): Store account config +ALTER TABLE signalmeow_device ADD COLUMN account_record bytea; From 59acb7e4dd861a1ea075cae4bcfbadaf75d7b902 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Wed, 2 Oct 2024 21:24:47 +0300 Subject: [PATCH 201/580] signalmeow: update protobufs --- pkg/signalmeow/protobuf/SignalService.pb.go | 3 - pkg/signalmeow/protobuf/SignalService.pb.raw | Bin 19136 -> 19130 bytes pkg/signalmeow/protobuf/SignalService.proto | 24 +-- pkg/signalmeow/protobuf/StorageService.pb.go | 173 ++++++++++++++---- pkg/signalmeow/protobuf/StorageService.pb.raw | Bin 5605 -> 5814 bytes pkg/signalmeow/protobuf/StorageService.proto | 8 + pkg/signalmeow/protobuf/update-protos.sh | 4 +- 7 files changed, 156 insertions(+), 56 deletions(-) diff --git a/pkg/signalmeow/protobuf/SignalService.pb.go b/pkg/signalmeow/protobuf/SignalService.pb.go index f524c90..f96f5d8 100644 --- a/pkg/signalmeow/protobuf/SignalService.pb.go +++ b/pkg/signalmeow/protobuf/SignalService.pb.go @@ -1467,18 +1467,15 @@ type SyncMessage_CallLinkUpdate_Type int32 const ( SyncMessage_CallLinkUpdate_UPDATE SyncMessage_CallLinkUpdate_Type = 0 - SyncMessage_CallLinkUpdate_DELETE SyncMessage_CallLinkUpdate_Type = 1 ) // Enum value maps for SyncMessage_CallLinkUpdate_Type. var ( SyncMessage_CallLinkUpdate_Type_name = map[int32]string{ 0: "UPDATE", - 1: "DELETE", } SyncMessage_CallLinkUpdate_Type_value = map[string]int32{ "UPDATE": 0, - "DELETE": 1, } ) diff --git a/pkg/signalmeow/protobuf/SignalService.pb.raw b/pkg/signalmeow/protobuf/SignalService.pb.raw index bc9a4d57969c32e0c0d280ef3808c2a3c4c70bbb..322d177c380305a0f2efe3ed65c91c4405103817 100644 GIT binary patch delta 51 zcmV-30L=ful>xey0kGpD0qV2lB9IgTtdn&&louEZ1XOu&WfBSs231f*K~zN$03rkk J0kbAJniBEO5AFZ} delta 57 zcmdlrmGQt-#tn~^7(Z-&qBKE-ans~d^C_}&Tr44#1*t+@Tx_8ME{-9t0t_Iwi>r@o Li0ftri&;VdSeFs7 diff --git a/pkg/signalmeow/protobuf/SignalService.proto b/pkg/signalmeow/protobuf/SignalService.proto index c516a1b..177018f 100644 --- a/pkg/signalmeow/protobuf/SignalService.proto +++ b/pkg/signalmeow/protobuf/SignalService.proto @@ -630,7 +630,7 @@ message SyncMessage { message CallLinkUpdate { enum Type { UPDATE = 0; - DELETE = 1; + reserved 1; // was DELETE, superseded by storage service } optional bytes rootKey = 1; @@ -819,17 +819,17 @@ message GroupDetails { optional string e164 = 2; } - optional bytes id = 1; - optional string name = 2; - repeated string membersE164 = 3; - repeated Member members = 9; - optional Avatar avatar = 4; - optional bool active = 5 [default = true]; - optional uint32 expireTimer = 6; - optional string color = 7; - optional bool blocked = 8; - optional uint32 inboxPosition = 10; - optional bool archived = 11; + optional bytes id = 1; + optional string name = 2; + repeated string membersE164 = 3; + repeated Member members = 9; + optional Avatar avatar = 4; + optional bool active = 5 [default = true]; + optional uint32 expireTimer = 6; + optional string color = 7; + optional bool blocked = 8; + optional uint32 inboxPosition = 10; + optional bool archived = 11; } message PaymentAddress { diff --git a/pkg/signalmeow/protobuf/StorageService.pb.go b/pkg/signalmeow/protobuf/StorageService.pb.go index 5f88b50..788cb41 100644 --- a/pkg/signalmeow/protobuf/StorageService.pb.go +++ b/pkg/signalmeow/protobuf/StorageService.pb.go @@ -85,6 +85,7 @@ const ( ManifestRecord_Identifier_GROUPV2 ManifestRecord_Identifier_Type = 3 ManifestRecord_Identifier_ACCOUNT ManifestRecord_Identifier_Type = 4 ManifestRecord_Identifier_STORY_DISTRIBUTION_LIST ManifestRecord_Identifier_Type = 5 + ManifestRecord_Identifier_CALL_LINK ManifestRecord_Identifier_Type = 7 ) // Enum value maps for ManifestRecord_Identifier_Type. @@ -96,6 +97,7 @@ var ( 3: "GROUPV2", 4: "ACCOUNT", 5: "STORY_DISTRIBUTION_LIST", + 7: "CALL_LINK", } ManifestRecord_Identifier_Type_value = map[string]int32{ "UNKNOWN": 0, @@ -104,6 +106,7 @@ var ( "GROUPV2": 3, "ACCOUNT": 4, "STORY_DISTRIBUTION_LIST": 5, + "CALL_LINK": 7, } ) @@ -698,6 +701,7 @@ type StorageRecord struct { // *StorageRecord_GroupV2 // *StorageRecord_Account // *StorageRecord_StoryDistributionList + // *StorageRecord_CallLink Record isStorageRecord_Record `protobuf_oneof:"record"` } @@ -775,6 +779,13 @@ func (x *StorageRecord) GetStoryDistributionList() *StoryDistributionListRecord return nil } +func (x *StorageRecord) GetCallLink() *CallLinkRecord { + if x, ok := x.GetRecord().(*StorageRecord_CallLink); ok { + return x.CallLink + } + return nil +} + type isStorageRecord_Record interface { isStorageRecord_Record() } @@ -799,6 +810,10 @@ type StorageRecord_StoryDistributionList struct { StoryDistributionList *StoryDistributionListRecord `protobuf:"bytes,5,opt,name=storyDistributionList,proto3,oneof"` } +type StorageRecord_CallLink struct { + CallLink *CallLinkRecord `protobuf:"bytes,7,opt,name=callLink,proto3,oneof"` +} + func (*StorageRecord_Contact) isStorageRecord_Record() {} func (*StorageRecord_GroupV1) isStorageRecord_Record() {} @@ -809,6 +824,8 @@ func (*StorageRecord_Account) isStorageRecord_Record() {} func (*StorageRecord_StoryDistributionList) isStorageRecord_Record() {} +func (*StorageRecord_CallLink) isStorageRecord_Record() {} + type ContactRecord struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -1667,6 +1684,69 @@ func (x *StoryDistributionListRecord) GetIsBlockList() bool { return false } +type CallLinkRecord struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + RootKey []byte `protobuf:"bytes,1,opt,name=rootKey,proto3" json:"rootKey,omitempty"` + AdminPasskey []byte `protobuf:"bytes,2,opt,name=adminPasskey,proto3" json:"adminPasskey,omitempty"` + DeletedAtTimestampMs uint64 `protobuf:"varint,3,opt,name=deletedAtTimestampMs,proto3" json:"deletedAtTimestampMs,omitempty"` +} + +func (x *CallLinkRecord) Reset() { + *x = CallLinkRecord{} + if protoimpl.UnsafeEnabled { + mi := &file_StorageService_proto_msgTypes[13] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *CallLinkRecord) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CallLinkRecord) ProtoMessage() {} + +func (x *CallLinkRecord) ProtoReflect() protoreflect.Message { + mi := &file_StorageService_proto_msgTypes[13] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use CallLinkRecord.ProtoReflect.Descriptor instead. +func (*CallLinkRecord) Descriptor() ([]byte, []int) { + return file_StorageService_proto_rawDescGZIP(), []int{13} +} + +func (x *CallLinkRecord) GetRootKey() []byte { + if x != nil { + return x.RootKey + } + return nil +} + +func (x *CallLinkRecord) GetAdminPasskey() []byte { + if x != nil { + return x.AdminPasskey + } + return nil +} + +func (x *CallLinkRecord) GetDeletedAtTimestampMs() uint64 { + if x != nil { + return x.DeletedAtTimestampMs + } + return 0 +} + type ManifestRecord_Identifier struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -1679,7 +1759,7 @@ type ManifestRecord_Identifier struct { func (x *ManifestRecord_Identifier) Reset() { *x = ManifestRecord_Identifier{} if protoimpl.UnsafeEnabled { - mi := &file_StorageService_proto_msgTypes[13] + mi := &file_StorageService_proto_msgTypes[14] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1692,7 +1772,7 @@ func (x *ManifestRecord_Identifier) String() string { func (*ManifestRecord_Identifier) ProtoMessage() {} func (x *ManifestRecord_Identifier) ProtoReflect() protoreflect.Message { - mi := &file_StorageService_proto_msgTypes[13] + mi := &file_StorageService_proto_msgTypes[14] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1734,7 +1814,7 @@ type ContactRecord_Name struct { func (x *ContactRecord_Name) Reset() { *x = ContactRecord_Name{} if protoimpl.UnsafeEnabled { - mi := &file_StorageService_proto_msgTypes[14] + mi := &file_StorageService_proto_msgTypes[15] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1747,7 +1827,7 @@ func (x *ContactRecord_Name) String() string { func (*ContactRecord_Name) ProtoMessage() {} func (x *ContactRecord_Name) ProtoReflect() protoreflect.Message { - mi := &file_StorageService_proto_msgTypes[14] + mi := &file_StorageService_proto_msgTypes[15] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1793,7 +1873,7 @@ type AccountRecord_PinnedConversation struct { func (x *AccountRecord_PinnedConversation) Reset() { *x = AccountRecord_PinnedConversation{} if protoimpl.UnsafeEnabled { - mi := &file_StorageService_proto_msgTypes[15] + mi := &file_StorageService_proto_msgTypes[16] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1806,7 +1886,7 @@ func (x *AccountRecord_PinnedConversation) String() string { func (*AccountRecord_PinnedConversation) ProtoMessage() {} func (x *AccountRecord_PinnedConversation) ProtoReflect() protoreflect.Message { - mi := &file_StorageService_proto_msgTypes[15] + mi := &file_StorageService_proto_msgTypes[16] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1887,7 +1967,7 @@ type AccountRecord_UsernameLink struct { func (x *AccountRecord_UsernameLink) Reset() { *x = AccountRecord_UsernameLink{} if protoimpl.UnsafeEnabled { - mi := &file_StorageService_proto_msgTypes[16] + mi := &file_StorageService_proto_msgTypes[17] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1900,7 +1980,7 @@ func (x *AccountRecord_UsernameLink) String() string { func (*AccountRecord_UsernameLink) ProtoMessage() {} func (x *AccountRecord_UsernameLink) ProtoReflect() protoreflect.Message { - mi := &file_StorageService_proto_msgTypes[16] + mi := &file_StorageService_proto_msgTypes[17] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1949,7 +2029,7 @@ type AccountRecord_PinnedConversation_Contact struct { func (x *AccountRecord_PinnedConversation_Contact) Reset() { *x = AccountRecord_PinnedConversation_Contact{} if protoimpl.UnsafeEnabled { - mi := &file_StorageService_proto_msgTypes[17] + mi := &file_StorageService_proto_msgTypes[18] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1962,7 +2042,7 @@ func (x *AccountRecord_PinnedConversation_Contact) String() string { func (*AccountRecord_PinnedConversation_Contact) ProtoMessage() {} func (x *AccountRecord_PinnedConversation_Contact) ProtoReflect() protoreflect.Message { - mi := &file_StorageService_proto_msgTypes[17] + mi := &file_StorageService_proto_msgTypes[18] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2010,7 +2090,7 @@ func file_StorageService_proto_rawDescGZIP() []byte { } var file_StorageService_proto_enumTypes = make([]protoimpl.EnumInfo, 6) -var file_StorageService_proto_msgTypes = make([]protoimpl.MessageInfo, 18) +var file_StorageService_proto_msgTypes = make([]protoimpl.MessageInfo, 19) var file_StorageService_proto_goTypes = []any{ (OptionalBool)(0), // 0: signalservice.OptionalBool (ManifestRecord_Identifier_Type)(0), // 1: signalservice.ManifestRecord.Identifier.Type @@ -2031,38 +2111,40 @@ var file_StorageService_proto_goTypes = []any{ (*Payments)(nil), // 16: signalservice.Payments (*AccountRecord)(nil), // 17: signalservice.AccountRecord (*StoryDistributionListRecord)(nil), // 18: signalservice.StoryDistributionListRecord - (*ManifestRecord_Identifier)(nil), // 19: signalservice.ManifestRecord.Identifier - (*ContactRecord_Name)(nil), // 20: signalservice.ContactRecord.Name - (*AccountRecord_PinnedConversation)(nil), // 21: signalservice.AccountRecord.PinnedConversation - (*AccountRecord_UsernameLink)(nil), // 22: signalservice.AccountRecord.UsernameLink - (*AccountRecord_PinnedConversation_Contact)(nil), // 23: signalservice.AccountRecord.PinnedConversation.Contact + (*CallLinkRecord)(nil), // 19: signalservice.CallLinkRecord + (*ManifestRecord_Identifier)(nil), // 20: signalservice.ManifestRecord.Identifier + (*ContactRecord_Name)(nil), // 21: signalservice.ContactRecord.Name + (*AccountRecord_PinnedConversation)(nil), // 22: signalservice.AccountRecord.PinnedConversation + (*AccountRecord_UsernameLink)(nil), // 23: signalservice.AccountRecord.UsernameLink + (*AccountRecord_PinnedConversation_Contact)(nil), // 24: signalservice.AccountRecord.PinnedConversation.Contact } var file_StorageService_proto_depIdxs = []int32{ 7, // 0: signalservice.StorageItems.items:type_name -> signalservice.StorageItem 6, // 1: signalservice.WriteOperation.manifest:type_name -> signalservice.StorageManifest 7, // 2: signalservice.WriteOperation.insertItem:type_name -> signalservice.StorageItem - 19, // 3: signalservice.ManifestRecord.identifiers:type_name -> signalservice.ManifestRecord.Identifier + 20, // 3: signalservice.ManifestRecord.identifiers:type_name -> signalservice.ManifestRecord.Identifier 13, // 4: signalservice.StorageRecord.contact:type_name -> signalservice.ContactRecord 14, // 5: signalservice.StorageRecord.groupV1:type_name -> signalservice.GroupV1Record 15, // 6: signalservice.StorageRecord.groupV2:type_name -> signalservice.GroupV2Record 17, // 7: signalservice.StorageRecord.account:type_name -> signalservice.AccountRecord 18, // 8: signalservice.StorageRecord.storyDistributionList:type_name -> signalservice.StoryDistributionListRecord - 2, // 9: signalservice.ContactRecord.identityState:type_name -> signalservice.ContactRecord.IdentityState - 20, // 10: signalservice.ContactRecord.nickname:type_name -> signalservice.ContactRecord.Name - 3, // 11: signalservice.GroupV2Record.storySendMode:type_name -> signalservice.GroupV2Record.StorySendMode - 4, // 12: signalservice.AccountRecord.phoneNumberSharingMode:type_name -> signalservice.AccountRecord.PhoneNumberSharingMode - 21, // 13: signalservice.AccountRecord.pinnedConversations:type_name -> signalservice.AccountRecord.PinnedConversation - 16, // 14: signalservice.AccountRecord.payments:type_name -> signalservice.Payments - 0, // 15: signalservice.AccountRecord.storyViewReceiptsEnabled:type_name -> signalservice.OptionalBool - 22, // 16: signalservice.AccountRecord.usernameLink:type_name -> signalservice.AccountRecord.UsernameLink - 1, // 17: signalservice.ManifestRecord.Identifier.type:type_name -> signalservice.ManifestRecord.Identifier.Type - 23, // 18: signalservice.AccountRecord.PinnedConversation.contact:type_name -> signalservice.AccountRecord.PinnedConversation.Contact - 5, // 19: signalservice.AccountRecord.UsernameLink.color:type_name -> signalservice.AccountRecord.UsernameLink.Color - 20, // [20:20] is the sub-list for method output_type - 20, // [20:20] is the sub-list for method input_type - 20, // [20:20] is the sub-list for extension type_name - 20, // [20:20] is the sub-list for extension extendee - 0, // [0:20] is the sub-list for field type_name + 19, // 9: signalservice.StorageRecord.callLink:type_name -> signalservice.CallLinkRecord + 2, // 10: signalservice.ContactRecord.identityState:type_name -> signalservice.ContactRecord.IdentityState + 21, // 11: signalservice.ContactRecord.nickname:type_name -> signalservice.ContactRecord.Name + 3, // 12: signalservice.GroupV2Record.storySendMode:type_name -> signalservice.GroupV2Record.StorySendMode + 4, // 13: signalservice.AccountRecord.phoneNumberSharingMode:type_name -> signalservice.AccountRecord.PhoneNumberSharingMode + 22, // 14: signalservice.AccountRecord.pinnedConversations:type_name -> signalservice.AccountRecord.PinnedConversation + 16, // 15: signalservice.AccountRecord.payments:type_name -> signalservice.Payments + 0, // 16: signalservice.AccountRecord.storyViewReceiptsEnabled:type_name -> signalservice.OptionalBool + 23, // 17: signalservice.AccountRecord.usernameLink:type_name -> signalservice.AccountRecord.UsernameLink + 1, // 18: signalservice.ManifestRecord.Identifier.type:type_name -> signalservice.ManifestRecord.Identifier.Type + 24, // 19: signalservice.AccountRecord.PinnedConversation.contact:type_name -> signalservice.AccountRecord.PinnedConversation.Contact + 5, // 20: signalservice.AccountRecord.UsernameLink.color:type_name -> signalservice.AccountRecord.UsernameLink.Color + 21, // [21:21] is the sub-list for method output_type + 21, // [21:21] is the sub-list for method input_type + 21, // [21:21] is the sub-list for extension type_name + 21, // [21:21] is the sub-list for extension extendee + 0, // [0:21] is the sub-list for field type_name } func init() { file_StorageService_proto_init() } @@ -2228,7 +2310,7 @@ func file_StorageService_proto_init() { } } file_StorageService_proto_msgTypes[13].Exporter = func(v any, i int) any { - switch v := v.(*ManifestRecord_Identifier); i { + switch v := v.(*CallLinkRecord); i { case 0: return &v.state case 1: @@ -2240,7 +2322,7 @@ func file_StorageService_proto_init() { } } file_StorageService_proto_msgTypes[14].Exporter = func(v any, i int) any { - switch v := v.(*ContactRecord_Name); i { + switch v := v.(*ManifestRecord_Identifier); i { case 0: return &v.state case 1: @@ -2252,7 +2334,7 @@ func file_StorageService_proto_init() { } } file_StorageService_proto_msgTypes[15].Exporter = func(v any, i int) any { - switch v := v.(*AccountRecord_PinnedConversation); i { + switch v := v.(*ContactRecord_Name); i { case 0: return &v.state case 1: @@ -2264,7 +2346,7 @@ func file_StorageService_proto_init() { } } file_StorageService_proto_msgTypes[16].Exporter = func(v any, i int) any { - switch v := v.(*AccountRecord_UsernameLink); i { + switch v := v.(*AccountRecord_PinnedConversation); i { case 0: return &v.state case 1: @@ -2276,6 +2358,18 @@ func file_StorageService_proto_init() { } } file_StorageService_proto_msgTypes[17].Exporter = func(v any, i int) any { + switch v := v.(*AccountRecord_UsernameLink); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_StorageService_proto_msgTypes[18].Exporter = func(v any, i int) any { switch v := v.(*AccountRecord_PinnedConversation_Contact); i { case 0: return &v.state @@ -2294,8 +2388,9 @@ func file_StorageService_proto_init() { (*StorageRecord_GroupV2)(nil), (*StorageRecord_Account)(nil), (*StorageRecord_StoryDistributionList)(nil), + (*StorageRecord_CallLink)(nil), } - file_StorageService_proto_msgTypes[15].OneofWrappers = []any{ + file_StorageService_proto_msgTypes[16].OneofWrappers = []any{ (*AccountRecord_PinnedConversation_Contact_)(nil), (*AccountRecord_PinnedConversation_LegacyGroupId)(nil), (*AccountRecord_PinnedConversation_GroupMasterKey)(nil), @@ -2306,7 +2401,7 @@ func file_StorageService_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_StorageService_proto_rawDesc, NumEnums: 6, - NumMessages: 18, + NumMessages: 19, NumExtensions: 0, NumServices: 0, }, diff --git a/pkg/signalmeow/protobuf/StorageService.pb.raw b/pkg/signalmeow/protobuf/StorageService.pb.raw index bd966cb8940f6481e516cf67d985ee329185222f..2dea02fae9b6d83f802dedf2454956c05857ef2e 100644 GIT binary patch delta 255 zcmaE=y-jz+B}T^2lP@#QVZ1iEfGL@=c=8pd6d@sAE>34hAD?(1Pd{$~cBMtko2{9n z8Eu8Exj2#&b8>t#^Rgw_6&N+Rjb!zTGt=`DbBa@o$}*Ev^_-#7L8;04MJXN(L2wP5 zr?FfXs8?!YzCkVzBQsUxCOv%m63rH+3&IU>|fu&Kz rgp9aEQc`nLOHxxDOF}YpQ;SOya|?WnC76L~S%T2y*dUUVGev6vbz)HK delta 43 zcmV+`0M!4sE#)h)(g6YFlhXm50mqYY0%HMWlhgua10v-Dvq}S70kh%+(-4z77JQJu B5d;7L diff --git a/pkg/signalmeow/protobuf/StorageService.proto b/pkg/signalmeow/protobuf/StorageService.proto index ac26d38..304e73f 100644 --- a/pkg/signalmeow/protobuf/StorageService.proto +++ b/pkg/signalmeow/protobuf/StorageService.proto @@ -50,6 +50,7 @@ message ManifestRecord { GROUPV2 = 3; ACCOUNT = 4; STORY_DISTRIBUTION_LIST = 5; + CALL_LINK = 7; } bytes raw = 1; @@ -69,6 +70,7 @@ message StorageRecord { GroupV2Record groupV2 = 3; AccountRecord account = 4; StoryDistributionListRecord storyDistributionList = 5; + CallLinkRecord callLink = 7; } } @@ -227,3 +229,9 @@ message StoryDistributionListRecord { bool allowsReplies = 5; bool isBlockList = 6; } + +message CallLinkRecord { + bytes rootKey = 1; + bytes adminPasskey = 2; + uint64 deletedAtTimestampMs = 3; +} diff --git a/pkg/signalmeow/protobuf/update-protos.sh b/pkg/signalmeow/protobuf/update-protos.sh index 43790f4..87eb1ec 100755 --- a/pkg/signalmeow/protobuf/update-protos.sh +++ b/pkg/signalmeow/protobuf/update-protos.sh @@ -1,8 +1,8 @@ #!/bin/bash set -euo pipefail -ANDROID_GIT_REVISION=${1:-ab7bdc3c03ecda2d746fd56cfd747f56feab7b17} -DESKTOP_GIT_REVISION=${1:-1898e964adcfc8a9096b4aaebff895813fb4f35c} +ANDROID_GIT_REVISION=${1:-69e1146e2c5bbd6f2773dfe12f723e7cc88064be} +DESKTOP_GIT_REVISION=${1:-2640c34bd3eb6d338fbf32621fdf839d2ca3d155} update_proto() { case "$1" in From 8cde7b350ea42fa7a899502617f1d0b5d37a05a0 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Wed, 2 Oct 2024 21:25:09 +0300 Subject: [PATCH 202/580] signalmeow/storageservice: don't stop reading records on error --- pkg/signalmeow/storageservice.go | 33 +++++++++++++++++++++++--------- 1 file changed, 24 insertions(+), 9 deletions(-) diff --git a/pkg/signalmeow/storageservice.go b/pkg/signalmeow/storageservice.go index fab5eed..f062f12 100644 --- a/pkg/signalmeow/storageservice.go +++ b/pkg/signalmeow/storageservice.go @@ -252,29 +252,44 @@ func (cli *Client) fetchStorageRecords(ctx context.Context, storageKey []byte, i } items = append(items, itemChunk...) } - records := make([]*DecryptedStorageRecord, len(items)) + records := make([]*DecryptedStorageRecord, 0, len(items)) + log := zerolog.Ctx(ctx) for i, encryptedItem := range items { base64Key := base64.StdEncoding.EncodeToString(encryptedItem.GetKey()) + itemType, ok := inputRecords[base64Key] + if !ok { + log.Warn().Int("item_index", i).Str("item_key", base64Key).Msg("Received unexpected storage item") + continue + } itemKey := deriveStorageItemKey(storageKey, base64Key) decryptedItemBytes, err := decryptBytes(itemKey, encryptedItem.GetValue()) if err != nil { - return nil, nil, fmt.Errorf("failed to decrypt storage item #%d (%s): %w", i+1, base64Key, err) + log.Warn().Err(err). + Stringer("item_type", itemType). + Int("item_index", i). + Str("item_key", base64Key). + Msg("Failed to decrypt storage item") + continue } var decryptedItem signalpb.StorageRecord err = proto.Unmarshal(decryptedItemBytes, &decryptedItem) if err != nil { - return nil, nil, fmt.Errorf("failed to unmarshal decrypted storage item #%d (%s): %w", i+1, base64Key, err) - } - itemType, ok := inputRecords[base64Key] - if !ok { - return nil, nil, fmt.Errorf("received unexpected storage item at index #%d: %s", i+1, base64Key) + logEvt := log.Warn().Err(err). + Stringer("item_type", itemType). + Int("item_index", i). + Str("item_key", base64Key) + if log.GetLevel() == zerolog.TraceLevel { + logEvt.Str("item_data", base64.StdEncoding.EncodeToString(decryptedItemBytes)) + } + logEvt.Msg("Failed to unmarshal storage item") + continue } delete(inputRecords, base64Key) - records[i] = &DecryptedStorageRecord{ + records = append(records, &DecryptedStorageRecord{ ItemType: itemType, StorageID: base64Key, StorageRecord: &decryptedItem, - } + }) } missingKeys := maps.Keys(inputRecords) return records, missingKeys, nil From b73c822a25245d2742b7b0dccd4387e83abee0e2 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Wed, 2 Oct 2024 21:57:32 +0300 Subject: [PATCH 203/580] signalmeow/storageservice: improve logging when syncing storage --- pkg/connector/connector.go | 1 + pkg/signalmeow/client.go | 1 + pkg/signalmeow/storageservice.go | 5 +++-- 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/pkg/connector/connector.go b/pkg/connector/connector.go index e5995ad..8cdb368 100644 --- a/pkg/connector/connector.go +++ b/pkg/connector/connector.go @@ -100,6 +100,7 @@ func (s *SignalConnector) LoadUserLogin(ctx context.Context, login *bridgev2.Use if device != nil { sc.Client = &signalmeow.Client{ Store: device, + Log: sc.UserLogin.Log.With().Str("component", "signalmeow").Logger(), EventHandler: sc.handleSignalEvent, SyncContactsOnConnect: s.Config.SyncContactsOnStartup, diff --git a/pkg/signalmeow/client.go b/pkg/signalmeow/client.go index 14db3b7..fcb463a 100644 --- a/pkg/signalmeow/client.go +++ b/pkg/signalmeow/client.go @@ -33,6 +33,7 @@ import ( type Client struct { Store *store.Device + Log zerolog.Logger SenderCertificateWithE164 *libsignalgo.SenderCertificate SenderCertificateNoE164 *libsignalgo.SenderCertificate diff --git a/pkg/signalmeow/storageservice.go b/pkg/signalmeow/storageservice.go index f062f12..f2385f3 100644 --- a/pkg/signalmeow/storageservice.go +++ b/pkg/signalmeow/storageservice.go @@ -40,7 +40,8 @@ import ( ) func (cli *Client) SyncStorage(ctx context.Context) { - log := zerolog.Ctx(ctx).With().Str("action", "sync storage").Logger() + log := cli.Log.With().Str("action", "sync storage").Logger() + ctx = log.WithContext(ctx) // TODO only fetch changed entries update, err := cli.FetchStorage(ctx, cli.Store.MasterKey, 0, nil) if err != nil { @@ -112,7 +113,7 @@ func (cli *Client) SyncStorage(ctx context.Context) { case *signalpb.StorageRecord_GroupV1, *signalpb.StorageRecord_StoryDistributionList: // irrelevant data default: - log.Warn().Str("type", fmt.Sprintf("%T", data)).Msg("Unknown storage record type") + log.Warn().Type("type", data).Str("item_id", record.StorageID).Msg("Unknown storage record type") } } } From 9c492d0d27caf630b7c1da1ead9b405496207f85 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Wed, 2 Oct 2024 21:57:50 +0300 Subject: [PATCH 204/580] signalmeow/storageservice: fix decrypting items --- pkg/signalmeow/profile.go | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) diff --git a/pkg/signalmeow/profile.go b/pkg/signalmeow/profile.go index 81a6c86..1a7571c 100644 --- a/pkg/signalmeow/profile.go +++ b/pkg/signalmeow/profile.go @@ -17,6 +17,7 @@ package signalmeow import ( + "bytes" "context" "crypto/aes" "crypto/cipher" @@ -281,25 +282,19 @@ func decryptBytes(key []byte, encryptedText []byte) ([]byte, error) { } nonce := encryptedText[:NONCE_LENGTH] ciphertext := encryptedText[NONCE_LENGTH:] - padded, err := AesgcmDecrypt(key, nonce, ciphertext, []byte{}) + decrypted, err := AesgcmDecrypt(key, nonce, ciphertext, []byte{}) if err != nil { return nil, err } - paddedLength := len(padded) - plaintextLength := 0 - for i := paddedLength - 1; i >= 0; i-- { - if padded[i] != byte(0) { - plaintextLength = i + 1 - break - } - } - returnString := padded[:plaintextLength] - return returnString, nil + return decrypted, nil } func decryptString(key *libsignalgo.ProfileKey, encryptedText []byte) (string, error) { data, err := decryptBytes(key[:], encryptedText) - return string(data), err + if err != nil { + return "", err + } + return string(bytes.TrimRight(data, "\x00")), nil } func encryptString(key libsignalgo.ProfileKey, plaintext string, paddedLength int) ([]byte, error) { From ce776bc1a086ad851d2979380b922fdf3c703fae Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Thu, 3 Oct 2024 11:54:10 +0300 Subject: [PATCH 205/580] dependencies: update mautrix-go --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 876e05f..089636c 100644 --- a/go.mod +++ b/go.mod @@ -18,7 +18,7 @@ require ( golang.org/x/exp v0.0.0-20240909161429-701f63a606c0 golang.org/x/net v0.29.0 google.golang.org/protobuf v1.34.2 - maunium.net/go/mautrix v0.21.1-0.20240930142122-741b4e823ffb + maunium.net/go/mautrix v0.21.1-0.20241002213655-b9fdcd0dcefb ) require ( diff --git a/go.sum b/go.sum index d76e998..40815cb 100644 --- a/go.sum +++ b/go.sum @@ -97,5 +97,5 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= maunium.net/go/mauflag v1.0.0 h1:YiaRc0tEI3toYtJMRIfjP+jklH45uDHtT80nUamyD4M= maunium.net/go/mauflag v1.0.0/go.mod h1:nLivPOpTpHnpzEh8jEdSL9UqO9+/KBJFmNRlwKfkPeA= -maunium.net/go/mautrix v0.21.1-0.20240930142122-741b4e823ffb h1:X19nOFvy3GINE6TbSshH5OiOgqbZqEgfu8e0Nsi2iAk= -maunium.net/go/mautrix v0.21.1-0.20240930142122-741b4e823ffb/go.mod h1:qN4yYKm3brOUWN8dlR0KPbKwSBGXQ4am/kzSQt/kLmY= +maunium.net/go/mautrix v0.21.1-0.20241002213655-b9fdcd0dcefb h1:mhJibm/mFfC/lHtySTA/e0J2pa/6p4Dy8r/TQv6DpDw= +maunium.net/go/mautrix v0.21.1-0.20241002213655-b9fdcd0dcefb/go.mod h1:qN4yYKm3brOUWN8dlR0KPbKwSBGXQ4am/kzSQt/kLmY= From bf96f62eec8acc79de8b2d4a20e2f354fddb7199 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Thu, 3 Oct 2024 12:39:02 +0300 Subject: [PATCH 206/580] libsignal: update to v0.58.1 --- go.mod | 8 +++---- go.sum | 12 +++++----- pkg/libsignalgo/libsignal | 2 +- pkg/libsignalgo/libsignal-ffi.h | 40 ++++++++++++++++++++++----------- pkg/libsignalgo/version.go | 2 +- 5 files changed, 39 insertions(+), 25 deletions(-) diff --git a/go.mod b/go.mod index 089636c..283e984 100644 --- a/go.mod +++ b/go.mod @@ -2,7 +2,7 @@ module go.mau.fi/mautrix-signal go 1.22.0 -toolchain go1.23.1 +toolchain go1.23.2 require ( github.com/coder/websocket v1.8.12 @@ -12,13 +12,13 @@ require ( github.com/mattn/go-pointer v0.0.1 github.com/rs/zerolog v1.33.0 github.com/stretchr/testify v1.9.0 - github.com/tidwall/gjson v1.17.3 - go.mau.fi/util v0.8.1-0.20240927174413-000d30f9a02a + github.com/tidwall/gjson v1.18.0 + go.mau.fi/util v0.8.1-0.20241003092848-3b49d3e0b9ee golang.org/x/crypto v0.27.0 golang.org/x/exp v0.0.0-20240909161429-701f63a606c0 golang.org/x/net v0.29.0 google.golang.org/protobuf v1.34.2 - maunium.net/go/mautrix v0.21.1-0.20241002213655-b9fdcd0dcefb + maunium.net/go/mautrix v0.21.1-0.20241003093300-7e041c6e76a5 ) require ( diff --git a/go.sum b/go.sum index 40815cb..c8e86e0 100644 --- a/go.sum +++ b/go.sum @@ -57,8 +57,8 @@ github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e/go.mod h1:XV66xRDq github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/tidwall/gjson v1.14.2/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= -github.com/tidwall/gjson v1.17.3 h1:bwWLZU7icoKRG+C+0PNwIKC6FCJO/Q3p2pZvuP0jN94= -github.com/tidwall/gjson v1.17.3/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= +github.com/tidwall/gjson v1.18.0 h1:FIDeeyB800efLX89e5a8Y0BNH+LOngJyGrIWxG2FKQY= +github.com/tidwall/gjson v1.18.0/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA= github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM= github.com/tidwall/pretty v1.2.0 h1:RWIZEg2iJ8/g6fDDYzMpobmaoGh5OLl4AXtGUGPcqCs= @@ -67,8 +67,8 @@ github.com/tidwall/sjson v1.2.5 h1:kLy8mja+1c9jlljvWTlSazM7cKDRfJuR/bOJhcY5NcY= github.com/tidwall/sjson v1.2.5/go.mod h1:Fvgq9kS/6ociJEDnK0Fk1cpYF4FIW6ZF7LAe+6jwd28= github.com/yuin/goldmark v1.7.4 h1:BDXOHExt+A7gwPCJgPIIq7ENvceR7we7rOS9TNoLZeg= github.com/yuin/goldmark v1.7.4/go.mod h1:uzxRWxtg69N339t3louHJ7+O03ezfj6PlliRlaOzY1E= -go.mau.fi/util v0.8.1-0.20240927174413-000d30f9a02a h1:4TrWJ0ooHT9YssDBUgXNU8FiR2cwi9jEAjtaVur4f0M= -go.mau.fi/util v0.8.1-0.20240927174413-000d30f9a02a/go.mod h1:1Ixb8HWoVbl3rT6nAX6nV4iMkzn7KU/KXwE0Rn5RmsQ= +go.mau.fi/util v0.8.1-0.20241003092848-3b49d3e0b9ee h1:/BGpUK7fzVyFgy5KBiyP7ktEDn20vzz/5FTngrXtIEE= +go.mau.fi/util v0.8.1-0.20241003092848-3b49d3e0b9ee/go.mod h1:L9qnqEkhe4KpuYmILrdttKTXL79MwGLyJ4EOskWxO3I= go.mau.fi/zeroconfig v0.1.3 h1:As9wYDKmktjmNZW5i1vn8zvJlmGKHeVxHVIBMXsm4kM= go.mau.fi/zeroconfig v0.1.3/go.mod h1:NcSJkf180JT+1IId76PcMuLTNa1CzsFFZ0nBygIQM70= golang.org/x/crypto v0.27.0 h1:GXm2NjJrPaiv/h1tb2UH8QfgC/hOf/+z0p6PT8o1w7A= @@ -97,5 +97,5 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= maunium.net/go/mauflag v1.0.0 h1:YiaRc0tEI3toYtJMRIfjP+jklH45uDHtT80nUamyD4M= maunium.net/go/mauflag v1.0.0/go.mod h1:nLivPOpTpHnpzEh8jEdSL9UqO9+/KBJFmNRlwKfkPeA= -maunium.net/go/mautrix v0.21.1-0.20241002213655-b9fdcd0dcefb h1:mhJibm/mFfC/lHtySTA/e0J2pa/6p4Dy8r/TQv6DpDw= -maunium.net/go/mautrix v0.21.1-0.20241002213655-b9fdcd0dcefb/go.mod h1:qN4yYKm3brOUWN8dlR0KPbKwSBGXQ4am/kzSQt/kLmY= +maunium.net/go/mautrix v0.21.1-0.20241003093300-7e041c6e76a5 h1:d5xUAixcJkxv9O3Ly/Ga2cU1Ez+WjS9gPIGD872wslw= +maunium.net/go/mautrix v0.21.1-0.20241003093300-7e041c6e76a5/go.mod h1:+fF5qsmXRCEXQZgW5ececC0PI3c7gISHTLcyftP4Bh0= diff --git a/pkg/libsignalgo/libsignal b/pkg/libsignalgo/libsignal index 3917f60..5de6300 160000 --- a/pkg/libsignalgo/libsignal +++ b/pkg/libsignalgo/libsignal @@ -1 +1 @@ -Subproject commit 3917f60919a987573e0599d414bb5d9d6f155fe4 +Subproject commit 5de6300ab21b34984dd0f79214aa6f3c08ac755d diff --git a/pkg/libsignalgo/libsignal-ffi.h b/pkg/libsignalgo/libsignal-ffi.h index 3ed14d2..60015ea 100644 --- a/pkg/libsignalgo/libsignal-ffi.h +++ b/pkg/libsignalgo/libsignal-ffi.h @@ -212,7 +212,9 @@ typedef struct SignalAes256GcmSiv SignalAes256GcmSiv; typedef struct SignalCdsiLookup SignalCdsiLookup; -typedef struct SignalChat SignalChat; +typedef struct SignalChatAuthChatService SignalChatAuthChatService; + +typedef struct SignalChatUnauthChatService SignalChatUnauthChatService; typedef struct SignalCiphertextMessage SignalCiphertextMessage; @@ -567,6 +569,10 @@ typedef struct { SignalCancellationId cancellation_id; } SignalCPromiseFfiCdsiLookupResponse; +typedef SignalChatAuthChatService SignalAuthChat; + +typedef SignalChatUnauthChatService SignalUnauthChat; + typedef struct { uint8_t raw_ip_type; double duration_secs; @@ -634,7 +640,7 @@ typedef void (*SignalReceivedIncomingMessage)(void *ctx, SignalOwnedBuffer envel typedef void (*SignalReceivedQueueEmpty)(void *ctx); -typedef void (*SignalConnectionInterrupted)(void *ctx); +typedef void (*SignalConnectionInterrupted)(void *ctx, SignalFfiError *error); typedef void (*SignalDestroyChatListener)(void *ctx); @@ -1467,6 +1473,8 @@ SignalFfiError *signal_svr3_restore(SignalCPromiseOwnedBufferOfc_uchar *promise, SignalFfiError *signal_svr3_remove(SignalCPromisebool *promise, const SignalTokioAsyncContext *async_runtime, const SignalConnectionManager *connection_manager, const char *username, const char *enclave_password); +SignalFfiError *signal_svr3_rotate(SignalCPromisebool *promise, const SignalTokioAsyncContext *async_runtime, const SignalConnectionManager *connection_manager, SignalBorrowedBuffer share_set, const char *username, const char *enclave_password); + SignalFfiError *signal_lookup_request_destroy(SignalLookupRequest *p); SignalFfiError *signal_lookup_request_new(SignalLookupRequest **out); @@ -1489,7 +1497,9 @@ SignalFfiError *signal_cdsi_lookup_token(SignalOwnedBuffer *out, const SignalCds SignalFfiError *signal_cdsi_lookup_complete(SignalCPromiseFfiCdsiLookupResponse *promise, const SignalTokioAsyncContext *async_runtime, const SignalCdsiLookup *lookup); -SignalFfiError *signal_chat_destroy(SignalChat *p); +SignalFfiError *signal_auth_chat_destroy(SignalAuthChat *p); + +SignalFfiError *signal_unauth_chat_destroy(SignalUnauthChat *p); SignalFfiError *signal_http_request_destroy(SignalHttpRequest *p); @@ -1499,25 +1509,29 @@ SignalFfiError *signal_http_request_new_without_body(SignalHttpRequest **out, co SignalFfiError *signal_http_request_add_header(const SignalHttpRequest *request, const char *name, const char *value); -SignalFfiError *signal_chat_service_new(SignalChat **out, const SignalConnectionManager *connection_manager, const char *username, const char *password, bool receive_stories); +SignalFfiError *signal_chat_service_new_unauth(SignalUnauthChat **out, const SignalConnectionManager *connection_manager); -SignalFfiError *signal_chat_service_disconnect(SignalCPromisebool *promise, const SignalTokioAsyncContext *async_runtime, const SignalChat *chat); +SignalFfiError *signal_chat_service_new_auth(SignalAuthChat **out, const SignalConnectionManager *connection_manager, const char *username, const char *password, bool receive_stories); -SignalFfiError *signal_chat_service_connect_unauth(SignalCPromiseFfiChatServiceDebugInfo *promise, const SignalTokioAsyncContext *async_runtime, const SignalChat *chat); +SignalFfiError *signal_chat_service_disconnect_unauth(SignalCPromisebool *promise, const SignalTokioAsyncContext *async_runtime, const SignalUnauthChat *chat); -SignalFfiError *signal_chat_service_connect_auth(SignalCPromiseFfiChatServiceDebugInfo *promise, const SignalTokioAsyncContext *async_runtime, const SignalChat *chat); +SignalFfiError *signal_chat_service_disconnect_auth(SignalCPromisebool *promise, const SignalTokioAsyncContext *async_runtime, const SignalAuthChat *chat); -SignalFfiError *signal_chat_service_unauth_send(SignalCPromiseFfiChatResponse *promise, const SignalTokioAsyncContext *async_runtime, const SignalChat *chat, const SignalHttpRequest *http_request, uint32_t timeout_millis); +SignalFfiError *signal_chat_service_connect_unauth(SignalCPromiseFfiChatServiceDebugInfo *promise, const SignalTokioAsyncContext *async_runtime, const SignalUnauthChat *chat); -SignalFfiError *signal_chat_service_unauth_send_and_debug(SignalCPromiseFfiResponseAndDebugInfo *promise, const SignalTokioAsyncContext *async_runtime, const SignalChat *chat, const SignalHttpRequest *http_request, uint32_t timeout_millis); +SignalFfiError *signal_chat_service_connect_auth(SignalCPromiseFfiChatServiceDebugInfo *promise, const SignalTokioAsyncContext *async_runtime, const SignalAuthChat *chat); -SignalFfiError *signal_chat_service_auth_send(SignalCPromiseFfiChatResponse *promise, const SignalTokioAsyncContext *async_runtime, const SignalChat *chat, const SignalHttpRequest *http_request, uint32_t timeout_millis); +SignalFfiError *signal_chat_service_unauth_send(SignalCPromiseFfiChatResponse *promise, const SignalTokioAsyncContext *async_runtime, const SignalUnauthChat *chat, const SignalHttpRequest *http_request, uint32_t timeout_millis); -SignalFfiError *signal_chat_service_auth_send_and_debug(SignalCPromiseFfiResponseAndDebugInfo *promise, const SignalTokioAsyncContext *async_runtime, const SignalChat *chat, const SignalHttpRequest *http_request, uint32_t timeout_millis); +SignalFfiError *signal_chat_service_unauth_send_and_debug(SignalCPromiseFfiResponseAndDebugInfo *promise, const SignalTokioAsyncContext *async_runtime, const SignalUnauthChat *chat, const SignalHttpRequest *http_request, uint32_t timeout_millis); -SignalFfiError *signal_chat_service_set_listener_auth(const SignalTokioAsyncContext *runtime, const SignalChat *chat, const SignalFfiMakeChatListenerStruct *make_listener); +SignalFfiError *signal_chat_service_auth_send(SignalCPromiseFfiChatResponse *promise, const SignalTokioAsyncContext *async_runtime, const SignalAuthChat *chat, const SignalHttpRequest *http_request, uint32_t timeout_millis); -SignalFfiError *signal_chat_service_set_listener_unauth(const SignalTokioAsyncContext *runtime, const SignalChat *chat, const SignalFfiMakeChatListenerStruct *make_listener); +SignalFfiError *signal_chat_service_auth_send_and_debug(SignalCPromiseFfiResponseAndDebugInfo *promise, const SignalTokioAsyncContext *async_runtime, const SignalAuthChat *chat, const SignalHttpRequest *http_request, uint32_t timeout_millis); + +SignalFfiError *signal_chat_service_set_listener_auth(const SignalTokioAsyncContext *runtime, const SignalAuthChat *chat, const SignalFfiMakeChatListenerStruct *make_listener); + +SignalFfiError *signal_chat_service_set_listener_unauth(const SignalTokioAsyncContext *runtime, const SignalUnauthChat *chat, const SignalFfiMakeChatListenerStruct *make_listener); SignalFfiError *signal_server_message_ack_destroy(SignalServerMessageAck *p); diff --git a/pkg/libsignalgo/version.go b/pkg/libsignalgo/version.go index c8272f5..a15914c 100644 --- a/pkg/libsignalgo/version.go +++ b/pkg/libsignalgo/version.go @@ -2,4 +2,4 @@ package libsignalgo -const Version = "v0.57.1" +const Version = "v0.58.1" From c4c57a8fe0c2fcfef6de487bb43cd75087d4ee0b Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Mon, 14 Oct 2024 12:37:15 +0300 Subject: [PATCH 207/580] .github: update bug report template --- .github/ISSUE_TEMPLATE/bug.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/.github/ISSUE_TEMPLATE/bug.md b/.github/ISSUE_TEMPLATE/bug.md index 02ed284..18862a5 100644 --- a/.github/ISSUE_TEMPLATE/bug.md +++ b/.github/ISSUE_TEMPLATE/bug.md @@ -5,3 +5,10 @@ about: If something is definitely wrong in the bridge (rather than just a setup labels: bug --- + + From b9dc3d4707b061f4943f4c5fbf2035bb17c20915 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Mon, 14 Oct 2024 12:37:30 +0300 Subject: [PATCH 208/580] signalmeow/receiving: add timestamp for call messages --- pkg/signalmeow/receiving.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/pkg/signalmeow/receiving.go b/pkg/signalmeow/receiving.go index ecd33f7..1961709 100644 --- a/pkg/signalmeow/receiving.go +++ b/pkg/signalmeow/receiving.go @@ -836,6 +836,8 @@ func (cli *Client) handleDecryptedResult( Sender: theirServiceID.UUID, ChatID: theirServiceID.String(), }, + // CallMessage doesn't have its own timestamp, use one from the envelope + Timestamp: envelope.GetTimestamp(), IsRinging: content.CallMessage.Offer != nil, }) } From 97e8f3eb5afa58b45e10e6aadc34edcf1f40cdae Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Tue, 15 Oct 2024 17:08:56 +0300 Subject: [PATCH 209/580] signalmeow: update protobufs --- pkg/msgconv/from-signal.go | 6 +- .../protobuf/ContactDiscovery.pb.go | 48 +- pkg/signalmeow/protobuf/DeviceName.pb.go | 26 +- pkg/signalmeow/protobuf/Groups.pb.go | 884 ++------ pkg/signalmeow/protobuf/Provisioning.pb.go | 70 +- pkg/signalmeow/protobuf/SignalService.pb.go | 1804 +++-------------- pkg/signalmeow/protobuf/SignalService.pb.raw | Bin 19130 -> 19130 bytes pkg/signalmeow/protobuf/SignalService.proto | 3 +- .../protobuf/StickerResources.pb.go | 48 +- pkg/signalmeow/protobuf/StorageService.pb.go | 438 +--- pkg/signalmeow/protobuf/StorageService.pb.raw | Bin 5814 -> 5934 bytes pkg/signalmeow/protobuf/StorageService.proto | 2 + .../protobuf/UnidentifiedDelivery.pb.go | 136 +- .../protobuf/WebSocketResources.pb.go | 70 +- pkg/signalmeow/protobuf/update-protos.sh | 4 +- 15 files changed, 671 insertions(+), 2868 deletions(-) diff --git a/pkg/msgconv/from-signal.go b/pkg/msgconv/from-signal.go index 4645dd0..9b27c07 100644 --- a/pkg/msgconv/from-signal.go +++ b/pkg/msgconv/from-signal.go @@ -237,8 +237,8 @@ func (mc *MessageConverter) convertContactToVCard(ctx context.Context, contact * HonorificSuffix: name.GetSuffix(), }) } - if name.GetDisplayName() != "" { - card.SetValue(vcard.FieldFormattedName, name.GetDisplayName()) + if name.GetNickname() != "" { + card.SetValue(vcard.FieldNickname, name.GetNickname()) } if contact.GetOrganization() != "" { card.SetValue(vcard.FieldOrganization, contact.GetOrganization()) @@ -320,7 +320,7 @@ func (mc *MessageConverter) convertContactToMatrix(ctx context.Context, contact } } data := buf.Bytes() - displayName := contact.GetName().GetDisplayName() + displayName := contact.GetName().GetNickname() if displayName == "" { displayName = contact.GetName().GetGivenName() if contact.GetName().GetFamilyName() != "" { diff --git a/pkg/signalmeow/protobuf/ContactDiscovery.pb.go b/pkg/signalmeow/protobuf/ContactDiscovery.pb.go index f15eba4..6fd86ab 100644 --- a/pkg/signalmeow/protobuf/ContactDiscovery.pb.go +++ b/pkg/signalmeow/protobuf/ContactDiscovery.pb.go @@ -1,6 +1,6 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.34.2 +// protoc-gen-go v1.35.1 // protoc v3.21.12 // source: ContactDiscovery.proto @@ -54,11 +54,9 @@ type CDSClientRequest struct { func (x *CDSClientRequest) Reset() { *x = CDSClientRequest{} - if protoimpl.UnsafeEnabled { - mi := &file_ContactDiscovery_proto_msgTypes[0] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_ContactDiscovery_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *CDSClientRequest) String() string { @@ -69,7 +67,7 @@ func (*CDSClientRequest) ProtoMessage() {} func (x *CDSClientRequest) ProtoReflect() protoreflect.Message { mi := &file_ContactDiscovery_proto_msgTypes[0] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -166,11 +164,9 @@ type CDSClientResponse struct { func (x *CDSClientResponse) Reset() { *x = CDSClientResponse{} - if protoimpl.UnsafeEnabled { - mi := &file_ContactDiscovery_proto_msgTypes[1] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_ContactDiscovery_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *CDSClientResponse) String() string { @@ -181,7 +177,7 @@ func (*CDSClientResponse) ProtoMessage() {} func (x *CDSClientResponse) ProtoReflect() protoreflect.Message { mi := &file_ContactDiscovery_proto_msgTypes[1] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -245,32 +241,6 @@ func file_ContactDiscovery_proto_init() { if File_ContactDiscovery_proto != nil { return } - if !protoimpl.UnsafeEnabled { - file_ContactDiscovery_proto_msgTypes[0].Exporter = func(v any, i int) any { - switch v := v.(*CDSClientRequest); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_ContactDiscovery_proto_msgTypes[1].Exporter = func(v any, i int) any { - switch v := v.(*CDSClientResponse); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - } type x struct{} out := protoimpl.TypeBuilder{ File: protoimpl.DescBuilder{ diff --git a/pkg/signalmeow/protobuf/DeviceName.pb.go b/pkg/signalmeow/protobuf/DeviceName.pb.go index 27dada3..8207918 100644 --- a/pkg/signalmeow/protobuf/DeviceName.pb.go +++ b/pkg/signalmeow/protobuf/DeviceName.pb.go @@ -1,6 +1,6 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.34.2 +// protoc-gen-go v1.35.1 // protoc v3.21.12 // source: DeviceName.proto @@ -37,11 +37,9 @@ type DeviceName struct { func (x *DeviceName) Reset() { *x = DeviceName{} - if protoimpl.UnsafeEnabled { - mi := &file_DeviceName_proto_msgTypes[0] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_DeviceName_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *DeviceName) String() string { @@ -52,7 +50,7 @@ func (*DeviceName) ProtoMessage() {} func (x *DeviceName) ProtoReflect() protoreflect.Message { mi := &file_DeviceName_proto_msgTypes[0] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -122,20 +120,6 @@ func file_DeviceName_proto_init() { if File_DeviceName_proto != nil { return } - if !protoimpl.UnsafeEnabled { - file_DeviceName_proto_msgTypes[0].Exporter = func(v any, i int) any { - switch v := v.(*DeviceName); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - } type x struct{} out := protoimpl.TypeBuilder{ File: protoimpl.DescBuilder{ diff --git a/pkg/signalmeow/protobuf/Groups.pb.go b/pkg/signalmeow/protobuf/Groups.pb.go index e76b7c1..b10d66a 100644 --- a/pkg/signalmeow/protobuf/Groups.pb.go +++ b/pkg/signalmeow/protobuf/Groups.pb.go @@ -5,7 +5,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.34.2 +// protoc-gen-go v1.35.1 // protoc v3.21.12 // source: Groups.proto @@ -147,11 +147,9 @@ type AvatarUploadAttributes struct { func (x *AvatarUploadAttributes) Reset() { *x = AvatarUploadAttributes{} - if protoimpl.UnsafeEnabled { - mi := &file_Groups_proto_msgTypes[0] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_Groups_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *AvatarUploadAttributes) String() string { @@ -162,7 +160,7 @@ func (*AvatarUploadAttributes) ProtoMessage() {} func (x *AvatarUploadAttributes) ProtoReflect() protoreflect.Message { mi := &file_Groups_proto_msgTypes[0] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -240,11 +238,9 @@ type Member struct { func (x *Member) Reset() { *x = Member{} - if protoimpl.UnsafeEnabled { - mi := &file_Groups_proto_msgTypes[1] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_Groups_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *Member) String() string { @@ -255,7 +251,7 @@ func (*Member) ProtoMessage() {} func (x *Member) ProtoReflect() protoreflect.Message { mi := &file_Groups_proto_msgTypes[1] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -317,11 +313,9 @@ type PendingMember struct { func (x *PendingMember) Reset() { *x = PendingMember{} - if protoimpl.UnsafeEnabled { - mi := &file_Groups_proto_msgTypes[2] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_Groups_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *PendingMember) String() string { @@ -332,7 +326,7 @@ func (*PendingMember) ProtoMessage() {} func (x *PendingMember) ProtoReflect() protoreflect.Message { mi := &file_Groups_proto_msgTypes[2] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -381,11 +375,9 @@ type RequestingMember struct { func (x *RequestingMember) Reset() { *x = RequestingMember{} - if protoimpl.UnsafeEnabled { - mi := &file_Groups_proto_msgTypes[3] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_Groups_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *RequestingMember) String() string { @@ -396,7 +388,7 @@ func (*RequestingMember) ProtoMessage() {} func (x *RequestingMember) ProtoReflect() protoreflect.Message { mi := &file_Groups_proto_msgTypes[3] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -450,11 +442,9 @@ type BannedMember struct { func (x *BannedMember) Reset() { *x = BannedMember{} - if protoimpl.UnsafeEnabled { - mi := &file_Groups_proto_msgTypes[4] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_Groups_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *BannedMember) String() string { @@ -465,7 +455,7 @@ func (*BannedMember) ProtoMessage() {} func (x *BannedMember) ProtoReflect() protoreflect.Message { mi := &file_Groups_proto_msgTypes[4] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -506,11 +496,9 @@ type AccessControl struct { func (x *AccessControl) Reset() { *x = AccessControl{} - if protoimpl.UnsafeEnabled { - mi := &file_Groups_proto_msgTypes[5] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_Groups_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *AccessControl) String() string { @@ -521,7 +509,7 @@ func (*AccessControl) ProtoMessage() {} func (x *AccessControl) ProtoReflect() protoreflect.Message { mi := &file_Groups_proto_msgTypes[5] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -579,11 +567,9 @@ type Group struct { func (x *Group) Reset() { *x = Group{} - if protoimpl.UnsafeEnabled { - mi := &file_Groups_proto_msgTypes[6] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_Groups_proto_msgTypes[6] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *Group) String() string { @@ -594,7 +580,7 @@ func (*Group) ProtoMessage() {} func (x *Group) ProtoReflect() protoreflect.Message { mi := &file_Groups_proto_msgTypes[6] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -712,11 +698,9 @@ type GroupChange struct { func (x *GroupChange) Reset() { *x = GroupChange{} - if protoimpl.UnsafeEnabled { - mi := &file_Groups_proto_msgTypes[7] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_Groups_proto_msgTypes[7] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *GroupChange) String() string { @@ -727,7 +711,7 @@ func (*GroupChange) ProtoMessage() {} func (x *GroupChange) ProtoReflect() protoreflect.Message { mi := &file_Groups_proto_msgTypes[7] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -774,11 +758,9 @@ type GroupResponse struct { func (x *GroupResponse) Reset() { *x = GroupResponse{} - if protoimpl.UnsafeEnabled { - mi := &file_Groups_proto_msgTypes[8] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_Groups_proto_msgTypes[8] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *GroupResponse) String() string { @@ -789,7 +771,7 @@ func (*GroupResponse) ProtoMessage() {} func (x *GroupResponse) ProtoReflect() protoreflect.Message { mi := &file_Groups_proto_msgTypes[8] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -829,11 +811,9 @@ type GroupChanges struct { func (x *GroupChanges) Reset() { *x = GroupChanges{} - if protoimpl.UnsafeEnabled { - mi := &file_Groups_proto_msgTypes[9] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_Groups_proto_msgTypes[9] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *GroupChanges) String() string { @@ -844,7 +824,7 @@ func (*GroupChanges) ProtoMessage() {} func (x *GroupChanges) ProtoReflect() protoreflect.Message { mi := &file_Groups_proto_msgTypes[9] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -884,11 +864,9 @@ type GroupChangeResponse struct { func (x *GroupChangeResponse) Reset() { *x = GroupChangeResponse{} - if protoimpl.UnsafeEnabled { - mi := &file_Groups_proto_msgTypes[10] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_Groups_proto_msgTypes[10] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *GroupChangeResponse) String() string { @@ -899,7 +877,7 @@ func (*GroupChangeResponse) ProtoMessage() {} func (x *GroupChangeResponse) ProtoReflect() protoreflect.Message { mi := &file_Groups_proto_msgTypes[10] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -944,11 +922,9 @@ type GroupAttributeBlob struct { func (x *GroupAttributeBlob) Reset() { *x = GroupAttributeBlob{} - if protoimpl.UnsafeEnabled { - mi := &file_Groups_proto_msgTypes[11] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_Groups_proto_msgTypes[11] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *GroupAttributeBlob) String() string { @@ -959,7 +935,7 @@ func (*GroupAttributeBlob) ProtoMessage() {} func (x *GroupAttributeBlob) ProtoReflect() protoreflect.Message { mi := &file_Groups_proto_msgTypes[11] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -1050,11 +1026,9 @@ type GroupInviteLink struct { func (x *GroupInviteLink) Reset() { *x = GroupInviteLink{} - if protoimpl.UnsafeEnabled { - mi := &file_Groups_proto_msgTypes[12] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_Groups_proto_msgTypes[12] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *GroupInviteLink) String() string { @@ -1065,7 +1039,7 @@ func (*GroupInviteLink) ProtoMessage() {} func (x *GroupInviteLink) ProtoReflect() protoreflect.Message { mi := &file_Groups_proto_msgTypes[12] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -1121,11 +1095,9 @@ type GroupJoinInfo struct { func (x *GroupJoinInfo) Reset() { *x = GroupJoinInfo{} - if protoimpl.UnsafeEnabled { - mi := &file_Groups_proto_msgTypes[13] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_Groups_proto_msgTypes[13] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *GroupJoinInfo) String() string { @@ -1136,7 +1108,7 @@ func (*GroupJoinInfo) ProtoMessage() {} func (x *GroupJoinInfo) ProtoReflect() protoreflect.Message { mi := &file_Groups_proto_msgTypes[13] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -1217,11 +1189,9 @@ type GroupExternalCredential struct { func (x *GroupExternalCredential) Reset() { *x = GroupExternalCredential{} - if protoimpl.UnsafeEnabled { - mi := &file_Groups_proto_msgTypes[14] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_Groups_proto_msgTypes[14] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *GroupExternalCredential) String() string { @@ -1232,7 +1202,7 @@ func (*GroupExternalCredential) ProtoMessage() {} func (x *GroupExternalCredential) ProtoReflect() protoreflect.Message { mi := &file_Groups_proto_msgTypes[14] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -1287,11 +1257,9 @@ type GroupChange_Actions struct { func (x *GroupChange_Actions) Reset() { *x = GroupChange_Actions{} - if protoimpl.UnsafeEnabled { - mi := &file_Groups_proto_msgTypes[15] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_Groups_proto_msgTypes[15] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *GroupChange_Actions) String() string { @@ -1302,7 +1270,7 @@ func (*GroupChange_Actions) ProtoMessage() {} func (x *GroupChange_Actions) ProtoReflect() protoreflect.Message { mi := &file_Groups_proto_msgTypes[15] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -1496,11 +1464,9 @@ type GroupChange_Actions_AddMemberAction struct { func (x *GroupChange_Actions_AddMemberAction) Reset() { *x = GroupChange_Actions_AddMemberAction{} - if protoimpl.UnsafeEnabled { - mi := &file_Groups_proto_msgTypes[16] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_Groups_proto_msgTypes[16] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *GroupChange_Actions_AddMemberAction) String() string { @@ -1511,7 +1477,7 @@ func (*GroupChange_Actions_AddMemberAction) ProtoMessage() {} func (x *GroupChange_Actions_AddMemberAction) ProtoReflect() protoreflect.Message { mi := &file_Groups_proto_msgTypes[16] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -1550,11 +1516,9 @@ type GroupChange_Actions_DeleteMemberAction struct { func (x *GroupChange_Actions_DeleteMemberAction) Reset() { *x = GroupChange_Actions_DeleteMemberAction{} - if protoimpl.UnsafeEnabled { - mi := &file_Groups_proto_msgTypes[17] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_Groups_proto_msgTypes[17] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *GroupChange_Actions_DeleteMemberAction) String() string { @@ -1565,7 +1529,7 @@ func (*GroupChange_Actions_DeleteMemberAction) ProtoMessage() {} func (x *GroupChange_Actions_DeleteMemberAction) ProtoReflect() protoreflect.Message { mi := &file_Groups_proto_msgTypes[17] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -1598,11 +1562,9 @@ type GroupChange_Actions_ModifyMemberRoleAction struct { func (x *GroupChange_Actions_ModifyMemberRoleAction) Reset() { *x = GroupChange_Actions_ModifyMemberRoleAction{} - if protoimpl.UnsafeEnabled { - mi := &file_Groups_proto_msgTypes[18] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_Groups_proto_msgTypes[18] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *GroupChange_Actions_ModifyMemberRoleAction) String() string { @@ -1613,7 +1575,7 @@ func (*GroupChange_Actions_ModifyMemberRoleAction) ProtoMessage() {} func (x *GroupChange_Actions_ModifyMemberRoleAction) ProtoReflect() protoreflect.Message { mi := &file_Groups_proto_msgTypes[18] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -1654,11 +1616,9 @@ type GroupChange_Actions_ModifyMemberProfileKeyAction struct { func (x *GroupChange_Actions_ModifyMemberProfileKeyAction) Reset() { *x = GroupChange_Actions_ModifyMemberProfileKeyAction{} - if protoimpl.UnsafeEnabled { - mi := &file_Groups_proto_msgTypes[19] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_Groups_proto_msgTypes[19] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *GroupChange_Actions_ModifyMemberProfileKeyAction) String() string { @@ -1669,7 +1629,7 @@ func (*GroupChange_Actions_ModifyMemberProfileKeyAction) ProtoMessage() {} func (x *GroupChange_Actions_ModifyMemberProfileKeyAction) ProtoReflect() protoreflect.Message { mi := &file_Groups_proto_msgTypes[19] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -1715,11 +1675,9 @@ type GroupChange_Actions_AddPendingMemberAction struct { func (x *GroupChange_Actions_AddPendingMemberAction) Reset() { *x = GroupChange_Actions_AddPendingMemberAction{} - if protoimpl.UnsafeEnabled { - mi := &file_Groups_proto_msgTypes[20] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_Groups_proto_msgTypes[20] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *GroupChange_Actions_AddPendingMemberAction) String() string { @@ -1730,7 +1688,7 @@ func (*GroupChange_Actions_AddPendingMemberAction) ProtoMessage() {} func (x *GroupChange_Actions_AddPendingMemberAction) ProtoReflect() protoreflect.Message { mi := &file_Groups_proto_msgTypes[20] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -1762,11 +1720,9 @@ type GroupChange_Actions_DeletePendingMemberAction struct { func (x *GroupChange_Actions_DeletePendingMemberAction) Reset() { *x = GroupChange_Actions_DeletePendingMemberAction{} - if protoimpl.UnsafeEnabled { - mi := &file_Groups_proto_msgTypes[21] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_Groups_proto_msgTypes[21] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *GroupChange_Actions_DeletePendingMemberAction) String() string { @@ -1777,7 +1733,7 @@ func (*GroupChange_Actions_DeletePendingMemberAction) ProtoMessage() {} func (x *GroupChange_Actions_DeletePendingMemberAction) ProtoReflect() protoreflect.Message { mi := &file_Groups_proto_msgTypes[21] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -1811,11 +1767,9 @@ type GroupChange_Actions_PromotePendingMemberAction struct { func (x *GroupChange_Actions_PromotePendingMemberAction) Reset() { *x = GroupChange_Actions_PromotePendingMemberAction{} - if protoimpl.UnsafeEnabled { - mi := &file_Groups_proto_msgTypes[22] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_Groups_proto_msgTypes[22] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *GroupChange_Actions_PromotePendingMemberAction) String() string { @@ -1826,7 +1780,7 @@ func (*GroupChange_Actions_PromotePendingMemberAction) ProtoMessage() {} func (x *GroupChange_Actions_PromotePendingMemberAction) ProtoReflect() protoreflect.Message { mi := &file_Groups_proto_msgTypes[22] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -1875,11 +1829,9 @@ type GroupChange_Actions_PromotePendingPniAciMemberProfileKeyAction struct { func (x *GroupChange_Actions_PromotePendingPniAciMemberProfileKeyAction) Reset() { *x = GroupChange_Actions_PromotePendingPniAciMemberProfileKeyAction{} - if protoimpl.UnsafeEnabled { - mi := &file_Groups_proto_msgTypes[23] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_Groups_proto_msgTypes[23] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *GroupChange_Actions_PromotePendingPniAciMemberProfileKeyAction) String() string { @@ -1890,7 +1842,7 @@ func (*GroupChange_Actions_PromotePendingPniAciMemberProfileKeyAction) ProtoMess func (x *GroupChange_Actions_PromotePendingPniAciMemberProfileKeyAction) ProtoReflect() protoreflect.Message { mi := &file_Groups_proto_msgTypes[23] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -1943,11 +1895,9 @@ type GroupChange_Actions_AddRequestingMemberAction struct { func (x *GroupChange_Actions_AddRequestingMemberAction) Reset() { *x = GroupChange_Actions_AddRequestingMemberAction{} - if protoimpl.UnsafeEnabled { - mi := &file_Groups_proto_msgTypes[24] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_Groups_proto_msgTypes[24] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *GroupChange_Actions_AddRequestingMemberAction) String() string { @@ -1958,7 +1908,7 @@ func (*GroupChange_Actions_AddRequestingMemberAction) ProtoMessage() {} func (x *GroupChange_Actions_AddRequestingMemberAction) ProtoReflect() protoreflect.Message { mi := &file_Groups_proto_msgTypes[24] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -1990,11 +1940,9 @@ type GroupChange_Actions_DeleteRequestingMemberAction struct { func (x *GroupChange_Actions_DeleteRequestingMemberAction) Reset() { *x = GroupChange_Actions_DeleteRequestingMemberAction{} - if protoimpl.UnsafeEnabled { - mi := &file_Groups_proto_msgTypes[25] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_Groups_proto_msgTypes[25] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *GroupChange_Actions_DeleteRequestingMemberAction) String() string { @@ -2005,7 +1953,7 @@ func (*GroupChange_Actions_DeleteRequestingMemberAction) ProtoMessage() {} func (x *GroupChange_Actions_DeleteRequestingMemberAction) ProtoReflect() protoreflect.Message { mi := &file_Groups_proto_msgTypes[25] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -2038,11 +1986,9 @@ type GroupChange_Actions_PromoteRequestingMemberAction struct { func (x *GroupChange_Actions_PromoteRequestingMemberAction) Reset() { *x = GroupChange_Actions_PromoteRequestingMemberAction{} - if protoimpl.UnsafeEnabled { - mi := &file_Groups_proto_msgTypes[26] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_Groups_proto_msgTypes[26] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *GroupChange_Actions_PromoteRequestingMemberAction) String() string { @@ -2053,7 +1999,7 @@ func (*GroupChange_Actions_PromoteRequestingMemberAction) ProtoMessage() {} func (x *GroupChange_Actions_PromoteRequestingMemberAction) ProtoReflect() protoreflect.Message { mi := &file_Groups_proto_msgTypes[26] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -2092,11 +2038,9 @@ type GroupChange_Actions_AddBannedMemberAction struct { func (x *GroupChange_Actions_AddBannedMemberAction) Reset() { *x = GroupChange_Actions_AddBannedMemberAction{} - if protoimpl.UnsafeEnabled { - mi := &file_Groups_proto_msgTypes[27] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_Groups_proto_msgTypes[27] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *GroupChange_Actions_AddBannedMemberAction) String() string { @@ -2107,7 +2051,7 @@ func (*GroupChange_Actions_AddBannedMemberAction) ProtoMessage() {} func (x *GroupChange_Actions_AddBannedMemberAction) ProtoReflect() protoreflect.Message { mi := &file_Groups_proto_msgTypes[27] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -2139,11 +2083,9 @@ type GroupChange_Actions_DeleteBannedMemberAction struct { func (x *GroupChange_Actions_DeleteBannedMemberAction) Reset() { *x = GroupChange_Actions_DeleteBannedMemberAction{} - if protoimpl.UnsafeEnabled { - mi := &file_Groups_proto_msgTypes[28] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_Groups_proto_msgTypes[28] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *GroupChange_Actions_DeleteBannedMemberAction) String() string { @@ -2154,7 +2096,7 @@ func (*GroupChange_Actions_DeleteBannedMemberAction) ProtoMessage() {} func (x *GroupChange_Actions_DeleteBannedMemberAction) ProtoReflect() protoreflect.Message { mi := &file_Groups_proto_msgTypes[28] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -2186,11 +2128,9 @@ type GroupChange_Actions_ModifyTitleAction struct { func (x *GroupChange_Actions_ModifyTitleAction) Reset() { *x = GroupChange_Actions_ModifyTitleAction{} - if protoimpl.UnsafeEnabled { - mi := &file_Groups_proto_msgTypes[29] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_Groups_proto_msgTypes[29] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *GroupChange_Actions_ModifyTitleAction) String() string { @@ -2201,7 +2141,7 @@ func (*GroupChange_Actions_ModifyTitleAction) ProtoMessage() {} func (x *GroupChange_Actions_ModifyTitleAction) ProtoReflect() protoreflect.Message { mi := &file_Groups_proto_msgTypes[29] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -2233,11 +2173,9 @@ type GroupChange_Actions_ModifyDescriptionAction struct { func (x *GroupChange_Actions_ModifyDescriptionAction) Reset() { *x = GroupChange_Actions_ModifyDescriptionAction{} - if protoimpl.UnsafeEnabled { - mi := &file_Groups_proto_msgTypes[30] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_Groups_proto_msgTypes[30] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *GroupChange_Actions_ModifyDescriptionAction) String() string { @@ -2248,7 +2186,7 @@ func (*GroupChange_Actions_ModifyDescriptionAction) ProtoMessage() {} func (x *GroupChange_Actions_ModifyDescriptionAction) ProtoReflect() protoreflect.Message { mi := &file_Groups_proto_msgTypes[30] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -2280,11 +2218,9 @@ type GroupChange_Actions_ModifyAvatarAction struct { func (x *GroupChange_Actions_ModifyAvatarAction) Reset() { *x = GroupChange_Actions_ModifyAvatarAction{} - if protoimpl.UnsafeEnabled { - mi := &file_Groups_proto_msgTypes[31] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_Groups_proto_msgTypes[31] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *GroupChange_Actions_ModifyAvatarAction) String() string { @@ -2295,7 +2231,7 @@ func (*GroupChange_Actions_ModifyAvatarAction) ProtoMessage() {} func (x *GroupChange_Actions_ModifyAvatarAction) ProtoReflect() protoreflect.Message { mi := &file_Groups_proto_msgTypes[31] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -2327,11 +2263,9 @@ type GroupChange_Actions_ModifyDisappearingMessagesTimerAction struct { func (x *GroupChange_Actions_ModifyDisappearingMessagesTimerAction) Reset() { *x = GroupChange_Actions_ModifyDisappearingMessagesTimerAction{} - if protoimpl.UnsafeEnabled { - mi := &file_Groups_proto_msgTypes[32] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_Groups_proto_msgTypes[32] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *GroupChange_Actions_ModifyDisappearingMessagesTimerAction) String() string { @@ -2342,7 +2276,7 @@ func (*GroupChange_Actions_ModifyDisappearingMessagesTimerAction) ProtoMessage() func (x *GroupChange_Actions_ModifyDisappearingMessagesTimerAction) ProtoReflect() protoreflect.Message { mi := &file_Groups_proto_msgTypes[32] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -2374,11 +2308,9 @@ type GroupChange_Actions_ModifyAttributesAccessControlAction struct { func (x *GroupChange_Actions_ModifyAttributesAccessControlAction) Reset() { *x = GroupChange_Actions_ModifyAttributesAccessControlAction{} - if protoimpl.UnsafeEnabled { - mi := &file_Groups_proto_msgTypes[33] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_Groups_proto_msgTypes[33] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *GroupChange_Actions_ModifyAttributesAccessControlAction) String() string { @@ -2389,7 +2321,7 @@ func (*GroupChange_Actions_ModifyAttributesAccessControlAction) ProtoMessage() { func (x *GroupChange_Actions_ModifyAttributesAccessControlAction) ProtoReflect() protoreflect.Message { mi := &file_Groups_proto_msgTypes[33] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -2421,11 +2353,9 @@ type GroupChange_Actions_ModifyMembersAccessControlAction struct { func (x *GroupChange_Actions_ModifyMembersAccessControlAction) Reset() { *x = GroupChange_Actions_ModifyMembersAccessControlAction{} - if protoimpl.UnsafeEnabled { - mi := &file_Groups_proto_msgTypes[34] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_Groups_proto_msgTypes[34] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *GroupChange_Actions_ModifyMembersAccessControlAction) String() string { @@ -2436,7 +2366,7 @@ func (*GroupChange_Actions_ModifyMembersAccessControlAction) ProtoMessage() {} func (x *GroupChange_Actions_ModifyMembersAccessControlAction) ProtoReflect() protoreflect.Message { mi := &file_Groups_proto_msgTypes[34] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -2468,11 +2398,9 @@ type GroupChange_Actions_ModifyAddFromInviteLinkAccessControlAction struct { func (x *GroupChange_Actions_ModifyAddFromInviteLinkAccessControlAction) Reset() { *x = GroupChange_Actions_ModifyAddFromInviteLinkAccessControlAction{} - if protoimpl.UnsafeEnabled { - mi := &file_Groups_proto_msgTypes[35] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_Groups_proto_msgTypes[35] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *GroupChange_Actions_ModifyAddFromInviteLinkAccessControlAction) String() string { @@ -2483,7 +2411,7 @@ func (*GroupChange_Actions_ModifyAddFromInviteLinkAccessControlAction) ProtoMess func (x *GroupChange_Actions_ModifyAddFromInviteLinkAccessControlAction) ProtoReflect() protoreflect.Message { mi := &file_Groups_proto_msgTypes[35] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -2515,11 +2443,9 @@ type GroupChange_Actions_ModifyInviteLinkPasswordAction struct { func (x *GroupChange_Actions_ModifyInviteLinkPasswordAction) Reset() { *x = GroupChange_Actions_ModifyInviteLinkPasswordAction{} - if protoimpl.UnsafeEnabled { - mi := &file_Groups_proto_msgTypes[36] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_Groups_proto_msgTypes[36] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *GroupChange_Actions_ModifyInviteLinkPasswordAction) String() string { @@ -2530,7 +2456,7 @@ func (*GroupChange_Actions_ModifyInviteLinkPasswordAction) ProtoMessage() {} func (x *GroupChange_Actions_ModifyInviteLinkPasswordAction) ProtoReflect() protoreflect.Message { mi := &file_Groups_proto_msgTypes[36] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -2562,11 +2488,9 @@ type GroupChange_Actions_ModifyAnnouncementsOnlyAction struct { func (x *GroupChange_Actions_ModifyAnnouncementsOnlyAction) Reset() { *x = GroupChange_Actions_ModifyAnnouncementsOnlyAction{} - if protoimpl.UnsafeEnabled { - mi := &file_Groups_proto_msgTypes[37] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_Groups_proto_msgTypes[37] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *GroupChange_Actions_ModifyAnnouncementsOnlyAction) String() string { @@ -2577,7 +2501,7 @@ func (*GroupChange_Actions_ModifyAnnouncementsOnlyAction) ProtoMessage() {} func (x *GroupChange_Actions_ModifyAnnouncementsOnlyAction) ProtoReflect() protoreflect.Message { mi := &file_Groups_proto_msgTypes[37] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -2610,11 +2534,9 @@ type GroupChanges_GroupChangeState struct { func (x *GroupChanges_GroupChangeState) Reset() { *x = GroupChanges_GroupChangeState{} - if protoimpl.UnsafeEnabled { - mi := &file_Groups_proto_msgTypes[38] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_Groups_proto_msgTypes[38] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *GroupChanges_GroupChangeState) String() string { @@ -2625,7 +2547,7 @@ func (*GroupChanges_GroupChangeState) ProtoMessage() {} func (x *GroupChanges_GroupChangeState) ProtoReflect() protoreflect.Message { mi := &file_Groups_proto_msgTypes[38] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -2665,11 +2587,9 @@ type GroupInviteLink_GroupInviteLinkContentsV1 struct { func (x *GroupInviteLink_GroupInviteLinkContentsV1) Reset() { *x = GroupInviteLink_GroupInviteLinkContentsV1{} - if protoimpl.UnsafeEnabled { - mi := &file_Groups_proto_msgTypes[39] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_Groups_proto_msgTypes[39] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *GroupInviteLink_GroupInviteLinkContentsV1) String() string { @@ -2680,7 +2600,7 @@ func (*GroupInviteLink_GroupInviteLinkContentsV1) ProtoMessage() {} func (x *GroupInviteLink_GroupInviteLinkContentsV1) ProtoReflect() protoreflect.Message { mi := &file_Groups_proto_msgTypes[39] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -2833,488 +2753,6 @@ func file_Groups_proto_init() { if File_Groups_proto != nil { return } - if !protoimpl.UnsafeEnabled { - file_Groups_proto_msgTypes[0].Exporter = func(v any, i int) any { - switch v := v.(*AvatarUploadAttributes); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_Groups_proto_msgTypes[1].Exporter = func(v any, i int) any { - switch v := v.(*Member); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_Groups_proto_msgTypes[2].Exporter = func(v any, i int) any { - switch v := v.(*PendingMember); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_Groups_proto_msgTypes[3].Exporter = func(v any, i int) any { - switch v := v.(*RequestingMember); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_Groups_proto_msgTypes[4].Exporter = func(v any, i int) any { - switch v := v.(*BannedMember); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_Groups_proto_msgTypes[5].Exporter = func(v any, i int) any { - switch v := v.(*AccessControl); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_Groups_proto_msgTypes[6].Exporter = func(v any, i int) any { - switch v := v.(*Group); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_Groups_proto_msgTypes[7].Exporter = func(v any, i int) any { - switch v := v.(*GroupChange); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_Groups_proto_msgTypes[8].Exporter = func(v any, i int) any { - switch v := v.(*GroupResponse); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_Groups_proto_msgTypes[9].Exporter = func(v any, i int) any { - switch v := v.(*GroupChanges); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_Groups_proto_msgTypes[10].Exporter = func(v any, i int) any { - switch v := v.(*GroupChangeResponse); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_Groups_proto_msgTypes[11].Exporter = func(v any, i int) any { - switch v := v.(*GroupAttributeBlob); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_Groups_proto_msgTypes[12].Exporter = func(v any, i int) any { - switch v := v.(*GroupInviteLink); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_Groups_proto_msgTypes[13].Exporter = func(v any, i int) any { - switch v := v.(*GroupJoinInfo); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_Groups_proto_msgTypes[14].Exporter = func(v any, i int) any { - switch v := v.(*GroupExternalCredential); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_Groups_proto_msgTypes[15].Exporter = func(v any, i int) any { - switch v := v.(*GroupChange_Actions); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_Groups_proto_msgTypes[16].Exporter = func(v any, i int) any { - switch v := v.(*GroupChange_Actions_AddMemberAction); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_Groups_proto_msgTypes[17].Exporter = func(v any, i int) any { - switch v := v.(*GroupChange_Actions_DeleteMemberAction); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_Groups_proto_msgTypes[18].Exporter = func(v any, i int) any { - switch v := v.(*GroupChange_Actions_ModifyMemberRoleAction); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_Groups_proto_msgTypes[19].Exporter = func(v any, i int) any { - switch v := v.(*GroupChange_Actions_ModifyMemberProfileKeyAction); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_Groups_proto_msgTypes[20].Exporter = func(v any, i int) any { - switch v := v.(*GroupChange_Actions_AddPendingMemberAction); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_Groups_proto_msgTypes[21].Exporter = func(v any, i int) any { - switch v := v.(*GroupChange_Actions_DeletePendingMemberAction); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_Groups_proto_msgTypes[22].Exporter = func(v any, i int) any { - switch v := v.(*GroupChange_Actions_PromotePendingMemberAction); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_Groups_proto_msgTypes[23].Exporter = func(v any, i int) any { - switch v := v.(*GroupChange_Actions_PromotePendingPniAciMemberProfileKeyAction); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_Groups_proto_msgTypes[24].Exporter = func(v any, i int) any { - switch v := v.(*GroupChange_Actions_AddRequestingMemberAction); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_Groups_proto_msgTypes[25].Exporter = func(v any, i int) any { - switch v := v.(*GroupChange_Actions_DeleteRequestingMemberAction); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_Groups_proto_msgTypes[26].Exporter = func(v any, i int) any { - switch v := v.(*GroupChange_Actions_PromoteRequestingMemberAction); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_Groups_proto_msgTypes[27].Exporter = func(v any, i int) any { - switch v := v.(*GroupChange_Actions_AddBannedMemberAction); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_Groups_proto_msgTypes[28].Exporter = func(v any, i int) any { - switch v := v.(*GroupChange_Actions_DeleteBannedMemberAction); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_Groups_proto_msgTypes[29].Exporter = func(v any, i int) any { - switch v := v.(*GroupChange_Actions_ModifyTitleAction); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_Groups_proto_msgTypes[30].Exporter = func(v any, i int) any { - switch v := v.(*GroupChange_Actions_ModifyDescriptionAction); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_Groups_proto_msgTypes[31].Exporter = func(v any, i int) any { - switch v := v.(*GroupChange_Actions_ModifyAvatarAction); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_Groups_proto_msgTypes[32].Exporter = func(v any, i int) any { - switch v := v.(*GroupChange_Actions_ModifyDisappearingMessagesTimerAction); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_Groups_proto_msgTypes[33].Exporter = func(v any, i int) any { - switch v := v.(*GroupChange_Actions_ModifyAttributesAccessControlAction); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_Groups_proto_msgTypes[34].Exporter = func(v any, i int) any { - switch v := v.(*GroupChange_Actions_ModifyMembersAccessControlAction); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_Groups_proto_msgTypes[35].Exporter = func(v any, i int) any { - switch v := v.(*GroupChange_Actions_ModifyAddFromInviteLinkAccessControlAction); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_Groups_proto_msgTypes[36].Exporter = func(v any, i int) any { - switch v := v.(*GroupChange_Actions_ModifyInviteLinkPasswordAction); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_Groups_proto_msgTypes[37].Exporter = func(v any, i int) any { - switch v := v.(*GroupChange_Actions_ModifyAnnouncementsOnlyAction); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_Groups_proto_msgTypes[38].Exporter = func(v any, i int) any { - switch v := v.(*GroupChanges_GroupChangeState); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_Groups_proto_msgTypes[39].Exporter = func(v any, i int) any { - switch v := v.(*GroupInviteLink_GroupInviteLinkContentsV1); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - } file_Groups_proto_msgTypes[11].OneofWrappers = []any{ (*GroupAttributeBlob_Title)(nil), (*GroupAttributeBlob_Avatar)(nil), diff --git a/pkg/signalmeow/protobuf/Provisioning.pb.go b/pkg/signalmeow/protobuf/Provisioning.pb.go index efde7da..7a866f3 100644 --- a/pkg/signalmeow/protobuf/Provisioning.pb.go +++ b/pkg/signalmeow/protobuf/Provisioning.pb.go @@ -5,7 +5,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.34.2 +// protoc-gen-go v1.35.1 // protoc v3.21.12 // source: Provisioning.proto @@ -96,11 +96,9 @@ type ProvisioningUuid struct { func (x *ProvisioningUuid) Reset() { *x = ProvisioningUuid{} - if protoimpl.UnsafeEnabled { - mi := &file_Provisioning_proto_msgTypes[0] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_Provisioning_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *ProvisioningUuid) String() string { @@ -111,7 +109,7 @@ func (*ProvisioningUuid) ProtoMessage() {} func (x *ProvisioningUuid) ProtoReflect() protoreflect.Message { mi := &file_Provisioning_proto_msgTypes[0] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -144,11 +142,9 @@ type ProvisionEnvelope struct { func (x *ProvisionEnvelope) Reset() { *x = ProvisionEnvelope{} - if protoimpl.UnsafeEnabled { - mi := &file_Provisioning_proto_msgTypes[1] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_Provisioning_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *ProvisionEnvelope) String() string { @@ -159,7 +155,7 @@ func (*ProvisionEnvelope) ProtoMessage() {} func (x *ProvisionEnvelope) ProtoReflect() protoreflect.Message { mi := &file_Provisioning_proto_msgTypes[1] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -210,11 +206,9 @@ type ProvisionMessage struct { func (x *ProvisionMessage) Reset() { *x = ProvisionMessage{} - if protoimpl.UnsafeEnabled { - mi := &file_Provisioning_proto_msgTypes[2] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_Provisioning_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *ProvisionMessage) String() string { @@ -225,7 +219,7 @@ func (*ProvisionMessage) ProtoMessage() {} func (x *ProvisionMessage) ProtoReflect() protoreflect.Message { mi := &file_Provisioning_proto_msgTypes[2] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -369,44 +363,6 @@ func file_Provisioning_proto_init() { if File_Provisioning_proto != nil { return } - if !protoimpl.UnsafeEnabled { - file_Provisioning_proto_msgTypes[0].Exporter = func(v any, i int) any { - switch v := v.(*ProvisioningUuid); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_Provisioning_proto_msgTypes[1].Exporter = func(v any, i int) any { - switch v := v.(*ProvisionEnvelope); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_Provisioning_proto_msgTypes[2].Exporter = func(v any, i int) any { - switch v := v.(*ProvisionMessage); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - } type x struct{} out := protoimpl.TypeBuilder{ File: protoimpl.DescBuilder{ diff --git a/pkg/signalmeow/protobuf/SignalService.pb.go b/pkg/signalmeow/protobuf/SignalService.pb.go index f96f5d8..9ce328c 100644 --- a/pkg/signalmeow/protobuf/SignalService.pb.go +++ b/pkg/signalmeow/protobuf/SignalService.pb.go @@ -5,7 +5,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.34.2 +// protoc-gen-go v1.35.1 // protoc v3.21.12 // source: SignalService.proto @@ -1724,11 +1724,9 @@ const ( func (x *Envelope) Reset() { *x = Envelope{} - if protoimpl.UnsafeEnabled { - mi := &file_SignalService_proto_msgTypes[0] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_SignalService_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *Envelope) String() string { @@ -1739,7 +1737,7 @@ func (*Envelope) ProtoMessage() {} func (x *Envelope) ProtoReflect() protoreflect.Message { mi := &file_SignalService_proto_msgTypes[0] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -1851,11 +1849,9 @@ type Content struct { func (x *Content) Reset() { *x = Content{} - if protoimpl.UnsafeEnabled { - mi := &file_SignalService_proto_msgTypes[1] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_SignalService_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *Content) String() string { @@ -1866,7 +1862,7 @@ func (*Content) ProtoMessage() {} func (x *Content) ProtoReflect() protoreflect.Message { mi := &file_SignalService_proto_msgTypes[1] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -1974,11 +1970,9 @@ type CallMessage struct { func (x *CallMessage) Reset() { *x = CallMessage{} - if protoimpl.UnsafeEnabled { - mi := &file_SignalService_proto_msgTypes[2] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_SignalService_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *CallMessage) String() string { @@ -1989,7 +1983,7 @@ func (*CallMessage) ProtoMessage() {} func (x *CallMessage) ProtoReflect() protoreflect.Message { mi := &file_SignalService_proto_msgTypes[2] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -2069,11 +2063,9 @@ type BodyRange struct { func (x *BodyRange) Reset() { *x = BodyRange{} - if protoimpl.UnsafeEnabled { - mi := &file_SignalService_proto_msgTypes[3] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_SignalService_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *BodyRange) String() string { @@ -2084,7 +2076,7 @@ func (*BodyRange) ProtoMessage() {} func (x *BodyRange) ProtoReflect() protoreflect.Message { mi := &file_SignalService_proto_msgTypes[3] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -2180,11 +2172,9 @@ type DataMessage struct { func (x *DataMessage) Reset() { *x = DataMessage{} - if protoimpl.UnsafeEnabled { - mi := &file_SignalService_proto_msgTypes[4] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_SignalService_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *DataMessage) String() string { @@ -2195,7 +2185,7 @@ func (*DataMessage) ProtoMessage() {} func (x *DataMessage) ProtoReflect() protoreflect.Message { mi := &file_SignalService_proto_msgTypes[4] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -2367,11 +2357,9 @@ type NullMessage struct { func (x *NullMessage) Reset() { *x = NullMessage{} - if protoimpl.UnsafeEnabled { - mi := &file_SignalService_proto_msgTypes[5] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_SignalService_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *NullMessage) String() string { @@ -2382,7 +2370,7 @@ func (*NullMessage) ProtoMessage() {} func (x *NullMessage) ProtoReflect() protoreflect.Message { mi := &file_SignalService_proto_msgTypes[5] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -2415,11 +2403,9 @@ type ReceiptMessage struct { func (x *ReceiptMessage) Reset() { *x = ReceiptMessage{} - if protoimpl.UnsafeEnabled { - mi := &file_SignalService_proto_msgTypes[6] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_SignalService_proto_msgTypes[6] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *ReceiptMessage) String() string { @@ -2430,7 +2416,7 @@ func (*ReceiptMessage) ProtoMessage() {} func (x *ReceiptMessage) ProtoReflect() protoreflect.Message { mi := &file_SignalService_proto_msgTypes[6] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -2471,11 +2457,9 @@ type TypingMessage struct { func (x *TypingMessage) Reset() { *x = TypingMessage{} - if protoimpl.UnsafeEnabled { - mi := &file_SignalService_proto_msgTypes[7] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_SignalService_proto_msgTypes[7] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *TypingMessage) String() string { @@ -2486,7 +2470,7 @@ func (*TypingMessage) ProtoMessage() {} func (x *TypingMessage) ProtoReflect() protoreflect.Message { mi := &file_SignalService_proto_msgTypes[7] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -2540,11 +2524,9 @@ type StoryMessage struct { func (x *StoryMessage) Reset() { *x = StoryMessage{} - if protoimpl.UnsafeEnabled { - mi := &file_SignalService_proto_msgTypes[8] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_SignalService_proto_msgTypes[8] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *StoryMessage) String() string { @@ -2555,7 +2537,7 @@ func (*StoryMessage) ProtoMessage() {} func (x *StoryMessage) ProtoReflect() protoreflect.Message { mi := &file_SignalService_proto_msgTypes[8] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -2649,11 +2631,9 @@ type Preview struct { func (x *Preview) Reset() { *x = Preview{} - if protoimpl.UnsafeEnabled { - mi := &file_SignalService_proto_msgTypes[9] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_SignalService_proto_msgTypes[9] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *Preview) String() string { @@ -2664,7 +2644,7 @@ func (*Preview) ProtoMessage() {} func (x *Preview) ProtoReflect() protoreflect.Message { mi := &file_SignalService_proto_msgTypes[9] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -2733,11 +2713,9 @@ type TextAttachment struct { func (x *TextAttachment) Reset() { *x = TextAttachment{} - if protoimpl.UnsafeEnabled { - mi := &file_SignalService_proto_msgTypes[10] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_SignalService_proto_msgTypes[10] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *TextAttachment) String() string { @@ -2748,7 +2726,7 @@ func (*TextAttachment) ProtoMessage() {} func (x *TextAttachment) ProtoReflect() protoreflect.Message { mi := &file_SignalService_proto_msgTypes[10] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -2848,11 +2826,9 @@ type Verified struct { func (x *Verified) Reset() { *x = Verified{} - if protoimpl.UnsafeEnabled { - mi := &file_SignalService_proto_msgTypes[11] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_SignalService_proto_msgTypes[11] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *Verified) String() string { @@ -2863,7 +2839,7 @@ func (*Verified) ProtoMessage() {} func (x *Verified) ProtoReflect() protoreflect.Message { mi := &file_SignalService_proto_msgTypes[11] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -2935,11 +2911,9 @@ type SyncMessage struct { func (x *SyncMessage) Reset() { *x = SyncMessage{} - if protoimpl.UnsafeEnabled { - mi := &file_SignalService_proto_msgTypes[12] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_SignalService_proto_msgTypes[12] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *SyncMessage) String() string { @@ -2950,7 +2924,7 @@ func (*SyncMessage) ProtoMessage() {} func (x *SyncMessage) ProtoReflect() protoreflect.Message { mi := &file_SignalService_proto_msgTypes[12] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -3135,11 +3109,9 @@ type AttachmentPointer struct { func (x *AttachmentPointer) Reset() { *x = AttachmentPointer{} - if protoimpl.UnsafeEnabled { - mi := &file_SignalService_proto_msgTypes[13] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_SignalService_proto_msgTypes[13] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *AttachmentPointer) String() string { @@ -3150,7 +3122,7 @@ func (*AttachmentPointer) ProtoMessage() {} func (x *AttachmentPointer) ProtoReflect() protoreflect.Message { mi := &file_SignalService_proto_msgTypes[13] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -3329,11 +3301,9 @@ type GroupContext struct { func (x *GroupContext) Reset() { *x = GroupContext{} - if protoimpl.UnsafeEnabled { - mi := &file_SignalService_proto_msgTypes[14] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_SignalService_proto_msgTypes[14] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *GroupContext) String() string { @@ -3344,7 +3314,7 @@ func (*GroupContext) ProtoMessage() {} func (x *GroupContext) ProtoReflect() protoreflect.Message { mi := &file_SignalService_proto_msgTypes[14] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -3413,11 +3383,9 @@ type GroupContextV2 struct { func (x *GroupContextV2) Reset() { *x = GroupContextV2{} - if protoimpl.UnsafeEnabled { - mi := &file_SignalService_proto_msgTypes[15] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_SignalService_proto_msgTypes[15] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *GroupContextV2) String() string { @@ -3428,7 +3396,7 @@ func (*GroupContextV2) ProtoMessage() {} func (x *GroupContextV2) ProtoReflect() protoreflect.Message { mi := &file_SignalService_proto_msgTypes[15] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -3484,11 +3452,9 @@ type ContactDetails struct { func (x *ContactDetails) Reset() { *x = ContactDetails{} - if protoimpl.UnsafeEnabled { - mi := &file_SignalService_proto_msgTypes[16] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_SignalService_proto_msgTypes[16] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *ContactDetails) String() string { @@ -3499,7 +3465,7 @@ func (*ContactDetails) ProtoMessage() {} func (x *ContactDetails) ProtoReflect() protoreflect.Message { mi := &file_SignalService_proto_msgTypes[16] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -3616,11 +3582,9 @@ const ( func (x *GroupDetails) Reset() { *x = GroupDetails{} - if protoimpl.UnsafeEnabled { - mi := &file_SignalService_proto_msgTypes[17] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_SignalService_proto_msgTypes[17] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *GroupDetails) String() string { @@ -3631,7 +3595,7 @@ func (*GroupDetails) ProtoMessage() {} func (x *GroupDetails) ProtoReflect() protoreflect.Message { mi := &file_SignalService_proto_msgTypes[17] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -3736,11 +3700,9 @@ type PaymentAddress struct { func (x *PaymentAddress) Reset() { *x = PaymentAddress{} - if protoimpl.UnsafeEnabled { - mi := &file_SignalService_proto_msgTypes[18] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_SignalService_proto_msgTypes[18] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *PaymentAddress) String() string { @@ -3751,7 +3713,7 @@ func (*PaymentAddress) ProtoMessage() {} func (x *PaymentAddress) ProtoReflect() protoreflect.Message { mi := &file_SignalService_proto_msgTypes[18] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -3802,11 +3764,9 @@ type DecryptionErrorMessage struct { func (x *DecryptionErrorMessage) Reset() { *x = DecryptionErrorMessage{} - if protoimpl.UnsafeEnabled { - mi := &file_SignalService_proto_msgTypes[19] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_SignalService_proto_msgTypes[19] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *DecryptionErrorMessage) String() string { @@ -3817,7 +3777,7 @@ func (*DecryptionErrorMessage) ProtoMessage() {} func (x *DecryptionErrorMessage) ProtoReflect() protoreflect.Message { mi := &file_SignalService_proto_msgTypes[19] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -3864,11 +3824,9 @@ type PniSignatureMessage struct { func (x *PniSignatureMessage) Reset() { *x = PniSignatureMessage{} - if protoimpl.UnsafeEnabled { - mi := &file_SignalService_proto_msgTypes[20] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_SignalService_proto_msgTypes[20] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *PniSignatureMessage) String() string { @@ -3879,7 +3837,7 @@ func (*PniSignatureMessage) ProtoMessage() {} func (x *PniSignatureMessage) ProtoReflect() protoreflect.Message { mi := &file_SignalService_proto_msgTypes[20] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -3919,11 +3877,9 @@ type EditMessage struct { func (x *EditMessage) Reset() { *x = EditMessage{} - if protoimpl.UnsafeEnabled { - mi := &file_SignalService_proto_msgTypes[21] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_SignalService_proto_msgTypes[21] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *EditMessage) String() string { @@ -3934,7 +3890,7 @@ func (*EditMessage) ProtoMessage() {} func (x *EditMessage) ProtoReflect() protoreflect.Message { mi := &file_SignalService_proto_msgTypes[21] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -3975,11 +3931,9 @@ type CallMessage_Offer struct { func (x *CallMessage_Offer) Reset() { *x = CallMessage_Offer{} - if protoimpl.UnsafeEnabled { - mi := &file_SignalService_proto_msgTypes[22] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_SignalService_proto_msgTypes[22] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *CallMessage_Offer) String() string { @@ -3990,7 +3944,7 @@ func (*CallMessage_Offer) ProtoMessage() {} func (x *CallMessage_Offer) ProtoReflect() protoreflect.Message { mi := &file_SignalService_proto_msgTypes[22] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -4037,11 +3991,9 @@ type CallMessage_Answer struct { func (x *CallMessage_Answer) Reset() { *x = CallMessage_Answer{} - if protoimpl.UnsafeEnabled { - mi := &file_SignalService_proto_msgTypes[23] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_SignalService_proto_msgTypes[23] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *CallMessage_Answer) String() string { @@ -4052,7 +4004,7 @@ func (*CallMessage_Answer) ProtoMessage() {} func (x *CallMessage_Answer) ProtoReflect() protoreflect.Message { mi := &file_SignalService_proto_msgTypes[23] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -4092,11 +4044,9 @@ type CallMessage_IceUpdate struct { func (x *CallMessage_IceUpdate) Reset() { *x = CallMessage_IceUpdate{} - if protoimpl.UnsafeEnabled { - mi := &file_SignalService_proto_msgTypes[24] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_SignalService_proto_msgTypes[24] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *CallMessage_IceUpdate) String() string { @@ -4107,7 +4057,7 @@ func (*CallMessage_IceUpdate) ProtoMessage() {} func (x *CallMessage_IceUpdate) ProtoReflect() protoreflect.Message { mi := &file_SignalService_proto_msgTypes[24] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -4146,11 +4096,9 @@ type CallMessage_Busy struct { func (x *CallMessage_Busy) Reset() { *x = CallMessage_Busy{} - if protoimpl.UnsafeEnabled { - mi := &file_SignalService_proto_msgTypes[25] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_SignalService_proto_msgTypes[25] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *CallMessage_Busy) String() string { @@ -4161,7 +4109,7 @@ func (*CallMessage_Busy) ProtoMessage() {} func (x *CallMessage_Busy) ProtoReflect() protoreflect.Message { mi := &file_SignalService_proto_msgTypes[25] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -4195,11 +4143,9 @@ type CallMessage_Hangup struct { func (x *CallMessage_Hangup) Reset() { *x = CallMessage_Hangup{} - if protoimpl.UnsafeEnabled { - mi := &file_SignalService_proto_msgTypes[26] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_SignalService_proto_msgTypes[26] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *CallMessage_Hangup) String() string { @@ -4210,7 +4156,7 @@ func (*CallMessage_Hangup) ProtoMessage() {} func (x *CallMessage_Hangup) ProtoReflect() protoreflect.Message { mi := &file_SignalService_proto_msgTypes[26] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -4257,11 +4203,9 @@ type CallMessage_Opaque struct { func (x *CallMessage_Opaque) Reset() { *x = CallMessage_Opaque{} - if protoimpl.UnsafeEnabled { - mi := &file_SignalService_proto_msgTypes[27] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_SignalService_proto_msgTypes[27] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *CallMessage_Opaque) String() string { @@ -4272,7 +4216,7 @@ func (*CallMessage_Opaque) ProtoMessage() {} func (x *CallMessage_Opaque) ProtoReflect() protoreflect.Message { mi := &file_SignalService_proto_msgTypes[27] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -4316,11 +4260,9 @@ type DataMessage_Quote struct { func (x *DataMessage_Quote) Reset() { *x = DataMessage_Quote{} - if protoimpl.UnsafeEnabled { - mi := &file_SignalService_proto_msgTypes[28] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_SignalService_proto_msgTypes[28] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *DataMessage_Quote) String() string { @@ -4331,7 +4273,7 @@ func (*DataMessage_Quote) ProtoMessage() {} func (x *DataMessage_Quote) ProtoReflect() protoreflect.Message { mi := &file_SignalService_proto_msgTypes[28] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -4403,11 +4345,9 @@ type DataMessage_Contact struct { func (x *DataMessage_Contact) Reset() { *x = DataMessage_Contact{} - if protoimpl.UnsafeEnabled { - mi := &file_SignalService_proto_msgTypes[29] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_SignalService_proto_msgTypes[29] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *DataMessage_Contact) String() string { @@ -4418,7 +4358,7 @@ func (*DataMessage_Contact) ProtoMessage() {} func (x *DataMessage_Contact) ProtoReflect() protoreflect.Message { mi := &file_SignalService_proto_msgTypes[29] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -4489,11 +4429,9 @@ type DataMessage_Sticker struct { func (x *DataMessage_Sticker) Reset() { *x = DataMessage_Sticker{} - if protoimpl.UnsafeEnabled { - mi := &file_SignalService_proto_msgTypes[30] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_SignalService_proto_msgTypes[30] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *DataMessage_Sticker) String() string { @@ -4504,7 +4442,7 @@ func (*DataMessage_Sticker) ProtoMessage() {} func (x *DataMessage_Sticker) ProtoReflect() protoreflect.Message { mi := &file_SignalService_proto_msgTypes[30] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -4567,11 +4505,9 @@ type DataMessage_Reaction struct { func (x *DataMessage_Reaction) Reset() { *x = DataMessage_Reaction{} - if protoimpl.UnsafeEnabled { - mi := &file_SignalService_proto_msgTypes[31] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_SignalService_proto_msgTypes[31] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *DataMessage_Reaction) String() string { @@ -4582,7 +4518,7 @@ func (*DataMessage_Reaction) ProtoMessage() {} func (x *DataMessage_Reaction) ProtoReflect() protoreflect.Message { mi := &file_SignalService_proto_msgTypes[31] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -4635,11 +4571,9 @@ type DataMessage_Delete struct { func (x *DataMessage_Delete) Reset() { *x = DataMessage_Delete{} - if protoimpl.UnsafeEnabled { - mi := &file_SignalService_proto_msgTypes[32] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_SignalService_proto_msgTypes[32] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *DataMessage_Delete) String() string { @@ -4650,7 +4584,7 @@ func (*DataMessage_Delete) ProtoMessage() {} func (x *DataMessage_Delete) ProtoReflect() protoreflect.Message { mi := &file_SignalService_proto_msgTypes[32] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -4682,11 +4616,9 @@ type DataMessage_GroupCallUpdate struct { func (x *DataMessage_GroupCallUpdate) Reset() { *x = DataMessage_GroupCallUpdate{} - if protoimpl.UnsafeEnabled { - mi := &file_SignalService_proto_msgTypes[33] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_SignalService_proto_msgTypes[33] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *DataMessage_GroupCallUpdate) String() string { @@ -4697,7 +4629,7 @@ func (*DataMessage_GroupCallUpdate) ProtoMessage() {} func (x *DataMessage_GroupCallUpdate) ProtoReflect() protoreflect.Message { mi := &file_SignalService_proto_msgTypes[33] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -4730,11 +4662,9 @@ type DataMessage_StoryContext struct { func (x *DataMessage_StoryContext) Reset() { *x = DataMessage_StoryContext{} - if protoimpl.UnsafeEnabled { - mi := &file_SignalService_proto_msgTypes[34] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_SignalService_proto_msgTypes[34] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *DataMessage_StoryContext) String() string { @@ -4745,7 +4675,7 @@ func (*DataMessage_StoryContext) ProtoMessage() {} func (x *DataMessage_StoryContext) ProtoReflect() protoreflect.Message { mi := &file_SignalService_proto_msgTypes[34] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -4788,11 +4718,9 @@ type DataMessage_Payment struct { func (x *DataMessage_Payment) Reset() { *x = DataMessage_Payment{} - if protoimpl.UnsafeEnabled { - mi := &file_SignalService_proto_msgTypes[35] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_SignalService_proto_msgTypes[35] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *DataMessage_Payment) String() string { @@ -4803,7 +4731,7 @@ func (*DataMessage_Payment) ProtoMessage() {} func (x *DataMessage_Payment) ProtoReflect() protoreflect.Message { mi := &file_SignalService_proto_msgTypes[35] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -4865,11 +4793,9 @@ type DataMessage_GiftBadge struct { func (x *DataMessage_GiftBadge) Reset() { *x = DataMessage_GiftBadge{} - if protoimpl.UnsafeEnabled { - mi := &file_SignalService_proto_msgTypes[36] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_SignalService_proto_msgTypes[36] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *DataMessage_GiftBadge) String() string { @@ -4880,7 +4806,7 @@ func (*DataMessage_GiftBadge) ProtoMessage() {} func (x *DataMessage_GiftBadge) ProtoReflect() protoreflect.Message { mi := &file_SignalService_proto_msgTypes[36] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -4914,11 +4840,9 @@ type DataMessage_Quote_QuotedAttachment struct { func (x *DataMessage_Quote_QuotedAttachment) Reset() { *x = DataMessage_Quote_QuotedAttachment{} - if protoimpl.UnsafeEnabled { - mi := &file_SignalService_proto_msgTypes[37] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_SignalService_proto_msgTypes[37] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *DataMessage_Quote_QuotedAttachment) String() string { @@ -4929,7 +4853,7 @@ func (*DataMessage_Quote_QuotedAttachment) ProtoMessage() {} func (x *DataMessage_Quote_QuotedAttachment) ProtoReflect() protoreflect.Message { mi := &file_SignalService_proto_msgTypes[37] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -4970,21 +4894,19 @@ type DataMessage_Contact_Name struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - GivenName *string `protobuf:"bytes,1,opt,name=givenName" json:"givenName,omitempty"` - FamilyName *string `protobuf:"bytes,2,opt,name=familyName" json:"familyName,omitempty"` - Prefix *string `protobuf:"bytes,3,opt,name=prefix" json:"prefix,omitempty"` - Suffix *string `protobuf:"bytes,4,opt,name=suffix" json:"suffix,omitempty"` - MiddleName *string `protobuf:"bytes,5,opt,name=middleName" json:"middleName,omitempty"` - DisplayName *string `protobuf:"bytes,6,opt,name=displayName" json:"displayName,omitempty"` + GivenName *string `protobuf:"bytes,1,opt,name=givenName" json:"givenName,omitempty"` + FamilyName *string `protobuf:"bytes,2,opt,name=familyName" json:"familyName,omitempty"` + Prefix *string `protobuf:"bytes,3,opt,name=prefix" json:"prefix,omitempty"` + Suffix *string `protobuf:"bytes,4,opt,name=suffix" json:"suffix,omitempty"` + MiddleName *string `protobuf:"bytes,5,opt,name=middleName" json:"middleName,omitempty"` + Nickname *string `protobuf:"bytes,7,opt,name=nickname" json:"nickname,omitempty"` } func (x *DataMessage_Contact_Name) Reset() { *x = DataMessage_Contact_Name{} - if protoimpl.UnsafeEnabled { - mi := &file_SignalService_proto_msgTypes[38] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_SignalService_proto_msgTypes[38] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *DataMessage_Contact_Name) String() string { @@ -4995,7 +4917,7 @@ func (*DataMessage_Contact_Name) ProtoMessage() {} func (x *DataMessage_Contact_Name) ProtoReflect() protoreflect.Message { mi := &file_SignalService_proto_msgTypes[38] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -5045,9 +4967,9 @@ func (x *DataMessage_Contact_Name) GetMiddleName() string { return "" } -func (x *DataMessage_Contact_Name) GetDisplayName() string { - if x != nil && x.DisplayName != nil { - return *x.DisplayName +func (x *DataMessage_Contact_Name) GetNickname() string { + if x != nil && x.Nickname != nil { + return *x.Nickname } return "" } @@ -5064,11 +4986,9 @@ type DataMessage_Contact_Phone struct { func (x *DataMessage_Contact_Phone) Reset() { *x = DataMessage_Contact_Phone{} - if protoimpl.UnsafeEnabled { - mi := &file_SignalService_proto_msgTypes[39] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_SignalService_proto_msgTypes[39] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *DataMessage_Contact_Phone) String() string { @@ -5079,7 +4999,7 @@ func (*DataMessage_Contact_Phone) ProtoMessage() {} func (x *DataMessage_Contact_Phone) ProtoReflect() protoreflect.Message { mi := &file_SignalService_proto_msgTypes[39] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -5127,11 +5047,9 @@ type DataMessage_Contact_Email struct { func (x *DataMessage_Contact_Email) Reset() { *x = DataMessage_Contact_Email{} - if protoimpl.UnsafeEnabled { - mi := &file_SignalService_proto_msgTypes[40] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_SignalService_proto_msgTypes[40] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *DataMessage_Contact_Email) String() string { @@ -5142,7 +5060,7 @@ func (*DataMessage_Contact_Email) ProtoMessage() {} func (x *DataMessage_Contact_Email) ProtoReflect() protoreflect.Message { mi := &file_SignalService_proto_msgTypes[40] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -5196,11 +5114,9 @@ type DataMessage_Contact_PostalAddress struct { func (x *DataMessage_Contact_PostalAddress) Reset() { *x = DataMessage_Contact_PostalAddress{} - if protoimpl.UnsafeEnabled { - mi := &file_SignalService_proto_msgTypes[41] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_SignalService_proto_msgTypes[41] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *DataMessage_Contact_PostalAddress) String() string { @@ -5211,7 +5127,7 @@ func (*DataMessage_Contact_PostalAddress) ProtoMessage() {} func (x *DataMessage_Contact_PostalAddress) ProtoReflect() protoreflect.Message { mi := &file_SignalService_proto_msgTypes[41] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -5300,11 +5216,9 @@ type DataMessage_Contact_Avatar struct { func (x *DataMessage_Contact_Avatar) Reset() { *x = DataMessage_Contact_Avatar{} - if protoimpl.UnsafeEnabled { - mi := &file_SignalService_proto_msgTypes[42] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_SignalService_proto_msgTypes[42] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *DataMessage_Contact_Avatar) String() string { @@ -5315,7 +5229,7 @@ func (*DataMessage_Contact_Avatar) ProtoMessage() {} func (x *DataMessage_Contact_Avatar) ProtoReflect() protoreflect.Message { mi := &file_SignalService_proto_msgTypes[42] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -5357,11 +5271,9 @@ type DataMessage_Payment_Amount struct { func (x *DataMessage_Payment_Amount) Reset() { *x = DataMessage_Payment_Amount{} - if protoimpl.UnsafeEnabled { - mi := &file_SignalService_proto_msgTypes[43] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_SignalService_proto_msgTypes[43] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *DataMessage_Payment_Amount) String() string { @@ -5372,7 +5284,7 @@ func (*DataMessage_Payment_Amount) ProtoMessage() {} func (x *DataMessage_Payment_Amount) ProtoReflect() protoreflect.Message { mi := &file_SignalService_proto_msgTypes[43] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -5425,11 +5337,9 @@ type DataMessage_Payment_Notification struct { func (x *DataMessage_Payment_Notification) Reset() { *x = DataMessage_Payment_Notification{} - if protoimpl.UnsafeEnabled { - mi := &file_SignalService_proto_msgTypes[44] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_SignalService_proto_msgTypes[44] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *DataMessage_Payment_Notification) String() string { @@ -5440,7 +5350,7 @@ func (*DataMessage_Payment_Notification) ProtoMessage() {} func (x *DataMessage_Payment_Notification) ProtoReflect() protoreflect.Message { mi := &file_SignalService_proto_msgTypes[44] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -5497,11 +5407,9 @@ type DataMessage_Payment_Activation struct { func (x *DataMessage_Payment_Activation) Reset() { *x = DataMessage_Payment_Activation{} - if protoimpl.UnsafeEnabled { - mi := &file_SignalService_proto_msgTypes[45] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_SignalService_proto_msgTypes[45] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *DataMessage_Payment_Activation) String() string { @@ -5512,7 +5420,7 @@ func (*DataMessage_Payment_Activation) ProtoMessage() {} func (x *DataMessage_Payment_Activation) ProtoReflect() protoreflect.Message { mi := &file_SignalService_proto_msgTypes[45] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -5544,11 +5452,9 @@ type DataMessage_Payment_Amount_MobileCoin struct { func (x *DataMessage_Payment_Amount_MobileCoin) Reset() { *x = DataMessage_Payment_Amount_MobileCoin{} - if protoimpl.UnsafeEnabled { - mi := &file_SignalService_proto_msgTypes[46] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_SignalService_proto_msgTypes[46] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *DataMessage_Payment_Amount_MobileCoin) String() string { @@ -5559,7 +5465,7 @@ func (*DataMessage_Payment_Amount_MobileCoin) ProtoMessage() {} func (x *DataMessage_Payment_Amount_MobileCoin) ProtoReflect() protoreflect.Message { mi := &file_SignalService_proto_msgTypes[46] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -5591,11 +5497,9 @@ type DataMessage_Payment_Notification_MobileCoin struct { func (x *DataMessage_Payment_Notification_MobileCoin) Reset() { *x = DataMessage_Payment_Notification_MobileCoin{} - if protoimpl.UnsafeEnabled { - mi := &file_SignalService_proto_msgTypes[47] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_SignalService_proto_msgTypes[47] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *DataMessage_Payment_Notification_MobileCoin) String() string { @@ -5606,7 +5510,7 @@ func (*DataMessage_Payment_Notification_MobileCoin) ProtoMessage() {} func (x *DataMessage_Payment_Notification_MobileCoin) ProtoReflect() protoreflect.Message { mi := &file_SignalService_proto_msgTypes[47] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -5642,11 +5546,9 @@ type TextAttachment_Gradient struct { func (x *TextAttachment_Gradient) Reset() { *x = TextAttachment_Gradient{} - if protoimpl.UnsafeEnabled { - mi := &file_SignalService_proto_msgTypes[48] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_SignalService_proto_msgTypes[48] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *TextAttachment_Gradient) String() string { @@ -5657,7 +5559,7 @@ func (*TextAttachment_Gradient) ProtoMessage() {} func (x *TextAttachment_Gradient) ProtoReflect() protoreflect.Message { mi := &file_SignalService_proto_msgTypes[48] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -5731,11 +5633,9 @@ const ( func (x *SyncMessage_Sent) Reset() { *x = SyncMessage_Sent{} - if protoimpl.UnsafeEnabled { - mi := &file_SignalService_proto_msgTypes[49] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_SignalService_proto_msgTypes[49] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *SyncMessage_Sent) String() string { @@ -5746,7 +5646,7 @@ func (*SyncMessage_Sent) ProtoMessage() {} func (x *SyncMessage_Sent) ProtoReflect() protoreflect.Message { mi := &file_SignalService_proto_msgTypes[49] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -5847,11 +5747,9 @@ const ( func (x *SyncMessage_Contacts) Reset() { *x = SyncMessage_Contacts{} - if protoimpl.UnsafeEnabled { - mi := &file_SignalService_proto_msgTypes[50] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_SignalService_proto_msgTypes[50] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *SyncMessage_Contacts) String() string { @@ -5862,7 +5760,7 @@ func (*SyncMessage_Contacts) ProtoMessage() {} func (x *SyncMessage_Contacts) ProtoReflect() protoreflect.Message { mi := &file_SignalService_proto_msgTypes[50] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -5903,11 +5801,9 @@ type SyncMessage_Blocked struct { func (x *SyncMessage_Blocked) Reset() { *x = SyncMessage_Blocked{} - if protoimpl.UnsafeEnabled { - mi := &file_SignalService_proto_msgTypes[51] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_SignalService_proto_msgTypes[51] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *SyncMessage_Blocked) String() string { @@ -5918,7 +5814,7 @@ func (*SyncMessage_Blocked) ProtoMessage() {} func (x *SyncMessage_Blocked) ProtoReflect() protoreflect.Message { mi := &file_SignalService_proto_msgTypes[51] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -5964,11 +5860,9 @@ type SyncMessage_Request struct { func (x *SyncMessage_Request) Reset() { *x = SyncMessage_Request{} - if protoimpl.UnsafeEnabled { - mi := &file_SignalService_proto_msgTypes[52] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_SignalService_proto_msgTypes[52] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *SyncMessage_Request) String() string { @@ -5979,7 +5873,7 @@ func (*SyncMessage_Request) ProtoMessage() {} func (x *SyncMessage_Request) ProtoReflect() protoreflect.Message { mi := &file_SignalService_proto_msgTypes[52] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -6012,11 +5906,9 @@ type SyncMessage_Read struct { func (x *SyncMessage_Read) Reset() { *x = SyncMessage_Read{} - if protoimpl.UnsafeEnabled { - mi := &file_SignalService_proto_msgTypes[53] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_SignalService_proto_msgTypes[53] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *SyncMessage_Read) String() string { @@ -6027,7 +5919,7 @@ func (*SyncMessage_Read) ProtoMessage() {} func (x *SyncMessage_Read) ProtoReflect() protoreflect.Message { mi := &file_SignalService_proto_msgTypes[53] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -6067,11 +5959,9 @@ type SyncMessage_Viewed struct { func (x *SyncMessage_Viewed) Reset() { *x = SyncMessage_Viewed{} - if protoimpl.UnsafeEnabled { - mi := &file_SignalService_proto_msgTypes[54] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_SignalService_proto_msgTypes[54] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *SyncMessage_Viewed) String() string { @@ -6082,7 +5972,7 @@ func (*SyncMessage_Viewed) ProtoMessage() {} func (x *SyncMessage_Viewed) ProtoReflect() protoreflect.Message { mi := &file_SignalService_proto_msgTypes[54] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -6125,11 +6015,9 @@ type SyncMessage_Configuration struct { func (x *SyncMessage_Configuration) Reset() { *x = SyncMessage_Configuration{} - if protoimpl.UnsafeEnabled { - mi := &file_SignalService_proto_msgTypes[55] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_SignalService_proto_msgTypes[55] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *SyncMessage_Configuration) String() string { @@ -6140,7 +6028,7 @@ func (*SyncMessage_Configuration) ProtoMessage() {} func (x *SyncMessage_Configuration) ProtoReflect() protoreflect.Message { mi := &file_SignalService_proto_msgTypes[55] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -6202,11 +6090,9 @@ type SyncMessage_StickerPackOperation struct { func (x *SyncMessage_StickerPackOperation) Reset() { *x = SyncMessage_StickerPackOperation{} - if protoimpl.UnsafeEnabled { - mi := &file_SignalService_proto_msgTypes[56] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_SignalService_proto_msgTypes[56] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *SyncMessage_StickerPackOperation) String() string { @@ -6217,7 +6103,7 @@ func (*SyncMessage_StickerPackOperation) ProtoMessage() {} func (x *SyncMessage_StickerPackOperation) ProtoReflect() protoreflect.Message { mi := &file_SignalService_proto_msgTypes[56] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -6264,11 +6150,9 @@ type SyncMessage_ViewOnceOpen struct { func (x *SyncMessage_ViewOnceOpen) Reset() { *x = SyncMessage_ViewOnceOpen{} - if protoimpl.UnsafeEnabled { - mi := &file_SignalService_proto_msgTypes[57] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_SignalService_proto_msgTypes[57] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *SyncMessage_ViewOnceOpen) String() string { @@ -6279,7 +6163,7 @@ func (*SyncMessage_ViewOnceOpen) ProtoMessage() {} func (x *SyncMessage_ViewOnceOpen) ProtoReflect() protoreflect.Message { mi := &file_SignalService_proto_msgTypes[57] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -6318,11 +6202,9 @@ type SyncMessage_FetchLatest struct { func (x *SyncMessage_FetchLatest) Reset() { *x = SyncMessage_FetchLatest{} - if protoimpl.UnsafeEnabled { - mi := &file_SignalService_proto_msgTypes[58] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_SignalService_proto_msgTypes[58] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *SyncMessage_FetchLatest) String() string { @@ -6333,7 +6215,7 @@ func (*SyncMessage_FetchLatest) ProtoMessage() {} func (x *SyncMessage_FetchLatest) ProtoReflect() protoreflect.Message { mi := &file_SignalService_proto_msgTypes[58] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -6367,11 +6249,9 @@ type SyncMessage_Keys struct { func (x *SyncMessage_Keys) Reset() { *x = SyncMessage_Keys{} - if protoimpl.UnsafeEnabled { - mi := &file_SignalService_proto_msgTypes[59] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_SignalService_proto_msgTypes[59] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *SyncMessage_Keys) String() string { @@ -6382,7 +6262,7 @@ func (*SyncMessage_Keys) ProtoMessage() {} func (x *SyncMessage_Keys) ProtoReflect() protoreflect.Message { mi := &file_SignalService_proto_msgTypes[59] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -6423,11 +6303,9 @@ type SyncMessage_MessageRequestResponse struct { func (x *SyncMessage_MessageRequestResponse) Reset() { *x = SyncMessage_MessageRequestResponse{} - if protoimpl.UnsafeEnabled { - mi := &file_SignalService_proto_msgTypes[60] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_SignalService_proto_msgTypes[60] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *SyncMessage_MessageRequestResponse) String() string { @@ -6438,7 +6316,7 @@ func (*SyncMessage_MessageRequestResponse) ProtoMessage() {} func (x *SyncMessage_MessageRequestResponse) ProtoReflect() protoreflect.Message { mi := &file_SignalService_proto_msgTypes[60] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -6489,11 +6367,9 @@ type SyncMessage_OutgoingPayment struct { func (x *SyncMessage_OutgoingPayment) Reset() { *x = SyncMessage_OutgoingPayment{} - if protoimpl.UnsafeEnabled { - mi := &file_SignalService_proto_msgTypes[61] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_SignalService_proto_msgTypes[61] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *SyncMessage_OutgoingPayment) String() string { @@ -6504,7 +6380,7 @@ func (*SyncMessage_OutgoingPayment) ProtoMessage() {} func (x *SyncMessage_OutgoingPayment) ProtoReflect() protoreflect.Message { mi := &file_SignalService_proto_msgTypes[61] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -6571,11 +6447,9 @@ type SyncMessage_PniChangeNumber struct { func (x *SyncMessage_PniChangeNumber) Reset() { *x = SyncMessage_PniChangeNumber{} - if protoimpl.UnsafeEnabled { - mi := &file_SignalService_proto_msgTypes[62] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_SignalService_proto_msgTypes[62] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *SyncMessage_PniChangeNumber) String() string { @@ -6586,7 +6460,7 @@ func (*SyncMessage_PniChangeNumber) ProtoMessage() {} func (x *SyncMessage_PniChangeNumber) ProtoReflect() protoreflect.Message { mi := &file_SignalService_proto_msgTypes[62] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -6651,11 +6525,9 @@ type SyncMessage_CallEvent struct { func (x *SyncMessage_CallEvent) Reset() { *x = SyncMessage_CallEvent{} - if protoimpl.UnsafeEnabled { - mi := &file_SignalService_proto_msgTypes[63] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_SignalService_proto_msgTypes[63] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *SyncMessage_CallEvent) String() string { @@ -6666,7 +6538,7 @@ func (*SyncMessage_CallEvent) ProtoMessage() {} func (x *SyncMessage_CallEvent) ProtoReflect() protoreflect.Message { mi := &file_SignalService_proto_msgTypes[63] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -6735,11 +6607,9 @@ type SyncMessage_CallLinkUpdate struct { func (x *SyncMessage_CallLinkUpdate) Reset() { *x = SyncMessage_CallLinkUpdate{} - if protoimpl.UnsafeEnabled { - mi := &file_SignalService_proto_msgTypes[64] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_SignalService_proto_msgTypes[64] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *SyncMessage_CallLinkUpdate) String() string { @@ -6750,7 +6620,7 @@ func (*SyncMessage_CallLinkUpdate) ProtoMessage() {} func (x *SyncMessage_CallLinkUpdate) ProtoReflect() protoreflect.Message { mi := &file_SignalService_proto_msgTypes[64] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -6804,11 +6674,9 @@ type SyncMessage_CallLogEvent struct { func (x *SyncMessage_CallLogEvent) Reset() { *x = SyncMessage_CallLogEvent{} - if protoimpl.UnsafeEnabled { - mi := &file_SignalService_proto_msgTypes[65] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_SignalService_proto_msgTypes[65] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *SyncMessage_CallLogEvent) String() string { @@ -6819,7 +6687,7 @@ func (*SyncMessage_CallLogEvent) ProtoMessage() {} func (x *SyncMessage_CallLogEvent) ProtoReflect() protoreflect.Message { mi := &file_SignalService_proto_msgTypes[65] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -6875,11 +6743,9 @@ type SyncMessage_DeleteForMe struct { func (x *SyncMessage_DeleteForMe) Reset() { *x = SyncMessage_DeleteForMe{} - if protoimpl.UnsafeEnabled { - mi := &file_SignalService_proto_msgTypes[66] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_SignalService_proto_msgTypes[66] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *SyncMessage_DeleteForMe) String() string { @@ -6890,7 +6756,7 @@ func (*SyncMessage_DeleteForMe) ProtoMessage() {} func (x *SyncMessage_DeleteForMe) ProtoReflect() protoreflect.Message { mi := &file_SignalService_proto_msgTypes[66] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -6945,11 +6811,9 @@ type SyncMessage_Sent_UnidentifiedDeliveryStatus struct { func (x *SyncMessage_Sent_UnidentifiedDeliveryStatus) Reset() { *x = SyncMessage_Sent_UnidentifiedDeliveryStatus{} - if protoimpl.UnsafeEnabled { - mi := &file_SignalService_proto_msgTypes[67] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_SignalService_proto_msgTypes[67] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *SyncMessage_Sent_UnidentifiedDeliveryStatus) String() string { @@ -6960,7 +6824,7 @@ func (*SyncMessage_Sent_UnidentifiedDeliveryStatus) ProtoMessage() {} func (x *SyncMessage_Sent_UnidentifiedDeliveryStatus) ProtoReflect() protoreflect.Message { mi := &file_SignalService_proto_msgTypes[67] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -7008,11 +6872,9 @@ type SyncMessage_Sent_StoryMessageRecipient struct { func (x *SyncMessage_Sent_StoryMessageRecipient) Reset() { *x = SyncMessage_Sent_StoryMessageRecipient{} - if protoimpl.UnsafeEnabled { - mi := &file_SignalService_proto_msgTypes[68] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_SignalService_proto_msgTypes[68] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *SyncMessage_Sent_StoryMessageRecipient) String() string { @@ -7023,7 +6885,7 @@ func (*SyncMessage_Sent_StoryMessageRecipient) ProtoMessage() {} func (x *SyncMessage_Sent_StoryMessageRecipient) ProtoReflect() protoreflect.Message { mi := &file_SignalService_proto_msgTypes[68] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -7079,11 +6941,9 @@ type SyncMessage_OutgoingPayment_MobileCoin struct { func (x *SyncMessage_OutgoingPayment_MobileCoin) Reset() { *x = SyncMessage_OutgoingPayment_MobileCoin{} - if protoimpl.UnsafeEnabled { - mi := &file_SignalService_proto_msgTypes[69] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_SignalService_proto_msgTypes[69] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *SyncMessage_OutgoingPayment_MobileCoin) String() string { @@ -7094,7 +6954,7 @@ func (*SyncMessage_OutgoingPayment_MobileCoin) ProtoMessage() {} func (x *SyncMessage_OutgoingPayment_MobileCoin) ProtoReflect() protoreflect.Message { mi := &file_SignalService_proto_msgTypes[69] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -7180,11 +7040,9 @@ type SyncMessage_DeleteForMe_ConversationIdentifier struct { func (x *SyncMessage_DeleteForMe_ConversationIdentifier) Reset() { *x = SyncMessage_DeleteForMe_ConversationIdentifier{} - if protoimpl.UnsafeEnabled { - mi := &file_SignalService_proto_msgTypes[70] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_SignalService_proto_msgTypes[70] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *SyncMessage_DeleteForMe_ConversationIdentifier) String() string { @@ -7195,7 +7053,7 @@ func (*SyncMessage_DeleteForMe_ConversationIdentifier) ProtoMessage() {} func (x *SyncMessage_DeleteForMe_ConversationIdentifier) ProtoReflect() protoreflect.Message { mi := &file_SignalService_proto_msgTypes[70] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -7278,11 +7136,9 @@ type SyncMessage_DeleteForMe_AddressableMessage struct { func (x *SyncMessage_DeleteForMe_AddressableMessage) Reset() { *x = SyncMessage_DeleteForMe_AddressableMessage{} - if protoimpl.UnsafeEnabled { - mi := &file_SignalService_proto_msgTypes[71] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_SignalService_proto_msgTypes[71] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *SyncMessage_DeleteForMe_AddressableMessage) String() string { @@ -7293,7 +7149,7 @@ func (*SyncMessage_DeleteForMe_AddressableMessage) ProtoMessage() {} func (x *SyncMessage_DeleteForMe_AddressableMessage) ProtoReflect() protoreflect.Message { mi := &file_SignalService_proto_msgTypes[71] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -7365,11 +7221,9 @@ type SyncMessage_DeleteForMe_MessageDeletes struct { func (x *SyncMessage_DeleteForMe_MessageDeletes) Reset() { *x = SyncMessage_DeleteForMe_MessageDeletes{} - if protoimpl.UnsafeEnabled { - mi := &file_SignalService_proto_msgTypes[72] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_SignalService_proto_msgTypes[72] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *SyncMessage_DeleteForMe_MessageDeletes) String() string { @@ -7380,7 +7234,7 @@ func (*SyncMessage_DeleteForMe_MessageDeletes) ProtoMessage() {} func (x *SyncMessage_DeleteForMe_MessageDeletes) ProtoReflect() protoreflect.Message { mi := &file_SignalService_proto_msgTypes[72] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -7423,11 +7277,9 @@ type SyncMessage_DeleteForMe_AttachmentDelete struct { func (x *SyncMessage_DeleteForMe_AttachmentDelete) Reset() { *x = SyncMessage_DeleteForMe_AttachmentDelete{} - if protoimpl.UnsafeEnabled { - mi := &file_SignalService_proto_msgTypes[73] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_SignalService_proto_msgTypes[73] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *SyncMessage_DeleteForMe_AttachmentDelete) String() string { @@ -7438,7 +7290,7 @@ func (*SyncMessage_DeleteForMe_AttachmentDelete) ProtoMessage() {} func (x *SyncMessage_DeleteForMe_AttachmentDelete) ProtoReflect() protoreflect.Message { mi := &file_SignalService_proto_msgTypes[73] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -7501,11 +7353,9 @@ type SyncMessage_DeleteForMe_ConversationDelete struct { func (x *SyncMessage_DeleteForMe_ConversationDelete) Reset() { *x = SyncMessage_DeleteForMe_ConversationDelete{} - if protoimpl.UnsafeEnabled { - mi := &file_SignalService_proto_msgTypes[74] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_SignalService_proto_msgTypes[74] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *SyncMessage_DeleteForMe_ConversationDelete) String() string { @@ -7516,7 +7366,7 @@ func (*SyncMessage_DeleteForMe_ConversationDelete) ProtoMessage() {} func (x *SyncMessage_DeleteForMe_ConversationDelete) ProtoReflect() protoreflect.Message { mi := &file_SignalService_proto_msgTypes[74] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -7569,11 +7419,9 @@ type SyncMessage_DeleteForMe_LocalOnlyConversationDelete struct { func (x *SyncMessage_DeleteForMe_LocalOnlyConversationDelete) Reset() { *x = SyncMessage_DeleteForMe_LocalOnlyConversationDelete{} - if protoimpl.UnsafeEnabled { - mi := &file_SignalService_proto_msgTypes[75] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_SignalService_proto_msgTypes[75] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *SyncMessage_DeleteForMe_LocalOnlyConversationDelete) String() string { @@ -7584,7 +7432,7 @@ func (*SyncMessage_DeleteForMe_LocalOnlyConversationDelete) ProtoMessage() {} func (x *SyncMessage_DeleteForMe_LocalOnlyConversationDelete) ProtoReflect() protoreflect.Message { mi := &file_SignalService_proto_msgTypes[75] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -7616,11 +7464,9 @@ type GroupContext_Member struct { func (x *GroupContext_Member) Reset() { *x = GroupContext_Member{} - if protoimpl.UnsafeEnabled { - mi := &file_SignalService_proto_msgTypes[76] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_SignalService_proto_msgTypes[76] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *GroupContext_Member) String() string { @@ -7631,7 +7477,7 @@ func (*GroupContext_Member) ProtoMessage() {} func (x *GroupContext_Member) ProtoReflect() protoreflect.Message { mi := &file_SignalService_proto_msgTypes[76] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -7664,11 +7510,9 @@ type ContactDetails_Avatar struct { func (x *ContactDetails_Avatar) Reset() { *x = ContactDetails_Avatar{} - if protoimpl.UnsafeEnabled { - mi := &file_SignalService_proto_msgTypes[77] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_SignalService_proto_msgTypes[77] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *ContactDetails_Avatar) String() string { @@ -7679,7 +7523,7 @@ func (*ContactDetails_Avatar) ProtoMessage() {} func (x *ContactDetails_Avatar) ProtoReflect() protoreflect.Message { mi := &file_SignalService_proto_msgTypes[77] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -7719,11 +7563,9 @@ type GroupDetails_Avatar struct { func (x *GroupDetails_Avatar) Reset() { *x = GroupDetails_Avatar{} - if protoimpl.UnsafeEnabled { - mi := &file_SignalService_proto_msgTypes[78] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_SignalService_proto_msgTypes[78] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *GroupDetails_Avatar) String() string { @@ -7734,7 +7576,7 @@ func (*GroupDetails_Avatar) ProtoMessage() {} func (x *GroupDetails_Avatar) ProtoReflect() protoreflect.Message { mi := &file_SignalService_proto_msgTypes[78] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -7773,11 +7615,9 @@ type GroupDetails_Member struct { func (x *GroupDetails_Member) Reset() { *x = GroupDetails_Member{} - if protoimpl.UnsafeEnabled { - mi := &file_SignalService_proto_msgTypes[79] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_SignalService_proto_msgTypes[79] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *GroupDetails_Member) String() string { @@ -7788,7 +7628,7 @@ func (*GroupDetails_Member) ProtoMessage() {} func (x *GroupDetails_Member) ProtoReflect() protoreflect.Message { mi := &file_SignalService_proto_msgTypes[79] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -7821,11 +7661,9 @@ type PaymentAddress_MobileCoinAddress struct { func (x *PaymentAddress_MobileCoinAddress) Reset() { *x = PaymentAddress_MobileCoinAddress{} - if protoimpl.UnsafeEnabled { - mi := &file_SignalService_proto_msgTypes[80] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_SignalService_proto_msgTypes[80] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *PaymentAddress_MobileCoinAddress) String() string { @@ -7836,7 +7674,7 @@ func (*PaymentAddress_MobileCoinAddress) ProtoMessage() {} func (x *PaymentAddress_MobileCoinAddress) ProtoReflect() protoreflect.Message { mi := &file_SignalService_proto_msgTypes[80] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -8126,980 +7964,6 @@ func file_SignalService_proto_init() { if File_SignalService_proto != nil { return } - if !protoimpl.UnsafeEnabled { - file_SignalService_proto_msgTypes[0].Exporter = func(v any, i int) any { - switch v := v.(*Envelope); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_SignalService_proto_msgTypes[1].Exporter = func(v any, i int) any { - switch v := v.(*Content); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_SignalService_proto_msgTypes[2].Exporter = func(v any, i int) any { - switch v := v.(*CallMessage); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_SignalService_proto_msgTypes[3].Exporter = func(v any, i int) any { - switch v := v.(*BodyRange); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_SignalService_proto_msgTypes[4].Exporter = func(v any, i int) any { - switch v := v.(*DataMessage); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_SignalService_proto_msgTypes[5].Exporter = func(v any, i int) any { - switch v := v.(*NullMessage); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_SignalService_proto_msgTypes[6].Exporter = func(v any, i int) any { - switch v := v.(*ReceiptMessage); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_SignalService_proto_msgTypes[7].Exporter = func(v any, i int) any { - switch v := v.(*TypingMessage); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_SignalService_proto_msgTypes[8].Exporter = func(v any, i int) any { - switch v := v.(*StoryMessage); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_SignalService_proto_msgTypes[9].Exporter = func(v any, i int) any { - switch v := v.(*Preview); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_SignalService_proto_msgTypes[10].Exporter = func(v any, i int) any { - switch v := v.(*TextAttachment); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_SignalService_proto_msgTypes[11].Exporter = func(v any, i int) any { - switch v := v.(*Verified); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_SignalService_proto_msgTypes[12].Exporter = func(v any, i int) any { - switch v := v.(*SyncMessage); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_SignalService_proto_msgTypes[13].Exporter = func(v any, i int) any { - switch v := v.(*AttachmentPointer); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_SignalService_proto_msgTypes[14].Exporter = func(v any, i int) any { - switch v := v.(*GroupContext); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_SignalService_proto_msgTypes[15].Exporter = func(v any, i int) any { - switch v := v.(*GroupContextV2); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_SignalService_proto_msgTypes[16].Exporter = func(v any, i int) any { - switch v := v.(*ContactDetails); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_SignalService_proto_msgTypes[17].Exporter = func(v any, i int) any { - switch v := v.(*GroupDetails); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_SignalService_proto_msgTypes[18].Exporter = func(v any, i int) any { - switch v := v.(*PaymentAddress); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_SignalService_proto_msgTypes[19].Exporter = func(v any, i int) any { - switch v := v.(*DecryptionErrorMessage); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_SignalService_proto_msgTypes[20].Exporter = func(v any, i int) any { - switch v := v.(*PniSignatureMessage); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_SignalService_proto_msgTypes[21].Exporter = func(v any, i int) any { - switch v := v.(*EditMessage); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_SignalService_proto_msgTypes[22].Exporter = func(v any, i int) any { - switch v := v.(*CallMessage_Offer); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_SignalService_proto_msgTypes[23].Exporter = func(v any, i int) any { - switch v := v.(*CallMessage_Answer); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_SignalService_proto_msgTypes[24].Exporter = func(v any, i int) any { - switch v := v.(*CallMessage_IceUpdate); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_SignalService_proto_msgTypes[25].Exporter = func(v any, i int) any { - switch v := v.(*CallMessage_Busy); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_SignalService_proto_msgTypes[26].Exporter = func(v any, i int) any { - switch v := v.(*CallMessage_Hangup); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_SignalService_proto_msgTypes[27].Exporter = func(v any, i int) any { - switch v := v.(*CallMessage_Opaque); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_SignalService_proto_msgTypes[28].Exporter = func(v any, i int) any { - switch v := v.(*DataMessage_Quote); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_SignalService_proto_msgTypes[29].Exporter = func(v any, i int) any { - switch v := v.(*DataMessage_Contact); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_SignalService_proto_msgTypes[30].Exporter = func(v any, i int) any { - switch v := v.(*DataMessage_Sticker); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_SignalService_proto_msgTypes[31].Exporter = func(v any, i int) any { - switch v := v.(*DataMessage_Reaction); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_SignalService_proto_msgTypes[32].Exporter = func(v any, i int) any { - switch v := v.(*DataMessage_Delete); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_SignalService_proto_msgTypes[33].Exporter = func(v any, i int) any { - switch v := v.(*DataMessage_GroupCallUpdate); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_SignalService_proto_msgTypes[34].Exporter = func(v any, i int) any { - switch v := v.(*DataMessage_StoryContext); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_SignalService_proto_msgTypes[35].Exporter = func(v any, i int) any { - switch v := v.(*DataMessage_Payment); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_SignalService_proto_msgTypes[36].Exporter = func(v any, i int) any { - switch v := v.(*DataMessage_GiftBadge); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_SignalService_proto_msgTypes[37].Exporter = func(v any, i int) any { - switch v := v.(*DataMessage_Quote_QuotedAttachment); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_SignalService_proto_msgTypes[38].Exporter = func(v any, i int) any { - switch v := v.(*DataMessage_Contact_Name); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_SignalService_proto_msgTypes[39].Exporter = func(v any, i int) any { - switch v := v.(*DataMessage_Contact_Phone); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_SignalService_proto_msgTypes[40].Exporter = func(v any, i int) any { - switch v := v.(*DataMessage_Contact_Email); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_SignalService_proto_msgTypes[41].Exporter = func(v any, i int) any { - switch v := v.(*DataMessage_Contact_PostalAddress); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_SignalService_proto_msgTypes[42].Exporter = func(v any, i int) any { - switch v := v.(*DataMessage_Contact_Avatar); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_SignalService_proto_msgTypes[43].Exporter = func(v any, i int) any { - switch v := v.(*DataMessage_Payment_Amount); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_SignalService_proto_msgTypes[44].Exporter = func(v any, i int) any { - switch v := v.(*DataMessage_Payment_Notification); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_SignalService_proto_msgTypes[45].Exporter = func(v any, i int) any { - switch v := v.(*DataMessage_Payment_Activation); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_SignalService_proto_msgTypes[46].Exporter = func(v any, i int) any { - switch v := v.(*DataMessage_Payment_Amount_MobileCoin); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_SignalService_proto_msgTypes[47].Exporter = func(v any, i int) any { - switch v := v.(*DataMessage_Payment_Notification_MobileCoin); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_SignalService_proto_msgTypes[48].Exporter = func(v any, i int) any { - switch v := v.(*TextAttachment_Gradient); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_SignalService_proto_msgTypes[49].Exporter = func(v any, i int) any { - switch v := v.(*SyncMessage_Sent); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_SignalService_proto_msgTypes[50].Exporter = func(v any, i int) any { - switch v := v.(*SyncMessage_Contacts); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_SignalService_proto_msgTypes[51].Exporter = func(v any, i int) any { - switch v := v.(*SyncMessage_Blocked); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_SignalService_proto_msgTypes[52].Exporter = func(v any, i int) any { - switch v := v.(*SyncMessage_Request); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_SignalService_proto_msgTypes[53].Exporter = func(v any, i int) any { - switch v := v.(*SyncMessage_Read); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_SignalService_proto_msgTypes[54].Exporter = func(v any, i int) any { - switch v := v.(*SyncMessage_Viewed); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_SignalService_proto_msgTypes[55].Exporter = func(v any, i int) any { - switch v := v.(*SyncMessage_Configuration); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_SignalService_proto_msgTypes[56].Exporter = func(v any, i int) any { - switch v := v.(*SyncMessage_StickerPackOperation); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_SignalService_proto_msgTypes[57].Exporter = func(v any, i int) any { - switch v := v.(*SyncMessage_ViewOnceOpen); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_SignalService_proto_msgTypes[58].Exporter = func(v any, i int) any { - switch v := v.(*SyncMessage_FetchLatest); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_SignalService_proto_msgTypes[59].Exporter = func(v any, i int) any { - switch v := v.(*SyncMessage_Keys); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_SignalService_proto_msgTypes[60].Exporter = func(v any, i int) any { - switch v := v.(*SyncMessage_MessageRequestResponse); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_SignalService_proto_msgTypes[61].Exporter = func(v any, i int) any { - switch v := v.(*SyncMessage_OutgoingPayment); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_SignalService_proto_msgTypes[62].Exporter = func(v any, i int) any { - switch v := v.(*SyncMessage_PniChangeNumber); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_SignalService_proto_msgTypes[63].Exporter = func(v any, i int) any { - switch v := v.(*SyncMessage_CallEvent); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_SignalService_proto_msgTypes[64].Exporter = func(v any, i int) any { - switch v := v.(*SyncMessage_CallLinkUpdate); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_SignalService_proto_msgTypes[65].Exporter = func(v any, i int) any { - switch v := v.(*SyncMessage_CallLogEvent); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_SignalService_proto_msgTypes[66].Exporter = func(v any, i int) any { - switch v := v.(*SyncMessage_DeleteForMe); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_SignalService_proto_msgTypes[67].Exporter = func(v any, i int) any { - switch v := v.(*SyncMessage_Sent_UnidentifiedDeliveryStatus); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_SignalService_proto_msgTypes[68].Exporter = func(v any, i int) any { - switch v := v.(*SyncMessage_Sent_StoryMessageRecipient); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_SignalService_proto_msgTypes[69].Exporter = func(v any, i int) any { - switch v := v.(*SyncMessage_OutgoingPayment_MobileCoin); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_SignalService_proto_msgTypes[70].Exporter = func(v any, i int) any { - switch v := v.(*SyncMessage_DeleteForMe_ConversationIdentifier); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_SignalService_proto_msgTypes[71].Exporter = func(v any, i int) any { - switch v := v.(*SyncMessage_DeleteForMe_AddressableMessage); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_SignalService_proto_msgTypes[72].Exporter = func(v any, i int) any { - switch v := v.(*SyncMessage_DeleteForMe_MessageDeletes); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_SignalService_proto_msgTypes[73].Exporter = func(v any, i int) any { - switch v := v.(*SyncMessage_DeleteForMe_AttachmentDelete); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_SignalService_proto_msgTypes[74].Exporter = func(v any, i int) any { - switch v := v.(*SyncMessage_DeleteForMe_ConversationDelete); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_SignalService_proto_msgTypes[75].Exporter = func(v any, i int) any { - switch v := v.(*SyncMessage_DeleteForMe_LocalOnlyConversationDelete); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_SignalService_proto_msgTypes[76].Exporter = func(v any, i int) any { - switch v := v.(*GroupContext_Member); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_SignalService_proto_msgTypes[77].Exporter = func(v any, i int) any { - switch v := v.(*ContactDetails_Avatar); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_SignalService_proto_msgTypes[78].Exporter = func(v any, i int) any { - switch v := v.(*GroupDetails_Avatar); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_SignalService_proto_msgTypes[79].Exporter = func(v any, i int) any { - switch v := v.(*GroupDetails_Member); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_SignalService_proto_msgTypes[80].Exporter = func(v any, i int) any { - switch v := v.(*PaymentAddress_MobileCoinAddress); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - } file_SignalService_proto_msgTypes[3].OneofWrappers = []any{ (*BodyRange_MentionAci)(nil), (*BodyRange_Style_)(nil), diff --git a/pkg/signalmeow/protobuf/SignalService.pb.raw b/pkg/signalmeow/protobuf/SignalService.pb.raw index 322d177c380305a0f2efe3ed65c91c4405103817..45c938aa97b57244e0ce9953a01cc7c33bc05a03 100644 GIT binary patch delta 48 wcmdlrm2uZp#tj0(ic(x0d6~)Cd5O8H66^|$8k|9Jz84Dzn*jS}L*Y(y09|1XLI3~& delta 48 tcmdlrm2uZp#tj0(iV9rZDVfCuIf<2iiMgo~YzmAToI%J!n+=6K%>i}04?F+> diff --git a/pkg/signalmeow/protobuf/SignalService.proto b/pkg/signalmeow/protobuf/SignalService.proto index 177018f..aa0a752 100644 --- a/pkg/signalmeow/protobuf/SignalService.proto +++ b/pkg/signalmeow/protobuf/SignalService.proto @@ -177,7 +177,8 @@ message DataMessage { optional string prefix = 3; optional string suffix = 4; optional string middleName = 5; - optional string displayName = 6; + reserved /*displayName*/ 6; + optional string nickname = 7; } message Phone { diff --git a/pkg/signalmeow/protobuf/StickerResources.pb.go b/pkg/signalmeow/protobuf/StickerResources.pb.go index b64f824..0da3266 100644 --- a/pkg/signalmeow/protobuf/StickerResources.pb.go +++ b/pkg/signalmeow/protobuf/StickerResources.pb.go @@ -5,7 +5,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.34.2 +// protoc-gen-go v1.35.1 // protoc v3.21.12 // source: StickerResources.proto @@ -40,11 +40,9 @@ type Pack struct { func (x *Pack) Reset() { *x = Pack{} - if protoimpl.UnsafeEnabled { - mi := &file_StickerResources_proto_msgTypes[0] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_StickerResources_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *Pack) String() string { @@ -55,7 +53,7 @@ func (*Pack) ProtoMessage() {} func (x *Pack) ProtoReflect() protoreflect.Message { mi := &file_StickerResources_proto_msgTypes[0] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -110,11 +108,9 @@ type Pack_Sticker struct { func (x *Pack_Sticker) Reset() { *x = Pack_Sticker{} - if protoimpl.UnsafeEnabled { - mi := &file_StickerResources_proto_msgTypes[1] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_StickerResources_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *Pack_Sticker) String() string { @@ -125,7 +121,7 @@ func (*Pack_Sticker) ProtoMessage() {} func (x *Pack_Sticker) ProtoReflect() protoreflect.Message { mi := &file_StickerResources_proto_msgTypes[1] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -198,32 +194,6 @@ func file_StickerResources_proto_init() { if File_StickerResources_proto != nil { return } - if !protoimpl.UnsafeEnabled { - file_StickerResources_proto_msgTypes[0].Exporter = func(v any, i int) any { - switch v := v.(*Pack); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_StickerResources_proto_msgTypes[1].Exporter = func(v any, i int) any { - switch v := v.(*Pack_Sticker); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - } type x struct{} out := protoimpl.TypeBuilder{ File: protoimpl.DescBuilder{ diff --git a/pkg/signalmeow/protobuf/StorageService.pb.go b/pkg/signalmeow/protobuf/StorageService.pb.go index 788cb41..269354a 100644 --- a/pkg/signalmeow/protobuf/StorageService.pb.go +++ b/pkg/signalmeow/protobuf/StorageService.pb.go @@ -5,7 +5,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.34.2 +// protoc-gen-go v1.35.1 // protoc v3.21.12 // source: StorageService.proto @@ -362,11 +362,9 @@ type StorageManifest struct { func (x *StorageManifest) Reset() { *x = StorageManifest{} - if protoimpl.UnsafeEnabled { - mi := &file_StorageService_proto_msgTypes[0] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_StorageService_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *StorageManifest) String() string { @@ -377,7 +375,7 @@ func (*StorageManifest) ProtoMessage() {} func (x *StorageManifest) ProtoReflect() protoreflect.Message { mi := &file_StorageService_proto_msgTypes[0] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -417,11 +415,9 @@ type StorageItem struct { func (x *StorageItem) Reset() { *x = StorageItem{} - if protoimpl.UnsafeEnabled { - mi := &file_StorageService_proto_msgTypes[1] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_StorageService_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *StorageItem) String() string { @@ -432,7 +428,7 @@ func (*StorageItem) ProtoMessage() {} func (x *StorageItem) ProtoReflect() protoreflect.Message { mi := &file_StorageService_proto_msgTypes[1] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -471,11 +467,9 @@ type StorageItems struct { func (x *StorageItems) Reset() { *x = StorageItems{} - if protoimpl.UnsafeEnabled { - mi := &file_StorageService_proto_msgTypes[2] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_StorageService_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *StorageItems) String() string { @@ -486,7 +480,7 @@ func (*StorageItems) ProtoMessage() {} func (x *StorageItems) ProtoReflect() protoreflect.Message { mi := &file_StorageService_proto_msgTypes[2] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -518,11 +512,9 @@ type ReadOperation struct { func (x *ReadOperation) Reset() { *x = ReadOperation{} - if protoimpl.UnsafeEnabled { - mi := &file_StorageService_proto_msgTypes[3] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_StorageService_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *ReadOperation) String() string { @@ -533,7 +525,7 @@ func (*ReadOperation) ProtoMessage() {} func (x *ReadOperation) ProtoReflect() protoreflect.Message { mi := &file_StorageService_proto_msgTypes[3] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -568,11 +560,9 @@ type WriteOperation struct { func (x *WriteOperation) Reset() { *x = WriteOperation{} - if protoimpl.UnsafeEnabled { - mi := &file_StorageService_proto_msgTypes[4] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_StorageService_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *WriteOperation) String() string { @@ -583,7 +573,7 @@ func (*WriteOperation) ProtoMessage() {} func (x *WriteOperation) ProtoReflect() protoreflect.Message { mi := &file_StorageService_proto_msgTypes[4] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -638,11 +628,9 @@ type ManifestRecord struct { func (x *ManifestRecord) Reset() { *x = ManifestRecord{} - if protoimpl.UnsafeEnabled { - mi := &file_StorageService_proto_msgTypes[5] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_StorageService_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *ManifestRecord) String() string { @@ -653,7 +641,7 @@ func (*ManifestRecord) ProtoMessage() {} func (x *ManifestRecord) ProtoReflect() protoreflect.Message { mi := &file_StorageService_proto_msgTypes[5] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -707,11 +695,9 @@ type StorageRecord struct { func (x *StorageRecord) Reset() { *x = StorageRecord{} - if protoimpl.UnsafeEnabled { - mi := &file_StorageService_proto_msgTypes[6] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_StorageService_proto_msgTypes[6] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *StorageRecord) String() string { @@ -722,7 +708,7 @@ func (*StorageRecord) ProtoMessage() {} func (x *StorageRecord) ProtoReflect() protoreflect.Message { mi := &file_StorageService_proto_msgTypes[6] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -858,11 +844,9 @@ type ContactRecord struct { func (x *ContactRecord) Reset() { *x = ContactRecord{} - if protoimpl.UnsafeEnabled { - mi := &file_StorageService_proto_msgTypes[7] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_StorageService_proto_msgTypes[7] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *ContactRecord) String() string { @@ -873,7 +857,7 @@ func (*ContactRecord) ProtoMessage() {} func (x *ContactRecord) ProtoReflect() protoreflect.Message { mi := &file_StorageService_proto_msgTypes[7] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -1064,11 +1048,9 @@ type GroupV1Record struct { func (x *GroupV1Record) Reset() { *x = GroupV1Record{} - if protoimpl.UnsafeEnabled { - mi := &file_StorageService_proto_msgTypes[8] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_StorageService_proto_msgTypes[8] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *GroupV1Record) String() string { @@ -1079,7 +1061,7 @@ func (*GroupV1Record) ProtoMessage() {} func (x *GroupV1Record) ProtoReflect() protoreflect.Message { mi := &file_StorageService_proto_msgTypes[8] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -1154,11 +1136,9 @@ type GroupV2Record struct { func (x *GroupV2Record) Reset() { *x = GroupV2Record{} - if protoimpl.UnsafeEnabled { - mi := &file_StorageService_proto_msgTypes[9] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_StorageService_proto_msgTypes[9] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *GroupV2Record) String() string { @@ -1169,7 +1149,7 @@ func (*GroupV2Record) ProtoMessage() {} func (x *GroupV2Record) ProtoReflect() protoreflect.Message { mi := &file_StorageService_proto_msgTypes[9] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -1258,11 +1238,9 @@ type Payments struct { func (x *Payments) Reset() { *x = Payments{} - if protoimpl.UnsafeEnabled { - mi := &file_StorageService_proto_msgTypes[10] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_StorageService_proto_msgTypes[10] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *Payments) String() string { @@ -1273,7 +1251,7 @@ func (*Payments) ProtoMessage() {} func (x *Payments) ProtoReflect() protoreflect.Message { mi := &file_StorageService_proto_msgTypes[10] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -1339,15 +1317,15 @@ type AccountRecord struct { Username string `protobuf:"bytes,33,opt,name=username,proto3" json:"username,omitempty"` HasCompletedUsernameOnboarding bool `protobuf:"varint,34,opt,name=hasCompletedUsernameOnboarding,proto3" json:"hasCompletedUsernameOnboarding,omitempty"` UsernameLink *AccountRecord_UsernameLink `protobuf:"bytes,35,opt,name=usernameLink,proto3" json:"usernameLink,omitempty"` + BackupsSubscriberId []byte `protobuf:"bytes,36,opt,name=backupsSubscriberId,proto3" json:"backupsSubscriberId,omitempty"` + BackupsSubscriberCurrencyCode string `protobuf:"bytes,37,opt,name=backupsSubscriberCurrencyCode,proto3" json:"backupsSubscriberCurrencyCode,omitempty"` } func (x *AccountRecord) Reset() { *x = AccountRecord{} - if protoimpl.UnsafeEnabled { - mi := &file_StorageService_proto_msgTypes[11] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_StorageService_proto_msgTypes[11] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *AccountRecord) String() string { @@ -1358,7 +1336,7 @@ func (*AccountRecord) ProtoMessage() {} func (x *AccountRecord) ProtoReflect() protoreflect.Message { mi := &file_StorageService_proto_msgTypes[11] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -1597,6 +1575,20 @@ func (x *AccountRecord) GetUsernameLink() *AccountRecord_UsernameLink { return nil } +func (x *AccountRecord) GetBackupsSubscriberId() []byte { + if x != nil { + return x.BackupsSubscriberId + } + return nil +} + +func (x *AccountRecord) GetBackupsSubscriberCurrencyCode() string { + if x != nil { + return x.BackupsSubscriberCurrencyCode + } + return "" +} + type StoryDistributionListRecord struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -1612,11 +1604,9 @@ type StoryDistributionListRecord struct { func (x *StoryDistributionListRecord) Reset() { *x = StoryDistributionListRecord{} - if protoimpl.UnsafeEnabled { - mi := &file_StorageService_proto_msgTypes[12] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_StorageService_proto_msgTypes[12] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *StoryDistributionListRecord) String() string { @@ -1627,7 +1617,7 @@ func (*StoryDistributionListRecord) ProtoMessage() {} func (x *StoryDistributionListRecord) ProtoReflect() protoreflect.Message { mi := &file_StorageService_proto_msgTypes[12] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -1696,11 +1686,9 @@ type CallLinkRecord struct { func (x *CallLinkRecord) Reset() { *x = CallLinkRecord{} - if protoimpl.UnsafeEnabled { - mi := &file_StorageService_proto_msgTypes[13] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_StorageService_proto_msgTypes[13] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *CallLinkRecord) String() string { @@ -1711,7 +1699,7 @@ func (*CallLinkRecord) ProtoMessage() {} func (x *CallLinkRecord) ProtoReflect() protoreflect.Message { mi := &file_StorageService_proto_msgTypes[13] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -1758,11 +1746,9 @@ type ManifestRecord_Identifier struct { func (x *ManifestRecord_Identifier) Reset() { *x = ManifestRecord_Identifier{} - if protoimpl.UnsafeEnabled { - mi := &file_StorageService_proto_msgTypes[14] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_StorageService_proto_msgTypes[14] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *ManifestRecord_Identifier) String() string { @@ -1773,7 +1759,7 @@ func (*ManifestRecord_Identifier) ProtoMessage() {} func (x *ManifestRecord_Identifier) ProtoReflect() protoreflect.Message { mi := &file_StorageService_proto_msgTypes[14] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -1813,11 +1799,9 @@ type ContactRecord_Name struct { func (x *ContactRecord_Name) Reset() { *x = ContactRecord_Name{} - if protoimpl.UnsafeEnabled { - mi := &file_StorageService_proto_msgTypes[15] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_StorageService_proto_msgTypes[15] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *ContactRecord_Name) String() string { @@ -1828,7 +1812,7 @@ func (*ContactRecord_Name) ProtoMessage() {} func (x *ContactRecord_Name) ProtoReflect() protoreflect.Message { mi := &file_StorageService_proto_msgTypes[15] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -1872,11 +1856,9 @@ type AccountRecord_PinnedConversation struct { func (x *AccountRecord_PinnedConversation) Reset() { *x = AccountRecord_PinnedConversation{} - if protoimpl.UnsafeEnabled { - mi := &file_StorageService_proto_msgTypes[16] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_StorageService_proto_msgTypes[16] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *AccountRecord_PinnedConversation) String() string { @@ -1887,7 +1869,7 @@ func (*AccountRecord_PinnedConversation) ProtoMessage() {} func (x *AccountRecord_PinnedConversation) ProtoReflect() protoreflect.Message { mi := &file_StorageService_proto_msgTypes[16] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -1966,11 +1948,9 @@ type AccountRecord_UsernameLink struct { func (x *AccountRecord_UsernameLink) Reset() { *x = AccountRecord_UsernameLink{} - if protoimpl.UnsafeEnabled { - mi := &file_StorageService_proto_msgTypes[17] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_StorageService_proto_msgTypes[17] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *AccountRecord_UsernameLink) String() string { @@ -1981,7 +1961,7 @@ func (*AccountRecord_UsernameLink) ProtoMessage() {} func (x *AccountRecord_UsernameLink) ProtoReflect() protoreflect.Message { mi := &file_StorageService_proto_msgTypes[17] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -2028,11 +2008,9 @@ type AccountRecord_PinnedConversation_Contact struct { func (x *AccountRecord_PinnedConversation_Contact) Reset() { *x = AccountRecord_PinnedConversation_Contact{} - if protoimpl.UnsafeEnabled { - mi := &file_StorageService_proto_msgTypes[18] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_StorageService_proto_msgTypes[18] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *AccountRecord_PinnedConversation_Contact) String() string { @@ -2043,7 +2021,7 @@ func (*AccountRecord_PinnedConversation_Contact) ProtoMessage() {} func (x *AccountRecord_PinnedConversation_Contact) ProtoReflect() protoreflect.Message { mi := &file_StorageService_proto_msgTypes[18] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -2152,236 +2130,6 @@ func file_StorageService_proto_init() { if File_StorageService_proto != nil { return } - if !protoimpl.UnsafeEnabled { - file_StorageService_proto_msgTypes[0].Exporter = func(v any, i int) any { - switch v := v.(*StorageManifest); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_StorageService_proto_msgTypes[1].Exporter = func(v any, i int) any { - switch v := v.(*StorageItem); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_StorageService_proto_msgTypes[2].Exporter = func(v any, i int) any { - switch v := v.(*StorageItems); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_StorageService_proto_msgTypes[3].Exporter = func(v any, i int) any { - switch v := v.(*ReadOperation); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_StorageService_proto_msgTypes[4].Exporter = func(v any, i int) any { - switch v := v.(*WriteOperation); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_StorageService_proto_msgTypes[5].Exporter = func(v any, i int) any { - switch v := v.(*ManifestRecord); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_StorageService_proto_msgTypes[6].Exporter = func(v any, i int) any { - switch v := v.(*StorageRecord); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_StorageService_proto_msgTypes[7].Exporter = func(v any, i int) any { - switch v := v.(*ContactRecord); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_StorageService_proto_msgTypes[8].Exporter = func(v any, i int) any { - switch v := v.(*GroupV1Record); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_StorageService_proto_msgTypes[9].Exporter = func(v any, i int) any { - switch v := v.(*GroupV2Record); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_StorageService_proto_msgTypes[10].Exporter = func(v any, i int) any { - switch v := v.(*Payments); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_StorageService_proto_msgTypes[11].Exporter = func(v any, i int) any { - switch v := v.(*AccountRecord); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_StorageService_proto_msgTypes[12].Exporter = func(v any, i int) any { - switch v := v.(*StoryDistributionListRecord); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_StorageService_proto_msgTypes[13].Exporter = func(v any, i int) any { - switch v := v.(*CallLinkRecord); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_StorageService_proto_msgTypes[14].Exporter = func(v any, i int) any { - switch v := v.(*ManifestRecord_Identifier); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_StorageService_proto_msgTypes[15].Exporter = func(v any, i int) any { - switch v := v.(*ContactRecord_Name); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_StorageService_proto_msgTypes[16].Exporter = func(v any, i int) any { - switch v := v.(*AccountRecord_PinnedConversation); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_StorageService_proto_msgTypes[17].Exporter = func(v any, i int) any { - switch v := v.(*AccountRecord_UsernameLink); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_StorageService_proto_msgTypes[18].Exporter = func(v any, i int) any { - switch v := v.(*AccountRecord_PinnedConversation_Contact); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - } file_StorageService_proto_msgTypes[6].OneofWrappers = []any{ (*StorageRecord_Contact)(nil), (*StorageRecord_GroupV1)(nil), diff --git a/pkg/signalmeow/protobuf/StorageService.pb.raw b/pkg/signalmeow/protobuf/StorageService.pb.raw index 2dea02fae9b6d83f802dedf2454956c05857ef2e..c4befd576011672424b415535ef42449380d7931 100644 GIT binary patch delta 108 zcmdm{yH0PzY;LAW!kg!EA7Zl;GT;(UN=(i!Ehr8yO)5?<%1lZv@=TFXQDD^I3Bo2N cwODo`zF5Q^aDc%g6>0JjMu_W%F@ delta 20 ccmZ3dw@r7$Y;LAmLYwDuA7a~lT_~Id09UpL-T(jq diff --git a/pkg/signalmeow/protobuf/StorageService.proto b/pkg/signalmeow/protobuf/StorageService.proto index 304e73f..7b2fa3a 100644 --- a/pkg/signalmeow/protobuf/StorageService.proto +++ b/pkg/signalmeow/protobuf/StorageService.proto @@ -219,6 +219,8 @@ message AccountRecord { string username = 33; bool hasCompletedUsernameOnboarding = 34; UsernameLink usernameLink = 35; + bytes backupsSubscriberId = 36; + string backupsSubscriberCurrencyCode = 37; } message StoryDistributionListRecord { diff --git a/pkg/signalmeow/protobuf/UnidentifiedDelivery.pb.go b/pkg/signalmeow/protobuf/UnidentifiedDelivery.pb.go index 97d1b46..b42ca6f 100644 --- a/pkg/signalmeow/protobuf/UnidentifiedDelivery.pb.go +++ b/pkg/signalmeow/protobuf/UnidentifiedDelivery.pb.go @@ -1,6 +1,6 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.34.2 +// protoc-gen-go v1.35.1 // protoc v3.21.12 // source: UnidentifiedDelivery.proto @@ -160,11 +160,9 @@ type ServerCertificate struct { func (x *ServerCertificate) Reset() { *x = ServerCertificate{} - if protoimpl.UnsafeEnabled { - mi := &file_UnidentifiedDelivery_proto_msgTypes[0] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_UnidentifiedDelivery_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *ServerCertificate) String() string { @@ -175,7 +173,7 @@ func (*ServerCertificate) ProtoMessage() {} func (x *ServerCertificate) ProtoReflect() protoreflect.Message { mi := &file_UnidentifiedDelivery_proto_msgTypes[0] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -215,11 +213,9 @@ type SenderCertificate struct { func (x *SenderCertificate) Reset() { *x = SenderCertificate{} - if protoimpl.UnsafeEnabled { - mi := &file_UnidentifiedDelivery_proto_msgTypes[1] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_UnidentifiedDelivery_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *SenderCertificate) String() string { @@ -230,7 +226,7 @@ func (*SenderCertificate) ProtoMessage() {} func (x *SenderCertificate) ProtoReflect() protoreflect.Message { mi := &file_UnidentifiedDelivery_proto_msgTypes[1] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -271,11 +267,9 @@ type UnidentifiedSenderMessage struct { func (x *UnidentifiedSenderMessage) Reset() { *x = UnidentifiedSenderMessage{} - if protoimpl.UnsafeEnabled { - mi := &file_UnidentifiedDelivery_proto_msgTypes[2] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_UnidentifiedDelivery_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *UnidentifiedSenderMessage) String() string { @@ -286,7 +280,7 @@ func (*UnidentifiedSenderMessage) ProtoMessage() {} func (x *UnidentifiedSenderMessage) ProtoReflect() protoreflect.Message { mi := &file_UnidentifiedDelivery_proto_msgTypes[2] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -333,11 +327,9 @@ type ServerCertificate_Certificate struct { func (x *ServerCertificate_Certificate) Reset() { *x = ServerCertificate_Certificate{} - if protoimpl.UnsafeEnabled { - mi := &file_UnidentifiedDelivery_proto_msgTypes[3] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_UnidentifiedDelivery_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *ServerCertificate_Certificate) String() string { @@ -348,7 +340,7 @@ func (*ServerCertificate_Certificate) ProtoMessage() {} func (x *ServerCertificate_Certificate) ProtoReflect() protoreflect.Message { mi := &file_UnidentifiedDelivery_proto_msgTypes[3] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -392,11 +384,9 @@ type SenderCertificate_Certificate struct { func (x *SenderCertificate_Certificate) Reset() { *x = SenderCertificate_Certificate{} - if protoimpl.UnsafeEnabled { - mi := &file_UnidentifiedDelivery_proto_msgTypes[4] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_UnidentifiedDelivery_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *SenderCertificate_Certificate) String() string { @@ -407,7 +397,7 @@ func (*SenderCertificate_Certificate) ProtoMessage() {} func (x *SenderCertificate_Certificate) ProtoReflect() protoreflect.Message { mi := &file_UnidentifiedDelivery_proto_msgTypes[4] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -478,11 +468,9 @@ type UnidentifiedSenderMessage_Message struct { func (x *UnidentifiedSenderMessage_Message) Reset() { *x = UnidentifiedSenderMessage_Message{} - if protoimpl.UnsafeEnabled { - mi := &file_UnidentifiedDelivery_proto_msgTypes[5] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_UnidentifiedDelivery_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *UnidentifiedSenderMessage_Message) String() string { @@ -493,7 +481,7 @@ func (*UnidentifiedSenderMessage_Message) ProtoMessage() {} func (x *UnidentifiedSenderMessage_Message) ProtoReflect() protoreflect.Message { mi := &file_UnidentifiedDelivery_proto_msgTypes[5] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -589,80 +577,6 @@ func file_UnidentifiedDelivery_proto_init() { if File_UnidentifiedDelivery_proto != nil { return } - if !protoimpl.UnsafeEnabled { - file_UnidentifiedDelivery_proto_msgTypes[0].Exporter = func(v any, i int) any { - switch v := v.(*ServerCertificate); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_UnidentifiedDelivery_proto_msgTypes[1].Exporter = func(v any, i int) any { - switch v := v.(*SenderCertificate); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_UnidentifiedDelivery_proto_msgTypes[2].Exporter = func(v any, i int) any { - switch v := v.(*UnidentifiedSenderMessage); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_UnidentifiedDelivery_proto_msgTypes[3].Exporter = func(v any, i int) any { - switch v := v.(*ServerCertificate_Certificate); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_UnidentifiedDelivery_proto_msgTypes[4].Exporter = func(v any, i int) any { - switch v := v.(*SenderCertificate_Certificate); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_UnidentifiedDelivery_proto_msgTypes[5].Exporter = func(v any, i int) any { - switch v := v.(*UnidentifiedSenderMessage_Message); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - } type x struct{} out := protoimpl.TypeBuilder{ File: protoimpl.DescBuilder{ diff --git a/pkg/signalmeow/protobuf/WebSocketResources.pb.go b/pkg/signalmeow/protobuf/WebSocketResources.pb.go index cf124d4..b3514e6 100644 --- a/pkg/signalmeow/protobuf/WebSocketResources.pb.go +++ b/pkg/signalmeow/protobuf/WebSocketResources.pb.go @@ -5,7 +5,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.34.2 +// protoc-gen-go v1.35.1 // protoc v3.21.12 // source: WebSocketResources.proto @@ -100,11 +100,9 @@ type WebSocketRequestMessage struct { func (x *WebSocketRequestMessage) Reset() { *x = WebSocketRequestMessage{} - if protoimpl.UnsafeEnabled { - mi := &file_WebSocketResources_proto_msgTypes[0] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_WebSocketResources_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *WebSocketRequestMessage) String() string { @@ -115,7 +113,7 @@ func (*WebSocketRequestMessage) ProtoMessage() {} func (x *WebSocketRequestMessage) ProtoReflect() protoreflect.Message { mi := &file_WebSocketResources_proto_msgTypes[0] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -179,11 +177,9 @@ type WebSocketResponseMessage struct { func (x *WebSocketResponseMessage) Reset() { *x = WebSocketResponseMessage{} - if protoimpl.UnsafeEnabled { - mi := &file_WebSocketResources_proto_msgTypes[1] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_WebSocketResources_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *WebSocketResponseMessage) String() string { @@ -194,7 +190,7 @@ func (*WebSocketResponseMessage) ProtoMessage() {} func (x *WebSocketResponseMessage) ProtoReflect() protoreflect.Message { mi := &file_WebSocketResources_proto_msgTypes[1] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -256,11 +252,9 @@ type WebSocketMessage struct { func (x *WebSocketMessage) Reset() { *x = WebSocketMessage{} - if protoimpl.UnsafeEnabled { - mi := &file_WebSocketResources_proto_msgTypes[2] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_WebSocketResources_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *WebSocketMessage) String() string { @@ -271,7 +265,7 @@ func (*WebSocketMessage) ProtoMessage() {} func (x *WebSocketMessage) ProtoReflect() protoreflect.Message { mi := &file_WebSocketResources_proto_msgTypes[2] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -348,44 +342,6 @@ func file_WebSocketResources_proto_init() { if File_WebSocketResources_proto != nil { return } - if !protoimpl.UnsafeEnabled { - file_WebSocketResources_proto_msgTypes[0].Exporter = func(v any, i int) any { - switch v := v.(*WebSocketRequestMessage); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_WebSocketResources_proto_msgTypes[1].Exporter = func(v any, i int) any { - switch v := v.(*WebSocketResponseMessage); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_WebSocketResources_proto_msgTypes[2].Exporter = func(v any, i int) any { - switch v := v.(*WebSocketMessage); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - } type x struct{} out := protoimpl.TypeBuilder{ File: protoimpl.DescBuilder{ diff --git a/pkg/signalmeow/protobuf/update-protos.sh b/pkg/signalmeow/protobuf/update-protos.sh index 87eb1ec..4faa611 100755 --- a/pkg/signalmeow/protobuf/update-protos.sh +++ b/pkg/signalmeow/protobuf/update-protos.sh @@ -1,8 +1,8 @@ #!/bin/bash set -euo pipefail -ANDROID_GIT_REVISION=${1:-69e1146e2c5bbd6f2773dfe12f723e7cc88064be} -DESKTOP_GIT_REVISION=${1:-2640c34bd3eb6d338fbf32621fdf839d2ca3d155} +ANDROID_GIT_REVISION=${1:-551cda13b7dbfaa168f8c1a577b29cdf075e7b3f} +DESKTOP_GIT_REVISION=${1:-76a77a9b7fde3fc21b86e29071eb4e93b5e12ff1} update_proto() { case "$1" in From bec70b6537d49573c326678697a774881a511d1f Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Tue, 15 Oct 2024 17:10:07 +0300 Subject: [PATCH 210/580] libsignal: update to v0.58.3 --- pkg/libsignalgo/libsignal | 2 +- pkg/libsignalgo/libsignal-ffi.h | 2 ++ pkg/libsignalgo/version.go | 2 +- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/pkg/libsignalgo/libsignal b/pkg/libsignalgo/libsignal index 5de6300..29d3270 160000 --- a/pkg/libsignalgo/libsignal +++ b/pkg/libsignalgo/libsignal @@ -1 +1 @@ -Subproject commit 5de6300ab21b34984dd0f79214aa6f3c08ac755d +Subproject commit 29d32702b5cb0dc302ca2fa08377cddaaaacb60c diff --git a/pkg/libsignalgo/libsignal-ffi.h b/pkg/libsignalgo/libsignal-ffi.h index 60015ea..5b13971 100644 --- a/pkg/libsignalgo/libsignal-ffi.h +++ b/pkg/libsignalgo/libsignal-ffi.h @@ -1559,6 +1559,8 @@ SignalFfiError *signal_pin_local_hash(const char **out, SignalBorrowedBuffer pin SignalFfiError *signal_pin_verify_local_hash(bool *out, const char *encoded_hash, SignalBorrowedBuffer pin); +SignalFfiError *signal_account_entropy_pool_generate(const char **out); + SignalFfiError *signal_svr2_client_new(SignalSgxClientState **out, SignalBorrowedBuffer mrenclave, SignalBorrowedBuffer attestation_msg, uint64_t current_timestamp); SignalFfiError *signal_incremental_mac_destroy(SignalIncrementalMac *p); diff --git a/pkg/libsignalgo/version.go b/pkg/libsignalgo/version.go index a15914c..e7c4740 100644 --- a/pkg/libsignalgo/version.go +++ b/pkg/libsignalgo/version.go @@ -2,4 +2,4 @@ package libsignalgo -const Version = "v0.58.1" +const Version = "v0.58.3" From 08c491ad7dbd158ae3b7ebc739b11451609a833e Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Tue, 15 Oct 2024 17:10:57 +0300 Subject: [PATCH 211/580] dependencies: update --- go.mod | 20 ++++++++++---------- go.sum | 40 ++++++++++++++++++++-------------------- 2 files changed, 30 insertions(+), 30 deletions(-) diff --git a/go.mod b/go.mod index 283e984..61f382c 100644 --- a/go.mod +++ b/go.mod @@ -13,12 +13,12 @@ require ( github.com/rs/zerolog v1.33.0 github.com/stretchr/testify v1.9.0 github.com/tidwall/gjson v1.18.0 - go.mau.fi/util v0.8.1-0.20241003092848-3b49d3e0b9ee - golang.org/x/crypto v0.27.0 - golang.org/x/exp v0.0.0-20240909161429-701f63a606c0 - golang.org/x/net v0.29.0 - google.golang.org/protobuf v1.34.2 - maunium.net/go/mautrix v0.21.1-0.20241003093300-7e041c6e76a5 + go.mau.fi/util v0.8.1-0.20241015132414-c3f7e22b3de9 + golang.org/x/crypto v0.28.0 + golang.org/x/exp v0.0.0-20241009180824-f66d83c29e7c + golang.org/x/net v0.30.0 + google.golang.org/protobuf v1.35.1 + maunium.net/go/mautrix v0.21.1-0.20241015140451-df65202dacf0 ) require ( @@ -30,7 +30,7 @@ require ( github.com/lib/pq v1.10.9 // indirect github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-isatty v0.0.19 // indirect - github.com/mattn/go-sqlite3 v1.14.23 // indirect + github.com/mattn/go-sqlite3 v1.14.24 // indirect github.com/petermattis/goid v0.0.0-20240813172612-4fcff4a6cae7 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/rogpeppe/go-internal v1.10.0 // indirect @@ -39,11 +39,11 @@ require ( github.com/tidwall/match v1.1.1 // indirect github.com/tidwall/pretty v1.2.0 // indirect github.com/tidwall/sjson v1.2.5 // indirect - github.com/yuin/goldmark v1.7.4 // indirect + github.com/yuin/goldmark v1.7.7 // indirect go.mau.fi/zeroconfig v0.1.3 // indirect golang.org/x/sync v0.8.0 // indirect - golang.org/x/sys v0.25.0 // indirect - golang.org/x/text v0.18.0 // indirect + golang.org/x/sys v0.26.0 // indirect + golang.org/x/text v0.19.0 // indirect gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect gopkg.in/natefinch/lumberjack.v2 v2.2.1 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect diff --git a/go.sum b/go.sum index c8e86e0..5e88b13 100644 --- a/go.sum +++ b/go.sum @@ -36,8 +36,8 @@ github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APP github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mattn/go-pointer v0.0.1 h1:n+XhsuGeVO6MEAp7xyEukFINEa+Quek5psIR/ylA6o0= github.com/mattn/go-pointer v0.0.1/go.mod h1:2zXcozF6qYGgmsG+SeTZz3oAbFLdD3OWqnUbNvJZAlc= -github.com/mattn/go-sqlite3 v1.14.23 h1:gbShiuAP1W5j9UOksQ06aiiqPMxYecovVGwmTxWtuw0= -github.com/mattn/go-sqlite3 v1.14.23/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y= +github.com/mattn/go-sqlite3 v1.14.24 h1:tpSp2G2KyMnnQu99ngJ47EIkWVmliIizyZBfPrBWDRM= +github.com/mattn/go-sqlite3 v1.14.24/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y= github.com/petermattis/goid v0.0.0-20240813172612-4fcff4a6cae7 h1:Dx7Ovyv/SFnMFw3fD4oEoeorXc6saIiQ23LrGLth0Gw= github.com/petermattis/goid v0.0.0-20240813172612-4fcff4a6cae7/go.mod h1:pxMtw7cyUw6B2bRH0ZBANSPg+AoSud1I1iyJHI69jH4= github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= @@ -65,29 +65,29 @@ github.com/tidwall/pretty v1.2.0 h1:RWIZEg2iJ8/g6fDDYzMpobmaoGh5OLl4AXtGUGPcqCs= github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU= github.com/tidwall/sjson v1.2.5 h1:kLy8mja+1c9jlljvWTlSazM7cKDRfJuR/bOJhcY5NcY= github.com/tidwall/sjson v1.2.5/go.mod h1:Fvgq9kS/6ociJEDnK0Fk1cpYF4FIW6ZF7LAe+6jwd28= -github.com/yuin/goldmark v1.7.4 h1:BDXOHExt+A7gwPCJgPIIq7ENvceR7we7rOS9TNoLZeg= -github.com/yuin/goldmark v1.7.4/go.mod h1:uzxRWxtg69N339t3louHJ7+O03ezfj6PlliRlaOzY1E= -go.mau.fi/util v0.8.1-0.20241003092848-3b49d3e0b9ee h1:/BGpUK7fzVyFgy5KBiyP7ktEDn20vzz/5FTngrXtIEE= -go.mau.fi/util v0.8.1-0.20241003092848-3b49d3e0b9ee/go.mod h1:L9qnqEkhe4KpuYmILrdttKTXL79MwGLyJ4EOskWxO3I= +github.com/yuin/goldmark v1.7.7 h1:5m9rrB1sW3JUMToKFQfb+FGt1U7r57IHu5GrYrG2nqU= +github.com/yuin/goldmark v1.7.7/go.mod h1:uzxRWxtg69N339t3louHJ7+O03ezfj6PlliRlaOzY1E= +go.mau.fi/util v0.8.1-0.20241015132414-c3f7e22b3de9 h1:DnZ0keW636LpkkQKA1LQilYglEjNbxwXOnsJw0fuNIo= +go.mau.fi/util v0.8.1-0.20241015132414-c3f7e22b3de9/go.mod h1:T1u/rD2rzidVrBLyaUdPpZiJdP/rsyi+aTzn0D+Q6wc= go.mau.fi/zeroconfig v0.1.3 h1:As9wYDKmktjmNZW5i1vn8zvJlmGKHeVxHVIBMXsm4kM= go.mau.fi/zeroconfig v0.1.3/go.mod h1:NcSJkf180JT+1IId76PcMuLTNa1CzsFFZ0nBygIQM70= -golang.org/x/crypto v0.27.0 h1:GXm2NjJrPaiv/h1tb2UH8QfgC/hOf/+z0p6PT8o1w7A= -golang.org/x/crypto v0.27.0/go.mod h1:1Xngt8kV6Dvbssa53Ziq6Eqn0HqbZi5Z6R0ZpwQzt70= -golang.org/x/exp v0.0.0-20240909161429-701f63a606c0 h1:e66Fs6Z+fZTbFBAxKfP3PALWBtpfqks2bwGcexMxgtk= -golang.org/x/exp v0.0.0-20240909161429-701f63a606c0/go.mod h1:2TbTHSBQa924w8M6Xs1QcRcFwyucIwBGpK1p2f1YFFY= -golang.org/x/net v0.29.0 h1:5ORfpBpCs4HzDYoodCDBbwHzdR5UrLBZ3sOnUJmFoHo= -golang.org/x/net v0.29.0/go.mod h1:gLkgy8jTGERgjzMic6DS9+SP0ajcu6Xu3Orq/SpETg0= +golang.org/x/crypto v0.28.0 h1:GBDwsMXVQi34v5CCYUm2jkJvu4cbtru2U4TN2PSyQnw= +golang.org/x/crypto v0.28.0/go.mod h1:rmgy+3RHxRZMyY0jjAJShp2zgEdOqj2AO7U0pYmeQ7U= +golang.org/x/exp v0.0.0-20241009180824-f66d83c29e7c h1:7dEasQXItcW1xKJ2+gg5VOiBnqWrJc+rq0DPKyvvdbY= +golang.org/x/exp v0.0.0-20241009180824-f66d83c29e7c/go.mod h1:NQtJDoLvd6faHhE7m4T/1IY708gDefGGjR/iUW8yQQ8= +golang.org/x/net v0.30.0 h1:AcW1SDZMkb8IpzCdQUaIq2sP4sZ4zw+55h6ynffypl4= +golang.org/x/net v0.30.0/go.mod h1:2wGyMJ5iFasEhkwi13ChkO/t1ECNC4X4eBKkVFyYFlU= golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.25.0 h1:r+8e+loiHxRqhXVl6ML1nO3l1+oFoWbnlu2Ehimmi34= -golang.org/x/sys v0.25.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/text v0.18.0 h1:XvMDiNzPAl0jr17s6W9lcaIhGUfUORdGCNsuLmPG224= -golang.org/x/text v0.18.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= -google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= -google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= +golang.org/x/sys v0.26.0 h1:KHjCJyddX0LoSTb3J+vWpupP9p0oznkqVk/IfjymZbo= +golang.org/x/sys v0.26.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/text v0.19.0 h1:kTxAhCbGbxhK0IwgSKiMO5awPoDQ0RpfiVYBfK860YM= +golang.org/x/text v0.19.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= +google.golang.org/protobuf v1.35.1 h1:m3LfL6/Ca+fqnjnlqQXNpFPABW1UD7mjh8KO2mKFytA= +google.golang.org/protobuf v1.35.1/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= @@ -97,5 +97,5 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= maunium.net/go/mauflag v1.0.0 h1:YiaRc0tEI3toYtJMRIfjP+jklH45uDHtT80nUamyD4M= maunium.net/go/mauflag v1.0.0/go.mod h1:nLivPOpTpHnpzEh8jEdSL9UqO9+/KBJFmNRlwKfkPeA= -maunium.net/go/mautrix v0.21.1-0.20241003093300-7e041c6e76a5 h1:d5xUAixcJkxv9O3Ly/Ga2cU1Ez+WjS9gPIGD872wslw= -maunium.net/go/mautrix v0.21.1-0.20241003093300-7e041c6e76a5/go.mod h1:+fF5qsmXRCEXQZgW5ececC0PI3c7gISHTLcyftP4Bh0= +maunium.net/go/mautrix v0.21.1-0.20241015140451-df65202dacf0 h1:HJpNwgwsibEVVxLlLVkoPiHw6qA32jpGeSmPrRv8ArA= +maunium.net/go/mautrix v0.21.1-0.20241015140451-df65202dacf0/go.mod h1:biYqPccrQnnoVFoBe7JBHX6JDkFHGwGfKAem38LeXEs= From 3def5415eee866a8a2caaa0adad33dc3ff7f96b5 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Wed, 16 Oct 2024 10:17:55 +0300 Subject: [PATCH 212/580] changelog: update [skip ci] --- CHANGELOG.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3e780d7..9bd123c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,14 @@ +# v0.7.2 (unreleased) + +* Updated to libsignal v0.58.3. +* Fixed spurious decryption error notices for Signal messages when the + websocket reconnects and receives old already-bridged messages. +* Fixed signalmeow not respecting account settings for choosing sender + certificate. +* Fixed bugs in storage service decryption, which could cause issues with + missing contact names among other things. +* Fixed call start notices only working once per direct chat. + # v0.7.1 (2024-09-16) * Updated to libsignal v0.57.1. @@ -22,6 +33,8 @@ manually. * Thanks to [@maltee1] for reimplementing Matrix -> Signal membership handling in the rewrite. + * If you are still somehow using a pre-v0.5.0 versions, upgrading to v0.6.3 + is required before upgrading to v0.7.0 or higher. # v0.6.3 (2024-07-16) From 0feadb1474d6bfaf92c3cc57f080aa8167cad443 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Wed, 16 Oct 2024 13:53:36 +0300 Subject: [PATCH 213/580] Bump version to v0.7.2 --- CHANGELOG.md | 2 +- cmd/mautrix-signal/main.go | 2 +- go.mod | 4 ++-- go.sum | 8 ++++---- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9bd123c..743c281 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,4 @@ -# v0.7.2 (unreleased) +# v0.7.2 (2024-10-16) * Updated to libsignal v0.58.3. * Fixed spurious decryption error notices for Signal messages when the diff --git a/cmd/mautrix-signal/main.go b/cmd/mautrix-signal/main.go index 9bd9e23..51dc76e 100644 --- a/cmd/mautrix-signal/main.go +++ b/cmd/mautrix-signal/main.go @@ -38,7 +38,7 @@ var m = mxmain.BridgeMain{ Name: "mautrix-signal", URL: "https://github.com/mautrix/signal", Description: "A Matrix-Signal puppeting bridge.", - Version: "0.7.1", + Version: "0.7.2", Connector: &connector.SignalConnector{}, } diff --git a/go.mod b/go.mod index 61f382c..0760b6f 100644 --- a/go.mod +++ b/go.mod @@ -13,12 +13,12 @@ require ( github.com/rs/zerolog v1.33.0 github.com/stretchr/testify v1.9.0 github.com/tidwall/gjson v1.18.0 - go.mau.fi/util v0.8.1-0.20241015132414-c3f7e22b3de9 + go.mau.fi/util v0.8.1 golang.org/x/crypto v0.28.0 golang.org/x/exp v0.0.0-20241009180824-f66d83c29e7c golang.org/x/net v0.30.0 google.golang.org/protobuf v1.35.1 - maunium.net/go/mautrix v0.21.1-0.20241015140451-df65202dacf0 + maunium.net/go/mautrix v0.21.1 ) require ( diff --git a/go.sum b/go.sum index 5e88b13..05f90ef 100644 --- a/go.sum +++ b/go.sum @@ -67,8 +67,8 @@ github.com/tidwall/sjson v1.2.5 h1:kLy8mja+1c9jlljvWTlSazM7cKDRfJuR/bOJhcY5NcY= github.com/tidwall/sjson v1.2.5/go.mod h1:Fvgq9kS/6ociJEDnK0Fk1cpYF4FIW6ZF7LAe+6jwd28= github.com/yuin/goldmark v1.7.7 h1:5m9rrB1sW3JUMToKFQfb+FGt1U7r57IHu5GrYrG2nqU= github.com/yuin/goldmark v1.7.7/go.mod h1:uzxRWxtg69N339t3louHJ7+O03ezfj6PlliRlaOzY1E= -go.mau.fi/util v0.8.1-0.20241015132414-c3f7e22b3de9 h1:DnZ0keW636LpkkQKA1LQilYglEjNbxwXOnsJw0fuNIo= -go.mau.fi/util v0.8.1-0.20241015132414-c3f7e22b3de9/go.mod h1:T1u/rD2rzidVrBLyaUdPpZiJdP/rsyi+aTzn0D+Q6wc= +go.mau.fi/util v0.8.1 h1:Ga43cz6esQBYqcjZ/onRoVnYWoUwjWbsxVeJg2jOTSo= +go.mau.fi/util v0.8.1/go.mod h1:T1u/rD2rzidVrBLyaUdPpZiJdP/rsyi+aTzn0D+Q6wc= go.mau.fi/zeroconfig v0.1.3 h1:As9wYDKmktjmNZW5i1vn8zvJlmGKHeVxHVIBMXsm4kM= go.mau.fi/zeroconfig v0.1.3/go.mod h1:NcSJkf180JT+1IId76PcMuLTNa1CzsFFZ0nBygIQM70= golang.org/x/crypto v0.28.0 h1:GBDwsMXVQi34v5CCYUm2jkJvu4cbtru2U4TN2PSyQnw= @@ -97,5 +97,5 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= maunium.net/go/mauflag v1.0.0 h1:YiaRc0tEI3toYtJMRIfjP+jklH45uDHtT80nUamyD4M= maunium.net/go/mauflag v1.0.0/go.mod h1:nLivPOpTpHnpzEh8jEdSL9UqO9+/KBJFmNRlwKfkPeA= -maunium.net/go/mautrix v0.21.1-0.20241015140451-df65202dacf0 h1:HJpNwgwsibEVVxLlLVkoPiHw6qA32jpGeSmPrRv8ArA= -maunium.net/go/mautrix v0.21.1-0.20241015140451-df65202dacf0/go.mod h1:biYqPccrQnnoVFoBe7JBHX6JDkFHGwGfKAem38LeXEs= +maunium.net/go/mautrix v0.21.1 h1:Z+e448jtlY977iC1kokNJTH5kg2WmDpcQCqn+v9oZOA= +maunium.net/go/mautrix v0.21.1/go.mod h1:7F/S6XAdyc/6DW+Q7xyFXRSPb6IjfqMb1OMepQ8C8OE= From b09995a892c9930628e1669532d9c1283a4938c8 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Thu, 17 Oct 2024 22:33:11 +0300 Subject: [PATCH 214/580] signalmeow/attachments: update upload path --- pkg/signalmeow/attachments.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/signalmeow/attachments.go b/pkg/signalmeow/attachments.go index c0859b7..8cd796e 100644 --- a/pkg/signalmeow/attachments.go +++ b/pkg/signalmeow/attachments.go @@ -149,7 +149,7 @@ func (cli *Client) UploadAttachment(ctx context.Context, body []byte) (*signalpb encryptedWithMAC := appendMAC(keys[32:], encrypted) // Get upload attributes from Signal server - attributesPath := "/v3/attachments/form/upload" + attributesPath := "/v4/attachments/form/upload" username, password := cli.Store.BasicAuthCreds() opts := &web.HTTPReqOpt{Username: &username, Password: &password} resp, err := web.SendHTTPRequest(ctx, http.MethodGet, attributesPath, opts) From 96221b6fb41ad4d19b13681bdabbd06638845a24 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Thu, 17 Oct 2024 22:33:21 +0300 Subject: [PATCH 215/580] ci: update pre-commit action version --- .github/workflows/go.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml index 76b76a1..c2496f6 100644 --- a/.github/workflows/go.yml +++ b/.github/workflows/go.yml @@ -33,7 +33,7 @@ jobs: export PATH="$HOME/go/bin:$PATH" - name: Run pre-commit - uses: pre-commit/action@v3.0.0 + uses: pre-commit/action@v3.0.1 test: runs-on: ubuntu-latest From 58dacbd6ac291a961d9b47913030335f10f048c8 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Fri, 18 Oct 2024 14:55:31 +0300 Subject: [PATCH 216/580] signalmeow/attachments: add basic support for TUS uploads --- pkg/signalmeow/attachments.go | 117 +++++++++++++++++++++++----------- pkg/signalmeow/web/web.go | 7 +- 2 files changed, 84 insertions(+), 40 deletions(-) diff --git a/pkg/signalmeow/attachments.go b/pkg/signalmeow/attachments.go index 8cd796e..e8ffe0b 100644 --- a/pkg/signalmeow/attachments.go +++ b/pkg/signalmeow/attachments.go @@ -23,6 +23,7 @@ import ( "crypto/cipher" "crypto/hmac" "crypto/sha256" + "encoding/base64" "encoding/json" "errors" "fmt" @@ -105,7 +106,7 @@ func decryptAttachment(body, key, digest []byte, size uint32) ([]byte, error) { return decrypted[:size], nil } -type attachmentV3UploadAttributes struct { +type attachmentV4UploadAttributes struct { Cdn uint32 `json:"cdn"` Key string `json:"key"` Headers map[string]string `json:"headers"` @@ -154,49 +155,26 @@ func (cli *Client) UploadAttachment(ctx context.Context, body []byte) (*signalpb opts := &web.HTTPReqOpt{Username: &username, Password: &password} resp, err := web.SendHTTPRequest(ctx, http.MethodGet, attributesPath, opts) if err != nil { - log.Err(err).Msg("Error sending request fetching upload attributes") - return nil, err + log.Err(err).Msg("Failed to request upload attributes") + return nil, fmt.Errorf("failed to request upload attributes: %w", err) } - var uploadAttributes attachmentV3UploadAttributes + var uploadAttributes attachmentV4UploadAttributes err = web.DecodeHTTPResponseBody(ctx, &uploadAttributes, resp) if err != nil { - log.Err(err).Msg("Error decoding response body fetching upload attributes") - return nil, err + log.Err(err).Msg("Failed to decode upload attributes") + return nil, fmt.Errorf("failed to decode upload attributes: %w", err) + } + if uploadAttributes.Cdn == 3 { + log.Trace().Msg("Using TUS upload") + err = cli.uploadAttachmentTUS(ctx, uploadAttributes, encryptedWithMAC, username, password) + } else { + log.Trace().Msg("Using legacy upload") + err = cli.uploadAttachmentLegacy(ctx, uploadAttributes, encryptedWithMAC, username, password) } - - // Allocate attachment on CDN - resp, err = web.SendHTTPRequest(ctx, http.MethodPost, "", &web.HTTPReqOpt{ - OverrideURL: uploadAttributes.SignedUploadLocation, - ContentType: web.ContentTypeOctetStream, - Headers: uploadAttributes.Headers, - Username: &username, - Password: &password, - }) if err != nil { - log.Err(err).Msg("Error sending request allocating attachment") + log.Err(err).Msg("Failed to upload attachment") return nil, err } - if resp.StatusCode < 200 || resp.StatusCode >= 300 { - log.Error().Int("status_code", resp.StatusCode).Msg("Error allocating attachment") - return nil, fmt.Errorf("error allocating attachment: %s", resp.Status) - } - - // Upload attachment to CDN - resp, err = web.SendHTTPRequest(ctx, http.MethodPut, "", &web.HTTPReqOpt{ - OverrideURL: resp.Header.Get("Location"), - Body: encryptedWithMAC, - ContentType: web.ContentTypeOctetStream, - Username: &username, - Password: &password, - }) - if err != nil { - log.Err(err).Msg("Error sending request uploading attachment") - return nil, err - } - if resp.StatusCode < 200 || resp.StatusCode >= 300 { - log.Error().Int("status_code", resp.StatusCode).Msg("Error uploading attachment") - return nil, fmt.Errorf("error uploading attachment: %s", resp.Status) - } digest := sha256.Sum256(encryptedWithMAC) @@ -213,6 +191,71 @@ func (cli *Client) UploadAttachment(ctx context.Context, body []byte) (*signalpb return attachmentPointer, nil } +func (cli *Client) uploadAttachmentLegacy( + ctx context.Context, + uploadAttributes attachmentV4UploadAttributes, + encryptedWithMAC []byte, + username string, + password string, +) error { + // Allocate attachment on CDN + resp, err := web.SendHTTPRequest(ctx, http.MethodPost, "", &web.HTTPReqOpt{ + OverrideURL: uploadAttributes.SignedUploadLocation, + ContentType: web.ContentTypeOctetStream, + Headers: uploadAttributes.Headers, + Username: &username, + Password: &password, + }) + if err != nil { + return fmt.Errorf("failed to send allocate request: %w", err) + } else if resp.StatusCode < 200 || resp.StatusCode >= 300 { + return fmt.Errorf("allocate request returned HTTP %d", resp.StatusCode) + } + + // Upload attachment to CDN + resp, err = web.SendHTTPRequest(ctx, http.MethodPut, "", &web.HTTPReqOpt{ + OverrideURL: resp.Header.Get("Location"), + Body: encryptedWithMAC, + ContentType: web.ContentTypeOctetStream, + Username: &username, + Password: &password, + }) + if err != nil { + return fmt.Errorf("failed to send upload request: %w", err) + } else if resp.StatusCode < 200 || resp.StatusCode >= 300 { + return fmt.Errorf("upload request returned HTTP %d", resp.StatusCode) + } + return nil +} + +func (cli *Client) uploadAttachmentTUS( + ctx context.Context, + uploadAttributes attachmentV4UploadAttributes, + encryptedWithMAC []byte, + username string, + password string, +) error { + uploadAttributes.Headers["Tus-Resumable"] = "1.0.0" + uploadAttributes.Headers["Upload-Length"] = fmt.Sprintf("%d", len(encryptedWithMAC)) + uploadAttributes.Headers["Upload-Metadata"] = "filename " + base64.StdEncoding.EncodeToString([]byte(uploadAttributes.Key)) + + resp, err := web.SendHTTPRequest(ctx, http.MethodPost, "", &web.HTTPReqOpt{ + OverrideURL: uploadAttributes.SignedUploadLocation, + Body: encryptedWithMAC, + ContentType: web.ContentTypeOffsetOctetStream, + Headers: uploadAttributes.Headers, + Username: &username, + Password: &password, + }) + // TODO actually support resuming on error + if err != nil { + return fmt.Errorf("failed to send upload request: %w", err) + } else if resp.StatusCode < 200 || resp.StatusCode >= 300 { + return fmt.Errorf("upload request returned HTTP %d", resp.StatusCode) + } + return nil +} + func (cli *Client) UploadGroupAvatar(ctx context.Context, avatarBytes []byte, gid types.GroupIdentifier) (*string, error) { log := zerolog.Ctx(ctx) groupMasterKey, err := cli.Store.GroupStore.MasterKeyFromGroupIdentifier(ctx, gid) diff --git a/pkg/signalmeow/web/web.go b/pkg/signalmeow/web/web.go index 1119128..3644451 100644 --- a/pkg/signalmeow/web/web.go +++ b/pkg/signalmeow/web/web.go @@ -95,9 +95,10 @@ func init() { type ContentType string const ( - ContentTypeJSON ContentType = "application/json" - ContentTypeProtobuf ContentType = "application/x-protobuf" - ContentTypeOctetStream ContentType = "application/octet-stream" + ContentTypeJSON ContentType = "application/json" + ContentTypeProtobuf ContentType = "application/x-protobuf" + ContentTypeOctetStream ContentType = "application/octet-stream" + ContentTypeOffsetOctetStream ContentType = "application/offset+octet-stream" ) type HTTPReqOpt struct { From ad41c86f116f484a57b7df07bc082f33fc12d908 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Sat, 19 Oct 2024 23:29:34 +0300 Subject: [PATCH 217/580] signalmeow/receiving: handle missing era ID in group call updates --- pkg/signalmeow/receiving.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/signalmeow/receiving.go b/pkg/signalmeow/receiving.go index 1961709..38a4e00 100644 --- a/pkg/signalmeow/receiving.go +++ b/pkg/signalmeow/receiving.go @@ -1025,7 +1025,7 @@ func (cli *Client) incomingDataMessage(ctx context.Context, dataMessage *signalp } // Hacky special case for group calls to cache the state if dataMessage.GroupCallUpdate != nil { - isRinging := cli.UpdateActiveCalls(groupID, *dataMessage.GroupCallUpdate.EraId) + isRinging := cli.UpdateActiveCalls(groupID, dataMessage.GroupCallUpdate.GetEraId()) cli.handleEvent(&events.Call{ Info: evtInfo, Timestamp: dataMessage.GetTimestamp(), From 1af3acb1302eb05b017ec643e1d77d1da73f029e Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Wed, 13 Nov 2024 15:46:55 +0200 Subject: [PATCH 218/580] signalmeow: update protobufs --- pkg/signalmeow/protobuf/Provisioning.pb.go | 26 +++++++++++++++++++- pkg/signalmeow/protobuf/Provisioning.pb.raw | Bin 804 -> 948 bytes pkg/signalmeow/protobuf/Provisioning.proto | 5 +++- pkg/signalmeow/protobuf/update-protos.sh | 4 +-- 4 files changed, 31 insertions(+), 4 deletions(-) diff --git a/pkg/signalmeow/protobuf/Provisioning.pb.go b/pkg/signalmeow/protobuf/Provisioning.pb.go index 7a866f3..e7b7585 100644 --- a/pkg/signalmeow/protobuf/Provisioning.pb.go +++ b/pkg/signalmeow/protobuf/Provisioning.pb.go @@ -201,7 +201,10 @@ type ProvisionMessage struct { ProfileKey []byte `protobuf:"bytes,6,opt,name=profileKey" json:"profileKey,omitempty"` ReadReceipts *bool `protobuf:"varint,7,opt,name=readReceipts" json:"readReceipts,omitempty"` ProvisioningVersion *uint32 `protobuf:"varint,9,opt,name=provisioningVersion" json:"provisioningVersion,omitempty"` - MasterKey []byte `protobuf:"bytes,13,opt,name=masterKey" json:"masterKey,omitempty"` // NEXT ID: 14 + MasterKey []byte `protobuf:"bytes,13,opt,name=masterKey" json:"masterKey,omitempty"` + EphemeralBackupKey []byte `protobuf:"bytes,14,opt,name=ephemeralBackupKey" json:"ephemeralBackupKey,omitempty"` // 32 bytes + AccountEntropyPool *string `protobuf:"bytes,15,opt,name=accountEntropyPool" json:"accountEntropyPool,omitempty"` + MediaRootBackupKey []byte `protobuf:"bytes,16,opt,name=mediaRootBackupKey" json:"mediaRootBackupKey,omitempty"` // 32-bytes } func (x *ProvisionMessage) Reset() { @@ -325,6 +328,27 @@ func (x *ProvisionMessage) GetMasterKey() []byte { return nil } +func (x *ProvisionMessage) GetEphemeralBackupKey() []byte { + if x != nil { + return x.EphemeralBackupKey + } + return nil +} + +func (x *ProvisionMessage) GetAccountEntropyPool() string { + if x != nil && x.AccountEntropyPool != nil { + return *x.AccountEntropyPool + } + return "" +} + +func (x *ProvisionMessage) GetMediaRootBackupKey() []byte { + if x != nil { + return x.MediaRootBackupKey + } + return nil +} + var File_Provisioning_proto protoreflect.FileDescriptor //go:embed Provisioning.pb.raw diff --git a/pkg/signalmeow/protobuf/Provisioning.pb.raw b/pkg/signalmeow/protobuf/Provisioning.pb.raw index 2ffce6fe9f767e9912d00644eafb26c9f454953e..385bc0221e1cce3935b116e6241b0b4d697c8df3 100644 GIT binary patch delta 159 zcmZ3&wuODdWTpwM3#T&G3+ZtQr50qQ=B5@U<~SuLXO|Xur&dbvDKKjA1YwZ@sZUH! z&M(a?am_0!$}gx4$j{G_;0LPb48kG Date: Wed, 13 Nov 2024 16:36:24 +0200 Subject: [PATCH 219/580] dependencies: update --- go.mod | 24 ++++++++++++------------ go.sum | 44 ++++++++++++++++++++++---------------------- 2 files changed, 34 insertions(+), 34 deletions(-) diff --git a/go.mod b/go.mod index 0760b6f..4e31e51 100644 --- a/go.mod +++ b/go.mod @@ -2,23 +2,23 @@ module go.mau.fi/mautrix-signal go 1.22.0 -toolchain go1.23.2 +toolchain go1.23.3 require ( github.com/coder/websocket v1.8.12 - github.com/emersion/go-vcard v0.0.0-20230815062825-8fda7d206ec9 + github.com/emersion/go-vcard v0.0.0-20241024213814-c9703dde27ff github.com/google/uuid v1.6.0 github.com/gorilla/mux v1.8.0 github.com/mattn/go-pointer v0.0.1 github.com/rs/zerolog v1.33.0 github.com/stretchr/testify v1.9.0 github.com/tidwall/gjson v1.18.0 - go.mau.fi/util v0.8.1 - golang.org/x/crypto v0.28.0 - golang.org/x/exp v0.0.0-20241009180824-f66d83c29e7c - golang.org/x/net v0.30.0 + go.mau.fi/util v0.8.2-0.20241113135441-636f8643f367 + golang.org/x/crypto v0.29.0 + golang.org/x/exp v0.0.0-20241108190413-2d47ceb2692f + golang.org/x/net v0.31.0 google.golang.org/protobuf v1.35.1 - maunium.net/go/mautrix v0.21.1 + maunium.net/go/mautrix v0.21.2-0.20241113135638-b22764aa170a ) require ( @@ -31,7 +31,7 @@ require ( github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-isatty v0.0.19 // indirect github.com/mattn/go-sqlite3 v1.14.24 // indirect - github.com/petermattis/goid v0.0.0-20240813172612-4fcff4a6cae7 // indirect + github.com/petermattis/goid v0.0.0-20241025130422-66cb2e6d7274 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/rogpeppe/go-internal v1.10.0 // indirect github.com/rs/xid v1.6.0 // indirect @@ -39,11 +39,11 @@ require ( github.com/tidwall/match v1.1.1 // indirect github.com/tidwall/pretty v1.2.0 // indirect github.com/tidwall/sjson v1.2.5 // indirect - github.com/yuin/goldmark v1.7.7 // indirect + github.com/yuin/goldmark v1.7.8 // indirect go.mau.fi/zeroconfig v0.1.3 // indirect - golang.org/x/sync v0.8.0 // indirect - golang.org/x/sys v0.26.0 // indirect - golang.org/x/text v0.19.0 // indirect + golang.org/x/sync v0.9.0 // indirect + golang.org/x/sys v0.27.0 // indirect + golang.org/x/text v0.20.0 // indirect gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect gopkg.in/natefinch/lumberjack.v2 v2.2.1 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect diff --git a/go.sum b/go.sum index 05f90ef..590bd3d 100644 --- a/go.sum +++ b/go.sum @@ -9,8 +9,8 @@ github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSV github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/emersion/go-vcard v0.0.0-20230815062825-8fda7d206ec9 h1:ATgqloALX6cHCranzkLb8/zjivwQ9DWWDCQRnxTPfaA= -github.com/emersion/go-vcard v0.0.0-20230815062825-8fda7d206ec9/go.mod h1:HMJKR5wlh/ziNp+sHEDV2ltblO4JD2+IdDOWtGcQBTM= +github.com/emersion/go-vcard v0.0.0-20241024213814-c9703dde27ff h1:4N8wnS3f1hNHSmFD5zgFkWCyA4L1kCDkImPAtK7D6tg= +github.com/emersion/go-vcard v0.0.0-20241024213814-c9703dde27ff/go.mod h1:HMJKR5wlh/ziNp+sHEDV2ltblO4JD2+IdDOWtGcQBTM= github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= @@ -38,8 +38,8 @@ github.com/mattn/go-pointer v0.0.1 h1:n+XhsuGeVO6MEAp7xyEukFINEa+Quek5psIR/ylA6o github.com/mattn/go-pointer v0.0.1/go.mod h1:2zXcozF6qYGgmsG+SeTZz3oAbFLdD3OWqnUbNvJZAlc= github.com/mattn/go-sqlite3 v1.14.24 h1:tpSp2G2KyMnnQu99ngJ47EIkWVmliIizyZBfPrBWDRM= github.com/mattn/go-sqlite3 v1.14.24/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y= -github.com/petermattis/goid v0.0.0-20240813172612-4fcff4a6cae7 h1:Dx7Ovyv/SFnMFw3fD4oEoeorXc6saIiQ23LrGLth0Gw= -github.com/petermattis/goid v0.0.0-20240813172612-4fcff4a6cae7/go.mod h1:pxMtw7cyUw6B2bRH0ZBANSPg+AoSud1I1iyJHI69jH4= +github.com/petermattis/goid v0.0.0-20241025130422-66cb2e6d7274 h1:qli3BGQK0tYDkSEvZ/FzZTi9ZrOX86Q6CIhKLGc489A= +github.com/petermattis/goid v0.0.0-20241025130422-66cb2e6d7274/go.mod h1:pxMtw7cyUw6B2bRH0ZBANSPg+AoSud1I1iyJHI69jH4= github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= @@ -65,27 +65,27 @@ github.com/tidwall/pretty v1.2.0 h1:RWIZEg2iJ8/g6fDDYzMpobmaoGh5OLl4AXtGUGPcqCs= github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU= github.com/tidwall/sjson v1.2.5 h1:kLy8mja+1c9jlljvWTlSazM7cKDRfJuR/bOJhcY5NcY= github.com/tidwall/sjson v1.2.5/go.mod h1:Fvgq9kS/6ociJEDnK0Fk1cpYF4FIW6ZF7LAe+6jwd28= -github.com/yuin/goldmark v1.7.7 h1:5m9rrB1sW3JUMToKFQfb+FGt1U7r57IHu5GrYrG2nqU= -github.com/yuin/goldmark v1.7.7/go.mod h1:uzxRWxtg69N339t3louHJ7+O03ezfj6PlliRlaOzY1E= -go.mau.fi/util v0.8.1 h1:Ga43cz6esQBYqcjZ/onRoVnYWoUwjWbsxVeJg2jOTSo= -go.mau.fi/util v0.8.1/go.mod h1:T1u/rD2rzidVrBLyaUdPpZiJdP/rsyi+aTzn0D+Q6wc= +github.com/yuin/goldmark v1.7.8 h1:iERMLn0/QJeHFhxSt3p6PeN9mGnvIKSpG9YYorDMnic= +github.com/yuin/goldmark v1.7.8/go.mod h1:uzxRWxtg69N339t3louHJ7+O03ezfj6PlliRlaOzY1E= +go.mau.fi/util v0.8.2-0.20241113135441-636f8643f367 h1:GU0TYiAOU79p6r3jf3e4k5cdgnPxOcJWkWeWampdAjw= +go.mau.fi/util v0.8.2-0.20241113135441-636f8643f367/go.mod h1:SVzC++wSl8Yq4YVQRClLPa1frNpSVDVP6mfkw/OvDbc= go.mau.fi/zeroconfig v0.1.3 h1:As9wYDKmktjmNZW5i1vn8zvJlmGKHeVxHVIBMXsm4kM= go.mau.fi/zeroconfig v0.1.3/go.mod h1:NcSJkf180JT+1IId76PcMuLTNa1CzsFFZ0nBygIQM70= -golang.org/x/crypto v0.28.0 h1:GBDwsMXVQi34v5CCYUm2jkJvu4cbtru2U4TN2PSyQnw= -golang.org/x/crypto v0.28.0/go.mod h1:rmgy+3RHxRZMyY0jjAJShp2zgEdOqj2AO7U0pYmeQ7U= -golang.org/x/exp v0.0.0-20241009180824-f66d83c29e7c h1:7dEasQXItcW1xKJ2+gg5VOiBnqWrJc+rq0DPKyvvdbY= -golang.org/x/exp v0.0.0-20241009180824-f66d83c29e7c/go.mod h1:NQtJDoLvd6faHhE7m4T/1IY708gDefGGjR/iUW8yQQ8= -golang.org/x/net v0.30.0 h1:AcW1SDZMkb8IpzCdQUaIq2sP4sZ4zw+55h6ynffypl4= -golang.org/x/net v0.30.0/go.mod h1:2wGyMJ5iFasEhkwi13ChkO/t1ECNC4X4eBKkVFyYFlU= -golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= -golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/crypto v0.29.0 h1:L5SG1JTTXupVV3n6sUqMTeWbjAyfPwoda2DLX8J8FrQ= +golang.org/x/crypto v0.29.0/go.mod h1:+F4F4N5hv6v38hfeYwTdx20oUvLLc+QfrE9Ax9HtgRg= +golang.org/x/exp v0.0.0-20241108190413-2d47ceb2692f h1:XdNn9LlyWAhLVp6P/i8QYBW+hlyhrhei9uErw2B5GJo= +golang.org/x/exp v0.0.0-20241108190413-2d47ceb2692f/go.mod h1:D5SMRVC3C2/4+F/DB1wZsLRnSNimn2Sp/NPsCrsv8ak= +golang.org/x/net v0.31.0 h1:68CPQngjLL0r2AlUKiSxtQFKvzRVbnzLwMUn5SzcLHo= +golang.org/x/net v0.31.0/go.mod h1:P4fl1q7dY2hnZFxEk4pPSkDHF+QqjitcnDjUQyMM+pM= +golang.org/x/sync v0.9.0 h1:fEo0HyrW1GIgZdpbhCRO0PkJajUS5H9IFUztCgEo2jQ= +golang.org/x/sync v0.9.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.26.0 h1:KHjCJyddX0LoSTb3J+vWpupP9p0oznkqVk/IfjymZbo= -golang.org/x/sys v0.26.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/text v0.19.0 h1:kTxAhCbGbxhK0IwgSKiMO5awPoDQ0RpfiVYBfK860YM= -golang.org/x/text v0.19.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= +golang.org/x/sys v0.27.0 h1:wBqf8DvsY9Y/2P8gAfPDEYNuS30J4lPHJxXSb/nJZ+s= +golang.org/x/sys v0.27.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/text v0.20.0 h1:gK/Kv2otX8gz+wn7Rmb3vT96ZwuoxnQlY+HlJVj7Qug= +golang.org/x/text v0.20.0/go.mod h1:D4IsuqiFMhST5bX19pQ9ikHC2GsaKyk/oF+pn3ducp4= google.golang.org/protobuf v1.35.1 h1:m3LfL6/Ca+fqnjnlqQXNpFPABW1UD7mjh8KO2mKFytA= google.golang.org/protobuf v1.35.1/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= @@ -97,5 +97,5 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= maunium.net/go/mauflag v1.0.0 h1:YiaRc0tEI3toYtJMRIfjP+jklH45uDHtT80nUamyD4M= maunium.net/go/mauflag v1.0.0/go.mod h1:nLivPOpTpHnpzEh8jEdSL9UqO9+/KBJFmNRlwKfkPeA= -maunium.net/go/mautrix v0.21.1 h1:Z+e448jtlY977iC1kokNJTH5kg2WmDpcQCqn+v9oZOA= -maunium.net/go/mautrix v0.21.1/go.mod h1:7F/S6XAdyc/6DW+Q7xyFXRSPb6IjfqMb1OMepQ8C8OE= +maunium.net/go/mautrix v0.21.2-0.20241113135638-b22764aa170a h1:+hOkf85qhGRoAPpoCk7AiqKxlNvCCizb6urJVmgk0+8= +maunium.net/go/mautrix v0.21.2-0.20241113135638-b22764aa170a/go.mod h1:X7VB/wOIUo6c3wACyVwA//v2k8BpMLFB2rvaX2Y0984= From d011d23c1c3cdcd75dae86c7e879590ce114e3a7 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Wed, 13 Nov 2024 16:36:53 +0200 Subject: [PATCH 220/580] libsignal: update to v0.61.0 --- pkg/libsignalgo/libsignal | 2 +- pkg/libsignalgo/libsignal-ffi.h | 48 ++++++++++++++++++++++++++++++--- pkg/libsignalgo/version.go | 2 +- 3 files changed, 46 insertions(+), 6 deletions(-) diff --git a/pkg/libsignalgo/libsignal b/pkg/libsignalgo/libsignal index 29d3270..0a06f69 160000 --- a/pkg/libsignalgo/libsignal +++ b/pkg/libsignalgo/libsignal @@ -1 +1 @@ -Subproject commit 29d32702b5cb0dc302ca2fa08377cddaaaacb60c +Subproject commit 0a06f69bce222c184a8d4022b8cf4202b02b9001 diff --git a/pkg/libsignalgo/libsignal-ffi.h b/pkg/libsignalgo/libsignal-ffi.h index 5b13971..627dfd6 100644 --- a/pkg/libsignalgo/libsignal-ffi.h +++ b/pkg/libsignalgo/libsignal-ffi.h @@ -15,6 +15,20 @@ SPDX-License-Identifier: AGPL-3.0-only #include #include +#define SignalSVR_KEY_LEN 32 + +#define SignalBACKUP_KEY_LEN 32 + +#define SignalLOCAL_BACKUP_METADATA_KEY_LEN 32 + +#define SignalMEDIA_ID_LEN 15 + +#define SignalMEDIA_ENCRYPTION_KEY_LEN (32 + 32) + +#define SignalBackupKey_MASTER_KEY_LEN SignalSVR_KEY_LEN + +#define SignalBackupId_LEN 16 + /** * The encoded length of a [`FourCC`], in bytes. */ @@ -1399,7 +1413,7 @@ SignalFfiError *signal_backup_auth_credential_request_context_get_request(Signal SignalFfiError *signal_backup_auth_credential_request_check_valid_contents(SignalBorrowedBuffer request_bytes); -SignalFfiError *signal_backup_auth_credential_request_issue_deterministic(SignalOwnedBuffer *out, SignalBorrowedBuffer request_bytes, uint64_t redemption_time, uint8_t backup_level, SignalBorrowedBuffer params_bytes, const uint8_t (*randomness)[SignalRANDOMNESS_LEN]); +SignalFfiError *signal_backup_auth_credential_request_issue_deterministic(SignalOwnedBuffer *out, SignalBorrowedBuffer request_bytes, uint64_t redemption_time, uint8_t backup_level, uint8_t credential_type, SignalBorrowedBuffer params_bytes, const uint8_t (*randomness)[SignalRANDOMNESS_LEN]); SignalFfiError *signal_backup_auth_credential_response_check_valid_contents(SignalBorrowedBuffer response_bytes); @@ -1411,6 +1425,8 @@ SignalFfiError *signal_backup_auth_credential_get_backup_id(uint8_t (*out)[16], SignalFfiError *signal_backup_auth_credential_get_backup_level(uint8_t *out, SignalBorrowedBuffer credential_bytes); +SignalFfiError *signal_backup_auth_credential_get_type(uint8_t *out, SignalBorrowedBuffer credential_bytes); + SignalFfiError *signal_backup_auth_credential_present_deterministic(SignalOwnedBuffer *out, SignalBorrowedBuffer credential_bytes, SignalBorrowedBuffer server_params_bytes, const uint8_t (*randomness)[SignalRANDOMNESS_LEN]); SignalFfiError *signal_backup_auth_credential_presentation_check_valid_contents(SignalBorrowedBuffer presentation_bytes); @@ -1449,8 +1465,6 @@ SignalFfiError *signal_group_send_full_token_get_expiration(uint64_t *out, Signa SignalFfiError *signal_group_send_full_token_verify(SignalBorrowedBuffer token, SignalBorrowedBuffer user_ids, uint64_t now, SignalBorrowedBuffer key_pair); -SignalFfiError *signal_verify_signature(bool *out, SignalBorrowedBuffer cert_pem, SignalBorrowedBuffer body, SignalBorrowedBuffer signature, uint64_t current_timestamp); - SignalFfiError *signal_connection_manager_destroy(SignalConnectionManager *p); SignalFfiError *signal_connection_manager_new(SignalConnectionManager **out, uint8_t environment, const char *user_agent); @@ -1459,6 +1473,8 @@ SignalFfiError *signal_connection_manager_set_proxy(const SignalConnectionManage SignalFfiError *signal_connection_manager_clear_proxy(const SignalConnectionManager *connection_manager); +SignalFfiError *signal_connection_manager_set_censorship_circumvention_enabled(const SignalConnectionManager *connection_manager, bool enabled); + SignalFfiError *signal_connection_manager_on_network_change(const SignalConnectionManager *connection_manager); SignalFfiError *signal_create_otp(const char **out, const char *username, SignalBorrowedBuffer secret); @@ -1561,6 +1577,22 @@ SignalFfiError *signal_pin_verify_local_hash(bool *out, const char *encoded_hash SignalFfiError *signal_account_entropy_pool_generate(const char **out); +SignalFfiError *signal_account_entropy_pool_derive_svr_key(uint8_t (*out)[SignalSVR_KEY_LEN], const char *account_entropy); + +SignalFfiError *signal_account_entropy_pool_derive_backup_key(uint8_t (*out)[SignalBACKUP_KEY_LEN], const char *account_entropy); + +SignalFfiError *signal_backup_key_derive_backup_id(uint8_t (*out)[16], const uint8_t (*backup_key)[SignalBACKUP_KEY_LEN], const SignalServiceIdFixedWidthBinaryBytes *aci); + +SignalFfiError *signal_backup_key_derive_ec_key(SignalPrivateKey **out, const uint8_t (*backup_key)[SignalBACKUP_KEY_LEN], const SignalServiceIdFixedWidthBinaryBytes *aci); + +SignalFfiError *signal_backup_key_derive_local_backup_metadata_key(uint8_t (*out)[SignalLOCAL_BACKUP_METADATA_KEY_LEN], const uint8_t (*backup_key)[SignalBACKUP_KEY_LEN]); + +SignalFfiError *signal_backup_key_derive_media_id(uint8_t (*out)[SignalMEDIA_ID_LEN], const uint8_t (*backup_key)[SignalBACKUP_KEY_LEN], const char *media_name); + +SignalFfiError *signal_backup_key_derive_media_encryption_key(uint8_t (*out)[SignalMEDIA_ENCRYPTION_KEY_LEN], const uint8_t (*backup_key)[SignalBACKUP_KEY_LEN], const uint8_t (*media_id)[SignalMEDIA_ID_LEN]); + +SignalFfiError *signal_backup_key_derive_thumbnail_transit_encryption_key(uint8_t (*out)[SignalMEDIA_ENCRYPTION_KEY_LEN], const uint8_t (*backup_key)[SignalBACKUP_KEY_LEN], const uint8_t (*media_id)[SignalMEDIA_ID_LEN]); + SignalFfiError *signal_svr2_client_new(SignalSgxClientState **out, SignalBorrowedBuffer mrenclave, SignalBorrowedBuffer attestation_msg, uint64_t current_timestamp); SignalFfiError *signal_incremental_mac_destroy(SignalIncrementalMac *p); @@ -1585,7 +1617,15 @@ SignalFfiError *signal_message_backup_key_destroy(SignalMessageBackupKey *p); SignalFfiError *signal_message_backup_validation_outcome_destroy(SignalMessageBackupValidationOutcome *p); -SignalFfiError *signal_message_backup_key_new(SignalMessageBackupKey **out, const uint8_t (*master_key)[32], const SignalServiceIdFixedWidthBinaryBytes *aci); +SignalFfiError *signal_message_backup_key_from_master_key(SignalMessageBackupKey **out, const uint8_t (*master_key)[32], const SignalServiceIdFixedWidthBinaryBytes *aci); + +SignalFfiError *signal_message_backup_key_from_account_entropy_pool(SignalMessageBackupKey **out, const char *account_entropy, const SignalServiceIdFixedWidthBinaryBytes *aci); + +SignalFfiError *signal_message_backup_key_from_backup_key_and_backup_id(SignalMessageBackupKey **out, const uint8_t (*backup_key)[32], const uint8_t (*backup_id)[16]); + +SignalFfiError *signal_message_backup_key_get_hmac_key(uint8_t (*out)[32], const SignalMessageBackupKey *key); + +SignalFfiError *signal_message_backup_key_get_aes_key(uint8_t (*out)[32], const SignalMessageBackupKey *key); SignalFfiError *signal_message_backup_validation_outcome_get_error_message(const char **out, const SignalMessageBackupValidationOutcome *outcome); diff --git a/pkg/libsignalgo/version.go b/pkg/libsignalgo/version.go index e7c4740..4bd3b99 100644 --- a/pkg/libsignalgo/version.go +++ b/pkg/libsignalgo/version.go @@ -2,4 +2,4 @@ package libsignalgo -const Version = "v0.58.3" +const Version = "v0.61.0" From a0389f98621f5987bcf8d79617058a2d6d93cb21 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Wed, 13 Nov 2024 16:38:12 +0200 Subject: [PATCH 221/580] login: save master key from provisioning message --- pkg/connector/login.go | 5 +++++ pkg/signalmeow/provisioning.go | 1 + 2 files changed, 6 insertions(+) diff --git a/pkg/connector/login.go b/pkg/connector/login.go index 2e79933..5636339 100644 --- a/pkg/connector/login.go +++ b/pkg/connector/login.go @@ -21,6 +21,7 @@ import ( "fmt" "github.com/google/uuid" + "github.com/rs/zerolog" "maunium.net/go/mautrix/bridge/status" "maunium.net/go/mautrix/bridgev2" "maunium.net/go/mautrix/bridgev2/database" @@ -175,6 +176,10 @@ func (qr *QRLogin) processingWait(ctx context.Context) (*bridgev2.LoginStep, err if err != nil { return nil, fmt.Errorf("failed to connect after login: %w", err) } + if signalClient := ul.Client.(*SignalClient).Client; signalClient.Store.MasterKey != nil { + zerolog.Ctx(ctx).Info().Msg("Received master key in login, syncing storage immediately") + go signalClient.SyncStorage(ctx) + } return &bridgev2.LoginStep{ Type: bridgev2.LoginStepTypeComplete, StepID: LoginStepComplete, diff --git a/pkg/signalmeow/provisioning.go b/pkg/signalmeow/provisioning.go index 213c246..75bb6df 100644 --- a/pkg/signalmeow/provisioning.go +++ b/pkg/signalmeow/provisioning.go @@ -164,6 +164,7 @@ func PerformProvisioning(ctx context.Context, deviceStore store.DeviceStore, dev DeviceID: deviceId, Number: *provisioningMessage.Number, Password: password, + MasterKey: provisioningMessage.GetMasterKey(), } // Store the provisioning data From b0966abd3eb31e1232917399def5fdbf90cc3c3e Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Wed, 13 Nov 2024 16:38:24 +0200 Subject: [PATCH 222/580] attachments: log data when TUS upload fails --- pkg/signalmeow/attachments.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/pkg/signalmeow/attachments.go b/pkg/signalmeow/attachments.go index e8ffe0b..8a4b618 100644 --- a/pkg/signalmeow/attachments.go +++ b/pkg/signalmeow/attachments.go @@ -251,6 +251,10 @@ func (cli *Client) uploadAttachmentTUS( if err != nil { return fmt.Errorf("failed to send upload request: %w", err) } else if resp.StatusCode < 200 || resp.StatusCode >= 300 { + zerolog.Ctx(ctx).Debug(). + Any("headers", uploadAttributes.Headers). + Str("location", uploadAttributes.SignedUploadLocation). + Msg("TUS upload failed") return fmt.Errorf("upload request returned HTTP %d", resp.StatusCode) } return nil From 3c31749fb2802a16e0e497bd3223102178c50d36 Mon Sep 17 00:00:00 2001 From: Scott Weber Date: Wed, 13 Nov 2024 16:20:28 -0500 Subject: [PATCH 223/580] handlesignal: add ServerTimestamp remote stream order on incoming messages (#550) --- pkg/connector/handlesignal.go | 23 ++++++++++++-------- pkg/signalmeow/events/message.go | 3 ++- pkg/signalmeow/receiving.go | 36 ++++++++++++++++++-------------- 3 files changed, 36 insertions(+), 26 deletions(-) diff --git a/pkg/connector/handlesignal.go b/pkg/connector/handlesignal.go index b39f202..2d863ac 100644 --- a/pkg/connector/handlesignal.go +++ b/pkg/connector/handlesignal.go @@ -135,15 +135,16 @@ type Bv2ChatEvent struct { } var ( - _ bridgev2.RemoteMessage = (*Bv2ChatEvent)(nil) - _ bridgev2.RemoteEdit = (*Bv2ChatEvent)(nil) - _ bridgev2.RemoteEventWithTimestamp = (*Bv2ChatEvent)(nil) - _ bridgev2.RemoteReaction = (*Bv2ChatEvent)(nil) - _ bridgev2.RemoteReactionRemove = (*Bv2ChatEvent)(nil) - _ bridgev2.RemoteMessageRemove = (*Bv2ChatEvent)(nil) - _ bridgev2.RemoteTyping = (*Bv2ChatEvent)(nil) - _ bridgev2.RemotePreHandler = (*Bv2ChatEvent)(nil) - _ bridgev2.RemoteChatInfoChange = (*Bv2ChatEvent)(nil) + _ bridgev2.RemoteMessage = (*Bv2ChatEvent)(nil) + _ bridgev2.RemoteEdit = (*Bv2ChatEvent)(nil) + _ bridgev2.RemoteEventWithTimestamp = (*Bv2ChatEvent)(nil) + _ bridgev2.RemoteReaction = (*Bv2ChatEvent)(nil) + _ bridgev2.RemoteReactionRemove = (*Bv2ChatEvent)(nil) + _ bridgev2.RemoteMessageRemove = (*Bv2ChatEvent)(nil) + _ bridgev2.RemoteTyping = (*Bv2ChatEvent)(nil) + _ bridgev2.RemotePreHandler = (*Bv2ChatEvent)(nil) + _ bridgev2.RemoteChatInfoChange = (*Bv2ChatEvent)(nil) + _ bridgev2.RemoteEventWithStreamOrder = (*Bv2ChatEvent)(nil) ) func (evt *Bv2ChatEvent) GetType() bridgev2.RemoteEventType { @@ -337,6 +338,10 @@ func (evt *Bv2ChatEvent) ConvertEdit(ctx context.Context, portal *bridgev2.Porta }, nil } +func (evt *Bv2ChatEvent) GetStreamOrder() int64 { + return int64(evt.Info.ServerTimestamp) +} + type Bv2Receipt struct { Type signalpb.ReceiptMessage_Type Chat networkid.PortalKey diff --git a/pkg/signalmeow/events/message.go b/pkg/signalmeow/events/message.go index a6fcc7f..0038657 100644 --- a/pkg/signalmeow/events/message.go +++ b/pkg/signalmeow/events/message.go @@ -40,7 +40,8 @@ type MessageInfo struct { Sender uuid.UUID ChatID string - GroupRevision uint32 + GroupRevision uint32 + ServerTimestamp uint64 } type ChatEvent struct { diff --git a/pkg/signalmeow/receiving.go b/pkg/signalmeow/receiving.go index 38a4e00..1bebf77 100644 --- a/pkg/signalmeow/receiving.go +++ b/pkg/signalmeow/receiving.go @@ -752,9 +752,9 @@ func (cli *Client) handleDecryptedResult( log.Warn().Msg("sync message sent destination is nil") } else if content.SyncMessage.Sent.Message != nil { // TODO handle expiration start ts, and maybe the sync message ts? - cli.incomingDataMessage(ctx, content.SyncMessage.Sent.Message, cli.Store.ACI, syncDestinationServiceID) + cli.incomingDataMessage(ctx, content.SyncMessage.Sent.Message, cli.Store.ACI, syncDestinationServiceID, envelope.GetServerTimestamp()) } else if content.SyncMessage.Sent.EditMessage != nil { - cli.incomingEditMessage(ctx, content.SyncMessage.Sent.EditMessage, cli.Store.ACI, syncDestinationServiceID) + cli.incomingEditMessage(ctx, content.SyncMessage.Sent.EditMessage, cli.Store.ACI, syncDestinationServiceID, envelope.GetServerTimestamp()) } } if content.SyncMessage.Contacts != nil { @@ -802,9 +802,9 @@ func (cli *Client) handleDecryptedResult( var sendDeliveryReceipt bool if content.DataMessage != nil { - sendDeliveryReceipt = cli.incomingDataMessage(ctx, content.DataMessage, theirServiceID.UUID, theirServiceID) + sendDeliveryReceipt = cli.incomingDataMessage(ctx, content.DataMessage, theirServiceID.UUID, theirServiceID, envelope.GetServerTimestamp()) } else if content.EditMessage != nil { - sendDeliveryReceipt = cli.incomingEditMessage(ctx, content.EditMessage, theirServiceID.UUID, theirServiceID) + sendDeliveryReceipt = cli.incomingEditMessage(ctx, content.EditMessage, theirServiceID.UUID, theirServiceID, envelope.GetServerTimestamp()) } if sendDeliveryReceipt { // TODO send delivery receipts after actually bridging instead of here @@ -822,8 +822,9 @@ func (cli *Client) handleDecryptedResult( } cli.handleEvent(&events.ChatEvent{ Info: events.MessageInfo{ - Sender: theirServiceID.UUID, - ChatID: groupOrUserID(groupID, theirServiceID), + Sender: theirServiceID.UUID, + ChatID: groupOrUserID(groupID, theirServiceID), + ServerTimestamp: envelope.GetServerTimestamp(), }, Event: content.TypingMessage, }) @@ -833,8 +834,9 @@ func (cli *Client) handleDecryptedResult( if content.CallMessage != nil && (content.CallMessage.Offer != nil || content.CallMessage.Hangup != nil) { cli.handleEvent(&events.Call{ Info: events.MessageInfo{ - Sender: theirServiceID.UUID, - ChatID: theirServiceID.String(), + Sender: theirServiceID.UUID, + ChatID: theirServiceID.String(), + ServerTimestamp: envelope.GetServerTimestamp(), }, // CallMessage doesn't have its own timestamp, use one from the envelope Timestamp: envelope.GetTimestamp(), @@ -964,7 +966,7 @@ func (cli *Client) handlePNISignatureMessage(ctx context.Context, sender libsign return nil } -func (cli *Client) incomingEditMessage(ctx context.Context, editMessage *signalpb.EditMessage, messageSenderACI uuid.UUID, chatRecipient libsignalgo.ServiceID) bool { +func (cli *Client) incomingEditMessage(ctx context.Context, editMessage *signalpb.EditMessage, messageSenderACI uuid.UUID, chatRecipient libsignalgo.ServiceID, serverTimestamp uint64) bool { // If it's a group message, get the ID and invalidate cache if necessary var groupID types.GroupIdentifier var groupRevision uint32 @@ -982,16 +984,17 @@ func (cli *Client) incomingEditMessage(ctx context.Context, editMessage *signalp } cli.handleEvent(&events.ChatEvent{ Info: events.MessageInfo{ - Sender: messageSenderACI, - ChatID: groupOrUserID(groupID, chatRecipient), - GroupRevision: groupRevision, + Sender: messageSenderACI, + ChatID: groupOrUserID(groupID, chatRecipient), + GroupRevision: groupRevision, + ServerTimestamp: serverTimestamp, }, Event: editMessage, }) return true } -func (cli *Client) incomingDataMessage(ctx context.Context, dataMessage *signalpb.DataMessage, messageSenderACI uuid.UUID, chatRecipient libsignalgo.ServiceID) bool { +func (cli *Client) incomingDataMessage(ctx context.Context, dataMessage *signalpb.DataMessage, messageSenderACI uuid.UUID, chatRecipient libsignalgo.ServiceID, serverTimestamp uint64) bool { // If there's a profile key, save it if dataMessage.ProfileKey != nil { profileKey := libsignalgo.ProfileKey(dataMessage.ProfileKey) @@ -1019,9 +1022,10 @@ func (cli *Client) incomingDataMessage(ctx context.Context, dataMessage *signalp } evtInfo := events.MessageInfo{ - Sender: messageSenderACI, - ChatID: groupOrUserID(groupID, chatRecipient), - GroupRevision: groupRevision, + Sender: messageSenderACI, + ChatID: groupOrUserID(groupID, chatRecipient), + GroupRevision: groupRevision, + ServerTimestamp: serverTimestamp, } // Hacky special case for group calls to cache the state if dataMessage.GroupCallUpdate != nil { From b538f47bff3902a1367937e0bdd1d40feea4d072 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Thu, 14 Nov 2024 17:23:10 +0200 Subject: [PATCH 224/580] signalmeow/attachments: log response headers for TUS uploads --- pkg/signalmeow/attachments.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pkg/signalmeow/attachments.go b/pkg/signalmeow/attachments.go index 8a4b618..4fc106f 100644 --- a/pkg/signalmeow/attachments.go +++ b/pkg/signalmeow/attachments.go @@ -252,7 +252,8 @@ func (cli *Client) uploadAttachmentTUS( return fmt.Errorf("failed to send upload request: %w", err) } else if resp.StatusCode < 200 || resp.StatusCode >= 300 { zerolog.Ctx(ctx).Debug(). - Any("headers", uploadAttributes.Headers). + Any("request_headers", uploadAttributes.Headers). + Any("response_headers", resp.Header). Str("location", uploadAttributes.SignedUploadLocation). Msg("TUS upload failed") return fmt.Errorf("upload request returned HTTP %d", resp.StatusCode) From 33ac0b4fcaf8bbfe08e2f2bd1641dc5a01c11b57 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Thu, 14 Nov 2024 18:03:05 +0200 Subject: [PATCH 225/580] signalmeow/attachments: remove auth from TUS upload request --- pkg/signalmeow/attachments.go | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/pkg/signalmeow/attachments.go b/pkg/signalmeow/attachments.go index 4fc106f..ca56634 100644 --- a/pkg/signalmeow/attachments.go +++ b/pkg/signalmeow/attachments.go @@ -166,7 +166,7 @@ func (cli *Client) UploadAttachment(ctx context.Context, body []byte) (*signalpb } if uploadAttributes.Cdn == 3 { log.Trace().Msg("Using TUS upload") - err = cli.uploadAttachmentTUS(ctx, uploadAttributes, encryptedWithMAC, username, password) + err = cli.uploadAttachmentTUS(ctx, uploadAttributes, encryptedWithMAC) } else { log.Trace().Msg("Using legacy upload") err = cli.uploadAttachmentLegacy(ctx, uploadAttributes, encryptedWithMAC, username, password) @@ -232,8 +232,6 @@ func (cli *Client) uploadAttachmentTUS( ctx context.Context, uploadAttributes attachmentV4UploadAttributes, encryptedWithMAC []byte, - username string, - password string, ) error { uploadAttributes.Headers["Tus-Resumable"] = "1.0.0" uploadAttributes.Headers["Upload-Length"] = fmt.Sprintf("%d", len(encryptedWithMAC)) @@ -244,8 +242,6 @@ func (cli *Client) uploadAttachmentTUS( Body: encryptedWithMAC, ContentType: web.ContentTypeOffsetOctetStream, Headers: uploadAttributes.Headers, - Username: &username, - Password: &password, }) // TODO actually support resuming on error if err != nil { From 45f97de8db3f44537ec40544f57b0c4cd786f2ee Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Fri, 15 Nov 2024 12:53:53 +0200 Subject: [PATCH 226/580] libsignal: update to v0.62.0 --- CHANGELOG.md | 5 +++++ pkg/libsignalgo/libsignal | 2 +- pkg/libsignalgo/libsignal-ffi.h | 16 +++++++++++----- pkg/libsignalgo/logging.go | 8 ++++---- pkg/libsignalgo/setup_test.go | 3 +-- pkg/libsignalgo/version.go | 2 +- pkg/signalmeow/misc.go | 3 +-- 7 files changed, 24 insertions(+), 15 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 743c281..2aff2f4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,8 @@ +# v0.7.3 (unreleased) + +* Updated libsignal to v0.62.0. +* Added basic support for Signal's new file upload protocol. + # v0.7.2 (2024-10-16) * Updated to libsignal v0.58.3. diff --git a/pkg/libsignalgo/libsignal b/pkg/libsignalgo/libsignal index 0a06f69..90ba453 160000 --- a/pkg/libsignalgo/libsignal +++ b/pkg/libsignalgo/libsignal @@ -1 +1 @@ -Subproject commit 0a06f69bce222c184a8d4022b8cf4202b02b9001 +Subproject commit 90ba45384073a467422d44783bc22a1152acd4c4 diff --git a/pkg/libsignalgo/libsignal-ffi.h b/pkg/libsignalgo/libsignal-ffi.h index 627dfd6..0af848b 100644 --- a/pkg/libsignalgo/libsignal-ffi.h +++ b/pkg/libsignalgo/libsignal-ffi.h @@ -445,7 +445,7 @@ typedef struct { SignalStoreSignedPreKey store_signed_pre_key; } SignalSignedPreKeyStore; -typedef void (*SignalLogCallback)(void *ctx, const char *target, SignalLogLevel level, const char *file, uint32_t line, const char *message); +typedef void (*SignalLogCallback)(void *ctx, SignalLogLevel level, const char *file, uint32_t line, const char *message); typedef void (*SignalLogFlushCallback)(void *ctx); @@ -664,6 +664,14 @@ typedef void (*SignalDestroyChatListener)(void *ctx); * Callbacks will be serialized (i.e. two calls will not come in at the same time), but may not * always happen on the same thread. Calls should be responded to promptly to avoid blocking later * messages. + * + * # Safety + * + * This type contains raw pointers. Code that constructs an instance of this type must ensure + * memory safety assuming that + * - the callback function pointer fields are called with `ctx` as an argument; + * - the `destroy` function pointer field is called with `ctx` as an argument; + * - no function pointer fields are called after `destroy` is called. */ typedef struct { void *ctx; @@ -673,8 +681,6 @@ typedef struct { SignalDestroyChatListener destroy; } SignalFfiChatListenerStruct; -typedef SignalFfiChatListenerStruct SignalFfiMakeChatListenerStruct; - typedef int (*SignalRead)(void *ctx, uint8_t *buf, size_t buf_len, size_t *amount_read); typedef int (*SignalSkip)(void *ctx, uint64_t amount); @@ -1545,9 +1551,9 @@ SignalFfiError *signal_chat_service_auth_send(SignalCPromiseFfiChatResponse *pro SignalFfiError *signal_chat_service_auth_send_and_debug(SignalCPromiseFfiResponseAndDebugInfo *promise, const SignalTokioAsyncContext *async_runtime, const SignalAuthChat *chat, const SignalHttpRequest *http_request, uint32_t timeout_millis); -SignalFfiError *signal_chat_service_set_listener_auth(const SignalTokioAsyncContext *runtime, const SignalAuthChat *chat, const SignalFfiMakeChatListenerStruct *make_listener); +SignalFfiError *signal_chat_service_set_listener_auth(const SignalTokioAsyncContext *runtime, const SignalAuthChat *chat, const SignalFfiChatListenerStruct *listener); -SignalFfiError *signal_chat_service_set_listener_unauth(const SignalTokioAsyncContext *runtime, const SignalUnauthChat *chat, const SignalFfiMakeChatListenerStruct *make_listener); +SignalFfiError *signal_chat_service_set_listener_unauth(const SignalTokioAsyncContext *runtime, const SignalUnauthChat *chat, const SignalFfiChatListenerStruct *listener); SignalFfiError *signal_server_message_ack_destroy(SignalServerMessageAck *p); diff --git a/pkg/libsignalgo/logging.go b/pkg/libsignalgo/logging.go index 2cbee01..e0a2351 100644 --- a/pkg/libsignalgo/logging.go +++ b/pkg/libsignalgo/logging.go @@ -20,7 +20,7 @@ package libsignalgo #cgo LDFLAGS: -lsignal_ffi -ldl -lm #include <./libsignal-ffi.h> -extern void signal_log_callback(void *ctx, char *target, SignalLogLevel level, char *file, uint32_t line, char *message); +extern void signal_log_callback(void *ctx, SignalLogLevel level, char *file, uint32_t line, char *message); extern void signal_log_flush_callback(void *ctx); */ import "C" @@ -32,8 +32,8 @@ import ( var ffiLogger Logger //export signal_log_callback -func signal_log_callback(ctx unsafe.Pointer, target *C.char, level C.SignalLogLevel, file *C.char, line C.uint32_t, message *C.char) { - ffiLogger.Log(C.GoString(target), LogLevel(int(level)), C.GoString(file), uint(line), C.GoString(message)) +func signal_log_callback(ctx unsafe.Pointer, level C.SignalLogLevel, file *C.char, line C.uint32_t, message *C.char) { + ffiLogger.Log(LogLevel(int(level)), C.GoString(file), uint(line), C.GoString(message)) } //export signal_log_flush_callback @@ -52,7 +52,7 @@ const ( ) type Logger interface { - Log(target string, level LogLevel, file string, line uint, message string) + Log(level LogLevel, file string, line uint, message string) Flush() } diff --git a/pkg/libsignalgo/setup_test.go b/pkg/libsignalgo/setup_test.go index 397238b..c22149d 100644 --- a/pkg/libsignalgo/setup_test.go +++ b/pkg/libsignalgo/setup_test.go @@ -29,7 +29,7 @@ type FFILogger struct{} func (FFILogger) Enabled(target string, level libsignalgo.LogLevel) bool { return true } -func (FFILogger) Log(target string, level libsignalgo.LogLevel, file string, line uint, message string) { +func (FFILogger) Log(level libsignalgo.LogLevel, file string, line uint, message string) { var evt *zerolog.Event switch level { case libsignalgo.LogLevelError: @@ -47,7 +47,6 @@ func (FFILogger) Log(target string, level libsignalgo.LogLevel, file string, lin } evt.Str("component", "libsignal"). - Str("target", target). Str("file", file). Uint("line", line). Msg(message) diff --git a/pkg/libsignalgo/version.go b/pkg/libsignalgo/version.go index 4bd3b99..47fc072 100644 --- a/pkg/libsignalgo/version.go +++ b/pkg/libsignalgo/version.go @@ -2,4 +2,4 @@ package libsignalgo -const Version = "v0.61.0" +const Version = "v0.62.0" diff --git a/pkg/signalmeow/misc.go b/pkg/signalmeow/misc.go index 1062dcb..1bf88a3 100644 --- a/pkg/signalmeow/misc.go +++ b/pkg/signalmeow/misc.go @@ -41,7 +41,7 @@ type FFILogger struct { logger zerolog.Logger } -func (l FFILogger) Log(target string, level libsignalgo.LogLevel, file string, line uint, message string) { +func (l FFILogger) Log(level libsignalgo.LogLevel, file string, line uint, message string) { var evt *zerolog.Event switch level { case libsignalgo.LogLevelError: @@ -59,7 +59,6 @@ func (l FFILogger) Log(target string, level libsignalgo.LogLevel, file string, l } evt.Str("component", "libsignal"). - Str("target", target). Str("file", file). Uint("line", line). Msg(message) From cf216cba7ab253da48dcfb352e54adc05d81ef69 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Sat, 16 Nov 2024 17:21:20 +0200 Subject: [PATCH 227/580] Bump version to v0.7.3 --- CHANGELOG.md | 6 +++++- cmd/mautrix-signal/main.go | 2 +- go.mod | 6 +++--- go.sum | 12 ++++++------ 4 files changed, 15 insertions(+), 11 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2aff2f4..8321abe 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,8 +1,12 @@ -# v0.7.3 (unreleased) +# v0.7.3 (2024-11-16) * Updated libsignal to v0.62.0. + * Note for bridges running in systemd: the new version of libsignal may be + incompatible with the `MemoryDenyWriteExecute=true` option (see [#750]). * Added basic support for Signal's new file upload protocol. +[#750]: https://github.com/mautrix/signal/issues/570 + # v0.7.2 (2024-10-16) * Updated to libsignal v0.58.3. diff --git a/cmd/mautrix-signal/main.go b/cmd/mautrix-signal/main.go index 51dc76e..92121cb 100644 --- a/cmd/mautrix-signal/main.go +++ b/cmd/mautrix-signal/main.go @@ -38,7 +38,7 @@ var m = mxmain.BridgeMain{ Name: "mautrix-signal", URL: "https://github.com/mautrix/signal", Description: "A Matrix-Signal puppeting bridge.", - Version: "0.7.2", + Version: "0.7.3", Connector: &connector.SignalConnector{}, } diff --git a/go.mod b/go.mod index 4e31e51..af76c4d 100644 --- a/go.mod +++ b/go.mod @@ -13,12 +13,12 @@ require ( github.com/rs/zerolog v1.33.0 github.com/stretchr/testify v1.9.0 github.com/tidwall/gjson v1.18.0 - go.mau.fi/util v0.8.2-0.20241113135441-636f8643f367 + go.mau.fi/util v0.8.2 golang.org/x/crypto v0.29.0 golang.org/x/exp v0.0.0-20241108190413-2d47ceb2692f golang.org/x/net v0.31.0 - google.golang.org/protobuf v1.35.1 - maunium.net/go/mautrix v0.21.2-0.20241113135638-b22764aa170a + google.golang.org/protobuf v1.35.2 + maunium.net/go/mautrix v0.22.0 ) require ( diff --git a/go.sum b/go.sum index 590bd3d..69e3105 100644 --- a/go.sum +++ b/go.sum @@ -67,8 +67,8 @@ github.com/tidwall/sjson v1.2.5 h1:kLy8mja+1c9jlljvWTlSazM7cKDRfJuR/bOJhcY5NcY= github.com/tidwall/sjson v1.2.5/go.mod h1:Fvgq9kS/6ociJEDnK0Fk1cpYF4FIW6ZF7LAe+6jwd28= github.com/yuin/goldmark v1.7.8 h1:iERMLn0/QJeHFhxSt3p6PeN9mGnvIKSpG9YYorDMnic= github.com/yuin/goldmark v1.7.8/go.mod h1:uzxRWxtg69N339t3louHJ7+O03ezfj6PlliRlaOzY1E= -go.mau.fi/util v0.8.2-0.20241113135441-636f8643f367 h1:GU0TYiAOU79p6r3jf3e4k5cdgnPxOcJWkWeWampdAjw= -go.mau.fi/util v0.8.2-0.20241113135441-636f8643f367/go.mod h1:SVzC++wSl8Yq4YVQRClLPa1frNpSVDVP6mfkw/OvDbc= +go.mau.fi/util v0.8.2 h1:zWbVHwdRKwI6U9AusmZ8bwgcLosikwbb4GGqLrNr1YE= +go.mau.fi/util v0.8.2/go.mod h1:BHHC9R2WLMJd1bwTZfTcFxUgRFmUgUmiWcT4RbzUgiA= go.mau.fi/zeroconfig v0.1.3 h1:As9wYDKmktjmNZW5i1vn8zvJlmGKHeVxHVIBMXsm4kM= go.mau.fi/zeroconfig v0.1.3/go.mod h1:NcSJkf180JT+1IId76PcMuLTNa1CzsFFZ0nBygIQM70= golang.org/x/crypto v0.29.0 h1:L5SG1JTTXupVV3n6sUqMTeWbjAyfPwoda2DLX8J8FrQ= @@ -86,8 +86,8 @@ golang.org/x/sys v0.27.0 h1:wBqf8DvsY9Y/2P8gAfPDEYNuS30J4lPHJxXSb/nJZ+s= golang.org/x/sys v0.27.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/text v0.20.0 h1:gK/Kv2otX8gz+wn7Rmb3vT96ZwuoxnQlY+HlJVj7Qug= golang.org/x/text v0.20.0/go.mod h1:D4IsuqiFMhST5bX19pQ9ikHC2GsaKyk/oF+pn3ducp4= -google.golang.org/protobuf v1.35.1 h1:m3LfL6/Ca+fqnjnlqQXNpFPABW1UD7mjh8KO2mKFytA= -google.golang.org/protobuf v1.35.1/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= +google.golang.org/protobuf v1.35.2 h1:8Ar7bF+apOIoThw1EdZl0p1oWvMqTHmpA2fRTyZO8io= +google.golang.org/protobuf v1.35.2/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= @@ -97,5 +97,5 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= maunium.net/go/mauflag v1.0.0 h1:YiaRc0tEI3toYtJMRIfjP+jklH45uDHtT80nUamyD4M= maunium.net/go/mauflag v1.0.0/go.mod h1:nLivPOpTpHnpzEh8jEdSL9UqO9+/KBJFmNRlwKfkPeA= -maunium.net/go/mautrix v0.21.2-0.20241113135638-b22764aa170a h1:+hOkf85qhGRoAPpoCk7AiqKxlNvCCizb6urJVmgk0+8= -maunium.net/go/mautrix v0.21.2-0.20241113135638-b22764aa170a/go.mod h1:X7VB/wOIUo6c3wACyVwA//v2k8BpMLFB2rvaX2Y0984= +maunium.net/go/mautrix v0.22.0 h1:nLrnLYiMyFV6qZPqpkNogkOPgm2dQTYiQXlu9Nc3rz8= +maunium.net/go/mautrix v0.22.0/go.mod h1:oqwf9WYC/brqucM+heYk4gX11O59nP+ljvyxVhndFIM= From 29d55ebbde24d008f8c12f6f1d50d2916c5f949b Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Mon, 18 Nov 2024 15:18:44 +0200 Subject: [PATCH 228/580] signalmeow: add support for ssre2 Corresponds to https://github.com/signalapp/Signal-Desktop/commit/a338bc5a6717eed455673c631f4077ad4ce47436 --- pkg/libsignalgo/accountentropy.go | 55 ++++++++++++++++++ .../protobuf/ContactDiscovery.pb.go | 2 +- pkg/signalmeow/protobuf/DeviceName.pb.go | 2 +- pkg/signalmeow/protobuf/Groups.pb.go | 2 +- pkg/signalmeow/protobuf/Provisioning.pb.go | 2 +- pkg/signalmeow/protobuf/SignalService.pb.go | 22 ++++++- pkg/signalmeow/protobuf/SignalService.pb.raw | Bin 19130 -> 19227 bytes pkg/signalmeow/protobuf/SignalService.proto | 2 + .../protobuf/StickerResources.pb.go | 2 +- pkg/signalmeow/protobuf/StorageService.pb.go | 13 ++++- pkg/signalmeow/protobuf/StorageService.pb.raw | Bin 5934 -> 5983 bytes pkg/signalmeow/protobuf/StorageService.proto | 2 + .../protobuf/UnidentifiedDelivery.pb.go | 2 +- .../protobuf/WebSocketResources.pb.go | 2 +- pkg/signalmeow/provisioning.go | 9 +++ pkg/signalmeow/receiving.go | 17 ++++++ pkg/signalmeow/storageservice.go | 30 +++++++--- 17 files changed, 145 insertions(+), 19 deletions(-) create mode 100644 pkg/libsignalgo/accountentropy.go diff --git a/pkg/libsignalgo/accountentropy.go b/pkg/libsignalgo/accountentropy.go new file mode 100644 index 0000000..3160d64 --- /dev/null +++ b/pkg/libsignalgo/accountentropy.go @@ -0,0 +1,55 @@ +// mautrix-signal - A Matrix-signal puppeting bridge. +// Copyright (C) 2024 Tulir Asokan +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +package libsignalgo + +/* +#cgo LDFLAGS: -lsignal_ffi -ldl -lm +#include "./libsignal-ffi.h" +*/ +import "C" +import ( + "runtime" + "unsafe" +) + +type AccountEntropyPool string + +func (aep AccountEntropyPool) DeriveSVRKey() ([]byte, error) { + var out [C.SignalSVR_KEY_LEN]byte + signalFfiError := C.signal_account_entropy_pool_derive_svr_key( + (*[C.SignalSVR_KEY_LEN]C.uint8_t)(unsafe.Pointer(&out)), + C.CString(string(aep)), + ) + runtime.KeepAlive(aep) + if signalFfiError != nil { + return nil, wrapError(signalFfiError) + } + return out[:], nil +} + +func (aep AccountEntropyPool) DeriveBackupKey() ([]byte, error) { + var out [C.SignalBACKUP_KEY_LEN]byte + signalFfiError := C.signal_account_entropy_pool_derive_backup_key( + (*[C.SignalBACKUP_KEY_LEN]C.uint8_t)(unsafe.Pointer(&out)), + C.CString(string(aep)), + ) + runtime.KeepAlive(aep) + if signalFfiError != nil { + return nil, wrapError(signalFfiError) + } + return out[:], nil +} diff --git a/pkg/signalmeow/protobuf/ContactDiscovery.pb.go b/pkg/signalmeow/protobuf/ContactDiscovery.pb.go index 6fd86ab..3c3d5b1 100644 --- a/pkg/signalmeow/protobuf/ContactDiscovery.pb.go +++ b/pkg/signalmeow/protobuf/ContactDiscovery.pb.go @@ -1,6 +1,6 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.35.1 +// protoc-gen-go v1.35.2 // protoc v3.21.12 // source: ContactDiscovery.proto diff --git a/pkg/signalmeow/protobuf/DeviceName.pb.go b/pkg/signalmeow/protobuf/DeviceName.pb.go index 8207918..9721926 100644 --- a/pkg/signalmeow/protobuf/DeviceName.pb.go +++ b/pkg/signalmeow/protobuf/DeviceName.pb.go @@ -1,6 +1,6 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.35.1 +// protoc-gen-go v1.35.2 // protoc v3.21.12 // source: DeviceName.proto diff --git a/pkg/signalmeow/protobuf/Groups.pb.go b/pkg/signalmeow/protobuf/Groups.pb.go index b10d66a..b6d2280 100644 --- a/pkg/signalmeow/protobuf/Groups.pb.go +++ b/pkg/signalmeow/protobuf/Groups.pb.go @@ -5,7 +5,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.35.1 +// protoc-gen-go v1.35.2 // protoc v3.21.12 // source: Groups.proto diff --git a/pkg/signalmeow/protobuf/Provisioning.pb.go b/pkg/signalmeow/protobuf/Provisioning.pb.go index e7b7585..24e3a64 100644 --- a/pkg/signalmeow/protobuf/Provisioning.pb.go +++ b/pkg/signalmeow/protobuf/Provisioning.pb.go @@ -5,7 +5,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.35.1 +// protoc-gen-go v1.35.2 // protoc v3.21.12 // source: Provisioning.proto diff --git a/pkg/signalmeow/protobuf/SignalService.pb.go b/pkg/signalmeow/protobuf/SignalService.pb.go index 9ce328c..f9abde1 100644 --- a/pkg/signalmeow/protobuf/SignalService.pb.go +++ b/pkg/signalmeow/protobuf/SignalService.pb.go @@ -5,7 +5,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.35.1 +// protoc-gen-go v1.35.2 // protoc v3.21.12 // source: SignalService.proto @@ -6243,8 +6243,10 @@ type SyncMessage_Keys struct { unknownFields protoimpl.UnknownFields // @deprecated - StorageService []byte `protobuf:"bytes,1,opt,name=storageService" json:"storageService,omitempty"` - Master []byte `protobuf:"bytes,2,opt,name=master" json:"master,omitempty"` + StorageService []byte `protobuf:"bytes,1,opt,name=storageService" json:"storageService,omitempty"` + Master []byte `protobuf:"bytes,2,opt,name=master" json:"master,omitempty"` + AccountEntropyPool *string `protobuf:"bytes,3,opt,name=accountEntropyPool" json:"accountEntropyPool,omitempty"` // Copied manually from Signal Desktop + MediaRootBackupKey []byte `protobuf:"bytes,4,opt,name=mediaRootBackupKey" json:"mediaRootBackupKey,omitempty"` // Copied manually from Signal Desktop } func (x *SyncMessage_Keys) Reset() { @@ -6291,6 +6293,20 @@ func (x *SyncMessage_Keys) GetMaster() []byte { return nil } +func (x *SyncMessage_Keys) GetAccountEntropyPool() string { + if x != nil && x.AccountEntropyPool != nil { + return *x.AccountEntropyPool + } + return "" +} + +func (x *SyncMessage_Keys) GetMediaRootBackupKey() []byte { + if x != nil { + return x.MediaRootBackupKey + } + return nil +} + type SyncMessage_MessageRequestResponse struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache diff --git a/pkg/signalmeow/protobuf/SignalService.pb.raw b/pkg/signalmeow/protobuf/SignalService.pb.raw index 45c938aa97b57244e0ce9953a01cc7c33bc05a03..0212283ad7d460eef2666a29af7587664d4aa392 100644 GIT binary patch delta 135 zcmdlrm2vho#tn~^m`+=7eyXI#$Fz)bGLNBKs*oO+P-1d&eraBbYhFoFenDkGetwPw zvjU?AXAl+{kow%zl+47S{QMH9#N_PK0`JsH2^OGwo**nTQhiKZVv{czifzs{^pykv DJtQp= delta 38 ucmbO|jd9mh#tn~^m|j_JeyXI#$LKbh*U*hss*j0FY_g$|*yeMFzLEeG1`M45 diff --git a/pkg/signalmeow/protobuf/SignalService.proto b/pkg/signalmeow/protobuf/SignalService.proto index aa0a752..8a4bca8 100644 --- a/pkg/signalmeow/protobuf/SignalService.proto +++ b/pkg/signalmeow/protobuf/SignalService.proto @@ -547,6 +547,8 @@ message SyncMessage { // @deprecated optional bytes storageService = 1; optional bytes master = 2; + optional string accountEntropyPool = 3; // Copied manually from Signal Desktop + optional bytes mediaRootBackupKey = 4; // Copied manually from Signal Desktop } message MessageRequestResponse { diff --git a/pkg/signalmeow/protobuf/StickerResources.pb.go b/pkg/signalmeow/protobuf/StickerResources.pb.go index 0da3266..d49db13 100644 --- a/pkg/signalmeow/protobuf/StickerResources.pb.go +++ b/pkg/signalmeow/protobuf/StickerResources.pb.go @@ -5,7 +5,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.35.1 +// protoc-gen-go v1.35.2 // protoc v3.21.12 // source: StickerResources.proto diff --git a/pkg/signalmeow/protobuf/StorageService.pb.go b/pkg/signalmeow/protobuf/StorageService.pb.go index 269354a..88b890a 100644 --- a/pkg/signalmeow/protobuf/StorageService.pb.go +++ b/pkg/signalmeow/protobuf/StorageService.pb.go @@ -5,7 +5,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.35.1 +// protoc-gen-go v1.35.2 // protoc v3.21.12 // source: StorageService.proto @@ -623,7 +623,8 @@ type ManifestRecord struct { Version uint64 `protobuf:"varint,1,opt,name=version,proto3" json:"version,omitempty"` SourceDevice uint32 `protobuf:"varint,3,opt,name=sourceDevice,proto3" json:"sourceDevice,omitempty"` - Identifiers []*ManifestRecord_Identifier `protobuf:"bytes,2,rep,name=identifiers,proto3" json:"identifiers,omitempty"` // Next ID: 4 + Identifiers []*ManifestRecord_Identifier `protobuf:"bytes,2,rep,name=identifiers,proto3" json:"identifiers,omitempty"` // Next ID: 4 + RecordIkm []byte `protobuf:"bytes,4,opt,name=recordIkm,proto3,oneof" json:"recordIkm,omitempty"` // Copied manually from Signal Desktop } func (x *ManifestRecord) Reset() { @@ -677,6 +678,13 @@ func (x *ManifestRecord) GetIdentifiers() []*ManifestRecord_Identifier { return nil } +func (x *ManifestRecord) GetRecordIkm() []byte { + if x != nil { + return x.RecordIkm + } + return nil +} + type StorageRecord struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -2130,6 +2138,7 @@ func file_StorageService_proto_init() { if File_StorageService_proto != nil { return } + file_StorageService_proto_msgTypes[5].OneofWrappers = []any{} file_StorageService_proto_msgTypes[6].OneofWrappers = []any{ (*StorageRecord_Contact)(nil), (*StorageRecord_GroupV1)(nil), diff --git a/pkg/signalmeow/protobuf/StorageService.pb.raw b/pkg/signalmeow/protobuf/StorageService.pb.raw index c4befd576011672424b415535ef42449380d7931..cee69e5c54315ecf9be610cfc5e7d8a70dc60c01 100644 GIT binary patch delta 74 zcmZ3dcVBPAB}S$t%#*J$&QcaqE`AN=I6oyf#wR0 diff --git a/pkg/signalmeow/protobuf/StorageService.proto b/pkg/signalmeow/protobuf/StorageService.proto index 7b2fa3a..c8f4582 100644 --- a/pkg/signalmeow/protobuf/StorageService.proto +++ b/pkg/signalmeow/protobuf/StorageService.proto @@ -61,6 +61,8 @@ message ManifestRecord { uint32 sourceDevice = 3; repeated Identifier identifiers = 2; // Next ID: 4 + + optional bytes recordIkm = 4; // Copied manually from Signal Desktop } message StorageRecord { diff --git a/pkg/signalmeow/protobuf/UnidentifiedDelivery.pb.go b/pkg/signalmeow/protobuf/UnidentifiedDelivery.pb.go index b42ca6f..e4eda97 100644 --- a/pkg/signalmeow/protobuf/UnidentifiedDelivery.pb.go +++ b/pkg/signalmeow/protobuf/UnidentifiedDelivery.pb.go @@ -1,6 +1,6 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.35.1 +// protoc-gen-go v1.35.2 // protoc v3.21.12 // source: UnidentifiedDelivery.proto diff --git a/pkg/signalmeow/protobuf/WebSocketResources.pb.go b/pkg/signalmeow/protobuf/WebSocketResources.pb.go index b3514e6..157c802 100644 --- a/pkg/signalmeow/protobuf/WebSocketResources.pb.go +++ b/pkg/signalmeow/protobuf/WebSocketResources.pb.go @@ -5,7 +5,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.35.1 +// protoc-gen-go v1.35.2 // protoc v3.21.12 // source: WebSocketResources.proto diff --git a/pkg/signalmeow/provisioning.go b/pkg/signalmeow/provisioning.go index 75bb6df..c997959 100644 --- a/pkg/signalmeow/provisioning.go +++ b/pkg/signalmeow/provisioning.go @@ -166,6 +166,14 @@ func PerformProvisioning(ctx context.Context, deviceStore store.DeviceStore, dev Password: password, MasterKey: provisioningMessage.GetMasterKey(), } + if provisioningMessage.GetMasterKey() == nil && provisioningMessage.GetAccountEntropyPool() != "" { + data.MasterKey, err = libsignalgo.AccountEntropyPool(provisioningMessage.GetAccountEntropyPool()).DeriveSVRKey() + if err != nil { + log.Err(err).Msg("Failed to derive master key from account entropy pool") + } else { + log.Debug().Msg("Derived master key from account entropy pool") + } + } // Store the provisioning data err = deviceStore.PutDevice(ctx, data) @@ -334,6 +342,7 @@ func continueProvisioning(ctx context.Context, ws *websocket.Conn, provisioningC var signalCapabilities = map[string]any{ "deleteSync": true, "versionedExpirationTimer": true, + "ssre2": true, } var signalCapabilitiesBody = exerrors.Must(json.Marshal(signalCapabilities)) diff --git a/pkg/signalmeow/receiving.go b/pkg/signalmeow/receiving.go index 1bebf77..aa07431 100644 --- a/pkg/signalmeow/receiving.go +++ b/pkg/signalmeow/receiving.go @@ -17,6 +17,7 @@ package signalmeow import ( + "bytes" "context" "encoding/base64" "fmt" @@ -718,7 +719,23 @@ func (cli *Client) handleDecryptedResult( // TODO: handle more sync messages if content.SyncMessage != nil { if content.SyncMessage.Keys != nil { + aep := libsignalgo.AccountEntropyPool(content.SyncMessage.Keys.GetAccountEntropyPool()) cli.Store.MasterKey = content.SyncMessage.Keys.GetMaster() + if aep != "" { + aepMasterKey, err := aep.DeriveSVRKey() + if err != nil { + log.Err(err).Msg("Failed to derive master key from account entropy pool") + } else if cli.Store.MasterKey == nil { + cli.Store.MasterKey = aepMasterKey + log.Debug().Msg("Derived master key from account entropy pool (no master key in sync message)") + } else if !bytes.Equal(aepMasterKey, cli.Store.MasterKey) { + log.Warn().Msg("Derived master key doesn't match one in sync message") + } else { + log.Debug().Msg("Derived master key matches one in sync message") + } + } else { + log.Debug().Msg("No account entropy pool in sync message") + } err = cli.Store.DeviceStore.PutDevice(ctx, &cli.Store.DeviceData) if err != nil { log.Err(err).Msg("Failed to save device after receiving master key") diff --git a/pkg/signalmeow/storageservice.go b/pkg/signalmeow/storageservice.go index f2385f3..1902c4b 100644 --- a/pkg/signalmeow/storageservice.go +++ b/pkg/signalmeow/storageservice.go @@ -29,6 +29,7 @@ import ( "github.com/google/uuid" "github.com/rs/zerolog" "go.mau.fi/util/exerrors" + "golang.org/x/crypto/hkdf" "golang.org/x/exp/maps" "golang.org/x/exp/slices" "google.golang.org/protobuf/proto" @@ -146,7 +147,7 @@ func (cli *Client) FetchStorage(ctx context.Context, masterKey []byte, currentVe } delete(newKeys, key) } - newRecords, missingKeys, err := cli.fetchStorageRecords(ctx, storageKey, newKeys) + newRecords, missingKeys, err := cli.fetchStorageRecords(ctx, storageKey, manifest.GetRecordIkm(), newKeys) if err != nil { return nil, err } @@ -178,10 +179,20 @@ func deriveStorageManifestKey(storageKey []byte, version uint64) []byte { return h.Sum(nil) } -func deriveStorageItemKey(storageKey []byte, itemID string) []byte { - h := hmac.New(sha256.New, storageKey) - exerrors.Must(fmt.Fprintf(h, "Item_%s", itemID)) - return h.Sum(nil) +const storageServiceItemKeyInfoPrefix = "20240801_SIGNAL_STORAGE_SERVICE_ITEM_" +const storageServiceItemKeyLen = 32 + +func deriveStorageItemKey(storageKey, recordIKM []byte, itemID string) []byte { + if recordIKM == nil { + h := hmac.New(sha256.New, storageKey) + exerrors.Must(fmt.Fprintf(h, "Item_%s", itemID)) + return h.Sum(nil) + } else { + h := hkdf.New(sha256.New, recordIKM, []byte{}, append([]byte(storageServiceItemKeyInfoPrefix), itemID...)) + out := make([]byte, storageServiceItemKeyLen) + exerrors.Must(io.ReadFull(h, out)) + return out + } } // MaxReadStorageRecords is the maximum number of storage records to fetch at once @@ -231,7 +242,12 @@ func (cli *Client) fetchStorageManifest(ctx context.Context, storageKey []byte, } } -func (cli *Client) fetchStorageRecords(ctx context.Context, storageKey []byte, inputRecords map[string]signalpb.ManifestRecord_Identifier_Type) ([]*DecryptedStorageRecord, []string, error) { +func (cli *Client) fetchStorageRecords( + ctx context.Context, + storageKey []byte, + recordIKM []byte, + inputRecords map[string]signalpb.ManifestRecord_Identifier_Type, +) ([]*DecryptedStorageRecord, []string, error) { recordKeys := make([][]byte, 0, len(inputRecords)) for key := range inputRecords { decoded, err := base64.StdEncoding.DecodeString(key) @@ -262,7 +278,7 @@ func (cli *Client) fetchStorageRecords(ctx context.Context, storageKey []byte, i log.Warn().Int("item_index", i).Str("item_key", base64Key).Msg("Received unexpected storage item") continue } - itemKey := deriveStorageItemKey(storageKey, base64Key) + itemKey := deriveStorageItemKey(storageKey, recordIKM, base64Key) decryptedItemBytes, err := decryptBytes(itemKey, encryptedItem.GetValue()) if err != nil { log.Warn().Err(err). From 958aa33a747dec560ac850c42bdc0be280cbd65b Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Mon, 2 Dec 2024 13:09:48 +0200 Subject: [PATCH 229/580] pre-commit: update hooks --- .pre-commit-config.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 8a667b3..1f3f910 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,6 +1,6 @@ repos: - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v4.6.0 + rev: v5.0.0 hooks: - id: trailing-whitespace exclude_types: [markdown] @@ -22,7 +22,7 @@ repos: # TODO: reenable this and fix all the problems - repo: https://github.com/beeper/pre-commit-go - rev: v0.3.1 + rev: v0.4.2 hooks: - id: zerolog-ban-msgf - id: zerolog-use-stringer From 39116d9e43d735cd795f9d746b3a3cd4d5d4a416 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Mon, 2 Dec 2024 13:14:44 +0200 Subject: [PATCH 230/580] signalmeow: update protobufs --- pkg/signalmeow/protobuf/Provisioning.pb.go | 32 +++++++++--------- pkg/signalmeow/protobuf/Provisioning.pb.raw | Bin 948 -> 957 bytes pkg/signalmeow/protobuf/Provisioning.proto | 4 +-- pkg/signalmeow/protobuf/SignalService.pb.go | 7 ++-- pkg/signalmeow/protobuf/SignalService.proto | 7 ++-- pkg/signalmeow/protobuf/StorageService.pb.go | 5 ++- pkg/signalmeow/protobuf/StorageService.pb.raw | Bin 5983 -> 5964 bytes pkg/signalmeow/protobuf/StorageService.proto | 5 ++- pkg/signalmeow/protobuf/update-protos.sh | 4 +-- pkg/signalmeow/provisioning.go | 7 ++-- 10 files changed, 36 insertions(+), 35 deletions(-) diff --git a/pkg/signalmeow/protobuf/Provisioning.pb.go b/pkg/signalmeow/protobuf/Provisioning.pb.go index 24e3a64..a1d3f0b 100644 --- a/pkg/signalmeow/protobuf/Provisioning.pb.go +++ b/pkg/signalmeow/protobuf/Provisioning.pb.go @@ -86,28 +86,28 @@ func (ProvisioningVersion) EnumDescriptor() ([]byte, []int) { return file_Provisioning_proto_rawDescGZIP(), []int{0} } -type ProvisioningUuid struct { +type ProvisioningAddress struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Uuid *string `protobuf:"bytes,1,opt,name=uuid" json:"uuid,omitempty"` + Address *string `protobuf:"bytes,1,opt,name=address" json:"address,omitempty"` } -func (x *ProvisioningUuid) Reset() { - *x = ProvisioningUuid{} +func (x *ProvisioningAddress) Reset() { + *x = ProvisioningAddress{} mi := &file_Provisioning_proto_msgTypes[0] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } -func (x *ProvisioningUuid) String() string { +func (x *ProvisioningAddress) String() string { return protoimpl.X.MessageStringOf(x) } -func (*ProvisioningUuid) ProtoMessage() {} +func (*ProvisioningAddress) ProtoMessage() {} -func (x *ProvisioningUuid) ProtoReflect() protoreflect.Message { +func (x *ProvisioningAddress) ProtoReflect() protoreflect.Message { mi := &file_Provisioning_proto_msgTypes[0] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -119,14 +119,14 @@ func (x *ProvisioningUuid) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use ProvisioningUuid.ProtoReflect.Descriptor instead. -func (*ProvisioningUuid) Descriptor() ([]byte, []int) { +// Deprecated: Use ProvisioningAddress.ProtoReflect.Descriptor instead. +func (*ProvisioningAddress) Descriptor() ([]byte, []int) { return file_Provisioning_proto_rawDescGZIP(), []int{0} } -func (x *ProvisioningUuid) GetUuid() string { - if x != nil && x.Uuid != nil { - return *x.Uuid +func (x *ProvisioningAddress) GetAddress() string { + if x != nil && x.Address != nil { + return *x.Address } return "" } @@ -369,10 +369,10 @@ func file_Provisioning_proto_rawDescGZIP() []byte { var file_Provisioning_proto_enumTypes = make([]protoimpl.EnumInfo, 1) var file_Provisioning_proto_msgTypes = make([]protoimpl.MessageInfo, 3) var file_Provisioning_proto_goTypes = []any{ - (ProvisioningVersion)(0), // 0: signalservice.ProvisioningVersion - (*ProvisioningUuid)(nil), // 1: signalservice.ProvisioningUuid - (*ProvisionEnvelope)(nil), // 2: signalservice.ProvisionEnvelope - (*ProvisionMessage)(nil), // 3: signalservice.ProvisionMessage + (ProvisioningVersion)(0), // 0: signalservice.ProvisioningVersion + (*ProvisioningAddress)(nil), // 1: signalservice.ProvisioningAddress + (*ProvisionEnvelope)(nil), // 2: signalservice.ProvisionEnvelope + (*ProvisionMessage)(nil), // 3: signalservice.ProvisionMessage } var file_Provisioning_proto_depIdxs = []int32{ 0, // [0:0] is the sub-list for method output_type diff --git a/pkg/signalmeow/protobuf/Provisioning.pb.raw b/pkg/signalmeow/protobuf/Provisioning.pb.raw index 385bc0221e1cce3935b116e6241b0b4d697c8df3..874538c7f1185b2aa7736feabcfdb3e4125f025d 100644 GIT binary patch delta 59 zcmdnOzL$N1ih(|ta6nOhS!Qu&eqLr?x?@U8QEG9qkOUWdB7`ZysKBVf83f~Q^v+}k E06uXNumAu6 delta 50 zcmdnXzJ+~)in Date: Mon, 2 Dec 2024 18:44:53 +0200 Subject: [PATCH 231/580] dependencies: update mautrix-go --- go.mod | 2 +- go.sum | 4 ++-- pkg/connector/client.go | 5 ++--- pkg/connector/login.go | 5 +---- 4 files changed, 6 insertions(+), 10 deletions(-) diff --git a/go.mod b/go.mod index af76c4d..5b56c84 100644 --- a/go.mod +++ b/go.mod @@ -18,7 +18,7 @@ require ( golang.org/x/exp v0.0.0-20241108190413-2d47ceb2692f golang.org/x/net v0.31.0 google.golang.org/protobuf v1.35.2 - maunium.net/go/mautrix v0.22.0 + maunium.net/go/mautrix v0.22.1-0.20241202131110-166ba04aae02 ) require ( diff --git a/go.sum b/go.sum index 69e3105..8df0f41 100644 --- a/go.sum +++ b/go.sum @@ -97,5 +97,5 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= maunium.net/go/mauflag v1.0.0 h1:YiaRc0tEI3toYtJMRIfjP+jklH45uDHtT80nUamyD4M= maunium.net/go/mauflag v1.0.0/go.mod h1:nLivPOpTpHnpzEh8jEdSL9UqO9+/KBJFmNRlwKfkPeA= -maunium.net/go/mautrix v0.22.0 h1:nLrnLYiMyFV6qZPqpkNogkOPgm2dQTYiQXlu9Nc3rz8= -maunium.net/go/mautrix v0.22.0/go.mod h1:oqwf9WYC/brqucM+heYk4gX11O59nP+ljvyxVhndFIM= +maunium.net/go/mautrix v0.22.1-0.20241202131110-166ba04aae02 h1:g8L4GpOhyg5EuXtASDKyU9Cg79ZjATlUnh+giFumQgc= +maunium.net/go/mautrix v0.22.1-0.20241202131110-166ba04aae02/go.mod h1:oqwf9WYC/brqucM+heYk4gX11O59nP+ljvyxVhndFIM= diff --git a/pkg/connector/client.go b/pkg/connector/client.go index ebd2def..8a8d415 100644 --- a/pkg/connector/client.go +++ b/pkg/connector/client.go @@ -219,14 +219,13 @@ func (s *SignalClient) bridgeStateLoop(statusChan <-chan signalmeow.SignalConnec } } -func (s *SignalClient) Connect(ctx context.Context) error { +func (s *SignalClient) Connect(ctx context.Context) { if s.Client == nil { s.UserLogin.BridgeState.Send(status.BridgeState{StateEvent: status.StateBadCredentials, Message: "You're not logged into Signal"}) - return nil + return } s.updateRemoteProfile(ctx, false) s.tryConnect(ctx, 0) - return nil } func (s *SignalClient) Disconnect() { diff --git a/pkg/connector/login.go b/pkg/connector/login.go index 5636339..525d14a 100644 --- a/pkg/connector/login.go +++ b/pkg/connector/login.go @@ -172,10 +172,7 @@ func (qr *QRLogin) processingWait(ctx context.Context) (*bridgev2.LoginStep, err return nil, fmt.Errorf("failed to create user login: %w", err) } backgroundCtx := ul.Log.WithContext(context.Background()) - err = ul.Client.Connect(backgroundCtx) - if err != nil { - return nil, fmt.Errorf("failed to connect after login: %w", err) - } + ul.Client.Connect(backgroundCtx) if signalClient := ul.Client.(*SignalClient).Client; signalClient.Store.MasterKey != nil { zerolog.Ctx(ctx).Info().Msg("Received master key in login, syncing storage immediately") go signalClient.SyncStorage(ctx) From 1f5fb4119fac45ec9da4c9821bbfd0a8bf2ca997 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Tue, 3 Dec 2024 17:44:34 +0200 Subject: [PATCH 232/580] signalmeow/receiving: log envelope timestamps when decrypting is successful --- pkg/signalmeow/receiving.go | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/pkg/signalmeow/receiving.go b/pkg/signalmeow/receiving.go index aa07431..b1dddea 100644 --- a/pkg/signalmeow/receiving.go +++ b/pkg/signalmeow/receiving.go @@ -659,7 +659,10 @@ func (cli *Client) handleDecryptedResult( Logger() log = &newLog ctx = log.WithContext(ctx) - log.Debug().Msg("Decrypted message") + log.Debug(). + Uint64("server_ts", envelope.GetServerTimestamp()). + Uint64("client_ts", envelope.GetTimestamp()). + Msg("Decrypted message") printContentFieldString(ctx, content, "Decrypted content fields") // If there's a sender key distribution message, process it From 66a5a5163035b5318eb720a89129c6034676f82d Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Tue, 10 Dec 2024 14:46:19 +0200 Subject: [PATCH 233/580] signalmeow: read receipt and typing settings from account record --- pkg/signalmeow/sending.go | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/pkg/signalmeow/sending.go b/pkg/signalmeow/sending.go index 902818d..b6a8a43 100644 --- a/pkg/signalmeow/sending.go +++ b/pkg/signalmeow/sending.go @@ -747,6 +747,16 @@ func (cli *Client) SendMessage(ctx context.Context, recipientID libsignalgo.Serv cli.sendSyncCopy(ctx, content, messageTimestamp, &res) } return SendMessageResult{WasSuccessful: true, SuccessfulSendResult: res} + } else if content.TypingMessage != nil && !cli.Store.DeviceData.AccountRecord.GetTypingIndicators() { + zerolog.Ctx(ctx).Debug().Msg("Not sending typing message as typing indicators are disabled") + res := SuccessfulSendResult{Recipient: recipientID} + return SendMessageResult{WasSuccessful: true, SuccessfulSendResult: res} + } else if content.GetReceiptMessage().GetType() == signalpb.ReceiptMessage_READ && !cli.Store.DeviceData.AccountRecord.GetReadReceipts() { + zerolog.Ctx(ctx).Debug().Msg("Not sending receipt message as read receipts are disabled") + res := SuccessfulSendResult{Recipient: recipientID} + // Still send sync messages for read receipts + cli.sendSyncCopy(ctx, content, messageTimestamp, &res) + return SendMessageResult{WasSuccessful: true, SuccessfulSendResult: res} } isDeliveryReceipt := content.ReceiptMessage != nil && content.GetReceiptMessage().GetType() == signalpb.ReceiptMessage_DELIVERY From e13fa634306d65773fe56a56a7c4d3deae134ab8 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Tue, 10 Dec 2024 14:50:54 +0200 Subject: [PATCH 234/580] libsignal: update to v0.64.1 --- pkg/libsignalgo/libsignal | 2 +- pkg/libsignalgo/libsignal-ffi.h | 12 ++++++++++-- pkg/libsignalgo/version.go | 2 +- 3 files changed, 12 insertions(+), 4 deletions(-) diff --git a/pkg/libsignalgo/libsignal b/pkg/libsignalgo/libsignal index 90ba453..4b78ebf 160000 --- a/pkg/libsignalgo/libsignal +++ b/pkg/libsignalgo/libsignal @@ -1 +1 @@ -Subproject commit 90ba45384073a467422d44783bc22a1152acd4c4 +Subproject commit 4b78ebfeeaec42e1f37c87ecb67b0e480b15f03a diff --git a/pkg/libsignalgo/libsignal-ffi.h b/pkg/libsignalgo/libsignal-ffi.h index 0af848b..b16aca6 100644 --- a/pkg/libsignalgo/libsignal-ffi.h +++ b/pkg/libsignalgo/libsignal-ffi.h @@ -256,6 +256,8 @@ typedef struct SignalMessageBackupKey SignalMessageBackupKey; typedef struct SignalMessageBackupValidationOutcome SignalMessageBackupValidationOutcome; +typedef struct SignalOnlineBackupValidator SignalOnlineBackupValidator; + typedef struct SignalPinHash SignalPinHash; typedef struct SignalPlaintextContent SignalPlaintextContent; @@ -1509,8 +1511,6 @@ SignalFfiError *signal_lookup_request_set_token(const SignalLookupRequest *reque SignalFfiError *signal_lookup_request_add_aci_and_access_key(const SignalLookupRequest *request, const SignalServiceIdFixedWidthBinaryBytes *aci, SignalBorrowedBuffer access_key); -SignalFfiError *signal_lookup_request_set_return_acis_without_uaks(const SignalLookupRequest *request, bool return_acis_without_uaks); - SignalFfiError *signal_cdsi_lookup_destroy(SignalCdsiLookup *p); SignalFfiError *signal_cdsi_lookup_new(SignalCPromiseCdsiLookup *promise, const SignalTokioAsyncContext *async_runtime, const SignalConnectionManager *connection_manager, const char *username, const char *password, const SignalLookupRequest *request); @@ -1639,6 +1639,14 @@ SignalFfiError *signal_message_backup_validation_outcome_get_unknown_fields(Sign SignalFfiError *signal_message_backup_validator_validate(SignalMessageBackupValidationOutcome **out, const SignalMessageBackupKey *key, const SignalInputStream *first_stream, const SignalInputStream *second_stream, uint64_t len, uint8_t purpose); +SignalFfiError *signal_online_backup_validator_destroy(SignalOnlineBackupValidator *p); + +SignalFfiError *signal_online_backup_validator_new(SignalOnlineBackupValidator **out, SignalBorrowedBuffer backup_info_frame, uint8_t purpose); + +SignalFfiError *signal_online_backup_validator_add_frame(SignalOnlineBackupValidator *backup, SignalBorrowedBuffer frame); + +SignalFfiError *signal_online_backup_validator_finalize(SignalOnlineBackupValidator *backup); + SignalFfiError *signal_username_hash(uint8_t (*out)[32], const char *username); SignalFfiError *signal_username_proof(SignalOwnedBuffer *out, const char *username, SignalBorrowedBuffer randomness); diff --git a/pkg/libsignalgo/version.go b/pkg/libsignalgo/version.go index 47fc072..5bcef1b 100644 --- a/pkg/libsignalgo/version.go +++ b/pkg/libsignalgo/version.go @@ -2,4 +2,4 @@ package libsignalgo -const Version = "v0.62.0" +const Version = "v0.64.1" From d17cd5f01ec5b0a3dbd1b7ae9c725da742c5f4c1 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Tue, 10 Dec 2024 14:51:43 +0200 Subject: [PATCH 235/580] docker: update to Alpine 3.21 --- Dockerfile | 4 ++-- Dockerfile.ci | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Dockerfile b/Dockerfile index 16c7d5b..a022666 100644 --- a/Dockerfile +++ b/Dockerfile @@ -11,7 +11,7 @@ ARG DBG=0 RUN ./build-rust.sh # -- Build mautrix-signal (with Go) -- -FROM golang:1-alpine3.20 AS go-builder +FROM golang:1-alpine3.21 AS go-builder RUN apk add --no-cache git ca-certificates build-base olm-dev WORKDIR /build @@ -39,7 +39,7 @@ EOF RUN ./build-go.sh # -- Run mautrix-signal -- -FROM alpine:3.20 +FROM alpine:3.21 ENV UID=1337 \ GID=1337 diff --git a/Dockerfile.ci b/Dockerfile.ci index e98ad03..556dfc1 100644 --- a/Dockerfile.ci +++ b/Dockerfile.ci @@ -1,4 +1,4 @@ -FROM alpine:3.20 +FROM alpine:3.21 ENV UID=1337 \ GID=1337 From 77edbf31df51fef24b904a2d765f7602e3f60a7f Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Tue, 10 Dec 2024 15:14:22 +0200 Subject: [PATCH 236/580] login: fix syncing storage after login --- pkg/connector/login.go | 2 +- pkg/signalmeow/sending.go | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/pkg/connector/login.go b/pkg/connector/login.go index 525d14a..da1b66a 100644 --- a/pkg/connector/login.go +++ b/pkg/connector/login.go @@ -175,7 +175,7 @@ func (qr *QRLogin) processingWait(ctx context.Context) (*bridgev2.LoginStep, err ul.Client.Connect(backgroundCtx) if signalClient := ul.Client.(*SignalClient).Client; signalClient.Store.MasterKey != nil { zerolog.Ctx(ctx).Info().Msg("Received master key in login, syncing storage immediately") - go signalClient.SyncStorage(ctx) + go signalClient.SyncStorage(backgroundCtx) } return &bridgev2.LoginStep{ Type: bridgev2.LoginStepTypeComplete, diff --git a/pkg/signalmeow/sending.go b/pkg/signalmeow/sending.go index b6a8a43..555cbc2 100644 --- a/pkg/signalmeow/sending.go +++ b/pkg/signalmeow/sending.go @@ -747,11 +747,11 @@ func (cli *Client) SendMessage(ctx context.Context, recipientID libsignalgo.Serv cli.sendSyncCopy(ctx, content, messageTimestamp, &res) } return SendMessageResult{WasSuccessful: true, SuccessfulSendResult: res} - } else if content.TypingMessage != nil && !cli.Store.DeviceData.AccountRecord.GetTypingIndicators() { + } else if content.TypingMessage != nil && cli.Store.DeviceData.AccountRecord != nil && !cli.Store.DeviceData.AccountRecord.GetTypingIndicators() { zerolog.Ctx(ctx).Debug().Msg("Not sending typing message as typing indicators are disabled") res := SuccessfulSendResult{Recipient: recipientID} return SendMessageResult{WasSuccessful: true, SuccessfulSendResult: res} - } else if content.GetReceiptMessage().GetType() == signalpb.ReceiptMessage_READ && !cli.Store.DeviceData.AccountRecord.GetReadReceipts() { + } else if content.GetReceiptMessage().GetType() == signalpb.ReceiptMessage_READ && cli.Store.DeviceData.AccountRecord != nil && !cli.Store.DeviceData.AccountRecord.GetReadReceipts() { zerolog.Ctx(ctx).Debug().Msg("Not sending receipt message as read receipts are disabled") res := SuccessfulSendResult{Recipient: recipientID} // Still send sync messages for read receipts From f8bde3991de27725f55e179dbe8ab3a17d547965 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Wed, 11 Dec 2024 19:57:03 +0200 Subject: [PATCH 237/580] signalmeow: update protobufs --- pkg/signalmeow/protobuf/Groups.pb.go | 8 + pkg/signalmeow/protobuf/Groups.pb.raw | Bin 7313 -> 7339 bytes pkg/signalmeow/protobuf/Groups.proto | 1 + pkg/signalmeow/protobuf/SignalService.pb.go | 275 +++++++++++-------- pkg/signalmeow/protobuf/SignalService.pb.raw | Bin 19227 -> 19370 bytes pkg/signalmeow/protobuf/SignalService.proto | 6 + pkg/signalmeow/protobuf/update-protos.sh | 4 +- 7 files changed, 182 insertions(+), 112 deletions(-) diff --git a/pkg/signalmeow/protobuf/Groups.pb.go b/pkg/signalmeow/protobuf/Groups.pb.go index b6d2280..de4a1ae 100644 --- a/pkg/signalmeow/protobuf/Groups.pb.go +++ b/pkg/signalmeow/protobuf/Groups.pb.go @@ -1230,6 +1230,7 @@ type GroupChange_Actions struct { unknownFields protoimpl.UnknownFields SourceServiceId []byte `protobuf:"bytes,1,opt,name=sourceServiceId,proto3" json:"sourceServiceId,omitempty"` + GroupId []byte `protobuf:"bytes,25,opt,name=groupId,proto3" json:"groupId,omitempty"` // Only set when receiving from server Revision uint32 `protobuf:"varint,2,opt,name=revision,proto3" json:"revision,omitempty"` AddMembers []*GroupChange_Actions_AddMemberAction `protobuf:"bytes,3,rep,name=addMembers,proto3" json:"addMembers,omitempty"` DeleteMembers []*GroupChange_Actions_DeleteMemberAction `protobuf:"bytes,4,rep,name=deleteMembers,proto3" json:"deleteMembers,omitempty"` @@ -1292,6 +1293,13 @@ func (x *GroupChange_Actions) GetSourceServiceId() []byte { return nil } +func (x *GroupChange_Actions) GetGroupId() []byte { + if x != nil { + return x.GroupId + } + return nil +} + func (x *GroupChange_Actions) GetRevision() uint32 { if x != nil { return x.Revision diff --git a/pkg/signalmeow/protobuf/Groups.pb.raw b/pkg/signalmeow/protobuf/Groups.pb.raw index 7549d560184e776c7a26830944fac136320946a9..dceda274eece491e05fbb427b8eb4b191fdc755d 100644 GIT binary patch delta 48 zcmbPex!Q6=F&pEv$t7&1j2|YyVlx$&;9^fN$}cVOOp%aOVAS9Vf^av>u$PJg0G=cd AZ~y=R delta 24 gcmZ2&Ini=MF&pEV$t7&1jMpZ=Vl&-r$zCK10D58xFaQ7m diff --git a/pkg/signalmeow/protobuf/Groups.proto b/pkg/signalmeow/protobuf/Groups.proto index 63970c7..e202eb2 100644 --- a/pkg/signalmeow/protobuf/Groups.proto +++ b/pkg/signalmeow/protobuf/Groups.proto @@ -183,6 +183,7 @@ message GroupChange { } bytes sourceServiceId = 1; + bytes groupId = 25; // Only set when receiving from server uint32 revision = 2; repeated AddMemberAction addMembers = 3; repeated DeleteMemberAction deleteMembers = 4; diff --git a/pkg/signalmeow/protobuf/SignalService.pb.go b/pkg/signalmeow/protobuf/SignalService.pb.go index a8686db..a633e85 100644 --- a/pkg/signalmeow/protobuf/SignalService.pb.go +++ b/pkg/signalmeow/protobuf/SignalService.pb.go @@ -2907,6 +2907,7 @@ type SyncMessage struct { CallLinkUpdate *SyncMessage_CallLinkUpdate `protobuf:"bytes,20,opt,name=callLinkUpdate" json:"callLinkUpdate,omitempty"` CallLogEvent *SyncMessage_CallLogEvent `protobuf:"bytes,21,opt,name=callLogEvent" json:"callLogEvent,omitempty"` DeleteForMe *SyncMessage_DeleteForMe `protobuf:"bytes,22,opt,name=deleteForMe" json:"deleteForMe,omitempty"` + DeviceNameChange *SyncMessage_DeviceNameChange `protobuf:"bytes,23,opt,name=deviceNameChange" json:"deviceNameChange,omitempty"` } func (x *SyncMessage) Reset() { @@ -3079,6 +3080,13 @@ func (x *SyncMessage) GetDeleteForMe() *SyncMessage_DeleteForMe { return nil } +func (x *SyncMessage) GetDeviceNameChange() *SyncMessage_DeviceNameChange { + if x != nil { + return x.DeviceNameChange + } + return nil +} + type AttachmentPointer struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -6816,6 +6824,51 @@ func (x *SyncMessage_DeleteForMe) GetAttachmentDeletes() []*SyncMessage_DeleteFo return nil } +type SyncMessage_DeviceNameChange struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + DeviceId *uint32 `protobuf:"varint,2,opt,name=deviceId" json:"deviceId,omitempty"` +} + +func (x *SyncMessage_DeviceNameChange) Reset() { + *x = SyncMessage_DeviceNameChange{} + mi := &file_SignalService_proto_msgTypes[67] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *SyncMessage_DeviceNameChange) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SyncMessage_DeviceNameChange) ProtoMessage() {} + +func (x *SyncMessage_DeviceNameChange) ProtoReflect() protoreflect.Message { + mi := &file_SignalService_proto_msgTypes[67] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use SyncMessage_DeviceNameChange.ProtoReflect.Descriptor instead. +func (*SyncMessage_DeviceNameChange) Descriptor() ([]byte, []int) { + return file_SignalService_proto_rawDescGZIP(), []int{12, 18} +} + +func (x *SyncMessage_DeviceNameChange) GetDeviceId() uint32 { + if x != nil && x.DeviceId != nil { + return *x.DeviceId + } + return 0 +} + type SyncMessage_Sent_UnidentifiedDeliveryStatus struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -6828,7 +6881,7 @@ type SyncMessage_Sent_UnidentifiedDeliveryStatus struct { func (x *SyncMessage_Sent_UnidentifiedDeliveryStatus) Reset() { *x = SyncMessage_Sent_UnidentifiedDeliveryStatus{} - mi := &file_SignalService_proto_msgTypes[67] + mi := &file_SignalService_proto_msgTypes[68] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6840,7 +6893,7 @@ func (x *SyncMessage_Sent_UnidentifiedDeliveryStatus) String() string { func (*SyncMessage_Sent_UnidentifiedDeliveryStatus) ProtoMessage() {} func (x *SyncMessage_Sent_UnidentifiedDeliveryStatus) ProtoReflect() protoreflect.Message { - mi := &file_SignalService_proto_msgTypes[67] + mi := &file_SignalService_proto_msgTypes[68] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6889,7 +6942,7 @@ type SyncMessage_Sent_StoryMessageRecipient struct { func (x *SyncMessage_Sent_StoryMessageRecipient) Reset() { *x = SyncMessage_Sent_StoryMessageRecipient{} - mi := &file_SignalService_proto_msgTypes[68] + mi := &file_SignalService_proto_msgTypes[69] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6901,7 +6954,7 @@ func (x *SyncMessage_Sent_StoryMessageRecipient) String() string { func (*SyncMessage_Sent_StoryMessageRecipient) ProtoMessage() {} func (x *SyncMessage_Sent_StoryMessageRecipient) ProtoReflect() protoreflect.Message { - mi := &file_SignalService_proto_msgTypes[68] + mi := &file_SignalService_proto_msgTypes[69] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6958,7 +7011,7 @@ type SyncMessage_OutgoingPayment_MobileCoin struct { func (x *SyncMessage_OutgoingPayment_MobileCoin) Reset() { *x = SyncMessage_OutgoingPayment_MobileCoin{} - mi := &file_SignalService_proto_msgTypes[69] + mi := &file_SignalService_proto_msgTypes[70] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6970,7 +7023,7 @@ func (x *SyncMessage_OutgoingPayment_MobileCoin) String() string { func (*SyncMessage_OutgoingPayment_MobileCoin) ProtoMessage() {} func (x *SyncMessage_OutgoingPayment_MobileCoin) ProtoReflect() protoreflect.Message { - mi := &file_SignalService_proto_msgTypes[69] + mi := &file_SignalService_proto_msgTypes[70] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7057,7 +7110,7 @@ type SyncMessage_DeleteForMe_ConversationIdentifier struct { func (x *SyncMessage_DeleteForMe_ConversationIdentifier) Reset() { *x = SyncMessage_DeleteForMe_ConversationIdentifier{} - mi := &file_SignalService_proto_msgTypes[70] + mi := &file_SignalService_proto_msgTypes[71] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7069,7 +7122,7 @@ func (x *SyncMessage_DeleteForMe_ConversationIdentifier) String() string { func (*SyncMessage_DeleteForMe_ConversationIdentifier) ProtoMessage() {} func (x *SyncMessage_DeleteForMe_ConversationIdentifier) ProtoReflect() protoreflect.Message { - mi := &file_SignalService_proto_msgTypes[70] + mi := &file_SignalService_proto_msgTypes[71] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7153,7 +7206,7 @@ type SyncMessage_DeleteForMe_AddressableMessage struct { func (x *SyncMessage_DeleteForMe_AddressableMessage) Reset() { *x = SyncMessage_DeleteForMe_AddressableMessage{} - mi := &file_SignalService_proto_msgTypes[71] + mi := &file_SignalService_proto_msgTypes[72] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7165,7 +7218,7 @@ func (x *SyncMessage_DeleteForMe_AddressableMessage) String() string { func (*SyncMessage_DeleteForMe_AddressableMessage) ProtoMessage() {} func (x *SyncMessage_DeleteForMe_AddressableMessage) ProtoReflect() protoreflect.Message { - mi := &file_SignalService_proto_msgTypes[71] + mi := &file_SignalService_proto_msgTypes[72] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7238,7 +7291,7 @@ type SyncMessage_DeleteForMe_MessageDeletes struct { func (x *SyncMessage_DeleteForMe_MessageDeletes) Reset() { *x = SyncMessage_DeleteForMe_MessageDeletes{} - mi := &file_SignalService_proto_msgTypes[72] + mi := &file_SignalService_proto_msgTypes[73] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7250,7 +7303,7 @@ func (x *SyncMessage_DeleteForMe_MessageDeletes) String() string { func (*SyncMessage_DeleteForMe_MessageDeletes) ProtoMessage() {} func (x *SyncMessage_DeleteForMe_MessageDeletes) ProtoReflect() protoreflect.Message { - mi := &file_SignalService_proto_msgTypes[72] + mi := &file_SignalService_proto_msgTypes[73] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7294,7 +7347,7 @@ type SyncMessage_DeleteForMe_AttachmentDelete struct { func (x *SyncMessage_DeleteForMe_AttachmentDelete) Reset() { *x = SyncMessage_DeleteForMe_AttachmentDelete{} - mi := &file_SignalService_proto_msgTypes[73] + mi := &file_SignalService_proto_msgTypes[74] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7306,7 +7359,7 @@ func (x *SyncMessage_DeleteForMe_AttachmentDelete) String() string { func (*SyncMessage_DeleteForMe_AttachmentDelete) ProtoMessage() {} func (x *SyncMessage_DeleteForMe_AttachmentDelete) ProtoReflect() protoreflect.Message { - mi := &file_SignalService_proto_msgTypes[73] + mi := &file_SignalService_proto_msgTypes[74] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7370,7 +7423,7 @@ type SyncMessage_DeleteForMe_ConversationDelete struct { func (x *SyncMessage_DeleteForMe_ConversationDelete) Reset() { *x = SyncMessage_DeleteForMe_ConversationDelete{} - mi := &file_SignalService_proto_msgTypes[74] + mi := &file_SignalService_proto_msgTypes[75] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7382,7 +7435,7 @@ func (x *SyncMessage_DeleteForMe_ConversationDelete) String() string { func (*SyncMessage_DeleteForMe_ConversationDelete) ProtoMessage() {} func (x *SyncMessage_DeleteForMe_ConversationDelete) ProtoReflect() protoreflect.Message { - mi := &file_SignalService_proto_msgTypes[74] + mi := &file_SignalService_proto_msgTypes[75] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7436,7 +7489,7 @@ type SyncMessage_DeleteForMe_LocalOnlyConversationDelete struct { func (x *SyncMessage_DeleteForMe_LocalOnlyConversationDelete) Reset() { *x = SyncMessage_DeleteForMe_LocalOnlyConversationDelete{} - mi := &file_SignalService_proto_msgTypes[75] + mi := &file_SignalService_proto_msgTypes[76] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7448,7 +7501,7 @@ func (x *SyncMessage_DeleteForMe_LocalOnlyConversationDelete) String() string { func (*SyncMessage_DeleteForMe_LocalOnlyConversationDelete) ProtoMessage() {} func (x *SyncMessage_DeleteForMe_LocalOnlyConversationDelete) ProtoReflect() protoreflect.Message { - mi := &file_SignalService_proto_msgTypes[75] + mi := &file_SignalService_proto_msgTypes[76] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7481,7 +7534,7 @@ type GroupContext_Member struct { func (x *GroupContext_Member) Reset() { *x = GroupContext_Member{} - mi := &file_SignalService_proto_msgTypes[76] + mi := &file_SignalService_proto_msgTypes[77] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7493,7 +7546,7 @@ func (x *GroupContext_Member) String() string { func (*GroupContext_Member) ProtoMessage() {} func (x *GroupContext_Member) ProtoReflect() protoreflect.Message { - mi := &file_SignalService_proto_msgTypes[76] + mi := &file_SignalService_proto_msgTypes[77] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7527,7 +7580,7 @@ type ContactDetails_Avatar struct { func (x *ContactDetails_Avatar) Reset() { *x = ContactDetails_Avatar{} - mi := &file_SignalService_proto_msgTypes[77] + mi := &file_SignalService_proto_msgTypes[78] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7539,7 +7592,7 @@ func (x *ContactDetails_Avatar) String() string { func (*ContactDetails_Avatar) ProtoMessage() {} func (x *ContactDetails_Avatar) ProtoReflect() protoreflect.Message { - mi := &file_SignalService_proto_msgTypes[77] + mi := &file_SignalService_proto_msgTypes[78] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7580,7 +7633,7 @@ type GroupDetails_Avatar struct { func (x *GroupDetails_Avatar) Reset() { *x = GroupDetails_Avatar{} - mi := &file_SignalService_proto_msgTypes[78] + mi := &file_SignalService_proto_msgTypes[79] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7592,7 +7645,7 @@ func (x *GroupDetails_Avatar) String() string { func (*GroupDetails_Avatar) ProtoMessage() {} func (x *GroupDetails_Avatar) ProtoReflect() protoreflect.Message { - mi := &file_SignalService_proto_msgTypes[78] + mi := &file_SignalService_proto_msgTypes[79] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7632,7 +7685,7 @@ type GroupDetails_Member struct { func (x *GroupDetails_Member) Reset() { *x = GroupDetails_Member{} - mi := &file_SignalService_proto_msgTypes[79] + mi := &file_SignalService_proto_msgTypes[80] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7644,7 +7697,7 @@ func (x *GroupDetails_Member) String() string { func (*GroupDetails_Member) ProtoMessage() {} func (x *GroupDetails_Member) ProtoReflect() protoreflect.Message { - mi := &file_SignalService_proto_msgTypes[79] + mi := &file_SignalService_proto_msgTypes[80] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7678,7 +7731,7 @@ type PaymentAddress_MobileCoinAddress struct { func (x *PaymentAddress_MobileCoinAddress) Reset() { *x = PaymentAddress_MobileCoinAddress{} - mi := &file_SignalService_proto_msgTypes[80] + mi := &file_SignalService_proto_msgTypes[81] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7690,7 +7743,7 @@ func (x *PaymentAddress_MobileCoinAddress) String() string { func (*PaymentAddress_MobileCoinAddress) ProtoMessage() {} func (x *PaymentAddress_MobileCoinAddress) ProtoReflect() protoreflect.Message { - mi := &file_SignalService_proto_msgTypes[80] + mi := &file_SignalService_proto_msgTypes[81] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7738,7 +7791,7 @@ func file_SignalService_proto_rawDescGZIP() []byte { } var file_SignalService_proto_enumTypes = make([]protoimpl.EnumInfo, 27) -var file_SignalService_proto_msgTypes = make([]protoimpl.MessageInfo, 81) +var file_SignalService_proto_msgTypes = make([]protoimpl.MessageInfo, 82) var file_SignalService_proto_goTypes = []any{ (Envelope_Type)(0), // 0: signalservice.Envelope.Type (CallMessage_Offer_Type)(0), // 1: signalservice.CallMessage.Offer.Type @@ -7834,20 +7887,21 @@ var file_SignalService_proto_goTypes = []any{ (*SyncMessage_CallLinkUpdate)(nil), // 91: signalservice.SyncMessage.CallLinkUpdate (*SyncMessage_CallLogEvent)(nil), // 92: signalservice.SyncMessage.CallLogEvent (*SyncMessage_DeleteForMe)(nil), // 93: signalservice.SyncMessage.DeleteForMe - (*SyncMessage_Sent_UnidentifiedDeliveryStatus)(nil), // 94: signalservice.SyncMessage.Sent.UnidentifiedDeliveryStatus - (*SyncMessage_Sent_StoryMessageRecipient)(nil), // 95: signalservice.SyncMessage.Sent.StoryMessageRecipient - (*SyncMessage_OutgoingPayment_MobileCoin)(nil), // 96: signalservice.SyncMessage.OutgoingPayment.MobileCoin - (*SyncMessage_DeleteForMe_ConversationIdentifier)(nil), // 97: signalservice.SyncMessage.DeleteForMe.ConversationIdentifier - (*SyncMessage_DeleteForMe_AddressableMessage)(nil), // 98: signalservice.SyncMessage.DeleteForMe.AddressableMessage - (*SyncMessage_DeleteForMe_MessageDeletes)(nil), // 99: signalservice.SyncMessage.DeleteForMe.MessageDeletes - (*SyncMessage_DeleteForMe_AttachmentDelete)(nil), // 100: signalservice.SyncMessage.DeleteForMe.AttachmentDelete - (*SyncMessage_DeleteForMe_ConversationDelete)(nil), // 101: signalservice.SyncMessage.DeleteForMe.ConversationDelete - (*SyncMessage_DeleteForMe_LocalOnlyConversationDelete)(nil), // 102: signalservice.SyncMessage.DeleteForMe.LocalOnlyConversationDelete - (*GroupContext_Member)(nil), // 103: signalservice.GroupContext.Member - (*ContactDetails_Avatar)(nil), // 104: signalservice.ContactDetails.Avatar - (*GroupDetails_Avatar)(nil), // 105: signalservice.GroupDetails.Avatar - (*GroupDetails_Member)(nil), // 106: signalservice.GroupDetails.Member - (*PaymentAddress_MobileCoinAddress)(nil), // 107: signalservice.PaymentAddress.MobileCoinAddress + (*SyncMessage_DeviceNameChange)(nil), // 94: signalservice.SyncMessage.DeviceNameChange + (*SyncMessage_Sent_UnidentifiedDeliveryStatus)(nil), // 95: signalservice.SyncMessage.Sent.UnidentifiedDeliveryStatus + (*SyncMessage_Sent_StoryMessageRecipient)(nil), // 96: signalservice.SyncMessage.Sent.StoryMessageRecipient + (*SyncMessage_OutgoingPayment_MobileCoin)(nil), // 97: signalservice.SyncMessage.OutgoingPayment.MobileCoin + (*SyncMessage_DeleteForMe_ConversationIdentifier)(nil), // 98: signalservice.SyncMessage.DeleteForMe.ConversationIdentifier + (*SyncMessage_DeleteForMe_AddressableMessage)(nil), // 99: signalservice.SyncMessage.DeleteForMe.AddressableMessage + (*SyncMessage_DeleteForMe_MessageDeletes)(nil), // 100: signalservice.SyncMessage.DeleteForMe.MessageDeletes + (*SyncMessage_DeleteForMe_AttachmentDelete)(nil), // 101: signalservice.SyncMessage.DeleteForMe.AttachmentDelete + (*SyncMessage_DeleteForMe_ConversationDelete)(nil), // 102: signalservice.SyncMessage.DeleteForMe.ConversationDelete + (*SyncMessage_DeleteForMe_LocalOnlyConversationDelete)(nil), // 103: signalservice.SyncMessage.DeleteForMe.LocalOnlyConversationDelete + (*GroupContext_Member)(nil), // 104: signalservice.GroupContext.Member + (*ContactDetails_Avatar)(nil), // 105: signalservice.ContactDetails.Avatar + (*GroupDetails_Avatar)(nil), // 106: signalservice.GroupDetails.Avatar + (*GroupDetails_Member)(nil), // 107: signalservice.GroupDetails.Member + (*PaymentAddress_MobileCoinAddress)(nil), // 108: signalservice.PaymentAddress.MobileCoinAddress } var file_SignalService_proto_depIdxs = []int32{ 0, // 0: signalservice.Envelope.type:type_name -> signalservice.Envelope.Type @@ -7910,70 +7964,71 @@ var file_SignalService_proto_depIdxs = []int32{ 91, // 57: signalservice.SyncMessage.callLinkUpdate:type_name -> signalservice.SyncMessage.CallLinkUpdate 92, // 58: signalservice.SyncMessage.callLogEvent:type_name -> signalservice.SyncMessage.CallLogEvent 93, // 59: signalservice.SyncMessage.deleteForMe:type_name -> signalservice.SyncMessage.DeleteForMe - 26, // 60: signalservice.GroupContext.type:type_name -> signalservice.GroupContext.Type - 103, // 61: signalservice.GroupContext.members:type_name -> signalservice.GroupContext.Member - 40, // 62: signalservice.GroupContext.avatar:type_name -> signalservice.AttachmentPointer - 104, // 63: signalservice.ContactDetails.avatar:type_name -> signalservice.ContactDetails.Avatar - 38, // 64: signalservice.ContactDetails.verified:type_name -> signalservice.Verified - 106, // 65: signalservice.GroupDetails.members:type_name -> signalservice.GroupDetails.Member - 105, // 66: signalservice.GroupDetails.avatar:type_name -> signalservice.GroupDetails.Avatar - 107, // 67: signalservice.PaymentAddress.mobileCoinAddress:type_name -> signalservice.PaymentAddress.MobileCoinAddress - 31, // 68: signalservice.EditMessage.dataMessage:type_name -> signalservice.DataMessage - 1, // 69: signalservice.CallMessage.Offer.type:type_name -> signalservice.CallMessage.Offer.Type - 2, // 70: signalservice.CallMessage.Hangup.type:type_name -> signalservice.CallMessage.Hangup.Type - 3, // 71: signalservice.CallMessage.Opaque.urgency:type_name -> signalservice.CallMessage.Opaque.Urgency - 64, // 72: signalservice.DataMessage.Quote.attachments:type_name -> signalservice.DataMessage.Quote.QuotedAttachment - 30, // 73: signalservice.DataMessage.Quote.bodyRanges:type_name -> signalservice.BodyRange - 7, // 74: signalservice.DataMessage.Quote.type:type_name -> signalservice.DataMessage.Quote.Type - 65, // 75: signalservice.DataMessage.Contact.name:type_name -> signalservice.DataMessage.Contact.Name - 66, // 76: signalservice.DataMessage.Contact.number:type_name -> signalservice.DataMessage.Contact.Phone - 67, // 77: signalservice.DataMessage.Contact.email:type_name -> signalservice.DataMessage.Contact.Email - 68, // 78: signalservice.DataMessage.Contact.address:type_name -> signalservice.DataMessage.Contact.PostalAddress - 69, // 79: signalservice.DataMessage.Contact.avatar:type_name -> signalservice.DataMessage.Contact.Avatar - 40, // 80: signalservice.DataMessage.Sticker.data:type_name -> signalservice.AttachmentPointer - 71, // 81: signalservice.DataMessage.Payment.notification:type_name -> signalservice.DataMessage.Payment.Notification - 72, // 82: signalservice.DataMessage.Payment.activation:type_name -> signalservice.DataMessage.Payment.Activation - 40, // 83: signalservice.DataMessage.Quote.QuotedAttachment.thumbnail:type_name -> signalservice.AttachmentPointer - 8, // 84: signalservice.DataMessage.Contact.Phone.type:type_name -> signalservice.DataMessage.Contact.Phone.Type - 9, // 85: signalservice.DataMessage.Contact.Email.type:type_name -> signalservice.DataMessage.Contact.Email.Type - 10, // 86: signalservice.DataMessage.Contact.PostalAddress.type:type_name -> signalservice.DataMessage.Contact.PostalAddress.Type - 40, // 87: signalservice.DataMessage.Contact.Avatar.avatar:type_name -> signalservice.AttachmentPointer - 73, // 88: signalservice.DataMessage.Payment.Amount.mobileCoin:type_name -> signalservice.DataMessage.Payment.Amount.MobileCoin - 74, // 89: signalservice.DataMessage.Payment.Notification.mobileCoin:type_name -> signalservice.DataMessage.Payment.Notification.MobileCoin - 11, // 90: signalservice.DataMessage.Payment.Activation.type:type_name -> signalservice.DataMessage.Payment.Activation.Type - 31, // 91: signalservice.SyncMessage.Sent.message:type_name -> signalservice.DataMessage - 94, // 92: signalservice.SyncMessage.Sent.unidentifiedStatus:type_name -> signalservice.SyncMessage.Sent.UnidentifiedDeliveryStatus - 35, // 93: signalservice.SyncMessage.Sent.storyMessage:type_name -> signalservice.StoryMessage - 95, // 94: signalservice.SyncMessage.Sent.storyMessageRecipients:type_name -> signalservice.SyncMessage.Sent.StoryMessageRecipient - 48, // 95: signalservice.SyncMessage.Sent.editMessage:type_name -> signalservice.EditMessage - 40, // 96: signalservice.SyncMessage.Contacts.blob:type_name -> signalservice.AttachmentPointer - 16, // 97: signalservice.SyncMessage.Request.type:type_name -> signalservice.SyncMessage.Request.Type - 17, // 98: signalservice.SyncMessage.StickerPackOperation.type:type_name -> signalservice.SyncMessage.StickerPackOperation.Type - 18, // 99: signalservice.SyncMessage.FetchLatest.type:type_name -> signalservice.SyncMessage.FetchLatest.Type - 19, // 100: signalservice.SyncMessage.MessageRequestResponse.type:type_name -> signalservice.SyncMessage.MessageRequestResponse.Type - 96, // 101: signalservice.SyncMessage.OutgoingPayment.mobileCoin:type_name -> signalservice.SyncMessage.OutgoingPayment.MobileCoin - 20, // 102: signalservice.SyncMessage.CallEvent.type:type_name -> signalservice.SyncMessage.CallEvent.Type - 21, // 103: signalservice.SyncMessage.CallEvent.direction:type_name -> signalservice.SyncMessage.CallEvent.Direction - 22, // 104: signalservice.SyncMessage.CallEvent.event:type_name -> signalservice.SyncMessage.CallEvent.Event - 23, // 105: signalservice.SyncMessage.CallLinkUpdate.type:type_name -> signalservice.SyncMessage.CallLinkUpdate.Type - 24, // 106: signalservice.SyncMessage.CallLogEvent.type:type_name -> signalservice.SyncMessage.CallLogEvent.Type - 99, // 107: signalservice.SyncMessage.DeleteForMe.messageDeletes:type_name -> signalservice.SyncMessage.DeleteForMe.MessageDeletes - 101, // 108: signalservice.SyncMessage.DeleteForMe.conversationDeletes:type_name -> signalservice.SyncMessage.DeleteForMe.ConversationDelete - 102, // 109: signalservice.SyncMessage.DeleteForMe.localOnlyConversationDeletes:type_name -> signalservice.SyncMessage.DeleteForMe.LocalOnlyConversationDelete - 100, // 110: signalservice.SyncMessage.DeleteForMe.attachmentDeletes:type_name -> signalservice.SyncMessage.DeleteForMe.AttachmentDelete - 97, // 111: signalservice.SyncMessage.DeleteForMe.MessageDeletes.conversation:type_name -> signalservice.SyncMessage.DeleteForMe.ConversationIdentifier - 98, // 112: signalservice.SyncMessage.DeleteForMe.MessageDeletes.messages:type_name -> signalservice.SyncMessage.DeleteForMe.AddressableMessage - 97, // 113: signalservice.SyncMessage.DeleteForMe.AttachmentDelete.conversation:type_name -> signalservice.SyncMessage.DeleteForMe.ConversationIdentifier - 98, // 114: signalservice.SyncMessage.DeleteForMe.AttachmentDelete.targetMessage:type_name -> signalservice.SyncMessage.DeleteForMe.AddressableMessage - 97, // 115: signalservice.SyncMessage.DeleteForMe.ConversationDelete.conversation:type_name -> signalservice.SyncMessage.DeleteForMe.ConversationIdentifier - 98, // 116: signalservice.SyncMessage.DeleteForMe.ConversationDelete.mostRecentMessages:type_name -> signalservice.SyncMessage.DeleteForMe.AddressableMessage - 98, // 117: signalservice.SyncMessage.DeleteForMe.ConversationDelete.mostRecentNonExpiringMessages:type_name -> signalservice.SyncMessage.DeleteForMe.AddressableMessage - 97, // 118: signalservice.SyncMessage.DeleteForMe.LocalOnlyConversationDelete.conversation:type_name -> signalservice.SyncMessage.DeleteForMe.ConversationIdentifier - 119, // [119:119] is the sub-list for method output_type - 119, // [119:119] is the sub-list for method input_type - 119, // [119:119] is the sub-list for extension type_name - 119, // [119:119] is the sub-list for extension extendee - 0, // [0:119] is the sub-list for field type_name + 94, // 60: signalservice.SyncMessage.deviceNameChange:type_name -> signalservice.SyncMessage.DeviceNameChange + 26, // 61: signalservice.GroupContext.type:type_name -> signalservice.GroupContext.Type + 104, // 62: signalservice.GroupContext.members:type_name -> signalservice.GroupContext.Member + 40, // 63: signalservice.GroupContext.avatar:type_name -> signalservice.AttachmentPointer + 105, // 64: signalservice.ContactDetails.avatar:type_name -> signalservice.ContactDetails.Avatar + 38, // 65: signalservice.ContactDetails.verified:type_name -> signalservice.Verified + 107, // 66: signalservice.GroupDetails.members:type_name -> signalservice.GroupDetails.Member + 106, // 67: signalservice.GroupDetails.avatar:type_name -> signalservice.GroupDetails.Avatar + 108, // 68: signalservice.PaymentAddress.mobileCoinAddress:type_name -> signalservice.PaymentAddress.MobileCoinAddress + 31, // 69: signalservice.EditMessage.dataMessage:type_name -> signalservice.DataMessage + 1, // 70: signalservice.CallMessage.Offer.type:type_name -> signalservice.CallMessage.Offer.Type + 2, // 71: signalservice.CallMessage.Hangup.type:type_name -> signalservice.CallMessage.Hangup.Type + 3, // 72: signalservice.CallMessage.Opaque.urgency:type_name -> signalservice.CallMessage.Opaque.Urgency + 64, // 73: signalservice.DataMessage.Quote.attachments:type_name -> signalservice.DataMessage.Quote.QuotedAttachment + 30, // 74: signalservice.DataMessage.Quote.bodyRanges:type_name -> signalservice.BodyRange + 7, // 75: signalservice.DataMessage.Quote.type:type_name -> signalservice.DataMessage.Quote.Type + 65, // 76: signalservice.DataMessage.Contact.name:type_name -> signalservice.DataMessage.Contact.Name + 66, // 77: signalservice.DataMessage.Contact.number:type_name -> signalservice.DataMessage.Contact.Phone + 67, // 78: signalservice.DataMessage.Contact.email:type_name -> signalservice.DataMessage.Contact.Email + 68, // 79: signalservice.DataMessage.Contact.address:type_name -> signalservice.DataMessage.Contact.PostalAddress + 69, // 80: signalservice.DataMessage.Contact.avatar:type_name -> signalservice.DataMessage.Contact.Avatar + 40, // 81: signalservice.DataMessage.Sticker.data:type_name -> signalservice.AttachmentPointer + 71, // 82: signalservice.DataMessage.Payment.notification:type_name -> signalservice.DataMessage.Payment.Notification + 72, // 83: signalservice.DataMessage.Payment.activation:type_name -> signalservice.DataMessage.Payment.Activation + 40, // 84: signalservice.DataMessage.Quote.QuotedAttachment.thumbnail:type_name -> signalservice.AttachmentPointer + 8, // 85: signalservice.DataMessage.Contact.Phone.type:type_name -> signalservice.DataMessage.Contact.Phone.Type + 9, // 86: signalservice.DataMessage.Contact.Email.type:type_name -> signalservice.DataMessage.Contact.Email.Type + 10, // 87: signalservice.DataMessage.Contact.PostalAddress.type:type_name -> signalservice.DataMessage.Contact.PostalAddress.Type + 40, // 88: signalservice.DataMessage.Contact.Avatar.avatar:type_name -> signalservice.AttachmentPointer + 73, // 89: signalservice.DataMessage.Payment.Amount.mobileCoin:type_name -> signalservice.DataMessage.Payment.Amount.MobileCoin + 74, // 90: signalservice.DataMessage.Payment.Notification.mobileCoin:type_name -> signalservice.DataMessage.Payment.Notification.MobileCoin + 11, // 91: signalservice.DataMessage.Payment.Activation.type:type_name -> signalservice.DataMessage.Payment.Activation.Type + 31, // 92: signalservice.SyncMessage.Sent.message:type_name -> signalservice.DataMessage + 95, // 93: signalservice.SyncMessage.Sent.unidentifiedStatus:type_name -> signalservice.SyncMessage.Sent.UnidentifiedDeliveryStatus + 35, // 94: signalservice.SyncMessage.Sent.storyMessage:type_name -> signalservice.StoryMessage + 96, // 95: signalservice.SyncMessage.Sent.storyMessageRecipients:type_name -> signalservice.SyncMessage.Sent.StoryMessageRecipient + 48, // 96: signalservice.SyncMessage.Sent.editMessage:type_name -> signalservice.EditMessage + 40, // 97: signalservice.SyncMessage.Contacts.blob:type_name -> signalservice.AttachmentPointer + 16, // 98: signalservice.SyncMessage.Request.type:type_name -> signalservice.SyncMessage.Request.Type + 17, // 99: signalservice.SyncMessage.StickerPackOperation.type:type_name -> signalservice.SyncMessage.StickerPackOperation.Type + 18, // 100: signalservice.SyncMessage.FetchLatest.type:type_name -> signalservice.SyncMessage.FetchLatest.Type + 19, // 101: signalservice.SyncMessage.MessageRequestResponse.type:type_name -> signalservice.SyncMessage.MessageRequestResponse.Type + 97, // 102: signalservice.SyncMessage.OutgoingPayment.mobileCoin:type_name -> signalservice.SyncMessage.OutgoingPayment.MobileCoin + 20, // 103: signalservice.SyncMessage.CallEvent.type:type_name -> signalservice.SyncMessage.CallEvent.Type + 21, // 104: signalservice.SyncMessage.CallEvent.direction:type_name -> signalservice.SyncMessage.CallEvent.Direction + 22, // 105: signalservice.SyncMessage.CallEvent.event:type_name -> signalservice.SyncMessage.CallEvent.Event + 23, // 106: signalservice.SyncMessage.CallLinkUpdate.type:type_name -> signalservice.SyncMessage.CallLinkUpdate.Type + 24, // 107: signalservice.SyncMessage.CallLogEvent.type:type_name -> signalservice.SyncMessage.CallLogEvent.Type + 100, // 108: signalservice.SyncMessage.DeleteForMe.messageDeletes:type_name -> signalservice.SyncMessage.DeleteForMe.MessageDeletes + 102, // 109: signalservice.SyncMessage.DeleteForMe.conversationDeletes:type_name -> signalservice.SyncMessage.DeleteForMe.ConversationDelete + 103, // 110: signalservice.SyncMessage.DeleteForMe.localOnlyConversationDeletes:type_name -> signalservice.SyncMessage.DeleteForMe.LocalOnlyConversationDelete + 101, // 111: signalservice.SyncMessage.DeleteForMe.attachmentDeletes:type_name -> signalservice.SyncMessage.DeleteForMe.AttachmentDelete + 98, // 112: signalservice.SyncMessage.DeleteForMe.MessageDeletes.conversation:type_name -> signalservice.SyncMessage.DeleteForMe.ConversationIdentifier + 99, // 113: signalservice.SyncMessage.DeleteForMe.MessageDeletes.messages:type_name -> signalservice.SyncMessage.DeleteForMe.AddressableMessage + 98, // 114: signalservice.SyncMessage.DeleteForMe.AttachmentDelete.conversation:type_name -> signalservice.SyncMessage.DeleteForMe.ConversationIdentifier + 99, // 115: signalservice.SyncMessage.DeleteForMe.AttachmentDelete.targetMessage:type_name -> signalservice.SyncMessage.DeleteForMe.AddressableMessage + 98, // 116: signalservice.SyncMessage.DeleteForMe.ConversationDelete.conversation:type_name -> signalservice.SyncMessage.DeleteForMe.ConversationIdentifier + 99, // 117: signalservice.SyncMessage.DeleteForMe.ConversationDelete.mostRecentMessages:type_name -> signalservice.SyncMessage.DeleteForMe.AddressableMessage + 99, // 118: signalservice.SyncMessage.DeleteForMe.ConversationDelete.mostRecentNonExpiringMessages:type_name -> signalservice.SyncMessage.DeleteForMe.AddressableMessage + 98, // 119: signalservice.SyncMessage.DeleteForMe.LocalOnlyConversationDelete.conversation:type_name -> signalservice.SyncMessage.DeleteForMe.ConversationIdentifier + 120, // [120:120] is the sub-list for method output_type + 120, // [120:120] is the sub-list for method input_type + 120, // [120:120] is the sub-list for extension type_name + 120, // [120:120] is the sub-list for extension extendee + 0, // [0:120] is the sub-list for field type_name } func init() { file_SignalService_proto_init() } @@ -8013,12 +8068,12 @@ func file_SignalService_proto_init() { file_SignalService_proto_msgTypes[61].OneofWrappers = []any{ (*SyncMessage_OutgoingPayment_MobileCoin_)(nil), } - file_SignalService_proto_msgTypes[70].OneofWrappers = []any{ + file_SignalService_proto_msgTypes[71].OneofWrappers = []any{ (*SyncMessage_DeleteForMe_ConversationIdentifier_ThreadServiceId)(nil), (*SyncMessage_DeleteForMe_ConversationIdentifier_ThreadGroupId)(nil), (*SyncMessage_DeleteForMe_ConversationIdentifier_ThreadE164)(nil), } - file_SignalService_proto_msgTypes[71].OneofWrappers = []any{ + file_SignalService_proto_msgTypes[72].OneofWrappers = []any{ (*SyncMessage_DeleteForMe_AddressableMessage_AuthorServiceId)(nil), (*SyncMessage_DeleteForMe_AddressableMessage_AuthorE164)(nil), } @@ -8028,7 +8083,7 @@ func file_SignalService_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_SignalService_proto_rawDesc, NumEnums: 27, - NumMessages: 81, + NumMessages: 82, NumExtensions: 0, NumServices: 0, }, diff --git a/pkg/signalmeow/protobuf/SignalService.pb.raw b/pkg/signalmeow/protobuf/SignalService.pb.raw index 0212283ad7d460eef2666a29af7587664d4aa392..ef74a34b022885779472ea55468cec2136898678 100644 GIT binary patch delta 147 zcmbO|jd9g<#tn~^m~Po@eyY^MDkT)oC6JO@mYJODmzbOCoROH9o+=@(z^K7JxxqkI z(FIK^2wm~!3=JCzGbs};0d%E8Qd}GmlRZ-;n1Cko2EqAWEF6piOq-WDlyd<9WnnJ2 delta 27 jcmZ2AopJUw#tn~^m`+=7eyY^My7`cXwZvv)$8s(Jr}zsE diff --git a/pkg/signalmeow/protobuf/SignalService.proto b/pkg/signalmeow/protobuf/SignalService.proto index f5cecb0..bd841ae 100644 --- a/pkg/signalmeow/protobuf/SignalService.proto +++ b/pkg/signalmeow/protobuf/SignalService.proto @@ -707,6 +707,11 @@ message SyncMessage { repeated AttachmentDelete attachmentDeletes = 4; } + message DeviceNameChange { + reserved /*name*/ 1; + optional uint32 deviceId = 2; + } + optional Sent sent = 1; optional Contacts contacts = 2; reserved /*groups*/ 3; @@ -729,6 +734,7 @@ message SyncMessage { optional CallLinkUpdate callLinkUpdate = 20; optional CallLogEvent callLogEvent = 21; optional DeleteForMe deleteForMe = 22; + optional DeviceNameChange deviceNameChange = 23; } message AttachmentPointer { diff --git a/pkg/signalmeow/protobuf/update-protos.sh b/pkg/signalmeow/protobuf/update-protos.sh index 7d59dea..cf36fdc 100755 --- a/pkg/signalmeow/protobuf/update-protos.sh +++ b/pkg/signalmeow/protobuf/update-protos.sh @@ -1,8 +1,8 @@ #!/bin/bash set -euo pipefail -ANDROID_GIT_REVISION=${1:-f5a68aa7aeccba3efba71e9868475a2483c5fa28} -DESKTOP_GIT_REVISION=${1:-5d899d740b236491d8cad6fe187bb9806ff95ccf} +ANDROID_GIT_REVISION=${1:-e47861796e3af0879dfd3a67f549674efb9c0c33} +DESKTOP_GIT_REVISION=${1:-94dba11bcb3973b98784b0a7aaefa6ea03c330ea} update_proto() { case "$1" in From 60fa2e75b5d4a1b56ae90178c12e4ac8716767ae Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Sun, 15 Dec 2024 12:51:10 +0200 Subject: [PATCH 238/580] dependencies: update --- go.mod | 22 +++++++++++----------- go.sum | 40 ++++++++++++++++++++-------------------- 2 files changed, 31 insertions(+), 31 deletions(-) diff --git a/go.mod b/go.mod index 5b56c84..e95b307 100644 --- a/go.mod +++ b/go.mod @@ -2,7 +2,7 @@ module go.mau.fi/mautrix-signal go 1.22.0 -toolchain go1.23.3 +toolchain go1.23.4 require ( github.com/coder/websocket v1.8.12 @@ -11,14 +11,14 @@ require ( github.com/gorilla/mux v1.8.0 github.com/mattn/go-pointer v0.0.1 github.com/rs/zerolog v1.33.0 - github.com/stretchr/testify v1.9.0 + github.com/stretchr/testify v1.10.0 github.com/tidwall/gjson v1.18.0 - go.mau.fi/util v0.8.2 - golang.org/x/crypto v0.29.0 - golang.org/x/exp v0.0.0-20241108190413-2d47ceb2692f - golang.org/x/net v0.31.0 + go.mau.fi/util v0.8.3-0.20241212004537-24c1a9b1d8f6 + golang.org/x/crypto v0.31.0 + golang.org/x/exp v0.0.0-20241210194714-1829a127f884 + golang.org/x/net v0.32.0 google.golang.org/protobuf v1.35.2 - maunium.net/go/mautrix v0.22.1-0.20241202131110-166ba04aae02 + maunium.net/go/mautrix v0.22.1-0.20241215103154-351b49f8a893 ) require ( @@ -31,7 +31,7 @@ require ( github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-isatty v0.0.19 // indirect github.com/mattn/go-sqlite3 v1.14.24 // indirect - github.com/petermattis/goid v0.0.0-20241025130422-66cb2e6d7274 // indirect + github.com/petermattis/goid v0.0.0-20241211131331-93ee7e083c43 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/rogpeppe/go-internal v1.10.0 // indirect github.com/rs/xid v1.6.0 // indirect @@ -41,9 +41,9 @@ require ( github.com/tidwall/sjson v1.2.5 // indirect github.com/yuin/goldmark v1.7.8 // indirect go.mau.fi/zeroconfig v0.1.3 // indirect - golang.org/x/sync v0.9.0 // indirect - golang.org/x/sys v0.27.0 // indirect - golang.org/x/text v0.20.0 // indirect + golang.org/x/sync v0.10.0 // indirect + golang.org/x/sys v0.28.0 // indirect + golang.org/x/text v0.21.0 // indirect gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect gopkg.in/natefinch/lumberjack.v2 v2.2.1 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect diff --git a/go.sum b/go.sum index 8df0f41..4d23cfe 100644 --- a/go.sum +++ b/go.sum @@ -38,8 +38,8 @@ github.com/mattn/go-pointer v0.0.1 h1:n+XhsuGeVO6MEAp7xyEukFINEa+Quek5psIR/ylA6o github.com/mattn/go-pointer v0.0.1/go.mod h1:2zXcozF6qYGgmsG+SeTZz3oAbFLdD3OWqnUbNvJZAlc= github.com/mattn/go-sqlite3 v1.14.24 h1:tpSp2G2KyMnnQu99ngJ47EIkWVmliIizyZBfPrBWDRM= github.com/mattn/go-sqlite3 v1.14.24/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y= -github.com/petermattis/goid v0.0.0-20241025130422-66cb2e6d7274 h1:qli3BGQK0tYDkSEvZ/FzZTi9ZrOX86Q6CIhKLGc489A= -github.com/petermattis/goid v0.0.0-20241025130422-66cb2e6d7274/go.mod h1:pxMtw7cyUw6B2bRH0ZBANSPg+AoSud1I1iyJHI69jH4= +github.com/petermattis/goid v0.0.0-20241211131331-93ee7e083c43 h1:ah1dvbqPMN5+ocrg/ZSgZ6k8bOk+kcZQ7fnyx6UvOm4= +github.com/petermattis/goid v0.0.0-20241211131331-93ee7e083c43/go.mod h1:pxMtw7cyUw6B2bRH0ZBANSPg+AoSud1I1iyJHI69jH4= github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= @@ -54,8 +54,8 @@ github.com/rs/zerolog v1.33.0 h1:1cU2KZkvPxNyfgEmhHAz/1A9Bz+llsdYzklWFzgp0r8= github.com/rs/zerolog v1.33.0/go.mod h1:/7mN4D5sKwJLZQ2b/znpjC3/GQWY/xaDXUM0kKWRHss= github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e h1:MRM5ITcdelLK2j1vwZ3Je0FKVCfqOLp5zO6trqMLYs0= github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e/go.mod h1:XV66xRDqSt+GTGFMVlhk3ULuV0y9ZmzeVGR4mloJI3M= -github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= -github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= +github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/tidwall/gjson v1.14.2/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= github.com/tidwall/gjson v1.18.0 h1:FIDeeyB800efLX89e5a8Y0BNH+LOngJyGrIWxG2FKQY= github.com/tidwall/gjson v1.18.0/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= @@ -67,25 +67,25 @@ github.com/tidwall/sjson v1.2.5 h1:kLy8mja+1c9jlljvWTlSazM7cKDRfJuR/bOJhcY5NcY= github.com/tidwall/sjson v1.2.5/go.mod h1:Fvgq9kS/6ociJEDnK0Fk1cpYF4FIW6ZF7LAe+6jwd28= github.com/yuin/goldmark v1.7.8 h1:iERMLn0/QJeHFhxSt3p6PeN9mGnvIKSpG9YYorDMnic= github.com/yuin/goldmark v1.7.8/go.mod h1:uzxRWxtg69N339t3louHJ7+O03ezfj6PlliRlaOzY1E= -go.mau.fi/util v0.8.2 h1:zWbVHwdRKwI6U9AusmZ8bwgcLosikwbb4GGqLrNr1YE= -go.mau.fi/util v0.8.2/go.mod h1:BHHC9R2WLMJd1bwTZfTcFxUgRFmUgUmiWcT4RbzUgiA= +go.mau.fi/util v0.8.3-0.20241212004537-24c1a9b1d8f6 h1:s4aQJQBBMkjkHTdThRRNp2E35wqmMJVGkOAXG4b0X8c= +go.mau.fi/util v0.8.3-0.20241212004537-24c1a9b1d8f6/go.mod h1:sWpI/kFgk/QP4BDJJwSjjBsuAT7oUsj9VlFhvUo+34I= go.mau.fi/zeroconfig v0.1.3 h1:As9wYDKmktjmNZW5i1vn8zvJlmGKHeVxHVIBMXsm4kM= go.mau.fi/zeroconfig v0.1.3/go.mod h1:NcSJkf180JT+1IId76PcMuLTNa1CzsFFZ0nBygIQM70= -golang.org/x/crypto v0.29.0 h1:L5SG1JTTXupVV3n6sUqMTeWbjAyfPwoda2DLX8J8FrQ= -golang.org/x/crypto v0.29.0/go.mod h1:+F4F4N5hv6v38hfeYwTdx20oUvLLc+QfrE9Ax9HtgRg= -golang.org/x/exp v0.0.0-20241108190413-2d47ceb2692f h1:XdNn9LlyWAhLVp6P/i8QYBW+hlyhrhei9uErw2B5GJo= -golang.org/x/exp v0.0.0-20241108190413-2d47ceb2692f/go.mod h1:D5SMRVC3C2/4+F/DB1wZsLRnSNimn2Sp/NPsCrsv8ak= -golang.org/x/net v0.31.0 h1:68CPQngjLL0r2AlUKiSxtQFKvzRVbnzLwMUn5SzcLHo= -golang.org/x/net v0.31.0/go.mod h1:P4fl1q7dY2hnZFxEk4pPSkDHF+QqjitcnDjUQyMM+pM= -golang.org/x/sync v0.9.0 h1:fEo0HyrW1GIgZdpbhCRO0PkJajUS5H9IFUztCgEo2jQ= -golang.org/x/sync v0.9.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/crypto v0.31.0 h1:ihbySMvVjLAeSH1IbfcRTkD/iNscyz8rGzjF/E5hV6U= +golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk= +golang.org/x/exp v0.0.0-20241210194714-1829a127f884 h1:Y/Mj/94zIQQGHVSv1tTtQBDaQaJe62U9bkDZKKyhPCU= +golang.org/x/exp v0.0.0-20241210194714-1829a127f884/go.mod h1:qj5a5QZpwLU2NLQudwIN5koi3beDhSAlJwa67PuM98c= +golang.org/x/net v0.32.0 h1:ZqPmj8Kzc+Y6e0+skZsuACbx+wzMgo5MQsJh9Qd6aYI= +golang.org/x/net v0.32.0/go.mod h1:CwU0IoeOlnQQWJ6ioyFrfRuomB8GKF6KbYXZVyeXNfs= +golang.org/x/sync v0.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ= +golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.27.0 h1:wBqf8DvsY9Y/2P8gAfPDEYNuS30J4lPHJxXSb/nJZ+s= -golang.org/x/sys v0.27.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/text v0.20.0 h1:gK/Kv2otX8gz+wn7Rmb3vT96ZwuoxnQlY+HlJVj7Qug= -golang.org/x/text v0.20.0/go.mod h1:D4IsuqiFMhST5bX19pQ9ikHC2GsaKyk/oF+pn3ducp4= +golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA= +golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo= +golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= google.golang.org/protobuf v1.35.2 h1:8Ar7bF+apOIoThw1EdZl0p1oWvMqTHmpA2fRTyZO8io= google.golang.org/protobuf v1.35.2/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= @@ -97,5 +97,5 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= maunium.net/go/mauflag v1.0.0 h1:YiaRc0tEI3toYtJMRIfjP+jklH45uDHtT80nUamyD4M= maunium.net/go/mauflag v1.0.0/go.mod h1:nLivPOpTpHnpzEh8jEdSL9UqO9+/KBJFmNRlwKfkPeA= -maunium.net/go/mautrix v0.22.1-0.20241202131110-166ba04aae02 h1:g8L4GpOhyg5EuXtASDKyU9Cg79ZjATlUnh+giFumQgc= -maunium.net/go/mautrix v0.22.1-0.20241202131110-166ba04aae02/go.mod h1:oqwf9WYC/brqucM+heYk4gX11O59nP+ljvyxVhndFIM= +maunium.net/go/mautrix v0.22.1-0.20241215103154-351b49f8a893 h1:nwV01xjyCMINMjHl+0diuWzuhHqkTWG/kXvlm2EWIOw= +maunium.net/go/mautrix v0.22.1-0.20241215103154-351b49f8a893/go.mod h1:bjPXzRi5r1eY4n3fvm9k1UrppoSDoqq7McoRPpBR8YM= From 06756933070eb3da01550cdb8324bedf15cc3125 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Mon, 16 Dec 2024 16:27:14 +0200 Subject: [PATCH 239/580] Bump version to v0.7.4 --- CHANGELOG.md | 7 +++++++ cmd/mautrix-signal/main.go | 2 +- go.mod | 6 +++--- go.sum | 12 ++++++------ 4 files changed, 17 insertions(+), 10 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8321abe..7c2ef6c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +# v0.7.4 (2024-12-16) + +* Fixed syncing server-side storage after Signal login. +* Added support for new SSRE2 method of receiving the server-side storage key. +* Updated libsignal to v0.64.1. +* Updated Docker image to Alpine 3.21. + # v0.7.3 (2024-11-16) * Updated libsignal to v0.62.0. diff --git a/cmd/mautrix-signal/main.go b/cmd/mautrix-signal/main.go index 92121cb..61d22dd 100644 --- a/cmd/mautrix-signal/main.go +++ b/cmd/mautrix-signal/main.go @@ -38,7 +38,7 @@ var m = mxmain.BridgeMain{ Name: "mautrix-signal", URL: "https://github.com/mautrix/signal", Description: "A Matrix-Signal puppeting bridge.", - Version: "0.7.3", + Version: "0.7.4", Connector: &connector.SignalConnector{}, } diff --git a/go.mod b/go.mod index e95b307..7eec39d 100644 --- a/go.mod +++ b/go.mod @@ -13,12 +13,12 @@ require ( github.com/rs/zerolog v1.33.0 github.com/stretchr/testify v1.10.0 github.com/tidwall/gjson v1.18.0 - go.mau.fi/util v0.8.3-0.20241212004537-24c1a9b1d8f6 + go.mau.fi/util v0.8.3 golang.org/x/crypto v0.31.0 - golang.org/x/exp v0.0.0-20241210194714-1829a127f884 + golang.org/x/exp v0.0.0-20241215155358-4a5509556b9e golang.org/x/net v0.32.0 google.golang.org/protobuf v1.35.2 - maunium.net/go/mautrix v0.22.1-0.20241215103154-351b49f8a893 + maunium.net/go/mautrix v0.22.1 ) require ( diff --git a/go.sum b/go.sum index 4d23cfe..b211283 100644 --- a/go.sum +++ b/go.sum @@ -67,14 +67,14 @@ github.com/tidwall/sjson v1.2.5 h1:kLy8mja+1c9jlljvWTlSazM7cKDRfJuR/bOJhcY5NcY= github.com/tidwall/sjson v1.2.5/go.mod h1:Fvgq9kS/6ociJEDnK0Fk1cpYF4FIW6ZF7LAe+6jwd28= github.com/yuin/goldmark v1.7.8 h1:iERMLn0/QJeHFhxSt3p6PeN9mGnvIKSpG9YYorDMnic= github.com/yuin/goldmark v1.7.8/go.mod h1:uzxRWxtg69N339t3louHJ7+O03ezfj6PlliRlaOzY1E= -go.mau.fi/util v0.8.3-0.20241212004537-24c1a9b1d8f6 h1:s4aQJQBBMkjkHTdThRRNp2E35wqmMJVGkOAXG4b0X8c= -go.mau.fi/util v0.8.3-0.20241212004537-24c1a9b1d8f6/go.mod h1:sWpI/kFgk/QP4BDJJwSjjBsuAT7oUsj9VlFhvUo+34I= +go.mau.fi/util v0.8.3 h1:sulhXtfquMrQjsOP67x9CzWVBYUwhYeoo8hNQIpCWZ4= +go.mau.fi/util v0.8.3/go.mod h1:c00Db8xog70JeIsEvhdHooylTkTkakgnAOsZ04hplQY= go.mau.fi/zeroconfig v0.1.3 h1:As9wYDKmktjmNZW5i1vn8zvJlmGKHeVxHVIBMXsm4kM= go.mau.fi/zeroconfig v0.1.3/go.mod h1:NcSJkf180JT+1IId76PcMuLTNa1CzsFFZ0nBygIQM70= golang.org/x/crypto v0.31.0 h1:ihbySMvVjLAeSH1IbfcRTkD/iNscyz8rGzjF/E5hV6U= golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk= -golang.org/x/exp v0.0.0-20241210194714-1829a127f884 h1:Y/Mj/94zIQQGHVSv1tTtQBDaQaJe62U9bkDZKKyhPCU= -golang.org/x/exp v0.0.0-20241210194714-1829a127f884/go.mod h1:qj5a5QZpwLU2NLQudwIN5koi3beDhSAlJwa67PuM98c= +golang.org/x/exp v0.0.0-20241215155358-4a5509556b9e h1:4qufH0hlUYs6AO6XmZC3GqfDPGSXHVXUFR6OND+iJX4= +golang.org/x/exp v0.0.0-20241215155358-4a5509556b9e/go.mod h1:qj5a5QZpwLU2NLQudwIN5koi3beDhSAlJwa67PuM98c= golang.org/x/net v0.32.0 h1:ZqPmj8Kzc+Y6e0+skZsuACbx+wzMgo5MQsJh9Qd6aYI= golang.org/x/net v0.32.0/go.mod h1:CwU0IoeOlnQQWJ6ioyFrfRuomB8GKF6KbYXZVyeXNfs= golang.org/x/sync v0.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ= @@ -97,5 +97,5 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= maunium.net/go/mauflag v1.0.0 h1:YiaRc0tEI3toYtJMRIfjP+jklH45uDHtT80nUamyD4M= maunium.net/go/mauflag v1.0.0/go.mod h1:nLivPOpTpHnpzEh8jEdSL9UqO9+/KBJFmNRlwKfkPeA= -maunium.net/go/mautrix v0.22.1-0.20241215103154-351b49f8a893 h1:nwV01xjyCMINMjHl+0diuWzuhHqkTWG/kXvlm2EWIOw= -maunium.net/go/mautrix v0.22.1-0.20241215103154-351b49f8a893/go.mod h1:bjPXzRi5r1eY4n3fvm9k1UrppoSDoqq7McoRPpBR8YM= +maunium.net/go/mautrix v0.22.1 h1:2lCM37vmVzZGE0tWD7UOySMtAuC5hq6Pw33KlY2VU/c= +maunium.net/go/mautrix v0.22.1/go.mod h1:1rhqwH34Rz54ZqzdQYkmNW6rQUymNeTdaLA4l9LK6AI= From 710068e90cd7609af77535570ce707438a360973 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Tue, 17 Dec 2024 12:39:43 +0200 Subject: [PATCH 240/580] signalmeow/web: clean up websocket code slightly --- pkg/signalmeow/web/signalwebsocket.go | 30 +++++++++++++-------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/pkg/signalmeow/web/signalwebsocket.go b/pkg/signalmeow/web/signalwebsocket.go index 986e17c..df284d8 100644 --- a/pkg/signalmeow/web/signalwebsocket.go +++ b/pkg/signalmeow/web/signalwebsocket.go @@ -134,6 +134,7 @@ func (s *SignalWebsocket) connectLoop( cancel() }() + const initialBackoff = 2 * time.Second const backoffIncrement = 5 * time.Second const maxBackoff = 60 * time.Second @@ -181,7 +182,7 @@ func (s *SignalWebsocket) connectLoop( // Main connection loop - if there's a problem with anything just // kill everything (including the websocket) and build it all up again - backoff := backoffIncrement + backoff := initialBackoff retrying := false errorCount := 0 for { @@ -257,14 +258,14 @@ func (s *SignalWebsocket) connectLoop( } s.ws = ws retrying = false - backoff = backoffIncrement + backoff = initialBackoff responseChannels := make(map[uint64]chan *signalpb.WebSocketResponseMessage) loopCtx, loopCancel := context.WithCancelCause(ctx) // Read loop (for reading incoming reqeusts and responses to outgoing requests) go func() { - err := readLoop(loopCtx, ws, incomingRequestChan, &responseChannels) + err := readLoop(loopCtx, ws, incomingRequestChan, responseChannels) // Don't want to put an err into loopCancel if we don't have one if err != nil { err = fmt.Errorf("error in readLoop: %w", err) @@ -275,7 +276,7 @@ func (s *SignalWebsocket) connectLoop( // Write loop (for sending outgoing requests and responses to incoming requests) go func() { - err := writeLoop(loopCtx, ws, s.sendChannel, &responseChannels) + err := writeLoop(loopCtx, ws, s.sendChannel, responseChannels) // Don't want to put an err into loopCancel if we don't have one if err != nil { err = fmt.Errorf("error in writeLoop: %w", err) @@ -346,7 +347,7 @@ func (s *SignalWebsocket) connectLoop( log.Info().Msg("Read or write loop exited") // Clean up - ws.Close(200, "Done") + ws.Close(websocket.StatusGoingAway, "Going away") for _, responseChannel := range responseChannels { close(responseChannel) } @@ -365,7 +366,7 @@ func readLoop( ctx context.Context, ws *websocket.Conn, incomingRequestChan chan *signalpb.WebSocketRequestMessage, - responseChannels *(map[uint64]chan *signalpb.WebSocketResponseMessage), + responseChannels map[uint64]chan *signalpb.WebSocketResponseMessage, ) error { log := zerolog.Ctx(ctx).With(). Str("loop", "signal_websocket_read_loop"). @@ -380,8 +381,7 @@ func readLoop( if err != nil { if err == context.Canceled { log.Info().Msg("readLoop context canceled") - } - if strings.Contains(err.Error(), "StatusNormalClosure") { + } else if websocket.CloseStatus(err) == websocket.StatusNormalClosure { log.Info().Msg("readLoop received StatusNormalClosure") return nil } @@ -406,7 +406,7 @@ func readLoop( if msg.Response.Id == nil { log.Fatal().Msg("Received response with no id") } - responseChannel, ok := (*responseChannels)[*msg.Response.Id] + responseChannel, ok := responseChannels[*msg.Response.Id] if !ok { log.Warn(). Uint64("response_id", *msg.Response.Id). @@ -418,7 +418,7 @@ func readLoop( Uint32("response_status", *msg.Response.Status). Msg("Received WS response") responseChannel <- msg.Response - delete(*responseChannels, *msg.Response.Id) + delete(responseChannels, *msg.Response.Id) log.Debug(). Uint64("response_id", *msg.Response.Id). Msg("Deleted response channel for ID") @@ -445,7 +445,7 @@ func writeLoop( ctx context.Context, ws *websocket.Conn, sendChannel chan SignalWebsocketSendMessage, - responseChannels *(map[uint64]chan *signalpb.WebSocketResponseMessage), + responseChannels map[uint64]chan *signalpb.WebSocketResponseMessage, ) error { log := zerolog.Ctx(ctx).With(). Str("loop", "signal_websocket_write_loop"). @@ -459,7 +459,7 @@ func writeLoop( return nil case request, ok := <-sendChannel: if !ok { - return errors.New("Send channel closed") + return errors.New("send channel closed") } if request.RequestMessage != nil && request.ResponseChannel != nil { msgType := signalpb.WebSocketMessage_REQUEST @@ -468,15 +468,15 @@ func writeLoop( Request: request.RequestMessage, } request.RequestMessage.Id = &i - (*responseChannels)[i] = request.ResponseChannel + responseChannels[i] = request.ResponseChannel path := *request.RequestMessage.Path if len(path) > 30 { path = path[:40] } - if request.RequestTime != (time.Time{}) { + if !request.RequestTime.IsZero() { elapsed := time.Since(request.RequestTime) if elapsed > 1*time.Minute { - return fmt.Errorf("Took too long, not sending (elapsed: %v)", elapsed) + return fmt.Errorf("request too old (%v), not sending", elapsed) } else if elapsed > 10*time.Second { log.Warn(). Uint64("request_id", i). From b01a912320d081f7f704c0b60b765ecf52d4fd91 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Tue, 17 Dec 2024 12:41:35 +0200 Subject: [PATCH 241/580] signalmeow/web: wait for all websocket loops to close --- pkg/signalmeow/web/signalwebsocket.go | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/pkg/signalmeow/web/signalwebsocket.go b/pkg/signalmeow/web/signalwebsocket.go index df284d8..4ac1bf0 100644 --- a/pkg/signalmeow/web/signalwebsocket.go +++ b/pkg/signalmeow/web/signalwebsocket.go @@ -23,6 +23,7 @@ import ( "fmt" "net/http" "strings" + "sync" "time" "github.com/coder/websocket" @@ -262,9 +263,12 @@ func (s *SignalWebsocket) connectLoop( responseChannels := make(map[uint64]chan *signalpb.WebSocketResponseMessage) loopCtx, loopCancel := context.WithCancelCause(ctx) + var wg sync.WaitGroup + wg.Add(3) // Read loop (for reading incoming reqeusts and responses to outgoing requests) go func() { + defer wg.Done() err := readLoop(loopCtx, ws, incomingRequestChan, responseChannels) // Don't want to put an err into loopCancel if we don't have one if err != nil { @@ -276,6 +280,7 @@ func (s *SignalWebsocket) connectLoop( // Write loop (for sending outgoing requests and responses to incoming requests) go func() { + defer wg.Done() err := writeLoop(loopCtx, ws, s.sendChannel, responseChannels) // Don't want to put an err into loopCancel if we don't have one if err != nil { @@ -287,6 +292,7 @@ func (s *SignalWebsocket) connectLoop( // Ping loop (send a keepalive Ping every 30s) go func() { + defer wg.Done() ticker := time.NewTicker(30 * time.Second) defer ticker.Stop() @@ -352,6 +358,7 @@ func (s *SignalWebsocket) connectLoop( close(responseChannel) } loopCancel(nil) + wg.Wait() log.Debug().Msg("Finished websocket cleanup") if errorCount > 500 { // Something is really wrong, we better panic. From 4b634863890e7818febc8b9b8341da52ccf61cb6 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Tue, 17 Dec 2024 12:48:56 +0200 Subject: [PATCH 242/580] signalmeow/web: add small sleep for all reconnects --- pkg/signalmeow/web/signalwebsocket.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/pkg/signalmeow/web/signalwebsocket.go b/pkg/signalmeow/web/signalwebsocket.go index 4ac1bf0..3b192fb 100644 --- a/pkg/signalmeow/web/signalwebsocket.go +++ b/pkg/signalmeow/web/signalwebsocket.go @@ -186,6 +186,7 @@ func (s *SignalWebsocket) connectLoop( backoff := initialBackoff retrying := false errorCount := 0 + isFirstConnect := true for { if retrying { if backoff > maxBackoff { @@ -194,11 +195,14 @@ func (s *SignalWebsocket) connectLoop( log.Warn().Dur("backoff", backoff).Msg("Failed to connect, waiting to retry...") time.Sleep(backoff) backoff += backoffIncrement + } else if !isFirstConnect { + time.Sleep(1 * time.Second) } if ctx.Err() != nil { log.Info().Msg("ctx done, stopping connection loop") return } + isFirstConnect = false ws, resp, err := OpenWebsocket(ctx, s.path) if resp != nil { From 192b5a79ca30fd86b1ad5073023c3c154d9f2629 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Fri, 20 Dec 2024 13:18:52 +0200 Subject: [PATCH 243/580] msgconv/from-signal: add option to make view-once messages disappear --- pkg/connector/config.go | 2 ++ pkg/connector/connector.go | 4 +++- pkg/connector/example-config.yaml | 2 ++ pkg/connector/handlesignal.go | 4 +++- pkg/msgconv/from-signal.go | 13 +++++++++++++ pkg/msgconv/msgconv.go | 10 +++++----- 6 files changed, 28 insertions(+), 7 deletions(-) diff --git a/pkg/connector/config.go b/pkg/connector/config.go index ec47f34..1f583c5 100644 --- a/pkg/connector/config.go +++ b/pkg/connector/config.go @@ -39,6 +39,7 @@ type SignalConfig struct { DeviceName string `yaml:"device_name"` NoteToSelfAvatar id.ContentURIString `yaml:"note_to_self_avatar"` LocationFormat string `yaml:"location_format"` + DisappearViewOnce bool `yaml:"disappear_view_once"` displaynameTemplate *template.Template `yaml:"-"` } @@ -81,6 +82,7 @@ func upgradeConfig(helper up.Helper) { helper.Copy(up.Str, "device_name") helper.Copy(up.Str, "note_to_self_avatar") helper.Copy(up.Str, "location_format") + helper.Copy(up.Bool, "disappear_view_once") } func (s *SignalConnector) GetConfig() (string, any, up.Upgrader) { diff --git a/pkg/connector/connector.go b/pkg/connector/connector.go index 8cdb368..1072983 100644 --- a/pkg/connector/connector.go +++ b/pkg/connector/connector.go @@ -69,7 +69,9 @@ func (s *SignalConnector) Init(bridge *bridgev2.Bridge) { } s.Store = store.NewStore(bridge.DB.Database, dbutil.ZeroLogger(bridge.Log.With().Str("db_section", "signalmeow").Logger())) s.Bridge = bridge - s.MsgConv = msgconv.NewMessageConverter(bridge, s.Config.LocationFormat) + s.MsgConv = msgconv.NewMessageConverter(bridge) + s.MsgConv.LocationFormat = s.Config.LocationFormat + s.MsgConv.DisappearViewOnce = s.Config.DisappearViewOnce } func (s *SignalConnector) SetMaxFileSize(maxSize int64) { diff --git a/pkg/connector/example-config.yaml b/pkg/connector/example-config.yaml index eea81f2..8c0a61e 100644 --- a/pkg/connector/example-config.yaml +++ b/pkg/connector/example-config.yaml @@ -21,3 +21,5 @@ note_to_self_avatar: mxc://maunium.net/REBIVrqjZwmaWpssCZpBlmlL # Google Maps: 'https://www.google.com/maps/place/%[1]s,%[2]s' # OpenStreetMap: 'https://www.openstreetmap.org/?mlat=%[1]s&mlon=%[2]s' location_format: 'https://www.google.com/maps/place/%[1]s,%[2]s' +# Should view-once messages disappear shortly after sending a read receipt on Matrix? +disappear_view_once: false diff --git a/pkg/connector/handlesignal.go b/pkg/connector/handlesignal.go index 2d863ac..1984862 100644 --- a/pkg/connector/handlesignal.go +++ b/pkg/connector/handlesignal.go @@ -314,7 +314,9 @@ func (evt *Bv2ChatEvent) ConvertMessage(ctx context.Context, portal *bridgev2.Po converted := evt.s.Main.MsgConv.ToMatrix(ctx, evt.s.Client, portal, intent, dataMsg) if converted.Disappear.Type != "" { evtTS := evt.GetTimestamp() - portal.UpdateDisappearingSetting(ctx, converted.Disappear, nil, evtTS, true, true) + if !dataMsg.GetIsViewOnce() { + portal.UpdateDisappearingSetting(ctx, converted.Disappear, nil, evtTS, true, true) + } if evt.Info.Sender == evt.s.Client.Store.ACI { converted.Disappear.DisappearAt = evtTS.Add(converted.Disappear.Timer) } diff --git a/pkg/msgconv/from-signal.go b/pkg/msgconv/from-signal.go index 9b27c07..486bde1 100644 --- a/pkg/msgconv/from-signal.go +++ b/pkg/msgconv/from-signal.go @@ -68,6 +68,8 @@ func CanConvertSignal(dm *signalpb.DataMessage) bool { return calculateLength(dm) > 0 } +const ViewOnceDisappearTimer = 5 * time.Minute + func (mc *MessageConverter) ToMatrix( ctx context.Context, client *signalmeow.Client, @@ -130,6 +132,17 @@ func (mc *MessageConverter) ToMatrix( }, }) } + if dm.GetIsViewOnce() && mc.DisappearViewOnce && (cm.Disappear.Timer == 0 || cm.Disappear.Timer > ViewOnceDisappearTimer) { + cm.Disappear.Type = database.DisappearingTypeAfterRead + cm.Disappear.Timer = ViewOnceDisappearTimer + cm.Parts = append(cm.Parts, &bridgev2.ConvertedMessagePart{ + Type: event.EventMessage, + Content: &event.MessageEventContent{ + MsgType: event.MsgText, + Body: "This is a view-once message. It will disappear in 5 minutes.", + }, + }) + } cm.MergeCaption() for i, part := range cm.Parts { part.ID = signalid.MakeMessagePartID(i) diff --git a/pkg/msgconv/msgconv.go b/pkg/msgconv/msgconv.go index 1d1fee8..80717fc 100644 --- a/pkg/msgconv/msgconv.go +++ b/pkg/msgconv/msgconv.go @@ -44,11 +44,12 @@ type MessageConverter struct { SignalFmtParams *signalfmt.FormatParams MatrixFmtParams *matrixfmt.HTMLParser - MaxFileSize int64 - LocationFormat string + MaxFileSize int64 + LocationFormat string + DisappearViewOnce bool } -func NewMessageConverter(br *bridgev2.Bridge, locationFormat string) *MessageConverter { +func NewMessageConverter(br *bridgev2.Bridge) *MessageConverter { return &MessageConverter{ Bridge: br, SignalFmtParams: &signalfmt.FormatParams{ @@ -89,8 +90,7 @@ func NewMessageConverter(br *bridgev2.Bridge, locationFormat string) *MessageCon return uuid.Nil }, }, - MaxFileSize: 50 * 1024 * 1024, - LocationFormat: locationFormat, + MaxFileSize: 50 * 1024 * 1024, } } From 7ed141bfadabd92340d97dde32ec685b18186fbe Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Tue, 7 Jan 2025 13:59:43 +0200 Subject: [PATCH 244/580] dependencies: update --- go.mod | 14 +- go.sum | 28 +- .../protobuf/ContactDiscovery.pb.go | 18 +- pkg/signalmeow/protobuf/DeviceName.pb.go | 15 +- pkg/signalmeow/protobuf/Groups.pb.go | 438 ++++--- pkg/signalmeow/protobuf/Provisioning.pb.go | 57 +- pkg/signalmeow/protobuf/SignalService.pb.go | 1076 ++++++++--------- .../protobuf/StickerResources.pb.go | 26 +- pkg/signalmeow/protobuf/StorageService.pb.go | 267 ++-- .../protobuf/UnidentifiedDelivery.pb.go | 66 +- .../protobuf/WebSocketResources.pb.go | 43 +- 11 files changed, 978 insertions(+), 1070 deletions(-) diff --git a/go.mod b/go.mod index 7eec39d..554048c 100644 --- a/go.mod +++ b/go.mod @@ -13,12 +13,12 @@ require ( github.com/rs/zerolog v1.33.0 github.com/stretchr/testify v1.10.0 github.com/tidwall/gjson v1.18.0 - go.mau.fi/util v0.8.3 - golang.org/x/crypto v0.31.0 - golang.org/x/exp v0.0.0-20241215155358-4a5509556b9e - golang.org/x/net v0.32.0 - google.golang.org/protobuf v1.35.2 - maunium.net/go/mautrix v0.22.1 + go.mau.fi/util v0.8.4-0.20250106152331-30b8c95e7d7a + golang.org/x/crypto v0.32.0 + golang.org/x/exp v0.0.0-20250106191152-7588d65b2ba8 + golang.org/x/net v0.34.0 + google.golang.org/protobuf v1.36.2 + maunium.net/go/mautrix v0.22.2-0.20250107114437-ceb9c7b866e1 ) require ( @@ -42,7 +42,7 @@ require ( github.com/yuin/goldmark v1.7.8 // indirect go.mau.fi/zeroconfig v0.1.3 // indirect golang.org/x/sync v0.10.0 // indirect - golang.org/x/sys v0.28.0 // indirect + golang.org/x/sys v0.29.0 // indirect golang.org/x/text v0.21.0 // indirect gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect gopkg.in/natefinch/lumberjack.v2 v2.2.1 // indirect diff --git a/go.sum b/go.sum index b211283..4d10fa9 100644 --- a/go.sum +++ b/go.sum @@ -67,27 +67,27 @@ github.com/tidwall/sjson v1.2.5 h1:kLy8mja+1c9jlljvWTlSazM7cKDRfJuR/bOJhcY5NcY= github.com/tidwall/sjson v1.2.5/go.mod h1:Fvgq9kS/6ociJEDnK0Fk1cpYF4FIW6ZF7LAe+6jwd28= github.com/yuin/goldmark v1.7.8 h1:iERMLn0/QJeHFhxSt3p6PeN9mGnvIKSpG9YYorDMnic= github.com/yuin/goldmark v1.7.8/go.mod h1:uzxRWxtg69N339t3louHJ7+O03ezfj6PlliRlaOzY1E= -go.mau.fi/util v0.8.3 h1:sulhXtfquMrQjsOP67x9CzWVBYUwhYeoo8hNQIpCWZ4= -go.mau.fi/util v0.8.3/go.mod h1:c00Db8xog70JeIsEvhdHooylTkTkakgnAOsZ04hplQY= +go.mau.fi/util v0.8.4-0.20250106152331-30b8c95e7d7a h1:D9RCHBFjxah9F/YB7amvRJjT2IEOFWcz8jpcEY8dBV0= +go.mau.fi/util v0.8.4-0.20250106152331-30b8c95e7d7a/go.mod h1:MOfGTs1CBuK6ERTcSL4lb5YU7/ujz09eOPVEDckuazY= go.mau.fi/zeroconfig v0.1.3 h1:As9wYDKmktjmNZW5i1vn8zvJlmGKHeVxHVIBMXsm4kM= go.mau.fi/zeroconfig v0.1.3/go.mod h1:NcSJkf180JT+1IId76PcMuLTNa1CzsFFZ0nBygIQM70= -golang.org/x/crypto v0.31.0 h1:ihbySMvVjLAeSH1IbfcRTkD/iNscyz8rGzjF/E5hV6U= -golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk= -golang.org/x/exp v0.0.0-20241215155358-4a5509556b9e h1:4qufH0hlUYs6AO6XmZC3GqfDPGSXHVXUFR6OND+iJX4= -golang.org/x/exp v0.0.0-20241215155358-4a5509556b9e/go.mod h1:qj5a5QZpwLU2NLQudwIN5koi3beDhSAlJwa67PuM98c= -golang.org/x/net v0.32.0 h1:ZqPmj8Kzc+Y6e0+skZsuACbx+wzMgo5MQsJh9Qd6aYI= -golang.org/x/net v0.32.0/go.mod h1:CwU0IoeOlnQQWJ6ioyFrfRuomB8GKF6KbYXZVyeXNfs= +golang.org/x/crypto v0.32.0 h1:euUpcYgM8WcP71gNpTqQCn6rC2t6ULUPiOzfWaXVVfc= +golang.org/x/crypto v0.32.0/go.mod h1:ZnnJkOaASj8g0AjIduWNlq2NRxL0PlBrbKVyZ6V/Ugc= +golang.org/x/exp v0.0.0-20250106191152-7588d65b2ba8 h1:yqrTHse8TCMW1M1ZCP+VAR/l0kKxwaAIqN/il7x4voA= +golang.org/x/exp v0.0.0-20250106191152-7588d65b2ba8/go.mod h1:tujkw807nyEEAamNbDrEGzRav+ilXA7PCRAd6xsmwiU= +golang.org/x/net v0.34.0 h1:Mb7Mrk043xzHgnRM88suvJFwzVrRfHEHJEl5/71CKw0= +golang.org/x/net v0.34.0/go.mod h1:di0qlW3YNM5oh6GqDGQr92MyTozJPmybPK4Ev/Gm31k= golang.org/x/sync v0.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ= golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA= -golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.29.0 h1:TPYlXGxvx1MGTn2GiZDhnjPA9wZzZeGKHHmKhHYvgaU= +golang.org/x/sys v0.29.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo= golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= -google.golang.org/protobuf v1.35.2 h1:8Ar7bF+apOIoThw1EdZl0p1oWvMqTHmpA2fRTyZO8io= -google.golang.org/protobuf v1.35.2/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= +google.golang.org/protobuf v1.36.2 h1:R8FeyR1/eLmkutZOM5CWghmo5itiG9z0ktFlTVLuTmU= +google.golang.org/protobuf v1.36.2/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= @@ -97,5 +97,5 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= maunium.net/go/mauflag v1.0.0 h1:YiaRc0tEI3toYtJMRIfjP+jklH45uDHtT80nUamyD4M= maunium.net/go/mauflag v1.0.0/go.mod h1:nLivPOpTpHnpzEh8jEdSL9UqO9+/KBJFmNRlwKfkPeA= -maunium.net/go/mautrix v0.22.1 h1:2lCM37vmVzZGE0tWD7UOySMtAuC5hq6Pw33KlY2VU/c= -maunium.net/go/mautrix v0.22.1/go.mod h1:1rhqwH34Rz54ZqzdQYkmNW6rQUymNeTdaLA4l9LK6AI= +maunium.net/go/mautrix v0.22.2-0.20250107114437-ceb9c7b866e1 h1:ECwjKJLKKsTp/gnp0Qd5GojeZOK/MLVFF0Tf7C6gZDQ= +maunium.net/go/mautrix v0.22.2-0.20250107114437-ceb9c7b866e1/go.mod h1:FmwzK7RSzrd1OfGDgJzFWXl7nYmYm8/P0Y77sy/A1Uw= diff --git a/pkg/signalmeow/protobuf/ContactDiscovery.pb.go b/pkg/signalmeow/protobuf/ContactDiscovery.pb.go index 3c3d5b1..020c413 100644 --- a/pkg/signalmeow/protobuf/ContactDiscovery.pb.go +++ b/pkg/signalmeow/protobuf/ContactDiscovery.pb.go @@ -1,6 +1,6 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.35.2 +// protoc-gen-go v1.36.1 // protoc v3.21.12 // source: ContactDiscovery.proto @@ -26,10 +26,7 @@ const ( ) type CDSClientRequest struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - + state protoimpl.MessageState `protogen:"open.v1"` // Each ACI/UAK pair is a 32-byte buffer, containing the 16-byte ACI followed // by its 16-byte UAK. AciUakPairs []byte `protobuf:"bytes,1,opt,name=aci_uak_pairs,json=aciUakPairs" json:"aci_uak_pairs,omitempty"` @@ -50,6 +47,8 @@ type CDSClientRequest struct { // Request that, if the server allows, both ACI and PNI be returned even // if the aci_uak_pairs don't match. ReturnAcisWithoutUaks *bool `protobuf:"varint,8,opt,name=return_acis_without_uaks,json=returnAcisWithoutUaks" json:"return_acis_without_uaks,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } func (x *CDSClientRequest) Reset() { @@ -139,10 +138,7 @@ func (x *CDSClientRequest) GetReturnAcisWithoutUaks() bool { } type CDSClientResponse struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - + state protoimpl.MessageState `protogen:"open.v1"` // Each triple is an 8-byte e164, a 16-byte PNI, and a 16-byte ACI. // If the e164 was not found, PNI and ACI are all zeros. If the PNI // was found but the ACI was not, the PNI will be non-zero and the ACI @@ -159,7 +155,9 @@ type CDSClientResponse struct { // A token which allows subsequent calls' rate limiting to discount the // e164s sent up in this request, only counting those in the next // request's new_e164s. - Token []byte `protobuf:"bytes,3,opt,name=token" json:"token,omitempty"` + Token []byte `protobuf:"bytes,3,opt,name=token" json:"token,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } func (x *CDSClientResponse) Reset() { diff --git a/pkg/signalmeow/protobuf/DeviceName.pb.go b/pkg/signalmeow/protobuf/DeviceName.pb.go index 9721926..dbc3df8 100644 --- a/pkg/signalmeow/protobuf/DeviceName.pb.go +++ b/pkg/signalmeow/protobuf/DeviceName.pb.go @@ -1,6 +1,6 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.35.2 +// protoc-gen-go v1.36.1 // protoc v3.21.12 // source: DeviceName.proto @@ -26,13 +26,12 @@ const ( ) type DeviceName struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - EphemeralPublic []byte `protobuf:"bytes,1,opt,name=ephemeralPublic" json:"ephemeralPublic,omitempty"` - SyntheticIv []byte `protobuf:"bytes,2,opt,name=syntheticIv" json:"syntheticIv,omitempty"` - Ciphertext []byte `protobuf:"bytes,3,opt,name=ciphertext" json:"ciphertext,omitempty"` + state protoimpl.MessageState `protogen:"open.v1"` + EphemeralPublic []byte `protobuf:"bytes,1,opt,name=ephemeralPublic" json:"ephemeralPublic,omitempty"` + SyntheticIv []byte `protobuf:"bytes,2,opt,name=syntheticIv" json:"syntheticIv,omitempty"` + Ciphertext []byte `protobuf:"bytes,3,opt,name=ciphertext" json:"ciphertext,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } func (x *DeviceName) Reset() { diff --git a/pkg/signalmeow/protobuf/Groups.pb.go b/pkg/signalmeow/protobuf/Groups.pb.go index de4a1ae..212d5a3 100644 --- a/pkg/signalmeow/protobuf/Groups.pb.go +++ b/pkg/signalmeow/protobuf/Groups.pb.go @@ -5,7 +5,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.35.2 +// protoc-gen-go v1.36.1 // protoc v3.21.12 // source: Groups.proto @@ -132,17 +132,16 @@ func (AccessControl_AccessRequired) EnumDescriptor() ([]byte, []int) { } type AvatarUploadAttributes struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` + Key string `protobuf:"bytes,1,opt,name=key,proto3" json:"key,omitempty"` + Credential string `protobuf:"bytes,2,opt,name=credential,proto3" json:"credential,omitempty"` + Acl string `protobuf:"bytes,3,opt,name=acl,proto3" json:"acl,omitempty"` + Algorithm string `protobuf:"bytes,4,opt,name=algorithm,proto3" json:"algorithm,omitempty"` + Date string `protobuf:"bytes,5,opt,name=date,proto3" json:"date,omitempty"` + Policy string `protobuf:"bytes,6,opt,name=policy,proto3" json:"policy,omitempty"` + Signature string `protobuf:"bytes,7,opt,name=signature,proto3" json:"signature,omitempty"` unknownFields protoimpl.UnknownFields - - Key string `protobuf:"bytes,1,opt,name=key,proto3" json:"key,omitempty"` - Credential string `protobuf:"bytes,2,opt,name=credential,proto3" json:"credential,omitempty"` - Acl string `protobuf:"bytes,3,opt,name=acl,proto3" json:"acl,omitempty"` - Algorithm string `protobuf:"bytes,4,opt,name=algorithm,proto3" json:"algorithm,omitempty"` - Date string `protobuf:"bytes,5,opt,name=date,proto3" json:"date,omitempty"` - Policy string `protobuf:"bytes,6,opt,name=policy,proto3" json:"policy,omitempty"` - Signature string `protobuf:"bytes,7,opt,name=signature,proto3" json:"signature,omitempty"` + sizeCache protoimpl.SizeCache } func (x *AvatarUploadAttributes) Reset() { @@ -225,15 +224,14 @@ func (x *AvatarUploadAttributes) GetSignature() string { } type Member struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - UserId []byte `protobuf:"bytes,1,opt,name=userId,proto3" json:"userId,omitempty"` - Role Member_Role `protobuf:"varint,2,opt,name=role,proto3,enum=Member_Role" json:"role,omitempty"` - ProfileKey []byte `protobuf:"bytes,3,opt,name=profileKey,proto3" json:"profileKey,omitempty"` - Presentation []byte `protobuf:"bytes,4,opt,name=presentation,proto3" json:"presentation,omitempty"` // Only set when sending to server - JoinedAtRevision uint32 `protobuf:"varint,5,opt,name=joinedAtRevision,proto3" json:"joinedAtRevision,omitempty"` + state protoimpl.MessageState `protogen:"open.v1"` + UserId []byte `protobuf:"bytes,1,opt,name=userId,proto3" json:"userId,omitempty"` + Role Member_Role `protobuf:"varint,2,opt,name=role,proto3,enum=Member_Role" json:"role,omitempty"` + ProfileKey []byte `protobuf:"bytes,3,opt,name=profileKey,proto3" json:"profileKey,omitempty"` + Presentation []byte `protobuf:"bytes,4,opt,name=presentation,proto3" json:"presentation,omitempty"` // Only set when sending to server + JoinedAtRevision uint32 `protobuf:"varint,5,opt,name=joinedAtRevision,proto3" json:"joinedAtRevision,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } func (x *Member) Reset() { @@ -302,13 +300,12 @@ func (x *Member) GetJoinedAtRevision() uint32 { } type PendingMember struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` + Member *Member `protobuf:"bytes,1,opt,name=member,proto3" json:"member,omitempty"` + AddedByUserId []byte `protobuf:"bytes,2,opt,name=addedByUserId,proto3" json:"addedByUserId,omitempty"` + Timestamp uint64 `protobuf:"varint,3,opt,name=timestamp,proto3" json:"timestamp,omitempty"` unknownFields protoimpl.UnknownFields - - Member *Member `protobuf:"bytes,1,opt,name=member,proto3" json:"member,omitempty"` - AddedByUserId []byte `protobuf:"bytes,2,opt,name=addedByUserId,proto3" json:"addedByUserId,omitempty"` - Timestamp uint64 `protobuf:"varint,3,opt,name=timestamp,proto3" json:"timestamp,omitempty"` + sizeCache protoimpl.SizeCache } func (x *PendingMember) Reset() { @@ -363,14 +360,13 @@ func (x *PendingMember) GetTimestamp() uint64 { } type RequestingMember struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` + UserId []byte `protobuf:"bytes,1,opt,name=userId,proto3" json:"userId,omitempty"` + ProfileKey []byte `protobuf:"bytes,2,opt,name=profileKey,proto3" json:"profileKey,omitempty"` + Presentation []byte `protobuf:"bytes,3,opt,name=presentation,proto3" json:"presentation,omitempty"` // Only set when sending to server + Timestamp uint64 `protobuf:"varint,4,opt,name=timestamp,proto3" json:"timestamp,omitempty"` unknownFields protoimpl.UnknownFields - - UserId []byte `protobuf:"bytes,1,opt,name=userId,proto3" json:"userId,omitempty"` - ProfileKey []byte `protobuf:"bytes,2,opt,name=profileKey,proto3" json:"profileKey,omitempty"` - Presentation []byte `protobuf:"bytes,3,opt,name=presentation,proto3" json:"presentation,omitempty"` // Only set when sending to server - Timestamp uint64 `protobuf:"varint,4,opt,name=timestamp,proto3" json:"timestamp,omitempty"` + sizeCache protoimpl.SizeCache } func (x *RequestingMember) Reset() { @@ -432,12 +428,11 @@ func (x *RequestingMember) GetTimestamp() uint64 { } type BannedMember struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` + UserId []byte `protobuf:"bytes,1,opt,name=userId,proto3" json:"userId,omitempty"` + Timestamp uint64 `protobuf:"varint,2,opt,name=timestamp,proto3" json:"timestamp,omitempty"` unknownFields protoimpl.UnknownFields - - UserId []byte `protobuf:"bytes,1,opt,name=userId,proto3" json:"userId,omitempty"` - Timestamp uint64 `protobuf:"varint,2,opt,name=timestamp,proto3" json:"timestamp,omitempty"` + sizeCache protoimpl.SizeCache } func (x *BannedMember) Reset() { @@ -485,13 +480,12 @@ func (x *BannedMember) GetTimestamp() uint64 { } type AccessControl struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - + state protoimpl.MessageState `protogen:"open.v1"` Attributes AccessControl_AccessRequired `protobuf:"varint,1,opt,name=attributes,proto3,enum=AccessControl_AccessRequired" json:"attributes,omitempty"` Members AccessControl_AccessRequired `protobuf:"varint,2,opt,name=members,proto3,enum=AccessControl_AccessRequired" json:"members,omitempty"` AddFromInviteLink AccessControl_AccessRequired `protobuf:"varint,3,opt,name=addFromInviteLink,proto3,enum=AccessControl_AccessRequired" json:"addFromInviteLink,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } func (x *AccessControl) Reset() { @@ -546,23 +540,22 @@ func (x *AccessControl) GetAddFromInviteLink() AccessControl_AccessRequired { } type Group struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - PublicKey []byte `protobuf:"bytes,1,opt,name=publicKey,proto3" json:"publicKey,omitempty"` - Title []byte `protobuf:"bytes,2,opt,name=title,proto3" json:"title,omitempty"` - Avatar string `protobuf:"bytes,3,opt,name=avatar,proto3" json:"avatar,omitempty"` - DisappearingMessagesTimer []byte `protobuf:"bytes,4,opt,name=disappearingMessagesTimer,proto3" json:"disappearingMessagesTimer,omitempty"` - AccessControl *AccessControl `protobuf:"bytes,5,opt,name=accessControl,proto3" json:"accessControl,omitempty"` - Revision uint32 `protobuf:"varint,6,opt,name=revision,proto3" json:"revision,omitempty"` - Members []*Member `protobuf:"bytes,7,rep,name=members,proto3" json:"members,omitempty"` - PendingMembers []*PendingMember `protobuf:"bytes,8,rep,name=pendingMembers,proto3" json:"pendingMembers,omitempty"` - RequestingMembers []*RequestingMember `protobuf:"bytes,9,rep,name=requestingMembers,proto3" json:"requestingMembers,omitempty"` - InviteLinkPassword []byte `protobuf:"bytes,10,opt,name=inviteLinkPassword,proto3" json:"inviteLinkPassword,omitempty"` - Description []byte `protobuf:"bytes,11,opt,name=description,proto3" json:"description,omitempty"` - AnnouncementsOnly bool `protobuf:"varint,12,opt,name=announcementsOnly,proto3" json:"announcementsOnly,omitempty"` - BannedMembers []*BannedMember `protobuf:"bytes,13,rep,name=bannedMembers,proto3" json:"bannedMembers,omitempty"` + state protoimpl.MessageState `protogen:"open.v1"` + PublicKey []byte `protobuf:"bytes,1,opt,name=publicKey,proto3" json:"publicKey,omitempty"` + Title []byte `protobuf:"bytes,2,opt,name=title,proto3" json:"title,omitempty"` + Avatar string `protobuf:"bytes,3,opt,name=avatar,proto3" json:"avatar,omitempty"` + DisappearingMessagesTimer []byte `protobuf:"bytes,4,opt,name=disappearingMessagesTimer,proto3" json:"disappearingMessagesTimer,omitempty"` + AccessControl *AccessControl `protobuf:"bytes,5,opt,name=accessControl,proto3" json:"accessControl,omitempty"` + Revision uint32 `protobuf:"varint,6,opt,name=revision,proto3" json:"revision,omitempty"` + Members []*Member `protobuf:"bytes,7,rep,name=members,proto3" json:"members,omitempty"` + PendingMembers []*PendingMember `protobuf:"bytes,8,rep,name=pendingMembers,proto3" json:"pendingMembers,omitempty"` + RequestingMembers []*RequestingMember `protobuf:"bytes,9,rep,name=requestingMembers,proto3" json:"requestingMembers,omitempty"` + InviteLinkPassword []byte `protobuf:"bytes,10,opt,name=inviteLinkPassword,proto3" json:"inviteLinkPassword,omitempty"` + Description []byte `protobuf:"bytes,11,opt,name=description,proto3" json:"description,omitempty"` + AnnouncementsOnly bool `protobuf:"varint,12,opt,name=announcementsOnly,proto3" json:"announcementsOnly,omitempty"` + BannedMembers []*BannedMember `protobuf:"bytes,13,rep,name=bannedMembers,proto3" json:"bannedMembers,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } func (x *Group) Reset() { @@ -687,13 +680,12 @@ func (x *Group) GetBannedMembers() []*BannedMember { } type GroupChange struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Actions []byte `protobuf:"bytes,1,opt,name=actions,proto3" json:"actions,omitempty"` - ServerSignature []byte `protobuf:"bytes,2,opt,name=serverSignature,proto3" json:"serverSignature,omitempty"` - ChangeEpoch uint32 `protobuf:"varint,3,opt,name=changeEpoch,proto3" json:"changeEpoch,omitempty"` + state protoimpl.MessageState `protogen:"open.v1"` + Actions []byte `protobuf:"bytes,1,opt,name=actions,proto3" json:"actions,omitempty"` + ServerSignature []byte `protobuf:"bytes,2,opt,name=serverSignature,proto3" json:"serverSignature,omitempty"` + ChangeEpoch uint32 `protobuf:"varint,3,opt,name=changeEpoch,proto3" json:"changeEpoch,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } func (x *GroupChange) Reset() { @@ -748,12 +740,11 @@ func (x *GroupChange) GetChangeEpoch() uint32 { } type GroupResponse struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Group *Group `protobuf:"bytes,1,opt,name=group,proto3" json:"group,omitempty"` - GroupSendEndorsementsResponse []byte `protobuf:"bytes,2,opt,name=groupSendEndorsementsResponse,proto3" json:"groupSendEndorsementsResponse,omitempty"` + state protoimpl.MessageState `protogen:"open.v1"` + Group *Group `protobuf:"bytes,1,opt,name=group,proto3" json:"group,omitempty"` + GroupSendEndorsementsResponse []byte `protobuf:"bytes,2,opt,name=groupSendEndorsementsResponse,proto3" json:"groupSendEndorsementsResponse,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } func (x *GroupResponse) Reset() { @@ -801,12 +792,11 @@ func (x *GroupResponse) GetGroupSendEndorsementsResponse() []byte { } type GroupChanges struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - + state protoimpl.MessageState `protogen:"open.v1"` GroupChanges []*GroupChanges_GroupChangeState `protobuf:"bytes,1,rep,name=groupChanges,proto3" json:"groupChanges,omitempty"` GroupSendEndorsementsResponse []byte `protobuf:"bytes,2,opt,name=groupSendEndorsementsResponse,proto3" json:"groupSendEndorsementsResponse,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } func (x *GroupChanges) Reset() { @@ -854,12 +844,11 @@ func (x *GroupChanges) GetGroupSendEndorsementsResponse() []byte { } type GroupChangeResponse struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - GroupChange *GroupChange `protobuf:"bytes,1,opt,name=groupChange,proto3" json:"groupChange,omitempty"` - GroupSendEndorsementsResponse []byte `protobuf:"bytes,2,opt,name=groupSendEndorsementsResponse,proto3" json:"groupSendEndorsementsResponse,omitempty"` + state protoimpl.MessageState `protogen:"open.v1"` + GroupChange *GroupChange `protobuf:"bytes,1,opt,name=groupChange,proto3" json:"groupChange,omitempty"` + GroupSendEndorsementsResponse []byte `protobuf:"bytes,2,opt,name=groupSendEndorsementsResponse,proto3" json:"groupSendEndorsementsResponse,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } func (x *GroupChangeResponse) Reset() { @@ -907,17 +896,16 @@ func (x *GroupChangeResponse) GetGroupSendEndorsementsResponse() []byte { } type GroupAttributeBlob struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // Types that are assignable to Content: + state protoimpl.MessageState `protogen:"open.v1"` + // Types that are valid to be assigned to Content: // // *GroupAttributeBlob_Title // *GroupAttributeBlob_Avatar // *GroupAttributeBlob_DisappearingMessagesDuration // *GroupAttributeBlob_Description - Content isGroupAttributeBlob_Content `protobuf_oneof:"content"` + Content isGroupAttributeBlob_Content `protobuf_oneof:"content"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } func (x *GroupAttributeBlob) Reset() { @@ -950,37 +938,45 @@ func (*GroupAttributeBlob) Descriptor() ([]byte, []int) { return file_Groups_proto_rawDescGZIP(), []int{11} } -func (m *GroupAttributeBlob) GetContent() isGroupAttributeBlob_Content { - if m != nil { - return m.Content +func (x *GroupAttributeBlob) GetContent() isGroupAttributeBlob_Content { + if x != nil { + return x.Content } return nil } func (x *GroupAttributeBlob) GetTitle() string { - if x, ok := x.GetContent().(*GroupAttributeBlob_Title); ok { - return x.Title + if x != nil { + if x, ok := x.Content.(*GroupAttributeBlob_Title); ok { + return x.Title + } } return "" } func (x *GroupAttributeBlob) GetAvatar() []byte { - if x, ok := x.GetContent().(*GroupAttributeBlob_Avatar); ok { - return x.Avatar + if x != nil { + if x, ok := x.Content.(*GroupAttributeBlob_Avatar); ok { + return x.Avatar + } } return nil } func (x *GroupAttributeBlob) GetDisappearingMessagesDuration() uint32 { - if x, ok := x.GetContent().(*GroupAttributeBlob_DisappearingMessagesDuration); ok { - return x.DisappearingMessagesDuration + if x != nil { + if x, ok := x.Content.(*GroupAttributeBlob_DisappearingMessagesDuration); ok { + return x.DisappearingMessagesDuration + } } return 0 } func (x *GroupAttributeBlob) GetDescription() string { - if x, ok := x.GetContent().(*GroupAttributeBlob_Description); ok { - return x.Description + if x != nil { + if x, ok := x.Content.(*GroupAttributeBlob_Description); ok { + return x.Description + } } return "" } @@ -1014,14 +1010,13 @@ func (*GroupAttributeBlob_DisappearingMessagesDuration) isGroupAttributeBlob_Con func (*GroupAttributeBlob_Description) isGroupAttributeBlob_Content() {} type GroupInviteLink struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // Types that are assignable to Contents: + state protoimpl.MessageState `protogen:"open.v1"` + // Types that are valid to be assigned to Contents: // // *GroupInviteLink_V1Contents - Contents isGroupInviteLink_Contents `protobuf_oneof:"contents"` + Contents isGroupInviteLink_Contents `protobuf_oneof:"contents"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } func (x *GroupInviteLink) Reset() { @@ -1054,16 +1049,18 @@ func (*GroupInviteLink) Descriptor() ([]byte, []int) { return file_Groups_proto_rawDescGZIP(), []int{12} } -func (m *GroupInviteLink) GetContents() isGroupInviteLink_Contents { - if m != nil { - return m.Contents +func (x *GroupInviteLink) GetContents() isGroupInviteLink_Contents { + if x != nil { + return x.Contents } return nil } func (x *GroupInviteLink) GetV1Contents() *GroupInviteLink_GroupInviteLinkContentsV1 { - if x, ok := x.GetContents().(*GroupInviteLink_V1Contents); ok { - return x.V1Contents + if x != nil { + if x, ok := x.Contents.(*GroupInviteLink_V1Contents); ok { + return x.V1Contents + } } return nil } @@ -1079,10 +1076,7 @@ type GroupInviteLink_V1Contents struct { func (*GroupInviteLink_V1Contents) isGroupInviteLink_Contents() {} type GroupJoinInfo struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - + state protoimpl.MessageState `protogen:"open.v1"` PublicKey []byte `protobuf:"bytes,1,opt,name=publicKey,proto3" json:"publicKey,omitempty"` Title []byte `protobuf:"bytes,2,opt,name=title,proto3" json:"title,omitempty"` Avatar string `protobuf:"bytes,3,opt,name=avatar,proto3" json:"avatar,omitempty"` @@ -1091,6 +1085,8 @@ type GroupJoinInfo struct { Revision uint32 `protobuf:"varint,6,opt,name=revision,proto3" json:"revision,omitempty"` PendingAdminApproval bool `protobuf:"varint,7,opt,name=pendingAdminApproval,proto3" json:"pendingAdminApproval,omitempty"` Description []byte `protobuf:"bytes,8,opt,name=description,proto3" json:"description,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } func (x *GroupJoinInfo) Reset() { @@ -1180,11 +1176,10 @@ func (x *GroupJoinInfo) GetDescription() []byte { } type GroupExternalCredential struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` + Token string `protobuf:"bytes,1,opt,name=token,proto3" json:"token,omitempty"` unknownFields protoimpl.UnknownFields - - Token string `protobuf:"bytes,1,opt,name=token,proto3" json:"token,omitempty"` + sizeCache protoimpl.SizeCache } func (x *GroupExternalCredential) Reset() { @@ -1225,10 +1220,7 @@ func (x *GroupExternalCredential) GetToken() string { } type GroupChange_Actions struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - + state protoimpl.MessageState `protogen:"open.v1"` SourceServiceId []byte `protobuf:"bytes,1,opt,name=sourceServiceId,proto3" json:"sourceServiceId,omitempty"` GroupId []byte `protobuf:"bytes,25,opt,name=groupId,proto3" json:"groupId,omitempty"` // Only set when receiving from server Revision uint32 `protobuf:"varint,2,opt,name=revision,proto3" json:"revision,omitempty"` @@ -1254,6 +1246,8 @@ type GroupChange_Actions struct { AddBannedMembers []*GroupChange_Actions_AddBannedMemberAction `protobuf:"bytes,22,rep,name=addBannedMembers,proto3" json:"addBannedMembers,omitempty"` DeleteBannedMembers []*GroupChange_Actions_DeleteBannedMemberAction `protobuf:"bytes,23,rep,name=deleteBannedMembers,proto3" json:"deleteBannedMembers,omitempty"` PromotePendingPniAciMembers []*GroupChange_Actions_PromotePendingPniAciMemberProfileKeyAction `protobuf:"bytes,24,rep,name=promotePendingPniAciMembers,proto3" json:"promotePendingPniAciMembers,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } func (x *GroupChange_Actions) Reset() { @@ -1462,12 +1456,11 @@ func (x *GroupChange_Actions) GetPromotePendingPniAciMembers() []*GroupChange_Ac } type GroupChange_Actions_AddMemberAction struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Added *Member `protobuf:"bytes,1,opt,name=added,proto3" json:"added,omitempty"` - JoinFromInviteLink bool `protobuf:"varint,2,opt,name=joinFromInviteLink,proto3" json:"joinFromInviteLink,omitempty"` + state protoimpl.MessageState `protogen:"open.v1"` + Added *Member `protobuf:"bytes,1,opt,name=added,proto3" json:"added,omitempty"` + JoinFromInviteLink bool `protobuf:"varint,2,opt,name=joinFromInviteLink,proto3" json:"joinFromInviteLink,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } func (x *GroupChange_Actions_AddMemberAction) Reset() { @@ -1515,11 +1508,10 @@ func (x *GroupChange_Actions_AddMemberAction) GetJoinFromInviteLink() bool { } type GroupChange_Actions_DeleteMemberAction struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` + DeletedUserId []byte `protobuf:"bytes,1,opt,name=deletedUserId,proto3" json:"deletedUserId,omitempty"` unknownFields protoimpl.UnknownFields - - DeletedUserId []byte `protobuf:"bytes,1,opt,name=deletedUserId,proto3" json:"deletedUserId,omitempty"` + sizeCache protoimpl.SizeCache } func (x *GroupChange_Actions_DeleteMemberAction) Reset() { @@ -1560,12 +1552,11 @@ func (x *GroupChange_Actions_DeleteMemberAction) GetDeletedUserId() []byte { } type GroupChange_Actions_ModifyMemberRoleAction struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` + UserId []byte `protobuf:"bytes,1,opt,name=userId,proto3" json:"userId,omitempty"` + Role Member_Role `protobuf:"varint,2,opt,name=role,proto3,enum=Member_Role" json:"role,omitempty"` unknownFields protoimpl.UnknownFields - - UserId []byte `protobuf:"bytes,1,opt,name=userId,proto3" json:"userId,omitempty"` - Role Member_Role `protobuf:"varint,2,opt,name=role,proto3,enum=Member_Role" json:"role,omitempty"` + sizeCache protoimpl.SizeCache } func (x *GroupChange_Actions_ModifyMemberRoleAction) Reset() { @@ -1613,13 +1604,12 @@ func (x *GroupChange_Actions_ModifyMemberRoleAction) GetRole() Member_Role { } type GroupChange_Actions_ModifyMemberProfileKeyAction struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` + Presentation []byte `protobuf:"bytes,1,opt,name=presentation,proto3" json:"presentation,omitempty"` // Only set when sending to server + UserId []byte `protobuf:"bytes,2,opt,name=user_id,json=userId,proto3" json:"user_id,omitempty"` // Only set when receiving from server + ProfileKey []byte `protobuf:"bytes,3,opt,name=profile_key,json=profileKey,proto3" json:"profile_key,omitempty"` // Only set when receiving from server unknownFields protoimpl.UnknownFields - - Presentation []byte `protobuf:"bytes,1,opt,name=presentation,proto3" json:"presentation,omitempty"` // Only set when sending to server - UserId []byte `protobuf:"bytes,2,opt,name=user_id,json=userId,proto3" json:"user_id,omitempty"` // Only set when receiving from server - ProfileKey []byte `protobuf:"bytes,3,opt,name=profile_key,json=profileKey,proto3" json:"profile_key,omitempty"` // Only set when receiving from server + sizeCache protoimpl.SizeCache } func (x *GroupChange_Actions_ModifyMemberProfileKeyAction) Reset() { @@ -1674,11 +1664,10 @@ func (x *GroupChange_Actions_ModifyMemberProfileKeyAction) GetProfileKey() []byt } type GroupChange_Actions_AddPendingMemberAction struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` + Added *PendingMember `protobuf:"bytes,1,opt,name=added,proto3" json:"added,omitempty"` unknownFields protoimpl.UnknownFields - - Added *PendingMember `protobuf:"bytes,1,opt,name=added,proto3" json:"added,omitempty"` + sizeCache protoimpl.SizeCache } func (x *GroupChange_Actions_AddPendingMemberAction) Reset() { @@ -1719,11 +1708,10 @@ func (x *GroupChange_Actions_AddPendingMemberAction) GetAdded() *PendingMember { } type GroupChange_Actions_DeletePendingMemberAction struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` + DeletedUserId []byte `protobuf:"bytes,1,opt,name=deletedUserId,proto3" json:"deletedUserId,omitempty"` unknownFields protoimpl.UnknownFields - - DeletedUserId []byte `protobuf:"bytes,1,opt,name=deletedUserId,proto3" json:"deletedUserId,omitempty"` + sizeCache protoimpl.SizeCache } func (x *GroupChange_Actions_DeletePendingMemberAction) Reset() { @@ -1764,13 +1752,12 @@ func (x *GroupChange_Actions_DeletePendingMemberAction) GetDeletedUserId() []byt } type GroupChange_Actions_PromotePendingMemberAction struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` + Presentation []byte `protobuf:"bytes,1,opt,name=presentation,proto3" json:"presentation,omitempty"` // Only set when sending to server + UserId []byte `protobuf:"bytes,2,opt,name=user_id,json=userId,proto3" json:"user_id,omitempty"` // Only set when receiving from server + ProfileKey []byte `protobuf:"bytes,3,opt,name=profile_key,json=profileKey,proto3" json:"profile_key,omitempty"` // Only set when receiving from server unknownFields protoimpl.UnknownFields - - Presentation []byte `protobuf:"bytes,1,opt,name=presentation,proto3" json:"presentation,omitempty"` // Only set when sending to server - UserId []byte `protobuf:"bytes,2,opt,name=user_id,json=userId,proto3" json:"user_id,omitempty"` // Only set when receiving from server - ProfileKey []byte `protobuf:"bytes,3,opt,name=profile_key,json=profileKey,proto3" json:"profile_key,omitempty"` // Only set when receiving from server + sizeCache protoimpl.SizeCache } func (x *GroupChange_Actions_PromotePendingMemberAction) Reset() { @@ -1825,14 +1812,13 @@ func (x *GroupChange_Actions_PromotePendingMemberAction) GetProfileKey() []byte } type GroupChange_Actions_PromotePendingPniAciMemberProfileKeyAction struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` + Presentation []byte `protobuf:"bytes,1,opt,name=presentation,proto3" json:"presentation,omitempty"` // Only set when sending to server + UserId []byte `protobuf:"bytes,2,opt,name=userId,proto3" json:"userId,omitempty"` // Only set when receiving from server + Pni []byte `protobuf:"bytes,3,opt,name=pni,proto3" json:"pni,omitempty"` // Only set when receiving from server + ProfileKey []byte `protobuf:"bytes,4,opt,name=profileKey,proto3" json:"profileKey,omitempty"` // Only set when receiving from server unknownFields protoimpl.UnknownFields - - Presentation []byte `protobuf:"bytes,1,opt,name=presentation,proto3" json:"presentation,omitempty"` // Only set when sending to server - UserId []byte `protobuf:"bytes,2,opt,name=userId,proto3" json:"userId,omitempty"` // Only set when receiving from server - Pni []byte `protobuf:"bytes,3,opt,name=pni,proto3" json:"pni,omitempty"` // Only set when receiving from server - ProfileKey []byte `protobuf:"bytes,4,opt,name=profileKey,proto3" json:"profileKey,omitempty"` // Only set when receiving from server + sizeCache protoimpl.SizeCache } func (x *GroupChange_Actions_PromotePendingPniAciMemberProfileKeyAction) Reset() { @@ -1894,11 +1880,10 @@ func (x *GroupChange_Actions_PromotePendingPniAciMemberProfileKeyAction) GetProf } type GroupChange_Actions_AddRequestingMemberAction struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` + Added *RequestingMember `protobuf:"bytes,1,opt,name=added,proto3" json:"added,omitempty"` unknownFields protoimpl.UnknownFields - - Added *RequestingMember `protobuf:"bytes,1,opt,name=added,proto3" json:"added,omitempty"` + sizeCache protoimpl.SizeCache } func (x *GroupChange_Actions_AddRequestingMemberAction) Reset() { @@ -1939,11 +1924,10 @@ func (x *GroupChange_Actions_AddRequestingMemberAction) GetAdded() *RequestingMe } type GroupChange_Actions_DeleteRequestingMemberAction struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` + DeletedUserId []byte `protobuf:"bytes,1,opt,name=deletedUserId,proto3" json:"deletedUserId,omitempty"` unknownFields protoimpl.UnknownFields - - DeletedUserId []byte `protobuf:"bytes,1,opt,name=deletedUserId,proto3" json:"deletedUserId,omitempty"` + sizeCache protoimpl.SizeCache } func (x *GroupChange_Actions_DeleteRequestingMemberAction) Reset() { @@ -1984,12 +1968,11 @@ func (x *GroupChange_Actions_DeleteRequestingMemberAction) GetDeletedUserId() [] } type GroupChange_Actions_PromoteRequestingMemberAction struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` + UserId []byte `protobuf:"bytes,1,opt,name=userId,proto3" json:"userId,omitempty"` + Role Member_Role `protobuf:"varint,2,opt,name=role,proto3,enum=Member_Role" json:"role,omitempty"` unknownFields protoimpl.UnknownFields - - UserId []byte `protobuf:"bytes,1,opt,name=userId,proto3" json:"userId,omitempty"` - Role Member_Role `protobuf:"varint,2,opt,name=role,proto3,enum=Member_Role" json:"role,omitempty"` + sizeCache protoimpl.SizeCache } func (x *GroupChange_Actions_PromoteRequestingMemberAction) Reset() { @@ -2037,11 +2020,10 @@ func (x *GroupChange_Actions_PromoteRequestingMemberAction) GetRole() Member_Rol } type GroupChange_Actions_AddBannedMemberAction struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` + Added *BannedMember `protobuf:"bytes,1,opt,name=added,proto3" json:"added,omitempty"` unknownFields protoimpl.UnknownFields - - Added *BannedMember `protobuf:"bytes,1,opt,name=added,proto3" json:"added,omitempty"` + sizeCache protoimpl.SizeCache } func (x *GroupChange_Actions_AddBannedMemberAction) Reset() { @@ -2082,11 +2064,10 @@ func (x *GroupChange_Actions_AddBannedMemberAction) GetAdded() *BannedMember { } type GroupChange_Actions_DeleteBannedMemberAction struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` + DeletedUserId []byte `protobuf:"bytes,1,opt,name=deletedUserId,proto3" json:"deletedUserId,omitempty"` unknownFields protoimpl.UnknownFields - - DeletedUserId []byte `protobuf:"bytes,1,opt,name=deletedUserId,proto3" json:"deletedUserId,omitempty"` + sizeCache protoimpl.SizeCache } func (x *GroupChange_Actions_DeleteBannedMemberAction) Reset() { @@ -2127,11 +2108,10 @@ func (x *GroupChange_Actions_DeleteBannedMemberAction) GetDeletedUserId() []byte } type GroupChange_Actions_ModifyTitleAction struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` + Title []byte `protobuf:"bytes,1,opt,name=title,proto3" json:"title,omitempty"` unknownFields protoimpl.UnknownFields - - Title []byte `protobuf:"bytes,1,opt,name=title,proto3" json:"title,omitempty"` + sizeCache protoimpl.SizeCache } func (x *GroupChange_Actions_ModifyTitleAction) Reset() { @@ -2172,11 +2152,10 @@ func (x *GroupChange_Actions_ModifyTitleAction) GetTitle() []byte { } type GroupChange_Actions_ModifyDescriptionAction struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` + Description []byte `protobuf:"bytes,1,opt,name=description,proto3" json:"description,omitempty"` unknownFields protoimpl.UnknownFields - - Description []byte `protobuf:"bytes,1,opt,name=description,proto3" json:"description,omitempty"` + sizeCache protoimpl.SizeCache } func (x *GroupChange_Actions_ModifyDescriptionAction) Reset() { @@ -2217,11 +2196,10 @@ func (x *GroupChange_Actions_ModifyDescriptionAction) GetDescription() []byte { } type GroupChange_Actions_ModifyAvatarAction struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` + Avatar string `protobuf:"bytes,1,opt,name=avatar,proto3" json:"avatar,omitempty"` unknownFields protoimpl.UnknownFields - - Avatar string `protobuf:"bytes,1,opt,name=avatar,proto3" json:"avatar,omitempty"` + sizeCache protoimpl.SizeCache } func (x *GroupChange_Actions_ModifyAvatarAction) Reset() { @@ -2262,11 +2240,10 @@ func (x *GroupChange_Actions_ModifyAvatarAction) GetAvatar() string { } type GroupChange_Actions_ModifyDisappearingMessagesTimerAction struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` + Timer []byte `protobuf:"bytes,1,opt,name=timer,proto3" json:"timer,omitempty"` unknownFields protoimpl.UnknownFields - - Timer []byte `protobuf:"bytes,1,opt,name=timer,proto3" json:"timer,omitempty"` + sizeCache protoimpl.SizeCache } func (x *GroupChange_Actions_ModifyDisappearingMessagesTimerAction) Reset() { @@ -2307,11 +2284,10 @@ func (x *GroupChange_Actions_ModifyDisappearingMessagesTimerAction) GetTimer() [ } type GroupChange_Actions_ModifyAttributesAccessControlAction struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - + state protoimpl.MessageState `protogen:"open.v1"` AttributesAccess AccessControl_AccessRequired `protobuf:"varint,1,opt,name=attributesAccess,proto3,enum=AccessControl_AccessRequired" json:"attributesAccess,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } func (x *GroupChange_Actions_ModifyAttributesAccessControlAction) Reset() { @@ -2352,11 +2328,10 @@ func (x *GroupChange_Actions_ModifyAttributesAccessControlAction) GetAttributesA } type GroupChange_Actions_ModifyMembersAccessControlAction struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - + state protoimpl.MessageState `protogen:"open.v1"` MembersAccess AccessControl_AccessRequired `protobuf:"varint,1,opt,name=membersAccess,proto3,enum=AccessControl_AccessRequired" json:"membersAccess,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } func (x *GroupChange_Actions_ModifyMembersAccessControlAction) Reset() { @@ -2397,11 +2372,10 @@ func (x *GroupChange_Actions_ModifyMembersAccessControlAction) GetMembersAccess( } type GroupChange_Actions_ModifyAddFromInviteLinkAccessControlAction struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - + state protoimpl.MessageState `protogen:"open.v1"` AddFromInviteLinkAccess AccessControl_AccessRequired `protobuf:"varint,1,opt,name=addFromInviteLinkAccess,proto3,enum=AccessControl_AccessRequired" json:"addFromInviteLinkAccess,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } func (x *GroupChange_Actions_ModifyAddFromInviteLinkAccessControlAction) Reset() { @@ -2442,11 +2416,10 @@ func (x *GroupChange_Actions_ModifyAddFromInviteLinkAccessControlAction) GetAddF } type GroupChange_Actions_ModifyInviteLinkPasswordAction struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - InviteLinkPassword []byte `protobuf:"bytes,1,opt,name=inviteLinkPassword,proto3" json:"inviteLinkPassword,omitempty"` + state protoimpl.MessageState `protogen:"open.v1"` + InviteLinkPassword []byte `protobuf:"bytes,1,opt,name=inviteLinkPassword,proto3" json:"inviteLinkPassword,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } func (x *GroupChange_Actions_ModifyInviteLinkPasswordAction) Reset() { @@ -2487,11 +2460,10 @@ func (x *GroupChange_Actions_ModifyInviteLinkPasswordAction) GetInviteLinkPasswo } type GroupChange_Actions_ModifyAnnouncementsOnlyAction struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - AnnouncementsOnly bool `protobuf:"varint,1,opt,name=announcementsOnly,proto3" json:"announcementsOnly,omitempty"` + state protoimpl.MessageState `protogen:"open.v1"` + AnnouncementsOnly bool `protobuf:"varint,1,opt,name=announcementsOnly,proto3" json:"announcementsOnly,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } func (x *GroupChange_Actions_ModifyAnnouncementsOnlyAction) Reset() { @@ -2532,12 +2504,11 @@ func (x *GroupChange_Actions_ModifyAnnouncementsOnlyAction) GetAnnouncementsOnly } type GroupChanges_GroupChangeState struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` + GroupChange *GroupChange `protobuf:"bytes,1,opt,name=groupChange,proto3" json:"groupChange,omitempty"` + GroupState *Group `protobuf:"bytes,2,opt,name=groupState,proto3" json:"groupState,omitempty"` unknownFields protoimpl.UnknownFields - - GroupChange *GroupChange `protobuf:"bytes,1,opt,name=groupChange,proto3" json:"groupChange,omitempty"` - GroupState *Group `protobuf:"bytes,2,opt,name=groupState,proto3" json:"groupState,omitempty"` + sizeCache protoimpl.SizeCache } func (x *GroupChanges_GroupChangeState) Reset() { @@ -2585,12 +2556,11 @@ func (x *GroupChanges_GroupChangeState) GetGroupState() *Group { } type GroupInviteLink_GroupInviteLinkContentsV1 struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - GroupMasterKey []byte `protobuf:"bytes,1,opt,name=groupMasterKey,proto3" json:"groupMasterKey,omitempty"` - InviteLinkPassword []byte `protobuf:"bytes,2,opt,name=inviteLinkPassword,proto3" json:"inviteLinkPassword,omitempty"` + state protoimpl.MessageState `protogen:"open.v1"` + GroupMasterKey []byte `protobuf:"bytes,1,opt,name=groupMasterKey,proto3" json:"groupMasterKey,omitempty"` + InviteLinkPassword []byte `protobuf:"bytes,2,opt,name=inviteLinkPassword,proto3" json:"inviteLinkPassword,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } func (x *GroupInviteLink_GroupInviteLinkContentsV1) Reset() { diff --git a/pkg/signalmeow/protobuf/Provisioning.pb.go b/pkg/signalmeow/protobuf/Provisioning.pb.go index a1d3f0b..97c5adc 100644 --- a/pkg/signalmeow/protobuf/Provisioning.pb.go +++ b/pkg/signalmeow/protobuf/Provisioning.pb.go @@ -5,7 +5,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.35.2 +// protoc-gen-go v1.36.1 // protoc v3.21.12 // source: Provisioning.proto @@ -87,11 +87,10 @@ func (ProvisioningVersion) EnumDescriptor() ([]byte, []int) { } type ProvisioningAddress struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` + Address *string `protobuf:"bytes,1,opt,name=address" json:"address,omitempty"` unknownFields protoimpl.UnknownFields - - Address *string `protobuf:"bytes,1,opt,name=address" json:"address,omitempty"` + sizeCache protoimpl.SizeCache } func (x *ProvisioningAddress) Reset() { @@ -132,12 +131,11 @@ func (x *ProvisioningAddress) GetAddress() string { } type ProvisionEnvelope struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` + PublicKey []byte `protobuf:"bytes,1,opt,name=publicKey" json:"publicKey,omitempty"` + Body []byte `protobuf:"bytes,2,opt,name=body" json:"body,omitempty"` // Encrypted ProvisionMessage unknownFields protoimpl.UnknownFields - - PublicKey []byte `protobuf:"bytes,1,opt,name=publicKey" json:"publicKey,omitempty"` - Body []byte `protobuf:"bytes,2,opt,name=body" json:"body,omitempty"` // Encrypted ProvisionMessage + sizeCache protoimpl.SizeCache } func (x *ProvisionEnvelope) Reset() { @@ -185,26 +183,25 @@ func (x *ProvisionEnvelope) GetBody() []byte { } type ProvisionMessage struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - AciIdentityKeyPublic []byte `protobuf:"bytes,1,opt,name=aciIdentityKeyPublic" json:"aciIdentityKeyPublic,omitempty"` - AciIdentityKeyPrivate []byte `protobuf:"bytes,2,opt,name=aciIdentityKeyPrivate" json:"aciIdentityKeyPrivate,omitempty"` - PniIdentityKeyPublic []byte `protobuf:"bytes,11,opt,name=pniIdentityKeyPublic" json:"pniIdentityKeyPublic,omitempty"` - PniIdentityKeyPrivate []byte `protobuf:"bytes,12,opt,name=pniIdentityKeyPrivate" json:"pniIdentityKeyPrivate,omitempty"` - Aci *string `protobuf:"bytes,8,opt,name=aci" json:"aci,omitempty"` - Pni *string `protobuf:"bytes,10,opt,name=pni" json:"pni,omitempty"` - Number *string `protobuf:"bytes,3,opt,name=number" json:"number,omitempty"` - ProvisioningCode *string `protobuf:"bytes,4,opt,name=provisioningCode" json:"provisioningCode,omitempty"` - UserAgent *string `protobuf:"bytes,5,opt,name=userAgent" json:"userAgent,omitempty"` - ProfileKey []byte `protobuf:"bytes,6,opt,name=profileKey" json:"profileKey,omitempty"` - ReadReceipts *bool `protobuf:"varint,7,opt,name=readReceipts" json:"readReceipts,omitempty"` - ProvisioningVersion *uint32 `protobuf:"varint,9,opt,name=provisioningVersion" json:"provisioningVersion,omitempty"` - MasterKey []byte `protobuf:"bytes,13,opt,name=masterKey" json:"masterKey,omitempty"` - EphemeralBackupKey []byte `protobuf:"bytes,14,opt,name=ephemeralBackupKey" json:"ephemeralBackupKey,omitempty"` // 32 bytes - AccountEntropyPool *string `protobuf:"bytes,15,opt,name=accountEntropyPool" json:"accountEntropyPool,omitempty"` - MediaRootBackupKey []byte `protobuf:"bytes,16,opt,name=mediaRootBackupKey" json:"mediaRootBackupKey,omitempty"` // 32-bytes + state protoimpl.MessageState `protogen:"open.v1"` + AciIdentityKeyPublic []byte `protobuf:"bytes,1,opt,name=aciIdentityKeyPublic" json:"aciIdentityKeyPublic,omitempty"` + AciIdentityKeyPrivate []byte `protobuf:"bytes,2,opt,name=aciIdentityKeyPrivate" json:"aciIdentityKeyPrivate,omitempty"` + PniIdentityKeyPublic []byte `protobuf:"bytes,11,opt,name=pniIdentityKeyPublic" json:"pniIdentityKeyPublic,omitempty"` + PniIdentityKeyPrivate []byte `protobuf:"bytes,12,opt,name=pniIdentityKeyPrivate" json:"pniIdentityKeyPrivate,omitempty"` + Aci *string `protobuf:"bytes,8,opt,name=aci" json:"aci,omitempty"` + Pni *string `protobuf:"bytes,10,opt,name=pni" json:"pni,omitempty"` + Number *string `protobuf:"bytes,3,opt,name=number" json:"number,omitempty"` + ProvisioningCode *string `protobuf:"bytes,4,opt,name=provisioningCode" json:"provisioningCode,omitempty"` + UserAgent *string `protobuf:"bytes,5,opt,name=userAgent" json:"userAgent,omitempty"` + ProfileKey []byte `protobuf:"bytes,6,opt,name=profileKey" json:"profileKey,omitempty"` + ReadReceipts *bool `protobuf:"varint,7,opt,name=readReceipts" json:"readReceipts,omitempty"` + ProvisioningVersion *uint32 `protobuf:"varint,9,opt,name=provisioningVersion" json:"provisioningVersion,omitempty"` + MasterKey []byte `protobuf:"bytes,13,opt,name=masterKey" json:"masterKey,omitempty"` + EphemeralBackupKey []byte `protobuf:"bytes,14,opt,name=ephemeralBackupKey" json:"ephemeralBackupKey,omitempty"` // 32 bytes + AccountEntropyPool *string `protobuf:"bytes,15,opt,name=accountEntropyPool" json:"accountEntropyPool,omitempty"` + MediaRootBackupKey []byte `protobuf:"bytes,16,opt,name=mediaRootBackupKey" json:"mediaRootBackupKey,omitempty"` // 32-bytes + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } func (x *ProvisionMessage) Reset() { diff --git a/pkg/signalmeow/protobuf/SignalService.pb.go b/pkg/signalmeow/protobuf/SignalService.pb.go index a633e85..aed9592 100644 --- a/pkg/signalmeow/protobuf/SignalService.pb.go +++ b/pkg/signalmeow/protobuf/SignalService.pb.go @@ -5,7 +5,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.35.2 +// protoc-gen-go v1.36.1 // protoc v3.21.12 // source: SignalService.proto @@ -1700,21 +1700,20 @@ func (GroupContext_Type) EnumDescriptor() ([]byte, []int) { } type Envelope struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Type *Envelope_Type `protobuf:"varint,1,opt,name=type,enum=signalservice.Envelope_Type" json:"type,omitempty"` - SourceServiceId *string `protobuf:"bytes,11,opt,name=sourceServiceId" json:"sourceServiceId,omitempty"` - SourceDevice *uint32 `protobuf:"varint,7,opt,name=sourceDevice" json:"sourceDevice,omitempty"` - DestinationServiceId *string `protobuf:"bytes,13,opt,name=destinationServiceId" json:"destinationServiceId,omitempty"` - Timestamp *uint64 `protobuf:"varint,5,opt,name=timestamp" json:"timestamp,omitempty"` - Content []byte `protobuf:"bytes,8,opt,name=content" json:"content,omitempty"` // Contains an encrypted Content - ServerGuid *string `protobuf:"bytes,9,opt,name=serverGuid" json:"serverGuid,omitempty"` - ServerTimestamp *uint64 `protobuf:"varint,10,opt,name=serverTimestamp" json:"serverTimestamp,omitempty"` - Urgent *bool `protobuf:"varint,14,opt,name=urgent,def=1" json:"urgent,omitempty"` - Story *bool `protobuf:"varint,16,opt,name=story" json:"story,omitempty"` - ReportingToken []byte `protobuf:"bytes,17,opt,name=reportingToken" json:"reportingToken,omitempty"` + state protoimpl.MessageState `protogen:"open.v1"` + Type *Envelope_Type `protobuf:"varint,1,opt,name=type,enum=signalservice.Envelope_Type" json:"type,omitempty"` + SourceServiceId *string `protobuf:"bytes,11,opt,name=sourceServiceId" json:"sourceServiceId,omitempty"` + SourceDevice *uint32 `protobuf:"varint,7,opt,name=sourceDevice" json:"sourceDevice,omitempty"` + DestinationServiceId *string `protobuf:"bytes,13,opt,name=destinationServiceId" json:"destinationServiceId,omitempty"` + Timestamp *uint64 `protobuf:"varint,5,opt,name=timestamp" json:"timestamp,omitempty"` + Content []byte `protobuf:"bytes,8,opt,name=content" json:"content,omitempty"` // Contains an encrypted Content + ServerGuid *string `protobuf:"bytes,9,opt,name=serverGuid" json:"serverGuid,omitempty"` + ServerTimestamp *uint64 `protobuf:"varint,10,opt,name=serverTimestamp" json:"serverTimestamp,omitempty"` + Urgent *bool `protobuf:"varint,14,opt,name=urgent,def=1" json:"urgent,omitempty"` + Story *bool `protobuf:"varint,16,opt,name=story" json:"story,omitempty"` + ReportingToken []byte `protobuf:"bytes,17,opt,name=reportingToken" json:"reportingToken,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } // Default values for Envelope fields. @@ -1830,21 +1829,20 @@ func (x *Envelope) GetReportingToken() []byte { } type Content struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - DataMessage *DataMessage `protobuf:"bytes,1,opt,name=dataMessage" json:"dataMessage,omitempty"` - SyncMessage *SyncMessage `protobuf:"bytes,2,opt,name=syncMessage" json:"syncMessage,omitempty"` - CallMessage *CallMessage `protobuf:"bytes,3,opt,name=callMessage" json:"callMessage,omitempty"` - NullMessage *NullMessage `protobuf:"bytes,4,opt,name=nullMessage" json:"nullMessage,omitempty"` - ReceiptMessage *ReceiptMessage `protobuf:"bytes,5,opt,name=receiptMessage" json:"receiptMessage,omitempty"` - TypingMessage *TypingMessage `protobuf:"bytes,6,opt,name=typingMessage" json:"typingMessage,omitempty"` - SenderKeyDistributionMessage []byte `protobuf:"bytes,7,opt,name=senderKeyDistributionMessage" json:"senderKeyDistributionMessage,omitempty"` - DecryptionErrorMessage []byte `protobuf:"bytes,8,opt,name=decryptionErrorMessage" json:"decryptionErrorMessage,omitempty"` - StoryMessage *StoryMessage `protobuf:"bytes,9,opt,name=storyMessage" json:"storyMessage,omitempty"` - PniSignatureMessage *PniSignatureMessage `protobuf:"bytes,10,opt,name=pniSignatureMessage" json:"pniSignatureMessage,omitempty"` - EditMessage *EditMessage `protobuf:"bytes,11,opt,name=editMessage" json:"editMessage,omitempty"` + state protoimpl.MessageState `protogen:"open.v1"` + DataMessage *DataMessage `protobuf:"bytes,1,opt,name=dataMessage" json:"dataMessage,omitempty"` + SyncMessage *SyncMessage `protobuf:"bytes,2,opt,name=syncMessage" json:"syncMessage,omitempty"` + CallMessage *CallMessage `protobuf:"bytes,3,opt,name=callMessage" json:"callMessage,omitempty"` + NullMessage *NullMessage `protobuf:"bytes,4,opt,name=nullMessage" json:"nullMessage,omitempty"` + ReceiptMessage *ReceiptMessage `protobuf:"bytes,5,opt,name=receiptMessage" json:"receiptMessage,omitempty"` + TypingMessage *TypingMessage `protobuf:"bytes,6,opt,name=typingMessage" json:"typingMessage,omitempty"` + SenderKeyDistributionMessage []byte `protobuf:"bytes,7,opt,name=senderKeyDistributionMessage" json:"senderKeyDistributionMessage,omitempty"` + DecryptionErrorMessage []byte `protobuf:"bytes,8,opt,name=decryptionErrorMessage" json:"decryptionErrorMessage,omitempty"` + StoryMessage *StoryMessage `protobuf:"bytes,9,opt,name=storyMessage" json:"storyMessage,omitempty"` + PniSignatureMessage *PniSignatureMessage `protobuf:"bytes,10,opt,name=pniSignatureMessage" json:"pniSignatureMessage,omitempty"` + EditMessage *EditMessage `protobuf:"bytes,11,opt,name=editMessage" json:"editMessage,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } func (x *Content) Reset() { @@ -1955,10 +1953,7 @@ func (x *Content) GetEditMessage() *EditMessage { } type CallMessage struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - + state protoimpl.MessageState `protogen:"open.v1"` Offer *CallMessage_Offer `protobuf:"bytes,1,opt,name=offer" json:"offer,omitempty"` Answer *CallMessage_Answer `protobuf:"bytes,2,opt,name=answer" json:"answer,omitempty"` IceUpdate []*CallMessage_IceUpdate `protobuf:"bytes,3,rep,name=iceUpdate" json:"iceUpdate,omitempty"` @@ -1966,6 +1961,8 @@ type CallMessage struct { Hangup *CallMessage_Hangup `protobuf:"bytes,7,opt,name=hangup" json:"hangup,omitempty"` DestinationDeviceId *uint32 `protobuf:"varint,9,opt,name=destinationDeviceId" json:"destinationDeviceId,omitempty"` Opaque *CallMessage_Opaque `protobuf:"bytes,10,opt,name=opaque" json:"opaque,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } func (x *CallMessage) Reset() { @@ -2048,17 +2045,16 @@ func (x *CallMessage) GetOpaque() *CallMessage_Opaque { } type BodyRange struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Start *uint32 `protobuf:"varint,1,opt,name=start" json:"start,omitempty"` - Length *uint32 `protobuf:"varint,2,opt,name=length" json:"length,omitempty"` - // Types that are assignable to AssociatedValue: + state protoimpl.MessageState `protogen:"open.v1"` + Start *uint32 `protobuf:"varint,1,opt,name=start" json:"start,omitempty"` + Length *uint32 `protobuf:"varint,2,opt,name=length" json:"length,omitempty"` + // Types that are valid to be assigned to AssociatedValue: // // *BodyRange_MentionAci // *BodyRange_Style_ AssociatedValue isBodyRange_AssociatedValue `protobuf_oneof:"associatedValue"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } func (x *BodyRange) Reset() { @@ -2105,23 +2101,27 @@ func (x *BodyRange) GetLength() uint32 { return 0 } -func (m *BodyRange) GetAssociatedValue() isBodyRange_AssociatedValue { - if m != nil { - return m.AssociatedValue +func (x *BodyRange) GetAssociatedValue() isBodyRange_AssociatedValue { + if x != nil { + return x.AssociatedValue } return nil } func (x *BodyRange) GetMentionAci() string { - if x, ok := x.GetAssociatedValue().(*BodyRange_MentionAci); ok { - return x.MentionAci + if x != nil { + if x, ok := x.AssociatedValue.(*BodyRange_MentionAci); ok { + return x.MentionAci + } } return "" } func (x *BodyRange) GetStyle() BodyRange_Style { - if x, ok := x.GetAssociatedValue().(*BodyRange_Style_); ok { - return x.Style + if x != nil { + if x, ok := x.AssociatedValue.(*BodyRange_Style_); ok { + return x.Style + } } return BodyRange_NONE } @@ -2143,10 +2143,7 @@ func (*BodyRange_MentionAci) isBodyRange_AssociatedValue() {} func (*BodyRange_Style_) isBodyRange_AssociatedValue() {} type DataMessage struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - + state protoimpl.MessageState `protogen:"open.v1"` Body *string `protobuf:"bytes,1,opt,name=body" json:"body,omitempty"` Attachments []*AttachmentPointer `protobuf:"bytes,2,rep,name=attachments" json:"attachments,omitempty"` GroupV2 *GroupContextV2 `protobuf:"bytes,15,opt,name=groupV2" json:"groupV2,omitempty"` @@ -2168,6 +2165,8 @@ type DataMessage struct { Payment *DataMessage_Payment `protobuf:"bytes,20,opt,name=payment" json:"payment,omitempty"` StoryContext *DataMessage_StoryContext `protobuf:"bytes,21,opt,name=storyContext" json:"storyContext,omitempty"` GiftBadge *DataMessage_GiftBadge `protobuf:"bytes,22,opt,name=giftBadge" json:"giftBadge,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } func (x *DataMessage) Reset() { @@ -2348,11 +2347,10 @@ func (x *DataMessage) GetGiftBadge() *DataMessage_GiftBadge { } type NullMessage struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` + Padding []byte `protobuf:"bytes,1,opt,name=padding" json:"padding,omitempty"` unknownFields protoimpl.UnknownFields - - Padding []byte `protobuf:"bytes,1,opt,name=padding" json:"padding,omitempty"` + sizeCache protoimpl.SizeCache } func (x *NullMessage) Reset() { @@ -2393,12 +2391,11 @@ func (x *NullMessage) GetPadding() []byte { } type ReceiptMessage struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` + Type *ReceiptMessage_Type `protobuf:"varint,1,opt,name=type,enum=signalservice.ReceiptMessage_Type" json:"type,omitempty"` + Timestamp []uint64 `protobuf:"varint,2,rep,name=timestamp" json:"timestamp,omitempty"` unknownFields protoimpl.UnknownFields - - Type *ReceiptMessage_Type `protobuf:"varint,1,opt,name=type,enum=signalservice.ReceiptMessage_Type" json:"type,omitempty"` - Timestamp []uint64 `protobuf:"varint,2,rep,name=timestamp" json:"timestamp,omitempty"` + sizeCache protoimpl.SizeCache } func (x *ReceiptMessage) Reset() { @@ -2446,13 +2443,12 @@ func (x *ReceiptMessage) GetTimestamp() []uint64 { } type TypingMessage struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` + Timestamp *uint64 `protobuf:"varint,1,opt,name=timestamp" json:"timestamp,omitempty"` + Action *TypingMessage_Action `protobuf:"varint,2,opt,name=action,enum=signalservice.TypingMessage_Action" json:"action,omitempty"` + GroupId []byte `protobuf:"bytes,3,opt,name=groupId" json:"groupId,omitempty"` unknownFields protoimpl.UnknownFields - - Timestamp *uint64 `protobuf:"varint,1,opt,name=timestamp" json:"timestamp,omitempty"` - Action *TypingMessage_Action `protobuf:"varint,2,opt,name=action,enum=signalservice.TypingMessage_Action" json:"action,omitempty"` - GroupId []byte `protobuf:"bytes,3,opt,name=groupId" json:"groupId,omitempty"` + sizeCache protoimpl.SizeCache } func (x *TypingMessage) Reset() { @@ -2507,19 +2503,18 @@ func (x *TypingMessage) GetGroupId() []byte { } type StoryMessage struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - ProfileKey []byte `protobuf:"bytes,1,opt,name=profileKey" json:"profileKey,omitempty"` - Group *GroupContextV2 `protobuf:"bytes,2,opt,name=group" json:"group,omitempty"` - // Types that are assignable to Attachment: + state protoimpl.MessageState `protogen:"open.v1"` + ProfileKey []byte `protobuf:"bytes,1,opt,name=profileKey" json:"profileKey,omitempty"` + Group *GroupContextV2 `protobuf:"bytes,2,opt,name=group" json:"group,omitempty"` + // Types that are valid to be assigned to Attachment: // // *StoryMessage_FileAttachment // *StoryMessage_TextAttachment Attachment isStoryMessage_Attachment `protobuf_oneof:"attachment"` AllowsReplies *bool `protobuf:"varint,5,opt,name=allowsReplies" json:"allowsReplies,omitempty"` BodyRanges []*BodyRange `protobuf:"bytes,6,rep,name=bodyRanges" json:"bodyRanges,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } func (x *StoryMessage) Reset() { @@ -2566,23 +2561,27 @@ func (x *StoryMessage) GetGroup() *GroupContextV2 { return nil } -func (m *StoryMessage) GetAttachment() isStoryMessage_Attachment { - if m != nil { - return m.Attachment +func (x *StoryMessage) GetAttachment() isStoryMessage_Attachment { + if x != nil { + return x.Attachment } return nil } func (x *StoryMessage) GetFileAttachment() *AttachmentPointer { - if x, ok := x.GetAttachment().(*StoryMessage_FileAttachment); ok { - return x.FileAttachment + if x != nil { + if x, ok := x.Attachment.(*StoryMessage_FileAttachment); ok { + return x.FileAttachment + } } return nil } func (x *StoryMessage) GetTextAttachment() *TextAttachment { - if x, ok := x.GetAttachment().(*StoryMessage_TextAttachment); ok { - return x.TextAttachment + if x != nil { + if x, ok := x.Attachment.(*StoryMessage_TextAttachment); ok { + return x.TextAttachment + } } return nil } @@ -2618,15 +2617,14 @@ func (*StoryMessage_FileAttachment) isStoryMessage_Attachment() {} func (*StoryMessage_TextAttachment) isStoryMessage_Attachment() {} type Preview struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` + Url *string `protobuf:"bytes,1,opt,name=url" json:"url,omitempty"` + Title *string `protobuf:"bytes,2,opt,name=title" json:"title,omitempty"` + Image *AttachmentPointer `protobuf:"bytes,3,opt,name=image" json:"image,omitempty"` + Description *string `protobuf:"bytes,4,opt,name=description" json:"description,omitempty"` + Date *uint64 `protobuf:"varint,5,opt,name=date" json:"date,omitempty"` unknownFields protoimpl.UnknownFields - - Url *string `protobuf:"bytes,1,opt,name=url" json:"url,omitempty"` - Title *string `protobuf:"bytes,2,opt,name=title" json:"title,omitempty"` - Image *AttachmentPointer `protobuf:"bytes,3,opt,name=image" json:"image,omitempty"` - Description *string `protobuf:"bytes,4,opt,name=description" json:"description,omitempty"` - Date *uint64 `protobuf:"varint,5,opt,name=date" json:"date,omitempty"` + sizeCache protoimpl.SizeCache } func (x *Preview) Reset() { @@ -2695,20 +2693,19 @@ func (x *Preview) GetDate() uint64 { } type TextAttachment struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Text *string `protobuf:"bytes,1,opt,name=text" json:"text,omitempty"` - TextStyle *TextAttachment_Style `protobuf:"varint,2,opt,name=textStyle,enum=signalservice.TextAttachment_Style" json:"textStyle,omitempty"` - TextForegroundColor *uint32 `protobuf:"varint,3,opt,name=textForegroundColor" json:"textForegroundColor,omitempty"` // integer representation of hex color - TextBackgroundColor *uint32 `protobuf:"varint,4,opt,name=textBackgroundColor" json:"textBackgroundColor,omitempty"` - Preview *Preview `protobuf:"bytes,5,opt,name=preview" json:"preview,omitempty"` - // Types that are assignable to Background: + state protoimpl.MessageState `protogen:"open.v1"` + Text *string `protobuf:"bytes,1,opt,name=text" json:"text,omitempty"` + TextStyle *TextAttachment_Style `protobuf:"varint,2,opt,name=textStyle,enum=signalservice.TextAttachment_Style" json:"textStyle,omitempty"` + TextForegroundColor *uint32 `protobuf:"varint,3,opt,name=textForegroundColor" json:"textForegroundColor,omitempty"` // integer representation of hex color + TextBackgroundColor *uint32 `protobuf:"varint,4,opt,name=textBackgroundColor" json:"textBackgroundColor,omitempty"` + Preview *Preview `protobuf:"bytes,5,opt,name=preview" json:"preview,omitempty"` + // Types that are valid to be assigned to Background: // // *TextAttachment_Gradient_ // *TextAttachment_Color - Background isTextAttachment_Background `protobuf_oneof:"background"` + Background isTextAttachment_Background `protobuf_oneof:"background"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } func (x *TextAttachment) Reset() { @@ -2776,23 +2773,27 @@ func (x *TextAttachment) GetPreview() *Preview { return nil } -func (m *TextAttachment) GetBackground() isTextAttachment_Background { - if m != nil { - return m.Background +func (x *TextAttachment) GetBackground() isTextAttachment_Background { + if x != nil { + return x.Background } return nil } func (x *TextAttachment) GetGradient() *TextAttachment_Gradient { - if x, ok := x.GetBackground().(*TextAttachment_Gradient_); ok { - return x.Gradient + if x != nil { + if x, ok := x.Background.(*TextAttachment_Gradient_); ok { + return x.Gradient + } } return nil } func (x *TextAttachment) GetColor() uint32 { - if x, ok := x.GetBackground().(*TextAttachment_Color); ok { - return x.Color + if x != nil { + if x, ok := x.Background.(*TextAttachment_Color); ok { + return x.Color + } } return 0 } @@ -2814,14 +2815,13 @@ func (*TextAttachment_Gradient_) isTextAttachment_Background() {} func (*TextAttachment_Color) isTextAttachment_Background() {} type Verified struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - DestinationAci *string `protobuf:"bytes,5,opt,name=destinationAci" json:"destinationAci,omitempty"` - IdentityKey []byte `protobuf:"bytes,2,opt,name=identityKey" json:"identityKey,omitempty"` - State *Verified_State `protobuf:"varint,3,opt,name=state,enum=signalservice.Verified_State" json:"state,omitempty"` - NullMessage []byte `protobuf:"bytes,4,opt,name=nullMessage" json:"nullMessage,omitempty"` + state protoimpl.MessageState `protogen:"open.v1"` + DestinationAci *string `protobuf:"bytes,5,opt,name=destinationAci" json:"destinationAci,omitempty"` + IdentityKey []byte `protobuf:"bytes,2,opt,name=identityKey" json:"identityKey,omitempty"` + State *Verified_State `protobuf:"varint,3,opt,name=state,enum=signalservice.Verified_State" json:"state,omitempty"` + NullMessage []byte `protobuf:"bytes,4,opt,name=nullMessage" json:"nullMessage,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } func (x *Verified) Reset() { @@ -2883,10 +2883,7 @@ func (x *Verified) GetNullMessage() []byte { } type SyncMessage struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - + state protoimpl.MessageState `protogen:"open.v1"` Sent *SyncMessage_Sent `protobuf:"bytes,1,opt,name=sent" json:"sent,omitempty"` Contacts *SyncMessage_Contacts `protobuf:"bytes,2,opt,name=contacts" json:"contacts,omitempty"` Request *SyncMessage_Request `protobuf:"bytes,4,opt,name=request" json:"request,omitempty"` @@ -2908,6 +2905,8 @@ type SyncMessage struct { CallLogEvent *SyncMessage_CallLogEvent `protobuf:"bytes,21,opt,name=callLogEvent" json:"callLogEvent,omitempty"` DeleteForMe *SyncMessage_DeleteForMe `protobuf:"bytes,22,opt,name=deleteForMe" json:"deleteForMe,omitempty"` DeviceNameChange *SyncMessage_DeviceNameChange `protobuf:"bytes,23,opt,name=deviceNameChange" json:"deviceNameChange,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } func (x *SyncMessage) Reset() { @@ -3088,11 +3087,8 @@ func (x *SyncMessage) GetDeviceNameChange() *SyncMessage_DeviceNameChange { } type AttachmentPointer struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // Types that are assignable to AttachmentIdentifier: + state protoimpl.MessageState `protogen:"open.v1"` + // Types that are valid to be assigned to AttachmentIdentifier: // // *AttachmentPointer_CdnId // *AttachmentPointer_CdnKey @@ -3113,6 +3109,8 @@ type AttachmentPointer struct { UploadTimestamp *uint64 `protobuf:"varint,13,opt,name=uploadTimestamp" json:"uploadTimestamp,omitempty"` CdnNumber *uint32 `protobuf:"varint,14,opt,name=cdnNumber" json:"cdnNumber,omitempty"` Uuid []byte `protobuf:"bytes,20,opt,name=uuid" json:"uuid,omitempty"` // Next ID: 21 + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } func (x *AttachmentPointer) Reset() { @@ -3145,23 +3143,27 @@ func (*AttachmentPointer) Descriptor() ([]byte, []int) { return file_SignalService_proto_rawDescGZIP(), []int{13} } -func (m *AttachmentPointer) GetAttachmentIdentifier() isAttachmentPointer_AttachmentIdentifier { - if m != nil { - return m.AttachmentIdentifier +func (x *AttachmentPointer) GetAttachmentIdentifier() isAttachmentPointer_AttachmentIdentifier { + if x != nil { + return x.AttachmentIdentifier } return nil } func (x *AttachmentPointer) GetCdnId() uint64 { - if x, ok := x.GetAttachmentIdentifier().(*AttachmentPointer_CdnId); ok { - return x.CdnId + if x != nil { + if x, ok := x.AttachmentIdentifier.(*AttachmentPointer_CdnId); ok { + return x.CdnId + } } return 0 } func (x *AttachmentPointer) GetCdnKey() string { - if x, ok := x.GetAttachmentIdentifier().(*AttachmentPointer_CdnKey); ok { - return x.CdnKey + if x != nil { + if x, ok := x.AttachmentIdentifier.(*AttachmentPointer_CdnKey); ok { + return x.CdnKey + } } return "" } @@ -3295,16 +3297,15 @@ func (*AttachmentPointer_CdnId) isAttachmentPointer_AttachmentIdentifier() {} func (*AttachmentPointer_CdnKey) isAttachmentPointer_AttachmentIdentifier() {} type GroupContext struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` + Id []byte `protobuf:"bytes,1,opt,name=id" json:"id,omitempty"` + Type *GroupContext_Type `protobuf:"varint,2,opt,name=type,enum=signalservice.GroupContext_Type" json:"type,omitempty"` + Name *string `protobuf:"bytes,3,opt,name=name" json:"name,omitempty"` + MembersE164 []string `protobuf:"bytes,4,rep,name=membersE164" json:"membersE164,omitempty"` + Members []*GroupContext_Member `protobuf:"bytes,6,rep,name=members" json:"members,omitempty"` + Avatar *AttachmentPointer `protobuf:"bytes,5,opt,name=avatar" json:"avatar,omitempty"` unknownFields protoimpl.UnknownFields - - Id []byte `protobuf:"bytes,1,opt,name=id" json:"id,omitempty"` - Type *GroupContext_Type `protobuf:"varint,2,opt,name=type,enum=signalservice.GroupContext_Type" json:"type,omitempty"` - Name *string `protobuf:"bytes,3,opt,name=name" json:"name,omitempty"` - MembersE164 []string `protobuf:"bytes,4,rep,name=membersE164" json:"membersE164,omitempty"` - Members []*GroupContext_Member `protobuf:"bytes,6,rep,name=members" json:"members,omitempty"` - Avatar *AttachmentPointer `protobuf:"bytes,5,opt,name=avatar" json:"avatar,omitempty"` + sizeCache protoimpl.SizeCache } func (x *GroupContext) Reset() { @@ -3380,13 +3381,12 @@ func (x *GroupContext) GetAvatar() *AttachmentPointer { } type GroupContextV2 struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` + MasterKey []byte `protobuf:"bytes,1,opt,name=masterKey" json:"masterKey,omitempty"` + Revision *uint32 `protobuf:"varint,2,opt,name=revision" json:"revision,omitempty"` + GroupChange []byte `protobuf:"bytes,3,opt,name=groupChange" json:"groupChange,omitempty"` unknownFields protoimpl.UnknownFields - - MasterKey []byte `protobuf:"bytes,1,opt,name=masterKey" json:"masterKey,omitempty"` - Revision *uint32 `protobuf:"varint,2,opt,name=revision" json:"revision,omitempty"` - GroupChange []byte `protobuf:"bytes,3,opt,name=groupChange" json:"groupChange,omitempty"` + sizeCache protoimpl.SizeCache } func (x *GroupContextV2) Reset() { @@ -3441,10 +3441,7 @@ func (x *GroupContextV2) GetGroupChange() []byte { } type ContactDetails struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - + state protoimpl.MessageState `protogen:"open.v1"` Number *string `protobuf:"bytes,1,opt,name=number" json:"number,omitempty"` Aci *string `protobuf:"bytes,9,opt,name=aci" json:"aci,omitempty"` Name *string `protobuf:"bytes,2,opt,name=name" json:"name,omitempty"` @@ -3456,6 +3453,8 @@ type ContactDetails struct { ExpireTimerVersion *uint32 `protobuf:"varint,12,opt,name=expireTimerVersion" json:"expireTimerVersion,omitempty"` InboxPosition *uint32 `protobuf:"varint,10,opt,name=inboxPosition" json:"inboxPosition,omitempty"` Archived *bool `protobuf:"varint,11,opt,name=archived" json:"archived,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } func (x *ContactDetails) Reset() { @@ -3566,10 +3565,7 @@ func (x *ContactDetails) GetArchived() bool { } type GroupDetails struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - + state protoimpl.MessageState `protogen:"open.v1"` Id []byte `protobuf:"bytes,1,opt,name=id" json:"id,omitempty"` Name *string `protobuf:"bytes,2,opt,name=name" json:"name,omitempty"` MembersE164 []string `protobuf:"bytes,3,rep,name=membersE164" json:"membersE164,omitempty"` @@ -3581,6 +3577,8 @@ type GroupDetails struct { Blocked *bool `protobuf:"varint,8,opt,name=blocked" json:"blocked,omitempty"` InboxPosition *uint32 `protobuf:"varint,10,opt,name=inboxPosition" json:"inboxPosition,omitempty"` Archived *bool `protobuf:"varint,11,opt,name=archived" json:"archived,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } // Default values for GroupDetails fields. @@ -3696,14 +3694,13 @@ func (x *GroupDetails) GetArchived() bool { } type PaymentAddress struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // Types that are assignable to Address: + state protoimpl.MessageState `protogen:"open.v1"` + // Types that are valid to be assigned to Address: // // *PaymentAddress_MobileCoinAddress_ - Address isPaymentAddress_Address `protobuf_oneof:"Address"` + Address isPaymentAddress_Address `protobuf_oneof:"Address"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } func (x *PaymentAddress) Reset() { @@ -3736,16 +3733,18 @@ func (*PaymentAddress) Descriptor() ([]byte, []int) { return file_SignalService_proto_rawDescGZIP(), []int{18} } -func (m *PaymentAddress) GetAddress() isPaymentAddress_Address { - if m != nil { - return m.Address +func (x *PaymentAddress) GetAddress() isPaymentAddress_Address { + if x != nil { + return x.Address } return nil } func (x *PaymentAddress) GetMobileCoinAddress() *PaymentAddress_MobileCoinAddress { - if x, ok := x.GetAddress().(*PaymentAddress_MobileCoinAddress_); ok { - return x.MobileCoinAddress + if x != nil { + if x, ok := x.Address.(*PaymentAddress_MobileCoinAddress_); ok { + return x.MobileCoinAddress + } } return nil } @@ -3761,13 +3760,12 @@ type PaymentAddress_MobileCoinAddress_ struct { func (*PaymentAddress_MobileCoinAddress_) isPaymentAddress_Address() {} type DecryptionErrorMessage struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` + RatchetKey []byte `protobuf:"bytes,1,opt,name=ratchetKey" json:"ratchetKey,omitempty"` + Timestamp *uint64 `protobuf:"varint,2,opt,name=timestamp" json:"timestamp,omitempty"` + DeviceId *uint32 `protobuf:"varint,3,opt,name=deviceId" json:"deviceId,omitempty"` unknownFields protoimpl.UnknownFields - - RatchetKey []byte `protobuf:"bytes,1,opt,name=ratchetKey" json:"ratchetKey,omitempty"` - Timestamp *uint64 `protobuf:"varint,2,opt,name=timestamp" json:"timestamp,omitempty"` - DeviceId *uint32 `protobuf:"varint,3,opt,name=deviceId" json:"deviceId,omitempty"` + sizeCache protoimpl.SizeCache } func (x *DecryptionErrorMessage) Reset() { @@ -3822,12 +3820,11 @@ func (x *DecryptionErrorMessage) GetDeviceId() uint32 { } type PniSignatureMessage struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` + Pni []byte `protobuf:"bytes,1,opt,name=pni" json:"pni,omitempty"` + Signature []byte `protobuf:"bytes,2,opt,name=signature" json:"signature,omitempty"` unknownFields protoimpl.UnknownFields - - Pni []byte `protobuf:"bytes,1,opt,name=pni" json:"pni,omitempty"` - Signature []byte `protobuf:"bytes,2,opt,name=signature" json:"signature,omitempty"` + sizeCache protoimpl.SizeCache } func (x *PniSignatureMessage) Reset() { @@ -3875,12 +3872,11 @@ func (x *PniSignatureMessage) GetSignature() []byte { } type EditMessage struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - TargetSentTimestamp *uint64 `protobuf:"varint,1,opt,name=targetSentTimestamp" json:"targetSentTimestamp,omitempty"` - DataMessage *DataMessage `protobuf:"bytes,2,opt,name=dataMessage" json:"dataMessage,omitempty"` + state protoimpl.MessageState `protogen:"open.v1"` + TargetSentTimestamp *uint64 `protobuf:"varint,1,opt,name=targetSentTimestamp" json:"targetSentTimestamp,omitempty"` + DataMessage *DataMessage `protobuf:"bytes,2,opt,name=dataMessage" json:"dataMessage,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } func (x *EditMessage) Reset() { @@ -3928,13 +3924,12 @@ func (x *EditMessage) GetDataMessage() *DataMessage { } type CallMessage_Offer struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` + Id *uint64 `protobuf:"varint,1,opt,name=id" json:"id,omitempty"` + Type *CallMessage_Offer_Type `protobuf:"varint,3,opt,name=type,enum=signalservice.CallMessage_Offer_Type" json:"type,omitempty"` + Opaque []byte `protobuf:"bytes,4,opt,name=opaque" json:"opaque,omitempty"` unknownFields protoimpl.UnknownFields - - Id *uint64 `protobuf:"varint,1,opt,name=id" json:"id,omitempty"` - Type *CallMessage_Offer_Type `protobuf:"varint,3,opt,name=type,enum=signalservice.CallMessage_Offer_Type" json:"type,omitempty"` - Opaque []byte `protobuf:"bytes,4,opt,name=opaque" json:"opaque,omitempty"` + sizeCache protoimpl.SizeCache } func (x *CallMessage_Offer) Reset() { @@ -3989,12 +3984,11 @@ func (x *CallMessage_Offer) GetOpaque() []byte { } type CallMessage_Answer struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` + Id *uint64 `protobuf:"varint,1,opt,name=id" json:"id,omitempty"` + Opaque []byte `protobuf:"bytes,3,opt,name=opaque" json:"opaque,omitempty"` unknownFields protoimpl.UnknownFields - - Id *uint64 `protobuf:"varint,1,opt,name=id" json:"id,omitempty"` - Opaque []byte `protobuf:"bytes,3,opt,name=opaque" json:"opaque,omitempty"` + sizeCache protoimpl.SizeCache } func (x *CallMessage_Answer) Reset() { @@ -4042,12 +4036,11 @@ func (x *CallMessage_Answer) GetOpaque() []byte { } type CallMessage_IceUpdate struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` + Id *uint64 `protobuf:"varint,1,opt,name=id" json:"id,omitempty"` + Opaque []byte `protobuf:"bytes,5,opt,name=opaque" json:"opaque,omitempty"` unknownFields protoimpl.UnknownFields - - Id *uint64 `protobuf:"varint,1,opt,name=id" json:"id,omitempty"` - Opaque []byte `protobuf:"bytes,5,opt,name=opaque" json:"opaque,omitempty"` + sizeCache protoimpl.SizeCache } func (x *CallMessage_IceUpdate) Reset() { @@ -4095,11 +4088,10 @@ func (x *CallMessage_IceUpdate) GetOpaque() []byte { } type CallMessage_Busy struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` + Id *uint64 `protobuf:"varint,1,opt,name=id" json:"id,omitempty"` unknownFields protoimpl.UnknownFields - - Id *uint64 `protobuf:"varint,1,opt,name=id" json:"id,omitempty"` + sizeCache protoimpl.SizeCache } func (x *CallMessage_Busy) Reset() { @@ -4140,13 +4132,12 @@ func (x *CallMessage_Busy) GetId() uint64 { } type CallMessage_Hangup struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` + Id *uint64 `protobuf:"varint,1,opt,name=id" json:"id,omitempty"` + Type *CallMessage_Hangup_Type `protobuf:"varint,2,opt,name=type,enum=signalservice.CallMessage_Hangup_Type" json:"type,omitempty"` + DeviceId *uint32 `protobuf:"varint,3,opt,name=deviceId" json:"deviceId,omitempty"` unknownFields protoimpl.UnknownFields - - Id *uint64 `protobuf:"varint,1,opt,name=id" json:"id,omitempty"` - Type *CallMessage_Hangup_Type `protobuf:"varint,2,opt,name=type,enum=signalservice.CallMessage_Hangup_Type" json:"type,omitempty"` - DeviceId *uint32 `protobuf:"varint,3,opt,name=deviceId" json:"deviceId,omitempty"` + sizeCache protoimpl.SizeCache } func (x *CallMessage_Hangup) Reset() { @@ -4201,12 +4192,11 @@ func (x *CallMessage_Hangup) GetDeviceId() uint32 { } type CallMessage_Opaque struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` + Data []byte `protobuf:"bytes,1,opt,name=data" json:"data,omitempty"` + Urgency *CallMessage_Opaque_Urgency `protobuf:"varint,2,opt,name=urgency,enum=signalservice.CallMessage_Opaque_Urgency" json:"urgency,omitempty"` unknownFields protoimpl.UnknownFields - - Data []byte `protobuf:"bytes,1,opt,name=data" json:"data,omitempty"` - Urgency *CallMessage_Opaque_Urgency `protobuf:"varint,2,opt,name=urgency,enum=signalservice.CallMessage_Opaque_Urgency" json:"urgency,omitempty"` + sizeCache protoimpl.SizeCache } func (x *CallMessage_Opaque) Reset() { @@ -4254,16 +4244,15 @@ func (x *CallMessage_Opaque) GetUrgency() CallMessage_Opaque_Urgency { } type DataMessage_Quote struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` + Id *uint64 `protobuf:"varint,1,opt,name=id" json:"id,omitempty"` + AuthorAci *string `protobuf:"bytes,5,opt,name=authorAci" json:"authorAci,omitempty"` + Text *string `protobuf:"bytes,3,opt,name=text" json:"text,omitempty"` + Attachments []*DataMessage_Quote_QuotedAttachment `protobuf:"bytes,4,rep,name=attachments" json:"attachments,omitempty"` + BodyRanges []*BodyRange `protobuf:"bytes,6,rep,name=bodyRanges" json:"bodyRanges,omitempty"` + Type *DataMessage_Quote_Type `protobuf:"varint,7,opt,name=type,enum=signalservice.DataMessage_Quote_Type" json:"type,omitempty"` unknownFields protoimpl.UnknownFields - - Id *uint64 `protobuf:"varint,1,opt,name=id" json:"id,omitempty"` - AuthorAci *string `protobuf:"bytes,5,opt,name=authorAci" json:"authorAci,omitempty"` - Text *string `protobuf:"bytes,3,opt,name=text" json:"text,omitempty"` - Attachments []*DataMessage_Quote_QuotedAttachment `protobuf:"bytes,4,rep,name=attachments" json:"attachments,omitempty"` - BodyRanges []*BodyRange `protobuf:"bytes,6,rep,name=bodyRanges" json:"bodyRanges,omitempty"` - Type *DataMessage_Quote_Type `protobuf:"varint,7,opt,name=type,enum=signalservice.DataMessage_Quote_Type" json:"type,omitempty"` + sizeCache protoimpl.SizeCache } func (x *DataMessage_Quote) Reset() { @@ -4339,16 +4328,15 @@ func (x *DataMessage_Quote) GetType() DataMessage_Quote_Type { } type DataMessage_Contact struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` + Name *DataMessage_Contact_Name `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"` + Number []*DataMessage_Contact_Phone `protobuf:"bytes,3,rep,name=number" json:"number,omitempty"` + Email []*DataMessage_Contact_Email `protobuf:"bytes,4,rep,name=email" json:"email,omitempty"` + Address []*DataMessage_Contact_PostalAddress `protobuf:"bytes,5,rep,name=address" json:"address,omitempty"` + Avatar *DataMessage_Contact_Avatar `protobuf:"bytes,6,opt,name=avatar" json:"avatar,omitempty"` + Organization *string `protobuf:"bytes,7,opt,name=organization" json:"organization,omitempty"` unknownFields protoimpl.UnknownFields - - Name *DataMessage_Contact_Name `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"` - Number []*DataMessage_Contact_Phone `protobuf:"bytes,3,rep,name=number" json:"number,omitempty"` - Email []*DataMessage_Contact_Email `protobuf:"bytes,4,rep,name=email" json:"email,omitempty"` - Address []*DataMessage_Contact_PostalAddress `protobuf:"bytes,5,rep,name=address" json:"address,omitempty"` - Avatar *DataMessage_Contact_Avatar `protobuf:"bytes,6,opt,name=avatar" json:"avatar,omitempty"` - Organization *string `protobuf:"bytes,7,opt,name=organization" json:"organization,omitempty"` + sizeCache protoimpl.SizeCache } func (x *DataMessage_Contact) Reset() { @@ -4424,15 +4412,14 @@ func (x *DataMessage_Contact) GetOrganization() string { } type DataMessage_Sticker struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` + PackId []byte `protobuf:"bytes,1,opt,name=packId" json:"packId,omitempty"` + PackKey []byte `protobuf:"bytes,2,opt,name=packKey" json:"packKey,omitempty"` + StickerId *uint32 `protobuf:"varint,3,opt,name=stickerId" json:"stickerId,omitempty"` + Data *AttachmentPointer `protobuf:"bytes,4,opt,name=data" json:"data,omitempty"` + Emoji *string `protobuf:"bytes,5,opt,name=emoji" json:"emoji,omitempty"` unknownFields protoimpl.UnknownFields - - PackId []byte `protobuf:"bytes,1,opt,name=packId" json:"packId,omitempty"` - PackKey []byte `protobuf:"bytes,2,opt,name=packKey" json:"packKey,omitempty"` - StickerId *uint32 `protobuf:"varint,3,opt,name=stickerId" json:"stickerId,omitempty"` - Data *AttachmentPointer `protobuf:"bytes,4,opt,name=data" json:"data,omitempty"` - Emoji *string `protobuf:"bytes,5,opt,name=emoji" json:"emoji,omitempty"` + sizeCache protoimpl.SizeCache } func (x *DataMessage_Sticker) Reset() { @@ -4501,14 +4488,13 @@ func (x *DataMessage_Sticker) GetEmoji() string { } type DataMessage_Reaction struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Emoji *string `protobuf:"bytes,1,opt,name=emoji" json:"emoji,omitempty"` - Remove *bool `protobuf:"varint,2,opt,name=remove" json:"remove,omitempty"` - TargetAuthorAci *string `protobuf:"bytes,4,opt,name=targetAuthorAci" json:"targetAuthorAci,omitempty"` - TargetSentTimestamp *uint64 `protobuf:"varint,5,opt,name=targetSentTimestamp" json:"targetSentTimestamp,omitempty"` + state protoimpl.MessageState `protogen:"open.v1"` + Emoji *string `protobuf:"bytes,1,opt,name=emoji" json:"emoji,omitempty"` + Remove *bool `protobuf:"varint,2,opt,name=remove" json:"remove,omitempty"` + TargetAuthorAci *string `protobuf:"bytes,4,opt,name=targetAuthorAci" json:"targetAuthorAci,omitempty"` + TargetSentTimestamp *uint64 `protobuf:"varint,5,opt,name=targetSentTimestamp" json:"targetSentTimestamp,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } func (x *DataMessage_Reaction) Reset() { @@ -4570,11 +4556,10 @@ func (x *DataMessage_Reaction) GetTargetSentTimestamp() uint64 { } type DataMessage_Delete struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - TargetSentTimestamp *uint64 `protobuf:"varint,1,opt,name=targetSentTimestamp" json:"targetSentTimestamp,omitempty"` + state protoimpl.MessageState `protogen:"open.v1"` + TargetSentTimestamp *uint64 `protobuf:"varint,1,opt,name=targetSentTimestamp" json:"targetSentTimestamp,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } func (x *DataMessage_Delete) Reset() { @@ -4615,11 +4600,10 @@ func (x *DataMessage_Delete) GetTargetSentTimestamp() uint64 { } type DataMessage_GroupCallUpdate struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` + EraId *string `protobuf:"bytes,1,opt,name=eraId" json:"eraId,omitempty"` unknownFields protoimpl.UnknownFields - - EraId *string `protobuf:"bytes,1,opt,name=eraId" json:"eraId,omitempty"` + sizeCache protoimpl.SizeCache } func (x *DataMessage_GroupCallUpdate) Reset() { @@ -4660,12 +4644,11 @@ func (x *DataMessage_GroupCallUpdate) GetEraId() string { } type DataMessage_StoryContext struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` + AuthorAci *string `protobuf:"bytes,1,opt,name=authorAci" json:"authorAci,omitempty"` + SentTimestamp *uint64 `protobuf:"varint,2,opt,name=sentTimestamp" json:"sentTimestamp,omitempty"` unknownFields protoimpl.UnknownFields - - AuthorAci *string `protobuf:"bytes,1,opt,name=authorAci" json:"authorAci,omitempty"` - SentTimestamp *uint64 `protobuf:"varint,2,opt,name=sentTimestamp" json:"sentTimestamp,omitempty"` + sizeCache protoimpl.SizeCache } func (x *DataMessage_StoryContext) Reset() { @@ -4713,15 +4696,14 @@ func (x *DataMessage_StoryContext) GetSentTimestamp() uint64 { } type DataMessage_Payment struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // Types that are assignable to Item: + state protoimpl.MessageState `protogen:"open.v1"` + // Types that are valid to be assigned to Item: // // *DataMessage_Payment_Notification_ // *DataMessage_Payment_Activation_ - Item isDataMessage_Payment_Item `protobuf_oneof:"Item"` + Item isDataMessage_Payment_Item `protobuf_oneof:"Item"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } func (x *DataMessage_Payment) Reset() { @@ -4754,23 +4736,27 @@ func (*DataMessage_Payment) Descriptor() ([]byte, []int) { return file_SignalService_proto_rawDescGZIP(), []int{4, 7} } -func (m *DataMessage_Payment) GetItem() isDataMessage_Payment_Item { - if m != nil { - return m.Item +func (x *DataMessage_Payment) GetItem() isDataMessage_Payment_Item { + if x != nil { + return x.Item } return nil } func (x *DataMessage_Payment) GetNotification() *DataMessage_Payment_Notification { - if x, ok := x.GetItem().(*DataMessage_Payment_Notification_); ok { - return x.Notification + if x != nil { + if x, ok := x.Item.(*DataMessage_Payment_Notification_); ok { + return x.Notification + } } return nil } func (x *DataMessage_Payment) GetActivation() *DataMessage_Payment_Activation { - if x, ok := x.GetItem().(*DataMessage_Payment_Activation_); ok { - return x.Activation + if x != nil { + if x, ok := x.Item.(*DataMessage_Payment_Activation_); ok { + return x.Activation + } } return nil } @@ -4792,11 +4778,10 @@ func (*DataMessage_Payment_Notification_) isDataMessage_Payment_Item() {} func (*DataMessage_Payment_Activation_) isDataMessage_Payment_Item() {} type DataMessage_GiftBadge struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - ReceiptCredentialPresentation []byte `protobuf:"bytes,1,opt,name=receiptCredentialPresentation" json:"receiptCredentialPresentation,omitempty"` + state protoimpl.MessageState `protogen:"open.v1"` + ReceiptCredentialPresentation []byte `protobuf:"bytes,1,opt,name=receiptCredentialPresentation" json:"receiptCredentialPresentation,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } func (x *DataMessage_GiftBadge) Reset() { @@ -4837,13 +4822,12 @@ func (x *DataMessage_GiftBadge) GetReceiptCredentialPresentation() []byte { } type DataMessage_Quote_QuotedAttachment struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` + ContentType *string `protobuf:"bytes,1,opt,name=contentType" json:"contentType,omitempty"` + FileName *string `protobuf:"bytes,2,opt,name=fileName" json:"fileName,omitempty"` + Thumbnail *AttachmentPointer `protobuf:"bytes,3,opt,name=thumbnail" json:"thumbnail,omitempty"` unknownFields protoimpl.UnknownFields - - ContentType *string `protobuf:"bytes,1,opt,name=contentType" json:"contentType,omitempty"` - FileName *string `protobuf:"bytes,2,opt,name=fileName" json:"fileName,omitempty"` - Thumbnail *AttachmentPointer `protobuf:"bytes,3,opt,name=thumbnail" json:"thumbnail,omitempty"` + sizeCache protoimpl.SizeCache } func (x *DataMessage_Quote_QuotedAttachment) Reset() { @@ -4898,16 +4882,15 @@ func (x *DataMessage_Quote_QuotedAttachment) GetThumbnail() *AttachmentPointer { } type DataMessage_Contact_Name struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` + GivenName *string `protobuf:"bytes,1,opt,name=givenName" json:"givenName,omitempty"` + FamilyName *string `protobuf:"bytes,2,opt,name=familyName" json:"familyName,omitempty"` + Prefix *string `protobuf:"bytes,3,opt,name=prefix" json:"prefix,omitempty"` + Suffix *string `protobuf:"bytes,4,opt,name=suffix" json:"suffix,omitempty"` + MiddleName *string `protobuf:"bytes,5,opt,name=middleName" json:"middleName,omitempty"` + Nickname *string `protobuf:"bytes,7,opt,name=nickname" json:"nickname,omitempty"` unknownFields protoimpl.UnknownFields - - GivenName *string `protobuf:"bytes,1,opt,name=givenName" json:"givenName,omitempty"` - FamilyName *string `protobuf:"bytes,2,opt,name=familyName" json:"familyName,omitempty"` - Prefix *string `protobuf:"bytes,3,opt,name=prefix" json:"prefix,omitempty"` - Suffix *string `protobuf:"bytes,4,opt,name=suffix" json:"suffix,omitempty"` - MiddleName *string `protobuf:"bytes,5,opt,name=middleName" json:"middleName,omitempty"` - Nickname *string `protobuf:"bytes,7,opt,name=nickname" json:"nickname,omitempty"` + sizeCache protoimpl.SizeCache } func (x *DataMessage_Contact_Name) Reset() { @@ -4983,13 +4966,12 @@ func (x *DataMessage_Contact_Name) GetNickname() string { } type DataMessage_Contact_Phone struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` + Value *string `protobuf:"bytes,1,opt,name=value" json:"value,omitempty"` + Type *DataMessage_Contact_Phone_Type `protobuf:"varint,2,opt,name=type,enum=signalservice.DataMessage_Contact_Phone_Type" json:"type,omitempty"` + Label *string `protobuf:"bytes,3,opt,name=label" json:"label,omitempty"` unknownFields protoimpl.UnknownFields - - Value *string `protobuf:"bytes,1,opt,name=value" json:"value,omitempty"` - Type *DataMessage_Contact_Phone_Type `protobuf:"varint,2,opt,name=type,enum=signalservice.DataMessage_Contact_Phone_Type" json:"type,omitempty"` - Label *string `protobuf:"bytes,3,opt,name=label" json:"label,omitempty"` + sizeCache protoimpl.SizeCache } func (x *DataMessage_Contact_Phone) Reset() { @@ -5044,13 +5026,12 @@ func (x *DataMessage_Contact_Phone) GetLabel() string { } type DataMessage_Contact_Email struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` + Value *string `protobuf:"bytes,1,opt,name=value" json:"value,omitempty"` + Type *DataMessage_Contact_Email_Type `protobuf:"varint,2,opt,name=type,enum=signalservice.DataMessage_Contact_Email_Type" json:"type,omitempty"` + Label *string `protobuf:"bytes,3,opt,name=label" json:"label,omitempty"` unknownFields protoimpl.UnknownFields - - Value *string `protobuf:"bytes,1,opt,name=value" json:"value,omitempty"` - Type *DataMessage_Contact_Email_Type `protobuf:"varint,2,opt,name=type,enum=signalservice.DataMessage_Contact_Email_Type" json:"type,omitempty"` - Label *string `protobuf:"bytes,3,opt,name=label" json:"label,omitempty"` + sizeCache protoimpl.SizeCache } func (x *DataMessage_Contact_Email) Reset() { @@ -5105,19 +5086,18 @@ func (x *DataMessage_Contact_Email) GetLabel() string { } type DataMessage_Contact_PostalAddress struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` + Type *DataMessage_Contact_PostalAddress_Type `protobuf:"varint,1,opt,name=type,enum=signalservice.DataMessage_Contact_PostalAddress_Type" json:"type,omitempty"` + Label *string `protobuf:"bytes,2,opt,name=label" json:"label,omitempty"` + Street *string `protobuf:"bytes,3,opt,name=street" json:"street,omitempty"` + Pobox *string `protobuf:"bytes,4,opt,name=pobox" json:"pobox,omitempty"` + Neighborhood *string `protobuf:"bytes,5,opt,name=neighborhood" json:"neighborhood,omitempty"` + City *string `protobuf:"bytes,6,opt,name=city" json:"city,omitempty"` + Region *string `protobuf:"bytes,7,opt,name=region" json:"region,omitempty"` + Postcode *string `protobuf:"bytes,8,opt,name=postcode" json:"postcode,omitempty"` + Country *string `protobuf:"bytes,9,opt,name=country" json:"country,omitempty"` unknownFields protoimpl.UnknownFields - - Type *DataMessage_Contact_PostalAddress_Type `protobuf:"varint,1,opt,name=type,enum=signalservice.DataMessage_Contact_PostalAddress_Type" json:"type,omitempty"` - Label *string `protobuf:"bytes,2,opt,name=label" json:"label,omitempty"` - Street *string `protobuf:"bytes,3,opt,name=street" json:"street,omitempty"` - Pobox *string `protobuf:"bytes,4,opt,name=pobox" json:"pobox,omitempty"` - Neighborhood *string `protobuf:"bytes,5,opt,name=neighborhood" json:"neighborhood,omitempty"` - City *string `protobuf:"bytes,6,opt,name=city" json:"city,omitempty"` - Region *string `protobuf:"bytes,7,opt,name=region" json:"region,omitempty"` - Postcode *string `protobuf:"bytes,8,opt,name=postcode" json:"postcode,omitempty"` - Country *string `protobuf:"bytes,9,opt,name=country" json:"country,omitempty"` + sizeCache protoimpl.SizeCache } func (x *DataMessage_Contact_PostalAddress) Reset() { @@ -5214,12 +5194,11 @@ func (x *DataMessage_Contact_PostalAddress) GetCountry() string { } type DataMessage_Contact_Avatar struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` + Avatar *AttachmentPointer `protobuf:"bytes,1,opt,name=avatar" json:"avatar,omitempty"` + IsProfile *bool `protobuf:"varint,2,opt,name=isProfile" json:"isProfile,omitempty"` unknownFields protoimpl.UnknownFields - - Avatar *AttachmentPointer `protobuf:"bytes,1,opt,name=avatar" json:"avatar,omitempty"` - IsProfile *bool `protobuf:"varint,2,opt,name=isProfile" json:"isProfile,omitempty"` + sizeCache protoimpl.SizeCache } func (x *DataMessage_Contact_Avatar) Reset() { @@ -5267,14 +5246,13 @@ func (x *DataMessage_Contact_Avatar) GetIsProfile() bool { } type DataMessage_Payment_Amount struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // Types that are assignable to Amount: + state protoimpl.MessageState `protogen:"open.v1"` + // Types that are valid to be assigned to Amount: // // *DataMessage_Payment_Amount_MobileCoin_ - Amount isDataMessage_Payment_Amount_Amount `protobuf_oneof:"Amount"` + Amount isDataMessage_Payment_Amount_Amount `protobuf_oneof:"Amount"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } func (x *DataMessage_Payment_Amount) Reset() { @@ -5307,16 +5285,18 @@ func (*DataMessage_Payment_Amount) Descriptor() ([]byte, []int) { return file_SignalService_proto_rawDescGZIP(), []int{4, 7, 0} } -func (m *DataMessage_Payment_Amount) GetAmount() isDataMessage_Payment_Amount_Amount { - if m != nil { - return m.Amount +func (x *DataMessage_Payment_Amount) GetAmount() isDataMessage_Payment_Amount_Amount { + if x != nil { + return x.Amount } return nil } func (x *DataMessage_Payment_Amount) GetMobileCoin() *DataMessage_Payment_Amount_MobileCoin { - if x, ok := x.GetAmount().(*DataMessage_Payment_Amount_MobileCoin_); ok { - return x.MobileCoin + if x != nil { + if x, ok := x.Amount.(*DataMessage_Payment_Amount_MobileCoin_); ok { + return x.MobileCoin + } } return nil } @@ -5332,15 +5312,14 @@ type DataMessage_Payment_Amount_MobileCoin_ struct { func (*DataMessage_Payment_Amount_MobileCoin_) isDataMessage_Payment_Amount_Amount() {} type DataMessage_Payment_Notification struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // Types that are assignable to Transaction: + state protoimpl.MessageState `protogen:"open.v1"` + // Types that are valid to be assigned to Transaction: // // *DataMessage_Payment_Notification_MobileCoin_ - Transaction isDataMessage_Payment_Notification_Transaction `protobuf_oneof:"Transaction"` - Note *string `protobuf:"bytes,2,opt,name=note" json:"note,omitempty"` + Transaction isDataMessage_Payment_Notification_Transaction `protobuf_oneof:"Transaction"` + Note *string `protobuf:"bytes,2,opt,name=note" json:"note,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } func (x *DataMessage_Payment_Notification) Reset() { @@ -5373,16 +5352,18 @@ func (*DataMessage_Payment_Notification) Descriptor() ([]byte, []int) { return file_SignalService_proto_rawDescGZIP(), []int{4, 7, 1} } -func (m *DataMessage_Payment_Notification) GetTransaction() isDataMessage_Payment_Notification_Transaction { - if m != nil { - return m.Transaction +func (x *DataMessage_Payment_Notification) GetTransaction() isDataMessage_Payment_Notification_Transaction { + if x != nil { + return x.Transaction } return nil } func (x *DataMessage_Payment_Notification) GetMobileCoin() *DataMessage_Payment_Notification_MobileCoin { - if x, ok := x.GetTransaction().(*DataMessage_Payment_Notification_MobileCoin_); ok { - return x.MobileCoin + if x != nil { + if x, ok := x.Transaction.(*DataMessage_Payment_Notification_MobileCoin_); ok { + return x.MobileCoin + } } return nil } @@ -5406,11 +5387,10 @@ func (*DataMessage_Payment_Notification_MobileCoin_) isDataMessage_Payment_Notif } type DataMessage_Payment_Activation struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` + Type *DataMessage_Payment_Activation_Type `protobuf:"varint,1,opt,name=type,enum=signalservice.DataMessage_Payment_Activation_Type" json:"type,omitempty"` unknownFields protoimpl.UnknownFields - - Type *DataMessage_Payment_Activation_Type `protobuf:"varint,1,opt,name=type,enum=signalservice.DataMessage_Payment_Activation_Type" json:"type,omitempty"` + sizeCache protoimpl.SizeCache } func (x *DataMessage_Payment_Activation) Reset() { @@ -5451,11 +5431,10 @@ func (x *DataMessage_Payment_Activation) GetType() DataMessage_Payment_Activatio } type DataMessage_Payment_Amount_MobileCoin struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` + PicoMob *uint64 `protobuf:"varint,1,opt,name=picoMob" json:"picoMob,omitempty"` unknownFields protoimpl.UnknownFields - - PicoMob *uint64 `protobuf:"varint,1,opt,name=picoMob" json:"picoMob,omitempty"` + sizeCache protoimpl.SizeCache } func (x *DataMessage_Payment_Amount_MobileCoin) Reset() { @@ -5496,11 +5475,10 @@ func (x *DataMessage_Payment_Amount_MobileCoin) GetPicoMob() uint64 { } type DataMessage_Payment_Notification_MobileCoin struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` + Receipt []byte `protobuf:"bytes,1,opt,name=receipt" json:"receipt,omitempty"` unknownFields protoimpl.UnknownFields - - Receipt []byte `protobuf:"bytes,1,opt,name=receipt" json:"receipt,omitempty"` + sizeCache protoimpl.SizeCache } func (x *DataMessage_Payment_Notification_MobileCoin) Reset() { @@ -5541,15 +5519,14 @@ func (x *DataMessage_Payment_Notification_MobileCoin) GetReceipt() []byte { } type TextAttachment_Gradient struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` + StartColor *uint32 `protobuf:"varint,1,opt,name=startColor" json:"startColor,omitempty"` // deprecated: this field will be removed in a future release. + EndColor *uint32 `protobuf:"varint,2,opt,name=endColor" json:"endColor,omitempty"` // deprecated: this field will be removed in a future release. + Angle *uint32 `protobuf:"varint,3,opt,name=angle" json:"angle,omitempty"` // degrees + Colors []uint32 `protobuf:"varint,4,rep,name=colors" json:"colors,omitempty"` + Positions []float32 `protobuf:"fixed32,5,rep,name=positions" json:"positions,omitempty"` // percent from 0 to 1 unknownFields protoimpl.UnknownFields - - StartColor *uint32 `protobuf:"varint,1,opt,name=startColor" json:"startColor,omitempty"` // deprecated: this field will be removed in a future release. - EndColor *uint32 `protobuf:"varint,2,opt,name=endColor" json:"endColor,omitempty"` // deprecated: this field will be removed in a future release. - Angle *uint32 `protobuf:"varint,3,opt,name=angle" json:"angle,omitempty"` // degrees - Colors []uint32 `protobuf:"varint,4,rep,name=colors" json:"colors,omitempty"` - Positions []float32 `protobuf:"fixed32,5,rep,name=positions" json:"positions,omitempty"` // percent from 0 to 1 + sizeCache protoimpl.SizeCache } func (x *TextAttachment_Gradient) Reset() { @@ -5618,10 +5595,7 @@ func (x *TextAttachment_Gradient) GetPositions() []float32 { } type SyncMessage_Sent struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - + state protoimpl.MessageState `protogen:"open.v1"` DestinationE164 *string `protobuf:"bytes,1,opt,name=destinationE164" json:"destinationE164,omitempty"` DestinationServiceId *string `protobuf:"bytes,7,opt,name=destinationServiceId" json:"destinationServiceId,omitempty"` Timestamp *uint64 `protobuf:"varint,2,opt,name=timestamp" json:"timestamp,omitempty"` @@ -5632,6 +5606,8 @@ type SyncMessage_Sent struct { StoryMessage *StoryMessage `protobuf:"bytes,8,opt,name=storyMessage" json:"storyMessage,omitempty"` StoryMessageRecipients []*SyncMessage_Sent_StoryMessageRecipient `protobuf:"bytes,9,rep,name=storyMessageRecipients" json:"storyMessageRecipients,omitempty"` EditMessage *EditMessage `protobuf:"bytes,10,opt,name=editMessage" json:"editMessage,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } // Default values for SyncMessage_Sent fields. @@ -5740,12 +5716,11 @@ func (x *SyncMessage_Sent) GetEditMessage() *EditMessage { } type SyncMessage_Contacts struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` + Blob *AttachmentPointer `protobuf:"bytes,1,opt,name=blob" json:"blob,omitempty"` + Complete *bool `protobuf:"varint,2,opt,name=complete,def=0" json:"complete,omitempty"` unknownFields protoimpl.UnknownFields - - Blob *AttachmentPointer `protobuf:"bytes,1,opt,name=blob" json:"blob,omitempty"` - Complete *bool `protobuf:"varint,2,opt,name=complete,def=0" json:"complete,omitempty"` + sizeCache protoimpl.SizeCache } // Default values for SyncMessage_Contacts fields. @@ -5798,13 +5773,12 @@ func (x *SyncMessage_Contacts) GetComplete() bool { } type SyncMessage_Blocked struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` + Numbers []string `protobuf:"bytes,1,rep,name=numbers" json:"numbers,omitempty"` + Acis []string `protobuf:"bytes,3,rep,name=acis" json:"acis,omitempty"` + GroupIds [][]byte `protobuf:"bytes,2,rep,name=groupIds" json:"groupIds,omitempty"` unknownFields protoimpl.UnknownFields - - Numbers []string `protobuf:"bytes,1,rep,name=numbers" json:"numbers,omitempty"` - Acis []string `protobuf:"bytes,3,rep,name=acis" json:"acis,omitempty"` - GroupIds [][]byte `protobuf:"bytes,2,rep,name=groupIds" json:"groupIds,omitempty"` + sizeCache protoimpl.SizeCache } func (x *SyncMessage_Blocked) Reset() { @@ -5859,11 +5833,10 @@ func (x *SyncMessage_Blocked) GetGroupIds() [][]byte { } type SyncMessage_Request struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` + Type *SyncMessage_Request_Type `protobuf:"varint,1,opt,name=type,enum=signalservice.SyncMessage_Request_Type" json:"type,omitempty"` unknownFields protoimpl.UnknownFields - - Type *SyncMessage_Request_Type `protobuf:"varint,1,opt,name=type,enum=signalservice.SyncMessage_Request_Type" json:"type,omitempty"` + sizeCache protoimpl.SizeCache } func (x *SyncMessage_Request) Reset() { @@ -5904,12 +5877,11 @@ func (x *SyncMessage_Request) GetType() SyncMessage_Request_Type { } type SyncMessage_Read struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` + SenderAci *string `protobuf:"bytes,3,opt,name=senderAci" json:"senderAci,omitempty"` + Timestamp *uint64 `protobuf:"varint,2,opt,name=timestamp" json:"timestamp,omitempty"` unknownFields protoimpl.UnknownFields - - SenderAci *string `protobuf:"bytes,3,opt,name=senderAci" json:"senderAci,omitempty"` - Timestamp *uint64 `protobuf:"varint,2,opt,name=timestamp" json:"timestamp,omitempty"` + sizeCache protoimpl.SizeCache } func (x *SyncMessage_Read) Reset() { @@ -5957,12 +5929,11 @@ func (x *SyncMessage_Read) GetTimestamp() uint64 { } type SyncMessage_Viewed struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` + SenderAci *string `protobuf:"bytes,3,opt,name=senderAci" json:"senderAci,omitempty"` + Timestamp *uint64 `protobuf:"varint,2,opt,name=timestamp" json:"timestamp,omitempty"` unknownFields protoimpl.UnknownFields - - SenderAci *string `protobuf:"bytes,3,opt,name=senderAci" json:"senderAci,omitempty"` - Timestamp *uint64 `protobuf:"varint,2,opt,name=timestamp" json:"timestamp,omitempty"` + sizeCache protoimpl.SizeCache } func (x *SyncMessage_Viewed) Reset() { @@ -6010,15 +5981,14 @@ func (x *SyncMessage_Viewed) GetTimestamp() uint64 { } type SyncMessage_Configuration struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - ReadReceipts *bool `protobuf:"varint,1,opt,name=readReceipts" json:"readReceipts,omitempty"` - UnidentifiedDeliveryIndicators *bool `protobuf:"varint,2,opt,name=unidentifiedDeliveryIndicators" json:"unidentifiedDeliveryIndicators,omitempty"` - TypingIndicators *bool `protobuf:"varint,3,opt,name=typingIndicators" json:"typingIndicators,omitempty"` - ProvisioningVersion *uint32 `protobuf:"varint,5,opt,name=provisioningVersion" json:"provisioningVersion,omitempty"` - LinkPreviews *bool `protobuf:"varint,6,opt,name=linkPreviews" json:"linkPreviews,omitempty"` + state protoimpl.MessageState `protogen:"open.v1"` + ReadReceipts *bool `protobuf:"varint,1,opt,name=readReceipts" json:"readReceipts,omitempty"` + UnidentifiedDeliveryIndicators *bool `protobuf:"varint,2,opt,name=unidentifiedDeliveryIndicators" json:"unidentifiedDeliveryIndicators,omitempty"` + TypingIndicators *bool `protobuf:"varint,3,opt,name=typingIndicators" json:"typingIndicators,omitempty"` + ProvisioningVersion *uint32 `protobuf:"varint,5,opt,name=provisioningVersion" json:"provisioningVersion,omitempty"` + LinkPreviews *bool `protobuf:"varint,6,opt,name=linkPreviews" json:"linkPreviews,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } func (x *SyncMessage_Configuration) Reset() { @@ -6087,13 +6057,12 @@ func (x *SyncMessage_Configuration) GetLinkPreviews() bool { } type SyncMessage_StickerPackOperation struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` + PackId []byte `protobuf:"bytes,1,opt,name=packId" json:"packId,omitempty"` + PackKey []byte `protobuf:"bytes,2,opt,name=packKey" json:"packKey,omitempty"` + Type *SyncMessage_StickerPackOperation_Type `protobuf:"varint,3,opt,name=type,enum=signalservice.SyncMessage_StickerPackOperation_Type" json:"type,omitempty"` unknownFields protoimpl.UnknownFields - - PackId []byte `protobuf:"bytes,1,opt,name=packId" json:"packId,omitempty"` - PackKey []byte `protobuf:"bytes,2,opt,name=packKey" json:"packKey,omitempty"` - Type *SyncMessage_StickerPackOperation_Type `protobuf:"varint,3,opt,name=type,enum=signalservice.SyncMessage_StickerPackOperation_Type" json:"type,omitempty"` + sizeCache protoimpl.SizeCache } func (x *SyncMessage_StickerPackOperation) Reset() { @@ -6148,12 +6117,11 @@ func (x *SyncMessage_StickerPackOperation) GetType() SyncMessage_StickerPackOper } type SyncMessage_ViewOnceOpen struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` + SenderAci *string `protobuf:"bytes,3,opt,name=senderAci" json:"senderAci,omitempty"` + Timestamp *uint64 `protobuf:"varint,2,opt,name=timestamp" json:"timestamp,omitempty"` unknownFields protoimpl.UnknownFields - - SenderAci *string `protobuf:"bytes,3,opt,name=senderAci" json:"senderAci,omitempty"` - Timestamp *uint64 `protobuf:"varint,2,opt,name=timestamp" json:"timestamp,omitempty"` + sizeCache protoimpl.SizeCache } func (x *SyncMessage_ViewOnceOpen) Reset() { @@ -6201,11 +6169,10 @@ func (x *SyncMessage_ViewOnceOpen) GetTimestamp() uint64 { } type SyncMessage_FetchLatest struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` + Type *SyncMessage_FetchLatest_Type `protobuf:"varint,1,opt,name=type,enum=signalservice.SyncMessage_FetchLatest_Type" json:"type,omitempty"` unknownFields protoimpl.UnknownFields - - Type *SyncMessage_FetchLatest_Type `protobuf:"varint,1,opt,name=type,enum=signalservice.SyncMessage_FetchLatest_Type" json:"type,omitempty"` + sizeCache protoimpl.SizeCache } func (x *SyncMessage_FetchLatest) Reset() { @@ -6246,16 +6213,15 @@ func (x *SyncMessage_FetchLatest) GetType() SyncMessage_FetchLatest_Type { } type SyncMessage_Keys struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - + state protoimpl.MessageState `protogen:"open.v1"` // @deprecated StorageService []byte `protobuf:"bytes,1,opt,name=storageService" json:"storageService,omitempty"` // @deprecated Master []byte `protobuf:"bytes,2,opt,name=master" json:"master,omitempty"` AccountEntropyPool *string `protobuf:"bytes,3,opt,name=accountEntropyPool" json:"accountEntropyPool,omitempty"` MediaRootBackupKey []byte `protobuf:"bytes,4,opt,name=mediaRootBackupKey" json:"mediaRootBackupKey,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } func (x *SyncMessage_Keys) Reset() { @@ -6317,13 +6283,12 @@ func (x *SyncMessage_Keys) GetMediaRootBackupKey() []byte { } type SyncMessage_MessageRequestResponse struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` + ThreadAci *string `protobuf:"bytes,2,opt,name=threadAci" json:"threadAci,omitempty"` + GroupId []byte `protobuf:"bytes,3,opt,name=groupId" json:"groupId,omitempty"` + Type *SyncMessage_MessageRequestResponse_Type `protobuf:"varint,4,opt,name=type,enum=signalservice.SyncMessage_MessageRequestResponse_Type" json:"type,omitempty"` unknownFields protoimpl.UnknownFields - - ThreadAci *string `protobuf:"bytes,2,opt,name=threadAci" json:"threadAci,omitempty"` - GroupId []byte `protobuf:"bytes,3,opt,name=groupId" json:"groupId,omitempty"` - Type *SyncMessage_MessageRequestResponse_Type `protobuf:"varint,4,opt,name=type,enum=signalservice.SyncMessage_MessageRequestResponse_Type" json:"type,omitempty"` + sizeCache protoimpl.SizeCache } func (x *SyncMessage_MessageRequestResponse) Reset() { @@ -6378,16 +6343,15 @@ func (x *SyncMessage_MessageRequestResponse) GetType() SyncMessage_MessageReques } type SyncMessage_OutgoingPayment struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - RecipientServiceId *string `protobuf:"bytes,1,opt,name=recipientServiceId" json:"recipientServiceId,omitempty"` - Note *string `protobuf:"bytes,2,opt,name=note" json:"note,omitempty"` - // Types that are assignable to PaymentDetail: + state protoimpl.MessageState `protogen:"open.v1"` + RecipientServiceId *string `protobuf:"bytes,1,opt,name=recipientServiceId" json:"recipientServiceId,omitempty"` + Note *string `protobuf:"bytes,2,opt,name=note" json:"note,omitempty"` + // Types that are valid to be assigned to PaymentDetail: // // *SyncMessage_OutgoingPayment_MobileCoin_ PaymentDetail isSyncMessage_OutgoingPayment_PaymentDetail `protobuf_oneof:"paymentDetail"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } func (x *SyncMessage_OutgoingPayment) Reset() { @@ -6434,16 +6398,18 @@ func (x *SyncMessage_OutgoingPayment) GetNote() string { return "" } -func (m *SyncMessage_OutgoingPayment) GetPaymentDetail() isSyncMessage_OutgoingPayment_PaymentDetail { - if m != nil { - return m.PaymentDetail +func (x *SyncMessage_OutgoingPayment) GetPaymentDetail() isSyncMessage_OutgoingPayment_PaymentDetail { + if x != nil { + return x.PaymentDetail } return nil } func (x *SyncMessage_OutgoingPayment) GetMobileCoin() *SyncMessage_OutgoingPayment_MobileCoin { - if x, ok := x.GetPaymentDetail().(*SyncMessage_OutgoingPayment_MobileCoin_); ok { - return x.MobileCoin + if x != nil { + if x, ok := x.PaymentDetail.(*SyncMessage_OutgoingPayment_MobileCoin_); ok { + return x.MobileCoin + } } return nil } @@ -6459,15 +6425,14 @@ type SyncMessage_OutgoingPayment_MobileCoin_ struct { func (*SyncMessage_OutgoingPayment_MobileCoin_) isSyncMessage_OutgoingPayment_PaymentDetail() {} type SyncMessage_PniChangeNumber struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - IdentityKeyPair []byte `protobuf:"bytes,1,opt,name=identityKeyPair" json:"identityKeyPair,omitempty"` // Serialized libsignal-client IdentityKeyPair - SignedPreKey []byte `protobuf:"bytes,2,opt,name=signedPreKey" json:"signedPreKey,omitempty"` // Serialized libsignal-client SignedPreKeyRecord - LastResortKyberPreKey []byte `protobuf:"bytes,5,opt,name=lastResortKyberPreKey" json:"lastResortKyberPreKey,omitempty"` // Serialized libsignal-client KyberPreKeyRecord - RegistrationId *uint32 `protobuf:"varint,3,opt,name=registrationId" json:"registrationId,omitempty"` - NewE164 *string `protobuf:"bytes,4,opt,name=newE164" json:"newE164,omitempty"` // The e164 we have changed our number to + state protoimpl.MessageState `protogen:"open.v1"` + IdentityKeyPair []byte `protobuf:"bytes,1,opt,name=identityKeyPair" json:"identityKeyPair,omitempty"` // Serialized libsignal-client IdentityKeyPair + SignedPreKey []byte `protobuf:"bytes,2,opt,name=signedPreKey" json:"signedPreKey,omitempty"` // Serialized libsignal-client SignedPreKeyRecord + LastResortKyberPreKey []byte `protobuf:"bytes,5,opt,name=lastResortKyberPreKey" json:"lastResortKyberPreKey,omitempty"` // Serialized libsignal-client KyberPreKeyRecord + RegistrationId *uint32 `protobuf:"varint,3,opt,name=registrationId" json:"registrationId,omitempty"` + NewE164 *string `protobuf:"bytes,4,opt,name=newE164" json:"newE164,omitempty"` // The e164 we have changed our number to + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } func (x *SyncMessage_PniChangeNumber) Reset() { @@ -6536,16 +6501,15 @@ func (x *SyncMessage_PniChangeNumber) GetNewE164() string { } type SyncMessage_CallEvent struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - + state protoimpl.MessageState `protogen:"open.v1"` ConversationId []byte `protobuf:"bytes,1,opt,name=conversationId" json:"conversationId,omitempty"` Id *uint64 `protobuf:"varint,2,opt,name=id" json:"id,omitempty"` Timestamp *uint64 `protobuf:"varint,3,opt,name=timestamp" json:"timestamp,omitempty"` Type *SyncMessage_CallEvent_Type `protobuf:"varint,4,opt,name=type,enum=signalservice.SyncMessage_CallEvent_Type" json:"type,omitempty"` Direction *SyncMessage_CallEvent_Direction `protobuf:"varint,5,opt,name=direction,enum=signalservice.SyncMessage_CallEvent_Direction" json:"direction,omitempty"` Event *SyncMessage_CallEvent_Event `protobuf:"varint,6,opt,name=event,enum=signalservice.SyncMessage_CallEvent_Event" json:"event,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } func (x *SyncMessage_CallEvent) Reset() { @@ -6621,13 +6585,12 @@ func (x *SyncMessage_CallEvent) GetEvent() SyncMessage_CallEvent_Event { } type SyncMessage_CallLinkUpdate struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` + RootKey []byte `protobuf:"bytes,1,opt,name=rootKey" json:"rootKey,omitempty"` + AdminPassKey []byte `protobuf:"bytes,2,opt,name=adminPassKey" json:"adminPassKey,omitempty"` + Type *SyncMessage_CallLinkUpdate_Type `protobuf:"varint,3,opt,name=type,enum=signalservice.SyncMessage_CallLinkUpdate_Type" json:"type,omitempty"` unknownFields protoimpl.UnknownFields - - RootKey []byte `protobuf:"bytes,1,opt,name=rootKey" json:"rootKey,omitempty"` - AdminPassKey []byte `protobuf:"bytes,2,opt,name=adminPassKey" json:"adminPassKey,omitempty"` - Type *SyncMessage_CallLinkUpdate_Type `protobuf:"varint,3,opt,name=type,enum=signalservice.SyncMessage_CallLinkUpdate_Type" json:"type,omitempty"` + sizeCache protoimpl.SizeCache } func (x *SyncMessage_CallLinkUpdate) Reset() { @@ -6682,10 +6645,7 @@ func (x *SyncMessage_CallLinkUpdate) GetType() SyncMessage_CallLinkUpdate_Type { } type SyncMessage_CallLogEvent struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - + state protoimpl.MessageState `protogen:"open.v1"` Type *SyncMessage_CallLogEvent_Type `protobuf:"varint,1,opt,name=type,enum=signalservice.SyncMessage_CallLogEvent_Type" json:"type,omitempty"` Timestamp *uint64 `protobuf:"varint,2,opt,name=timestamp" json:"timestamp,omitempty"` // Data identifying a conversation. The service ID for 1:1, the group ID for @@ -6694,7 +6654,9 @@ type SyncMessage_CallLogEvent struct { ConversationId []byte `protobuf:"bytes,3,opt,name=conversationId" json:"conversationId,omitempty"` // An identifier for a call. Generated directly for 1:1, or derived from // the era ID for group and ad-hoc calls. See also `CallEvent/callId`. - CallId *uint64 `protobuf:"varint,4,opt,name=callId" json:"callId,omitempty"` + CallId *uint64 `protobuf:"varint,4,opt,name=callId" json:"callId,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } func (x *SyncMessage_CallLogEvent) Reset() { @@ -6756,14 +6718,13 @@ func (x *SyncMessage_CallLogEvent) GetCallId() uint64 { } type SyncMessage_DeleteForMe struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - + state protoimpl.MessageState `protogen:"open.v1"` MessageDeletes []*SyncMessage_DeleteForMe_MessageDeletes `protobuf:"bytes,1,rep,name=messageDeletes" json:"messageDeletes,omitempty"` ConversationDeletes []*SyncMessage_DeleteForMe_ConversationDelete `protobuf:"bytes,2,rep,name=conversationDeletes" json:"conversationDeletes,omitempty"` LocalOnlyConversationDeletes []*SyncMessage_DeleteForMe_LocalOnlyConversationDelete `protobuf:"bytes,3,rep,name=localOnlyConversationDeletes" json:"localOnlyConversationDeletes,omitempty"` AttachmentDeletes []*SyncMessage_DeleteForMe_AttachmentDelete `protobuf:"bytes,4,rep,name=attachmentDeletes" json:"attachmentDeletes,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } func (x *SyncMessage_DeleteForMe) Reset() { @@ -6825,11 +6786,10 @@ func (x *SyncMessage_DeleteForMe) GetAttachmentDeletes() []*SyncMessage_DeleteFo } type SyncMessage_DeviceNameChange struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` + DeviceId *uint32 `protobuf:"varint,2,opt,name=deviceId" json:"deviceId,omitempty"` unknownFields protoimpl.UnknownFields - - DeviceId *uint32 `protobuf:"varint,2,opt,name=deviceId" json:"deviceId,omitempty"` + sizeCache protoimpl.SizeCache } func (x *SyncMessage_DeviceNameChange) Reset() { @@ -6870,13 +6830,12 @@ func (x *SyncMessage_DeviceNameChange) GetDeviceId() uint32 { } type SyncMessage_Sent_UnidentifiedDeliveryStatus struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - DestinationServiceId *string `protobuf:"bytes,3,opt,name=destinationServiceId" json:"destinationServiceId,omitempty"` - Unidentified *bool `protobuf:"varint,2,opt,name=unidentified" json:"unidentified,omitempty"` - DestinationIdentityKey []byte `protobuf:"bytes,5,opt,name=destinationIdentityKey" json:"destinationIdentityKey,omitempty"` + state protoimpl.MessageState `protogen:"open.v1"` + DestinationServiceId *string `protobuf:"bytes,3,opt,name=destinationServiceId" json:"destinationServiceId,omitempty"` + Unidentified *bool `protobuf:"varint,2,opt,name=unidentified" json:"unidentified,omitempty"` + DestinationIdentityKey []byte `protobuf:"bytes,5,opt,name=destinationIdentityKey" json:"destinationIdentityKey,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } func (x *SyncMessage_Sent_UnidentifiedDeliveryStatus) Reset() { @@ -6931,13 +6890,12 @@ func (x *SyncMessage_Sent_UnidentifiedDeliveryStatus) GetDestinationIdentityKey( } type SyncMessage_Sent_StoryMessageRecipient struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - DestinationServiceId *string `protobuf:"bytes,1,opt,name=destinationServiceId" json:"destinationServiceId,omitempty"` - DistributionListIds []string `protobuf:"bytes,2,rep,name=distributionListIds" json:"distributionListIds,omitempty"` - IsAllowedToReply *bool `protobuf:"varint,3,opt,name=isAllowedToReply" json:"isAllowedToReply,omitempty"` + state protoimpl.MessageState `protogen:"open.v1"` + DestinationServiceId *string `protobuf:"bytes,1,opt,name=destinationServiceId" json:"destinationServiceId,omitempty"` + DistributionListIds []string `protobuf:"bytes,2,rep,name=distributionListIds" json:"distributionListIds,omitempty"` + IsAllowedToReply *bool `protobuf:"varint,3,opt,name=isAllowedToReply" json:"isAllowedToReply,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } func (x *SyncMessage_Sent_StoryMessageRecipient) Reset() { @@ -6992,11 +6950,8 @@ func (x *SyncMessage_Sent_StoryMessageRecipient) GetIsAllowedToReply() bool { } type SyncMessage_OutgoingPayment_MobileCoin struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - RecipientAddress []byte `protobuf:"bytes,1,opt,name=recipientAddress" json:"recipientAddress,omitempty"` + state protoimpl.MessageState `protogen:"open.v1"` + RecipientAddress []byte `protobuf:"bytes,1,opt,name=recipientAddress" json:"recipientAddress,omitempty"` // @required AmountPicoMob *uint64 `protobuf:"varint,2,opt,name=amountPicoMob" json:"amountPicoMob,omitempty"` // @required @@ -7007,6 +6962,8 @@ type SyncMessage_OutgoingPayment_MobileCoin struct { LedgerBlockIndex *uint64 `protobuf:"varint,6,opt,name=ledgerBlockIndex" json:"ledgerBlockIndex,omitempty"` SpentKeyImages [][]byte `protobuf:"bytes,7,rep,name=spentKeyImages" json:"spentKeyImages,omitempty"` OutputPublicKeys [][]byte `protobuf:"bytes,8,rep,name=outputPublicKeys" json:"outputPublicKeys,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } func (x *SyncMessage_OutgoingPayment_MobileCoin) Reset() { @@ -7096,16 +7053,15 @@ func (x *SyncMessage_OutgoingPayment_MobileCoin) GetOutputPublicKeys() [][]byte } type SyncMessage_DeleteForMe_ConversationIdentifier struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // Types that are assignable to Identifier: + state protoimpl.MessageState `protogen:"open.v1"` + // Types that are valid to be assigned to Identifier: // // *SyncMessage_DeleteForMe_ConversationIdentifier_ThreadServiceId // *SyncMessage_DeleteForMe_ConversationIdentifier_ThreadGroupId // *SyncMessage_DeleteForMe_ConversationIdentifier_ThreadE164 - Identifier isSyncMessage_DeleteForMe_ConversationIdentifier_Identifier `protobuf_oneof:"identifier"` + Identifier isSyncMessage_DeleteForMe_ConversationIdentifier_Identifier `protobuf_oneof:"identifier"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } func (x *SyncMessage_DeleteForMe_ConversationIdentifier) Reset() { @@ -7138,30 +7094,36 @@ func (*SyncMessage_DeleteForMe_ConversationIdentifier) Descriptor() ([]byte, []i return file_SignalService_proto_rawDescGZIP(), []int{12, 17, 0} } -func (m *SyncMessage_DeleteForMe_ConversationIdentifier) GetIdentifier() isSyncMessage_DeleteForMe_ConversationIdentifier_Identifier { - if m != nil { - return m.Identifier +func (x *SyncMessage_DeleteForMe_ConversationIdentifier) GetIdentifier() isSyncMessage_DeleteForMe_ConversationIdentifier_Identifier { + if x != nil { + return x.Identifier } return nil } func (x *SyncMessage_DeleteForMe_ConversationIdentifier) GetThreadServiceId() string { - if x, ok := x.GetIdentifier().(*SyncMessage_DeleteForMe_ConversationIdentifier_ThreadServiceId); ok { - return x.ThreadServiceId + if x != nil { + if x, ok := x.Identifier.(*SyncMessage_DeleteForMe_ConversationIdentifier_ThreadServiceId); ok { + return x.ThreadServiceId + } } return "" } func (x *SyncMessage_DeleteForMe_ConversationIdentifier) GetThreadGroupId() []byte { - if x, ok := x.GetIdentifier().(*SyncMessage_DeleteForMe_ConversationIdentifier_ThreadGroupId); ok { - return x.ThreadGroupId + if x != nil { + if x, ok := x.Identifier.(*SyncMessage_DeleteForMe_ConversationIdentifier_ThreadGroupId); ok { + return x.ThreadGroupId + } } return nil } func (x *SyncMessage_DeleteForMe_ConversationIdentifier) GetThreadE164() string { - if x, ok := x.GetIdentifier().(*SyncMessage_DeleteForMe_ConversationIdentifier_ThreadE164); ok { - return x.ThreadE164 + if x != nil { + if x, ok := x.Identifier.(*SyncMessage_DeleteForMe_ConversationIdentifier_ThreadE164); ok { + return x.ThreadE164 + } } return "" } @@ -7192,16 +7154,15 @@ func (*SyncMessage_DeleteForMe_ConversationIdentifier_ThreadE164) isSyncMessage_ } type SyncMessage_DeleteForMe_AddressableMessage struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // Types that are assignable to Author: + state protoimpl.MessageState `protogen:"open.v1"` + // Types that are valid to be assigned to Author: // // *SyncMessage_DeleteForMe_AddressableMessage_AuthorServiceId // *SyncMessage_DeleteForMe_AddressableMessage_AuthorE164 Author isSyncMessage_DeleteForMe_AddressableMessage_Author `protobuf_oneof:"author"` SentTimestamp *uint64 `protobuf:"varint,3,opt,name=sentTimestamp" json:"sentTimestamp,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } func (x *SyncMessage_DeleteForMe_AddressableMessage) Reset() { @@ -7234,23 +7195,27 @@ func (*SyncMessage_DeleteForMe_AddressableMessage) Descriptor() ([]byte, []int) return file_SignalService_proto_rawDescGZIP(), []int{12, 17, 1} } -func (m *SyncMessage_DeleteForMe_AddressableMessage) GetAuthor() isSyncMessage_DeleteForMe_AddressableMessage_Author { - if m != nil { - return m.Author +func (x *SyncMessage_DeleteForMe_AddressableMessage) GetAuthor() isSyncMessage_DeleteForMe_AddressableMessage_Author { + if x != nil { + return x.Author } return nil } func (x *SyncMessage_DeleteForMe_AddressableMessage) GetAuthorServiceId() string { - if x, ok := x.GetAuthor().(*SyncMessage_DeleteForMe_AddressableMessage_AuthorServiceId); ok { - return x.AuthorServiceId + if x != nil { + if x, ok := x.Author.(*SyncMessage_DeleteForMe_AddressableMessage_AuthorServiceId); ok { + return x.AuthorServiceId + } } return "" } func (x *SyncMessage_DeleteForMe_AddressableMessage) GetAuthorE164() string { - if x, ok := x.GetAuthor().(*SyncMessage_DeleteForMe_AddressableMessage_AuthorE164); ok { - return x.AuthorE164 + if x != nil { + if x, ok := x.Author.(*SyncMessage_DeleteForMe_AddressableMessage_AuthorE164); ok { + return x.AuthorE164 + } } return "" } @@ -7281,12 +7246,11 @@ func (*SyncMessage_DeleteForMe_AddressableMessage_AuthorE164) isSyncMessage_Dele } type SyncMessage_DeleteForMe_MessageDeletes struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` + Conversation *SyncMessage_DeleteForMe_ConversationIdentifier `protobuf:"bytes,1,opt,name=conversation" json:"conversation,omitempty"` + Messages []*SyncMessage_DeleteForMe_AddressableMessage `protobuf:"bytes,2,rep,name=messages" json:"messages,omitempty"` unknownFields protoimpl.UnknownFields - - Conversation *SyncMessage_DeleteForMe_ConversationIdentifier `protobuf:"bytes,1,opt,name=conversation" json:"conversation,omitempty"` - Messages []*SyncMessage_DeleteForMe_AddressableMessage `protobuf:"bytes,2,rep,name=messages" json:"messages,omitempty"` + sizeCache protoimpl.SizeCache } func (x *SyncMessage_DeleteForMe_MessageDeletes) Reset() { @@ -7334,15 +7298,14 @@ func (x *SyncMessage_DeleteForMe_MessageDeletes) GetMessages() []*SyncMessage_De } type SyncMessage_DeleteForMe_AttachmentDelete struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - + state protoimpl.MessageState `protogen:"open.v1"` Conversation *SyncMessage_DeleteForMe_ConversationIdentifier `protobuf:"bytes,1,opt,name=conversation" json:"conversation,omitempty"` TargetMessage *SyncMessage_DeleteForMe_AddressableMessage `protobuf:"bytes,2,opt,name=targetMessage" json:"targetMessage,omitempty"` Uuid []byte `protobuf:"bytes,3,opt,name=uuid" json:"uuid,omitempty"` // The `uuid` from the `Attachment`. FallbackDigest []byte `protobuf:"bytes,4,opt,name=fallbackDigest" json:"fallbackDigest,omitempty"` FallbackPlaintextHash []byte `protobuf:"bytes,5,opt,name=fallbackPlaintextHash" json:"fallbackPlaintextHash,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } func (x *SyncMessage_DeleteForMe_AttachmentDelete) Reset() { @@ -7411,14 +7374,13 @@ func (x *SyncMessage_DeleteForMe_AttachmentDelete) GetFallbackPlaintextHash() [] } type SyncMessage_DeleteForMe_ConversationDelete struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - + state protoimpl.MessageState `protogen:"open.v1"` Conversation *SyncMessage_DeleteForMe_ConversationIdentifier `protobuf:"bytes,1,opt,name=conversation" json:"conversation,omitempty"` MostRecentMessages []*SyncMessage_DeleteForMe_AddressableMessage `protobuf:"bytes,2,rep,name=mostRecentMessages" json:"mostRecentMessages,omitempty"` MostRecentNonExpiringMessages []*SyncMessage_DeleteForMe_AddressableMessage `protobuf:"bytes,4,rep,name=mostRecentNonExpiringMessages" json:"mostRecentNonExpiringMessages,omitempty"` IsFullDelete *bool `protobuf:"varint,3,opt,name=isFullDelete" json:"isFullDelete,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } func (x *SyncMessage_DeleteForMe_ConversationDelete) Reset() { @@ -7480,11 +7442,10 @@ func (x *SyncMessage_DeleteForMe_ConversationDelete) GetIsFullDelete() bool { } type SyncMessage_DeleteForMe_LocalOnlyConversationDelete struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` + Conversation *SyncMessage_DeleteForMe_ConversationIdentifier `protobuf:"bytes,1,opt,name=conversation" json:"conversation,omitempty"` unknownFields protoimpl.UnknownFields - - Conversation *SyncMessage_DeleteForMe_ConversationIdentifier `protobuf:"bytes,1,opt,name=conversation" json:"conversation,omitempty"` + sizeCache protoimpl.SizeCache } func (x *SyncMessage_DeleteForMe_LocalOnlyConversationDelete) Reset() { @@ -7525,11 +7486,10 @@ func (x *SyncMessage_DeleteForMe_LocalOnlyConversationDelete) GetConversation() } type GroupContext_Member struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` + E164 *string `protobuf:"bytes,2,opt,name=e164" json:"e164,omitempty"` unknownFields protoimpl.UnknownFields - - E164 *string `protobuf:"bytes,2,opt,name=e164" json:"e164,omitempty"` + sizeCache protoimpl.SizeCache } func (x *GroupContext_Member) Reset() { @@ -7570,12 +7530,11 @@ func (x *GroupContext_Member) GetE164() string { } type ContactDetails_Avatar struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` + ContentType *string `protobuf:"bytes,1,opt,name=contentType" json:"contentType,omitempty"` + Length *uint32 `protobuf:"varint,2,opt,name=length" json:"length,omitempty"` unknownFields protoimpl.UnknownFields - - ContentType *string `protobuf:"bytes,1,opt,name=contentType" json:"contentType,omitempty"` - Length *uint32 `protobuf:"varint,2,opt,name=length" json:"length,omitempty"` + sizeCache protoimpl.SizeCache } func (x *ContactDetails_Avatar) Reset() { @@ -7623,12 +7582,11 @@ func (x *ContactDetails_Avatar) GetLength() uint32 { } type GroupDetails_Avatar struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` + ContentType *string `protobuf:"bytes,1,opt,name=contentType" json:"contentType,omitempty"` + Length *uint32 `protobuf:"varint,2,opt,name=length" json:"length,omitempty"` unknownFields protoimpl.UnknownFields - - ContentType *string `protobuf:"bytes,1,opt,name=contentType" json:"contentType,omitempty"` - Length *uint32 `protobuf:"varint,2,opt,name=length" json:"length,omitempty"` + sizeCache protoimpl.SizeCache } func (x *GroupDetails_Avatar) Reset() { @@ -7676,11 +7634,10 @@ func (x *GroupDetails_Avatar) GetLength() uint32 { } type GroupDetails_Member struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` + E164 *string `protobuf:"bytes,2,opt,name=e164" json:"e164,omitempty"` unknownFields protoimpl.UnknownFields - - E164 *string `protobuf:"bytes,2,opt,name=e164" json:"e164,omitempty"` + sizeCache protoimpl.SizeCache } func (x *GroupDetails_Member) Reset() { @@ -7721,12 +7678,11 @@ func (x *GroupDetails_Member) GetE164() string { } type PaymentAddress_MobileCoinAddress struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` + Address []byte `protobuf:"bytes,1,opt,name=address" json:"address,omitempty"` + Signature []byte `protobuf:"bytes,2,opt,name=signature" json:"signature,omitempty"` unknownFields protoimpl.UnknownFields - - Address []byte `protobuf:"bytes,1,opt,name=address" json:"address,omitempty"` - Signature []byte `protobuf:"bytes,2,opt,name=signature" json:"signature,omitempty"` + sizeCache protoimpl.SizeCache } func (x *PaymentAddress_MobileCoinAddress) Reset() { diff --git a/pkg/signalmeow/protobuf/StickerResources.pb.go b/pkg/signalmeow/protobuf/StickerResources.pb.go index d49db13..c194ebc 100644 --- a/pkg/signalmeow/protobuf/StickerResources.pb.go +++ b/pkg/signalmeow/protobuf/StickerResources.pb.go @@ -5,7 +5,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.35.2 +// protoc-gen-go v1.36.1 // protoc v3.21.12 // source: StickerResources.proto @@ -28,14 +28,13 @@ const ( ) type Pack struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` + Title *string `protobuf:"bytes,1,opt,name=title" json:"title,omitempty"` + Author *string `protobuf:"bytes,2,opt,name=author" json:"author,omitempty"` + Cover *Pack_Sticker `protobuf:"bytes,3,opt,name=cover" json:"cover,omitempty"` + Stickers []*Pack_Sticker `protobuf:"bytes,4,rep,name=stickers" json:"stickers,omitempty"` unknownFields protoimpl.UnknownFields - - Title *string `protobuf:"bytes,1,opt,name=title" json:"title,omitempty"` - Author *string `protobuf:"bytes,2,opt,name=author" json:"author,omitempty"` - Cover *Pack_Sticker `protobuf:"bytes,3,opt,name=cover" json:"cover,omitempty"` - Stickers []*Pack_Sticker `protobuf:"bytes,4,rep,name=stickers" json:"stickers,omitempty"` + sizeCache protoimpl.SizeCache } func (x *Pack) Reset() { @@ -97,13 +96,12 @@ func (x *Pack) GetStickers() []*Pack_Sticker { } type Pack_Sticker struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` + Id *uint32 `protobuf:"varint,1,opt,name=id" json:"id,omitempty"` + Emoji *string `protobuf:"bytes,2,opt,name=emoji" json:"emoji,omitempty"` + ContentType *string `protobuf:"bytes,3,opt,name=contentType" json:"contentType,omitempty"` unknownFields protoimpl.UnknownFields - - Id *uint32 `protobuf:"varint,1,opt,name=id" json:"id,omitempty"` - Emoji *string `protobuf:"bytes,2,opt,name=emoji" json:"emoji,omitempty"` - ContentType *string `protobuf:"bytes,3,opt,name=contentType" json:"contentType,omitempty"` + sizeCache protoimpl.SizeCache } func (x *Pack_Sticker) Reset() { diff --git a/pkg/signalmeow/protobuf/StorageService.pb.go b/pkg/signalmeow/protobuf/StorageService.pb.go index d37c1e2..ee6fbef 100644 --- a/pkg/signalmeow/protobuf/StorageService.pb.go +++ b/pkg/signalmeow/protobuf/StorageService.pb.go @@ -5,7 +5,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.35.2 +// protoc-gen-go v1.36.1 // protoc v3.21.12 // source: StorageService.proto @@ -352,12 +352,11 @@ func (AccountRecord_UsernameLink_Color) EnumDescriptor() ([]byte, []int) { } type StorageManifest struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` + Version uint64 `protobuf:"varint,1,opt,name=version,proto3" json:"version,omitempty"` + Value []byte `protobuf:"bytes,2,opt,name=value,proto3" json:"value,omitempty"` unknownFields protoimpl.UnknownFields - - Version uint64 `protobuf:"varint,1,opt,name=version,proto3" json:"version,omitempty"` - Value []byte `protobuf:"bytes,2,opt,name=value,proto3" json:"value,omitempty"` + sizeCache protoimpl.SizeCache } func (x *StorageManifest) Reset() { @@ -405,12 +404,11 @@ func (x *StorageManifest) GetValue() []byte { } type StorageItem struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` + Key []byte `protobuf:"bytes,1,opt,name=key,proto3" json:"key,omitempty"` + Value []byte `protobuf:"bytes,2,opt,name=value,proto3" json:"value,omitempty"` unknownFields protoimpl.UnknownFields - - Key []byte `protobuf:"bytes,1,opt,name=key,proto3" json:"key,omitempty"` - Value []byte `protobuf:"bytes,2,opt,name=value,proto3" json:"value,omitempty"` + sizeCache protoimpl.SizeCache } func (x *StorageItem) Reset() { @@ -458,11 +456,10 @@ func (x *StorageItem) GetValue() []byte { } type StorageItems struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` + Items []*StorageItem `protobuf:"bytes,1,rep,name=items,proto3" json:"items,omitempty"` unknownFields protoimpl.UnknownFields - - Items []*StorageItem `protobuf:"bytes,1,rep,name=items,proto3" json:"items,omitempty"` + sizeCache protoimpl.SizeCache } func (x *StorageItems) Reset() { @@ -503,11 +500,10 @@ func (x *StorageItems) GetItems() []*StorageItem { } type ReadOperation struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` + ReadKey [][]byte `protobuf:"bytes,1,rep,name=readKey,proto3" json:"readKey,omitempty"` unknownFields protoimpl.UnknownFields - - ReadKey [][]byte `protobuf:"bytes,1,rep,name=readKey,proto3" json:"readKey,omitempty"` + sizeCache protoimpl.SizeCache } func (x *ReadOperation) Reset() { @@ -548,14 +544,13 @@ func (x *ReadOperation) GetReadKey() [][]byte { } type WriteOperation struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` + Manifest *StorageManifest `protobuf:"bytes,1,opt,name=manifest,proto3" json:"manifest,omitempty"` + InsertItem []*StorageItem `protobuf:"bytes,2,rep,name=insertItem,proto3" json:"insertItem,omitempty"` + DeleteKey [][]byte `protobuf:"bytes,3,rep,name=deleteKey,proto3" json:"deleteKey,omitempty"` + ClearAll bool `protobuf:"varint,4,opt,name=clearAll,proto3" json:"clearAll,omitempty"` unknownFields protoimpl.UnknownFields - - Manifest *StorageManifest `protobuf:"bytes,1,opt,name=manifest,proto3" json:"manifest,omitempty"` - InsertItem []*StorageItem `protobuf:"bytes,2,rep,name=insertItem,proto3" json:"insertItem,omitempty"` - DeleteKey [][]byte `protobuf:"bytes,3,rep,name=deleteKey,proto3" json:"deleteKey,omitempty"` - ClearAll bool `protobuf:"varint,4,opt,name=clearAll,proto3" json:"clearAll,omitempty"` + sizeCache protoimpl.SizeCache } func (x *WriteOperation) Reset() { @@ -617,14 +612,13 @@ func (x *WriteOperation) GetClearAll() bool { } type ManifestRecord struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` + Version uint64 `protobuf:"varint,1,opt,name=version,proto3" json:"version,omitempty"` + SourceDevice uint32 `protobuf:"varint,3,opt,name=sourceDevice,proto3" json:"sourceDevice,omitempty"` + Identifiers []*ManifestRecord_Identifier `protobuf:"bytes,2,rep,name=identifiers,proto3" json:"identifiers,omitempty"` + RecordIkm []byte `protobuf:"bytes,4,opt,name=recordIkm,proto3" json:"recordIkm,omitempty"` // Next ID: 5 unknownFields protoimpl.UnknownFields - - Version uint64 `protobuf:"varint,1,opt,name=version,proto3" json:"version,omitempty"` - SourceDevice uint32 `protobuf:"varint,3,opt,name=sourceDevice,proto3" json:"sourceDevice,omitempty"` - Identifiers []*ManifestRecord_Identifier `protobuf:"bytes,2,rep,name=identifiers,proto3" json:"identifiers,omitempty"` - RecordIkm []byte `protobuf:"bytes,4,opt,name=recordIkm,proto3" json:"recordIkm,omitempty"` // Next ID: 5 + sizeCache protoimpl.SizeCache } func (x *ManifestRecord) Reset() { @@ -686,11 +680,8 @@ func (x *ManifestRecord) GetRecordIkm() []byte { } type StorageRecord struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // Types that are assignable to Record: + state protoimpl.MessageState `protogen:"open.v1"` + // Types that are valid to be assigned to Record: // // *StorageRecord_Contact // *StorageRecord_GroupV1 @@ -698,7 +689,9 @@ type StorageRecord struct { // *StorageRecord_Account // *StorageRecord_StoryDistributionList // *StorageRecord_CallLink - Record isStorageRecord_Record `protobuf_oneof:"record"` + Record isStorageRecord_Record `protobuf_oneof:"record"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } func (x *StorageRecord) Reset() { @@ -731,51 +724,63 @@ func (*StorageRecord) Descriptor() ([]byte, []int) { return file_StorageService_proto_rawDescGZIP(), []int{6} } -func (m *StorageRecord) GetRecord() isStorageRecord_Record { - if m != nil { - return m.Record +func (x *StorageRecord) GetRecord() isStorageRecord_Record { + if x != nil { + return x.Record } return nil } func (x *StorageRecord) GetContact() *ContactRecord { - if x, ok := x.GetRecord().(*StorageRecord_Contact); ok { - return x.Contact + if x != nil { + if x, ok := x.Record.(*StorageRecord_Contact); ok { + return x.Contact + } } return nil } func (x *StorageRecord) GetGroupV1() *GroupV1Record { - if x, ok := x.GetRecord().(*StorageRecord_GroupV1); ok { - return x.GroupV1 + if x != nil { + if x, ok := x.Record.(*StorageRecord_GroupV1); ok { + return x.GroupV1 + } } return nil } func (x *StorageRecord) GetGroupV2() *GroupV2Record { - if x, ok := x.GetRecord().(*StorageRecord_GroupV2); ok { - return x.GroupV2 + if x != nil { + if x, ok := x.Record.(*StorageRecord_GroupV2); ok { + return x.GroupV2 + } } return nil } func (x *StorageRecord) GetAccount() *AccountRecord { - if x, ok := x.GetRecord().(*StorageRecord_Account); ok { - return x.Account + if x != nil { + if x, ok := x.Record.(*StorageRecord_Account); ok { + return x.Account + } } return nil } func (x *StorageRecord) GetStoryDistributionList() *StoryDistributionListRecord { - if x, ok := x.GetRecord().(*StorageRecord_StoryDistributionList); ok { - return x.StoryDistributionList + if x != nil { + if x, ok := x.Record.(*StorageRecord_StoryDistributionList); ok { + return x.StoryDistributionList + } } return nil } func (x *StorageRecord) GetCallLink() *CallLinkRecord { - if x, ok := x.GetRecord().(*StorageRecord_CallLink); ok { - return x.CallLink + if x != nil { + if x, ok := x.Record.(*StorageRecord_CallLink); ok { + return x.CallLink + } } return nil } @@ -821,10 +826,7 @@ func (*StorageRecord_StoryDistributionList) isStorageRecord_Record() {} func (*StorageRecord_CallLink) isStorageRecord_Record() {} type ContactRecord struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - + state protoimpl.MessageState `protogen:"open.v1"` Aci string `protobuf:"bytes,1,opt,name=aci,proto3" json:"aci,omitempty"` E164 string `protobuf:"bytes,2,opt,name=e164,proto3" json:"e164,omitempty"` Pni string `protobuf:"bytes,15,opt,name=pni,proto3" json:"pni,omitempty"` @@ -848,6 +850,8 @@ type ContactRecord struct { PniSignatureVerified bool `protobuf:"varint,21,opt,name=pniSignatureVerified,proto3" json:"pniSignatureVerified,omitempty"` Nickname *ContactRecord_Name `protobuf:"bytes,22,opt,name=nickname,proto3" json:"nickname,omitempty"` Note string `protobuf:"bytes,23,opt,name=note,proto3" json:"note,omitempty"` // NEXT ID: 24 + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } func (x *ContactRecord) Reset() { @@ -1042,16 +1046,15 @@ func (x *ContactRecord) GetNote() string { } type GroupV1Record struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Id []byte `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` - Blocked bool `protobuf:"varint,2,opt,name=blocked,proto3" json:"blocked,omitempty"` - Whitelisted bool `protobuf:"varint,3,opt,name=whitelisted,proto3" json:"whitelisted,omitempty"` - Archived bool `protobuf:"varint,4,opt,name=archived,proto3" json:"archived,omitempty"` - MarkedUnread bool `protobuf:"varint,5,opt,name=markedUnread,proto3" json:"markedUnread,omitempty"` - MutedUntilTimestamp uint64 `protobuf:"varint,6,opt,name=mutedUntilTimestamp,proto3" json:"mutedUntilTimestamp,omitempty"` + state protoimpl.MessageState `protogen:"open.v1"` + Id []byte `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + Blocked bool `protobuf:"varint,2,opt,name=blocked,proto3" json:"blocked,omitempty"` + Whitelisted bool `protobuf:"varint,3,opt,name=whitelisted,proto3" json:"whitelisted,omitempty"` + Archived bool `protobuf:"varint,4,opt,name=archived,proto3" json:"archived,omitempty"` + MarkedUnread bool `protobuf:"varint,5,opt,name=markedUnread,proto3" json:"markedUnread,omitempty"` + MutedUntilTimestamp uint64 `protobuf:"varint,6,opt,name=mutedUntilTimestamp,proto3" json:"mutedUntilTimestamp,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } func (x *GroupV1Record) Reset() { @@ -1127,10 +1130,7 @@ func (x *GroupV1Record) GetMutedUntilTimestamp() uint64 { } type GroupV2Record struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - + state protoimpl.MessageState `protogen:"open.v1"` MasterKey []byte `protobuf:"bytes,1,opt,name=masterKey,proto3" json:"masterKey,omitempty"` Blocked bool `protobuf:"varint,2,opt,name=blocked,proto3" json:"blocked,omitempty"` Whitelisted bool `protobuf:"varint,3,opt,name=whitelisted,proto3" json:"whitelisted,omitempty"` @@ -1140,6 +1140,8 @@ type GroupV2Record struct { DontNotifyForMentionsIfMuted bool `protobuf:"varint,7,opt,name=dontNotifyForMentionsIfMuted,proto3" json:"dontNotifyForMentionsIfMuted,omitempty"` HideStory bool `protobuf:"varint,8,opt,name=hideStory,proto3" json:"hideStory,omitempty"` StorySendMode GroupV2Record_StorySendMode `protobuf:"varint,10,opt,name=storySendMode,proto3,enum=signalservice.GroupV2Record_StorySendMode" json:"storySendMode,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } func (x *GroupV2Record) Reset() { @@ -1236,12 +1238,11 @@ func (x *GroupV2Record) GetStorySendMode() GroupV2Record_StorySendMode { } type Payments struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` + Enabled bool `protobuf:"varint,1,opt,name=enabled,proto3" json:"enabled,omitempty"` + Entropy []byte `protobuf:"bytes,2,opt,name=entropy,proto3" json:"entropy,omitempty"` unknownFields protoimpl.UnknownFields - - Enabled bool `protobuf:"varint,1,opt,name=enabled,proto3" json:"enabled,omitempty"` - Entropy []byte `protobuf:"bytes,2,opt,name=entropy,proto3" json:"entropy,omitempty"` + sizeCache protoimpl.SizeCache } func (x *Payments) Reset() { @@ -1289,10 +1290,7 @@ func (x *Payments) GetEntropy() []byte { } type AccountRecord struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - + state protoimpl.MessageState `protogen:"open.v1"` ProfileKey []byte `protobuf:"bytes,1,opt,name=profileKey,proto3" json:"profileKey,omitempty"` GivenName string `protobuf:"bytes,2,opt,name=givenName,proto3" json:"givenName,omitempty"` FamilyName string `protobuf:"bytes,3,opt,name=familyName,proto3" json:"familyName,omitempty"` @@ -1327,6 +1325,8 @@ type AccountRecord struct { UsernameLink *AccountRecord_UsernameLink `protobuf:"bytes,35,opt,name=usernameLink,proto3" json:"usernameLink,omitempty"` BackupsSubscriberId []byte `protobuf:"bytes,36,opt,name=backupsSubscriberId,proto3" json:"backupsSubscriberId,omitempty"` BackupsSubscriberCurrencyCode string `protobuf:"bytes,37,opt,name=backupsSubscriberCurrencyCode,proto3" json:"backupsSubscriberCurrencyCode,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } func (x *AccountRecord) Reset() { @@ -1598,16 +1598,15 @@ func (x *AccountRecord) GetBackupsSubscriberCurrencyCode() string { } type StoryDistributionListRecord struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Identifier []byte `protobuf:"bytes,1,opt,name=identifier,proto3" json:"identifier,omitempty"` - Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` - RecipientServiceIds []string `protobuf:"bytes,3,rep,name=recipientServiceIds,proto3" json:"recipientServiceIds,omitempty"` - DeletedAtTimestamp uint64 `protobuf:"varint,4,opt,name=deletedAtTimestamp,proto3" json:"deletedAtTimestamp,omitempty"` - AllowsReplies bool `protobuf:"varint,5,opt,name=allowsReplies,proto3" json:"allowsReplies,omitempty"` - IsBlockList bool `protobuf:"varint,6,opt,name=isBlockList,proto3" json:"isBlockList,omitempty"` + state protoimpl.MessageState `protogen:"open.v1"` + Identifier []byte `protobuf:"bytes,1,opt,name=identifier,proto3" json:"identifier,omitempty"` + Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` + RecipientServiceIds []string `protobuf:"bytes,3,rep,name=recipientServiceIds,proto3" json:"recipientServiceIds,omitempty"` + DeletedAtTimestamp uint64 `protobuf:"varint,4,opt,name=deletedAtTimestamp,proto3" json:"deletedAtTimestamp,omitempty"` + AllowsReplies bool `protobuf:"varint,5,opt,name=allowsReplies,proto3" json:"allowsReplies,omitempty"` + IsBlockList bool `protobuf:"varint,6,opt,name=isBlockList,proto3" json:"isBlockList,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } func (x *StoryDistributionListRecord) Reset() { @@ -1683,13 +1682,12 @@ func (x *StoryDistributionListRecord) GetIsBlockList() bool { } type CallLinkRecord struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - RootKey []byte `protobuf:"bytes,1,opt,name=rootKey,proto3" json:"rootKey,omitempty"` - AdminPasskey []byte `protobuf:"bytes,2,opt,name=adminPasskey,proto3" json:"adminPasskey,omitempty"` - DeletedAtTimestampMs uint64 `protobuf:"varint,3,opt,name=deletedAtTimestampMs,proto3" json:"deletedAtTimestampMs,omitempty"` + state protoimpl.MessageState `protogen:"open.v1"` + RootKey []byte `protobuf:"bytes,1,opt,name=rootKey,proto3" json:"rootKey,omitempty"` + AdminPasskey []byte `protobuf:"bytes,2,opt,name=adminPasskey,proto3" json:"adminPasskey,omitempty"` + DeletedAtTimestampMs uint64 `protobuf:"varint,3,opt,name=deletedAtTimestampMs,proto3" json:"deletedAtTimestampMs,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } func (x *CallLinkRecord) Reset() { @@ -1744,12 +1742,11 @@ func (x *CallLinkRecord) GetDeletedAtTimestampMs() uint64 { } type ManifestRecord_Identifier struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` + Raw []byte `protobuf:"bytes,1,opt,name=raw,proto3" json:"raw,omitempty"` + Type ManifestRecord_Identifier_Type `protobuf:"varint,2,opt,name=type,proto3,enum=signalservice.ManifestRecord_Identifier_Type" json:"type,omitempty"` unknownFields protoimpl.UnknownFields - - Raw []byte `protobuf:"bytes,1,opt,name=raw,proto3" json:"raw,omitempty"` - Type ManifestRecord_Identifier_Type `protobuf:"varint,2,opt,name=type,proto3,enum=signalservice.ManifestRecord_Identifier_Type" json:"type,omitempty"` + sizeCache protoimpl.SizeCache } func (x *ManifestRecord_Identifier) Reset() { @@ -1797,12 +1794,11 @@ func (x *ManifestRecord_Identifier) GetType() ManifestRecord_Identifier_Type { } type ContactRecord_Name struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` + Given string `protobuf:"bytes,1,opt,name=given,proto3" json:"given,omitempty"` + Family string `protobuf:"bytes,2,opt,name=family,proto3" json:"family,omitempty"` unknownFields protoimpl.UnknownFields - - Given string `protobuf:"bytes,1,opt,name=given,proto3" json:"given,omitempty"` - Family string `protobuf:"bytes,2,opt,name=family,proto3" json:"family,omitempty"` + sizeCache protoimpl.SizeCache } func (x *ContactRecord_Name) Reset() { @@ -1850,16 +1846,15 @@ func (x *ContactRecord_Name) GetFamily() string { } type AccountRecord_PinnedConversation struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // Types that are assignable to Identifier: + state protoimpl.MessageState `protogen:"open.v1"` + // Types that are valid to be assigned to Identifier: // // *AccountRecord_PinnedConversation_Contact_ // *AccountRecord_PinnedConversation_LegacyGroupId // *AccountRecord_PinnedConversation_GroupMasterKey - Identifier isAccountRecord_PinnedConversation_Identifier `protobuf_oneof:"identifier"` + Identifier isAccountRecord_PinnedConversation_Identifier `protobuf_oneof:"identifier"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } func (x *AccountRecord_PinnedConversation) Reset() { @@ -1892,30 +1887,36 @@ func (*AccountRecord_PinnedConversation) Descriptor() ([]byte, []int) { return file_StorageService_proto_rawDescGZIP(), []int{11, 0} } -func (m *AccountRecord_PinnedConversation) GetIdentifier() isAccountRecord_PinnedConversation_Identifier { - if m != nil { - return m.Identifier +func (x *AccountRecord_PinnedConversation) GetIdentifier() isAccountRecord_PinnedConversation_Identifier { + if x != nil { + return x.Identifier } return nil } func (x *AccountRecord_PinnedConversation) GetContact() *AccountRecord_PinnedConversation_Contact { - if x, ok := x.GetIdentifier().(*AccountRecord_PinnedConversation_Contact_); ok { - return x.Contact + if x != nil { + if x, ok := x.Identifier.(*AccountRecord_PinnedConversation_Contact_); ok { + return x.Contact + } } return nil } func (x *AccountRecord_PinnedConversation) GetLegacyGroupId() []byte { - if x, ok := x.GetIdentifier().(*AccountRecord_PinnedConversation_LegacyGroupId); ok { - return x.LegacyGroupId + if x != nil { + if x, ok := x.Identifier.(*AccountRecord_PinnedConversation_LegacyGroupId); ok { + return x.LegacyGroupId + } } return nil } func (x *AccountRecord_PinnedConversation) GetGroupMasterKey() []byte { - if x, ok := x.GetIdentifier().(*AccountRecord_PinnedConversation_GroupMasterKey); ok { - return x.GroupMasterKey + if x != nil { + if x, ok := x.Identifier.(*AccountRecord_PinnedConversation_GroupMasterKey); ok { + return x.GroupMasterKey + } } return nil } @@ -1945,13 +1946,12 @@ func (*AccountRecord_PinnedConversation_GroupMasterKey) isAccountRecord_PinnedCo } type AccountRecord_UsernameLink struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` + Entropy []byte `protobuf:"bytes,1,opt,name=entropy,proto3" json:"entropy,omitempty"` // 32 bytes of entropy used for encryption + ServerId []byte `protobuf:"bytes,2,opt,name=serverId,proto3" json:"serverId,omitempty"` // 16 bytes of encoded UUID provided by the server + Color AccountRecord_UsernameLink_Color `protobuf:"varint,3,opt,name=color,proto3,enum=signalservice.AccountRecord_UsernameLink_Color" json:"color,omitempty"` unknownFields protoimpl.UnknownFields - - Entropy []byte `protobuf:"bytes,1,opt,name=entropy,proto3" json:"entropy,omitempty"` // 32 bytes of entropy used for encryption - ServerId []byte `protobuf:"bytes,2,opt,name=serverId,proto3" json:"serverId,omitempty"` // 16 bytes of encoded UUID provided by the server - Color AccountRecord_UsernameLink_Color `protobuf:"varint,3,opt,name=color,proto3,enum=signalservice.AccountRecord_UsernameLink_Color" json:"color,omitempty"` + sizeCache protoimpl.SizeCache } func (x *AccountRecord_UsernameLink) Reset() { @@ -2006,12 +2006,11 @@ func (x *AccountRecord_UsernameLink) GetColor() AccountRecord_UsernameLink_Color } type AccountRecord_PinnedConversation_Contact struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` + ServiceId string `protobuf:"bytes,1,opt,name=serviceId,proto3" json:"serviceId,omitempty"` + E164 string `protobuf:"bytes,2,opt,name=e164,proto3" json:"e164,omitempty"` unknownFields protoimpl.UnknownFields - - ServiceId string `protobuf:"bytes,1,opt,name=serviceId,proto3" json:"serviceId,omitempty"` - E164 string `protobuf:"bytes,2,opt,name=e164,proto3" json:"e164,omitempty"` + sizeCache protoimpl.SizeCache } func (x *AccountRecord_PinnedConversation_Contact) Reset() { diff --git a/pkg/signalmeow/protobuf/UnidentifiedDelivery.pb.go b/pkg/signalmeow/protobuf/UnidentifiedDelivery.pb.go index e4eda97..1d1da9b 100644 --- a/pkg/signalmeow/protobuf/UnidentifiedDelivery.pb.go +++ b/pkg/signalmeow/protobuf/UnidentifiedDelivery.pb.go @@ -1,6 +1,6 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.35.2 +// protoc-gen-go v1.36.1 // protoc v3.21.12 // source: UnidentifiedDelivery.proto @@ -150,12 +150,11 @@ func (UnidentifiedSenderMessage_Message_ContentHint) EnumDescriptor() ([]byte, [ } type ServerCertificate struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` + Certificate []byte `protobuf:"bytes,1,opt,name=certificate" json:"certificate,omitempty"` + Signature []byte `protobuf:"bytes,2,opt,name=signature" json:"signature,omitempty"` unknownFields protoimpl.UnknownFields - - Certificate []byte `protobuf:"bytes,1,opt,name=certificate" json:"certificate,omitempty"` - Signature []byte `protobuf:"bytes,2,opt,name=signature" json:"signature,omitempty"` + sizeCache protoimpl.SizeCache } func (x *ServerCertificate) Reset() { @@ -203,12 +202,11 @@ func (x *ServerCertificate) GetSignature() []byte { } type SenderCertificate struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` + Certificate []byte `protobuf:"bytes,1,opt,name=certificate" json:"certificate,omitempty"` + Signature []byte `protobuf:"bytes,2,opt,name=signature" json:"signature,omitempty"` unknownFields protoimpl.UnknownFields - - Certificate []byte `protobuf:"bytes,1,opt,name=certificate" json:"certificate,omitempty"` - Signature []byte `protobuf:"bytes,2,opt,name=signature" json:"signature,omitempty"` + sizeCache protoimpl.SizeCache } func (x *SenderCertificate) Reset() { @@ -256,13 +254,12 @@ func (x *SenderCertificate) GetSignature() []byte { } type UnidentifiedSenderMessage struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - EphemeralPublic []byte `protobuf:"bytes,1,opt,name=ephemeralPublic" json:"ephemeralPublic,omitempty"` - EncryptedStatic []byte `protobuf:"bytes,2,opt,name=encryptedStatic" json:"encryptedStatic,omitempty"` - EncryptedMessage []byte `protobuf:"bytes,3,opt,name=encryptedMessage" json:"encryptedMessage,omitempty"` + state protoimpl.MessageState `protogen:"open.v1"` + EphemeralPublic []byte `protobuf:"bytes,1,opt,name=ephemeralPublic" json:"ephemeralPublic,omitempty"` + EncryptedStatic []byte `protobuf:"bytes,2,opt,name=encryptedStatic" json:"encryptedStatic,omitempty"` + EncryptedMessage []byte `protobuf:"bytes,3,opt,name=encryptedMessage" json:"encryptedMessage,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } func (x *UnidentifiedSenderMessage) Reset() { @@ -317,12 +314,11 @@ func (x *UnidentifiedSenderMessage) GetEncryptedMessage() []byte { } type ServerCertificate_Certificate struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` + Id *uint32 `protobuf:"varint,1,opt,name=id" json:"id,omitempty"` + Key []byte `protobuf:"bytes,2,opt,name=key" json:"key,omitempty"` unknownFields protoimpl.UnknownFields - - Id *uint32 `protobuf:"varint,1,opt,name=id" json:"id,omitempty"` - Key []byte `protobuf:"bytes,2,opt,name=key" json:"key,omitempty"` + sizeCache protoimpl.SizeCache } func (x *ServerCertificate_Certificate) Reset() { @@ -370,16 +366,15 @@ func (x *ServerCertificate_Certificate) GetKey() []byte { } type SenderCertificate_Certificate struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` + SenderE164 *string `protobuf:"bytes,1,opt,name=senderE164" json:"senderE164,omitempty"` + SenderUuid *string `protobuf:"bytes,6,opt,name=senderUuid" json:"senderUuid,omitempty"` + SenderDevice *uint32 `protobuf:"varint,2,opt,name=senderDevice" json:"senderDevice,omitempty"` + Expires *uint64 `protobuf:"fixed64,3,opt,name=expires" json:"expires,omitempty"` + IdentityKey []byte `protobuf:"bytes,4,opt,name=identityKey" json:"identityKey,omitempty"` + Signer *ServerCertificate `protobuf:"bytes,5,opt,name=signer" json:"signer,omitempty"` unknownFields protoimpl.UnknownFields - - SenderE164 *string `protobuf:"bytes,1,opt,name=senderE164" json:"senderE164,omitempty"` - SenderUuid *string `protobuf:"bytes,6,opt,name=senderUuid" json:"senderUuid,omitempty"` - SenderDevice *uint32 `protobuf:"varint,2,opt,name=senderDevice" json:"senderDevice,omitempty"` - Expires *uint64 `protobuf:"fixed64,3,opt,name=expires" json:"expires,omitempty"` - IdentityKey []byte `protobuf:"bytes,4,opt,name=identityKey" json:"identityKey,omitempty"` - Signer *ServerCertificate `protobuf:"bytes,5,opt,name=signer" json:"signer,omitempty"` + sizeCache protoimpl.SizeCache } func (x *SenderCertificate_Certificate) Reset() { @@ -455,15 +450,14 @@ func (x *SenderCertificate_Certificate) GetSigner() *ServerCertificate { } type UnidentifiedSenderMessage_Message struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - + state protoimpl.MessageState `protogen:"open.v1"` Type *UnidentifiedSenderMessage_Message_Type `protobuf:"varint,1,opt,name=type,enum=signalservice.UnidentifiedSenderMessage_Message_Type" json:"type,omitempty"` SenderCertificate *SenderCertificate `protobuf:"bytes,2,opt,name=senderCertificate" json:"senderCertificate,omitempty"` Content []byte `protobuf:"bytes,3,opt,name=content" json:"content,omitempty"` ContentHint *UnidentifiedSenderMessage_Message_ContentHint `protobuf:"varint,4,opt,name=contentHint,enum=signalservice.UnidentifiedSenderMessage_Message_ContentHint" json:"contentHint,omitempty"` GroupId []byte `protobuf:"bytes,5,opt,name=groupId" json:"groupId,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } func (x *UnidentifiedSenderMessage_Message) Reset() { diff --git a/pkg/signalmeow/protobuf/WebSocketResources.pb.go b/pkg/signalmeow/protobuf/WebSocketResources.pb.go index 157c802..45d5396 100644 --- a/pkg/signalmeow/protobuf/WebSocketResources.pb.go +++ b/pkg/signalmeow/protobuf/WebSocketResources.pb.go @@ -5,7 +5,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.35.2 +// protoc-gen-go v1.36.1 // protoc v3.21.12 // source: WebSocketResources.proto @@ -87,15 +87,14 @@ func (WebSocketMessage_Type) EnumDescriptor() ([]byte, []int) { } type WebSocketRequestMessage struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` + Verb *string `protobuf:"bytes,1,opt,name=verb" json:"verb,omitempty"` + Path *string `protobuf:"bytes,2,opt,name=path" json:"path,omitempty"` + Body []byte `protobuf:"bytes,3,opt,name=body" json:"body,omitempty"` + Headers []string `protobuf:"bytes,5,rep,name=headers" json:"headers,omitempty"` + Id *uint64 `protobuf:"varint,4,opt,name=id" json:"id,omitempty"` unknownFields protoimpl.UnknownFields - - Verb *string `protobuf:"bytes,1,opt,name=verb" json:"verb,omitempty"` - Path *string `protobuf:"bytes,2,opt,name=path" json:"path,omitempty"` - Body []byte `protobuf:"bytes,3,opt,name=body" json:"body,omitempty"` - Headers []string `protobuf:"bytes,5,rep,name=headers" json:"headers,omitempty"` - Id *uint64 `protobuf:"varint,4,opt,name=id" json:"id,omitempty"` + sizeCache protoimpl.SizeCache } func (x *WebSocketRequestMessage) Reset() { @@ -164,15 +163,14 @@ func (x *WebSocketRequestMessage) GetId() uint64 { } type WebSocketResponseMessage struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` + Id *uint64 `protobuf:"varint,1,opt,name=id" json:"id,omitempty"` + Status *uint32 `protobuf:"varint,2,opt,name=status" json:"status,omitempty"` + Message *string `protobuf:"bytes,3,opt,name=message" json:"message,omitempty"` + Headers []string `protobuf:"bytes,5,rep,name=headers" json:"headers,omitempty"` + Body []byte `protobuf:"bytes,4,opt,name=body" json:"body,omitempty"` unknownFields protoimpl.UnknownFields - - Id *uint64 `protobuf:"varint,1,opt,name=id" json:"id,omitempty"` - Status *uint32 `protobuf:"varint,2,opt,name=status" json:"status,omitempty"` - Message *string `protobuf:"bytes,3,opt,name=message" json:"message,omitempty"` - Headers []string `protobuf:"bytes,5,rep,name=headers" json:"headers,omitempty"` - Body []byte `protobuf:"bytes,4,opt,name=body" json:"body,omitempty"` + sizeCache protoimpl.SizeCache } func (x *WebSocketResponseMessage) Reset() { @@ -241,13 +239,12 @@ func (x *WebSocketResponseMessage) GetBody() []byte { } type WebSocketMessage struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` + Type *WebSocketMessage_Type `protobuf:"varint,1,opt,name=type,enum=signalservice.WebSocketMessage_Type" json:"type,omitempty"` + Request *WebSocketRequestMessage `protobuf:"bytes,2,opt,name=request" json:"request,omitempty"` + Response *WebSocketResponseMessage `protobuf:"bytes,3,opt,name=response" json:"response,omitempty"` unknownFields protoimpl.UnknownFields - - Type *WebSocketMessage_Type `protobuf:"varint,1,opt,name=type,enum=signalservice.WebSocketMessage_Type" json:"type,omitempty"` - Request *WebSocketRequestMessage `protobuf:"bytes,2,opt,name=request" json:"request,omitempty"` - Response *WebSocketResponseMessage `protobuf:"bytes,3,opt,name=response" json:"response,omitempty"` + sizeCache protoimpl.SizeCache } func (x *WebSocketMessage) Reset() { From 44f363fa4b2e5d149130e0df48beeee3d8f9ab36 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Tue, 7 Jan 2025 19:08:27 +0200 Subject: [PATCH 245/580] signalmeow/websocket: don't disconnect on first ping timeout --- pkg/signalmeow/web/signalwebsocket.go | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/pkg/signalmeow/web/signalwebsocket.go b/pkg/signalmeow/web/signalwebsocket.go index 3b192fb..4774b9f 100644 --- a/pkg/signalmeow/web/signalwebsocket.go +++ b/pkg/signalmeow/web/signalwebsocket.go @@ -195,8 +195,8 @@ func (s *SignalWebsocket) connectLoop( log.Warn().Dur("backoff", backoff).Msg("Failed to connect, waiting to retry...") time.Sleep(backoff) backoff += backoffIncrement - } else if !isFirstConnect { - time.Sleep(1 * time.Second) + } else if !isFirstConnect && s.basicAuth != nil { + time.Sleep(initialBackoff) } if ctx.Err() != nil { log.Info().Msg("ctx done, stopping connection loop") @@ -300,6 +300,7 @@ func (s *SignalWebsocket) connectLoop( ticker := time.NewTicker(30 * time.Second) defer ticker.Stop() + pingTimeoutCount := 0 for { select { case <-ticker.C: @@ -307,11 +308,20 @@ func (s *SignalWebsocket) connectLoop( err := ws.Ping(pingCtx) cancel() if err != nil { + pingTimeoutCount++ log.Err(err).Msg("Error pinging") - loopCancel(err) - return + if pingTimeoutCount >= 5 { + log.Warn().Msg("Ping timeout count exceeded, closing websocket") + err = ws.Close(websocket.StatusNormalClosure, "Ping timeout") + if err != nil { + log.Err(err).Msg("Error closing websocket after ping timeout") + } + return + } + } else { + pingTimeoutCount = 0 + log.Trace().Msg("Sent keepalive") } - log.Trace().Msg("Sent keepalive") case <-loopCtx.Done(): return } From f986c8ec633f92823a2da1d963cd4c5b76515d98 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Fri, 10 Jan 2025 16:57:54 +0200 Subject: [PATCH 246/580] capabilities: update to new format --- go.mod | 4 +- go.sum | 8 +- pkg/connector/capabilities.go | 166 ++++++++++++++++++++++++++++++++++ pkg/connector/client.go | 50 ++++------ pkg/connector/connector.go | 9 -- pkg/msgconv/from-matrix.go | 2 +- 6 files changed, 189 insertions(+), 50 deletions(-) create mode 100644 pkg/connector/capabilities.go diff --git a/go.mod b/go.mod index 554048c..36be8a9 100644 --- a/go.mod +++ b/go.mod @@ -13,12 +13,12 @@ require ( github.com/rs/zerolog v1.33.0 github.com/stretchr/testify v1.10.0 github.com/tidwall/gjson v1.18.0 - go.mau.fi/util v0.8.4-0.20250106152331-30b8c95e7d7a + go.mau.fi/util v0.8.4-0.20250110124612-64d4dbbec957 golang.org/x/crypto v0.32.0 golang.org/x/exp v0.0.0-20250106191152-7588d65b2ba8 golang.org/x/net v0.34.0 google.golang.org/protobuf v1.36.2 - maunium.net/go/mautrix v0.22.2-0.20250107114437-ceb9c7b866e1 + maunium.net/go/mautrix v0.22.2-0.20250110145518-285106586976 ) require ( diff --git a/go.sum b/go.sum index 4d10fa9..4427ab3 100644 --- a/go.sum +++ b/go.sum @@ -67,8 +67,8 @@ github.com/tidwall/sjson v1.2.5 h1:kLy8mja+1c9jlljvWTlSazM7cKDRfJuR/bOJhcY5NcY= github.com/tidwall/sjson v1.2.5/go.mod h1:Fvgq9kS/6ociJEDnK0Fk1cpYF4FIW6ZF7LAe+6jwd28= github.com/yuin/goldmark v1.7.8 h1:iERMLn0/QJeHFhxSt3p6PeN9mGnvIKSpG9YYorDMnic= github.com/yuin/goldmark v1.7.8/go.mod h1:uzxRWxtg69N339t3louHJ7+O03ezfj6PlliRlaOzY1E= -go.mau.fi/util v0.8.4-0.20250106152331-30b8c95e7d7a h1:D9RCHBFjxah9F/YB7amvRJjT2IEOFWcz8jpcEY8dBV0= -go.mau.fi/util v0.8.4-0.20250106152331-30b8c95e7d7a/go.mod h1:MOfGTs1CBuK6ERTcSL4lb5YU7/ujz09eOPVEDckuazY= +go.mau.fi/util v0.8.4-0.20250110124612-64d4dbbec957 h1:tsLt3t6ARc55niz+JMgJy6U4sL210Z0K/nyxF09xT0E= +go.mau.fi/util v0.8.4-0.20250110124612-64d4dbbec957/go.mod h1:MOfGTs1CBuK6ERTcSL4lb5YU7/ujz09eOPVEDckuazY= go.mau.fi/zeroconfig v0.1.3 h1:As9wYDKmktjmNZW5i1vn8zvJlmGKHeVxHVIBMXsm4kM= go.mau.fi/zeroconfig v0.1.3/go.mod h1:NcSJkf180JT+1IId76PcMuLTNa1CzsFFZ0nBygIQM70= golang.org/x/crypto v0.32.0 h1:euUpcYgM8WcP71gNpTqQCn6rC2t6ULUPiOzfWaXVVfc= @@ -97,5 +97,5 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= maunium.net/go/mauflag v1.0.0 h1:YiaRc0tEI3toYtJMRIfjP+jklH45uDHtT80nUamyD4M= maunium.net/go/mauflag v1.0.0/go.mod h1:nLivPOpTpHnpzEh8jEdSL9UqO9+/KBJFmNRlwKfkPeA= -maunium.net/go/mautrix v0.22.2-0.20250107114437-ceb9c7b866e1 h1:ECwjKJLKKsTp/gnp0Qd5GojeZOK/MLVFF0Tf7C6gZDQ= -maunium.net/go/mautrix v0.22.2-0.20250107114437-ceb9c7b866e1/go.mod h1:FmwzK7RSzrd1OfGDgJzFWXl7nYmYm8/P0Y77sy/A1Uw= +maunium.net/go/mautrix v0.22.2-0.20250110145518-285106586976 h1:I06GGTFPiwWTMuLoZCtTg2y9Oc3Qi85MzvS+9fgyCtg= +maunium.net/go/mautrix v0.22.2-0.20250110145518-285106586976/go.mod h1:07i96D7BALyuAqxFhRzvaId8FC9NABgRQBPY5HWndf4= diff --git a/pkg/connector/capabilities.go b/pkg/connector/capabilities.go new file mode 100644 index 0000000..8a57f13 --- /dev/null +++ b/pkg/connector/capabilities.go @@ -0,0 +1,166 @@ +// mautrix-signal - A Matrix-Signal puppeting bridge. +// Copyright (C) 2025 Tulir Asokan +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +package connector + +import ( + "context" + "time" + + "go.mau.fi/util/ffmpeg" + "go.mau.fi/util/jsontime" + "go.mau.fi/util/ptr" + + "maunium.net/go/mautrix/bridgev2" + "maunium.net/go/mautrix/bridgev2/networkid" + "maunium.net/go/mautrix/event" +) + +func supportedIfFFmpeg() event.CapabilitySupportLevel { + if ffmpeg.Supported() { + return event.CapLevelPartialSupport + } + return event.CapLevelRejected +} + +func capID() string { + base := "fi.mau.signal.capabilities.2025_01_10" + if ffmpeg.Supported() { + return base + "+ffmpeg" + } + return base +} + +const MaxFileSize = 100 * 1024 * 1024 + +var signalCaps = &event.RoomFeatures{ + ID: capID(), + + Formatting: map[event.FormattingFeature]event.CapabilitySupportLevel{ + // Features that Signal supports natively + event.FmtBold: event.CapLevelFullySupported, + event.FmtItalic: event.CapLevelFullySupported, + event.FmtStrikethrough: event.CapLevelFullySupported, + event.FmtSpoiler: event.CapLevelFullySupported, + event.FmtInlineCode: event.CapLevelFullySupported, + event.FmtCodeBlock: event.CapLevelFullySupported, + event.FmtUserLink: event.CapLevelFullySupported, + + // Features that aren't supported on Signal, but are converted into a markdown-like representation + event.FmtBlockquote: event.CapLevelPartialSupport, + event.FmtInlineLink: event.CapLevelPartialSupport, + event.FmtUnorderedList: event.CapLevelPartialSupport, + event.FmtOrderedList: event.CapLevelPartialSupport, + event.FmtListStart: event.CapLevelPartialSupport, + event.FmtHeaders: event.CapLevelPartialSupport, + }, + File: map[event.CapabilityMsgType]*event.FileFeatures{ + event.MsgImage: { + MimeTypes: map[string]event.CapabilitySupportLevel{ + "image/gif": event.CapLevelFullySupported, + "image/png": event.CapLevelFullySupported, + "image/jpeg": event.CapLevelFullySupported, + }, + MaxWidth: 4096, + MaxHeight: 4096, + MaxSize: MaxFileSize, + }, + event.MsgVideo: { + MimeTypes: map[string]event.CapabilitySupportLevel{ + "video/mp4": event.CapLevelFullySupported, + "video/ogg": event.CapLevelFullySupported, + "video/webm": event.CapLevelFullySupported, + }, + MaxSize: MaxFileSize, + }, + event.MsgAudio: { + MimeTypes: map[string]event.CapabilitySupportLevel{ + "audio/aac": event.CapLevelFullySupported, + "audio/mpeg": event.CapLevelFullySupported, + }, + MaxSize: MaxFileSize, + }, + event.MsgFile: { + MimeTypes: map[string]event.CapabilitySupportLevel{ + "*/*": event.CapLevelFullySupported, + }, + MaxSize: MaxFileSize, + }, + event.CapMsgSticker: { + MimeTypes: map[string]event.CapabilitySupportLevel{ + "image/webp": event.CapLevelFullySupported, + "image/png": event.CapLevelFullySupported, + "image/apng": event.CapLevelFullySupported, + "image/gif": supportedIfFFmpeg(), + }, + Caption: event.CapLevelDropped, + MaxSize: MaxFileSize, + }, + event.CapMsgVoice: { + MimeTypes: map[string]event.CapabilitySupportLevel{ + "audio/aac": event.CapLevelFullySupported, + "audio/ogg": supportedIfFFmpeg(), + }, + Caption: event.CapLevelDropped, + MaxSize: MaxFileSize, + MaxDuration: ptr.Ptr(jsontime.S(1 * time.Hour)), + }, + }, + LocationMessage: event.CapLevelPartialSupport, + Poll: event.CapLevelRejected, + Thread: event.CapLevelUnsupported, + Reply: event.CapLevelFullySupported, + Edit: event.CapLevelFullySupported, + EditMaxCount: 10, + EditMaxAge: ptr.Ptr(jsontime.S(24 * time.Hour)), + Delete: event.CapLevelFullySupported, + DeleteForMe: false, + DeleteMaxAge: ptr.Ptr(jsontime.S(24 * time.Hour)), + Reaction: event.CapLevelFullySupported, + ReactionCount: 1, + AllowedReactions: nil, + CustomEmojiReactions: false, + ReadReceipts: true, + TypingNotifications: true, +} + +var signalCapsNoteToSelf *event.RoomFeatures + +func init() { + signalCapsNoteToSelf = ptr.Clone(signalCaps) + signalCapsNoteToSelf.EditMaxAge = nil + signalCapsNoteToSelf.ID = capID() + "+note_to_self" +} + +func (s *SignalClient) GetCapabilities(ctx context.Context, portal *bridgev2.Portal) *event.RoomFeatures { + if portal.Receiver == s.UserLogin.ID && portal.ID == networkid.PortalID(s.UserLogin.ID) { + return signalCapsNoteToSelf + } + return signalCaps +} + +var signalGeneralCaps = &bridgev2.NetworkGeneralCapabilities{ + DisappearingMessages: true, + AggressiveUpdateInfo: true, +} + +func (s *SignalConnector) GetCapabilities() *bridgev2.NetworkGeneralCapabilities { + return signalGeneralCaps +} + +func (s *SignalConnector) GetBridgeInfoVersion() (info, capabilities int) { + return 1, 1 +} diff --git a/pkg/connector/client.go b/pkg/connector/client.go index 8a8d415..3b0be20 100644 --- a/pkg/connector/client.go +++ b/pkg/connector/client.go @@ -1,3 +1,19 @@ +// mautrix-signal - A Matrix-Signal puppeting bridge. +// Copyright (C) 2024 Tulir Asokan +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + package connector import ( @@ -6,7 +22,6 @@ import ( "time" "github.com/rs/zerolog" - "go.mau.fi/util/ptr" "maunium.net/go/mautrix/bridge/status" "maunium.net/go/mautrix/bridgev2" "maunium.net/go/mautrix/bridgev2/networkid" @@ -22,39 +37,6 @@ type SignalClient struct { Ghost *bridgev2.Ghost } -var signalCaps = &bridgev2.NetworkRoomCapabilities{ - FormattedText: true, - UserMentions: true, - LocationMessages: true, - Captions: true, - Replies: true, - Edits: true, - EditMaxCount: 10, - EditMaxAge: 24 * time.Hour, - Deletes: true, - DeleteMaxAge: 24 * time.Hour, - DefaultFileRestriction: &bridgev2.FileRestriction{ - MaxSize: 100 * 1024 * 1024, - }, - ReadReceipts: true, - Reactions: true, - ReactionCount: 1, -} - -var signalCapsNoteToSelf *bridgev2.NetworkRoomCapabilities - -func init() { - signalCapsNoteToSelf = ptr.Clone(signalCaps) - signalCapsNoteToSelf.EditMaxAge = 0 -} - -func (s *SignalClient) GetCapabilities(ctx context.Context, portal *bridgev2.Portal) *bridgev2.NetworkRoomCapabilities { - if portal.Receiver == s.UserLogin.ID && portal.ID == networkid.PortalID(s.UserLogin.ID) { - return signalCapsNoteToSelf - } - return signalCaps -} - var ( _ bridgev2.NetworkAPI = (*SignalClient)(nil) _ bridgev2.EditHandlingNetworkAPI = (*SignalClient)(nil) diff --git a/pkg/connector/connector.go b/pkg/connector/connector.go index 1072983..f4fc7ae 100644 --- a/pkg/connector/connector.go +++ b/pkg/connector/connector.go @@ -40,15 +40,6 @@ type SignalConnector struct { var _ bridgev2.NetworkConnector = (*SignalConnector)(nil) var _ bridgev2.MaxFileSizeingNetwork = (*SignalConnector)(nil) -var signalGeneralCaps = &bridgev2.NetworkGeneralCapabilities{ - DisappearingMessages: true, - AggressiveUpdateInfo: true, -} - -func (s *SignalConnector) GetCapabilities() *bridgev2.NetworkGeneralCapabilities { - return signalGeneralCaps -} - func (s *SignalConnector) GetName() bridgev2.BridgeName { return bridgev2.BridgeName{ DisplayName: "Signal", diff --git a/pkg/msgconv/from-matrix.go b/pkg/msgconv/from-matrix.go index cb938e7..b91dcda 100644 --- a/pkg/msgconv/from-matrix.go +++ b/pkg/msgconv/from-matrix.go @@ -160,7 +160,7 @@ func (mc *MessageConverter) convertFileToSignal(ctx context.Context, evt *event. fileName = content.FileName } mime := content.GetInfo().MimeType - if content.MSC3245Voice != nil && ffmpeg.Supported() { + if content.MSC3245Voice != nil && mime != "audio/aac" && ffmpeg.Supported() { data, err = ffmpeg.ConvertBytes(ctx, data, ".aac", []string{}, []string{"-c:a", "aac"}, mime) if err != nil { return nil, err From d205154aeda533313de41c9a4a4414a0562549dd Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Fri, 10 Jan 2025 17:20:36 +0200 Subject: [PATCH 247/580] signalmeow/websocket: add log when ping stops failing --- pkg/signalmeow/web/signalwebsocket.go | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/pkg/signalmeow/web/signalwebsocket.go b/pkg/signalmeow/web/signalwebsocket.go index 4774b9f..4f817c8 100644 --- a/pkg/signalmeow/web/signalwebsocket.go +++ b/pkg/signalmeow/web/signalwebsocket.go @@ -309,7 +309,7 @@ func (s *SignalWebsocket) connectLoop( cancel() if err != nil { pingTimeoutCount++ - log.Err(err).Msg("Error pinging") + log.Err(err).Msg("Failed to send ping") if pingTimeoutCount >= 5 { log.Warn().Msg("Ping timeout count exceeded, closing websocket") err = ws.Close(websocket.StatusNormalClosure, "Ping timeout") @@ -318,8 +318,10 @@ func (s *SignalWebsocket) connectLoop( } return } - } else { + } else if pingTimeoutCount > 0 { pingTimeoutCount = 0 + log.Debug().Msg("Recovered from ping error") + } else { log.Trace().Msg("Sent keepalive") } case <-loopCtx.Done(): From 305d8499da188036f5e12e241bd015b0227cc9f3 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Fri, 10 Jan 2025 18:26:44 +0200 Subject: [PATCH 248/580] capabilities: add text length limit --- go.mod | 2 +- go.sum | 4 ++-- pkg/connector/capabilities.go | 22 +++++++++++++++------- 3 files changed, 18 insertions(+), 10 deletions(-) diff --git a/go.mod b/go.mod index 36be8a9..88432c1 100644 --- a/go.mod +++ b/go.mod @@ -18,7 +18,7 @@ require ( golang.org/x/exp v0.0.0-20250106191152-7588d65b2ba8 golang.org/x/net v0.34.0 google.golang.org/protobuf v1.36.2 - maunium.net/go/mautrix v0.22.2-0.20250110145518-285106586976 + maunium.net/go/mautrix v0.22.2-0.20250110154103-bbcb1904e268 ) require ( diff --git a/go.sum b/go.sum index 4427ab3..570b3f9 100644 --- a/go.sum +++ b/go.sum @@ -97,5 +97,5 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= maunium.net/go/mauflag v1.0.0 h1:YiaRc0tEI3toYtJMRIfjP+jklH45uDHtT80nUamyD4M= maunium.net/go/mauflag v1.0.0/go.mod h1:nLivPOpTpHnpzEh8jEdSL9UqO9+/KBJFmNRlwKfkPeA= -maunium.net/go/mautrix v0.22.2-0.20250110145518-285106586976 h1:I06GGTFPiwWTMuLoZCtTg2y9Oc3Qi85MzvS+9fgyCtg= -maunium.net/go/mautrix v0.22.2-0.20250110145518-285106586976/go.mod h1:07i96D7BALyuAqxFhRzvaId8FC9NABgRQBPY5HWndf4= +maunium.net/go/mautrix v0.22.2-0.20250110154103-bbcb1904e268 h1:p+3TofdhqiVYIkLjgzidayg2XriGUEbj+nbWs3/UQbk= +maunium.net/go/mautrix v0.22.2-0.20250110154103-bbcb1904e268/go.mod h1:07i96D7BALyuAqxFhRzvaId8FC9NABgRQBPY5HWndf4= diff --git a/pkg/connector/capabilities.go b/pkg/connector/capabilities.go index 8a57f13..9350180 100644 --- a/pkg/connector/capabilities.go +++ b/pkg/connector/capabilities.go @@ -37,7 +37,7 @@ func supportedIfFFmpeg() event.CapabilitySupportLevel { } func capID() string { - base := "fi.mau.signal.capabilities.2025_01_10" + base := "fi.mau.signal.capabilities.2025_01_10-2" if ffmpeg.Supported() { return base + "+ffmpeg" } @@ -45,6 +45,7 @@ func capID() string { } const MaxFileSize = 100 * 1024 * 1024 +const MaxTextLength = 2000 var signalCaps = &event.RoomFeatures{ ID: capID(), @@ -74,9 +75,11 @@ var signalCaps = &event.RoomFeatures{ "image/png": event.CapLevelFullySupported, "image/jpeg": event.CapLevelFullySupported, }, - MaxWidth: 4096, - MaxHeight: 4096, - MaxSize: MaxFileSize, + MaxWidth: 4096, + MaxHeight: 4096, + MaxSize: MaxFileSize, + Caption: event.CapLevelFullySupported, + MaxCaptionLength: MaxTextLength, }, event.MsgVideo: { MimeTypes: map[string]event.CapabilitySupportLevel{ @@ -84,7 +87,9 @@ var signalCaps = &event.RoomFeatures{ "video/ogg": event.CapLevelFullySupported, "video/webm": event.CapLevelFullySupported, }, - MaxSize: MaxFileSize, + MaxSize: MaxFileSize, + Caption: event.CapLevelFullySupported, + MaxCaptionLength: MaxTextLength, }, event.MsgAudio: { MimeTypes: map[string]event.CapabilitySupportLevel{ @@ -97,7 +102,9 @@ var signalCaps = &event.RoomFeatures{ MimeTypes: map[string]event.CapabilitySupportLevel{ "*/*": event.CapLevelFullySupported, }, - MaxSize: MaxFileSize, + MaxSize: MaxFileSize, + Caption: event.CapLevelFullySupported, + MaxCaptionLength: MaxTextLength, }, event.CapMsgSticker: { MimeTypes: map[string]event.CapabilitySupportLevel{ @@ -119,6 +126,7 @@ var signalCaps = &event.RoomFeatures{ MaxDuration: ptr.Ptr(jsontime.S(1 * time.Hour)), }, }, + MaxTextLength: MaxTextLength, // TODO support arbitrary sized text messages with files LocationMessage: event.CapLevelPartialSupport, Poll: event.CapLevelRejected, Thread: event.CapLevelUnsupported, @@ -162,5 +170,5 @@ func (s *SignalConnector) GetCapabilities() *bridgev2.NetworkGeneralCapabilities } func (s *SignalConnector) GetBridgeInfoVersion() (info, capabilities int) { - return 1, 1 + return 1, 2 } From e19843f3f381e8d11bb8e605be4e2ed56e5fd9ee Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Tue, 14 Jan 2025 14:09:43 +0200 Subject: [PATCH 249/580] msgconv: add support for mp4 gifs in both directions --- go.mod | 2 +- go.sum | 4 ++-- pkg/connector/capabilities.go | 10 +++++++++- pkg/msgconv/from-matrix.go | 3 +++ pkg/msgconv/from-signal.go | 20 ++++++++++++++++++++ 5 files changed, 35 insertions(+), 4 deletions(-) diff --git a/go.mod b/go.mod index 88432c1..ef61db9 100644 --- a/go.mod +++ b/go.mod @@ -18,7 +18,7 @@ require ( golang.org/x/exp v0.0.0-20250106191152-7588d65b2ba8 golang.org/x/net v0.34.0 google.golang.org/protobuf v1.36.2 - maunium.net/go/mautrix v0.22.2-0.20250110154103-bbcb1904e268 + maunium.net/go/mautrix v0.22.2-0.20250113200949-53a56684d3d3 ) require ( diff --git a/go.sum b/go.sum index 570b3f9..e9bd1dd 100644 --- a/go.sum +++ b/go.sum @@ -97,5 +97,5 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= maunium.net/go/mauflag v1.0.0 h1:YiaRc0tEI3toYtJMRIfjP+jklH45uDHtT80nUamyD4M= maunium.net/go/mauflag v1.0.0/go.mod h1:nLivPOpTpHnpzEh8jEdSL9UqO9+/KBJFmNRlwKfkPeA= -maunium.net/go/mautrix v0.22.2-0.20250110154103-bbcb1904e268 h1:p+3TofdhqiVYIkLjgzidayg2XriGUEbj+nbWs3/UQbk= -maunium.net/go/mautrix v0.22.2-0.20250110154103-bbcb1904e268/go.mod h1:07i96D7BALyuAqxFhRzvaId8FC9NABgRQBPY5HWndf4= +maunium.net/go/mautrix v0.22.2-0.20250113200949-53a56684d3d3 h1:ouuSo9unoAHaEze2hOo7z7lQG+rTjxhvXlXngExQwqg= +maunium.net/go/mautrix v0.22.2-0.20250113200949-53a56684d3d3/go.mod h1:07i96D7BALyuAqxFhRzvaId8FC9NABgRQBPY5HWndf4= diff --git a/pkg/connector/capabilities.go b/pkg/connector/capabilities.go index 9350180..986e46d 100644 --- a/pkg/connector/capabilities.go +++ b/pkg/connector/capabilities.go @@ -37,7 +37,7 @@ func supportedIfFFmpeg() event.CapabilitySupportLevel { } func capID() string { - base := "fi.mau.signal.capabilities.2025_01_10-2" + base := "fi.mau.signal.capabilities.2025_01_14" if ffmpeg.Supported() { return base + "+ffmpeg" } @@ -125,6 +125,14 @@ var signalCaps = &event.RoomFeatures{ MaxSize: MaxFileSize, MaxDuration: ptr.Ptr(jsontime.S(1 * time.Hour)), }, + event.CapMsgGIF: { + MimeTypes: map[string]event.CapabilitySupportLevel{ + "image/gif": event.CapLevelFullySupported, + "video/mp4": event.CapLevelFullySupported, + }, + Caption: event.CapLevelFullySupported, + MaxSize: MaxFileSize, + }, }, MaxTextLength: MaxTextLength, // TODO support arbitrary sized text messages with files LocationMessage: event.CapLevelPartialSupport, diff --git a/pkg/msgconv/from-matrix.go b/pkg/msgconv/from-matrix.go index b91dcda..8edf40f 100644 --- a/pkg/msgconv/from-matrix.go +++ b/pkg/msgconv/from-matrix.go @@ -193,6 +193,9 @@ func (mc *MessageConverter) convertFileToSignal(ctx context.Context, evt *event. if content.MSC3245Voice != nil && mime == "audio/aac" { att.Flags = proto.Uint32(uint32(signalpb.AttachmentPointer_VOICE_MESSAGE)) } + if content.Info.MauGIF { + att.Flags = proto.Uint32(uint32(compatFlagGIF)) + } att.ContentType = proto.String(mime) att.FileName = &fileName att.Height = maybeInt(uint32(content.Info.Height)) diff --git a/pkg/msgconv/from-signal.go b/pkg/msgconv/from-signal.go index 486bde1..a7ceb0d 100644 --- a/pkg/msgconv/from-signal.go +++ b/pkg/msgconv/from-signal.go @@ -70,6 +70,13 @@ func CanConvertSignal(dm *signalpb.DataMessage) bool { const ViewOnceDisappearTimer = 5 * time.Minute +// Why does signal have two different flags for gifs?? +// https://github.com/signalapp/Signal-Android/blob/v7.29.4/libsignal-service/src/main/protowire/SignalService.proto#L745 +// https://github.com/signalapp/Signal-Desktop/blob/v7.38.0-beta.1/protos/SignalService.proto#L740 +// https://github.com/signalapp/Signal-iOS/blob/7.42.0.545-beta/SignalServiceKit/protobuf/SignalService.proto#L756 +// Apparently the android one is a lie and doesn't work? +const compatFlagGIF = 8 + func (mc *MessageConverter) ToMatrix( ctx context.Context, client *signalmeow.Client, @@ -478,6 +485,18 @@ func (mc *MessageConverter) reuploadAttachment(ctx context.Context, att *signalp default: content.MsgType = event.MsgFile } + var extra map[string]any + if att.GetFlags()&uint32(compatFlagGIF) != 0 { + content.Info.MauGIF = true + extra = map[string]any{ + "info": map[string]any{ + "fi.mau.loop": true, + "fi.mau.autoplay": true, + "fi.mau.hide_controls": true, + "fi.mau.no_audio": true, + }, + } + } content.Body = fileName content.Info.MimeType = mimeType if content.Body == "" { @@ -486,5 +505,6 @@ func (mc *MessageConverter) reuploadAttachment(ctx context.Context, att *signalp return &bridgev2.ConvertedMessagePart{ Type: event.EventMessage, Content: content, + Extra: extra, }, nil } From 53ad7fa43f7a382788b9cd0753e993a84389d7ae Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Tue, 14 Jan 2025 14:13:46 +0200 Subject: [PATCH 250/580] signalmeow: update protobufs --- pkg/signalmeow/protobuf/StorageService.pb.go | 155 +++++++++++++++--- pkg/signalmeow/protobuf/StorageService.pb.raw | Bin 5964 -> 6238 bytes pkg/signalmeow/protobuf/StorageService.proto | 89 +++++----- pkg/signalmeow/protobuf/build-protos.sh | 1 + pkg/signalmeow/protobuf/update-protos.sh | 4 +- 5 files changed, 187 insertions(+), 62 deletions(-) diff --git a/pkg/signalmeow/protobuf/StorageService.pb.go b/pkg/signalmeow/protobuf/StorageService.pb.go index ee6fbef..a371ea9 100644 --- a/pkg/signalmeow/protobuf/StorageService.pb.go +++ b/pkg/signalmeow/protobuf/StorageService.pb.go @@ -1323,8 +1323,9 @@ type AccountRecord struct { Username string `protobuf:"bytes,33,opt,name=username,proto3" json:"username,omitempty"` HasCompletedUsernameOnboarding bool `protobuf:"varint,34,opt,name=hasCompletedUsernameOnboarding,proto3" json:"hasCompletedUsernameOnboarding,omitempty"` UsernameLink *AccountRecord_UsernameLink `protobuf:"bytes,35,opt,name=usernameLink,proto3" json:"usernameLink,omitempty"` - BackupsSubscriberId []byte `protobuf:"bytes,36,opt,name=backupsSubscriberId,proto3" json:"backupsSubscriberId,omitempty"` - BackupsSubscriberCurrencyCode string `protobuf:"bytes,37,opt,name=backupsSubscriberCurrencyCode,proto3" json:"backupsSubscriberCurrencyCode,omitempty"` + HasBackup *bool `protobuf:"varint,39,opt,name=hasBackup,proto3,oneof" json:"hasBackup,omitempty"` // Set to true after backups are enabled and one is uploaded. + BackupTier *uint64 `protobuf:"varint,40,opt,name=backupTier,proto3,oneof" json:"backupTier,omitempty"` // See zkgroup for integer particular values + BackupSubscriberData *AccountRecord_IAPSubscriberData `protobuf:"bytes,41,opt,name=backupSubscriberData,proto3" json:"backupSubscriberData,omitempty"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } @@ -1583,18 +1584,25 @@ func (x *AccountRecord) GetUsernameLink() *AccountRecord_UsernameLink { return nil } -func (x *AccountRecord) GetBackupsSubscriberId() []byte { - if x != nil { - return x.BackupsSubscriberId +func (x *AccountRecord) GetHasBackup() bool { + if x != nil && x.HasBackup != nil { + return *x.HasBackup } - return nil + return false } -func (x *AccountRecord) GetBackupsSubscriberCurrencyCode() string { - if x != nil { - return x.BackupsSubscriberCurrencyCode +func (x *AccountRecord) GetBackupTier() uint64 { + if x != nil && x.BackupTier != nil { + return *x.BackupTier } - return "" + return 0 +} + +func (x *AccountRecord) GetBackupSubscriberData() *AccountRecord_IAPSubscriberData { + if x != nil { + return x.BackupSubscriberData + } + return nil } type StoryDistributionListRecord struct { @@ -2005,6 +2013,100 @@ func (x *AccountRecord_UsernameLink) GetColor() AccountRecord_UsernameLink_Color return AccountRecord_UsernameLink_UNKNOWN } +type AccountRecord_IAPSubscriberData struct { + state protoimpl.MessageState `protogen:"open.v1"` + SubscriberId []byte `protobuf:"bytes,1,opt,name=subscriberId,proto3" json:"subscriberId,omitempty"` + // Types that are valid to be assigned to IapSubscriptionId: + // + // *AccountRecord_IAPSubscriberData_PurchaseToken + // *AccountRecord_IAPSubscriberData_OriginalTransactionId + IapSubscriptionId isAccountRecord_IAPSubscriberData_IapSubscriptionId `protobuf_oneof:"iapSubscriptionId"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *AccountRecord_IAPSubscriberData) Reset() { + *x = AccountRecord_IAPSubscriberData{} + mi := &file_StorageService_proto_msgTypes[18] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *AccountRecord_IAPSubscriberData) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*AccountRecord_IAPSubscriberData) ProtoMessage() {} + +func (x *AccountRecord_IAPSubscriberData) ProtoReflect() protoreflect.Message { + mi := &file_StorageService_proto_msgTypes[18] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use AccountRecord_IAPSubscriberData.ProtoReflect.Descriptor instead. +func (*AccountRecord_IAPSubscriberData) Descriptor() ([]byte, []int) { + return file_StorageService_proto_rawDescGZIP(), []int{11, 2} +} + +func (x *AccountRecord_IAPSubscriberData) GetSubscriberId() []byte { + if x != nil { + return x.SubscriberId + } + return nil +} + +func (x *AccountRecord_IAPSubscriberData) GetIapSubscriptionId() isAccountRecord_IAPSubscriberData_IapSubscriptionId { + if x != nil { + return x.IapSubscriptionId + } + return nil +} + +func (x *AccountRecord_IAPSubscriberData) GetPurchaseToken() string { + if x != nil { + if x, ok := x.IapSubscriptionId.(*AccountRecord_IAPSubscriberData_PurchaseToken); ok { + return x.PurchaseToken + } + } + return "" +} + +func (x *AccountRecord_IAPSubscriberData) GetOriginalTransactionId() uint64 { + if x != nil { + if x, ok := x.IapSubscriptionId.(*AccountRecord_IAPSubscriberData_OriginalTransactionId); ok { + return x.OriginalTransactionId + } + } + return 0 +} + +type isAccountRecord_IAPSubscriberData_IapSubscriptionId interface { + isAccountRecord_IAPSubscriberData_IapSubscriptionId() +} + +type AccountRecord_IAPSubscriberData_PurchaseToken struct { + // Identifies an Android Play Store IAP subscription. + PurchaseToken string `protobuf:"bytes,2,opt,name=purchaseToken,proto3,oneof"` +} + +type AccountRecord_IAPSubscriberData_OriginalTransactionId struct { + // Identifies an iOS App Store IAP subscription. + OriginalTransactionId uint64 `protobuf:"varint,3,opt,name=originalTransactionId,proto3,oneof"` +} + +func (*AccountRecord_IAPSubscriberData_PurchaseToken) isAccountRecord_IAPSubscriberData_IapSubscriptionId() { +} + +func (*AccountRecord_IAPSubscriberData_OriginalTransactionId) isAccountRecord_IAPSubscriberData_IapSubscriptionId() { +} + type AccountRecord_PinnedConversation_Contact struct { state protoimpl.MessageState `protogen:"open.v1"` ServiceId string `protobuf:"bytes,1,opt,name=serviceId,proto3" json:"serviceId,omitempty"` @@ -2015,7 +2117,7 @@ type AccountRecord_PinnedConversation_Contact struct { func (x *AccountRecord_PinnedConversation_Contact) Reset() { *x = AccountRecord_PinnedConversation_Contact{} - mi := &file_StorageService_proto_msgTypes[18] + mi := &file_StorageService_proto_msgTypes[19] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2027,7 +2129,7 @@ func (x *AccountRecord_PinnedConversation_Contact) String() string { func (*AccountRecord_PinnedConversation_Contact) ProtoMessage() {} func (x *AccountRecord_PinnedConversation_Contact) ProtoReflect() protoreflect.Message { - mi := &file_StorageService_proto_msgTypes[18] + mi := &file_StorageService_proto_msgTypes[19] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2075,7 +2177,7 @@ func file_StorageService_proto_rawDescGZIP() []byte { } var file_StorageService_proto_enumTypes = make([]protoimpl.EnumInfo, 6) -var file_StorageService_proto_msgTypes = make([]protoimpl.MessageInfo, 19) +var file_StorageService_proto_msgTypes = make([]protoimpl.MessageInfo, 20) var file_StorageService_proto_goTypes = []any{ (OptionalBool)(0), // 0: signalservice.OptionalBool (ManifestRecord_Identifier_Type)(0), // 1: signalservice.ManifestRecord.Identifier.Type @@ -2101,7 +2203,8 @@ var file_StorageService_proto_goTypes = []any{ (*ContactRecord_Name)(nil), // 21: signalservice.ContactRecord.Name (*AccountRecord_PinnedConversation)(nil), // 22: signalservice.AccountRecord.PinnedConversation (*AccountRecord_UsernameLink)(nil), // 23: signalservice.AccountRecord.UsernameLink - (*AccountRecord_PinnedConversation_Contact)(nil), // 24: signalservice.AccountRecord.PinnedConversation.Contact + (*AccountRecord_IAPSubscriberData)(nil), // 24: signalservice.AccountRecord.IAPSubscriberData + (*AccountRecord_PinnedConversation_Contact)(nil), // 25: signalservice.AccountRecord.PinnedConversation.Contact } var file_StorageService_proto_depIdxs = []int32{ 7, // 0: signalservice.StorageItems.items:type_name -> signalservice.StorageItem @@ -2122,14 +2225,15 @@ var file_StorageService_proto_depIdxs = []int32{ 16, // 15: signalservice.AccountRecord.payments:type_name -> signalservice.Payments 0, // 16: signalservice.AccountRecord.storyViewReceiptsEnabled:type_name -> signalservice.OptionalBool 23, // 17: signalservice.AccountRecord.usernameLink:type_name -> signalservice.AccountRecord.UsernameLink - 1, // 18: signalservice.ManifestRecord.Identifier.type:type_name -> signalservice.ManifestRecord.Identifier.Type - 24, // 19: signalservice.AccountRecord.PinnedConversation.contact:type_name -> signalservice.AccountRecord.PinnedConversation.Contact - 5, // 20: signalservice.AccountRecord.UsernameLink.color:type_name -> signalservice.AccountRecord.UsernameLink.Color - 21, // [21:21] is the sub-list for method output_type - 21, // [21:21] is the sub-list for method input_type - 21, // [21:21] is the sub-list for extension type_name - 21, // [21:21] is the sub-list for extension extendee - 0, // [0:21] is the sub-list for field type_name + 24, // 18: signalservice.AccountRecord.backupSubscriberData:type_name -> signalservice.AccountRecord.IAPSubscriberData + 1, // 19: signalservice.ManifestRecord.Identifier.type:type_name -> signalservice.ManifestRecord.Identifier.Type + 25, // 20: signalservice.AccountRecord.PinnedConversation.contact:type_name -> signalservice.AccountRecord.PinnedConversation.Contact + 5, // 21: signalservice.AccountRecord.UsernameLink.color:type_name -> signalservice.AccountRecord.UsernameLink.Color + 22, // [22:22] is the sub-list for method output_type + 22, // [22:22] is the sub-list for method input_type + 22, // [22:22] is the sub-list for extension type_name + 22, // [22:22] is the sub-list for extension extendee + 0, // [0:22] is the sub-list for field type_name } func init() { file_StorageService_proto_init() } @@ -2145,18 +2249,23 @@ func file_StorageService_proto_init() { (*StorageRecord_StoryDistributionList)(nil), (*StorageRecord_CallLink)(nil), } + file_StorageService_proto_msgTypes[11].OneofWrappers = []any{} file_StorageService_proto_msgTypes[16].OneofWrappers = []any{ (*AccountRecord_PinnedConversation_Contact_)(nil), (*AccountRecord_PinnedConversation_LegacyGroupId)(nil), (*AccountRecord_PinnedConversation_GroupMasterKey)(nil), } + file_StorageService_proto_msgTypes[18].OneofWrappers = []any{ + (*AccountRecord_IAPSubscriberData_PurchaseToken)(nil), + (*AccountRecord_IAPSubscriberData_OriginalTransactionId)(nil), + } type x struct{} out := protoimpl.TypeBuilder{ File: protoimpl.DescBuilder{ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_StorageService_proto_rawDesc, NumEnums: 6, - NumMessages: 19, + NumMessages: 20, NumExtensions: 0, NumServices: 0, }, diff --git a/pkg/signalmeow/protobuf/StorageService.pb.raw b/pkg/signalmeow/protobuf/StorageService.pb.raw index 8f93e74982fe1059f03f61ad98f60995b00294e5..9c6689d9adaa8592bc569b23dfe69630c4881315 100644 GIT binary patch delta 428 zcmX@3ch6wMPHv_pqMLVfA7)Ee26QCyb zQUKAUx6=sUn~X SBvl2}fTWs$`et9z|BL_xoq!Ag delta 143 zcmca-a7J&#PHv`2!kc$ Date: Wed, 15 Jan 2025 23:40:50 +0200 Subject: [PATCH 251/580] signalmeow: update websocket auth --- pkg/signalmeow/client.go | 9 ++------- pkg/signalmeow/contactdiscovery.go | 2 +- pkg/signalmeow/provisioning.go | 12 ++++++++++-- pkg/signalmeow/web/signalwebsocket.go | 28 ++++++++++++--------------- 4 files changed, 25 insertions(+), 26 deletions(-) diff --git a/pkg/signalmeow/client.go b/pkg/signalmeow/client.go index fcb463a..8f44db0 100644 --- a/pkg/signalmeow/client.go +++ b/pkg/signalmeow/client.go @@ -84,12 +84,7 @@ func (cli *Client) ConnectAuthedWS(ctx context.Context, requestHandler web.Reque Str("username", username). Logger() ctx = log.WithContext(ctx) - username = url.QueryEscape(username) - password = url.QueryEscape(password) - path := web.WebsocketPath + - "?login=" + username + - "&password=" + password - authedWS := web.NewSignalWebsocket(path, &username, &password) + authedWS := web.NewSignalWebsocket(url.UserPassword(username, password)) statusChan := authedWS.Connect(ctx, &requestHandler) cli.AuthedWS = authedWS return statusChan, nil @@ -104,7 +99,7 @@ func (cli *Client) ConnectUnauthedWS(ctx context.Context) (chan web.SignalWebsoc Str("websocket_type", "unauthed"). Logger() ctx = log.WithContext(ctx) - unauthedWS := web.NewSignalWebsocket(web.WebsocketPath, nil, nil) + unauthedWS := web.NewSignalWebsocket(nil) statusChan := unauthedWS.Connect(ctx, nil) cli.UnauthedWS = unauthedWS return statusChan, nil diff --git a/pkg/signalmeow/contactdiscovery.go b/pkg/signalmeow/contactdiscovery.go index b732339..33b0ad3 100644 --- a/pkg/signalmeow/contactdiscovery.go +++ b/pkg/signalmeow/contactdiscovery.go @@ -111,7 +111,7 @@ func (cli *Client) doContactDiscovery(ctx context.Context, req *signalpb.CDSClie Path: path.Join("v1", ProdContactDiscoveryMrenclave, "discovery"), }).String() log.Trace().Msg("Connecting to contact discovery websocket") - ws, _, err := web.OpenWebsocketURL(ctx, addr) + ws, _, err := web.OpenWebsocket(ctx, addr) if err != nil { var closeErr websocket.CloseError if errors.As(err, &closeErr) && closeErr.Code == rateLimitCloseCode { diff --git a/pkg/signalmeow/provisioning.go b/pkg/signalmeow/provisioning.go index 507f5d9..4aedc44 100644 --- a/pkg/signalmeow/provisioning.go +++ b/pkg/signalmeow/provisioning.go @@ -87,7 +87,11 @@ func PerformProvisioning(ctx context.Context, deviceStore store.DeviceStore, dev timeoutCtx, cancel := context.WithTimeout(ctx, 2*time.Minute) defer cancel() - ws, resp, err := web.OpenWebsocket(timeoutCtx, web.WebsocketProvisioningPath) + ws, resp, err := web.OpenWebsocket(timeoutCtx, (&url.URL{ + Scheme: "wss", + Host: web.APIHostname, + Path: web.WebsocketProvisioningPath, + }).String()) if err != nil { log.Err(err).Any("resp", resp).Msg("error opening provisioning websocket") c <- ProvisioningResponse{State: StateProvisioningError, Err: err} @@ -388,7 +392,11 @@ func confirmDevice( return nil, fmt.Errorf("failed to encrypt device name: %w", err) } - ws, resp, err := web.OpenWebsocket(ctx, web.WebsocketPath) + ws, resp, err := web.OpenWebsocket(ctx, (&url.URL{ + Scheme: "wss", + Host: web.APIHostname, + Path: web.WebsocketPath, + }).String()) if err != nil { log.Err(err).Any("resp", resp).Msg("error opening websocket") return nil, err diff --git a/pkg/signalmeow/web/signalwebsocket.go b/pkg/signalmeow/web/signalwebsocket.go index 4f817c8..c273c31 100644 --- a/pkg/signalmeow/web/signalwebsocket.go +++ b/pkg/signalmeow/web/signalwebsocket.go @@ -22,6 +22,7 @@ import ( "errors" "fmt" "net/http" + "net/url" "strings" "sync" "time" @@ -43,20 +44,13 @@ type RequestHandlerFunc func(context.Context, *signalpb.WebSocketRequestMessage) type SignalWebsocket struct { ws *websocket.Conn - path string - basicAuth *string + basicAuth *url.Userinfo sendChannel chan SignalWebsocketSendMessage statusChannel chan SignalWebsocketConnectionStatus } -func NewSignalWebsocket(path string, username *string, password *string) *SignalWebsocket { - var basicAuth *string - if username != nil && password != nil { - b := base64.StdEncoding.EncodeToString([]byte(*username + ":" + *password)) - basicAuth = &b - } +func NewSignalWebsocket(basicAuth *url.Userinfo) *SignalWebsocket { return &SignalWebsocket{ - path: path, basicAuth: basicAuth, sendChannel: make(chan SignalWebsocketSendMessage), statusChannel: make(chan SignalWebsocketConnectionStatus), @@ -187,6 +181,12 @@ func (s *SignalWebsocket) connectLoop( retrying := false errorCount := 0 isFirstConnect := true + wsURL := (&url.URL{ + Scheme: "wss", + Host: APIHostname, + Path: WebsocketPath, + User: s.basicAuth, + }).String() for { if retrying { if backoff > maxBackoff { @@ -204,7 +204,7 @@ func (s *SignalWebsocket) connectLoop( } isFirstConnect = false - ws, resp, err := OpenWebsocket(ctx, s.path) + ws, resp, err := OpenWebsocket(ctx, wsURL) if resp != nil { if resp.StatusCode != 101 { // Server didn't want to open websocket @@ -555,7 +555,7 @@ func (s *SignalWebsocket) sendRequestInternal( retryCount int, ) (*signalpb.WebSocketResponseMessage, error) { if s.basicAuth != nil { - request.Headers = append(request.Headers, "authorization:Basic "+*s.basicAuth) + request.Headers = append(request.Headers, "authorization:Basic "+s.basicAuth.String()) } responseChannel := make(chan *signalpb.WebSocketResponseMessage, 1) if s.sendChannel == nil { @@ -590,11 +590,7 @@ func (s *SignalWebsocket) sendRequestInternal( return response, nil } -func OpenWebsocket(ctx context.Context, path string) (*websocket.Conn, *http.Response, error) { - return OpenWebsocketURL(ctx, "wss://"+APIHostname+path) -} - -func OpenWebsocketURL(ctx context.Context, url string) (*websocket.Conn, *http.Response, error) { +func OpenWebsocket(ctx context.Context, url string) (*websocket.Conn, *http.Response, error) { opt := &websocket.DialOptions{ HTTPClient: SignalHTTPClient, HTTPHeader: make(http.Header, 2), From 0083384814c820afe3bd7ddc6a593fece9265b30 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Thu, 16 Jan 2025 14:40:30 +0200 Subject: [PATCH 252/580] Bump version to v0.7.5 --- CHANGELOG.md | 8 ++++++++ cmd/mautrix-signal/main.go | 2 +- go.mod | 12 ++++++------ go.sum | 21 ++++++++++++--------- pkg/connector/capabilities.go | 4 +++- 5 files changed, 30 insertions(+), 17 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7c2ef6c..da0850e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,11 @@ +# v0.7.5 (2025-01-16) + +* Added support for bridging mp4 gifs in both directions. +* Added support for signaling supported features to clients using the + `com.beeper.room_features` state event. +* Updated Signal websocket authentication method. +* Fixed some cases where websocket would get stuck after a ping timeout. + # v0.7.4 (2024-12-16) * Fixed syncing server-side storage after Signal login. diff --git a/cmd/mautrix-signal/main.go b/cmd/mautrix-signal/main.go index 61d22dd..1cd74ce 100644 --- a/cmd/mautrix-signal/main.go +++ b/cmd/mautrix-signal/main.go @@ -38,7 +38,7 @@ var m = mxmain.BridgeMain{ Name: "mautrix-signal", URL: "https://github.com/mautrix/signal", Description: "A Matrix-Signal puppeting bridge.", - Version: "0.7.4", + Version: "0.7.5", Connector: &connector.SignalConnector{}, } diff --git a/go.mod b/go.mod index ef61db9..f4eaf6a 100644 --- a/go.mod +++ b/go.mod @@ -13,12 +13,12 @@ require ( github.com/rs/zerolog v1.33.0 github.com/stretchr/testify v1.10.0 github.com/tidwall/gjson v1.18.0 - go.mau.fi/util v0.8.4-0.20250110124612-64d4dbbec957 + go.mau.fi/util v0.8.4 golang.org/x/crypto v0.32.0 golang.org/x/exp v0.0.0-20250106191152-7588d65b2ba8 golang.org/x/net v0.34.0 - google.golang.org/protobuf v1.36.2 - maunium.net/go/mautrix v0.22.2-0.20250113200949-53a56684d3d3 + google.golang.org/protobuf v1.36.3 + maunium.net/go/mautrix v0.23.0 ) require ( @@ -28,8 +28,8 @@ require ( github.com/gorilla/websocket v1.5.0 // indirect github.com/kr/pretty v0.3.1 // indirect github.com/lib/pq v1.10.9 // indirect - github.com/mattn/go-colorable v0.1.13 // indirect - github.com/mattn/go-isatty v0.0.19 // indirect + github.com/mattn/go-colorable v0.1.14 // indirect + github.com/mattn/go-isatty v0.0.20 // indirect github.com/mattn/go-sqlite3 v1.14.24 // indirect github.com/petermattis/goid v0.0.0-20241211131331-93ee7e083c43 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect @@ -37,7 +37,7 @@ require ( github.com/rs/xid v1.6.0 // indirect github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e // indirect github.com/tidwall/match v1.1.1 // indirect - github.com/tidwall/pretty v1.2.0 // indirect + github.com/tidwall/pretty v1.2.1 // indirect github.com/tidwall/sjson v1.2.5 // indirect github.com/yuin/goldmark v1.7.8 // indirect go.mau.fi/zeroconfig v0.1.3 // indirect diff --git a/go.sum b/go.sum index e9bd1dd..1ee4934 100644 --- a/go.sum +++ b/go.sum @@ -29,11 +29,13 @@ github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw= github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= -github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= +github.com/mattn/go-colorable v0.1.14 h1:9A9LHSqF/7dyVVX6g0U9cwm9pG3kP9gSzcuIPHPsaIE= +github.com/mattn/go-colorable v0.1.14/go.mod h1:6LmQG8QLFO4G5z1gPvYEzlUgJ2wF+stgPZH1UqBm1s8= github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= -github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA= github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= +github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= +github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mattn/go-pointer v0.0.1 h1:n+XhsuGeVO6MEAp7xyEukFINEa+Quek5psIR/ylA6o0= github.com/mattn/go-pointer v0.0.1/go.mod h1:2zXcozF6qYGgmsG+SeTZz3oAbFLdD3OWqnUbNvJZAlc= github.com/mattn/go-sqlite3 v1.14.24 h1:tpSp2G2KyMnnQu99ngJ47EIkWVmliIizyZBfPrBWDRM= @@ -61,14 +63,15 @@ github.com/tidwall/gjson v1.18.0 h1:FIDeeyB800efLX89e5a8Y0BNH+LOngJyGrIWxG2FKQY= github.com/tidwall/gjson v1.18.0/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA= github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM= -github.com/tidwall/pretty v1.2.0 h1:RWIZEg2iJ8/g6fDDYzMpobmaoGh5OLl4AXtGUGPcqCs= github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU= +github.com/tidwall/pretty v1.2.1 h1:qjsOFOWWQl+N3RsoF5/ssm1pHmJJwhjlSbZ51I6wMl4= +github.com/tidwall/pretty v1.2.1/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU= github.com/tidwall/sjson v1.2.5 h1:kLy8mja+1c9jlljvWTlSazM7cKDRfJuR/bOJhcY5NcY= github.com/tidwall/sjson v1.2.5/go.mod h1:Fvgq9kS/6ociJEDnK0Fk1cpYF4FIW6ZF7LAe+6jwd28= github.com/yuin/goldmark v1.7.8 h1:iERMLn0/QJeHFhxSt3p6PeN9mGnvIKSpG9YYorDMnic= github.com/yuin/goldmark v1.7.8/go.mod h1:uzxRWxtg69N339t3louHJ7+O03ezfj6PlliRlaOzY1E= -go.mau.fi/util v0.8.4-0.20250110124612-64d4dbbec957 h1:tsLt3t6ARc55niz+JMgJy6U4sL210Z0K/nyxF09xT0E= -go.mau.fi/util v0.8.4-0.20250110124612-64d4dbbec957/go.mod h1:MOfGTs1CBuK6ERTcSL4lb5YU7/ujz09eOPVEDckuazY= +go.mau.fi/util v0.8.4 h1:mVKlJcXWfVo8ZW3f4vqtjGpqtZqJvX4ETekxawt2vnQ= +go.mau.fi/util v0.8.4/go.mod h1:MOfGTs1CBuK6ERTcSL4lb5YU7/ujz09eOPVEDckuazY= go.mau.fi/zeroconfig v0.1.3 h1:As9wYDKmktjmNZW5i1vn8zvJlmGKHeVxHVIBMXsm4kM= go.mau.fi/zeroconfig v0.1.3/go.mod h1:NcSJkf180JT+1IId76PcMuLTNa1CzsFFZ0nBygIQM70= golang.org/x/crypto v0.32.0 h1:euUpcYgM8WcP71gNpTqQCn6rC2t6ULUPiOzfWaXVVfc= @@ -86,8 +89,8 @@ golang.org/x/sys v0.29.0 h1:TPYlXGxvx1MGTn2GiZDhnjPA9wZzZeGKHHmKhHYvgaU= golang.org/x/sys v0.29.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo= golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= -google.golang.org/protobuf v1.36.2 h1:R8FeyR1/eLmkutZOM5CWghmo5itiG9z0ktFlTVLuTmU= -google.golang.org/protobuf v1.36.2/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= +google.golang.org/protobuf v1.36.3 h1:82DV7MYdb8anAVi3qge1wSnMDrnKK7ebr+I0hHRN1BU= +google.golang.org/protobuf v1.36.3/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= @@ -97,5 +100,5 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= maunium.net/go/mauflag v1.0.0 h1:YiaRc0tEI3toYtJMRIfjP+jklH45uDHtT80nUamyD4M= maunium.net/go/mauflag v1.0.0/go.mod h1:nLivPOpTpHnpzEh8jEdSL9UqO9+/KBJFmNRlwKfkPeA= -maunium.net/go/mautrix v0.22.2-0.20250113200949-53a56684d3d3 h1:ouuSo9unoAHaEze2hOo7z7lQG+rTjxhvXlXngExQwqg= -maunium.net/go/mautrix v0.22.2-0.20250113200949-53a56684d3d3/go.mod h1:07i96D7BALyuAqxFhRzvaId8FC9NABgRQBPY5HWndf4= +maunium.net/go/mautrix v0.23.0 h1:HNlR19eew5lvrNSL2muhExaGhYdaGk5FfEiA82QqUP4= +maunium.net/go/mautrix v0.23.0/go.mod h1:AGnnaz3ylGikUo1I1MJVn9QLsl2No1/ZNnGDyO0QD5s= diff --git a/pkg/connector/capabilities.go b/pkg/connector/capabilities.go index 986e46d..1be2d45 100644 --- a/pkg/connector/capabilities.go +++ b/pkg/connector/capabilities.go @@ -37,7 +37,7 @@ func supportedIfFFmpeg() event.CapabilitySupportLevel { } func capID() string { - base := "fi.mau.signal.capabilities.2025_01_14" + base := "fi.mau.signal.capabilities.2025_01_16" if ffmpeg.Supported() { return base + "+ffmpeg" } @@ -74,6 +74,8 @@ var signalCaps = &event.RoomFeatures{ "image/gif": event.CapLevelFullySupported, "image/png": event.CapLevelFullySupported, "image/jpeg": event.CapLevelFullySupported, + "image/webp": event.CapLevelFullySupported, + "image/bmp": event.CapLevelFullySupported, }, MaxWidth: 4096, MaxHeight: 4096, From aca0ee20e8793810b8ccce8a65819e306881c2b2 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Thu, 16 Jan 2025 16:29:51 +0200 Subject: [PATCH 253/580] client: add support for connect-once background resync interface --- pkg/connector/client.go | 42 ++++++++++++++++++++++++++++++++ pkg/connector/connector.go | 3 +++ pkg/connector/handlesignal.go | 4 +++ pkg/signalmeow/client.go | 4 +-- pkg/signalmeow/events/message.go | 3 +++ pkg/signalmeow/receiving.go | 17 +++++++++++-- 6 files changed, 69 insertions(+), 4 deletions(-) diff --git a/pkg/connector/client.go b/pkg/connector/client.go index 3b0be20..2f2925c 100644 --- a/pkg/connector/client.go +++ b/pkg/connector/client.go @@ -22,12 +22,14 @@ import ( "time" "github.com/rs/zerolog" + "go.mau.fi/util/exsync" "maunium.net/go/mautrix/bridge/status" "maunium.net/go/mautrix/bridgev2" "maunium.net/go/mautrix/bridgev2/networkid" "go.mau.fi/mautrix-signal/pkg/signalid" "go.mau.fi/mautrix-signal/pkg/signalmeow" + "go.mau.fi/mautrix-signal/pkg/signalmeow/web" ) type SignalClient struct { @@ -35,6 +37,8 @@ type SignalClient struct { UserLogin *bridgev2.UserLogin Client *signalmeow.Client Ghost *bridgev2.Ghost + + queueEmptyWaiter *exsync.Event } var ( @@ -51,6 +55,7 @@ var ( _ bridgev2.RoomNameHandlingNetworkAPI = (*SignalClient)(nil) _ bridgev2.RoomAvatarHandlingNetworkAPI = (*SignalClient)(nil) _ bridgev2.RoomTopicHandlingNetworkAPI = (*SignalClient)(nil) + _ bridgev2.BackgroundSyncingNetworkAPI = (*SignalClient)(nil) ) var pushCfg = &bridgev2.PushConfig{ @@ -210,6 +215,43 @@ func (s *SignalClient) Connect(ctx context.Context) { s.tryConnect(ctx, 0) } +func (s *SignalClient) ConnectBackground(ctx context.Context) error { + s.queueEmptyWaiter.Clear() + ch, err := s.Client.StartAuthedWS(ctx) + if err != nil { + return err + } + defer s.Disconnect() + log := zerolog.Ctx(ctx) + queueEmpty := s.queueEmptyWaiter.GetChan() + for { + select { + case status := <-ch: + switch status.Event { + case web.SignalWebsocketConnectionEventConnected: + log.Info().Msg("Authed websocket connected") + case web.SignalWebsocketConnectionEventDisconnected: + log.Err(status.Err).Msg("Authed websocket disconnected") + return fmt.Errorf("authed websocket disconnected: %w", status.Err) + case web.SignalWebsocketConnectionEventLoggedOut: + log.Err(status.Err).Msg("Authed websocket logged out") + return fmt.Errorf("authed websocket logged out: %w", status.Err) + case web.SignalWebsocketConnectionEventError: + log.Err(status.Err).Msg("Authed websocket error") + return fmt.Errorf("authed websocket errored: %w", status.Err) + case web.SignalWebsocketConnectionEventCleanShutdown: + log.Info().Msg("Authed websocket clean shutdown") + } + case <-ctx.Done(): + log.Warn().Msg("Context finished before queue empty event") + return ctx.Err() + case <-queueEmpty: + log.Info().Msg("Received queue empty event") + return nil + } + } +} + func (s *SignalClient) Disconnect() { if s.Client == nil { return diff --git a/pkg/connector/connector.go b/pkg/connector/connector.go index f4fc7ae..229d4ea 100644 --- a/pkg/connector/connector.go +++ b/pkg/connector/connector.go @@ -23,6 +23,7 @@ import ( "github.com/google/uuid" "go.mau.fi/util/dbutil" + "go.mau.fi/util/exsync" "maunium.net/go/mautrix/bridgev2" "go.mau.fi/mautrix-signal/pkg/msgconv" @@ -89,6 +90,8 @@ func (s *SignalConnector) LoadUserLogin(ctx context.Context, login *bridgev2.Use sc := &SignalClient{ Main: s, UserLogin: login, + + queueEmptyWaiter: exsync.NewEvent(), } if device != nil { sc.Client = &signalmeow.Client{ diff --git a/pkg/connector/handlesignal.go b/pkg/connector/handlesignal.go index 1984862..d39f250 100644 --- a/pkg/connector/handlesignal.go +++ b/pkg/connector/handlesignal.go @@ -52,6 +52,10 @@ func (s *SignalClient) handleSignalEvent(rawEvt events.SignalEvent) { s.handleSignalContactList(evt) case *events.ACIFound: s.handleSignalACIFound(evt) + case *events.QueueEmpty: + s.queueEmptyWaiter.Set() + default: + s.UserLogin.Log.Warn().Type("event_type", evt).Msg("Unrecognized signalmeow event type") } } diff --git a/pkg/signalmeow/client.go b/pkg/signalmeow/client.go index 8f44db0..7ef1abb 100644 --- a/pkg/signalmeow/client.go +++ b/pkg/signalmeow/client.go @@ -73,7 +73,7 @@ func (cli *Client) IsConnected() bool { return cli.AuthedWS.IsConnected() && cli.UnauthedWS.IsConnected() } -func (cli *Client) ConnectAuthedWS(ctx context.Context, requestHandler web.RequestHandlerFunc) (chan web.SignalWebsocketConnectionStatus, error) { +func (cli *Client) connectAuthedWS(ctx context.Context, requestHandler web.RequestHandlerFunc) (chan web.SignalWebsocketConnectionStatus, error) { if cli.AuthedWS != nil { return nil, errors.New("authed websocket already connected") } @@ -90,7 +90,7 @@ func (cli *Client) ConnectAuthedWS(ctx context.Context, requestHandler web.Reque return statusChan, nil } -func (cli *Client) ConnectUnauthedWS(ctx context.Context) (chan web.SignalWebsocketConnectionStatus, error) { +func (cli *Client) connectUnauthedWS(ctx context.Context) (chan web.SignalWebsocketConnectionStatus, error) { if cli.UnauthedWS != nil { return nil, errors.New("unauthed websocket already connected") } diff --git a/pkg/signalmeow/events/message.go b/pkg/signalmeow/events/message.go index 0038657..9b8e79d 100644 --- a/pkg/signalmeow/events/message.go +++ b/pkg/signalmeow/events/message.go @@ -35,6 +35,7 @@ func (*ReadSelf) isSignalEvent() {} func (*Call) isSignalEvent() {} func (*ContactList) isSignalEvent() {} func (*ACIFound) isSignalEvent() {} +func (*QueueEmpty) isSignalEvent() {} type MessageInfo struct { Sender uuid.UUID @@ -78,3 +79,5 @@ type ACIFound struct { PNI libsignalgo.ServiceID ACI libsignalgo.ServiceID } + +type QueueEmpty struct{} diff --git a/pkg/signalmeow/receiving.go b/pkg/signalmeow/receiving.go index b1dddea..4d913e2 100644 --- a/pkg/signalmeow/receiving.go +++ b/pkg/signalmeow/receiving.go @@ -68,17 +68,29 @@ type SignalConnectionStatus struct { Err error } +func (cli *Client) StartAuthedWS(ctx context.Context) (chan web.SignalWebsocketConnectionStatus, error) { + ctx, cancel := context.WithCancel(ctx) + cli.WSCancel = cancel + authChan, err := cli.connectAuthedWS(ctx, cli.incomingRequestHandler) + if err != nil { + cancel() + return nil, err + } + zerolog.Ctx(ctx).Info().Msg("Authed websocket connecting") + return authChan, nil +} + func (cli *Client) StartReceiveLoops(ctx context.Context) (chan SignalConnectionStatus, error) { log := zerolog.Ctx(ctx).With().Str("action", "start receive loops").Logger() ctx, cancel := context.WithCancel(log.WithContext(ctx)) cli.WSCancel = cancel - authChan, err := cli.ConnectAuthedWS(ctx, cli.incomingRequestHandler) + authChan, err := cli.connectAuthedWS(ctx, cli.incomingRequestHandler) if err != nil { cancel() return nil, err } log.Info().Msg("Authed websocket connecting") - unauthChan, err := cli.ConnectUnauthedWS(ctx) + unauthChan, err := cli.connectUnauthedWS(ctx) if err != nil { cancel() return nil, err @@ -257,6 +269,7 @@ func (cli *Client) incomingRequestHandler(ctx context.Context, req *signalpb.Web return cli.incomingAPIMessageHandler(ctx, req) } else if *req.Verb == http.MethodPut && *req.Path == "/api/v1/queue/empty" { log.Trace().Msg("Received queue empty") + cli.handleEvent(&events.QueueEmpty{}) } else { log.Warn().Any("req", req).Msg("Unknown websocket request message") } From 33905f74ac051918e824d163aa0c78fc335c5148 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Fri, 17 Jan 2025 17:49:37 +0200 Subject: [PATCH 254/580] libsignal: update to v0.65.2 --- go.mod | 2 +- pkg/libsignalgo/address.go | 25 +- pkg/libsignalgo/aes256gcmsiv.go | 31 +- pkg/libsignalgo/authcredential.go | 5 +- pkg/libsignalgo/ciphertextmessage.go | 24 +- pkg/libsignalgo/decryptionerrormessage.go | 54 +- pkg/libsignalgo/fingerprint.go | 35 +- pkg/libsignalgo/groupcipher.go | 9 +- pkg/libsignalgo/groupsecretparams.go | 3 +- pkg/libsignalgo/hsmenclave.go | 29 +- pkg/libsignalgo/identitykey.go | 31 +- pkg/libsignalgo/identitykeystore.go | 7 +- pkg/libsignalgo/kyberprekey.go | 99 +- pkg/libsignalgo/kyberprekeystore.go | 7 +- pkg/libsignalgo/libsignal | 2 +- pkg/libsignalgo/libsignal-ffi.h | 1334 +++++++++++------ pkg/libsignalgo/message.go | 63 +- pkg/libsignalgo/plaintextcontent.go | 37 +- pkg/libsignalgo/prekey.go | 52 +- pkg/libsignalgo/prekeybundle.go | 39 +- pkg/libsignalgo/prekeymessage.go | 49 +- pkg/libsignalgo/prekeystore.go | 7 +- pkg/libsignalgo/privatekey.go | 37 +- pkg/libsignalgo/profilekey.go | 5 +- pkg/libsignalgo/protocol.go | 49 - pkg/libsignalgo/publickey.go | 34 +- pkg/libsignalgo/sealedsender.go | 51 +- pkg/libsignalgo/sendercertificate.go | 72 +- .../senderkeydistributionmessage.go | 31 +- pkg/libsignalgo/senderkeyrecord.go | 23 +- pkg/libsignalgo/senderkeystore.go | 7 +- pkg/libsignalgo/servercertificate.go | 46 +- pkg/libsignalgo/serverpublicparams.go | 12 +- pkg/libsignalgo/sessionrecord.go | 44 +- pkg/libsignalgo/sessionstore.go | 7 +- pkg/libsignalgo/sgxclient.go | 30 +- pkg/libsignalgo/signedprekey.go | 57 +- pkg/libsignalgo/signedprekeystore.go | 7 +- pkg/libsignalgo/version.go | 2 +- 39 files changed, 1626 insertions(+), 832 deletions(-) delete mode 100644 pkg/libsignalgo/protocol.go diff --git a/go.mod b/go.mod index f4eaf6a..040c374 100644 --- a/go.mod +++ b/go.mod @@ -2,7 +2,7 @@ module go.mau.fi/mautrix-signal go 1.22.0 -toolchain go1.23.4 +toolchain go1.23.5 require ( github.com/coder/websocket v1.8.12 diff --git a/pkg/libsignalgo/address.go b/pkg/libsignalgo/address.go index 9afacc0..95e4249 100644 --- a/pkg/libsignalgo/address.go +++ b/pkg/libsignalgo/address.go @@ -1,5 +1,6 @@ // mautrix-signal - A Matrix-signal puppeting bridge. // Copyright (C) 2023 Sumner Evans +// Copyright (C) 2025 Tulir Asokan // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU Affero General Public License as published by @@ -45,27 +46,35 @@ func NewUUIDAddressFromString(uuidStr string, deviceID uint) (*Address, error) { } func newAddress(name string, deviceID uint) (*Address, error) { - var pa *C.SignalProtocolAddress + var pa C.SignalMutPointerProtocolAddress signalFfiError := C.signal_address_new(&pa, C.CString(name), C.uint(deviceID)) if signalFfiError != nil { return nil, wrapError(signalFfiError) } - return wrapAddress(pa), nil + return wrapAddress(pa.raw), nil +} + +func (pa *Address) mutPtr() C.SignalMutPointerProtocolAddress { + return C.SignalMutPointerProtocolAddress{pa.ptr} +} + +func (pa *Address) constPtr() C.SignalConstPointerProtocolAddress { + return C.SignalConstPointerProtocolAddress{pa.ptr} } func (pa *Address) Clone() (*Address, error) { - var cloned *C.SignalProtocolAddress - signalFfiError := C.signal_address_clone(&cloned, pa.ptr) + var cloned C.SignalMutPointerProtocolAddress + signalFfiError := C.signal_address_clone(&cloned, pa.constPtr()) runtime.KeepAlive(pa) if signalFfiError != nil { return nil, wrapError(signalFfiError) } - return wrapAddress(cloned), nil + return wrapAddress(cloned.raw), nil } func (pa *Address) Destroy() error { pa.CancelFinalizer() - return wrapError(C.signal_address_destroy(pa.ptr)) + return wrapError(C.signal_address_destroy(pa.mutPtr())) } func (pa *Address) CancelFinalizer() { @@ -74,7 +83,7 @@ func (pa *Address) CancelFinalizer() { func (pa *Address) Name() (string, error) { var name *C.char - signalFfiError := C.signal_address_get_name(&name, pa.ptr) + signalFfiError := C.signal_address_get_name(&name, pa.constPtr()) runtime.KeepAlive(pa) if signalFfiError != nil { return "", wrapError(signalFfiError) @@ -92,7 +101,7 @@ func (pa *Address) NameServiceID() (ServiceID, error) { func (pa *Address) DeviceID() (uint, error) { var deviceID C.uint - signalFfiError := C.signal_address_get_device_id(&deviceID, pa.ptr) + signalFfiError := C.signal_address_get_device_id(&deviceID, pa.constPtr()) runtime.KeepAlive(pa) if signalFfiError != nil { return 0, wrapError(signalFfiError) diff --git a/pkg/libsignalgo/aes256gcmsiv.go b/pkg/libsignalgo/aes256gcmsiv.go index f6fd2c8..b4d0924 100644 --- a/pkg/libsignalgo/aes256gcmsiv.go +++ b/pkg/libsignalgo/aes256gcmsiv.go @@ -1,5 +1,6 @@ // mautrix-signal - A Matrix-signal puppeting bridge. // Copyright (C) 2023 Sumner Evans +// Copyright (C) 2025 Tulir Asokan // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU Affero General Public License as published by @@ -35,23 +36,37 @@ func wrapAES256_GCM_SIV(ptr *C.SignalAes256GcmSiv) *AES256_GCM_SIV { } func NewAES256_GCM_SIV(key []byte) (*AES256_GCM_SIV, error) { - var aes *C.SignalAes256GcmSiv + var aes C.SignalMutPointerAes256GcmSiv signalFfiError := C.signal_aes256_gcm_siv_new(&aes, BytesToBuffer(key)) if signalFfiError != nil { return nil, wrapError(signalFfiError) } - return wrapAES256_GCM_SIV(aes), nil + return wrapAES256_GCM_SIV(aes.raw), nil +} + +func (aes *AES256_GCM_SIV) mutPtr() C.SignalMutPointerAes256GcmSiv { + return C.SignalMutPointerAes256GcmSiv{aes.ptr} +} + +func (aes *AES256_GCM_SIV) constPtr() C.SignalConstPointerAes256GcmSiv { + return C.SignalConstPointerAes256GcmSiv{aes.ptr} } func (aes *AES256_GCM_SIV) Destroy() error { runtime.SetFinalizer(aes, nil) - return wrapError(C.signal_aes256_gcm_siv_destroy(aes.ptr)) + return wrapError(C.signal_aes256_gcm_siv_destroy(C.SignalMutPointerAes256GcmSiv{raw: aes.ptr})) } func (aes *AES256_GCM_SIV) Encrypt(plaintext, nonce, associatedData []byte) ([]byte, error) { var encrypted C.SignalOwnedBuffer = C.SignalOwnedBuffer{} - signalFfiError := C.signal_aes256_gcm_siv_encrypt(&encrypted, aes.ptr, BytesToBuffer(plaintext), BytesToBuffer(nonce), BytesToBuffer(associatedData)) + signalFfiError := C.signal_aes256_gcm_siv_encrypt( + &encrypted, + C.SignalConstPointerAes256GcmSiv{raw: aes.ptr}, + BytesToBuffer(plaintext), + BytesToBuffer(nonce), + BytesToBuffer(associatedData), + ) runtime.KeepAlive(aes) if signalFfiError != nil { return nil, wrapError(signalFfiError) @@ -61,7 +76,13 @@ func (aes *AES256_GCM_SIV) Encrypt(plaintext, nonce, associatedData []byte) ([]b func (aes *AES256_GCM_SIV) Decrypt(ciphertext, nonce, associatedData []byte) ([]byte, error) { var decrypted C.SignalOwnedBuffer = C.SignalOwnedBuffer{} - signalFfiError := C.signal_aes256_gcm_siv_decrypt(&decrypted, aes.ptr, BytesToBuffer(ciphertext), BytesToBuffer(nonce), BytesToBuffer(associatedData)) + signalFfiError := C.signal_aes256_gcm_siv_decrypt( + &decrypted, + C.SignalConstPointerAes256GcmSiv{raw: aes.ptr}, + BytesToBuffer(ciphertext), + BytesToBuffer(nonce), + BytesToBuffer(associatedData), + ) if signalFfiError != nil { return nil, wrapError(signalFfiError) } diff --git a/pkg/libsignalgo/authcredential.go b/pkg/libsignalgo/authcredential.go index 0c7354f..65b9a67 100644 --- a/pkg/libsignalgo/authcredential.go +++ b/pkg/libsignalgo/authcredential.go @@ -1,5 +1,6 @@ // mautrix-signal - A Matrix-signal puppeting bridge. // Copyright (C) 2023 Scott Weber +// Copyright (C) 2025 Tulir Asokan // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU Affero General Public License as published by @@ -50,7 +51,7 @@ func ReceiveAuthCredentialWithPni( signalFfiError := C.signal_server_public_params_receive_auth_credential_with_pni_as_service_id( &c_result, - serverPublicParams, + C.SignalConstPointerServerPublicParams{serverPublicParams}, NewACIServiceID(aci).CFixedBytes(), NewPNIServiceID(pni).CFixedBytes(), C.uint64_t(redemptionTime), @@ -88,7 +89,7 @@ func CreateAuthCredentialWithPniPresentation( signalFfiError := C.signal_server_public_params_create_auth_credential_with_pni_presentation_deterministic( &c_result, - serverPublicParams, + C.SignalConstPointerServerPublicParams{serverPublicParams}, c_randomness, c_groupSecretParams, BytesToBuffer(authCredWithPni[:]), diff --git a/pkg/libsignalgo/ciphertextmessage.go b/pkg/libsignalgo/ciphertextmessage.go index f783ad8..e1c1bdb 100644 --- a/pkg/libsignalgo/ciphertextmessage.go +++ b/pkg/libsignalgo/ciphertextmessage.go @@ -1,5 +1,6 @@ // mautrix-signal - A Matrix-signal puppeting bridge. // Copyright (C) 2023 Sumner Evans +// Copyright (C) 2025 Tulir Asokan // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU Affero General Public License as published by @@ -44,17 +45,28 @@ func wrapCiphertextMessage(ptr *C.SignalCiphertextMessage) *CiphertextMessage { } func NewCiphertextMessage(plaintext *PlaintextContent) (*CiphertextMessage, error) { - var ciphertextMessage *C.SignalCiphertextMessage - signalFfiError := C.signal_ciphertext_message_from_plaintext_content(&ciphertextMessage, plaintext.ptr) + var ciphertextMessage C.SignalMutPointerCiphertextMessage + signalFfiError := C.signal_ciphertext_message_from_plaintext_content( + &ciphertextMessage, + plaintext.constPtr(), + ) if signalFfiError != nil { return nil, wrapError(signalFfiError) } - return wrapCiphertextMessage(ciphertextMessage), nil + return wrapCiphertextMessage(ciphertextMessage.raw), nil +} + +func (c *CiphertextMessage) mutPtr() C.SignalMutPointerCiphertextMessage { + return C.SignalMutPointerCiphertextMessage{c.ptr} +} + +func (c *CiphertextMessage) constPtr() C.SignalConstPointerCiphertextMessage { + return C.SignalConstPointerCiphertextMessage{c.ptr} } func (c *CiphertextMessage) Destroy() error { c.CancelFinalizer() - return wrapError(C.signal_ciphertext_message_destroy(c.ptr)) + return wrapError(C.signal_ciphertext_message_destroy(c.mutPtr())) } func (c *CiphertextMessage) CancelFinalizer() { @@ -63,7 +75,7 @@ func (c *CiphertextMessage) CancelFinalizer() { func (c *CiphertextMessage) Serialize() ([]byte, error) { var serialized C.SignalOwnedBuffer = C.SignalOwnedBuffer{} - signalFfiError := C.signal_ciphertext_message_serialize(&serialized, c.ptr) + signalFfiError := C.signal_ciphertext_message_serialize(&serialized, c.constPtr()) runtime.KeepAlive(c) if signalFfiError != nil { return nil, wrapError(signalFfiError) @@ -73,7 +85,7 @@ func (c *CiphertextMessage) Serialize() ([]byte, error) { func (c *CiphertextMessage) MessageType() (CiphertextMessageType, error) { var messageType C.uint8_t - signalFfiError := C.signal_ciphertext_message_type(&messageType, c.ptr) + signalFfiError := C.signal_ciphertext_message_type(&messageType, c.constPtr()) runtime.KeepAlive(c) if signalFfiError != nil { return 0, wrapError(signalFfiError) diff --git a/pkg/libsignalgo/decryptionerrormessage.go b/pkg/libsignalgo/decryptionerrormessage.go index c5d5f18..5e4e3b9 100644 --- a/pkg/libsignalgo/decryptionerrormessage.go +++ b/pkg/libsignalgo/decryptionerrormessage.go @@ -1,5 +1,6 @@ // mautrix-signal - A Matrix-signal puppeting bridge. // Copyright (C) 2023 Sumner Evans +// Copyright (C) 2025 Tulir Asokan // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU Affero General Public License as published by @@ -38,47 +39,64 @@ func wrapDecryptionErrorMessage(ptr *C.SignalDecryptionErrorMessage) *Decryption } func DeserializeDecryptionErrorMessage(messageBytes []byte) (*DecryptionErrorMessage, error) { - var dem *C.SignalDecryptionErrorMessage - signalFfiError := C.signal_decryption_error_message_deserialize(&dem, BytesToBuffer(messageBytes)) + var dem C.SignalMutPointerDecryptionErrorMessage + signalFfiError := C.signal_decryption_error_message_deserialize( + &dem, + BytesToBuffer(messageBytes), + ) if signalFfiError != nil { return nil, wrapError(signalFfiError) } - return wrapDecryptionErrorMessage(dem), nil + return wrapDecryptionErrorMessage(dem.raw), nil } func DecryptionErrorMessageForOriginalMessage(originalBytes []byte, originalType uint8, originalTs uint64, originalSenderDeviceID uint) (*DecryptionErrorMessage, error) { - var dem *C.SignalDecryptionErrorMessage - signalFfiError := C.signal_decryption_error_message_for_original_message(&dem, BytesToBuffer(originalBytes), C.uint8_t(originalType), C.uint64_t(originalTs), C.uint32_t(originalSenderDeviceID)) + var dem C.SignalMutPointerDecryptionErrorMessage + signalFfiError := C.signal_decryption_error_message_for_original_message( + &dem, + BytesToBuffer(originalBytes), + C.uint8_t(originalType), + C.uint64_t(originalTs), + C.uint32_t(originalSenderDeviceID), + ) runtime.KeepAlive(originalBytes) if signalFfiError != nil { return nil, wrapError(signalFfiError) } - return wrapDecryptionErrorMessage(dem), nil + return wrapDecryptionErrorMessage(dem.raw), nil } func DecryptionErrorMessageFromSerializedContent(serialized []byte) (*DecryptionErrorMessage, error) { - var dem *C.SignalDecryptionErrorMessage + var dem C.SignalMutPointerDecryptionErrorMessage signalFfiError := C.signal_decryption_error_message_extract_from_serialized_content(&dem, BytesToBuffer(serialized)) runtime.KeepAlive(serialized) if signalFfiError != nil { return nil, wrapError(signalFfiError) } - return wrapDecryptionErrorMessage(dem), nil + return wrapDecryptionErrorMessage(dem.raw), nil +} + +func (dem *DecryptionErrorMessage) mutPtr() C.SignalMutPointerDecryptionErrorMessage { + return C.SignalMutPointerDecryptionErrorMessage{dem.ptr} +} + +func (dem *DecryptionErrorMessage) constPtr() C.SignalConstPointerDecryptionErrorMessage { + return C.SignalConstPointerDecryptionErrorMessage{dem.ptr} } func (dem *DecryptionErrorMessage) Clone() (*DecryptionErrorMessage, error) { - var cloned *C.SignalDecryptionErrorMessage - signalFfiError := C.signal_decryption_error_message_clone(&cloned, dem.ptr) + var cloned C.SignalMutPointerDecryptionErrorMessage + signalFfiError := C.signal_decryption_error_message_clone(&cloned, dem.constPtr()) runtime.KeepAlive(dem) if signalFfiError != nil { return nil, wrapError(signalFfiError) } - return wrapDecryptionErrorMessage(cloned), nil + return wrapDecryptionErrorMessage(cloned.raw), nil } func (dem *DecryptionErrorMessage) Destroy() error { dem.CancelFinalizer() - return wrapError(C.signal_decryption_error_message_destroy(dem.ptr)) + return wrapError(C.signal_decryption_error_message_destroy(dem.mutPtr())) } func (dem *DecryptionErrorMessage) CancelFinalizer() { @@ -87,7 +105,7 @@ func (dem *DecryptionErrorMessage) CancelFinalizer() { func (dem *DecryptionErrorMessage) Serialize() ([]byte, error) { var serialized C.SignalOwnedBuffer = C.SignalOwnedBuffer{} - signalFfiError := C.signal_decryption_error_message_serialize(&serialized, dem.ptr) + signalFfiError := C.signal_decryption_error_message_serialize(&serialized, dem.constPtr()) runtime.KeepAlive(dem) if signalFfiError != nil { return nil, wrapError(signalFfiError) @@ -97,7 +115,7 @@ func (dem *DecryptionErrorMessage) Serialize() ([]byte, error) { func (dem *DecryptionErrorMessage) GetTimestamp() (time.Time, error) { var ts C.uint64_t - signalFfiError := C.signal_decryption_error_message_get_timestamp(&ts, dem.ptr) + signalFfiError := C.signal_decryption_error_message_get_timestamp(&ts, dem.constPtr()) runtime.KeepAlive(dem) if signalFfiError != nil { return time.Time{}, wrapError(signalFfiError) @@ -107,7 +125,7 @@ func (dem *DecryptionErrorMessage) GetTimestamp() (time.Time, error) { func (dem *DecryptionErrorMessage) GetDeviceID() (uint32, error) { var deviceID C.uint32_t - signalFfiError := C.signal_decryption_error_message_get_device_id(&deviceID, dem.ptr) + signalFfiError := C.signal_decryption_error_message_get_device_id(&deviceID, dem.constPtr()) runtime.KeepAlive(dem) if signalFfiError != nil { return 0, wrapError(signalFfiError) @@ -116,11 +134,11 @@ func (dem *DecryptionErrorMessage) GetDeviceID() (uint32, error) { } func (dem *DecryptionErrorMessage) GetRatchetKey() (*PublicKey, error) { - var pk *C.SignalPublicKey - signalFfiError := C.signal_decryption_error_message_get_ratchet_key(&pk, dem.ptr) + var pk C.SignalMutPointerPublicKey + signalFfiError := C.signal_decryption_error_message_get_ratchet_key(&pk, dem.constPtr()) runtime.KeepAlive(dem) if signalFfiError != nil { return nil, wrapError(signalFfiError) } - return wrapPublicKey(pk), nil + return wrapPublicKey(pk.raw), nil } diff --git a/pkg/libsignalgo/fingerprint.go b/pkg/libsignalgo/fingerprint.go index 2636015..4bbf24c 100644 --- a/pkg/libsignalgo/fingerprint.go +++ b/pkg/libsignalgo/fingerprint.go @@ -1,5 +1,6 @@ // mautrix-signal - A Matrix-signal puppeting bridge. // Copyright (C) 2023 Sumner Evans +// Copyright (C) 2025 Tulir Asokan // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU Affero General Public License as published by @@ -42,32 +43,48 @@ func wrapFingerprint(ptr *C.SignalFingerprint) *Fingerprint { } func NewFingerprint(iterations, version FingerprintVersion, localIdentifier []byte, localKey *PublicKey, remoteIdentifier []byte, remoteKey *PublicKey) (*Fingerprint, error) { - var pa *C.SignalFingerprint - signalFfiError := C.signal_fingerprint_new(&pa, C.uint32_t(iterations), C.uint32_t(version), BytesToBuffer(localIdentifier), localKey.ptr, BytesToBuffer(remoteIdentifier), remoteKey.ptr) + var pa C.SignalMutPointerFingerprint + signalFfiError := C.signal_fingerprint_new( + &pa, + C.uint32_t(iterations), + C.uint32_t(version), + BytesToBuffer(localIdentifier), + localKey.constPtr(), + BytesToBuffer(remoteIdentifier), + remoteKey.constPtr(), + ) if signalFfiError != nil { return nil, wrapError(signalFfiError) } - return wrapFingerprint(pa), nil + return wrapFingerprint(pa.raw), nil +} + +func (f *Fingerprint) mutPtr() C.SignalMutPointerFingerprint { + return C.SignalMutPointerFingerprint{f.ptr} +} + +func (f *Fingerprint) constPtr() C.SignalConstPointerFingerprint { + return C.SignalConstPointerFingerprint{f.ptr} } func (f *Fingerprint) Clone() (*Fingerprint, error) { - var cloned *C.SignalFingerprint - signalFfiError := C.signal_fingerprint_clone(&cloned, f.ptr) + var cloned C.SignalMutPointerFingerprint + signalFfiError := C.signal_fingerprint_clone(&cloned, f.constPtr()) runtime.KeepAlive(f) if signalFfiError != nil { return nil, wrapError(signalFfiError) } - return wrapFingerprint(cloned), nil + return wrapFingerprint(cloned.raw), nil } func (f *Fingerprint) Destroy() error { runtime.SetFinalizer(f, nil) - return wrapError(C.signal_fingerprint_destroy(f.ptr)) + return wrapError(C.signal_fingerprint_destroy(f.mutPtr())) } func (f *Fingerprint) ScannableEncoding() ([]byte, error) { var scannableEncoding C.SignalOwnedBuffer = C.SignalOwnedBuffer{} - signalFfiError := C.signal_fingerprint_scannable_encoding(&scannableEncoding, f.ptr) + signalFfiError := C.signal_fingerprint_scannable_encoding(&scannableEncoding, f.constPtr()) runtime.KeepAlive(f) if signalFfiError != nil { return nil, wrapError(signalFfiError) @@ -77,7 +94,7 @@ func (f *Fingerprint) ScannableEncoding() ([]byte, error) { func (f *Fingerprint) DisplayString() (string, error) { var displayString *C.char - signalFfiError := C.signal_fingerprint_display_string(&displayString, f.ptr) + signalFfiError := C.signal_fingerprint_display_string(&displayString, f.constPtr()) runtime.KeepAlive(f) if signalFfiError != nil { return "", wrapError(signalFfiError) diff --git a/pkg/libsignalgo/groupcipher.go b/pkg/libsignalgo/groupcipher.go index 7faaf90..33e18aa 100644 --- a/pkg/libsignalgo/groupcipher.go +++ b/pkg/libsignalgo/groupcipher.go @@ -1,5 +1,6 @@ // mautrix-signal - A Matrix-signal puppeting bridge. // Copyright (C) 2023 Sumner Evans +// Copyright (C) 2025 Tulir Asokan // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU Affero General Public License as published by @@ -32,10 +33,10 @@ import ( func GroupEncrypt(ctx context.Context, ptext []byte, sender *Address, distributionID uuid.UUID, store SenderKeyStore) (*CiphertextMessage, error) { callbackCtx := NewCallbackContext(ctx) defer callbackCtx.Unref() - var ciphertextMessage *C.SignalCiphertextMessage + var ciphertextMessage C.SignalMutPointerCiphertextMessage signalFfiError := C.signal_group_encrypt_message( &ciphertextMessage, - sender.ptr, + sender.constPtr(), (*[C.SignalUUID_LEN]C.uchar)(unsafe.Pointer(&distributionID)), BytesToBuffer(ptext), callbackCtx.wrapSenderKeyStore(store)) @@ -44,7 +45,7 @@ func GroupEncrypt(ctx context.Context, ptext []byte, sender *Address, distributi if signalFfiError != nil { return nil, callbackCtx.wrapError(signalFfiError) } - return wrapCiphertextMessage(ciphertextMessage), nil + return wrapCiphertextMessage(ciphertextMessage.raw), nil } func GroupDecrypt(ctx context.Context, ctext []byte, sender *Address, store SenderKeyStore) ([]byte, error) { @@ -53,7 +54,7 @@ func GroupDecrypt(ctx context.Context, ctext []byte, sender *Address, store Send var resp C.SignalOwnedBuffer = C.SignalOwnedBuffer{} signalFfiError := C.signal_group_decrypt_message( &resp, - sender.ptr, + sender.constPtr(), BytesToBuffer(ctext), callbackCtx.wrapSenderKeyStore(store)) runtime.KeepAlive(ctext) diff --git a/pkg/libsignalgo/groupsecretparams.go b/pkg/libsignalgo/groupsecretparams.go index 0df5ec8..943dfda 100644 --- a/pkg/libsignalgo/groupsecretparams.go +++ b/pkg/libsignalgo/groupsecretparams.go @@ -1,5 +1,6 @@ // mautrix-signal - A Matrix-signal puppeting bridge. // Copyright (C) 2023 Sumner Evans +// Copyright (C) 2025 Tulir Asokan // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU Affero General Public License as published by @@ -213,7 +214,7 @@ func (gsp *GroupSecretParams) CreateExpiringProfileKeyCredentialPresentation(spp randomness := GenerateRandomness() signalFfiError := C.signal_server_public_params_create_expiring_profile_key_credential_presentation_deterministic( &out, - spp, + C.SignalConstPointerServerPublicParams{spp}, (*[C.SignalRANDOMNESS_LEN]C.uint8_t)(unsafe.Pointer(&randomness)), (*[C.SignalGROUP_SECRET_PARAMS_LEN]C.uchar)(unsafe.Pointer(gsp)), (*[C.SignalEXPIRING_PROFILE_KEY_CREDENTIAL_LEN]C.uchar)(unsafe.Pointer(&credential)), diff --git a/pkg/libsignalgo/hsmenclave.go b/pkg/libsignalgo/hsmenclave.go index 51ca6f4..15a44fa 100644 --- a/pkg/libsignalgo/hsmenclave.go +++ b/pkg/libsignalgo/hsmenclave.go @@ -1,5 +1,6 @@ // mautrix-signal - A Matrix-signal puppeting bridge. // Copyright (C) 2023 Sumner Evans +// Copyright (C) 2025 Tulir Asokan // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU Affero General Public License as published by @@ -35,22 +36,34 @@ func wrapHSMEnclaveClient(ptr *C.SignalHsmEnclaveClient) *HSMEnclaveClient { } func NewHSMEnclaveClient(trustedPublicKey, trustedCodeHashes []byte) (*HSMEnclaveClient, error) { - var cds *C.SignalHsmEnclaveClient - signalFfiError := C.signal_hsm_enclave_client_new(&cds, BytesToBuffer(trustedPublicKey), BytesToBuffer(trustedCodeHashes)) + var cds C.SignalMutPointerHsmEnclaveClient + signalFfiError := C.signal_hsm_enclave_client_new( + &cds, + BytesToBuffer(trustedPublicKey), + BytesToBuffer(trustedCodeHashes), + ) if signalFfiError != nil { return nil, wrapError(signalFfiError) } - return wrapHSMEnclaveClient(cds), nil + return wrapHSMEnclaveClient(cds.raw), nil +} + +func (hsm *HSMEnclaveClient) mutPtr() C.SignalMutPointerHsmEnclaveClient { + return C.SignalMutPointerHsmEnclaveClient{hsm.ptr} +} + +func (hsm *HSMEnclaveClient) constPtr() C.SignalConstPointerHsmEnclaveClient { + return C.SignalConstPointerHsmEnclaveClient{hsm.ptr} } func (hsm *HSMEnclaveClient) Destroy() error { runtime.SetFinalizer(hsm, nil) - return wrapError(C.signal_hsm_enclave_client_destroy(hsm.ptr)) + return wrapError(C.signal_hsm_enclave_client_destroy(hsm.mutPtr())) } func (hsm *HSMEnclaveClient) InitialRequest() ([]byte, error) { var resp C.SignalOwnedBuffer = C.SignalOwnedBuffer{} - signalFfiError := C.signal_hsm_enclave_client_initial_request(&resp, hsm.ptr) + signalFfiError := C.signal_hsm_enclave_client_initial_request(&resp, hsm.constPtr()) runtime.KeepAlive(hsm) if signalFfiError != nil { return nil, wrapError(signalFfiError) @@ -59,7 +72,7 @@ func (hsm *HSMEnclaveClient) InitialRequest() ([]byte, error) { } func (hsm *HSMEnclaveClient) CompleteHandshake(handshakeReceived []byte) error { - signalFfiError := C.signal_hsm_enclave_client_complete_handshake(hsm.ptr, BytesToBuffer(handshakeReceived)) + signalFfiError := C.signal_hsm_enclave_client_complete_handshake(hsm.mutPtr(), BytesToBuffer(handshakeReceived)) runtime.KeepAlive(hsm) runtime.KeepAlive(handshakeReceived) return wrapError(signalFfiError) @@ -67,7 +80,7 @@ func (hsm *HSMEnclaveClient) CompleteHandshake(handshakeReceived []byte) error { func (hsm *HSMEnclaveClient) EstablishedSend(plaintext []byte) ([]byte, error) { var resp C.SignalOwnedBuffer = C.SignalOwnedBuffer{} - signalFfiError := C.signal_hsm_enclave_client_established_send(&resp, hsm.ptr, BytesToBuffer(plaintext)) + signalFfiError := C.signal_hsm_enclave_client_established_send(&resp, hsm.mutPtr(), BytesToBuffer(plaintext)) runtime.KeepAlive(hsm) runtime.KeepAlive(plaintext) if signalFfiError != nil { @@ -78,7 +91,7 @@ func (hsm *HSMEnclaveClient) EstablishedSend(plaintext []byte) ([]byte, error) { func (hsm *HSMEnclaveClient) EstablishedReceive(ciphertext []byte) ([]byte, error) { var resp C.SignalOwnedBuffer = C.SignalOwnedBuffer{} - signalFfiError := C.signal_hsm_enclave_client_established_recv(&resp, hsm.ptr, BytesToBuffer(ciphertext)) + signalFfiError := C.signal_hsm_enclave_client_established_recv(&resp, hsm.mutPtr(), BytesToBuffer(ciphertext)) runtime.KeepAlive(hsm) runtime.KeepAlive(ciphertext) if signalFfiError != nil { diff --git a/pkg/libsignalgo/identitykey.go b/pkg/libsignalgo/identitykey.go index 796e575..9cd8425 100644 --- a/pkg/libsignalgo/identitykey.go +++ b/pkg/libsignalgo/identitykey.go @@ -1,5 +1,6 @@ // mautrix-signal - A Matrix-signal puppeting bridge. // Copyright (C) 2023 Sumner Evans +// Copyright (C) 2025 Tulir Asokan // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU Affero General Public License as published by @@ -57,18 +58,23 @@ func (i *IdentityKey) Serialize() ([]byte, error) { } func DeserializeIdentityKey(bytes []byte) (*IdentityKey, error) { - var publicKey *C.SignalPublicKey + var publicKey C.SignalMutPointerPublicKey signalFfiError := C.signal_publickey_deserialize(&publicKey, BytesToBuffer(bytes)) runtime.KeepAlive(bytes) if signalFfiError != nil { return nil, wrapError(signalFfiError) } - return &IdentityKey{publicKey: wrapPublicKey(publicKey)}, nil + return &IdentityKey{publicKey: wrapPublicKey(publicKey.raw)}, nil } func (i *IdentityKey) VerifyAlternateIdentity(other *IdentityKey, signature []byte) (bool, error) { var verify C.bool - signalFfiError := C.signal_identitykey_verify_alternate_identity(&verify, i.publicKey.ptr, other.publicKey.ptr, BytesToBuffer(signature)) + signalFfiError := C.signal_identitykey_verify_alternate_identity( + &verify, + i.publicKey.constPtr(), + other.publicKey.constPtr(), + BytesToBuffer(signature), + ) runtime.KeepAlive(i) runtime.KeepAlive(other) runtime.KeepAlive(signature) @@ -109,14 +115,14 @@ func GenerateIdentityKeyPair() (*IdentityKeyPair, error) { } func DeserializeIdentityKeyPair(bytes []byte) (*IdentityKeyPair, error) { - var privateKey *C.SignalPrivateKey - var publicKey *C.SignalPublicKey + var privateKey C.SignalMutPointerPrivateKey + var publicKey C.SignalMutPointerPublicKey signalFfiError := C.signal_identitykeypair_deserialize(&privateKey, &publicKey, BytesToBuffer(bytes)) runtime.KeepAlive(bytes) if signalFfiError != nil { return nil, wrapError(signalFfiError) } - return &IdentityKeyPair{publicKey: wrapPublicKey(publicKey), privateKey: wrapPrivateKey(privateKey)}, nil + return &IdentityKeyPair{publicKey: wrapPublicKey(publicKey.raw), privateKey: wrapPrivateKey(privateKey.raw)}, nil } func NewIdentityKeyPair(publicKey *PublicKey, privateKey *PrivateKey) (*IdentityKeyPair, error) { @@ -125,7 +131,11 @@ func NewIdentityKeyPair(publicKey *PublicKey, privateKey *PrivateKey) (*Identity func (i *IdentityKeyPair) Serialize() ([]byte, error) { var serialized C.SignalOwnedBuffer = C.SignalOwnedBuffer{} - signalFfiError := C.signal_identitykeypair_serialize(&serialized, i.publicKey.ptr, i.privateKey.ptr) + signalFfiError := C.signal_identitykeypair_serialize( + &serialized, + i.publicKey.constPtr(), + i.privateKey.constPtr(), + ) runtime.KeepAlive(i) if signalFfiError != nil { return nil, wrapError(signalFfiError) @@ -139,7 +149,12 @@ func (i *IdentityKeyPair) GetIdentityKey() *IdentityKey { func (i *IdentityKeyPair) SignAlternateIdentity(other *IdentityKey) ([]byte, error) { var signature C.SignalOwnedBuffer = C.SignalOwnedBuffer{} - signalFfiError := C.signal_identitykeypair_sign_alternate_identity(&signature, i.publicKey.ptr, i.privateKey.ptr, other.publicKey.ptr) + signalFfiError := C.signal_identitykeypair_sign_alternate_identity( + &signature, + i.publicKey.constPtr(), + i.privateKey.constPtr(), + other.publicKey.constPtr(), + ) runtime.KeepAlive(i) runtime.KeepAlive(other) if signalFfiError != nil { diff --git a/pkg/libsignalgo/identitykeystore.go b/pkg/libsignalgo/identitykeystore.go index 19c6520..88e5eaa 100644 --- a/pkg/libsignalgo/identitykeystore.go +++ b/pkg/libsignalgo/identitykeystore.go @@ -1,5 +1,6 @@ // mautrix-signal - A Matrix-signal puppeting bridge. // Copyright (C) 2023 Sumner Evans +// Copyright (C) 2025 Tulir Asokan // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU Affero General Public License as published by @@ -148,13 +149,13 @@ func signal_is_trusted_identity_callback(storeCtx unsafe.Pointer, address *C.con }) } -func (ctx *CallbackContext) wrapIdentityKeyStore(store IdentityKeyStore) *C.SignalIdentityKeyStore { - return &C.SignalIdentityKeyStore{ +func (ctx *CallbackContext) wrapIdentityKeyStore(store IdentityKeyStore) C.SignalConstPointerFfiIdentityKeyStoreStruct { + return C.SignalConstPointerFfiIdentityKeyStoreStruct{&C.SignalIdentityKeyStore{ ctx: wrapStore(ctx, store), get_identity_key_pair: C.SignalGetIdentityKeyPair(C.signal_get_identity_key_pair_callback), get_local_registration_id: C.SignalGetLocalRegistrationId(C.signal_get_local_registration_id_callback), save_identity: C.SignalSaveIdentityKey(C.signal_save_identity_key_callback), get_identity: C.SignalGetIdentityKey(C.signal_get_identity_key_callback), is_trusted_identity: C.SignalIsTrustedIdentity(C.signal_is_trusted_identity_callback), - } + }} } diff --git a/pkg/libsignalgo/kyberprekey.go b/pkg/libsignalgo/kyberprekey.go index d049d0a..7f9c7b4 100644 --- a/pkg/libsignalgo/kyberprekey.go +++ b/pkg/libsignalgo/kyberprekey.go @@ -1,5 +1,6 @@ // mautrix-signal - A Matrix-signal puppeting bridge. // Copyright (C) 2023 Scott Weber +// Copyright (C) 2025 Tulir Asokan // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU Affero General Public License as published by @@ -52,9 +53,17 @@ func wrapKyberKeyPair(ptr *C.SignalKyberKeyPair) *KyberKeyPair { return kp } +func (kp *KyberKeyPair) mutPtr() C.SignalMutPointerKyberKeyPair { + return C.SignalMutPointerKyberKeyPair{kp.ptr} +} + +func (kp *KyberKeyPair) constPtr() C.SignalConstPointerKyberKeyPair { + return C.SignalConstPointerKyberKeyPair{kp.ptr} +} + func (kp *KyberKeyPair) Destroy() error { kp.CancelFinalizer() - return wrapError(C.signal_kyber_key_pair_destroy(kp.ptr)) + return wrapError(C.signal_kyber_key_pair_destroy(kp.mutPtr())) } func (kp *KyberKeyPair) CancelFinalizer() { @@ -67,9 +76,17 @@ func wrapKyberPublicKey(ptr *C.SignalKyberPublicKey) *KyberPublicKey { return publicKey } +func (k *KyberPublicKey) mutPtr() C.SignalMutPointerKyberPublicKey { + return C.SignalMutPointerKyberPublicKey{k.ptr} +} + +func (k *KyberPublicKey) constPtr() C.SignalConstPointerKyberPublicKey { + return C.SignalConstPointerKyberPublicKey{k.ptr} +} + func (k *KyberPublicKey) Destroy() error { k.CancelFinalizer() - return wrapError(C.signal_publickey_destroy(k.ptr)) + return wrapError(C.signal_kyber_public_key_destroy(k.mutPtr())) } func (k *KyberPublicKey) CancelFinalizer() { @@ -82,9 +99,17 @@ func wrapKyberSecretKey(ptr *C.SignalKyberSecretKey) *KyberSecretKey { return secretKey } +func (k *KyberSecretKey) mutPtr() C.SignalMutPointerKyberSecretKey { + return C.SignalMutPointerKyberSecretKey{k.ptr} +} + +func (k *KyberSecretKey) constPtr() C.SignalConstPointerKyberSecretKey { + return C.SignalConstPointerKyberSecretKey{k.ptr} +} + func (k *KyberSecretKey) Destroy() error { k.CancelFinalizer() - return wrapError(C.signal_kyber_secret_key_destroy(k.ptr)) + return wrapError(C.signal_kyber_secret_key_destroy(k.mutPtr())) } func (k *KyberSecretKey) CancelFinalizer() { @@ -98,18 +123,18 @@ func wrapKyberPreKeyRecord(ptr *C.SignalKyberPreKeyRecord) *KyberPreKeyRecord { } func (kp *KyberKeyPair) GetPublicKey() (*KyberPublicKey, error) { - var pub *C.SignalKyberPublicKey - signalFfiError := C.signal_kyber_key_pair_get_public_key(&pub, kp.ptr) + var pub C.SignalMutPointerKyberPublicKey + signalFfiError := C.signal_kyber_key_pair_get_public_key(&pub, kp.constPtr()) runtime.KeepAlive(kp) if signalFfiError != nil { return nil, wrapError(signalFfiError) } - return wrapKyberPublicKey(pub), nil + return wrapKyberPublicKey(pub.raw), nil } func (kp *KyberPublicKey) Serialize() ([]byte, error) { var serialized C.SignalOwnedBuffer = C.SignalOwnedBuffer{} - signalFfiError := C.signal_kyber_public_key_serialize(&serialized, kp.ptr) + signalFfiError := C.signal_kyber_public_key_serialize(&serialized, kp.constPtr()) runtime.KeepAlive(kp) if signalFfiError != nil { return nil, wrapError(signalFfiError) @@ -118,49 +143,63 @@ func (kp *KyberPublicKey) Serialize() ([]byte, error) { } func DeserializeKyberPublicKey(serialized []byte) (*KyberPublicKey, error) { - var kyberPublicKey *C.SignalKyberPublicKey + var kyberPublicKey C.SignalMutPointerKyberPublicKey signalFfiError := C.signal_kyber_public_key_deserialize(&kyberPublicKey, BytesToBuffer(serialized)) runtime.KeepAlive(serialized) if signalFfiError != nil { return nil, wrapError(signalFfiError) } - return wrapKyberPublicKey(kyberPublicKey), nil + return wrapKyberPublicKey(kyberPublicKey.raw), nil } func NewKyberPreKeyRecord(id uint32, timestamp time.Time, keyPair *KyberKeyPair, signature []byte) (*KyberPreKeyRecord, error) { - var kpkr *C.SignalKyberPreKeyRecord - signalFfiError := C.signal_kyber_pre_key_record_new(&kpkr, C.uint32_t(id), C.uint64_t(timestamp.UnixMilli()), keyPair.ptr, BytesToBuffer(signature)) + var kpkr C.SignalMutPointerKyberPreKeyRecord + signalFfiError := C.signal_kyber_pre_key_record_new( + &kpkr, + C.uint32_t(id), + C.uint64_t(timestamp.UnixMilli()), + keyPair.constPtr(), + BytesToBuffer(signature), + ) runtime.KeepAlive(keyPair) runtime.KeepAlive(signature) if signalFfiError != nil { return nil, wrapError(signalFfiError) } - return wrapKyberPreKeyRecord(kpkr), nil + return wrapKyberPreKeyRecord(kpkr.raw), nil } func DeserializeKyberPreKeyRecord(serialized []byte) (*KyberPreKeyRecord, error) { - var kpkr *C.SignalKyberPreKeyRecord + var kpkr C.SignalMutPointerKyberPreKeyRecord signalFfiError := C.signal_kyber_pre_key_record_deserialize(&kpkr, BytesToBuffer(serialized)) runtime.KeepAlive(serialized) if signalFfiError != nil { return nil, wrapError(signalFfiError) } - return wrapKyberPreKeyRecord(kpkr), nil + return wrapKyberPreKeyRecord(kpkr.raw), nil +} + +func (kpkr *KyberPreKeyRecord) mutPtr() C.SignalMutPointerKyberPreKeyRecord { + return C.SignalMutPointerKyberPreKeyRecord{kpkr.ptr} +} + +func (kpkr *KyberPreKeyRecord) constPtr() C.SignalConstPointerKyberPreKeyRecord { + return C.SignalConstPointerKyberPreKeyRecord{kpkr.ptr} } func (kpkr *KyberPreKeyRecord) Clone() (*KyberPreKeyRecord, error) { - var cloned *C.SignalKyberPreKeyRecord - signalFfiError := C.signal_kyber_pre_key_record_clone(&cloned, kpkr.ptr) + var cloned C.SignalMutPointerKyberPreKeyRecord + signalFfiError := C.signal_kyber_pre_key_record_clone(&cloned, kpkr.constPtr()) runtime.KeepAlive(kpkr) if signalFfiError != nil { return nil, wrapError(signalFfiError) } - return wrapKyberPreKeyRecord(cloned), nil + return wrapKyberPreKeyRecord(cloned.raw), nil } func (kpkr *KyberPreKeyRecord) Destroy() error { kpkr.CancelFinalizer() - return wrapError(C.signal_kyber_pre_key_record_destroy(kpkr.ptr)) + return wrapError(C.signal_kyber_pre_key_record_destroy(kpkr.mutPtr())) } func (kpkr *KyberPreKeyRecord) CancelFinalizer() { @@ -169,7 +208,7 @@ func (kpkr *KyberPreKeyRecord) CancelFinalizer() { func (kpkr *KyberPreKeyRecord) Serialize() ([]byte, error) { var serialized C.SignalOwnedBuffer = C.SignalOwnedBuffer{} - signalFfiError := C.signal_kyber_pre_key_record_serialize(&serialized, kpkr.ptr) + signalFfiError := C.signal_kyber_pre_key_record_serialize(&serialized, kpkr.constPtr()) runtime.KeepAlive(kpkr) if signalFfiError != nil { return nil, wrapError(signalFfiError) @@ -179,7 +218,7 @@ func (kpkr *KyberPreKeyRecord) Serialize() ([]byte, error) { func (kpkr *KyberPreKeyRecord) GetSignature() ([]byte, error) { var signature C.SignalOwnedBuffer = C.SignalOwnedBuffer{} - signalFfiError := C.signal_kyber_pre_key_record_get_signature(&signature, kpkr.ptr) + signalFfiError := C.signal_kyber_pre_key_record_get_signature(&signature, kpkr.constPtr()) runtime.KeepAlive(kpkr) if signalFfiError != nil { return nil, wrapError(signalFfiError) @@ -189,7 +228,7 @@ func (kpkr *KyberPreKeyRecord) GetSignature() ([]byte, error) { func (kpkr *KyberPreKeyRecord) GetID() (uint32, error) { var id C.uint32_t - signalFfiError := C.signal_kyber_pre_key_record_get_id(&id, kpkr.ptr) + signalFfiError := C.signal_kyber_pre_key_record_get_id(&id, kpkr.constPtr()) runtime.KeepAlive(kpkr) if signalFfiError != nil { return 0, wrapError(signalFfiError) @@ -199,7 +238,7 @@ func (kpkr *KyberPreKeyRecord) GetID() (uint32, error) { func (kpkr *KyberPreKeyRecord) GetTimestamp() (time.Time, error) { var ts C.uint64_t - signalFfiError := C.signal_kyber_pre_key_record_get_timestamp(&ts, kpkr.ptr) + signalFfiError := C.signal_kyber_pre_key_record_get_timestamp(&ts, kpkr.constPtr()) runtime.KeepAlive(kpkr) if signalFfiError != nil { return time.Time{}, wrapError(signalFfiError) @@ -208,30 +247,30 @@ func (kpkr *KyberPreKeyRecord) GetTimestamp() (time.Time, error) { } func (kpkr *KyberPreKeyRecord) GetPublicKey() (*KyberPublicKey, error) { - var pub *C.SignalKyberPublicKey - signalFfiError := C.signal_kyber_pre_key_record_get_public_key(&pub, kpkr.ptr) + var pub C.SignalMutPointerKyberPublicKey + signalFfiError := C.signal_kyber_pre_key_record_get_public_key(&pub, kpkr.constPtr()) runtime.KeepAlive(kpkr) if signalFfiError != nil { return nil, wrapError(signalFfiError) } - return wrapKyberPublicKey(pub), nil + return wrapKyberPublicKey(pub.raw), nil } func (kpkr *KyberPreKeyRecord) GetSecretKey() (*KyberSecretKey, error) { - var sec *C.SignalKyberSecretKey - signalFfiError := C.signal_kyber_pre_key_record_get_secret_key(&sec, kpkr.ptr) + var sec C.SignalMutPointerKyberSecretKey + signalFfiError := C.signal_kyber_pre_key_record_get_secret_key(&sec, kpkr.constPtr()) runtime.KeepAlive(kpkr) if signalFfiError != nil { return nil, wrapError(signalFfiError) } - return wrapKyberSecretKey(sec), nil + return wrapKyberSecretKey(sec.raw), nil } func KyberKeyPairGenerate() (*KyberKeyPair, error) { - var kp *C.SignalKyberKeyPair + var kp C.SignalMutPointerKyberKeyPair signalFfiError := C.signal_kyber_key_pair_generate(&kp) if signalFfiError != nil { return nil, wrapError(signalFfiError) } - return wrapKyberKeyPair(kp), nil + return wrapKyberKeyPair(kp.raw), nil } diff --git a/pkg/libsignalgo/kyberprekeystore.go b/pkg/libsignalgo/kyberprekeystore.go index a0204e5..39beed7 100644 --- a/pkg/libsignalgo/kyberprekeystore.go +++ b/pkg/libsignalgo/kyberprekeystore.go @@ -1,5 +1,6 @@ // mautrix-signal - A Matrix-signal puppeting bridge. // Copyright (C) 2023 Scott Weber +// Copyright (C) 2025 Tulir Asokan // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU Affero General Public License as published by @@ -70,11 +71,11 @@ func signal_mark_kyber_pre_key_used_callback(storeCtx unsafe.Pointer, id C.uint3 }) } -func (ctx *CallbackContext) wrapKyberPreKeyStore(store KyberPreKeyStore) *C.SignalKyberPreKeyStore { - return &C.SignalKyberPreKeyStore{ +func (ctx *CallbackContext) wrapKyberPreKeyStore(store KyberPreKeyStore) C.SignalConstPointerFfiKyberPreKeyStoreStruct { + return C.SignalConstPointerFfiKyberPreKeyStoreStruct{&C.SignalKyberPreKeyStore{ ctx: wrapStore(ctx, store), load_kyber_pre_key: C.SignalLoadKyberPreKey(C.signal_load_kyber_pre_key_callback), store_kyber_pre_key: C.SignalStoreKyberPreKey(C.signal_store_kyber_pre_key_callback), mark_kyber_pre_key_used: C.SignalMarkKyberPreKeyUsed(C.signal_mark_kyber_pre_key_used_callback), - } + }} } diff --git a/pkg/libsignalgo/libsignal b/pkg/libsignalgo/libsignal index 4b78ebf..864a1a1 160000 --- a/pkg/libsignalgo/libsignal +++ b/pkg/libsignalgo/libsignal @@ -1 +1 @@ -Subproject commit 4b78ebfeeaec42e1f37c87ecb67b0e480b15f03a +Subproject commit 864a1a1a87d08b30516fdf5734ae426b0508f445 diff --git a/pkg/libsignalgo/libsignal-ffi.h b/pkg/libsignalgo/libsignal-ffi.h index b16aca6..457d343 100644 --- a/pkg/libsignalgo/libsignal-ffi.h +++ b/pkg/libsignalgo/libsignal-ffi.h @@ -224,6 +224,8 @@ typedef struct SignalAes256GcmEncryption SignalAes256GcmEncryption; typedef struct SignalAes256GcmSiv SignalAes256GcmSiv; +typedef struct SignalAuthenticatedChatConnection SignalAuthenticatedChatConnection; + typedef struct SignalCdsiLookup SignalCdsiLookup; typedef struct SignalChatAuthChatService SignalChatAuthChatService; @@ -232,6 +234,11 @@ typedef struct SignalChatUnauthChatService SignalChatUnauthChatService; typedef struct SignalCiphertextMessage SignalCiphertextMessage; +/** + * Information about an established connection. + */ +typedef struct SignalConnectionInfo SignalConnectionInfo; + typedef struct SignalConnectionManager SignalConnectionManager; typedef struct SignalDecryptionErrorMessage SignalDecryptionErrorMessage; @@ -277,9 +284,7 @@ typedef struct SignalProtocolAddress SignalProtocolAddress; typedef struct SignalPublicKey SignalPublicKey; -#if defined(SIGNAL_MEDIA_SUPPORTED) typedef struct SignalSanitizedMetadata SignalSanitizedMetadata; -#endif typedef struct SignalSenderCertificate SignalSenderCertificate; @@ -292,7 +297,7 @@ typedef struct SignalSenderKeyRecord SignalSenderKeyRecord; typedef struct SignalServerCertificate SignalServerCertificate; /** - * Wraps a named type and a single-use guard around [`chat::server_requests::AckEnvelopeFuture`]. + * Wraps a named type and a single-use guard around [`chat::server_requests::ResponseEnvelopeSender`]. */ typedef struct SignalServerMessageAck SignalServerMessageAck; @@ -320,6 +325,8 @@ typedef struct SignalSignedPreKeyRecord SignalSignedPreKeyRecord; typedef struct SignalTokioAsyncContext SignalTokioAsyncContext; +typedef struct SignalUnauthenticatedChatConnection SignalUnauthenticatedChatConnection; + typedef struct SignalUnidentifiedSenderMessageContent SignalUnidentifiedSenderMessageContent; typedef struct SignalValidatingMac SignalValidatingMac; @@ -388,16 +395,44 @@ typedef struct { SignalOwnedBufferOfusize lengths; } SignalBytestringArray; +typedef struct { + SignalProtocolAddress *raw; +} SignalMutPointerProtocolAddress; + typedef SignalBytestringArray SignalStringArray; +typedef struct { + SignalPrivateKey *raw; +} SignalMutPointerPrivateKey; + +typedef struct { + SignalPublicKey *raw; +} SignalMutPointerPublicKey; + typedef struct { const unsigned char *base; size_t length; } SignalBorrowedBuffer; -typedef int (*SignalLoadSession)(void *store_ctx, SignalSessionRecord **recordp, const SignalProtocolAddress *address); +typedef struct { + const SignalPublicKey *raw; +} SignalConstPointerPublicKey; -typedef int (*SignalStoreSession)(void *store_ctx, const SignalProtocolAddress *address, const SignalSessionRecord *record); +typedef struct { + SignalSessionRecord *raw; +} SignalMutPointerSessionRecord; + +typedef struct { + const SignalProtocolAddress *raw; +} SignalConstPointerProtocolAddress; + +typedef int (*SignalLoadSession)(void *store_ctx, SignalMutPointerSessionRecord *recordp, SignalConstPointerProtocolAddress address); + +typedef struct { + const SignalSessionRecord *raw; +} SignalConstPointerSessionRecord; + +typedef int (*SignalStoreSession)(void *store_ctx, SignalConstPointerProtocolAddress address, SignalConstPointerSessionRecord record); typedef struct { void *ctx; @@ -405,15 +440,19 @@ typedef struct { SignalStoreSession store_session; } SignalSessionStore; -typedef int (*SignalGetIdentityKeyPair)(void *store_ctx, SignalPrivateKey **keyp); +typedef struct { + const SignalSessionStore *raw; +} SignalConstPointerFfiSessionStoreStruct; + +typedef int (*SignalGetIdentityKeyPair)(void *store_ctx, SignalMutPointerPrivateKey *keyp); typedef int (*SignalGetLocalRegistrationId)(void *store_ctx, uint32_t *idp); -typedef int (*SignalSaveIdentityKey)(void *store_ctx, const SignalProtocolAddress *address, const SignalPublicKey *public_key); +typedef int (*SignalSaveIdentityKey)(void *store_ctx, SignalConstPointerProtocolAddress address, SignalConstPointerPublicKey public_key); -typedef int (*SignalGetIdentityKey)(void *store_ctx, SignalPublicKey **public_keyp, const SignalProtocolAddress *address); +typedef int (*SignalGetIdentityKey)(void *store_ctx, SignalMutPointerPublicKey *public_keyp, SignalConstPointerProtocolAddress address); -typedef int (*SignalIsTrustedIdentity)(void *store_ctx, const SignalProtocolAddress *address, const SignalPublicKey *public_key, unsigned int direction); +typedef int (*SignalIsTrustedIdentity)(void *store_ctx, SignalConstPointerProtocolAddress address, SignalConstPointerPublicKey public_key, unsigned int direction); typedef struct { void *ctx; @@ -424,9 +463,21 @@ typedef struct { SignalIsTrustedIdentity is_trusted_identity; } SignalIdentityKeyStore; -typedef int (*SignalLoadPreKey)(void *store_ctx, SignalPreKeyRecord **recordp, uint32_t id); +typedef struct { + const SignalIdentityKeyStore *raw; +} SignalConstPointerFfiIdentityKeyStoreStruct; -typedef int (*SignalStorePreKey)(void *store_ctx, uint32_t id, const SignalPreKeyRecord *record); +typedef struct { + SignalPreKeyRecord *raw; +} SignalMutPointerPreKeyRecord; + +typedef int (*SignalLoadPreKey)(void *store_ctx, SignalMutPointerPreKeyRecord *recordp, uint32_t id); + +typedef struct { + const SignalPreKeyRecord *raw; +} SignalConstPointerPreKeyRecord; + +typedef int (*SignalStorePreKey)(void *store_ctx, uint32_t id, SignalConstPointerPreKeyRecord record); typedef int (*SignalRemovePreKey)(void *store_ctx, uint32_t id); @@ -437,9 +488,21 @@ typedef struct { SignalRemovePreKey remove_pre_key; } SignalPreKeyStore; -typedef int (*SignalLoadSignedPreKey)(void *store_ctx, SignalSignedPreKeyRecord **recordp, uint32_t id); +typedef struct { + const SignalPreKeyStore *raw; +} SignalConstPointerFfiPreKeyStoreStruct; -typedef int (*SignalStoreSignedPreKey)(void *store_ctx, uint32_t id, const SignalSignedPreKeyRecord *record); +typedef struct { + SignalSignedPreKeyRecord *raw; +} SignalMutPointerSignedPreKeyRecord; + +typedef int (*SignalLoadSignedPreKey)(void *store_ctx, SignalMutPointerSignedPreKeyRecord *recordp, uint32_t id); + +typedef struct { + const SignalSignedPreKeyRecord *raw; +} SignalConstPointerSignedPreKeyRecord; + +typedef int (*SignalStoreSignedPreKey)(void *store_ctx, uint32_t id, SignalConstPointerSignedPreKeyRecord record); typedef struct { void *ctx; @@ -447,6 +510,10 @@ typedef struct { SignalStoreSignedPreKey store_signed_pre_key; } SignalSignedPreKeyStore; +typedef struct { + const SignalSignedPreKeyStore *raw; +} SignalConstPointerFfiSignedPreKeyStoreStruct; + typedef void (*SignalLogCallback)(void *ctx, SignalLogLevel level, const char *file, uint32_t line, const char *message); typedef void (*SignalLogFlushCallback)(void *ctx); @@ -457,15 +524,159 @@ typedef struct { SignalLogFlushCallback flush; } SignalFfiLogger; +typedef struct { + SignalAes256GcmSiv *raw; +} SignalMutPointerAes256GcmSiv; + +typedef struct { + SignalAes256Ctr32 *raw; +} SignalMutPointerAes256Ctr32; + +typedef struct { + SignalAes256GcmEncryption *raw; +} SignalMutPointerAes256GcmEncryption; + +typedef struct { + SignalAes256GcmDecryption *raw; +} SignalMutPointerAes256GcmDecryption; + typedef struct { unsigned char *base; size_t length; } SignalBorrowedMutableBuffer; +typedef struct { + const SignalAes256GcmSiv *raw; +} SignalConstPointerAes256GcmSiv; + +typedef struct { + SignalCiphertextMessage *raw; +} SignalMutPointerCiphertextMessage; + +typedef struct { + SignalDecryptionErrorMessage *raw; +} SignalMutPointerDecryptionErrorMessage; + +typedef struct { + const SignalDecryptionErrorMessage *raw; +} SignalConstPointerDecryptionErrorMessage; + +typedef struct { + SignalFingerprint *raw; +} SignalMutPointerFingerprint; + +typedef struct { + const SignalFingerprint *raw; +} SignalConstPointerFingerprint; + +typedef struct { + SignalPlaintextContent *raw; +} SignalMutPointerPlaintextContent; + +typedef struct { + const SignalPlaintextContent *raw; +} SignalConstPointerPlaintextContent; + +typedef struct { + SignalPreKeyBundle *raw; +} SignalMutPointerPreKeyBundle; + +typedef struct { + const SignalPreKeyBundle *raw; +} SignalConstPointerPreKeyBundle; + +typedef struct { + SignalPreKeySignalMessage *raw; +} SignalMutPointerPreKeySignalMessage; + +typedef struct { + const SignalPreKeySignalMessage *raw; +} SignalConstPointerPreKeySignalMessage; + +typedef struct { + const SignalPrivateKey *raw; +} SignalConstPointerPrivateKey; + +typedef struct { + SignalSenderCertificate *raw; +} SignalMutPointerSenderCertificate; + +typedef struct { + const SignalSenderCertificate *raw; +} SignalConstPointerSenderCertificate; + +typedef struct { + SignalSenderKeyDistributionMessage *raw; +} SignalMutPointerSenderKeyDistributionMessage; + +typedef struct { + const SignalSenderKeyDistributionMessage *raw; +} SignalConstPointerSenderKeyDistributionMessage; + +typedef struct { + SignalSenderKeyMessage *raw; +} SignalMutPointerSenderKeyMessage; + +typedef struct { + const SignalSenderKeyMessage *raw; +} SignalConstPointerSenderKeyMessage; + +typedef struct { + SignalSenderKeyRecord *raw; +} SignalMutPointerSenderKeyRecord; + +typedef struct { + const SignalSenderKeyRecord *raw; +} SignalConstPointerSenderKeyRecord; + +typedef struct { + SignalServerCertificate *raw; +} SignalMutPointerServerCertificate; + +typedef struct { + const SignalServerCertificate *raw; +} SignalConstPointerServerCertificate; + +typedef struct { + SignalMessage *raw; +} SignalMutPointerSignalMessage; + +typedef struct { + const SignalMessage *raw; +} SignalConstPointerSignalMessage; + +typedef struct { + SignalKyberPreKeyRecord *raw; +} SignalMutPointerKyberPreKeyRecord; + +typedef struct { + const SignalKyberPreKeyRecord *raw; +} SignalConstPointerKyberPreKeyRecord; + +typedef struct { + SignalUnidentifiedSenderMessageContent *raw; +} SignalMutPointerUnidentifiedSenderMessageContent; + typedef SignalKeyPair SignalKyberKeyPair; +typedef struct { + SignalKyberKeyPair *raw; +} SignalMutPointerKyberKeyPair; + +typedef struct { + const SignalKyberKeyPair *raw; +} SignalConstPointerKyberKeyPair; + typedef SignalPublicKey SignalKyberPublicKey; +typedef struct { + SignalKyberPublicKey *raw; +} SignalMutPointerKyberPublicKey; + +typedef struct { + const SignalKyberPublicKey *raw; +} SignalConstPointerKyberPublicKey; + /** * A KEM secret key with the ability to decapsulate a shared secret. */ @@ -473,6 +684,14 @@ typedef SignalKeySecret SignalSecretKey; typedef SignalSecretKey SignalKyberSecretKey; +typedef struct { + SignalKyberSecretKey *raw; +} SignalMutPointerKyberSecretKey; + +typedef struct { + const SignalKyberSecretKey *raw; +} SignalConstPointerKyberSecretKey; + /** * The fixed-width binary representation of a ServiceId. * @@ -480,9 +699,17 @@ typedef SignalSecretKey SignalKyberSecretKey; */ typedef uint8_t SignalServiceIdFixedWidthBinaryBytes[17]; -typedef int (*SignalLoadKyberPreKey)(void *store_ctx, SignalKyberPreKeyRecord **recordp, uint32_t id); +typedef struct { + const SignalUnidentifiedSenderMessageContent *raw; +} SignalConstPointerUnidentifiedSenderMessageContent; -typedef int (*SignalStoreKyberPreKey)(void *store_ctx, uint32_t id, const SignalKyberPreKeyRecord *record); +typedef struct { + const SignalCiphertextMessage *raw; +} SignalConstPointerCiphertextMessage; + +typedef int (*SignalLoadKyberPreKey)(void *store_ctx, SignalMutPointerKyberPreKeyRecord *recordp, uint32_t id); + +typedef int (*SignalStoreKyberPreKey)(void *store_ctx, uint32_t id, SignalConstPointerKyberPreKeyRecord record); typedef int (*SignalMarkKyberPreKeyUsed)(void *store_ctx, uint32_t id); @@ -494,18 +721,22 @@ typedef struct { } SignalKyberPreKeyStore; typedef struct { - const SignalProtocolAddress *const *base; - size_t length; -} SignalBorrowedSliceOfProtocolAddress; + const SignalKyberPreKeyStore *raw; +} SignalConstPointerFfiKyberPreKeyStoreStruct; typedef struct { - const SignalSessionRecord *const *base; + const SignalConstPointerProtocolAddress *base; size_t length; -} SignalBorrowedSliceOfSessionRecord; +} SignalBorrowedSliceOfConstPointerProtocolAddress; -typedef int (*SignalLoadSenderKey)(void *store_ctx, SignalSenderKeyRecord**, const SignalProtocolAddress*, const uint8_t (*distribution_id)[16]); +typedef struct { + const SignalConstPointerSessionRecord *base; + size_t length; +} SignalBorrowedSliceOfConstPointerSessionRecord; -typedef int (*SignalStoreSenderKey)(void *store_ctx, const SignalProtocolAddress*, const uint8_t (*distribution_id)[16], const SignalSenderKeyRecord*); +typedef int (*SignalLoadSenderKey)(void *store_ctx, SignalMutPointerSenderKeyRecord*, SignalConstPointerProtocolAddress, const uint8_t (*distribution_id)[16]); + +typedef int (*SignalStoreSenderKey)(void *store_ctx, SignalConstPointerProtocolAddress, const uint8_t (*distribution_id)[16], SignalConstPointerSenderKeyRecord); typedef struct { void *ctx; @@ -513,11 +744,71 @@ typedef struct { SignalStoreSenderKey store_sender_key; } SignalSenderKeyStore; +typedef struct { + const SignalSenderKeyStore *raw; +} SignalConstPointerFfiSenderKeyStoreStruct; + +typedef struct { + SignalSgxClientState *raw; +} SignalMutPointerSgxClientState; + +typedef struct { + SignalHsmEnclaveClient *raw; +} SignalMutPointerHsmEnclaveClient; + +typedef struct { + const SignalHsmEnclaveClient *raw; +} SignalConstPointerHsmEnclaveClient; + +typedef struct { + const SignalSgxClientState *raw; +} SignalConstPointerSgxClientState; + +typedef struct { + SignalServerPublicParams *raw; +} SignalMutPointerServerPublicParams; + +typedef struct { + const SignalServerPublicParams *raw; +} SignalConstPointerServerPublicParams; + +typedef struct { + SignalServerSecretParams *raw; +} SignalMutPointerServerSecretParams; + +typedef struct { + const SignalServerSecretParams *raw; +} SignalConstPointerServerSecretParams; + typedef struct { const SignalBorrowedBuffer *base; size_t length; } SignalBorrowedSliceOfBuffers; +typedef struct { + SignalConnectionInfo *raw; +} SignalMutPointerConnectionInfo; + +typedef struct { + SignalConnectionManager *raw; +} SignalMutPointerConnectionManager; + +typedef struct { + const SignalConnectionManager *raw; +} SignalConstPointerConnectionManager; + +typedef struct { + SignalLookupRequest *raw; +} SignalMutPointerLookupRequest; + +typedef struct { + const SignalLookupRequest *raw; +} SignalConstPointerLookupRequest; + +typedef struct { + SignalCdsiLookup *raw; +} SignalMutPointerCdsiLookup; + typedef uint64_t SignalCancellationId; /** @@ -530,40 +821,18 @@ typedef uint64_t SignalCancellationId; * completed once. */ typedef struct { - void (*complete)(SignalFfiError *error, const SignalOwnedBuffer *result, const void *context); + void (*complete)(SignalFfiError *error, const SignalMutPointerCdsiLookup *result, const void *context); const void *context; SignalCancellationId cancellation_id; -} SignalCPromiseOwnedBufferOfc_uchar; +} SignalCPromiseMutPointerCdsiLookup; -/** - * A C callback used to report the results of Rust futures. - * - * cbindgen will produce independent C types like `SignalCPromisei32` and - * `SignalCPromiseProtocolAddress`. - * - * This derives Copy because it behaves like a C type; nevertheless, a promise should still only be - * completed once. - */ typedef struct { - void (*complete)(SignalFfiError *error, const bool *result, const void *context); - const void *context; - SignalCancellationId cancellation_id; -} SignalCPromisebool; + const SignalTokioAsyncContext *raw; +} SignalConstPointerTokioAsyncContext; -/** - * A C callback used to report the results of Rust futures. - * - * cbindgen will produce independent C types like `SignalCPromisei32` and - * `SignalCPromiseProtocolAddress`. - * - * This derives Copy because it behaves like a C type; nevertheless, a promise should still only be - * completed once. - */ typedef struct { - void (*complete)(SignalFfiError *error, SignalCdsiLookup *const *result, const void *context); - const void *context; - SignalCancellationId cancellation_id; -} SignalCPromiseCdsiLookup; + const SignalCdsiLookup *raw; +} SignalConstPointerCdsiLookup; typedef struct { SignalOwnedBufferOfFfiCdsiLookupResponseEntry entries; @@ -587,13 +856,37 @@ typedef struct { typedef SignalChatAuthChatService SignalAuthChat; +typedef struct { + SignalAuthChat *raw; +} SignalMutPointerAuthChat; + typedef SignalChatUnauthChatService SignalUnauthChat; typedef struct { - uint8_t raw_ip_type; - double duration_secs; - const char *connection_info; -} SignalFfiChatServiceDebugInfo; + SignalUnauthChat *raw; +} SignalMutPointerUnauthChat; + +typedef struct { + SignalHttpRequest *raw; +} SignalMutPointerHttpRequest; + +typedef struct { + SignalUnauthenticatedChatConnection *raw; +} SignalMutPointerUnauthenticatedChatConnection; + +typedef struct { + SignalAuthenticatedChatConnection *raw; +} SignalMutPointerAuthenticatedChatConnection; + +typedef struct { + const SignalHttpRequest *raw; +} SignalConstPointerHttpRequest; + +typedef SignalConnectionInfo SignalChatConnectionInfo; + +typedef struct { + const SignalChatConnectionInfo *raw; +} SignalConstPointerChatConnectionInfo; /** * A C callback used to report the results of Rust futures. @@ -605,52 +898,14 @@ typedef struct { * completed once. */ typedef struct { - void (*complete)(SignalFfiError *error, const SignalFfiChatServiceDebugInfo *result, const void *context); + void (*complete)(SignalFfiError *error, const SignalMutPointerUnauthenticatedChatConnection *result, const void *context); const void *context; SignalCancellationId cancellation_id; -} SignalCPromiseFfiChatServiceDebugInfo; +} SignalCPromiseMutPointerUnauthenticatedChatConnection; typedef struct { - uint16_t status; - const char *message; - SignalOwnedBufferOfCStringPtr headers; - SignalOwnedBuffer body; -} SignalFfiChatResponse; - -/** - * A C callback used to report the results of Rust futures. - * - * cbindgen will produce independent C types like `SignalCPromisei32` and - * `SignalCPromiseProtocolAddress`. - * - * This derives Copy because it behaves like a C type; nevertheless, a promise should still only be - * completed once. - */ -typedef struct { - void (*complete)(SignalFfiError *error, const SignalFfiChatResponse *result, const void *context); - const void *context; - SignalCancellationId cancellation_id; -} SignalCPromiseFfiChatResponse; - -typedef struct { - SignalFfiChatResponse response; - SignalFfiChatServiceDebugInfo debug_info; -} SignalFfiResponseAndDebugInfo; - -/** - * A C callback used to report the results of Rust futures. - * - * cbindgen will produce independent C types like `SignalCPromisei32` and - * `SignalCPromiseProtocolAddress`. - * - * This derives Copy because it behaves like a C type; nevertheless, a promise should still only be - * completed once. - */ -typedef struct { - void (*complete)(SignalFfiError *error, const SignalFfiResponseAndDebugInfo *result, const void *context); - const void *context; - SignalCancellationId cancellation_id; -} SignalCPromiseFfiResponseAndDebugInfo; + const SignalUnauthenticatedChatConnection *raw; +} SignalConstPointerUnauthenticatedChatConnection; typedef void (*SignalReceivedIncomingMessage)(void *ctx, SignalOwnedBuffer envelope, uint64_t timestamp_millis, SignalServerMessageAck *cleanup); @@ -683,6 +938,163 @@ typedef struct { SignalDestroyChatListener destroy; } SignalFfiChatListenerStruct; +typedef struct { + const SignalFfiChatListenerStruct *raw; +} SignalConstPointerFfiChatListenerStruct; + +typedef struct { + uint16_t status; + const char *message; + SignalOwnedBufferOfCStringPtr headers; + SignalOwnedBuffer body; +} SignalFfiChatResponse; + +/** + * A C callback used to report the results of Rust futures. + * + * cbindgen will produce independent C types like `SignalCPromisei32` and + * `SignalCPromiseProtocolAddress`. + * + * This derives Copy because it behaves like a C type; nevertheless, a promise should still only be + * completed once. + */ +typedef struct { + void (*complete)(SignalFfiError *error, const SignalFfiChatResponse *result, const void *context); + const void *context; + SignalCancellationId cancellation_id; +} SignalCPromiseFfiChatResponse; + +/** + * A C callback used to report the results of Rust futures. + * + * cbindgen will produce independent C types like `SignalCPromisei32` and + * `SignalCPromiseProtocolAddress`. + * + * This derives Copy because it behaves like a C type; nevertheless, a promise should still only be + * completed once. + */ +typedef struct { + void (*complete)(SignalFfiError *error, const bool *result, const void *context); + const void *context; + SignalCancellationId cancellation_id; +} SignalCPromisebool; + +typedef struct { + SignalChatConnectionInfo *raw; +} SignalMutPointerChatConnectionInfo; + +/** + * A C callback used to report the results of Rust futures. + * + * cbindgen will produce independent C types like `SignalCPromisei32` and + * `SignalCPromiseProtocolAddress`. + * + * This derives Copy because it behaves like a C type; nevertheless, a promise should still only be + * completed once. + */ +typedef struct { + void (*complete)(SignalFfiError *error, const SignalMutPointerAuthenticatedChatConnection *result, const void *context); + const void *context; + SignalCancellationId cancellation_id; +} SignalCPromiseMutPointerAuthenticatedChatConnection; + +typedef struct { + const SignalAuthenticatedChatConnection *raw; +} SignalConstPointerAuthenticatedChatConnection; + +typedef struct { + const SignalUnauthChat *raw; +} SignalConstPointerUnauthChat; + +typedef struct { + const SignalAuthChat *raw; +} SignalConstPointerAuthChat; + +typedef struct { + uint8_t raw_ip_type; + double duration_secs; + const char *connection_info; +} SignalFfiChatServiceDebugInfo; + +/** + * A C callback used to report the results of Rust futures. + * + * cbindgen will produce independent C types like `SignalCPromisei32` and + * `SignalCPromiseProtocolAddress`. + * + * This derives Copy because it behaves like a C type; nevertheless, a promise should still only be + * completed once. + */ +typedef struct { + void (*complete)(SignalFfiError *error, const SignalFfiChatServiceDebugInfo *result, const void *context); + const void *context; + SignalCancellationId cancellation_id; +} SignalCPromiseFfiChatServiceDebugInfo; + +typedef struct { + SignalFfiChatResponse response; + SignalFfiChatServiceDebugInfo debug_info; +} SignalFfiResponseAndDebugInfo; + +/** + * A C callback used to report the results of Rust futures. + * + * cbindgen will produce independent C types like `SignalCPromisei32` and + * `SignalCPromiseProtocolAddress`. + * + * This derives Copy because it behaves like a C type; nevertheless, a promise should still only be + * completed once. + */ +typedef struct { + void (*complete)(SignalFfiError *error, const SignalFfiResponseAndDebugInfo *result, const void *context); + const void *context; + SignalCancellationId cancellation_id; +} SignalCPromiseFfiResponseAndDebugInfo; + +typedef struct { + SignalServerMessageAck *raw; +} SignalMutPointerServerMessageAck; + +typedef struct { + const SignalServerMessageAck *raw; +} SignalConstPointerServerMessageAck; + +typedef struct { + SignalTokioAsyncContext *raw; +} SignalMutPointerTokioAsyncContext; + +typedef struct { + SignalPinHash *raw; +} SignalMutPointerPinHash; + +typedef struct { + const SignalPinHash *raw; +} SignalConstPointerPinHash; + +typedef struct { + SignalIncrementalMac *raw; +} SignalMutPointerIncrementalMac; + +typedef struct { + SignalValidatingMac *raw; +} SignalMutPointerValidatingMac; + +typedef struct { + SignalMessageBackupKey *raw; +} SignalMutPointerMessageBackupKey; + +typedef struct { + SignalMessageBackupValidationOutcome *raw; +} SignalMutPointerMessageBackupValidationOutcome; + +typedef struct { + const SignalMessageBackupKey *raw; +} SignalConstPointerMessageBackupKey; + +typedef struct { + const SignalMessageBackupValidationOutcome *raw; +} SignalConstPointerMessageBackupValidationOutcome; + typedef int (*SignalRead)(void *ctx, uint8_t *buf, size_t buf_len, size_t *amount_read); typedef int (*SignalSkip)(void *ctx, uint64_t amount); @@ -693,8 +1105,28 @@ typedef struct { SignalSkip skip; } SignalInputStream; +typedef struct { + const SignalInputStream *raw; +} SignalConstPointerFfiInputStreamStruct; + +typedef struct { + SignalOnlineBackupValidator *raw; +} SignalMutPointerOnlineBackupValidator; + +typedef struct { + SignalSanitizedMetadata *raw; +} SignalMutPointerSanitizedMetadata; + +typedef struct { + const SignalSanitizedMetadata *raw; +} SignalConstPointerSanitizedMetadata; + typedef SignalInputStream SignalSyncInputStream; +typedef struct { + const SignalSyncInputStream *raw; +} SignalConstPointerFfiSyncInputStreamStruct; + typedef uint8_t SignalRandomnessBytes[SignalRANDOMNESS_LEN]; void signal_print_ptr(const void *p); @@ -711,7 +1143,7 @@ void signal_free_bytestring_array(SignalBytestringArray array); SignalFfiError *signal_error_get_message(const SignalFfiError *err, const char **out); -SignalFfiError *signal_error_get_address(const SignalFfiError *err, SignalProtocolAddress **out); +SignalFfiError *signal_error_get_address(const SignalFfiError *err, SignalMutPointerProtocolAddress *out); SignalFfiError *signal_error_get_uuid(const SignalFfiError *err, uint8_t (*out)[16]); @@ -725,129 +1157,129 @@ SignalFfiError *signal_error_get_unknown_fields(const SignalFfiError *err, Signa void signal_error_free(SignalFfiError *err); -SignalFfiError *signal_identitykeypair_deserialize(SignalPrivateKey **private_key, SignalPublicKey **public_key, SignalBorrowedBuffer input); +SignalFfiError *signal_identitykeypair_deserialize(SignalMutPointerPrivateKey *private_key, SignalMutPointerPublicKey *public_key, SignalBorrowedBuffer input); -SignalFfiError *signal_sealed_session_cipher_decrypt(SignalOwnedBuffer *out, const char **sender_e164, const char **sender_uuid, uint32_t *sender_device_id, SignalBorrowedBuffer ctext, const SignalPublicKey *trust_root, uint64_t timestamp, const char *local_e164, const char *local_uuid, unsigned int local_device_id, const SignalSessionStore *session_store, const SignalIdentityKeyStore *identity_store, const SignalPreKeyStore *prekey_store, const SignalSignedPreKeyStore *signed_prekey_store); +SignalFfiError *signal_sealed_session_cipher_decrypt(SignalOwnedBuffer *out, const char **sender_e164, const char **sender_uuid, uint32_t *sender_device_id, SignalBorrowedBuffer ctext, SignalConstPointerPublicKey trust_root, uint64_t timestamp, const char *local_e164, const char *local_uuid, unsigned int local_device_id, SignalConstPointerFfiSessionStoreStruct session_store, SignalConstPointerFfiIdentityKeyStoreStruct identity_store, SignalConstPointerFfiPreKeyStoreStruct prekey_store, SignalConstPointerFfiSignedPreKeyStoreStruct signed_prekey_store); bool signal_init_logger(SignalLogLevel max_level, SignalFfiLogger logger); -SignalFfiError *signal_aes256_gcm_siv_destroy(SignalAes256GcmSiv *p); +SignalFfiError *signal_aes256_gcm_siv_destroy(SignalMutPointerAes256GcmSiv p); -SignalFfiError *signal_aes256_ctr32_destroy(SignalAes256Ctr32 *p); +SignalFfiError *signal_aes256_ctr32_destroy(SignalMutPointerAes256Ctr32 p); -SignalFfiError *signal_aes256_gcm_encryption_destroy(SignalAes256GcmEncryption *p); +SignalFfiError *signal_aes256_gcm_encryption_destroy(SignalMutPointerAes256GcmEncryption p); -SignalFfiError *signal_aes256_gcm_decryption_destroy(SignalAes256GcmDecryption *p); +SignalFfiError *signal_aes256_gcm_decryption_destroy(SignalMutPointerAes256GcmDecryption p); -SignalFfiError *signal_aes256_ctr32_new(SignalAes256Ctr32 **out, SignalBorrowedBuffer key, SignalBorrowedBuffer nonce, uint32_t initial_ctr); +SignalFfiError *signal_aes256_ctr32_new(SignalMutPointerAes256Ctr32 *out, SignalBorrowedBuffer key, SignalBorrowedBuffer nonce, uint32_t initial_ctr); -SignalFfiError *signal_aes256_ctr32_process(SignalAes256Ctr32 *ctr, SignalBorrowedMutableBuffer data, uint32_t offset, uint32_t length); +SignalFfiError *signal_aes256_ctr32_process(SignalMutPointerAes256Ctr32 ctr, SignalBorrowedMutableBuffer data, uint32_t offset, uint32_t length); -SignalFfiError *signal_aes256_gcm_encryption_new(SignalAes256GcmEncryption **out, SignalBorrowedBuffer key, SignalBorrowedBuffer nonce, SignalBorrowedBuffer associated_data); +SignalFfiError *signal_aes256_gcm_encryption_new(SignalMutPointerAes256GcmEncryption *out, SignalBorrowedBuffer key, SignalBorrowedBuffer nonce, SignalBorrowedBuffer associated_data); -SignalFfiError *signal_aes256_gcm_encryption_update(SignalAes256GcmEncryption *gcm, SignalBorrowedMutableBuffer data, uint32_t offset, uint32_t length); +SignalFfiError *signal_aes256_gcm_encryption_update(SignalMutPointerAes256GcmEncryption gcm, SignalBorrowedMutableBuffer data, uint32_t offset, uint32_t length); -SignalFfiError *signal_aes256_gcm_encryption_compute_tag(SignalOwnedBuffer *out, SignalAes256GcmEncryption *gcm); +SignalFfiError *signal_aes256_gcm_encryption_compute_tag(SignalOwnedBuffer *out, SignalMutPointerAes256GcmEncryption gcm); -SignalFfiError *signal_aes256_gcm_decryption_new(SignalAes256GcmDecryption **out, SignalBorrowedBuffer key, SignalBorrowedBuffer nonce, SignalBorrowedBuffer associated_data); +SignalFfiError *signal_aes256_gcm_decryption_new(SignalMutPointerAes256GcmDecryption *out, SignalBorrowedBuffer key, SignalBorrowedBuffer nonce, SignalBorrowedBuffer associated_data); -SignalFfiError *signal_aes256_gcm_decryption_update(SignalAes256GcmDecryption *gcm, SignalBorrowedMutableBuffer data, uint32_t offset, uint32_t length); +SignalFfiError *signal_aes256_gcm_decryption_update(SignalMutPointerAes256GcmDecryption gcm, SignalBorrowedMutableBuffer data, uint32_t offset, uint32_t length); -SignalFfiError *signal_aes256_gcm_decryption_verify_tag(bool *out, SignalAes256GcmDecryption *gcm, SignalBorrowedBuffer tag); +SignalFfiError *signal_aes256_gcm_decryption_verify_tag(bool *out, SignalMutPointerAes256GcmDecryption gcm, SignalBorrowedBuffer tag); -SignalFfiError *signal_aes256_gcm_siv_new(SignalAes256GcmSiv **out, SignalBorrowedBuffer key); +SignalFfiError *signal_aes256_gcm_siv_new(SignalMutPointerAes256GcmSiv *out, SignalBorrowedBuffer key); -SignalFfiError *signal_aes256_gcm_siv_encrypt(SignalOwnedBuffer *out, const SignalAes256GcmSiv *aes_gcm_siv_obj, SignalBorrowedBuffer ptext, SignalBorrowedBuffer nonce, SignalBorrowedBuffer associated_data); +SignalFfiError *signal_aes256_gcm_siv_encrypt(SignalOwnedBuffer *out, SignalConstPointerAes256GcmSiv aes_gcm_siv_obj, SignalBorrowedBuffer ptext, SignalBorrowedBuffer nonce, SignalBorrowedBuffer associated_data); -SignalFfiError *signal_aes256_gcm_siv_decrypt(SignalOwnedBuffer *out, const SignalAes256GcmSiv *aes_gcm_siv, SignalBorrowedBuffer ctext, SignalBorrowedBuffer nonce, SignalBorrowedBuffer associated_data); +SignalFfiError *signal_aes256_gcm_siv_decrypt(SignalOwnedBuffer *out, SignalConstPointerAes256GcmSiv aes_gcm_siv, SignalBorrowedBuffer ctext, SignalBorrowedBuffer nonce, SignalBorrowedBuffer associated_data); -SignalFfiError *signal_ciphertext_message_destroy(SignalCiphertextMessage *p); +SignalFfiError *signal_ciphertext_message_destroy(SignalMutPointerCiphertextMessage p); -SignalFfiError *signal_decryption_error_message_destroy(SignalDecryptionErrorMessage *p); +SignalFfiError *signal_decryption_error_message_destroy(SignalMutPointerDecryptionErrorMessage p); -SignalFfiError *signal_decryption_error_message_clone(SignalDecryptionErrorMessage **new_obj, const SignalDecryptionErrorMessage *obj); +SignalFfiError *signal_decryption_error_message_clone(SignalMutPointerDecryptionErrorMessage *new_obj, SignalConstPointerDecryptionErrorMessage obj); -SignalFfiError *signal_fingerprint_destroy(SignalFingerprint *p); +SignalFfiError *signal_fingerprint_destroy(SignalMutPointerFingerprint p); -SignalFfiError *signal_fingerprint_clone(SignalFingerprint **new_obj, const SignalFingerprint *obj); +SignalFfiError *signal_fingerprint_clone(SignalMutPointerFingerprint *new_obj, SignalConstPointerFingerprint obj); -SignalFfiError *signal_plaintext_content_destroy(SignalPlaintextContent *p); +SignalFfiError *signal_plaintext_content_destroy(SignalMutPointerPlaintextContent p); -SignalFfiError *signal_plaintext_content_clone(SignalPlaintextContent **new_obj, const SignalPlaintextContent *obj); +SignalFfiError *signal_plaintext_content_clone(SignalMutPointerPlaintextContent *new_obj, SignalConstPointerPlaintextContent obj); -SignalFfiError *signal_pre_key_bundle_destroy(SignalPreKeyBundle *p); +SignalFfiError *signal_pre_key_bundle_destroy(SignalMutPointerPreKeyBundle p); -SignalFfiError *signal_pre_key_bundle_clone(SignalPreKeyBundle **new_obj, const SignalPreKeyBundle *obj); +SignalFfiError *signal_pre_key_bundle_clone(SignalMutPointerPreKeyBundle *new_obj, SignalConstPointerPreKeyBundle obj); -SignalFfiError *signal_pre_key_record_destroy(SignalPreKeyRecord *p); +SignalFfiError *signal_pre_key_record_destroy(SignalMutPointerPreKeyRecord p); -SignalFfiError *signal_pre_key_record_clone(SignalPreKeyRecord **new_obj, const SignalPreKeyRecord *obj); +SignalFfiError *signal_pre_key_record_clone(SignalMutPointerPreKeyRecord *new_obj, SignalConstPointerPreKeyRecord obj); -SignalFfiError *signal_pre_key_signal_message_destroy(SignalPreKeySignalMessage *p); +SignalFfiError *signal_pre_key_signal_message_destroy(SignalMutPointerPreKeySignalMessage p); -SignalFfiError *signal_pre_key_signal_message_clone(SignalPreKeySignalMessage **new_obj, const SignalPreKeySignalMessage *obj); +SignalFfiError *signal_pre_key_signal_message_clone(SignalMutPointerPreKeySignalMessage *new_obj, SignalConstPointerPreKeySignalMessage obj); -SignalFfiError *signal_privatekey_destroy(SignalPrivateKey *p); +SignalFfiError *signal_privatekey_destroy(SignalMutPointerPrivateKey p); -SignalFfiError *signal_privatekey_clone(SignalPrivateKey **new_obj, const SignalPrivateKey *obj); +SignalFfiError *signal_privatekey_clone(SignalMutPointerPrivateKey *new_obj, SignalConstPointerPrivateKey obj); -SignalFfiError *signal_address_destroy(SignalProtocolAddress *p); +SignalFfiError *signal_address_destroy(SignalMutPointerProtocolAddress p); -SignalFfiError *signal_address_clone(SignalProtocolAddress **new_obj, const SignalProtocolAddress *obj); +SignalFfiError *signal_address_clone(SignalMutPointerProtocolAddress *new_obj, SignalConstPointerProtocolAddress obj); -SignalFfiError *signal_publickey_destroy(SignalPublicKey *p); +SignalFfiError *signal_publickey_destroy(SignalMutPointerPublicKey p); -SignalFfiError *signal_publickey_clone(SignalPublicKey **new_obj, const SignalPublicKey *obj); +SignalFfiError *signal_publickey_clone(SignalMutPointerPublicKey *new_obj, SignalConstPointerPublicKey obj); -SignalFfiError *signal_sender_certificate_destroy(SignalSenderCertificate *p); +SignalFfiError *signal_sender_certificate_destroy(SignalMutPointerSenderCertificate p); -SignalFfiError *signal_sender_certificate_clone(SignalSenderCertificate **new_obj, const SignalSenderCertificate *obj); +SignalFfiError *signal_sender_certificate_clone(SignalMutPointerSenderCertificate *new_obj, SignalConstPointerSenderCertificate obj); -SignalFfiError *signal_sender_key_distribution_message_destroy(SignalSenderKeyDistributionMessage *p); +SignalFfiError *signal_sender_key_distribution_message_destroy(SignalMutPointerSenderKeyDistributionMessage p); -SignalFfiError *signal_sender_key_distribution_message_clone(SignalSenderKeyDistributionMessage **new_obj, const SignalSenderKeyDistributionMessage *obj); +SignalFfiError *signal_sender_key_distribution_message_clone(SignalMutPointerSenderKeyDistributionMessage *new_obj, SignalConstPointerSenderKeyDistributionMessage obj); -SignalFfiError *signal_sender_key_message_destroy(SignalSenderKeyMessage *p); +SignalFfiError *signal_sender_key_message_destroy(SignalMutPointerSenderKeyMessage p); -SignalFfiError *signal_sender_key_message_clone(SignalSenderKeyMessage **new_obj, const SignalSenderKeyMessage *obj); +SignalFfiError *signal_sender_key_message_clone(SignalMutPointerSenderKeyMessage *new_obj, SignalConstPointerSenderKeyMessage obj); -SignalFfiError *signal_sender_key_record_destroy(SignalSenderKeyRecord *p); +SignalFfiError *signal_sender_key_record_destroy(SignalMutPointerSenderKeyRecord p); -SignalFfiError *signal_sender_key_record_clone(SignalSenderKeyRecord **new_obj, const SignalSenderKeyRecord *obj); +SignalFfiError *signal_sender_key_record_clone(SignalMutPointerSenderKeyRecord *new_obj, SignalConstPointerSenderKeyRecord obj); -SignalFfiError *signal_server_certificate_destroy(SignalServerCertificate *p); +SignalFfiError *signal_server_certificate_destroy(SignalMutPointerServerCertificate p); -SignalFfiError *signal_server_certificate_clone(SignalServerCertificate **new_obj, const SignalServerCertificate *obj); +SignalFfiError *signal_server_certificate_clone(SignalMutPointerServerCertificate *new_obj, SignalConstPointerServerCertificate obj); -SignalFfiError *signal_session_record_destroy(SignalSessionRecord *p); +SignalFfiError *signal_session_record_destroy(SignalMutPointerSessionRecord p); -SignalFfiError *signal_session_record_clone(SignalSessionRecord **new_obj, const SignalSessionRecord *obj); +SignalFfiError *signal_session_record_clone(SignalMutPointerSessionRecord *new_obj, SignalConstPointerSessionRecord obj); -SignalFfiError *signal_message_destroy(SignalMessage *p); +SignalFfiError *signal_message_destroy(SignalMutPointerSignalMessage p); -SignalFfiError *signal_message_clone(SignalMessage **new_obj, const SignalMessage *obj); +SignalFfiError *signal_message_clone(SignalMutPointerSignalMessage *new_obj, SignalConstPointerSignalMessage obj); -SignalFfiError *signal_signed_pre_key_record_destroy(SignalSignedPreKeyRecord *p); +SignalFfiError *signal_signed_pre_key_record_destroy(SignalMutPointerSignedPreKeyRecord p); -SignalFfiError *signal_signed_pre_key_record_clone(SignalSignedPreKeyRecord **new_obj, const SignalSignedPreKeyRecord *obj); +SignalFfiError *signal_signed_pre_key_record_clone(SignalMutPointerSignedPreKeyRecord *new_obj, SignalConstPointerSignedPreKeyRecord obj); -SignalFfiError *signal_kyber_pre_key_record_destroy(SignalKyberPreKeyRecord *p); +SignalFfiError *signal_kyber_pre_key_record_destroy(SignalMutPointerKyberPreKeyRecord p); -SignalFfiError *signal_kyber_pre_key_record_clone(SignalKyberPreKeyRecord **new_obj, const SignalKyberPreKeyRecord *obj); +SignalFfiError *signal_kyber_pre_key_record_clone(SignalMutPointerKyberPreKeyRecord *new_obj, SignalConstPointerKyberPreKeyRecord obj); -SignalFfiError *signal_unidentified_sender_message_content_destroy(SignalUnidentifiedSenderMessageContent *p); +SignalFfiError *signal_unidentified_sender_message_content_destroy(SignalMutPointerUnidentifiedSenderMessageContent p); -SignalFfiError *signal_kyber_key_pair_destroy(SignalKyberKeyPair *p); +SignalFfiError *signal_kyber_key_pair_destroy(SignalMutPointerKyberKeyPair p); -SignalFfiError *signal_kyber_key_pair_clone(SignalKyberKeyPair **new_obj, const SignalKyberKeyPair *obj); +SignalFfiError *signal_kyber_key_pair_clone(SignalMutPointerKyberKeyPair *new_obj, SignalConstPointerKyberKeyPair obj); -SignalFfiError *signal_kyber_public_key_destroy(SignalKyberPublicKey *p); +SignalFfiError *signal_kyber_public_key_destroy(SignalMutPointerKyberPublicKey p); -SignalFfiError *signal_kyber_public_key_clone(SignalKyberPublicKey **new_obj, const SignalKyberPublicKey *obj); +SignalFfiError *signal_kyber_public_key_clone(SignalMutPointerKyberPublicKey *new_obj, SignalConstPointerKyberPublicKey obj); -SignalFfiError *signal_kyber_secret_key_destroy(SignalKyberSecretKey *p); +SignalFfiError *signal_kyber_secret_key_destroy(SignalMutPointerKyberSecretKey p); -SignalFfiError *signal_kyber_secret_key_clone(SignalKyberSecretKey **new_obj, const SignalKyberSecretKey *obj); +SignalFfiError *signal_kyber_secret_key_clone(SignalMutPointerKyberSecretKey *new_obj, SignalConstPointerKyberSecretKey obj); SignalFfiError *signal_hkdf_derive(SignalBorrowedMutableBuffer output, SignalBorrowedBuffer ikm, SignalBorrowedBuffer label, SignalBorrowedBuffer salt); @@ -861,327 +1293,327 @@ SignalFfiError *signal_service_id_parse_from_service_id_binary(SignalServiceIdFi SignalFfiError *signal_service_id_parse_from_service_id_string(SignalServiceIdFixedWidthBinaryBytes *out, const char *input); -SignalFfiError *signal_address_new(SignalProtocolAddress **out, const char *name, uint32_t device_id); +SignalFfiError *signal_address_new(SignalMutPointerProtocolAddress *out, const char *name, uint32_t device_id); -SignalFfiError *signal_publickey_deserialize(SignalPublicKey **out, SignalBorrowedBuffer data); +SignalFfiError *signal_publickey_deserialize(SignalMutPointerPublicKey *out, SignalBorrowedBuffer data); -SignalFfiError *signal_publickey_serialize(SignalOwnedBuffer *out, const SignalPublicKey *obj); +SignalFfiError *signal_publickey_serialize(SignalOwnedBuffer *out, SignalConstPointerPublicKey obj); -SignalFfiError *signal_publickey_get_public_key_bytes(SignalOwnedBuffer *out, const SignalPublicKey *obj); +SignalFfiError *signal_publickey_get_public_key_bytes(SignalOwnedBuffer *out, SignalConstPointerPublicKey obj); -SignalFfiError *signal_address_get_device_id(uint32_t *out, const SignalProtocolAddress *obj); +SignalFfiError *signal_address_get_device_id(uint32_t *out, SignalConstPointerProtocolAddress obj); -SignalFfiError *signal_address_get_name(const char **out, const SignalProtocolAddress *obj); +SignalFfiError *signal_address_get_name(const char **out, SignalConstPointerProtocolAddress obj); -SignalFfiError *signal_publickey_equals(bool *out, const SignalPublicKey *lhs, const SignalPublicKey *rhs); +SignalFfiError *signal_publickey_equals(bool *out, SignalConstPointerPublicKey lhs, SignalConstPointerPublicKey rhs); -SignalFfiError *signal_publickey_compare(int32_t *out, const SignalPublicKey *key1, const SignalPublicKey *key2); +SignalFfiError *signal_publickey_compare(int32_t *out, SignalConstPointerPublicKey key1, SignalConstPointerPublicKey key2); -SignalFfiError *signal_publickey_verify(bool *out, const SignalPublicKey *key, SignalBorrowedBuffer message, SignalBorrowedBuffer signature); +SignalFfiError *signal_publickey_verify(bool *out, SignalConstPointerPublicKey key, SignalBorrowedBuffer message, SignalBorrowedBuffer signature); -SignalFfiError *signal_privatekey_deserialize(SignalPrivateKey **out, SignalBorrowedBuffer data); +SignalFfiError *signal_privatekey_deserialize(SignalMutPointerPrivateKey *out, SignalBorrowedBuffer data); -SignalFfiError *signal_privatekey_serialize(SignalOwnedBuffer *out, const SignalPrivateKey *obj); +SignalFfiError *signal_privatekey_serialize(SignalOwnedBuffer *out, SignalConstPointerPrivateKey obj); -SignalFfiError *signal_privatekey_generate(SignalPrivateKey **out); +SignalFfiError *signal_privatekey_generate(SignalMutPointerPrivateKey *out); -SignalFfiError *signal_privatekey_get_public_key(SignalPublicKey **out, const SignalPrivateKey *k); +SignalFfiError *signal_privatekey_get_public_key(SignalMutPointerPublicKey *out, SignalConstPointerPrivateKey k); -SignalFfiError *signal_privatekey_sign(SignalOwnedBuffer *out, const SignalPrivateKey *key, SignalBorrowedBuffer message); +SignalFfiError *signal_privatekey_sign(SignalOwnedBuffer *out, SignalConstPointerPrivateKey key, SignalBorrowedBuffer message); -SignalFfiError *signal_privatekey_agree(SignalOwnedBuffer *out, const SignalPrivateKey *private_key, const SignalPublicKey *public_key); +SignalFfiError *signal_privatekey_agree(SignalOwnedBuffer *out, SignalConstPointerPrivateKey private_key, SignalConstPointerPublicKey public_key); -SignalFfiError *signal_kyber_public_key_serialize(SignalOwnedBuffer *out, const SignalKyberPublicKey *obj); +SignalFfiError *signal_kyber_public_key_serialize(SignalOwnedBuffer *out, SignalConstPointerKyberPublicKey obj); -SignalFfiError *signal_kyber_public_key_deserialize(SignalKyberPublicKey **out, SignalBorrowedBuffer data); +SignalFfiError *signal_kyber_public_key_deserialize(SignalMutPointerKyberPublicKey *out, SignalBorrowedBuffer data); -SignalFfiError *signal_kyber_secret_key_serialize(SignalOwnedBuffer *out, const SignalKyberSecretKey *obj); +SignalFfiError *signal_kyber_secret_key_serialize(SignalOwnedBuffer *out, SignalConstPointerKyberSecretKey obj); -SignalFfiError *signal_kyber_secret_key_deserialize(SignalKyberSecretKey **out, SignalBorrowedBuffer data); +SignalFfiError *signal_kyber_secret_key_deserialize(SignalMutPointerKyberSecretKey *out, SignalBorrowedBuffer data); -SignalFfiError *signal_kyber_public_key_equals(bool *out, const SignalKyberPublicKey *lhs, const SignalKyberPublicKey *rhs); +SignalFfiError *signal_kyber_public_key_equals(bool *out, SignalConstPointerKyberPublicKey lhs, SignalConstPointerKyberPublicKey rhs); -SignalFfiError *signal_kyber_key_pair_generate(SignalKyberKeyPair **out); +SignalFfiError *signal_kyber_key_pair_generate(SignalMutPointerKyberKeyPair *out); -SignalFfiError *signal_kyber_key_pair_get_public_key(SignalKyberPublicKey **out, const SignalKyberKeyPair *key_pair); +SignalFfiError *signal_kyber_key_pair_get_public_key(SignalMutPointerKyberPublicKey *out, SignalConstPointerKyberKeyPair key_pair); -SignalFfiError *signal_kyber_key_pair_get_secret_key(SignalKyberSecretKey **out, const SignalKyberKeyPair *key_pair); +SignalFfiError *signal_kyber_key_pair_get_secret_key(SignalMutPointerKyberSecretKey *out, SignalConstPointerKyberKeyPair key_pair); -SignalFfiError *signal_identitykeypair_serialize(SignalOwnedBuffer *out, const SignalPublicKey *public_key, const SignalPrivateKey *private_key); +SignalFfiError *signal_identitykeypair_serialize(SignalOwnedBuffer *out, SignalConstPointerPublicKey public_key, SignalConstPointerPrivateKey private_key); -SignalFfiError *signal_identitykeypair_sign_alternate_identity(SignalOwnedBuffer *out, const SignalPublicKey *public_key, const SignalPrivateKey *private_key, const SignalPublicKey *other_identity); +SignalFfiError *signal_identitykeypair_sign_alternate_identity(SignalOwnedBuffer *out, SignalConstPointerPublicKey public_key, SignalConstPointerPrivateKey private_key, SignalConstPointerPublicKey other_identity); -SignalFfiError *signal_identitykey_verify_alternate_identity(bool *out, const SignalPublicKey *public_key, const SignalPublicKey *other_identity, SignalBorrowedBuffer signature); +SignalFfiError *signal_identitykey_verify_alternate_identity(bool *out, SignalConstPointerPublicKey public_key, SignalConstPointerPublicKey other_identity, SignalBorrowedBuffer signature); -SignalFfiError *signal_fingerprint_new(SignalFingerprint **out, uint32_t iterations, uint32_t version, SignalBorrowedBuffer local_identifier, const SignalPublicKey *local_key, SignalBorrowedBuffer remote_identifier, const SignalPublicKey *remote_key); +SignalFfiError *signal_fingerprint_new(SignalMutPointerFingerprint *out, uint32_t iterations, uint32_t version, SignalBorrowedBuffer local_identifier, SignalConstPointerPublicKey local_key, SignalBorrowedBuffer remote_identifier, SignalConstPointerPublicKey remote_key); -SignalFfiError *signal_fingerprint_scannable_encoding(SignalOwnedBuffer *out, const SignalFingerprint *obj); +SignalFfiError *signal_fingerprint_scannable_encoding(SignalOwnedBuffer *out, SignalConstPointerFingerprint obj); -SignalFfiError *signal_fingerprint_display_string(const char **out, const SignalFingerprint *obj); +SignalFfiError *signal_fingerprint_display_string(const char **out, SignalConstPointerFingerprint obj); SignalFfiError *signal_fingerprint_compare(bool *out, SignalBorrowedBuffer fprint1, SignalBorrowedBuffer fprint2); -SignalFfiError *signal_message_deserialize(SignalMessage **out, SignalBorrowedBuffer data); +SignalFfiError *signal_message_deserialize(SignalMutPointerSignalMessage *out, SignalBorrowedBuffer data); -SignalFfiError *signal_message_get_body(SignalOwnedBuffer *out, const SignalMessage *obj); +SignalFfiError *signal_message_get_body(SignalOwnedBuffer *out, SignalConstPointerSignalMessage obj); -SignalFfiError *signal_message_get_serialized(SignalOwnedBuffer *out, const SignalMessage *obj); +SignalFfiError *signal_message_get_serialized(SignalOwnedBuffer *out, SignalConstPointerSignalMessage obj); -SignalFfiError *signal_message_get_counter(uint32_t *out, const SignalMessage *obj); +SignalFfiError *signal_message_get_counter(uint32_t *out, SignalConstPointerSignalMessage obj); -SignalFfiError *signal_message_get_message_version(uint32_t *out, const SignalMessage *obj); +SignalFfiError *signal_message_get_message_version(uint32_t *out, SignalConstPointerSignalMessage obj); -SignalFfiError *signal_message_new(SignalMessage **out, uint8_t message_version, SignalBorrowedBuffer mac_key, const SignalPublicKey *sender_ratchet_key, uint32_t counter, uint32_t previous_counter, SignalBorrowedBuffer ciphertext, const SignalPublicKey *sender_identity_key, const SignalPublicKey *receiver_identity_key); +SignalFfiError *signal_message_new(SignalMutPointerSignalMessage *out, uint8_t message_version, SignalBorrowedBuffer mac_key, SignalConstPointerPublicKey sender_ratchet_key, uint32_t counter, uint32_t previous_counter, SignalBorrowedBuffer ciphertext, SignalConstPointerPublicKey sender_identity_key, SignalConstPointerPublicKey receiver_identity_key); -SignalFfiError *signal_message_verify_mac(bool *out, const SignalMessage *msg, const SignalPublicKey *sender_identity_key, const SignalPublicKey *receiver_identity_key, SignalBorrowedBuffer mac_key); +SignalFfiError *signal_message_verify_mac(bool *out, SignalConstPointerSignalMessage msg, SignalConstPointerPublicKey sender_identity_key, SignalConstPointerPublicKey receiver_identity_key, SignalBorrowedBuffer mac_key); -SignalFfiError *signal_message_get_sender_ratchet_key(SignalPublicKey **out, const SignalMessage *m); +SignalFfiError *signal_message_get_sender_ratchet_key(SignalMutPointerPublicKey *out, SignalConstPointerSignalMessage m); -SignalFfiError *signal_pre_key_signal_message_new(SignalPreKeySignalMessage **out, uint8_t message_version, uint32_t registration_id, uint32_t pre_key_id, uint32_t signed_pre_key_id, const SignalPublicKey *base_key, const SignalPublicKey *identity_key, const SignalMessage *signal_message); +SignalFfiError *signal_pre_key_signal_message_new(SignalMutPointerPreKeySignalMessage *out, uint8_t message_version, uint32_t registration_id, uint32_t pre_key_id, uint32_t signed_pre_key_id, SignalConstPointerPublicKey base_key, SignalConstPointerPublicKey identity_key, SignalConstPointerSignalMessage signal_message); -SignalFfiError *signal_pre_key_signal_message_get_base_key(SignalPublicKey **out, const SignalPreKeySignalMessage *m); +SignalFfiError *signal_pre_key_signal_message_get_base_key(SignalMutPointerPublicKey *out, SignalConstPointerPreKeySignalMessage m); -SignalFfiError *signal_pre_key_signal_message_get_identity_key(SignalPublicKey **out, const SignalPreKeySignalMessage *m); +SignalFfiError *signal_pre_key_signal_message_get_identity_key(SignalMutPointerPublicKey *out, SignalConstPointerPreKeySignalMessage m); -SignalFfiError *signal_pre_key_signal_message_get_signal_message(SignalMessage **out, const SignalPreKeySignalMessage *m); +SignalFfiError *signal_pre_key_signal_message_get_signal_message(SignalMutPointerSignalMessage *out, SignalConstPointerPreKeySignalMessage m); -SignalFfiError *signal_pre_key_signal_message_deserialize(SignalPreKeySignalMessage **out, SignalBorrowedBuffer data); +SignalFfiError *signal_pre_key_signal_message_deserialize(SignalMutPointerPreKeySignalMessage *out, SignalBorrowedBuffer data); -SignalFfiError *signal_pre_key_signal_message_serialize(SignalOwnedBuffer *out, const SignalPreKeySignalMessage *obj); +SignalFfiError *signal_pre_key_signal_message_serialize(SignalOwnedBuffer *out, SignalConstPointerPreKeySignalMessage obj); -SignalFfiError *signal_pre_key_signal_message_get_registration_id(uint32_t *out, const SignalPreKeySignalMessage *obj); +SignalFfiError *signal_pre_key_signal_message_get_registration_id(uint32_t *out, SignalConstPointerPreKeySignalMessage obj); -SignalFfiError *signal_pre_key_signal_message_get_signed_pre_key_id(uint32_t *out, const SignalPreKeySignalMessage *obj); +SignalFfiError *signal_pre_key_signal_message_get_signed_pre_key_id(uint32_t *out, SignalConstPointerPreKeySignalMessage obj); -SignalFfiError *signal_pre_key_signal_message_get_pre_key_id(uint32_t *out, const SignalPreKeySignalMessage *obj); +SignalFfiError *signal_pre_key_signal_message_get_pre_key_id(uint32_t *out, SignalConstPointerPreKeySignalMessage obj); -SignalFfiError *signal_pre_key_signal_message_get_version(uint32_t *out, const SignalPreKeySignalMessage *obj); +SignalFfiError *signal_pre_key_signal_message_get_version(uint32_t *out, SignalConstPointerPreKeySignalMessage obj); -SignalFfiError *signal_sender_key_message_deserialize(SignalSenderKeyMessage **out, SignalBorrowedBuffer data); +SignalFfiError *signal_sender_key_message_deserialize(SignalMutPointerSenderKeyMessage *out, SignalBorrowedBuffer data); -SignalFfiError *signal_sender_key_message_get_cipher_text(SignalOwnedBuffer *out, const SignalSenderKeyMessage *obj); +SignalFfiError *signal_sender_key_message_get_cipher_text(SignalOwnedBuffer *out, SignalConstPointerSenderKeyMessage obj); -SignalFfiError *signal_sender_key_message_serialize(SignalOwnedBuffer *out, const SignalSenderKeyMessage *obj); +SignalFfiError *signal_sender_key_message_serialize(SignalOwnedBuffer *out, SignalConstPointerSenderKeyMessage obj); -SignalFfiError *signal_sender_key_message_get_distribution_id(uint8_t (*out)[16], const SignalSenderKeyMessage *obj); +SignalFfiError *signal_sender_key_message_get_distribution_id(uint8_t (*out)[16], SignalConstPointerSenderKeyMessage obj); -SignalFfiError *signal_sender_key_message_get_chain_id(uint32_t *out, const SignalSenderKeyMessage *obj); +SignalFfiError *signal_sender_key_message_get_chain_id(uint32_t *out, SignalConstPointerSenderKeyMessage obj); -SignalFfiError *signal_sender_key_message_get_iteration(uint32_t *out, const SignalSenderKeyMessage *obj); +SignalFfiError *signal_sender_key_message_get_iteration(uint32_t *out, SignalConstPointerSenderKeyMessage obj); -SignalFfiError *signal_sender_key_message_new(SignalSenderKeyMessage **out, uint8_t message_version, const uint8_t (*distribution_id)[16], uint32_t chain_id, uint32_t iteration, SignalBorrowedBuffer ciphertext, const SignalPrivateKey *pk); +SignalFfiError *signal_sender_key_message_new(SignalMutPointerSenderKeyMessage *out, uint8_t message_version, const uint8_t (*distribution_id)[16], uint32_t chain_id, uint32_t iteration, SignalBorrowedBuffer ciphertext, SignalConstPointerPrivateKey pk); -SignalFfiError *signal_sender_key_message_verify_signature(bool *out, const SignalSenderKeyMessage *skm, const SignalPublicKey *pubkey); +SignalFfiError *signal_sender_key_message_verify_signature(bool *out, SignalConstPointerSenderKeyMessage skm, SignalConstPointerPublicKey pubkey); -SignalFfiError *signal_sender_key_distribution_message_deserialize(SignalSenderKeyDistributionMessage **out, SignalBorrowedBuffer data); +SignalFfiError *signal_sender_key_distribution_message_deserialize(SignalMutPointerSenderKeyDistributionMessage *out, SignalBorrowedBuffer data); -SignalFfiError *signal_sender_key_distribution_message_get_chain_key(SignalOwnedBuffer *out, const SignalSenderKeyDistributionMessage *obj); +SignalFfiError *signal_sender_key_distribution_message_get_chain_key(SignalOwnedBuffer *out, SignalConstPointerSenderKeyDistributionMessage obj); -SignalFfiError *signal_sender_key_distribution_message_serialize(SignalOwnedBuffer *out, const SignalSenderKeyDistributionMessage *obj); +SignalFfiError *signal_sender_key_distribution_message_serialize(SignalOwnedBuffer *out, SignalConstPointerSenderKeyDistributionMessage obj); -SignalFfiError *signal_sender_key_distribution_message_get_distribution_id(uint8_t (*out)[16], const SignalSenderKeyDistributionMessage *obj); +SignalFfiError *signal_sender_key_distribution_message_get_distribution_id(uint8_t (*out)[16], SignalConstPointerSenderKeyDistributionMessage obj); -SignalFfiError *signal_sender_key_distribution_message_get_chain_id(uint32_t *out, const SignalSenderKeyDistributionMessage *obj); +SignalFfiError *signal_sender_key_distribution_message_get_chain_id(uint32_t *out, SignalConstPointerSenderKeyDistributionMessage obj); -SignalFfiError *signal_sender_key_distribution_message_get_iteration(uint32_t *out, const SignalSenderKeyDistributionMessage *obj); +SignalFfiError *signal_sender_key_distribution_message_get_iteration(uint32_t *out, SignalConstPointerSenderKeyDistributionMessage obj); -SignalFfiError *signal_sender_key_distribution_message_new(SignalSenderKeyDistributionMessage **out, uint8_t message_version, const uint8_t (*distribution_id)[16], uint32_t chain_id, uint32_t iteration, SignalBorrowedBuffer chainkey, const SignalPublicKey *pk); +SignalFfiError *signal_sender_key_distribution_message_new(SignalMutPointerSenderKeyDistributionMessage *out, uint8_t message_version, const uint8_t (*distribution_id)[16], uint32_t chain_id, uint32_t iteration, SignalBorrowedBuffer chainkey, SignalConstPointerPublicKey pk); -SignalFfiError *signal_sender_key_distribution_message_get_signature_key(SignalPublicKey **out, const SignalSenderKeyDistributionMessage *m); +SignalFfiError *signal_sender_key_distribution_message_get_signature_key(SignalMutPointerPublicKey *out, SignalConstPointerSenderKeyDistributionMessage m); -SignalFfiError *signal_decryption_error_message_deserialize(SignalDecryptionErrorMessage **out, SignalBorrowedBuffer data); +SignalFfiError *signal_decryption_error_message_deserialize(SignalMutPointerDecryptionErrorMessage *out, SignalBorrowedBuffer data); -SignalFfiError *signal_decryption_error_message_get_timestamp(uint64_t *out, const SignalDecryptionErrorMessage *obj); +SignalFfiError *signal_decryption_error_message_get_timestamp(uint64_t *out, SignalConstPointerDecryptionErrorMessage obj); -SignalFfiError *signal_decryption_error_message_get_device_id(uint32_t *out, const SignalDecryptionErrorMessage *obj); +SignalFfiError *signal_decryption_error_message_get_device_id(uint32_t *out, SignalConstPointerDecryptionErrorMessage obj); -SignalFfiError *signal_decryption_error_message_serialize(SignalOwnedBuffer *out, const SignalDecryptionErrorMessage *obj); +SignalFfiError *signal_decryption_error_message_serialize(SignalOwnedBuffer *out, SignalConstPointerDecryptionErrorMessage obj); -SignalFfiError *signal_decryption_error_message_get_ratchet_key(SignalPublicKey **out, const SignalDecryptionErrorMessage *m); +SignalFfiError *signal_decryption_error_message_get_ratchet_key(SignalMutPointerPublicKey *out, SignalConstPointerDecryptionErrorMessage m); -SignalFfiError *signal_decryption_error_message_for_original_message(SignalDecryptionErrorMessage **out, SignalBorrowedBuffer original_bytes, uint8_t original_type, uint64_t original_timestamp, uint32_t original_sender_device_id); +SignalFfiError *signal_decryption_error_message_for_original_message(SignalMutPointerDecryptionErrorMessage *out, SignalBorrowedBuffer original_bytes, uint8_t original_type, uint64_t original_timestamp, uint32_t original_sender_device_id); -SignalFfiError *signal_decryption_error_message_extract_from_serialized_content(SignalDecryptionErrorMessage **out, SignalBorrowedBuffer bytes); +SignalFfiError *signal_decryption_error_message_extract_from_serialized_content(SignalMutPointerDecryptionErrorMessage *out, SignalBorrowedBuffer bytes); -SignalFfiError *signal_plaintext_content_deserialize(SignalPlaintextContent **out, SignalBorrowedBuffer data); +SignalFfiError *signal_plaintext_content_deserialize(SignalMutPointerPlaintextContent *out, SignalBorrowedBuffer data); -SignalFfiError *signal_plaintext_content_serialize(SignalOwnedBuffer *out, const SignalPlaintextContent *obj); +SignalFfiError *signal_plaintext_content_serialize(SignalOwnedBuffer *out, SignalConstPointerPlaintextContent obj); -SignalFfiError *signal_plaintext_content_get_body(SignalOwnedBuffer *out, const SignalPlaintextContent *obj); +SignalFfiError *signal_plaintext_content_get_body(SignalOwnedBuffer *out, SignalConstPointerPlaintextContent obj); -SignalFfiError *signal_plaintext_content_from_decryption_error_message(SignalPlaintextContent **out, const SignalDecryptionErrorMessage *m); +SignalFfiError *signal_plaintext_content_from_decryption_error_message(SignalMutPointerPlaintextContent *out, SignalConstPointerDecryptionErrorMessage m); -SignalFfiError *signal_pre_key_bundle_new(SignalPreKeyBundle **out, uint32_t registration_id, uint32_t device_id, uint32_t prekey_id, const SignalPublicKey *prekey, uint32_t signed_prekey_id, const SignalPublicKey *signed_prekey, SignalBorrowedBuffer signed_prekey_signature, const SignalPublicKey *identity_key, uint32_t kyber_prekey_id, const SignalKyberPublicKey *kyber_prekey, SignalBorrowedBuffer kyber_prekey_signature); +SignalFfiError *signal_pre_key_bundle_new(SignalMutPointerPreKeyBundle *out, uint32_t registration_id, uint32_t device_id, uint32_t prekey_id, SignalConstPointerPublicKey prekey, uint32_t signed_prekey_id, SignalConstPointerPublicKey signed_prekey, SignalBorrowedBuffer signed_prekey_signature, SignalConstPointerPublicKey identity_key, uint32_t kyber_prekey_id, SignalConstPointerKyberPublicKey kyber_prekey, SignalBorrowedBuffer kyber_prekey_signature); -SignalFfiError *signal_pre_key_bundle_get_identity_key(SignalPublicKey **out, const SignalPreKeyBundle *p); +SignalFfiError *signal_pre_key_bundle_get_identity_key(SignalMutPointerPublicKey *out, SignalConstPointerPreKeyBundle p); -SignalFfiError *signal_pre_key_bundle_get_signed_pre_key_signature(SignalOwnedBuffer *out, const SignalPreKeyBundle *obj); +SignalFfiError *signal_pre_key_bundle_get_signed_pre_key_signature(SignalOwnedBuffer *out, SignalConstPointerPreKeyBundle obj); -SignalFfiError *signal_pre_key_bundle_get_registration_id(uint32_t *out, const SignalPreKeyBundle *obj); +SignalFfiError *signal_pre_key_bundle_get_registration_id(uint32_t *out, SignalConstPointerPreKeyBundle obj); -SignalFfiError *signal_pre_key_bundle_get_device_id(uint32_t *out, const SignalPreKeyBundle *obj); +SignalFfiError *signal_pre_key_bundle_get_device_id(uint32_t *out, SignalConstPointerPreKeyBundle obj); -SignalFfiError *signal_pre_key_bundle_get_signed_pre_key_id(uint32_t *out, const SignalPreKeyBundle *obj); +SignalFfiError *signal_pre_key_bundle_get_signed_pre_key_id(uint32_t *out, SignalConstPointerPreKeyBundle obj); -SignalFfiError *signal_pre_key_bundle_get_pre_key_id(uint32_t *out, const SignalPreKeyBundle *obj); +SignalFfiError *signal_pre_key_bundle_get_pre_key_id(uint32_t *out, SignalConstPointerPreKeyBundle obj); -SignalFfiError *signal_pre_key_bundle_get_pre_key_public(SignalPublicKey **out, const SignalPreKeyBundle *obj); +SignalFfiError *signal_pre_key_bundle_get_pre_key_public(SignalMutPointerPublicKey *out, SignalConstPointerPreKeyBundle obj); -SignalFfiError *signal_pre_key_bundle_get_signed_pre_key_public(SignalPublicKey **out, const SignalPreKeyBundle *obj); +SignalFfiError *signal_pre_key_bundle_get_signed_pre_key_public(SignalMutPointerPublicKey *out, SignalConstPointerPreKeyBundle obj); -SignalFfiError *signal_pre_key_bundle_get_kyber_pre_key_id(uint32_t *out, const SignalPreKeyBundle *obj); +SignalFfiError *signal_pre_key_bundle_get_kyber_pre_key_id(uint32_t *out, SignalConstPointerPreKeyBundle obj); -SignalFfiError *signal_pre_key_bundle_get_kyber_pre_key_public(SignalKyberPublicKey **out, const SignalPreKeyBundle *bundle); +SignalFfiError *signal_pre_key_bundle_get_kyber_pre_key_public(SignalMutPointerKyberPublicKey *out, SignalConstPointerPreKeyBundle bundle); -SignalFfiError *signal_pre_key_bundle_get_kyber_pre_key_signature(SignalOwnedBuffer *out, const SignalPreKeyBundle *bundle); +SignalFfiError *signal_pre_key_bundle_get_kyber_pre_key_signature(SignalOwnedBuffer *out, SignalConstPointerPreKeyBundle bundle); -SignalFfiError *signal_signed_pre_key_record_deserialize(SignalSignedPreKeyRecord **out, SignalBorrowedBuffer data); +SignalFfiError *signal_signed_pre_key_record_deserialize(SignalMutPointerSignedPreKeyRecord *out, SignalBorrowedBuffer data); -SignalFfiError *signal_signed_pre_key_record_get_signature(SignalOwnedBuffer *out, const SignalSignedPreKeyRecord *obj); +SignalFfiError *signal_signed_pre_key_record_get_signature(SignalOwnedBuffer *out, SignalConstPointerSignedPreKeyRecord obj); -SignalFfiError *signal_signed_pre_key_record_serialize(SignalOwnedBuffer *out, const SignalSignedPreKeyRecord *obj); +SignalFfiError *signal_signed_pre_key_record_serialize(SignalOwnedBuffer *out, SignalConstPointerSignedPreKeyRecord obj); -SignalFfiError *signal_signed_pre_key_record_get_id(uint32_t *out, const SignalSignedPreKeyRecord *obj); +SignalFfiError *signal_signed_pre_key_record_get_id(uint32_t *out, SignalConstPointerSignedPreKeyRecord obj); -SignalFfiError *signal_signed_pre_key_record_get_timestamp(uint64_t *out, const SignalSignedPreKeyRecord *obj); +SignalFfiError *signal_signed_pre_key_record_get_timestamp(uint64_t *out, SignalConstPointerSignedPreKeyRecord obj); -SignalFfiError *signal_signed_pre_key_record_get_public_key(SignalPublicKey **out, const SignalSignedPreKeyRecord *obj); +SignalFfiError *signal_signed_pre_key_record_get_public_key(SignalMutPointerPublicKey *out, SignalConstPointerSignedPreKeyRecord obj); -SignalFfiError *signal_signed_pre_key_record_get_private_key(SignalPrivateKey **out, const SignalSignedPreKeyRecord *obj); +SignalFfiError *signal_signed_pre_key_record_get_private_key(SignalMutPointerPrivateKey *out, SignalConstPointerSignedPreKeyRecord obj); -SignalFfiError *signal_kyber_pre_key_record_deserialize(SignalKyberPreKeyRecord **out, SignalBorrowedBuffer data); +SignalFfiError *signal_kyber_pre_key_record_deserialize(SignalMutPointerKyberPreKeyRecord *out, SignalBorrowedBuffer data); -SignalFfiError *signal_kyber_pre_key_record_get_signature(SignalOwnedBuffer *out, const SignalKyberPreKeyRecord *obj); +SignalFfiError *signal_kyber_pre_key_record_get_signature(SignalOwnedBuffer *out, SignalConstPointerKyberPreKeyRecord obj); -SignalFfiError *signal_kyber_pre_key_record_serialize(SignalOwnedBuffer *out, const SignalKyberPreKeyRecord *obj); +SignalFfiError *signal_kyber_pre_key_record_serialize(SignalOwnedBuffer *out, SignalConstPointerKyberPreKeyRecord obj); -SignalFfiError *signal_kyber_pre_key_record_get_id(uint32_t *out, const SignalKyberPreKeyRecord *obj); +SignalFfiError *signal_kyber_pre_key_record_get_id(uint32_t *out, SignalConstPointerKyberPreKeyRecord obj); -SignalFfiError *signal_kyber_pre_key_record_get_timestamp(uint64_t *out, const SignalKyberPreKeyRecord *obj); +SignalFfiError *signal_kyber_pre_key_record_get_timestamp(uint64_t *out, SignalConstPointerKyberPreKeyRecord obj); -SignalFfiError *signal_kyber_pre_key_record_get_public_key(SignalKyberPublicKey **out, const SignalKyberPreKeyRecord *obj); +SignalFfiError *signal_kyber_pre_key_record_get_public_key(SignalMutPointerKyberPublicKey *out, SignalConstPointerKyberPreKeyRecord obj); -SignalFfiError *signal_kyber_pre_key_record_get_secret_key(SignalKyberSecretKey **out, const SignalKyberPreKeyRecord *obj); +SignalFfiError *signal_kyber_pre_key_record_get_secret_key(SignalMutPointerKyberSecretKey *out, SignalConstPointerKyberPreKeyRecord obj); -SignalFfiError *signal_kyber_pre_key_record_get_key_pair(SignalKyberKeyPair **out, const SignalKyberPreKeyRecord *obj); +SignalFfiError *signal_kyber_pre_key_record_get_key_pair(SignalMutPointerKyberKeyPair *out, SignalConstPointerKyberPreKeyRecord obj); -SignalFfiError *signal_signed_pre_key_record_new(SignalSignedPreKeyRecord **out, uint32_t id, uint64_t timestamp, const SignalPublicKey *pub_key, const SignalPrivateKey *priv_key, SignalBorrowedBuffer signature); +SignalFfiError *signal_signed_pre_key_record_new(SignalMutPointerSignedPreKeyRecord *out, uint32_t id, uint64_t timestamp, SignalConstPointerPublicKey pub_key, SignalConstPointerPrivateKey priv_key, SignalBorrowedBuffer signature); -SignalFfiError *signal_kyber_pre_key_record_new(SignalKyberPreKeyRecord **out, uint32_t id, uint64_t timestamp, const SignalKyberKeyPair *key_pair, SignalBorrowedBuffer signature); +SignalFfiError *signal_kyber_pre_key_record_new(SignalMutPointerKyberPreKeyRecord *out, uint32_t id, uint64_t timestamp, SignalConstPointerKyberKeyPair key_pair, SignalBorrowedBuffer signature); -SignalFfiError *signal_pre_key_record_deserialize(SignalPreKeyRecord **out, SignalBorrowedBuffer data); +SignalFfiError *signal_pre_key_record_deserialize(SignalMutPointerPreKeyRecord *out, SignalBorrowedBuffer data); -SignalFfiError *signal_pre_key_record_serialize(SignalOwnedBuffer *out, const SignalPreKeyRecord *obj); +SignalFfiError *signal_pre_key_record_serialize(SignalOwnedBuffer *out, SignalConstPointerPreKeyRecord obj); -SignalFfiError *signal_pre_key_record_get_id(uint32_t *out, const SignalPreKeyRecord *obj); +SignalFfiError *signal_pre_key_record_get_id(uint32_t *out, SignalConstPointerPreKeyRecord obj); -SignalFfiError *signal_pre_key_record_get_public_key(SignalPublicKey **out, const SignalPreKeyRecord *obj); +SignalFfiError *signal_pre_key_record_get_public_key(SignalMutPointerPublicKey *out, SignalConstPointerPreKeyRecord obj); -SignalFfiError *signal_pre_key_record_get_private_key(SignalPrivateKey **out, const SignalPreKeyRecord *obj); +SignalFfiError *signal_pre_key_record_get_private_key(SignalMutPointerPrivateKey *out, SignalConstPointerPreKeyRecord obj); -SignalFfiError *signal_pre_key_record_new(SignalPreKeyRecord **out, uint32_t id, const SignalPublicKey *pub_key, const SignalPrivateKey *priv_key); +SignalFfiError *signal_pre_key_record_new(SignalMutPointerPreKeyRecord *out, uint32_t id, SignalConstPointerPublicKey pub_key, SignalConstPointerPrivateKey priv_key); -SignalFfiError *signal_sender_key_record_deserialize(SignalSenderKeyRecord **out, SignalBorrowedBuffer data); +SignalFfiError *signal_sender_key_record_deserialize(SignalMutPointerSenderKeyRecord *out, SignalBorrowedBuffer data); -SignalFfiError *signal_sender_key_record_serialize(SignalOwnedBuffer *out, const SignalSenderKeyRecord *obj); +SignalFfiError *signal_sender_key_record_serialize(SignalOwnedBuffer *out, SignalConstPointerSenderKeyRecord obj); -SignalFfiError *signal_server_certificate_deserialize(SignalServerCertificate **out, SignalBorrowedBuffer data); +SignalFfiError *signal_server_certificate_deserialize(SignalMutPointerServerCertificate *out, SignalBorrowedBuffer data); -SignalFfiError *signal_server_certificate_get_serialized(SignalOwnedBuffer *out, const SignalServerCertificate *obj); +SignalFfiError *signal_server_certificate_get_serialized(SignalOwnedBuffer *out, SignalConstPointerServerCertificate obj); -SignalFfiError *signal_server_certificate_get_certificate(SignalOwnedBuffer *out, const SignalServerCertificate *obj); +SignalFfiError *signal_server_certificate_get_certificate(SignalOwnedBuffer *out, SignalConstPointerServerCertificate obj); -SignalFfiError *signal_server_certificate_get_signature(SignalOwnedBuffer *out, const SignalServerCertificate *obj); +SignalFfiError *signal_server_certificate_get_signature(SignalOwnedBuffer *out, SignalConstPointerServerCertificate obj); -SignalFfiError *signal_server_certificate_get_key_id(uint32_t *out, const SignalServerCertificate *obj); +SignalFfiError *signal_server_certificate_get_key_id(uint32_t *out, SignalConstPointerServerCertificate obj); -SignalFfiError *signal_server_certificate_get_key(SignalPublicKey **out, const SignalServerCertificate *obj); +SignalFfiError *signal_server_certificate_get_key(SignalMutPointerPublicKey *out, SignalConstPointerServerCertificate obj); -SignalFfiError *signal_server_certificate_new(SignalServerCertificate **out, uint32_t key_id, const SignalPublicKey *server_key, const SignalPrivateKey *trust_root); +SignalFfiError *signal_server_certificate_new(SignalMutPointerServerCertificate *out, uint32_t key_id, SignalConstPointerPublicKey server_key, SignalConstPointerPrivateKey trust_root); -SignalFfiError *signal_sender_certificate_deserialize(SignalSenderCertificate **out, SignalBorrowedBuffer data); +SignalFfiError *signal_sender_certificate_deserialize(SignalMutPointerSenderCertificate *out, SignalBorrowedBuffer data); -SignalFfiError *signal_sender_certificate_get_serialized(SignalOwnedBuffer *out, const SignalSenderCertificate *obj); +SignalFfiError *signal_sender_certificate_get_serialized(SignalOwnedBuffer *out, SignalConstPointerSenderCertificate obj); -SignalFfiError *signal_sender_certificate_get_certificate(SignalOwnedBuffer *out, const SignalSenderCertificate *obj); +SignalFfiError *signal_sender_certificate_get_certificate(SignalOwnedBuffer *out, SignalConstPointerSenderCertificate obj); -SignalFfiError *signal_sender_certificate_get_signature(SignalOwnedBuffer *out, const SignalSenderCertificate *obj); +SignalFfiError *signal_sender_certificate_get_signature(SignalOwnedBuffer *out, SignalConstPointerSenderCertificate obj); -SignalFfiError *signal_sender_certificate_get_sender_uuid(const char **out, const SignalSenderCertificate *obj); +SignalFfiError *signal_sender_certificate_get_sender_uuid(const char **out, SignalConstPointerSenderCertificate obj); -SignalFfiError *signal_sender_certificate_get_sender_e164(const char **out, const SignalSenderCertificate *obj); +SignalFfiError *signal_sender_certificate_get_sender_e164(const char **out, SignalConstPointerSenderCertificate obj); -SignalFfiError *signal_sender_certificate_get_expiration(uint64_t *out, const SignalSenderCertificate *obj); +SignalFfiError *signal_sender_certificate_get_expiration(uint64_t *out, SignalConstPointerSenderCertificate obj); -SignalFfiError *signal_sender_certificate_get_device_id(uint32_t *out, const SignalSenderCertificate *obj); +SignalFfiError *signal_sender_certificate_get_device_id(uint32_t *out, SignalConstPointerSenderCertificate obj); -SignalFfiError *signal_sender_certificate_get_key(SignalPublicKey **out, const SignalSenderCertificate *obj); +SignalFfiError *signal_sender_certificate_get_key(SignalMutPointerPublicKey *out, SignalConstPointerSenderCertificate obj); -SignalFfiError *signal_sender_certificate_validate(bool *out, const SignalSenderCertificate *cert, const SignalPublicKey *key, uint64_t time); +SignalFfiError *signal_sender_certificate_validate(bool *out, SignalConstPointerSenderCertificate cert, SignalConstPointerPublicKey key, uint64_t time); -SignalFfiError *signal_sender_certificate_get_server_certificate(SignalServerCertificate **out, const SignalSenderCertificate *cert); +SignalFfiError *signal_sender_certificate_get_server_certificate(SignalMutPointerServerCertificate *out, SignalConstPointerSenderCertificate cert); -SignalFfiError *signal_sender_certificate_new(SignalSenderCertificate **out, const char *sender_uuid, const char *sender_e164, uint32_t sender_device_id, const SignalPublicKey *sender_key, uint64_t expiration, const SignalServerCertificate *signer_cert, const SignalPrivateKey *signer_key); +SignalFfiError *signal_sender_certificate_new(SignalMutPointerSenderCertificate *out, const char *sender_uuid, const char *sender_e164, uint32_t sender_device_id, SignalConstPointerPublicKey sender_key, uint64_t expiration, SignalConstPointerServerCertificate signer_cert, SignalConstPointerPrivateKey signer_key); -SignalFfiError *signal_unidentified_sender_message_content_deserialize(SignalUnidentifiedSenderMessageContent **out, SignalBorrowedBuffer data); +SignalFfiError *signal_unidentified_sender_message_content_deserialize(SignalMutPointerUnidentifiedSenderMessageContent *out, SignalBorrowedBuffer data); -SignalFfiError *signal_unidentified_sender_message_content_serialize(SignalOwnedBuffer *out, const SignalUnidentifiedSenderMessageContent *obj); +SignalFfiError *signal_unidentified_sender_message_content_serialize(SignalOwnedBuffer *out, SignalConstPointerUnidentifiedSenderMessageContent obj); -SignalFfiError *signal_unidentified_sender_message_content_get_contents(SignalOwnedBuffer *out, const SignalUnidentifiedSenderMessageContent *obj); +SignalFfiError *signal_unidentified_sender_message_content_get_contents(SignalOwnedBuffer *out, SignalConstPointerUnidentifiedSenderMessageContent obj); -SignalFfiError *signal_unidentified_sender_message_content_get_group_id_or_empty(SignalOwnedBuffer *out, const SignalUnidentifiedSenderMessageContent *m); +SignalFfiError *signal_unidentified_sender_message_content_get_group_id_or_empty(SignalOwnedBuffer *out, SignalConstPointerUnidentifiedSenderMessageContent m); -SignalFfiError *signal_unidentified_sender_message_content_get_sender_cert(SignalSenderCertificate **out, const SignalUnidentifiedSenderMessageContent *m); +SignalFfiError *signal_unidentified_sender_message_content_get_sender_cert(SignalMutPointerSenderCertificate *out, SignalConstPointerUnidentifiedSenderMessageContent m); -SignalFfiError *signal_unidentified_sender_message_content_get_msg_type(uint8_t *out, const SignalUnidentifiedSenderMessageContent *m); +SignalFfiError *signal_unidentified_sender_message_content_get_msg_type(uint8_t *out, SignalConstPointerUnidentifiedSenderMessageContent m); -SignalFfiError *signal_unidentified_sender_message_content_get_content_hint(uint32_t *out, const SignalUnidentifiedSenderMessageContent *m); +SignalFfiError *signal_unidentified_sender_message_content_get_content_hint(uint32_t *out, SignalConstPointerUnidentifiedSenderMessageContent m); -SignalFfiError *signal_unidentified_sender_message_content_new(SignalUnidentifiedSenderMessageContent **out, const SignalCiphertextMessage *message, const SignalSenderCertificate *sender, uint32_t content_hint, SignalBorrowedBuffer group_id); +SignalFfiError *signal_unidentified_sender_message_content_new(SignalMutPointerUnidentifiedSenderMessageContent *out, SignalConstPointerCiphertextMessage message, SignalConstPointerSenderCertificate sender, uint32_t content_hint, SignalBorrowedBuffer group_id); -SignalFfiError *signal_ciphertext_message_type(uint8_t *out, const SignalCiphertextMessage *msg); +SignalFfiError *signal_ciphertext_message_type(uint8_t *out, SignalConstPointerCiphertextMessage msg); -SignalFfiError *signal_ciphertext_message_serialize(SignalOwnedBuffer *out, const SignalCiphertextMessage *obj); +SignalFfiError *signal_ciphertext_message_serialize(SignalOwnedBuffer *out, SignalConstPointerCiphertextMessage obj); -SignalFfiError *signal_ciphertext_message_from_plaintext_content(SignalCiphertextMessage **out, const SignalPlaintextContent *m); +SignalFfiError *signal_ciphertext_message_from_plaintext_content(SignalMutPointerCiphertextMessage *out, SignalConstPointerPlaintextContent m); -SignalFfiError *signal_session_record_archive_current_state(SignalSessionRecord *session_record); +SignalFfiError *signal_session_record_archive_current_state(SignalMutPointerSessionRecord session_record); -SignalFfiError *signal_session_record_has_usable_sender_chain(bool *out, const SignalSessionRecord *s, uint64_t now); +SignalFfiError *signal_session_record_has_usable_sender_chain(bool *out, SignalConstPointerSessionRecord s, uint64_t now); -SignalFfiError *signal_session_record_current_ratchet_key_matches(bool *out, const SignalSessionRecord *s, const SignalPublicKey *key); +SignalFfiError *signal_session_record_current_ratchet_key_matches(bool *out, SignalConstPointerSessionRecord s, SignalConstPointerPublicKey key); -SignalFfiError *signal_session_record_deserialize(SignalSessionRecord **out, SignalBorrowedBuffer data); +SignalFfiError *signal_session_record_deserialize(SignalMutPointerSessionRecord *out, SignalBorrowedBuffer data); -SignalFfiError *signal_session_record_serialize(SignalOwnedBuffer *out, const SignalSessionRecord *obj); +SignalFfiError *signal_session_record_serialize(SignalOwnedBuffer *out, SignalConstPointerSessionRecord obj); -SignalFfiError *signal_session_record_get_local_registration_id(uint32_t *out, const SignalSessionRecord *obj); +SignalFfiError *signal_session_record_get_local_registration_id(uint32_t *out, SignalConstPointerSessionRecord obj); -SignalFfiError *signal_session_record_get_remote_registration_id(uint32_t *out, const SignalSessionRecord *obj); +SignalFfiError *signal_session_record_get_remote_registration_id(uint32_t *out, SignalConstPointerSessionRecord obj); -SignalFfiError *signal_process_prekey_bundle(const SignalPreKeyBundle *bundle, const SignalProtocolAddress *protocol_address, const SignalSessionStore *session_store, const SignalIdentityKeyStore *identity_key_store, uint64_t now); +SignalFfiError *signal_process_prekey_bundle(SignalConstPointerPreKeyBundle bundle, SignalConstPointerProtocolAddress protocol_address, SignalConstPointerFfiSessionStoreStruct session_store, SignalConstPointerFfiIdentityKeyStoreStruct identity_key_store, uint64_t now); -SignalFfiError *signal_encrypt_message(SignalCiphertextMessage **out, SignalBorrowedBuffer ptext, const SignalProtocolAddress *protocol_address, const SignalSessionStore *session_store, const SignalIdentityKeyStore *identity_key_store, uint64_t now); +SignalFfiError *signal_encrypt_message(SignalMutPointerCiphertextMessage *out, SignalBorrowedBuffer ptext, SignalConstPointerProtocolAddress protocol_address, SignalConstPointerFfiSessionStoreStruct session_store, SignalConstPointerFfiIdentityKeyStoreStruct identity_key_store, uint64_t now); -SignalFfiError *signal_decrypt_message(SignalOwnedBuffer *out, const SignalMessage *message, const SignalProtocolAddress *protocol_address, const SignalSessionStore *session_store, const SignalIdentityKeyStore *identity_key_store); +SignalFfiError *signal_decrypt_message(SignalOwnedBuffer *out, SignalConstPointerSignalMessage message, SignalConstPointerProtocolAddress protocol_address, SignalConstPointerFfiSessionStoreStruct session_store, SignalConstPointerFfiIdentityKeyStoreStruct identity_key_store); -SignalFfiError *signal_decrypt_pre_key_message(SignalOwnedBuffer *out, const SignalPreKeySignalMessage *message, const SignalProtocolAddress *protocol_address, const SignalSessionStore *session_store, const SignalIdentityKeyStore *identity_key_store, const SignalPreKeyStore *prekey_store, const SignalSignedPreKeyStore *signed_prekey_store, const SignalKyberPreKeyStore *kyber_prekey_store); +SignalFfiError *signal_decrypt_pre_key_message(SignalOwnedBuffer *out, SignalConstPointerPreKeySignalMessage message, SignalConstPointerProtocolAddress protocol_address, SignalConstPointerFfiSessionStoreStruct session_store, SignalConstPointerFfiIdentityKeyStoreStruct identity_key_store, SignalConstPointerFfiPreKeyStoreStruct prekey_store, SignalConstPointerFfiSignedPreKeyStoreStruct signed_prekey_store, SignalConstPointerFfiKyberPreKeyStoreStruct kyber_prekey_store); -SignalFfiError *signal_sealed_session_cipher_encrypt(SignalOwnedBuffer *out, const SignalProtocolAddress *destination, const SignalUnidentifiedSenderMessageContent *content, const SignalIdentityKeyStore *identity_key_store); +SignalFfiError *signal_sealed_session_cipher_encrypt(SignalOwnedBuffer *out, SignalConstPointerProtocolAddress destination, SignalConstPointerUnidentifiedSenderMessageContent content, SignalConstPointerFfiIdentityKeyStoreStruct identity_key_store); -SignalFfiError *signal_sealed_sender_multi_recipient_encrypt(SignalOwnedBuffer *out, SignalBorrowedSliceOfProtocolAddress recipients, SignalBorrowedSliceOfSessionRecord recipient_sessions, SignalBorrowedBuffer excluded_recipients, const SignalUnidentifiedSenderMessageContent *content, const SignalIdentityKeyStore *identity_key_store); +SignalFfiError *signal_sealed_sender_multi_recipient_encrypt(SignalOwnedBuffer *out, SignalBorrowedSliceOfConstPointerProtocolAddress recipients, SignalBorrowedSliceOfConstPointerSessionRecord recipient_sessions, SignalBorrowedBuffer excluded_recipients, SignalConstPointerUnidentifiedSenderMessageContent content, SignalConstPointerFfiIdentityKeyStoreStruct identity_key_store); SignalFfiError *signal_sealed_sender_multi_recipient_message_for_single_recipient(SignalOwnedBuffer *out, SignalBorrowedBuffer encoded_multi_recipient_message); -SignalFfiError *signal_sealed_session_cipher_decrypt_to_usmc(SignalUnidentifiedSenderMessageContent **out, SignalBorrowedBuffer ctext, const SignalIdentityKeyStore *identity_store); +SignalFfiError *signal_sealed_session_cipher_decrypt_to_usmc(SignalMutPointerUnidentifiedSenderMessageContent *out, SignalBorrowedBuffer ctext, SignalConstPointerFfiIdentityKeyStoreStruct identity_store); -SignalFfiError *signal_sender_key_distribution_message_create(SignalSenderKeyDistributionMessage **out, const SignalProtocolAddress *sender, const uint8_t (*distribution_id)[16], const SignalSenderKeyStore *store); +SignalFfiError *signal_sender_key_distribution_message_create(SignalMutPointerSenderKeyDistributionMessage *out, SignalConstPointerProtocolAddress sender, const uint8_t (*distribution_id)[16], SignalConstPointerFfiSenderKeyStoreStruct store); -SignalFfiError *signal_process_sender_key_distribution_message(const SignalProtocolAddress *sender, const SignalSenderKeyDistributionMessage *sender_key_distribution_message, const SignalSenderKeyStore *store); +SignalFfiError *signal_process_sender_key_distribution_message(SignalConstPointerProtocolAddress sender, SignalConstPointerSenderKeyDistributionMessage sender_key_distribution_message, SignalConstPointerFfiSenderKeyStoreStruct store); -SignalFfiError *signal_group_encrypt_message(SignalCiphertextMessage **out, const SignalProtocolAddress *sender, const uint8_t (*distribution_id)[16], SignalBorrowedBuffer message, const SignalSenderKeyStore *store); +SignalFfiError *signal_group_encrypt_message(SignalMutPointerCiphertextMessage *out, SignalConstPointerProtocolAddress sender, const uint8_t (*distribution_id)[16], SignalBorrowedBuffer message, SignalConstPointerFfiSenderKeyStoreStruct store); -SignalFfiError *signal_group_decrypt_message(SignalOwnedBuffer *out, const SignalProtocolAddress *sender, SignalBorrowedBuffer message, const SignalSenderKeyStore *store); +SignalFfiError *signal_group_decrypt_message(SignalOwnedBuffer *out, SignalConstPointerProtocolAddress sender, SignalBorrowedBuffer message, SignalConstPointerFfiSenderKeyStoreStruct store); SignalFfiError *signal_device_transfer_generate_private_key(SignalOwnedBuffer *out); @@ -1189,29 +1621,29 @@ SignalFfiError *signal_device_transfer_generate_private_key_with_format(SignalOw SignalFfiError *signal_device_transfer_generate_certificate(SignalOwnedBuffer *out, SignalBorrowedBuffer private_key, const char *name, uint32_t days_to_expire); -SignalFfiError *signal_cds2_client_state_new(SignalSgxClientState **out, SignalBorrowedBuffer mrenclave, SignalBorrowedBuffer attestation_msg, uint64_t current_timestamp); +SignalFfiError *signal_cds2_client_state_new(SignalMutPointerSgxClientState *out, SignalBorrowedBuffer mrenclave, SignalBorrowedBuffer attestation_msg, uint64_t current_timestamp); -SignalFfiError *signal_hsm_enclave_client_destroy(SignalHsmEnclaveClient *p); +SignalFfiError *signal_hsm_enclave_client_destroy(SignalMutPointerHsmEnclaveClient p); -SignalFfiError *signal_hsm_enclave_client_new(SignalHsmEnclaveClient **out, SignalBorrowedBuffer trusted_public_key, SignalBorrowedBuffer trusted_code_hashes); +SignalFfiError *signal_hsm_enclave_client_new(SignalMutPointerHsmEnclaveClient *out, SignalBorrowedBuffer trusted_public_key, SignalBorrowedBuffer trusted_code_hashes); -SignalFfiError *signal_hsm_enclave_client_complete_handshake(SignalHsmEnclaveClient *cli, SignalBorrowedBuffer handshake_received); +SignalFfiError *signal_hsm_enclave_client_complete_handshake(SignalMutPointerHsmEnclaveClient cli, SignalBorrowedBuffer handshake_received); -SignalFfiError *signal_hsm_enclave_client_established_send(SignalOwnedBuffer *out, SignalHsmEnclaveClient *cli, SignalBorrowedBuffer plaintext_to_send); +SignalFfiError *signal_hsm_enclave_client_established_send(SignalOwnedBuffer *out, SignalMutPointerHsmEnclaveClient cli, SignalBorrowedBuffer plaintext_to_send); -SignalFfiError *signal_hsm_enclave_client_established_recv(SignalOwnedBuffer *out, SignalHsmEnclaveClient *cli, SignalBorrowedBuffer received_ciphertext); +SignalFfiError *signal_hsm_enclave_client_established_recv(SignalOwnedBuffer *out, SignalMutPointerHsmEnclaveClient cli, SignalBorrowedBuffer received_ciphertext); -SignalFfiError *signal_hsm_enclave_client_initial_request(SignalOwnedBuffer *out, const SignalHsmEnclaveClient *obj); +SignalFfiError *signal_hsm_enclave_client_initial_request(SignalOwnedBuffer *out, SignalConstPointerHsmEnclaveClient obj); -SignalFfiError *signal_sgx_client_state_destroy(SignalSgxClientState *p); +SignalFfiError *signal_sgx_client_state_destroy(SignalMutPointerSgxClientState p); -SignalFfiError *signal_sgx_client_state_initial_request(SignalOwnedBuffer *out, const SignalSgxClientState *obj); +SignalFfiError *signal_sgx_client_state_initial_request(SignalOwnedBuffer *out, SignalConstPointerSgxClientState obj); -SignalFfiError *signal_sgx_client_state_complete_handshake(SignalSgxClientState *cli, SignalBorrowedBuffer handshake_received); +SignalFfiError *signal_sgx_client_state_complete_handshake(SignalMutPointerSgxClientState cli, SignalBorrowedBuffer handshake_received); -SignalFfiError *signal_sgx_client_state_established_send(SignalOwnedBuffer *out, SignalSgxClientState *cli, SignalBorrowedBuffer plaintext_to_send); +SignalFfiError *signal_sgx_client_state_established_send(SignalOwnedBuffer *out, SignalMutPointerSgxClientState cli, SignalBorrowedBuffer plaintext_to_send); -SignalFfiError *signal_sgx_client_state_established_recv(SignalOwnedBuffer *out, SignalSgxClientState *cli, SignalBorrowedBuffer received_ciphertext); +SignalFfiError *signal_sgx_client_state_established_recv(SignalOwnedBuffer *out, SignalMutPointerSgxClientState cli, SignalBorrowedBuffer received_ciphertext); SignalFfiError *signal_expiring_profile_key_credential_check_valid_contents(SignalBorrowedBuffer buffer); @@ -1245,17 +1677,17 @@ SignalFfiError *signal_receipt_credential_response_check_valid_contents(SignalBo SignalFfiError *signal_uuid_ciphertext_check_valid_contents(SignalBorrowedBuffer buffer); -SignalFfiError *signal_server_public_params_destroy(SignalServerPublicParams *p); +SignalFfiError *signal_server_public_params_destroy(SignalMutPointerServerPublicParams p); -SignalFfiError *signal_server_public_params_deserialize(SignalServerPublicParams **out, SignalBorrowedBuffer buffer); +SignalFfiError *signal_server_public_params_deserialize(SignalMutPointerServerPublicParams *out, SignalBorrowedBuffer buffer); -SignalFfiError *signal_server_public_params_serialize(SignalOwnedBuffer *out, const SignalServerPublicParams *handle); +SignalFfiError *signal_server_public_params_serialize(SignalOwnedBuffer *out, SignalConstPointerServerPublicParams handle); -SignalFfiError *signal_server_secret_params_destroy(SignalServerSecretParams *p); +SignalFfiError *signal_server_secret_params_destroy(SignalMutPointerServerSecretParams p); -SignalFfiError *signal_server_secret_params_deserialize(SignalServerSecretParams **out, SignalBorrowedBuffer buffer); +SignalFfiError *signal_server_secret_params_deserialize(SignalMutPointerServerSecretParams *out, SignalBorrowedBuffer buffer); -SignalFfiError *signal_server_secret_params_serialize(SignalOwnedBuffer *out, const SignalServerSecretParams *handle); +SignalFfiError *signal_server_secret_params_serialize(SignalOwnedBuffer *out, SignalConstPointerServerSecretParams handle); SignalFfiError *signal_profile_key_get_commitment(unsigned char (*out)[SignalPROFILE_KEY_COMMITMENT_LEN], const unsigned char (*profile_key)[SignalPROFILE_KEY_LEN], const SignalServiceIdFixedWidthBinaryBytes *user_id); @@ -1283,55 +1715,53 @@ SignalFfiError *signal_group_secret_params_encrypt_blob_with_padding_determinist SignalFfiError *signal_group_secret_params_decrypt_blob_with_padding(SignalOwnedBuffer *out, const unsigned char (*params)[SignalGROUP_SECRET_PARAMS_LEN], SignalBorrowedBuffer ciphertext); -SignalFfiError *signal_server_secret_params_generate_deterministic(SignalServerSecretParams **out, const uint8_t (*randomness)[SignalRANDOMNESS_LEN]); +SignalFfiError *signal_server_secret_params_generate_deterministic(SignalMutPointerServerSecretParams *out, const uint8_t (*randomness)[SignalRANDOMNESS_LEN]); -SignalFfiError *signal_server_secret_params_get_public_params(SignalServerPublicParams **out, const SignalServerSecretParams *params); +SignalFfiError *signal_server_secret_params_get_public_params(SignalMutPointerServerPublicParams *out, SignalConstPointerServerSecretParams params); -SignalFfiError *signal_server_secret_params_sign_deterministic(uint8_t (*out)[SignalSIGNATURE_LEN], const SignalServerSecretParams *params, const uint8_t (*randomness)[SignalRANDOMNESS_LEN], SignalBorrowedBuffer message); +SignalFfiError *signal_server_secret_params_sign_deterministic(uint8_t (*out)[SignalSIGNATURE_LEN], SignalConstPointerServerSecretParams params, const uint8_t (*randomness)[SignalRANDOMNESS_LEN], SignalBorrowedBuffer message); -SignalFfiError *signal_server_public_params_receive_auth_credential_with_pni_as_service_id(SignalOwnedBuffer *out, const SignalServerPublicParams *params, const SignalServiceIdFixedWidthBinaryBytes *aci, const SignalServiceIdFixedWidthBinaryBytes *pni, uint64_t redemption_time, SignalBorrowedBuffer auth_credential_with_pni_response_bytes); +SignalFfiError *signal_server_public_params_receive_auth_credential_with_pni_as_service_id(SignalOwnedBuffer *out, SignalConstPointerServerPublicParams params, const SignalServiceIdFixedWidthBinaryBytes *aci, const SignalServiceIdFixedWidthBinaryBytes *pni, uint64_t redemption_time, SignalBorrowedBuffer auth_credential_with_pni_response_bytes); -SignalFfiError *signal_server_public_params_create_auth_credential_with_pni_presentation_deterministic(SignalOwnedBuffer *out, const SignalServerPublicParams *server_public_params, const uint8_t (*randomness)[SignalRANDOMNESS_LEN], const unsigned char (*group_secret_params)[SignalGROUP_SECRET_PARAMS_LEN], SignalBorrowedBuffer auth_credential_with_pni_bytes); +SignalFfiError *signal_server_public_params_create_auth_credential_with_pni_presentation_deterministic(SignalOwnedBuffer *out, SignalConstPointerServerPublicParams server_public_params, const uint8_t (*randomness)[SignalRANDOMNESS_LEN], const unsigned char (*group_secret_params)[SignalGROUP_SECRET_PARAMS_LEN], SignalBorrowedBuffer auth_credential_with_pni_bytes); -SignalFfiError *signal_server_public_params_create_profile_key_credential_request_context_deterministic(unsigned char (*out)[SignalPROFILE_KEY_CREDENTIAL_REQUEST_CONTEXT_LEN], const SignalServerPublicParams *server_public_params, const uint8_t (*randomness)[SignalRANDOMNESS_LEN], const SignalServiceIdFixedWidthBinaryBytes *user_id, const unsigned char (*profile_key)[SignalPROFILE_KEY_LEN]); +SignalFfiError *signal_server_public_params_create_profile_key_credential_request_context_deterministic(unsigned char (*out)[SignalPROFILE_KEY_CREDENTIAL_REQUEST_CONTEXT_LEN], SignalConstPointerServerPublicParams server_public_params, const uint8_t (*randomness)[SignalRANDOMNESS_LEN], const SignalServiceIdFixedWidthBinaryBytes *user_id, const unsigned char (*profile_key)[SignalPROFILE_KEY_LEN]); -SignalFfiError *signal_server_public_params_receive_expiring_profile_key_credential(unsigned char (*out)[SignalEXPIRING_PROFILE_KEY_CREDENTIAL_LEN], const SignalServerPublicParams *server_public_params, const unsigned char (*request_context)[SignalPROFILE_KEY_CREDENTIAL_REQUEST_CONTEXT_LEN], const unsigned char (*response)[SignalEXPIRING_PROFILE_KEY_CREDENTIAL_RESPONSE_LEN], uint64_t current_time_in_seconds); +SignalFfiError *signal_server_public_params_receive_expiring_profile_key_credential(unsigned char (*out)[SignalEXPIRING_PROFILE_KEY_CREDENTIAL_LEN], SignalConstPointerServerPublicParams server_public_params, const unsigned char (*request_context)[SignalPROFILE_KEY_CREDENTIAL_REQUEST_CONTEXT_LEN], const unsigned char (*response)[SignalEXPIRING_PROFILE_KEY_CREDENTIAL_RESPONSE_LEN], uint64_t current_time_in_seconds); -SignalFfiError *signal_server_public_params_create_expiring_profile_key_credential_presentation_deterministic(SignalOwnedBuffer *out, const SignalServerPublicParams *server_public_params, const uint8_t (*randomness)[SignalRANDOMNESS_LEN], const unsigned char (*group_secret_params)[SignalGROUP_SECRET_PARAMS_LEN], const unsigned char (*profile_key_credential)[SignalEXPIRING_PROFILE_KEY_CREDENTIAL_LEN]); +SignalFfiError *signal_server_public_params_create_expiring_profile_key_credential_presentation_deterministic(SignalOwnedBuffer *out, SignalConstPointerServerPublicParams server_public_params, const uint8_t (*randomness)[SignalRANDOMNESS_LEN], const unsigned char (*group_secret_params)[SignalGROUP_SECRET_PARAMS_LEN], const unsigned char (*profile_key_credential)[SignalEXPIRING_PROFILE_KEY_CREDENTIAL_LEN]); -SignalFfiError *signal_server_public_params_create_receipt_credential_request_context_deterministic(unsigned char (*out)[SignalRECEIPT_CREDENTIAL_REQUEST_CONTEXT_LEN], const SignalServerPublicParams *server_public_params, const uint8_t (*randomness)[SignalRANDOMNESS_LEN], const uint8_t (*receipt_serial)[SignalRECEIPT_SERIAL_LEN]); +SignalFfiError *signal_server_public_params_create_receipt_credential_request_context_deterministic(unsigned char (*out)[SignalRECEIPT_CREDENTIAL_REQUEST_CONTEXT_LEN], SignalConstPointerServerPublicParams server_public_params, const uint8_t (*randomness)[SignalRANDOMNESS_LEN], const uint8_t (*receipt_serial)[SignalRECEIPT_SERIAL_LEN]); -SignalFfiError *signal_server_public_params_receive_receipt_credential(unsigned char (*out)[SignalRECEIPT_CREDENTIAL_LEN], const SignalServerPublicParams *server_public_params, const unsigned char (*request_context)[SignalRECEIPT_CREDENTIAL_REQUEST_CONTEXT_LEN], const unsigned char (*response)[SignalRECEIPT_CREDENTIAL_RESPONSE_LEN]); +SignalFfiError *signal_server_public_params_receive_receipt_credential(unsigned char (*out)[SignalRECEIPT_CREDENTIAL_LEN], SignalConstPointerServerPublicParams server_public_params, const unsigned char (*request_context)[SignalRECEIPT_CREDENTIAL_REQUEST_CONTEXT_LEN], const unsigned char (*response)[SignalRECEIPT_CREDENTIAL_RESPONSE_LEN]); -SignalFfiError *signal_server_public_params_create_receipt_credential_presentation_deterministic(unsigned char (*out)[SignalRECEIPT_CREDENTIAL_PRESENTATION_LEN], const SignalServerPublicParams *server_public_params, const uint8_t (*randomness)[SignalRANDOMNESS_LEN], const unsigned char (*receipt_credential)[SignalRECEIPT_CREDENTIAL_LEN]); +SignalFfiError *signal_server_public_params_create_receipt_credential_presentation_deterministic(unsigned char (*out)[SignalRECEIPT_CREDENTIAL_PRESENTATION_LEN], SignalConstPointerServerPublicParams server_public_params, const uint8_t (*randomness)[SignalRANDOMNESS_LEN], const unsigned char (*receipt_credential)[SignalRECEIPT_CREDENTIAL_LEN]); -SignalFfiError *signal_server_secret_params_issue_auth_credential_with_pni_as_service_id_deterministic(SignalOwnedBuffer *out, const SignalServerSecretParams *server_secret_params, const uint8_t (*randomness)[SignalRANDOMNESS_LEN], const SignalServiceIdFixedWidthBinaryBytes *aci, const SignalServiceIdFixedWidthBinaryBytes *pni, uint64_t redemption_time); - -SignalFfiError *signal_server_secret_params_issue_auth_credential_with_pni_zkc_deterministic(SignalOwnedBuffer *out, const SignalServerSecretParams *server_secret_params, const uint8_t (*randomness)[SignalRANDOMNESS_LEN], const SignalServiceIdFixedWidthBinaryBytes *aci, const SignalServiceIdFixedWidthBinaryBytes *pni, uint64_t redemption_time); +SignalFfiError *signal_server_secret_params_issue_auth_credential_with_pni_zkc_deterministic(SignalOwnedBuffer *out, SignalConstPointerServerSecretParams server_secret_params, const uint8_t (*randomness)[SignalRANDOMNESS_LEN], const SignalServiceIdFixedWidthBinaryBytes *aci, const SignalServiceIdFixedWidthBinaryBytes *pni, uint64_t redemption_time); SignalFfiError *signal_auth_credential_with_pni_check_valid_contents(SignalBorrowedBuffer bytes); SignalFfiError *signal_auth_credential_with_pni_response_check_valid_contents(SignalBorrowedBuffer bytes); -SignalFfiError *signal_server_secret_params_verify_auth_credential_presentation(const SignalServerSecretParams *server_secret_params, const unsigned char (*group_public_params)[SignalGROUP_PUBLIC_PARAMS_LEN], SignalBorrowedBuffer presentation_bytes, uint64_t current_time_in_seconds); +SignalFfiError *signal_server_secret_params_verify_auth_credential_presentation(SignalConstPointerServerSecretParams server_secret_params, const unsigned char (*group_public_params)[SignalGROUP_PUBLIC_PARAMS_LEN], SignalBorrowedBuffer presentation_bytes, uint64_t current_time_in_seconds); -SignalFfiError *signal_server_secret_params_issue_expiring_profile_key_credential_deterministic(unsigned char (*out)[SignalEXPIRING_PROFILE_KEY_CREDENTIAL_RESPONSE_LEN], const SignalServerSecretParams *server_secret_params, const uint8_t (*randomness)[SignalRANDOMNESS_LEN], const unsigned char (*request)[SignalPROFILE_KEY_CREDENTIAL_REQUEST_LEN], const SignalServiceIdFixedWidthBinaryBytes *user_id, const unsigned char (*commitment)[SignalPROFILE_KEY_COMMITMENT_LEN], uint64_t expiration_in_seconds); +SignalFfiError *signal_server_secret_params_issue_expiring_profile_key_credential_deterministic(unsigned char (*out)[SignalEXPIRING_PROFILE_KEY_CREDENTIAL_RESPONSE_LEN], SignalConstPointerServerSecretParams server_secret_params, const uint8_t (*randomness)[SignalRANDOMNESS_LEN], const unsigned char (*request)[SignalPROFILE_KEY_CREDENTIAL_REQUEST_LEN], const SignalServiceIdFixedWidthBinaryBytes *user_id, const unsigned char (*commitment)[SignalPROFILE_KEY_COMMITMENT_LEN], uint64_t expiration_in_seconds); -SignalFfiError *signal_server_secret_params_verify_profile_key_credential_presentation(const SignalServerSecretParams *server_secret_params, const unsigned char (*group_public_params)[SignalGROUP_PUBLIC_PARAMS_LEN], SignalBorrowedBuffer presentation_bytes, uint64_t current_time_in_seconds); +SignalFfiError *signal_server_secret_params_verify_profile_key_credential_presentation(SignalConstPointerServerSecretParams server_secret_params, const unsigned char (*group_public_params)[SignalGROUP_PUBLIC_PARAMS_LEN], SignalBorrowedBuffer presentation_bytes, uint64_t current_time_in_seconds); -SignalFfiError *signal_server_secret_params_issue_receipt_credential_deterministic(unsigned char (*out)[SignalRECEIPT_CREDENTIAL_RESPONSE_LEN], const SignalServerSecretParams *server_secret_params, const uint8_t (*randomness)[SignalRANDOMNESS_LEN], const unsigned char (*request)[SignalRECEIPT_CREDENTIAL_REQUEST_LEN], uint64_t receipt_expiration_time, uint64_t receipt_level); +SignalFfiError *signal_server_secret_params_issue_receipt_credential_deterministic(unsigned char (*out)[SignalRECEIPT_CREDENTIAL_RESPONSE_LEN], SignalConstPointerServerSecretParams server_secret_params, const uint8_t (*randomness)[SignalRANDOMNESS_LEN], const unsigned char (*request)[SignalRECEIPT_CREDENTIAL_REQUEST_LEN], uint64_t receipt_expiration_time, uint64_t receipt_level); -SignalFfiError *signal_server_secret_params_verify_receipt_credential_presentation(const SignalServerSecretParams *server_secret_params, const unsigned char (*presentation)[SignalRECEIPT_CREDENTIAL_PRESENTATION_LEN]); +SignalFfiError *signal_server_secret_params_verify_receipt_credential_presentation(SignalConstPointerServerSecretParams server_secret_params, const unsigned char (*presentation)[SignalRECEIPT_CREDENTIAL_PRESENTATION_LEN]); SignalFfiError *signal_group_public_params_get_group_identifier(uint8_t (*out)[SignalGROUP_IDENTIFIER_LEN], const unsigned char (*group_public_params)[SignalGROUP_PUBLIC_PARAMS_LEN]); -SignalFfiError *signal_server_public_params_verify_signature(const SignalServerPublicParams *server_public_params, SignalBorrowedBuffer message, const uint8_t (*notary_signature)[SignalSIGNATURE_LEN]); +SignalFfiError *signal_server_public_params_verify_signature(SignalConstPointerServerPublicParams server_public_params, SignalBorrowedBuffer message, const uint8_t (*notary_signature)[SignalSIGNATURE_LEN]); SignalFfiError *signal_auth_credential_presentation_check_valid_contents(SignalBorrowedBuffer presentation_bytes); SignalFfiError *signal_auth_credential_presentation_get_uuid_ciphertext(unsigned char (*out)[SignalUUID_CIPHERTEXT_LEN], SignalBorrowedBuffer presentation_bytes); -SignalFfiError *signal_auth_credential_presentation_get_pni_ciphertext_or_empty(SignalOwnedBuffer *out, SignalBorrowedBuffer presentation_bytes); +SignalFfiError *signal_auth_credential_presentation_get_pni_ciphertext(unsigned char (*out)[SignalUUID_CIPHERTEXT_LEN], SignalBorrowedBuffer presentation_bytes); SignalFfiError *signal_auth_credential_presentation_get_redemption_time(uint64_t *out, SignalBorrowedBuffer presentation_bytes); @@ -1443,7 +1873,7 @@ SignalFfiError *signal_backup_auth_credential_presentation_verify(SignalBorrowed SignalFfiError *signal_group_send_derived_key_pair_check_valid_contents(SignalBorrowedBuffer bytes); -SignalFfiError *signal_group_send_derived_key_pair_for_expiration(SignalOwnedBuffer *out, uint64_t expiration, const SignalServerSecretParams *server_params); +SignalFfiError *signal_group_send_derived_key_pair_for_expiration(SignalOwnedBuffer *out, uint64_t expiration, SignalConstPointerServerSecretParams server_params); SignalFfiError *signal_group_send_endorsements_response_check_valid_contents(SignalBorrowedBuffer bytes); @@ -1451,9 +1881,9 @@ SignalFfiError *signal_group_send_endorsements_response_issue_deterministic(Sign SignalFfiError *signal_group_send_endorsements_response_get_expiration(uint64_t *out, SignalBorrowedBuffer response_bytes); -SignalFfiError *signal_group_send_endorsements_response_receive_and_combine_with_service_ids(SignalBytestringArray *out, SignalBorrowedBuffer response_bytes, SignalBorrowedBuffer group_members, const SignalServiceIdFixedWidthBinaryBytes *local_user, uint64_t now, const unsigned char (*group_params)[SignalGROUP_SECRET_PARAMS_LEN], const SignalServerPublicParams *server_params); +SignalFfiError *signal_group_send_endorsements_response_receive_and_combine_with_service_ids(SignalBytestringArray *out, SignalBorrowedBuffer response_bytes, SignalBorrowedBuffer group_members, const SignalServiceIdFixedWidthBinaryBytes *local_user, uint64_t now, const unsigned char (*group_params)[SignalGROUP_SECRET_PARAMS_LEN], SignalConstPointerServerPublicParams server_params); -SignalFfiError *signal_group_send_endorsements_response_receive_and_combine_with_ciphertexts(SignalBytestringArray *out, SignalBorrowedBuffer response_bytes, SignalBorrowedBuffer concatenated_group_member_ciphertexts, SignalBorrowedBuffer local_user_ciphertext, uint64_t now, const SignalServerPublicParams *server_params); +SignalFfiError *signal_group_send_endorsements_response_receive_and_combine_with_ciphertexts(SignalBytestringArray *out, SignalBorrowedBuffer response_bytes, SignalBorrowedBuffer concatenated_group_member_ciphertexts, SignalBorrowedBuffer local_user_ciphertext, uint64_t now, SignalConstPointerServerPublicParams server_params); SignalFfiError *signal_group_send_endorsement_check_valid_contents(SignalBorrowedBuffer bytes); @@ -1473,109 +1903,131 @@ SignalFfiError *signal_group_send_full_token_get_expiration(uint64_t *out, Signa SignalFfiError *signal_group_send_full_token_verify(SignalBorrowedBuffer token, SignalBorrowedBuffer user_ids, uint64_t now, SignalBorrowedBuffer key_pair); -SignalFfiError *signal_connection_manager_destroy(SignalConnectionManager *p); +SignalFfiError *signal_connection_info_destroy(SignalMutPointerConnectionInfo p); -SignalFfiError *signal_connection_manager_new(SignalConnectionManager **out, uint8_t environment, const char *user_agent); +SignalFfiError *signal_connection_manager_destroy(SignalMutPointerConnectionManager p); -SignalFfiError *signal_connection_manager_set_proxy(const SignalConnectionManager *connection_manager, const char *host, int32_t port); +SignalFfiError *signal_connection_manager_new(SignalMutPointerConnectionManager *out, uint8_t environment, const char *user_agent); -SignalFfiError *signal_connection_manager_clear_proxy(const SignalConnectionManager *connection_manager); +SignalFfiError *signal_connection_manager_set_proxy(SignalConstPointerConnectionManager connection_manager, const char *host, int32_t port); -SignalFfiError *signal_connection_manager_set_censorship_circumvention_enabled(const SignalConnectionManager *connection_manager, bool enabled); +SignalFfiError *signal_connection_manager_clear_proxy(SignalConstPointerConnectionManager connection_manager); -SignalFfiError *signal_connection_manager_on_network_change(const SignalConnectionManager *connection_manager); +SignalFfiError *signal_connection_manager_set_censorship_circumvention_enabled(SignalConstPointerConnectionManager connection_manager, bool enabled); + +SignalFfiError *signal_connection_manager_on_network_change(SignalConstPointerConnectionManager connection_manager); SignalFfiError *signal_create_otp(const char **out, const char *username, SignalBorrowedBuffer secret); SignalFfiError *signal_create_otp_from_base64(const char **out, const char *username, const char *secret); -SignalFfiError *signal_svr3_backup(SignalCPromiseOwnedBufferOfc_uchar *promise, const SignalTokioAsyncContext *async_runtime, const SignalConnectionManager *connection_manager, SignalBorrowedBuffer secret, const char *password, uint32_t max_tries, const char *username, const char *enclave_password); +SignalFfiError *signal_lookup_request_destroy(SignalMutPointerLookupRequest p); -SignalFfiError *signal_svr3_migrate(SignalCPromiseOwnedBufferOfc_uchar *promise, const SignalTokioAsyncContext *async_runtime, const SignalConnectionManager *connection_manager, SignalBorrowedBuffer secret, const char *password, uint32_t max_tries, const char *username, const char *enclave_password); +SignalFfiError *signal_lookup_request_new(SignalMutPointerLookupRequest *out); -SignalFfiError *signal_svr3_restore(SignalCPromiseOwnedBufferOfc_uchar *promise, const SignalTokioAsyncContext *async_runtime, const SignalConnectionManager *connection_manager, const char *password, SignalBorrowedBuffer share_set, const char *username, const char *enclave_password); +SignalFfiError *signal_lookup_request_add_e164(SignalConstPointerLookupRequest request, const char *e164); -SignalFfiError *signal_svr3_remove(SignalCPromisebool *promise, const SignalTokioAsyncContext *async_runtime, const SignalConnectionManager *connection_manager, const char *username, const char *enclave_password); +SignalFfiError *signal_lookup_request_add_previous_e164(SignalConstPointerLookupRequest request, const char *e164); -SignalFfiError *signal_svr3_rotate(SignalCPromisebool *promise, const SignalTokioAsyncContext *async_runtime, const SignalConnectionManager *connection_manager, SignalBorrowedBuffer share_set, const char *username, const char *enclave_password); +SignalFfiError *signal_lookup_request_set_token(SignalConstPointerLookupRequest request, SignalBorrowedBuffer token); -SignalFfiError *signal_lookup_request_destroy(SignalLookupRequest *p); +SignalFfiError *signal_lookup_request_add_aci_and_access_key(SignalConstPointerLookupRequest request, const SignalServiceIdFixedWidthBinaryBytes *aci, SignalBorrowedBuffer access_key); -SignalFfiError *signal_lookup_request_new(SignalLookupRequest **out); +SignalFfiError *signal_cdsi_lookup_destroy(SignalMutPointerCdsiLookup p); -SignalFfiError *signal_lookup_request_add_e164(const SignalLookupRequest *request, const char *e164); +SignalFfiError *signal_cdsi_lookup_new(SignalCPromiseMutPointerCdsiLookup *promise, SignalConstPointerTokioAsyncContext async_runtime, SignalConstPointerConnectionManager connection_manager, const char *username, const char *password, SignalConstPointerLookupRequest request); -SignalFfiError *signal_lookup_request_add_previous_e164(const SignalLookupRequest *request, const char *e164); +SignalFfiError *signal_cdsi_lookup_token(SignalOwnedBuffer *out, SignalConstPointerCdsiLookup lookup); -SignalFfiError *signal_lookup_request_set_token(const SignalLookupRequest *request, SignalBorrowedBuffer token); +SignalFfiError *signal_cdsi_lookup_complete(SignalCPromiseFfiCdsiLookupResponse *promise, SignalConstPointerTokioAsyncContext async_runtime, SignalConstPointerCdsiLookup lookup); -SignalFfiError *signal_lookup_request_add_aci_and_access_key(const SignalLookupRequest *request, const SignalServiceIdFixedWidthBinaryBytes *aci, SignalBorrowedBuffer access_key); +SignalFfiError *signal_auth_chat_destroy(SignalMutPointerAuthChat p); -SignalFfiError *signal_cdsi_lookup_destroy(SignalCdsiLookup *p); +SignalFfiError *signal_unauth_chat_destroy(SignalMutPointerUnauthChat p); -SignalFfiError *signal_cdsi_lookup_new(SignalCPromiseCdsiLookup *promise, const SignalTokioAsyncContext *async_runtime, const SignalConnectionManager *connection_manager, const char *username, const char *password, const SignalLookupRequest *request); +SignalFfiError *signal_http_request_destroy(SignalMutPointerHttpRequest p); -SignalFfiError *signal_cdsi_lookup_token(SignalOwnedBuffer *out, const SignalCdsiLookup *lookup); +SignalFfiError *signal_unauthenticated_chat_connection_destroy(SignalMutPointerUnauthenticatedChatConnection p); -SignalFfiError *signal_cdsi_lookup_complete(SignalCPromiseFfiCdsiLookupResponse *promise, const SignalTokioAsyncContext *async_runtime, const SignalCdsiLookup *lookup); +SignalFfiError *signal_authenticated_chat_connection_destroy(SignalMutPointerAuthenticatedChatConnection p); -SignalFfiError *signal_auth_chat_destroy(SignalAuthChat *p); +SignalFfiError *signal_http_request_new_with_body(SignalMutPointerHttpRequest *out, const char *method, const char *path, SignalBorrowedBuffer body_as_slice); -SignalFfiError *signal_unauth_chat_destroy(SignalUnauthChat *p); +SignalFfiError *signal_http_request_new_without_body(SignalMutPointerHttpRequest *out, const char *method, const char *path); -SignalFfiError *signal_http_request_destroy(SignalHttpRequest *p); +SignalFfiError *signal_http_request_add_header(SignalConstPointerHttpRequest request, const char *name, const char *value); -SignalFfiError *signal_http_request_new_with_body(SignalHttpRequest **out, const char *method, const char *path, SignalBorrowedBuffer body_as_slice); +SignalFfiError *signal_chat_connection_info_local_port(uint16_t *out, SignalConstPointerChatConnectionInfo connection_info); -SignalFfiError *signal_http_request_new_without_body(SignalHttpRequest **out, const char *method, const char *path); +SignalFfiError *signal_chat_connection_info_ip_version(uint8_t *out, SignalConstPointerChatConnectionInfo connection_info); -SignalFfiError *signal_http_request_add_header(const SignalHttpRequest *request, const char *name, const char *value); +SignalFfiError *signal_chat_connection_info_description(const char **out, SignalConstPointerChatConnectionInfo connection_info); -SignalFfiError *signal_chat_service_new_unauth(SignalUnauthChat **out, const SignalConnectionManager *connection_manager); +SignalFfiError *signal_chat_service_new_unauth(SignalMutPointerUnauthChat *out, SignalConstPointerConnectionManager connection_manager); -SignalFfiError *signal_chat_service_new_auth(SignalAuthChat **out, const SignalConnectionManager *connection_manager, const char *username, const char *password, bool receive_stories); +SignalFfiError *signal_chat_service_new_auth(SignalMutPointerAuthChat *out, SignalConstPointerConnectionManager connection_manager, const char *username, const char *password, bool receive_stories); -SignalFfiError *signal_chat_service_disconnect_unauth(SignalCPromisebool *promise, const SignalTokioAsyncContext *async_runtime, const SignalUnauthChat *chat); +SignalFfiError *signal_unauthenticated_chat_connection_connect(SignalCPromiseMutPointerUnauthenticatedChatConnection *promise, SignalConstPointerTokioAsyncContext async_runtime, SignalConstPointerConnectionManager connection_manager); -SignalFfiError *signal_chat_service_disconnect_auth(SignalCPromisebool *promise, const SignalTokioAsyncContext *async_runtime, const SignalAuthChat *chat); +SignalFfiError *signal_unauthenticated_chat_connection_init_listener(SignalConstPointerUnauthenticatedChatConnection chat, SignalConstPointerFfiChatListenerStruct listener); -SignalFfiError *signal_chat_service_connect_unauth(SignalCPromiseFfiChatServiceDebugInfo *promise, const SignalTokioAsyncContext *async_runtime, const SignalUnauthChat *chat); +SignalFfiError *signal_unauthenticated_chat_connection_send(SignalCPromiseFfiChatResponse *promise, SignalConstPointerTokioAsyncContext async_runtime, SignalConstPointerUnauthenticatedChatConnection chat, SignalConstPointerHttpRequest http_request, uint32_t timeout_millis); -SignalFfiError *signal_chat_service_connect_auth(SignalCPromiseFfiChatServiceDebugInfo *promise, const SignalTokioAsyncContext *async_runtime, const SignalAuthChat *chat); +SignalFfiError *signal_unauthenticated_chat_connection_disconnect(SignalCPromisebool *promise, SignalConstPointerTokioAsyncContext async_runtime, SignalConstPointerUnauthenticatedChatConnection chat); -SignalFfiError *signal_chat_service_unauth_send(SignalCPromiseFfiChatResponse *promise, const SignalTokioAsyncContext *async_runtime, const SignalUnauthChat *chat, const SignalHttpRequest *http_request, uint32_t timeout_millis); +SignalFfiError *signal_unauthenticated_chat_connection_info(SignalMutPointerChatConnectionInfo *out, SignalConstPointerUnauthenticatedChatConnection chat); -SignalFfiError *signal_chat_service_unauth_send_and_debug(SignalCPromiseFfiResponseAndDebugInfo *promise, const SignalTokioAsyncContext *async_runtime, const SignalUnauthChat *chat, const SignalHttpRequest *http_request, uint32_t timeout_millis); +SignalFfiError *signal_authenticated_chat_connection_connect(SignalCPromiseMutPointerAuthenticatedChatConnection *promise, SignalConstPointerTokioAsyncContext async_runtime, SignalConstPointerConnectionManager connection_manager, const char *username, const char *password, bool receive_stories); -SignalFfiError *signal_chat_service_auth_send(SignalCPromiseFfiChatResponse *promise, const SignalTokioAsyncContext *async_runtime, const SignalAuthChat *chat, const SignalHttpRequest *http_request, uint32_t timeout_millis); +SignalFfiError *signal_authenticated_chat_connection_init_listener(SignalConstPointerAuthenticatedChatConnection chat, SignalConstPointerFfiChatListenerStruct listener); -SignalFfiError *signal_chat_service_auth_send_and_debug(SignalCPromiseFfiResponseAndDebugInfo *promise, const SignalTokioAsyncContext *async_runtime, const SignalAuthChat *chat, const SignalHttpRequest *http_request, uint32_t timeout_millis); +SignalFfiError *signal_authenticated_chat_connection_send(SignalCPromiseFfiChatResponse *promise, SignalConstPointerTokioAsyncContext async_runtime, SignalConstPointerAuthenticatedChatConnection chat, SignalConstPointerHttpRequest http_request, uint32_t timeout_millis); -SignalFfiError *signal_chat_service_set_listener_auth(const SignalTokioAsyncContext *runtime, const SignalAuthChat *chat, const SignalFfiChatListenerStruct *listener); +SignalFfiError *signal_authenticated_chat_connection_disconnect(SignalCPromisebool *promise, SignalConstPointerTokioAsyncContext async_runtime, SignalConstPointerAuthenticatedChatConnection chat); -SignalFfiError *signal_chat_service_set_listener_unauth(const SignalTokioAsyncContext *runtime, const SignalUnauthChat *chat, const SignalFfiChatListenerStruct *listener); +SignalFfiError *signal_authenticated_chat_connection_info(SignalMutPointerChatConnectionInfo *out, SignalConstPointerAuthenticatedChatConnection chat); -SignalFfiError *signal_server_message_ack_destroy(SignalServerMessageAck *p); +SignalFfiError *signal_chat_service_disconnect_unauth(SignalCPromisebool *promise, SignalConstPointerTokioAsyncContext async_runtime, SignalConstPointerUnauthChat chat); -SignalFfiError *signal_server_message_ack_send(SignalCPromisebool *promise, const SignalTokioAsyncContext *async_runtime, const SignalServerMessageAck *ack); +SignalFfiError *signal_chat_service_disconnect_auth(SignalCPromisebool *promise, SignalConstPointerTokioAsyncContext async_runtime, SignalConstPointerAuthChat chat); -SignalFfiError *signal_tokio_async_context_destroy(SignalTokioAsyncContext *p); +SignalFfiError *signal_chat_service_connect_unauth(SignalCPromiseFfiChatServiceDebugInfo *promise, SignalConstPointerTokioAsyncContext async_runtime, SignalConstPointerUnauthChat chat); -SignalFfiError *signal_tokio_async_context_new(SignalTokioAsyncContext **out); +SignalFfiError *signal_chat_service_connect_auth(SignalCPromiseFfiChatServiceDebugInfo *promise, SignalConstPointerTokioAsyncContext async_runtime, SignalConstPointerAuthChat chat); -SignalFfiError *signal_tokio_async_context_cancel(const SignalTokioAsyncContext *context, uint64_t raw_cancellation_id); +SignalFfiError *signal_chat_service_unauth_send(SignalCPromiseFfiChatResponse *promise, SignalConstPointerTokioAsyncContext async_runtime, SignalConstPointerUnauthChat chat, SignalConstPointerHttpRequest http_request, uint32_t timeout_millis); -SignalFfiError *signal_pin_hash_destroy(SignalPinHash *p); +SignalFfiError *signal_chat_service_unauth_send_and_debug(SignalCPromiseFfiResponseAndDebugInfo *promise, SignalConstPointerTokioAsyncContext async_runtime, SignalConstPointerUnauthChat chat, SignalConstPointerHttpRequest http_request, uint32_t timeout_millis); -SignalFfiError *signal_pin_hash_clone(SignalPinHash **new_obj, const SignalPinHash *obj); +SignalFfiError *signal_chat_service_auth_send(SignalCPromiseFfiChatResponse *promise, SignalConstPointerTokioAsyncContext async_runtime, SignalConstPointerAuthChat chat, SignalConstPointerHttpRequest http_request, uint32_t timeout_millis); -SignalFfiError *signal_pin_hash_encryption_key(uint8_t (*out)[32], const SignalPinHash *ph); +SignalFfiError *signal_chat_service_auth_send_and_debug(SignalCPromiseFfiResponseAndDebugInfo *promise, SignalConstPointerTokioAsyncContext async_runtime, SignalConstPointerAuthChat chat, SignalConstPointerHttpRequest http_request, uint32_t timeout_millis); -SignalFfiError *signal_pin_hash_access_key(uint8_t (*out)[32], const SignalPinHash *ph); +SignalFfiError *signal_chat_service_set_listener_auth(SignalConstPointerTokioAsyncContext runtime, SignalConstPointerAuthChat chat, SignalConstPointerFfiChatListenerStruct listener); -SignalFfiError *signal_pin_hash_from_salt(SignalPinHash **out, SignalBorrowedBuffer pin, const uint8_t (*salt)[32]); +SignalFfiError *signal_chat_service_set_listener_unauth(SignalConstPointerTokioAsyncContext runtime, SignalConstPointerUnauthChat chat, SignalConstPointerFfiChatListenerStruct listener); -SignalFfiError *signal_pin_hash_from_username_mrenclave(SignalPinHash **out, SignalBorrowedBuffer pin, const char *username, SignalBorrowedBuffer mrenclave); +SignalFfiError *signal_server_message_ack_destroy(SignalMutPointerServerMessageAck p); + +SignalFfiError *signal_server_message_ack_send(SignalCPromisebool *promise, SignalConstPointerTokioAsyncContext async_runtime, SignalConstPointerServerMessageAck ack); + +SignalFfiError *signal_tokio_async_context_destroy(SignalMutPointerTokioAsyncContext p); + +SignalFfiError *signal_tokio_async_context_new(SignalMutPointerTokioAsyncContext *out); + +SignalFfiError *signal_tokio_async_context_cancel(SignalConstPointerTokioAsyncContext context, uint64_t raw_cancellation_id); + +SignalFfiError *signal_pin_hash_destroy(SignalMutPointerPinHash p); + +SignalFfiError *signal_pin_hash_clone(SignalMutPointerPinHash *new_obj, SignalConstPointerPinHash obj); + +SignalFfiError *signal_pin_hash_encryption_key(uint8_t (*out)[32], SignalConstPointerPinHash ph); + +SignalFfiError *signal_pin_hash_access_key(uint8_t (*out)[32], SignalConstPointerPinHash ph); + +SignalFfiError *signal_pin_hash_from_salt(SignalMutPointerPinHash *out, SignalBorrowedBuffer pin, const uint8_t (*salt)[32]); + +SignalFfiError *signal_pin_hash_from_username_mrenclave(SignalMutPointerPinHash *out, SignalBorrowedBuffer pin, const char *username, SignalBorrowedBuffer mrenclave); SignalFfiError *signal_pin_local_hash(const char **out, SignalBorrowedBuffer pin); @@ -1583,13 +2035,15 @@ SignalFfiError *signal_pin_verify_local_hash(bool *out, const char *encoded_hash SignalFfiError *signal_account_entropy_pool_generate(const char **out); +SignalFfiError *signal_account_entropy_pool_is_valid(bool *out, const char *account_entropy); + SignalFfiError *signal_account_entropy_pool_derive_svr_key(uint8_t (*out)[SignalSVR_KEY_LEN], const char *account_entropy); SignalFfiError *signal_account_entropy_pool_derive_backup_key(uint8_t (*out)[SignalBACKUP_KEY_LEN], const char *account_entropy); SignalFfiError *signal_backup_key_derive_backup_id(uint8_t (*out)[16], const uint8_t (*backup_key)[SignalBACKUP_KEY_LEN], const SignalServiceIdFixedWidthBinaryBytes *aci); -SignalFfiError *signal_backup_key_derive_ec_key(SignalPrivateKey **out, const uint8_t (*backup_key)[SignalBACKUP_KEY_LEN], const SignalServiceIdFixedWidthBinaryBytes *aci); +SignalFfiError *signal_backup_key_derive_ec_key(SignalMutPointerPrivateKey *out, const uint8_t (*backup_key)[SignalBACKUP_KEY_LEN], const SignalServiceIdFixedWidthBinaryBytes *aci); SignalFfiError *signal_backup_key_derive_local_backup_metadata_key(uint8_t (*out)[SignalLOCAL_BACKUP_METADATA_KEY_LEN], const uint8_t (*backup_key)[SignalBACKUP_KEY_LEN]); @@ -1599,53 +2053,53 @@ SignalFfiError *signal_backup_key_derive_media_encryption_key(uint8_t (*out)[Sig SignalFfiError *signal_backup_key_derive_thumbnail_transit_encryption_key(uint8_t (*out)[SignalMEDIA_ENCRYPTION_KEY_LEN], const uint8_t (*backup_key)[SignalBACKUP_KEY_LEN], const uint8_t (*media_id)[SignalMEDIA_ID_LEN]); -SignalFfiError *signal_svr2_client_new(SignalSgxClientState **out, SignalBorrowedBuffer mrenclave, SignalBorrowedBuffer attestation_msg, uint64_t current_timestamp); +SignalFfiError *signal_svr2_client_new(SignalMutPointerSgxClientState *out, SignalBorrowedBuffer mrenclave, SignalBorrowedBuffer attestation_msg, uint64_t current_timestamp); -SignalFfiError *signal_incremental_mac_destroy(SignalIncrementalMac *p); +SignalFfiError *signal_incremental_mac_destroy(SignalMutPointerIncrementalMac p); SignalFfiError *signal_incremental_mac_calculate_chunk_size(uint32_t *out, uint32_t data_size); -SignalFfiError *signal_incremental_mac_initialize(SignalIncrementalMac **out, SignalBorrowedBuffer key, uint32_t chunk_size); +SignalFfiError *signal_incremental_mac_initialize(SignalMutPointerIncrementalMac *out, SignalBorrowedBuffer key, uint32_t chunk_size); -SignalFfiError *signal_incremental_mac_update(SignalOwnedBuffer *out, SignalIncrementalMac *mac, SignalBorrowedBuffer bytes, uint32_t offset, uint32_t length); +SignalFfiError *signal_incremental_mac_update(SignalOwnedBuffer *out, SignalMutPointerIncrementalMac mac, SignalBorrowedBuffer bytes, uint32_t offset, uint32_t length); -SignalFfiError *signal_incremental_mac_finalize(SignalOwnedBuffer *out, SignalIncrementalMac *mac); +SignalFfiError *signal_incremental_mac_finalize(SignalOwnedBuffer *out, SignalMutPointerIncrementalMac mac); -SignalFfiError *signal_validating_mac_destroy(SignalValidatingMac *p); +SignalFfiError *signal_validating_mac_destroy(SignalMutPointerValidatingMac p); -SignalFfiError *signal_validating_mac_initialize(SignalValidatingMac **out, SignalBorrowedBuffer key, uint32_t chunk_size, SignalBorrowedBuffer digests); +SignalFfiError *signal_validating_mac_initialize(SignalMutPointerValidatingMac *out, SignalBorrowedBuffer key, uint32_t chunk_size, SignalBorrowedBuffer digests); -SignalFfiError *signal_validating_mac_update(int32_t *out, SignalValidatingMac *mac, SignalBorrowedBuffer bytes, uint32_t offset, uint32_t length); +SignalFfiError *signal_validating_mac_update(int32_t *out, SignalMutPointerValidatingMac mac, SignalBorrowedBuffer bytes, uint32_t offset, uint32_t length); -SignalFfiError *signal_validating_mac_finalize(int32_t *out, SignalValidatingMac *mac); +SignalFfiError *signal_validating_mac_finalize(int32_t *out, SignalMutPointerValidatingMac mac); -SignalFfiError *signal_message_backup_key_destroy(SignalMessageBackupKey *p); +SignalFfiError *signal_message_backup_key_destroy(SignalMutPointerMessageBackupKey p); -SignalFfiError *signal_message_backup_validation_outcome_destroy(SignalMessageBackupValidationOutcome *p); +SignalFfiError *signal_message_backup_validation_outcome_destroy(SignalMutPointerMessageBackupValidationOutcome p); -SignalFfiError *signal_message_backup_key_from_master_key(SignalMessageBackupKey **out, const uint8_t (*master_key)[32], const SignalServiceIdFixedWidthBinaryBytes *aci); +SignalFfiError *signal_message_backup_key_from_master_key(SignalMutPointerMessageBackupKey *out, const uint8_t (*master_key)[32], const SignalServiceIdFixedWidthBinaryBytes *aci); -SignalFfiError *signal_message_backup_key_from_account_entropy_pool(SignalMessageBackupKey **out, const char *account_entropy, const SignalServiceIdFixedWidthBinaryBytes *aci); +SignalFfiError *signal_message_backup_key_from_account_entropy_pool(SignalMutPointerMessageBackupKey *out, const char *account_entropy, const SignalServiceIdFixedWidthBinaryBytes *aci); -SignalFfiError *signal_message_backup_key_from_backup_key_and_backup_id(SignalMessageBackupKey **out, const uint8_t (*backup_key)[32], const uint8_t (*backup_id)[16]); +SignalFfiError *signal_message_backup_key_from_backup_key_and_backup_id(SignalMutPointerMessageBackupKey *out, const uint8_t (*backup_key)[32], const uint8_t (*backup_id)[16]); -SignalFfiError *signal_message_backup_key_get_hmac_key(uint8_t (*out)[32], const SignalMessageBackupKey *key); +SignalFfiError *signal_message_backup_key_get_hmac_key(uint8_t (*out)[32], SignalConstPointerMessageBackupKey key); -SignalFfiError *signal_message_backup_key_get_aes_key(uint8_t (*out)[32], const SignalMessageBackupKey *key); +SignalFfiError *signal_message_backup_key_get_aes_key(uint8_t (*out)[32], SignalConstPointerMessageBackupKey key); -SignalFfiError *signal_message_backup_validation_outcome_get_error_message(const char **out, const SignalMessageBackupValidationOutcome *outcome); +SignalFfiError *signal_message_backup_validation_outcome_get_error_message(const char **out, SignalConstPointerMessageBackupValidationOutcome outcome); -SignalFfiError *signal_message_backup_validation_outcome_get_unknown_fields(SignalStringArray *out, const SignalMessageBackupValidationOutcome *outcome); +SignalFfiError *signal_message_backup_validation_outcome_get_unknown_fields(SignalStringArray *out, SignalConstPointerMessageBackupValidationOutcome outcome); -SignalFfiError *signal_message_backup_validator_validate(SignalMessageBackupValidationOutcome **out, const SignalMessageBackupKey *key, const SignalInputStream *first_stream, const SignalInputStream *second_stream, uint64_t len, uint8_t purpose); +SignalFfiError *signal_message_backup_validator_validate(SignalMutPointerMessageBackupValidationOutcome *out, SignalConstPointerMessageBackupKey key, SignalConstPointerFfiInputStreamStruct first_stream, SignalConstPointerFfiInputStreamStruct second_stream, uint64_t len, uint8_t purpose); -SignalFfiError *signal_online_backup_validator_destroy(SignalOnlineBackupValidator *p); +SignalFfiError *signal_online_backup_validator_destroy(SignalMutPointerOnlineBackupValidator p); -SignalFfiError *signal_online_backup_validator_new(SignalOnlineBackupValidator **out, SignalBorrowedBuffer backup_info_frame, uint8_t purpose); +SignalFfiError *signal_online_backup_validator_new(SignalMutPointerOnlineBackupValidator *out, SignalBorrowedBuffer backup_info_frame, uint8_t purpose); -SignalFfiError *signal_online_backup_validator_add_frame(SignalOnlineBackupValidator *backup, SignalBorrowedBuffer frame); +SignalFfiError *signal_online_backup_validator_add_frame(SignalMutPointerOnlineBackupValidator backup, SignalBorrowedBuffer frame); -SignalFfiError *signal_online_backup_validator_finalize(SignalOnlineBackupValidator *backup); +SignalFfiError *signal_online_backup_validator_finalize(SignalMutPointerOnlineBackupValidator backup); SignalFfiError *signal_username_hash(uint8_t (*out)[32], const char *username); @@ -1662,11 +2116,11 @@ SignalFfiError *signal_username_link_create(SignalOwnedBuffer *out, const char * SignalFfiError *signal_username_link_decrypt_username(const char **out, SignalBorrowedBuffer entropy, SignalBorrowedBuffer encrypted_username); #if defined(SIGNAL_MEDIA_SUPPORTED) -SignalFfiError *signal_sanitized_metadata_destroy(SignalSanitizedMetadata *p); +SignalFfiError *signal_sanitized_metadata_destroy(SignalMutPointerSanitizedMetadata p); #endif #if defined(SIGNAL_MEDIA_SUPPORTED) -SignalFfiError *signal_sanitized_metadata_clone(SignalSanitizedMetadata **new_obj, const SignalSanitizedMetadata *obj); +SignalFfiError *signal_sanitized_metadata_clone(SignalMutPointerSanitizedMetadata *new_obj, SignalConstPointerSanitizedMetadata obj); #endif #if defined(SIGNAL_MEDIA_SUPPORTED) @@ -1674,23 +2128,23 @@ SignalFfiError *signal_signal_media_check_available(void); #endif #if defined(SIGNAL_MEDIA_SUPPORTED) -SignalFfiError *signal_mp4_sanitizer_sanitize(SignalSanitizedMetadata **out, const SignalInputStream *input, uint64_t len); +SignalFfiError *signal_mp4_sanitizer_sanitize(SignalMutPointerSanitizedMetadata *out, SignalConstPointerFfiInputStreamStruct input, uint64_t len); #endif #if defined(SIGNAL_MEDIA_SUPPORTED) -SignalFfiError *signal_webp_sanitizer_sanitize(const SignalSyncInputStream *input); +SignalFfiError *signal_webp_sanitizer_sanitize(SignalConstPointerFfiSyncInputStreamStruct input); #endif #if defined(SIGNAL_MEDIA_SUPPORTED) -SignalFfiError *signal_sanitized_metadata_get_metadata(SignalOwnedBuffer *out, const SignalSanitizedMetadata *sanitized); +SignalFfiError *signal_sanitized_metadata_get_metadata(SignalOwnedBuffer *out, SignalConstPointerSanitizedMetadata sanitized); #endif #if defined(SIGNAL_MEDIA_SUPPORTED) -SignalFfiError *signal_sanitized_metadata_get_data_offset(uint64_t *out, const SignalSanitizedMetadata *sanitized); +SignalFfiError *signal_sanitized_metadata_get_data_offset(uint64_t *out, SignalConstPointerSanitizedMetadata sanitized); #endif #if defined(SIGNAL_MEDIA_SUPPORTED) -SignalFfiError *signal_sanitized_metadata_get_data_len(uint64_t *out, const SignalSanitizedMetadata *sanitized); +SignalFfiError *signal_sanitized_metadata_get_data_len(uint64_t *out, SignalConstPointerSanitizedMetadata sanitized); #endif #endif /* SIGNAL_FFI_H_ */ diff --git a/pkg/libsignalgo/message.go b/pkg/libsignalgo/message.go index 43a1a39..d512d6f 100644 --- a/pkg/libsignalgo/message.go +++ b/pkg/libsignalgo/message.go @@ -1,5 +1,6 @@ // mautrix-signal - A Matrix-signal puppeting bridge. // Copyright (C) 2023 Sumner Evans +// Copyright (C) 2025 Tulir Asokan // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU Affero General Public License as published by @@ -24,16 +25,38 @@ import "C" import ( "context" "runtime" + "time" ) +func Encrypt(ctx context.Context, plaintext []byte, forAddress *Address, sessionStore SessionStore, identityKeyStore IdentityKeyStore) (*CiphertextMessage, error) { + var ciphertextMessage C.SignalMutPointerCiphertextMessage + var now C.uint64_t = C.uint64_t(time.Now().Unix()) + callbackCtx := NewCallbackContext(ctx) + defer callbackCtx.Unref() + signalFfiError := C.signal_encrypt_message( + &ciphertextMessage, + BytesToBuffer(plaintext), + forAddress.constPtr(), + callbackCtx.wrapSessionStore(sessionStore), + callbackCtx.wrapIdentityKeyStore(identityKeyStore), + now, + ) + runtime.KeepAlive(plaintext) + runtime.KeepAlive(forAddress) + if signalFfiError != nil { + return nil, callbackCtx.wrapError(signalFfiError) + } + return wrapCiphertextMessage(ciphertextMessage.raw), nil +} + func Decrypt(ctx context.Context, message *Message, fromAddress *Address, sessionStore SessionStore, identityStore IdentityKeyStore) ([]byte, error) { callbackCtx := NewCallbackContext(ctx) defer callbackCtx.Unref() var decrypted C.SignalOwnedBuffer = C.SignalOwnedBuffer{} signalFfiError := C.signal_decrypt_message( &decrypted, - message.ptr, - fromAddress.ptr, + message.constPtr(), + fromAddress.constPtr(), callbackCtx.wrapSessionStore(sessionStore), callbackCtx.wrapIdentityKeyStore(identityStore), ) @@ -57,28 +80,36 @@ func wrapMessage(ptr *C.SignalMessage) *Message { } func DeserializeMessage(serialized []byte) (*Message, error) { - var m *C.SignalMessage + var m C.SignalMutPointerSignalMessage signalFfiError := C.signal_message_deserialize(&m, BytesToBuffer(serialized)) runtime.KeepAlive(serialized) if signalFfiError != nil { return nil, wrapError(signalFfiError) } - return wrapMessage(m), nil + return wrapMessage(m.raw), nil +} + +func (m *Message) mutPtr() C.SignalMutPointerSignalMessage { + return C.SignalMutPointerSignalMessage{m.ptr} +} + +func (m *Message) constPtr() C.SignalConstPointerSignalMessage { + return C.SignalConstPointerSignalMessage{m.ptr} } func (m *Message) Clone() (*Message, error) { - var cloned *C.SignalMessage - signalFfiError := C.signal_message_clone(&cloned, m.ptr) + var cloned C.SignalMutPointerSignalMessage + signalFfiError := C.signal_message_clone(&cloned, m.constPtr()) runtime.KeepAlive(m) if signalFfiError != nil { return nil, wrapError(signalFfiError) } - return wrapMessage(cloned), nil + return wrapMessage(cloned.raw), nil } func (m *Message) Destroy() error { m.CancelFinalizer() - return wrapError(C.signal_message_destroy(m.ptr)) + return wrapError(C.signal_message_destroy(m.mutPtr())) } func (m *Message) CancelFinalizer() { @@ -87,7 +118,7 @@ func (m *Message) CancelFinalizer() { func (m *Message) GetBody() ([]byte, error) { var body C.SignalOwnedBuffer = C.SignalOwnedBuffer{} - signalFfiError := C.signal_message_get_body(&body, m.ptr) + signalFfiError := C.signal_message_get_body(&body, m.constPtr()) runtime.KeepAlive(m) if signalFfiError != nil { return nil, wrapError(signalFfiError) @@ -97,7 +128,7 @@ func (m *Message) GetBody() ([]byte, error) { func (m *Message) Serialize() ([]byte, error) { var serialized C.SignalOwnedBuffer = C.SignalOwnedBuffer{} - signalFfiError := C.signal_message_get_serialized(&serialized, m.ptr) + signalFfiError := C.signal_message_get_serialized(&serialized, m.constPtr()) runtime.KeepAlive(m) if signalFfiError != nil { return nil, wrapError(signalFfiError) @@ -107,7 +138,7 @@ func (m *Message) Serialize() ([]byte, error) { func (m *Message) GetMessageVersion() (uint32, error) { var messageVersion C.uint32_t - signalFfiError := C.signal_message_get_message_version(&messageVersion, m.ptr) + signalFfiError := C.signal_message_get_message_version(&messageVersion, m.constPtr()) runtime.KeepAlive(m) if signalFfiError != nil { return 0, wrapError(signalFfiError) @@ -117,7 +148,7 @@ func (m *Message) GetMessageVersion() (uint32, error) { func (m *Message) GetCounter() (uint32, error) { var counter C.uint32_t - signalFfiError := C.signal_message_get_counter(&counter, m.ptr) + signalFfiError := C.signal_message_get_counter(&counter, m.constPtr()) runtime.KeepAlive(m) if signalFfiError != nil { return 0, wrapError(signalFfiError) @@ -127,7 +158,13 @@ func (m *Message) GetCounter() (uint32, error) { func (m *Message) VerifyMAC(sender, receiver *PublicKey, macKey []byte) (bool, error) { var result C.bool - signalFfiError := C.signal_message_verify_mac(&result, m.ptr, sender.ptr, receiver.ptr, BytesToBuffer(macKey)) + signalFfiError := C.signal_message_verify_mac( + &result, + m.constPtr(), + sender.constPtr(), + receiver.constPtr(), + BytesToBuffer(macKey), + ) runtime.KeepAlive(m) runtime.KeepAlive(sender) runtime.KeepAlive(receiver) diff --git a/pkg/libsignalgo/plaintextcontent.go b/pkg/libsignalgo/plaintextcontent.go index 6503c5d..f395f0b 100644 --- a/pkg/libsignalgo/plaintextcontent.go +++ b/pkg/libsignalgo/plaintextcontent.go @@ -1,5 +1,6 @@ // mautrix-signal - A Matrix-signal puppeting bridge. // Copyright (C) 2023 Sumner Evans +// Copyright (C) 2025 Tulir Asokan // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU Affero General Public License as published by @@ -35,38 +36,52 @@ func wrapPlaintextContent(ptr *C.SignalPlaintextContent) *PlaintextContent { } func PlaintextContentFromDecryptionErrorMessage(message *DecryptionErrorMessage) (*PlaintextContent, error) { - var pc *C.SignalPlaintextContent - signalFfiError := C.signal_plaintext_content_from_decryption_error_message(&pc, message.ptr) + var pc C.SignalMutPointerPlaintextContent + signalFfiError := C.signal_plaintext_content_from_decryption_error_message( + &pc, + message.constPtr(), + ) runtime.KeepAlive(message) if signalFfiError != nil { return nil, wrapError(signalFfiError) } - return wrapPlaintextContent(pc), nil + return wrapPlaintextContent(pc.raw), nil } func DeserializePlaintextContent(plaintextContentBytes []byte) (*PlaintextContent, error) { - var pc *C.SignalPlaintextContent + var pc C.SignalMutPointerPlaintextContent signalFfiError := C.signal_plaintext_content_deserialize(&pc, BytesToBuffer(plaintextContentBytes)) runtime.KeepAlive(plaintextContentBytes) if signalFfiError != nil { return nil, wrapError(signalFfiError) } - return wrapPlaintextContent(pc), nil + return wrapPlaintextContent(pc.raw), nil +} + +func (pc *PlaintextContent) mutPtr() C.SignalMutPointerPlaintextContent { + return C.SignalMutPointerPlaintextContent{pc.ptr} +} + +func (pc *PlaintextContent) constPtr() C.SignalConstPointerPlaintextContent { + return C.SignalConstPointerPlaintextContent{pc.ptr} } func (pc *PlaintextContent) Clone() (*PlaintextContent, error) { - var cloned *C.SignalPlaintextContent - signalFfiError := C.signal_plaintext_content_clone(&cloned, pc.ptr) + var cloned C.SignalMutPointerPlaintextContent + signalFfiError := C.signal_plaintext_content_clone( + &cloned, + pc.constPtr(), + ) runtime.KeepAlive(pc) if signalFfiError != nil { return nil, wrapError(signalFfiError) } - return wrapPlaintextContent(cloned), nil + return wrapPlaintextContent(cloned.raw), nil } func (pc *PlaintextContent) Destroy() error { pc.CancelFinalizer() - return wrapError(C.signal_plaintext_content_destroy(pc.ptr)) + return wrapError(C.signal_plaintext_content_destroy(pc.mutPtr())) } func (pc *PlaintextContent) CancelFinalizer() { @@ -75,7 +90,7 @@ func (pc *PlaintextContent) CancelFinalizer() { func (pc *PlaintextContent) Serialize() ([]byte, error) { var serialized C.SignalOwnedBuffer = C.SignalOwnedBuffer{} - signalFfiError := C.signal_plaintext_content_serialize(&serialized, pc.ptr) + signalFfiError := C.signal_plaintext_content_serialize(&serialized, pc.constPtr()) runtime.KeepAlive(pc) if signalFfiError != nil { return nil, wrapError(signalFfiError) @@ -85,7 +100,7 @@ func (pc *PlaintextContent) Serialize() ([]byte, error) { func (pc *PlaintextContent) GetBody() ([]byte, error) { var body C.SignalOwnedBuffer = C.SignalOwnedBuffer{} - signalFfiError := C.signal_plaintext_content_get_body(&body, pc.ptr) + signalFfiError := C.signal_plaintext_content_get_body(&body, pc.constPtr()) runtime.KeepAlive(pc) if signalFfiError != nil { return nil, wrapError(signalFfiError) diff --git a/pkg/libsignalgo/prekey.go b/pkg/libsignalgo/prekey.go index 82b2cd1..0c56c71 100644 --- a/pkg/libsignalgo/prekey.go +++ b/pkg/libsignalgo/prekey.go @@ -1,5 +1,6 @@ // mautrix-signal - A Matrix-signal puppeting bridge. // Copyright (C) 2023 Sumner Evans +// Copyright (C) 2025 Tulir Asokan // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU Affero General Public License as published by @@ -32,8 +33,8 @@ func DecryptPreKey(ctx context.Context, preKeyMessage *PreKeyMessage, fromAddres var decrypted C.SignalOwnedBuffer = C.SignalOwnedBuffer{} signalFfiError := C.signal_decrypt_pre_key_message( &decrypted, - preKeyMessage.ptr, - fromAddress.ptr, + preKeyMessage.constPtr(), + fromAddress.constPtr(), callbackCtx.wrapSessionStore(sessionStore), callbackCtx.wrapIdentityKeyStore(identityStore), callbackCtx.wrapPreKeyStore(preKeyStore), @@ -60,14 +61,19 @@ func wrapPreKeyRecord(ptr *C.SignalPreKeyRecord) *PreKeyRecord { } func NewPreKeyRecord(id uint32, publicKey *PublicKey, privateKey *PrivateKey) (*PreKeyRecord, error) { - var pkr *C.SignalPreKeyRecord - signalFfiError := C.signal_pre_key_record_new(&pkr, C.uint32_t(id), publicKey.ptr, privateKey.ptr) + var pkr C.SignalMutPointerPreKeyRecord + signalFfiError := C.signal_pre_key_record_new( + &pkr, + C.uint32_t(id), + publicKey.constPtr(), + privateKey.constPtr(), + ) runtime.KeepAlive(publicKey) runtime.KeepAlive(privateKey) if signalFfiError != nil { return nil, wrapError(signalFfiError) } - return wrapPreKeyRecord(pkr), nil + return wrapPreKeyRecord(pkr.raw), nil } func NewPreKeyRecordFromPrivateKey(id uint32, privateKey *PrivateKey) (*PreKeyRecord, error) { @@ -79,28 +85,36 @@ func NewPreKeyRecordFromPrivateKey(id uint32, privateKey *PrivateKey) (*PreKeyRe } func DeserializePreKeyRecord(serialized []byte) (*PreKeyRecord, error) { - var pkr *C.SignalPreKeyRecord + var pkr C.SignalMutPointerPreKeyRecord signalFfiError := C.signal_pre_key_record_deserialize(&pkr, BytesToBuffer(serialized)) runtime.KeepAlive(serialized) if signalFfiError != nil { return nil, wrapError(signalFfiError) } - return wrapPreKeyRecord(pkr), nil + return wrapPreKeyRecord(pkr.raw), nil +} + +func (pkr *PreKeyRecord) mutPtr() C.SignalMutPointerPreKeyRecord { + return C.SignalMutPointerPreKeyRecord{pkr.ptr} +} + +func (pkr *PreKeyRecord) constPtr() C.SignalConstPointerPreKeyRecord { + return C.SignalConstPointerPreKeyRecord{pkr.ptr} } func (pkr *PreKeyRecord) Clone() (*PreKeyRecord, error) { - var cloned *C.SignalPreKeyRecord - signalFfiError := C.signal_pre_key_record_clone(&cloned, pkr.ptr) + var cloned C.SignalMutPointerPreKeyRecord + signalFfiError := C.signal_pre_key_record_clone(&cloned, pkr.constPtr()) runtime.KeepAlive(pkr) if signalFfiError != nil { return nil, wrapError(signalFfiError) } - return wrapPreKeyRecord(cloned), nil + return wrapPreKeyRecord(cloned.raw), nil } func (pkr *PreKeyRecord) Destroy() error { pkr.CancelFinalizer() - return wrapError(C.signal_pre_key_record_destroy(pkr.ptr)) + return wrapError(C.signal_pre_key_record_destroy(pkr.mutPtr())) } func (pkr *PreKeyRecord) CancelFinalizer() { @@ -109,7 +123,7 @@ func (pkr *PreKeyRecord) CancelFinalizer() { func (pkr *PreKeyRecord) Serialize() ([]byte, error) { var serialized C.SignalOwnedBuffer = C.SignalOwnedBuffer{} - signalFfiError := C.signal_pre_key_record_serialize(&serialized, pkr.ptr) + signalFfiError := C.signal_pre_key_record_serialize(&serialized, pkr.constPtr()) runtime.KeepAlive(pkr) if signalFfiError != nil { return nil, wrapError(signalFfiError) @@ -119,7 +133,7 @@ func (pkr *PreKeyRecord) Serialize() ([]byte, error) { func (pkr *PreKeyRecord) GetID() (uint32, error) { var id C.uint32_t - signalFfiError := C.signal_pre_key_record_get_id(&id, pkr.ptr) + signalFfiError := C.signal_pre_key_record_get_id(&id, pkr.constPtr()) runtime.KeepAlive(pkr) if signalFfiError != nil { return 0, wrapError(signalFfiError) @@ -128,21 +142,21 @@ func (pkr *PreKeyRecord) GetID() (uint32, error) { } func (pkr *PreKeyRecord) GetPublicKey() (*PublicKey, error) { - var pub *C.SignalPublicKey - signalFfiError := C.signal_pre_key_record_get_public_key(&pub, pkr.ptr) + var pub C.SignalMutPointerPublicKey + signalFfiError := C.signal_pre_key_record_get_public_key(&pub, pkr.constPtr()) runtime.KeepAlive(pkr) if signalFfiError != nil { return nil, wrapError(signalFfiError) } - return wrapPublicKey(pub), nil + return wrapPublicKey(pub.raw), nil } func (pkr *PreKeyRecord) GetPrivateKey() (*PrivateKey, error) { - var priv *C.SignalPrivateKey - signalFfiError := C.signal_pre_key_record_get_private_key(&priv, pkr.ptr) + var priv C.SignalMutPointerPrivateKey + signalFfiError := C.signal_pre_key_record_get_private_key(&priv, pkr.constPtr()) runtime.KeepAlive(pkr) if signalFfiError != nil { return nil, wrapError(signalFfiError) } - return wrapPrivateKey(priv), nil + return wrapPrivateKey(priv.raw), nil } diff --git a/pkg/libsignalgo/prekeybundle.go b/pkg/libsignalgo/prekeybundle.go index 905496c..7fd2e34 100644 --- a/pkg/libsignalgo/prekeybundle.go +++ b/pkg/libsignalgo/prekeybundle.go @@ -1,5 +1,6 @@ // mautrix-signal - A Matrix-signal puppeting bridge. // Copyright (C) 2023 Sumner Evans +// Copyright (C) 2025 Tulir Asokan // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU Affero General Public License as published by @@ -32,8 +33,8 @@ func ProcessPreKeyBundle(ctx context.Context, bundle *PreKeyBundle, forAddress * defer callbackCtx.Unref() var now C.uint64_t = C.uint64_t(time.Now().Unix()) signalFfiError := C.signal_process_prekey_bundle( - bundle.ptr, - forAddress.ptr, + bundle.constPtr(), + forAddress.constPtr(), callbackCtx.wrapSessionStore(sessionStore), callbackCtx.wrapIdentityKeyStore(identityStore), now, @@ -67,7 +68,7 @@ func NewPreKeyBundle( kyberPreKeySignature []byte, identityKey *IdentityKey, ) (*PreKeyBundle, error) { - var pkb *C.SignalPreKeyBundle + var pkb C.SignalMutPointerPreKeyBundle var zero uint32 = 0 var kyberSignatureBuffer = EmptyBorrowedBuffer() if preKey == nil { @@ -85,13 +86,13 @@ func NewPreKeyBundle( C.uint32_t(registrationID), C.uint32_t(deviceID), C.uint32_t(preKeyID), - preKey.ptr, + preKey.constPtr(), C.uint32_t(signedPreKeyID), - signedPreKey.ptr, + signedPreKey.constPtr(), BytesToBuffer(signedPreKeySignature), - identityKey.publicKey.ptr, + identityKey.publicKey.constPtr(), C.uint32_t(kyberPreKeyID), - kyberPreKey.ptr, + kyberPreKey.constPtr(), kyberSignatureBuffer, ) runtime.KeepAlive(preKey) @@ -103,22 +104,30 @@ func NewPreKeyBundle( if signalFfiError != nil { return nil, wrapError(signalFfiError) } - return wrapPreKeyBundle(pkb), nil + return wrapPreKeyBundle(pkb.raw), nil +} + +func (pkb *PreKeyBundle) mutPtr() C.SignalMutPointerPreKeyBundle { + return C.SignalMutPointerPreKeyBundle{pkb.ptr} +} + +func (pkb *PreKeyBundle) constPtr() C.SignalConstPointerPreKeyBundle { + return C.SignalConstPointerPreKeyBundle{pkb.ptr} } func (pkb *PreKeyBundle) Clone() (*PreKeyBundle, error) { - var cloned *C.SignalPreKeyBundle - signalFfiError := C.signal_pre_key_bundle_clone(&cloned, pkb.ptr) + var cloned C.SignalMutPointerPreKeyBundle + signalFfiError := C.signal_pre_key_bundle_clone(&cloned, pkb.constPtr()) if signalFfiError != nil { return nil, wrapError(signalFfiError) } runtime.KeepAlive(pkb) - return wrapPreKeyBundle(cloned), nil + return wrapPreKeyBundle(cloned.raw), nil } func (pkb *PreKeyBundle) Destroy() error { pkb.CancelFinalizer() - return wrapError(C.signal_pre_key_bundle_destroy(pkb.ptr)) + return wrapError(C.signal_pre_key_bundle_destroy(pkb.mutPtr())) } func (pkb *PreKeyBundle) CancelFinalizer() { @@ -126,11 +135,11 @@ func (pkb *PreKeyBundle) CancelFinalizer() { } func (pkb *PreKeyBundle) GetIdentityKey() (*IdentityKey, error) { - var pk *C.SignalPublicKey - signalFfiError := C.signal_pre_key_bundle_get_identity_key(&pk, pkb.ptr) + var pk C.SignalMutPointerPublicKey + signalFfiError := C.signal_pre_key_bundle_get_identity_key(&pk, pkb.constPtr()) if signalFfiError != nil { return nil, wrapError(signalFfiError) } runtime.KeepAlive(pkb) - return NewIdentityKeyFromPublicKey(wrapPublicKey(pk)) + return NewIdentityKeyFromPublicKey(wrapPublicKey(pk.raw)) } diff --git a/pkg/libsignalgo/prekeymessage.go b/pkg/libsignalgo/prekeymessage.go index 435cf5e..6bff0bb 100644 --- a/pkg/libsignalgo/prekeymessage.go +++ b/pkg/libsignalgo/prekeymessage.go @@ -1,5 +1,6 @@ // mautrix-signal - A Matrix-signal puppeting bridge. // Copyright (C) 2023 Sumner Evans +// Copyright (C) 2025 Tulir Asokan // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU Affero General Public License as published by @@ -35,28 +36,36 @@ func wrapPreKeyMessage(ptr *C.SignalPreKeySignalMessage) *PreKeyMessage { } func DeserializePreKeyMessage(serialized []byte) (*PreKeyMessage, error) { - var m *C.SignalPreKeySignalMessage + var m C.SignalMutPointerPreKeySignalMessage signalFfiError := C.signal_pre_key_signal_message_deserialize(&m, BytesToBuffer(serialized)) runtime.KeepAlive(serialized) if signalFfiError != nil { return nil, wrapError(signalFfiError) } - return wrapPreKeyMessage(m), nil + return wrapPreKeyMessage(m.raw), nil +} + +func (m *PreKeyMessage) mutPtr() C.SignalMutPointerPreKeySignalMessage { + return C.SignalMutPointerPreKeySignalMessage{m.ptr} +} + +func (m *PreKeyMessage) constPtr() C.SignalConstPointerPreKeySignalMessage { + return C.SignalConstPointerPreKeySignalMessage{m.ptr} } func (m *PreKeyMessage) Clone() (*PreKeyMessage, error) { - var cloned *C.SignalPreKeySignalMessage - signalFfiError := C.signal_pre_key_signal_message_clone(&cloned, m.ptr) + var cloned C.SignalMutPointerPreKeySignalMessage + signalFfiError := C.signal_pre_key_signal_message_clone(&cloned, m.constPtr()) runtime.KeepAlive(m) if signalFfiError != nil { return nil, wrapError(signalFfiError) } - return wrapPreKeyMessage(cloned), nil + return wrapPreKeyMessage(cloned.raw), nil } func (m *PreKeyMessage) Destroy() error { m.CancelFinalizer() - return wrapError(C.signal_pre_key_signal_message_destroy(m.ptr)) + return wrapError(C.signal_pre_key_signal_message_destroy(m.mutPtr())) } func (m *PreKeyMessage) CancelFinalizer() { @@ -65,7 +74,7 @@ func (m *PreKeyMessage) CancelFinalizer() { func (m *PreKeyMessage) Serialize() ([]byte, error) { var serialized C.SignalOwnedBuffer = C.SignalOwnedBuffer{} - signalFfiError := C.signal_pre_key_signal_message_serialize(&serialized, m.ptr) + signalFfiError := C.signal_pre_key_signal_message_serialize(&serialized, m.constPtr()) runtime.KeepAlive(m) if signalFfiError != nil { return nil, wrapError(signalFfiError) @@ -75,7 +84,7 @@ func (m *PreKeyMessage) Serialize() ([]byte, error) { func (m *PreKeyMessage) GetVersion() (uint32, error) { var version C.uint - signalFfiError := C.signal_pre_key_signal_message_get_version(&version, m.ptr) + signalFfiError := C.signal_pre_key_signal_message_get_version(&version, m.constPtr()) runtime.KeepAlive(m) if signalFfiError != nil { return 0, wrapError(signalFfiError) @@ -85,7 +94,7 @@ func (m *PreKeyMessage) GetVersion() (uint32, error) { func (m *PreKeyMessage) GetRegistrationID() (uint32, error) { var registrationID C.uint - signalFfiError := C.signal_pre_key_signal_message_get_registration_id(®istrationID, m.ptr) + signalFfiError := C.signal_pre_key_signal_message_get_registration_id(®istrationID, m.constPtr()) runtime.KeepAlive(m) if signalFfiError != nil { return 0, wrapError(signalFfiError) @@ -95,7 +104,7 @@ func (m *PreKeyMessage) GetRegistrationID() (uint32, error) { func (m *PreKeyMessage) GetPreKeyID() (*uint32, error) { var preKeyID C.uint - signalFfiError := C.signal_pre_key_signal_message_get_pre_key_id(&preKeyID, m.ptr) + signalFfiError := C.signal_pre_key_signal_message_get_pre_key_id(&preKeyID, m.constPtr()) runtime.KeepAlive(m) if signalFfiError != nil { return nil, wrapError(signalFfiError) @@ -108,7 +117,7 @@ func (m *PreKeyMessage) GetPreKeyID() (*uint32, error) { func (m *PreKeyMessage) GetSignedPreKeyID() (uint32, error) { var signedPreKeyID C.uint - signalFfiError := C.signal_pre_key_signal_message_get_signed_pre_key_id(&signedPreKeyID, m.ptr) + signalFfiError := C.signal_pre_key_signal_message_get_signed_pre_key_id(&signedPreKeyID, m.constPtr()) runtime.KeepAlive(m) if signalFfiError != nil { return 0, wrapError(signalFfiError) @@ -117,31 +126,31 @@ func (m *PreKeyMessage) GetSignedPreKeyID() (uint32, error) { } func (m *PreKeyMessage) GetBaseKey() (*PublicKey, error) { - var publicKey *C.SignalPublicKey - signalFfiError := C.signal_pre_key_signal_message_get_base_key(&publicKey, m.ptr) + var publicKey C.SignalMutPointerPublicKey + signalFfiError := C.signal_pre_key_signal_message_get_base_key(&publicKey, m.constPtr()) runtime.KeepAlive(m) if signalFfiError != nil { return nil, wrapError(signalFfiError) } - return wrapPublicKey(publicKey), nil + return wrapPublicKey(publicKey.raw), nil } func (m *PreKeyMessage) GetIdentityKey() (*IdentityKey, error) { - var publicKey *C.SignalPublicKey - signalFfiError := C.signal_pre_key_signal_message_get_identity_key(&publicKey, m.ptr) + var publicKey C.SignalMutPointerPublicKey + signalFfiError := C.signal_pre_key_signal_message_get_identity_key(&publicKey, m.constPtr()) runtime.KeepAlive(m) if signalFfiError != nil { return nil, wrapError(signalFfiError) } - return &IdentityKey{wrapPublicKey(publicKey)}, nil + return &IdentityKey{wrapPublicKey(publicKey.raw)}, nil } func (m *PreKeyMessage) GetSignalMessage() (*Message, error) { - var message *C.SignalMessage - signalFfiError := C.signal_pre_key_signal_message_get_signal_message(&message, m.ptr) + var message C.SignalMutPointerSignalMessage + signalFfiError := C.signal_pre_key_signal_message_get_signal_message(&message, m.constPtr()) runtime.KeepAlive(m) if signalFfiError != nil { return nil, wrapError(signalFfiError) } - return wrapMessage(message), nil + return wrapMessage(message.raw), nil } diff --git a/pkg/libsignalgo/prekeystore.go b/pkg/libsignalgo/prekeystore.go index c678ade..c9b0469 100644 --- a/pkg/libsignalgo/prekeystore.go +++ b/pkg/libsignalgo/prekeystore.go @@ -1,5 +1,6 @@ // mautrix-signal - A Matrix-signal puppeting bridge. // Copyright (C) 2023 Sumner Evans +// Copyright (C) 2025 Tulir Asokan // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU Affero General Public License as published by @@ -69,11 +70,11 @@ func signal_remove_pre_key_callback(storeCtx unsafe.Pointer, id C.uint32_t) C.in }) } -func (ctx *CallbackContext) wrapPreKeyStore(store PreKeyStore) *C.SignalPreKeyStore { - return &C.SignalPreKeyStore{ +func (ctx *CallbackContext) wrapPreKeyStore(store PreKeyStore) C.SignalConstPointerFfiPreKeyStoreStruct { + return C.SignalConstPointerFfiPreKeyStoreStruct{&C.SignalPreKeyStore{ ctx: wrapStore(ctx, store), load_pre_key: C.SignalLoadPreKey(C.signal_load_pre_key_callback), store_pre_key: C.SignalStorePreKey(C.signal_store_pre_key_callback), remove_pre_key: C.SignalRemovePreKey(C.signal_remove_pre_key_callback), - } + }} } diff --git a/pkg/libsignalgo/privatekey.go b/pkg/libsignalgo/privatekey.go index fa78a77..3703727 100644 --- a/pkg/libsignalgo/privatekey.go +++ b/pkg/libsignalgo/privatekey.go @@ -1,5 +1,6 @@ // mautrix-signal - A Matrix-signal puppeting bridge. // Copyright (C) 2023 Sumner Evans +// Copyright (C) 2025 Tulir Asokan // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU Affero General Public License as published by @@ -35,37 +36,45 @@ func wrapPrivateKey(ptr *C.SignalPrivateKey) *PrivateKey { } func GeneratePrivateKey() (*PrivateKey, error) { - var pk *C.SignalPrivateKey + var pk C.SignalMutPointerPrivateKey signalFfiError := C.signal_privatekey_generate(&pk) if signalFfiError != nil { return nil, wrapError(signalFfiError) } - return wrapPrivateKey(pk), nil + return wrapPrivateKey(pk.raw), nil } func DeserializePrivateKey(keyData []byte) (*PrivateKey, error) { - var pk *C.SignalPrivateKey + var pk C.SignalMutPointerPrivateKey signalFfiError := C.signal_privatekey_deserialize(&pk, BytesToBuffer(keyData)) runtime.KeepAlive(keyData) if signalFfiError != nil { return nil, wrapError(signalFfiError) } - return wrapPrivateKey(pk), nil + return wrapPrivateKey(pk.raw), nil +} + +func (pk *PrivateKey) mutPtr() C.SignalMutPointerPrivateKey { + return C.SignalMutPointerPrivateKey{pk.ptr} +} + +func (pk *PrivateKey) constPtr() C.SignalConstPointerPrivateKey { + return C.SignalConstPointerPrivateKey{pk.ptr} } func (pk *PrivateKey) Clone() (*PrivateKey, error) { - var cloned *C.SignalPrivateKey - signalFfiError := C.signal_privatekey_clone(&cloned, pk.ptr) + var cloned C.SignalMutPointerPrivateKey + signalFfiError := C.signal_privatekey_clone(&cloned, pk.constPtr()) runtime.KeepAlive(pk) if signalFfiError != nil { return nil, wrapError(signalFfiError) } - return wrapPrivateKey(cloned), nil + return wrapPrivateKey(cloned.raw), nil } func (pk *PrivateKey) Destroy() error { pk.CancelFinalizer() - return wrapError(C.signal_privatekey_destroy(pk.ptr)) + return wrapError(C.signal_privatekey_destroy(pk.mutPtr())) } func (pk *PrivateKey) CancelFinalizer() { @@ -73,18 +82,18 @@ func (pk *PrivateKey) CancelFinalizer() { } func (pk *PrivateKey) GetPublicKey() (*PublicKey, error) { - var pub *C.SignalPublicKey - signalFfiError := C.signal_privatekey_get_public_key(&pub, pk.ptr) + var pub C.SignalMutPointerPublicKey + signalFfiError := C.signal_privatekey_get_public_key(&pub, pk.constPtr()) runtime.KeepAlive(pk) if signalFfiError != nil { return nil, wrapError(signalFfiError) } - return wrapPublicKey(pub), nil + return wrapPublicKey(pub.raw), nil } func (pk *PrivateKey) Serialize() ([]byte, error) { var serialized C.SignalOwnedBuffer = C.SignalOwnedBuffer{} - signalFfiError := C.signal_privatekey_serialize(&serialized, pk.ptr) + signalFfiError := C.signal_privatekey_serialize(&serialized, pk.constPtr()) runtime.KeepAlive(pk) if signalFfiError != nil { return nil, wrapError(signalFfiError) @@ -94,7 +103,7 @@ func (pk *PrivateKey) Serialize() ([]byte, error) { func (pk *PrivateKey) Sign(message []byte) ([]byte, error) { var signed C.SignalOwnedBuffer = C.SignalOwnedBuffer{} - signalFfiError := C.signal_privatekey_sign(&signed, pk.ptr, BytesToBuffer(message)) + signalFfiError := C.signal_privatekey_sign(&signed, pk.constPtr(), BytesToBuffer(message)) runtime.KeepAlive(pk) runtime.KeepAlive(message) if signalFfiError != nil { @@ -105,7 +114,7 @@ func (pk *PrivateKey) Sign(message []byte) ([]byte, error) { func (pk *PrivateKey) Agree(publicKey *PublicKey) ([]byte, error) { var agreed C.SignalOwnedBuffer = C.SignalOwnedBuffer{} - signalFfiError := C.signal_privatekey_agree(&agreed, pk.ptr, publicKey.ptr) + signalFfiError := C.signal_privatekey_agree(&agreed, pk.constPtr(), publicKey.constPtr()) runtime.KeepAlive(pk) runtime.KeepAlive(publicKey) if signalFfiError != nil { diff --git a/pkg/libsignalgo/profilekey.go b/pkg/libsignalgo/profilekey.go index 82e3036..c78c9d1 100644 --- a/pkg/libsignalgo/profilekey.go +++ b/pkg/libsignalgo/profilekey.go @@ -1,5 +1,6 @@ // mautrix-signal - A Matrix-signal puppeting bridge. // Copyright (C) 2023 Scott Weber +// Copyright (C) 2025 Tulir Asokan // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU Affero General Public License as published by @@ -148,7 +149,7 @@ func CreateProfileKeyCredentialRequestContext(serverPublicParams *ServerPublicPa signalFfiError := C.signal_server_public_params_create_profile_key_credential_request_context_deterministic( &c_result, - serverPublicParams, + C.SignalConstPointerServerPublicParams{serverPublicParams}, c_random, c_uuid, c_profileKey, @@ -194,7 +195,7 @@ func ReceiveExpiringProfileKeyCredential(spp *ServerPublicParams, requestContext c_credential := [C.SignalEXPIRING_PROFILE_KEY_CREDENTIAL_LEN]C.uchar{} signalFfiError := C.signal_server_public_params_receive_expiring_profile_key_credential( &c_credential, - spp, + C.SignalConstPointerServerPublicParams{spp}, (*[C.SignalPROFILE_KEY_CREDENTIAL_REQUEST_CONTEXT_LEN]C.uchar)(unsafe.Pointer(requestContext)), (*[C.SignalEXPIRING_PROFILE_KEY_CREDENTIAL_RESPONSE_LEN]C.uchar)(unsafe.Pointer(response)), (C.uint64_t)(currentTimeInSeconds), diff --git a/pkg/libsignalgo/protocol.go b/pkg/libsignalgo/protocol.go deleted file mode 100644 index 4d834fe..0000000 --- a/pkg/libsignalgo/protocol.go +++ /dev/null @@ -1,49 +0,0 @@ -// mautrix-signal - A Matrix-signal puppeting bridge. -// Copyright (C) 2023 Sumner Evans -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see . - -package libsignalgo - -/* -#cgo LDFLAGS: -lsignal_ffi -ldl -lm -#include "./libsignal-ffi.h" -*/ -import "C" -import ( - "context" - "runtime" - "time" -) - -func Encrypt(ctx context.Context, plaintext []byte, forAddress *Address, sessionStore SessionStore, identityKeyStore IdentityKeyStore) (*CiphertextMessage, error) { - var ciphertextMessage *C.SignalCiphertextMessage - var now C.uint64_t = C.uint64_t(time.Now().Unix()) - callbackCtx := NewCallbackContext(ctx) - defer callbackCtx.Unref() - signalFfiError := C.signal_encrypt_message( - &ciphertextMessage, - BytesToBuffer(plaintext), - forAddress.ptr, - callbackCtx.wrapSessionStore(sessionStore), - callbackCtx.wrapIdentityKeyStore(identityKeyStore), - now, - ) - runtime.KeepAlive(plaintext) - runtime.KeepAlive(forAddress) - if signalFfiError != nil { - return nil, callbackCtx.wrapError(signalFfiError) - } - return wrapCiphertextMessage(ciphertextMessage), nil -} diff --git a/pkg/libsignalgo/publickey.go b/pkg/libsignalgo/publickey.go index 5ce452d..8c4c98f 100644 --- a/pkg/libsignalgo/publickey.go +++ b/pkg/libsignalgo/publickey.go @@ -1,5 +1,6 @@ // mautrix-signal - A Matrix-signal puppeting bridge. // Copyright (C) 2023 Sumner Evans +// Copyright (C) 2025 Tulir Asokan // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU Affero General Public License as published by @@ -34,29 +35,37 @@ func wrapPublicKey(ptr *C.SignalPublicKey) *PublicKey { return publicKey } +func (pk *PublicKey) mutPtr() C.SignalMutPointerPublicKey { + return C.SignalMutPointerPublicKey{pk.ptr} +} + +func (pk *PublicKey) constPtr() C.SignalConstPointerPublicKey { + return C.SignalConstPointerPublicKey{pk.ptr} +} + func (pk *PublicKey) Clone() (*PublicKey, error) { - var cloned *C.SignalPublicKey - signalFfiError := C.signal_publickey_clone(&cloned, pk.ptr) + var cloned C.SignalMutPointerPublicKey + signalFfiError := C.signal_publickey_clone(&cloned, pk.constPtr()) runtime.KeepAlive(pk) if signalFfiError != nil { return nil, wrapError(signalFfiError) } - return wrapPublicKey(cloned), nil + return wrapPublicKey(cloned.raw), nil } func DeserializePublicKey(keyData []byte) (*PublicKey, error) { - var pk *C.SignalPublicKey + var pk C.SignalMutPointerPublicKey signalFfiError := C.signal_publickey_deserialize(&pk, BytesToBuffer(keyData)) runtime.KeepAlive(keyData) if signalFfiError != nil { return nil, wrapError(signalFfiError) } - return wrapPublicKey(pk), nil + return wrapPublicKey(pk.raw), nil } func (pk *PublicKey) Serialize() ([]byte, error) { var serialized C.SignalOwnedBuffer = C.SignalOwnedBuffer{} - signalFfiError := C.signal_publickey_serialize(&serialized, pk.ptr) + signalFfiError := C.signal_publickey_serialize(&serialized, pk.constPtr()) runtime.KeepAlive(pk) if signalFfiError != nil { return nil, wrapError(signalFfiError) @@ -66,7 +75,7 @@ func (pk *PublicKey) Serialize() ([]byte, error) { func (k *PublicKey) Destroy() error { k.CancelFinalizer() - return wrapError(C.signal_publickey_destroy(k.ptr)) + return wrapError(C.signal_publickey_destroy(k.mutPtr())) } func (k *PublicKey) CancelFinalizer() { @@ -75,7 +84,7 @@ func (k *PublicKey) CancelFinalizer() { func (k *PublicKey) Compare(other *PublicKey) (int, error) { var comparison C.int - signalFfiError := C.signal_publickey_compare(&comparison, k.ptr, other.ptr) + signalFfiError := C.signal_publickey_compare(&comparison, k.constPtr(), other.constPtr()) runtime.KeepAlive(k) runtime.KeepAlive(other) if signalFfiError != nil { @@ -86,7 +95,7 @@ func (k *PublicKey) Compare(other *PublicKey) (int, error) { func (k *PublicKey) Bytes() ([]byte, error) { var pub C.SignalOwnedBuffer = C.SignalOwnedBuffer{} - signalFfiError := C.signal_publickey_get_public_key_bytes(&pub, k.ptr) + signalFfiError := C.signal_publickey_get_public_key_bytes(&pub, k.constPtr()) runtime.KeepAlive(k) if signalFfiError != nil { return nil, wrapError(signalFfiError) @@ -96,7 +105,12 @@ func (k *PublicKey) Bytes() ([]byte, error) { func (k *PublicKey) Verify(message, signature []byte) (bool, error) { var verify C.bool - signalFfiError := C.signal_publickey_verify(&verify, k.ptr, BytesToBuffer(message), BytesToBuffer(signature)) + signalFfiError := C.signal_publickey_verify( + &verify, + k.constPtr(), + BytesToBuffer(message), + BytesToBuffer(signature), + ) runtime.KeepAlive(k) runtime.KeepAlive(message) runtime.KeepAlive(signature) diff --git a/pkg/libsignalgo/sealedsender.go b/pkg/libsignalgo/sealedsender.go index 0d12b74..4912977 100644 --- a/pkg/libsignalgo/sealedsender.go +++ b/pkg/libsignalgo/sealedsender.go @@ -1,5 +1,6 @@ // mautrix-signal - A Matrix-signal puppeting bridge. // Copyright (C) 2023 Scott Weber +// Copyright (C) 2025 Tulir Asokan // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU Affero General Public License as published by @@ -66,8 +67,8 @@ func SealedSenderEncrypt(ctx context.Context, usmc *UnidentifiedSenderMessageCon defer callbackCtx.Unref() signalFfiError := C.signal_sealed_session_cipher_encrypt( &encrypted, - forRecipient.ptr, - usmc.ptr, + forRecipient.constPtr(), + usmc.constPtr(), callbackCtx.wrapIdentityKeyStore(identityStore), ) runtime.KeepAlive(usmc) @@ -94,7 +95,7 @@ func SealedSenderDecryptToUSMC( ) (*UnidentifiedSenderMessageContent, error) { callbackCtx := NewCallbackContext(ctx) defer callbackCtx.Unref() - var usmc *C.SignalUnidentifiedSenderMessageContent = nil + var usmc C.SignalMutPointerUnidentifiedSenderMessageContent signalFfiError := C.signal_sealed_session_cipher_decrypt_to_usmc( &usmc, BytesToBuffer(ciphertext), @@ -104,7 +105,7 @@ func SealedSenderDecryptToUSMC( if signalFfiError != nil { return nil, callbackCtx.wrapError(signalFfiError) } - return wrapUnidentifiedSenderMessageContent(usmc), nil + return wrapUnidentifiedSenderMessageContent(usmc.raw), nil } func SealedSenderDecrypt( @@ -132,7 +133,7 @@ func SealedSenderDecrypt( &senderUUID, &senderDeviceID, BytesToBuffer(ciphertext), - trustRoot.ptr, + trustRoot.constPtr(), C.uint64_t(timestamp), C.CString(localAddress.E164), C.CString(localAddress.UUID.String()), @@ -182,15 +183,21 @@ func wrapUnidentifiedSenderMessageContent(ptr *C.SignalUnidentifiedSenderMessage } func NewUnidentifiedSenderMessageContent(message *CiphertextMessage, senderCertificate *SenderCertificate, contentHint UnidentifiedSenderMessageContentHint, groupID []byte) (*UnidentifiedSenderMessageContent, error) { - var usmc *C.SignalUnidentifiedSenderMessageContent - signalFfiError := C.signal_unidentified_sender_message_content_new(&usmc, message.ptr, senderCertificate.ptr, C.uint32_t(contentHint), BytesToBuffer(groupID)) + var usmc C.SignalMutPointerUnidentifiedSenderMessageContent + signalFfiError := C.signal_unidentified_sender_message_content_new( + &usmc, + message.constPtr(), + senderCertificate.constPtr(), + C.uint32_t(contentHint), + BytesToBuffer(groupID), + ) runtime.KeepAlive(message) runtime.KeepAlive(senderCertificate) runtime.KeepAlive(groupID) if signalFfiError != nil { return nil, wrapError(signalFfiError) } - return wrapUnidentifiedSenderMessageContent(usmc), nil + return wrapUnidentifiedSenderMessageContent(usmc.raw), nil } //func NewUnidentifiedSenderMessageContentFromMessage(sealedSenderMessage []byte, identityStore IdentityKeyStore, ctx *CallbackContext) (*UnidentifiedSenderMessageContent, error) { @@ -212,18 +219,26 @@ func NewUnidentifiedSenderMessageContent(message *CiphertextMessage, senderCerti //} func DeserializeUnidentifiedSenderMessageContent(serialized []byte) (*UnidentifiedSenderMessageContent, error) { - var usmc *C.SignalUnidentifiedSenderMessageContent + var usmc C.SignalMutPointerUnidentifiedSenderMessageContent signalFfiError := C.signal_unidentified_sender_message_content_deserialize(&usmc, BytesToBuffer(serialized)) runtime.KeepAlive(serialized) if signalFfiError != nil { return nil, wrapError(signalFfiError) } - return wrapUnidentifiedSenderMessageContent(usmc), nil + return wrapUnidentifiedSenderMessageContent(usmc.raw), nil +} + +func (usmc *UnidentifiedSenderMessageContent) mutPtr() C.SignalMutPointerUnidentifiedSenderMessageContent { + return C.SignalMutPointerUnidentifiedSenderMessageContent{usmc.ptr} +} + +func (usmc *UnidentifiedSenderMessageContent) constPtr() C.SignalConstPointerUnidentifiedSenderMessageContent { + return C.SignalConstPointerUnidentifiedSenderMessageContent{usmc.ptr} } func (usmc *UnidentifiedSenderMessageContent) Destroy() error { usmc.CancelFinalizer() - return wrapError(C.signal_unidentified_sender_message_content_destroy(usmc.ptr)) + return wrapError(C.signal_unidentified_sender_message_content_destroy(usmc.mutPtr())) } func (usmc *UnidentifiedSenderMessageContent) CancelFinalizer() { @@ -232,7 +247,7 @@ func (usmc *UnidentifiedSenderMessageContent) CancelFinalizer() { func (usmc *UnidentifiedSenderMessageContent) Serialize() ([]byte, error) { var serialized C.SignalOwnedBuffer = C.SignalOwnedBuffer{} - signalFfiError := C.signal_unidentified_sender_message_content_serialize(&serialized, usmc.ptr) + signalFfiError := C.signal_unidentified_sender_message_content_serialize(&serialized, usmc.constPtr()) runtime.KeepAlive(usmc) if signalFfiError != nil { return nil, wrapError(signalFfiError) @@ -242,7 +257,7 @@ func (usmc *UnidentifiedSenderMessageContent) Serialize() ([]byte, error) { func (usmc *UnidentifiedSenderMessageContent) GetContents() ([]byte, error) { var contents C.SignalOwnedBuffer = C.SignalOwnedBuffer{} - signalFfiError := C.signal_unidentified_sender_message_content_get_contents(&contents, usmc.ptr) + signalFfiError := C.signal_unidentified_sender_message_content_get_contents(&contents, usmc.constPtr()) runtime.KeepAlive(usmc) if signalFfiError != nil { return nil, wrapError(signalFfiError) @@ -264,18 +279,18 @@ func (usmc *UnidentifiedSenderMessageContent) GetContents() ([]byte, error) { //} func (usmc *UnidentifiedSenderMessageContent) GetSenderCertificate() (*SenderCertificate, error) { - var senderCertificate *C.SignalSenderCertificate - signalFfiError := C.signal_unidentified_sender_message_content_get_sender_cert(&senderCertificate, usmc.ptr) + var senderCertificate C.SignalMutPointerSenderCertificate + signalFfiError := C.signal_unidentified_sender_message_content_get_sender_cert(&senderCertificate, usmc.constPtr()) runtime.KeepAlive(usmc) if signalFfiError != nil { return nil, wrapError(signalFfiError) } - return wrapSenderCertificate(senderCertificate), nil + return wrapSenderCertificate(senderCertificate.raw), nil } func (usmc *UnidentifiedSenderMessageContent) GetMessageType() (CiphertextMessageType, error) { var messageType C.uint8_t - signalFfiError := C.signal_unidentified_sender_message_content_get_msg_type(&messageType, usmc.ptr) + signalFfiError := C.signal_unidentified_sender_message_content_get_msg_type(&messageType, usmc.constPtr()) runtime.KeepAlive(usmc) if signalFfiError != nil { return 0, wrapError(signalFfiError) @@ -285,7 +300,7 @@ func (usmc *UnidentifiedSenderMessageContent) GetMessageType() (CiphertextMessag func (usmc *UnidentifiedSenderMessageContent) GetContentHint() (UnidentifiedSenderMessageContentHint, error) { var contentHint C.uint32_t - signalFfiError := C.signal_unidentified_sender_message_content_get_content_hint(&contentHint, usmc.ptr) + signalFfiError := C.signal_unidentified_sender_message_content_get_content_hint(&contentHint, usmc.constPtr()) runtime.KeepAlive(usmc) if signalFfiError != nil { return 0, wrapError(signalFfiError) diff --git a/pkg/libsignalgo/sendercertificate.go b/pkg/libsignalgo/sendercertificate.go index a5d3f6f..46caf1c 100644 --- a/pkg/libsignalgo/sendercertificate.go +++ b/pkg/libsignalgo/sendercertificate.go @@ -1,5 +1,6 @@ // mautrix-signal - A Matrix-signal puppeting bridge. // Copyright (C) 2023 Sumner Evans +// Copyright (C) 2025 Tulir Asokan // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU Affero General Public License as published by @@ -42,8 +43,17 @@ func wrapSenderCertificate(ptr *C.SignalSenderCertificate) *SenderCertificate { // NewSenderCertificate should only be used for testing (at least according to // the Swift bindings). func NewSenderCertificate(sender *SealedSenderAddress, publicKey *PublicKey, expiration time.Time, signerCertificate *ServerCertificate, signerKey *PrivateKey) (*SenderCertificate, error) { - var sc *C.SignalSenderCertificate - signalFfiError := C.signal_sender_certificate_new(&sc, C.CString(sender.UUID.String()), C.CString(sender.E164), C.uint32_t(sender.DeviceID), publicKey.ptr, C.uint64_t(expiration.UnixMilli()), signerCertificate.ptr, signerKey.ptr) + var sc C.SignalMutPointerSenderCertificate + signalFfiError := C.signal_sender_certificate_new( + &sc, + C.CString(sender.UUID.String()), + C.CString(sender.E164), + C.uint32_t(sender.DeviceID), + publicKey.constPtr(), + C.uint64_t(expiration.UnixMilli()), + signerCertificate.constPtr(), + signerKey.constPtr(), + ) runtime.KeepAlive(sender) runtime.KeepAlive(publicKey) runtime.KeepAlive(signerCertificate) @@ -51,32 +61,43 @@ func NewSenderCertificate(sender *SealedSenderAddress, publicKey *PublicKey, exp if signalFfiError != nil { return nil, wrapError(signalFfiError) } - return wrapSenderCertificate(sc), nil + return wrapSenderCertificate(sc.raw), nil } func DeserializeSenderCertificate(serialized []byte) (*SenderCertificate, error) { - var sc *C.SignalSenderCertificate + var sc C.SignalMutPointerSenderCertificate signalFfiError := C.signal_sender_certificate_deserialize(&sc, BytesToBuffer(serialized)) runtime.KeepAlive(serialized) if signalFfiError != nil { return nil, wrapError(signalFfiError) } - return wrapSenderCertificate(sc), nil + return wrapSenderCertificate(sc.raw), nil } func (sc *SenderCertificate) Clone() (*SenderCertificate, error) { - var cloned *C.SignalSenderCertificate - signalFfiError := C.signal_sender_certificate_clone(&cloned, sc.ptr) + var cloned C.SignalMutPointerSenderCertificate + signalFfiError := C.signal_sender_certificate_clone( + &cloned, + sc.constPtr(), + ) runtime.KeepAlive(sc) if signalFfiError != nil { return nil, wrapError(signalFfiError) } - return wrapSenderCertificate(cloned), nil + return wrapSenderCertificate(cloned.raw), nil +} + +func (sc *SenderCertificate) mutPtr() C.SignalMutPointerSenderCertificate { + return C.SignalMutPointerSenderCertificate{sc.ptr} +} + +func (sc *SenderCertificate) constPtr() C.SignalConstPointerSenderCertificate { + return C.SignalConstPointerSenderCertificate{sc.ptr} } func (sc *SenderCertificate) Destroy() error { sc.CancelFinalizer() - return wrapError(C.signal_sender_certificate_destroy(sc.ptr)) + return wrapError(C.signal_sender_certificate_destroy(sc.mutPtr())) } func (sc *SenderCertificate) CancelFinalizer() { @@ -85,7 +106,7 @@ func (sc *SenderCertificate) CancelFinalizer() { func (sc *SenderCertificate) Serialize() ([]byte, error) { var serialized C.SignalOwnedBuffer = C.SignalOwnedBuffer{} - signalFfiError := C.signal_sender_certificate_get_serialized(&serialized, sc.ptr) + signalFfiError := C.signal_sender_certificate_get_serialized(&serialized, sc.constPtr()) runtime.KeepAlive(sc) if signalFfiError != nil { return nil, wrapError(signalFfiError) @@ -95,7 +116,7 @@ func (sc *SenderCertificate) Serialize() ([]byte, error) { func (sc *SenderCertificate) GetCertificate() ([]byte, error) { var certificate C.SignalOwnedBuffer = C.SignalOwnedBuffer{} - signalFfiError := C.signal_sender_certificate_get_certificate(&certificate, sc.ptr) + signalFfiError := C.signal_sender_certificate_get_certificate(&certificate, sc.constPtr()) runtime.KeepAlive(sc) if signalFfiError != nil { return nil, wrapError(signalFfiError) @@ -105,7 +126,7 @@ func (sc *SenderCertificate) GetCertificate() ([]byte, error) { func (sc *SenderCertificate) GetSignature() ([]byte, error) { var signature C.SignalOwnedBuffer = C.SignalOwnedBuffer{} - signalFfiError := C.signal_sender_certificate_get_signature(&signature, sc.ptr) + signalFfiError := C.signal_sender_certificate_get_signature(&signature, sc.constPtr()) runtime.KeepAlive(sc) if signalFfiError != nil { return nil, wrapError(signalFfiError) @@ -115,7 +136,7 @@ func (sc *SenderCertificate) GetSignature() ([]byte, error) { func (sc *SenderCertificate) GetSenderUUID() (uuid.UUID, error) { var rawUUID *C.char - signalFfiError := C.signal_sender_certificate_get_sender_uuid(&rawUUID, sc.ptr) + signalFfiError := C.signal_sender_certificate_get_sender_uuid(&rawUUID, sc.constPtr()) runtime.KeepAlive(sc) if signalFfiError != nil { return uuid.UUID{}, wrapError(signalFfiError) @@ -125,7 +146,7 @@ func (sc *SenderCertificate) GetSenderUUID() (uuid.UUID, error) { func (sc *SenderCertificate) GetSenderE164() (string, error) { var e164 *C.char - signalFfiError := C.signal_sender_certificate_get_sender_e164(&e164, sc.ptr) + signalFfiError := C.signal_sender_certificate_get_sender_e164(&e164, sc.constPtr()) runtime.KeepAlive(sc) if signalFfiError != nil { return "", wrapError(signalFfiError) @@ -138,7 +159,7 @@ func (sc *SenderCertificate) GetSenderE164() (string, error) { func (sc *SenderCertificate) GetExpiration() (time.Time, error) { var expiration C.uint64_t - signalFfiError := C.signal_sender_certificate_get_expiration(&expiration, sc.ptr) + signalFfiError := C.signal_sender_certificate_get_expiration(&expiration, sc.constPtr()) runtime.KeepAlive(sc) if signalFfiError != nil { return time.Time{}, wrapError(signalFfiError) @@ -148,7 +169,7 @@ func (sc *SenderCertificate) GetExpiration() (time.Time, error) { func (sc *SenderCertificate) GetDeviceID() (uint32, error) { var deviceID C.uint32_t - signalFfiError := C.signal_sender_certificate_get_device_id(&deviceID, sc.ptr) + signalFfiError := C.signal_sender_certificate_get_device_id(&deviceID, sc.constPtr()) runtime.KeepAlive(sc) if signalFfiError != nil { return 0, wrapError(signalFfiError) @@ -157,18 +178,23 @@ func (sc *SenderCertificate) GetDeviceID() (uint32, error) { } func (sc *SenderCertificate) GetKey() (*PublicKey, error) { - var key *C.SignalPublicKey - signalFfiError := C.signal_sender_certificate_get_key(&key, sc.ptr) + var key C.SignalMutPointerPublicKey + signalFfiError := C.signal_sender_certificate_get_key(&key, sc.constPtr()) runtime.KeepAlive(sc) if signalFfiError != nil { return nil, wrapError(signalFfiError) } - return wrapPublicKey(key), nil + return wrapPublicKey(key.raw), nil } func (sc *SenderCertificate) Validate(trustRoot *PublicKey, ts time.Time) (bool, error) { var valid C.bool - signalFfiError := C.signal_sender_certificate_validate(&valid, sc.ptr, trustRoot.ptr, C.uint64_t(ts.UnixMilli())) + signalFfiError := C.signal_sender_certificate_validate( + &valid, + sc.constPtr(), + trustRoot.constPtr(), + C.uint64_t(ts.UnixMilli()), + ) runtime.KeepAlive(sc) runtime.KeepAlive(trustRoot) if signalFfiError != nil { @@ -178,11 +204,11 @@ func (sc *SenderCertificate) Validate(trustRoot *PublicKey, ts time.Time) (bool, } func (sc *SenderCertificate) GetServerCertificate() (*ServerCertificate, error) { - var serverCertificate *C.SignalServerCertificate - signalFfiError := C.signal_sender_certificate_get_server_certificate(&serverCertificate, sc.ptr) + var serverCertificate C.SignalMutPointerServerCertificate + signalFfiError := C.signal_sender_certificate_get_server_certificate(&serverCertificate, sc.constPtr()) runtime.KeepAlive(sc) if signalFfiError != nil { return nil, wrapError(signalFfiError) } - return wrapServerCertificate(serverCertificate), nil + return wrapServerCertificate(serverCertificate.raw), nil } diff --git a/pkg/libsignalgo/senderkeydistributionmessage.go b/pkg/libsignalgo/senderkeydistributionmessage.go index 60c5910..e772c58 100644 --- a/pkg/libsignalgo/senderkeydistributionmessage.go +++ b/pkg/libsignalgo/senderkeydistributionmessage.go @@ -1,5 +1,6 @@ // mautrix-signal - A Matrix-signal puppeting bridge. // Copyright (C) 2023 Sumner Evans +// Copyright (C) 2025 Tulir Asokan // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU Affero General Public License as published by @@ -33,8 +34,8 @@ func ProcessSenderKeyDistributionMessage(ctx context.Context, message *SenderKey callbackCtx := NewCallbackContext(ctx) defer callbackCtx.Unref() signalFfiError := C.signal_process_sender_key_distribution_message( - fromSender.ptr, - message.ptr, + fromSender.constPtr(), + message.constPtr(), callbackCtx.wrapSenderKeyStore(store), ) runtime.KeepAlive(message) @@ -56,10 +57,10 @@ func wrapSenderKeyDistributionMessage(ptr *C.SignalSenderKeyDistributionMessage) func NewSenderKeyDistributionMessage(ctx context.Context, sender *Address, distributionID uuid.UUID, store SenderKeyStore) (*SenderKeyDistributionMessage, error) { callbackCtx := NewCallbackContext(ctx) defer callbackCtx.Unref() - var skdm *C.SignalSenderKeyDistributionMessage + var skdm C.SignalMutPointerSenderKeyDistributionMessage signalFfiError := C.signal_sender_key_distribution_message_create( &skdm, - sender.ptr, + sender.constPtr(), (*[C.SignalUUID_LEN]C.uchar)(unsafe.Pointer(&distributionID)), callbackCtx.wrapSenderKeyStore(store), ) @@ -68,22 +69,30 @@ func NewSenderKeyDistributionMessage(ctx context.Context, sender *Address, distr if signalFfiError != nil { return nil, callbackCtx.wrapError(signalFfiError) } - return wrapSenderKeyDistributionMessage(skdm), nil + return wrapSenderKeyDistributionMessage(skdm.raw), nil } func DeserializeSenderKeyDistributionMessage(serialized []byte) (*SenderKeyDistributionMessage, error) { - var skdm *C.SignalSenderKeyDistributionMessage + var skdm C.SignalMutPointerSenderKeyDistributionMessage signalFfiError := C.signal_sender_key_distribution_message_deserialize(&skdm, BytesToBuffer(serialized)) runtime.KeepAlive(serialized) if signalFfiError != nil { return nil, wrapError(signalFfiError) } - return wrapSenderKeyDistributionMessage(skdm), nil + return wrapSenderKeyDistributionMessage(skdm.raw), nil +} + +func (sc *SenderKeyDistributionMessage) mutPtr() C.SignalMutPointerSenderKeyDistributionMessage { + return C.SignalMutPointerSenderKeyDistributionMessage{sc.ptr} +} + +func (sc *SenderKeyDistributionMessage) constPtr() C.SignalConstPointerSenderKeyDistributionMessage { + return C.SignalConstPointerSenderKeyDistributionMessage{sc.ptr} } func (sc *SenderKeyDistributionMessage) Destroy() error { sc.CancelFinalizer() - return wrapError(C.signal_sender_key_distribution_message_destroy(sc.ptr)) + return wrapError(C.signal_sender_key_distribution_message_destroy(sc.mutPtr())) } func (sc *SenderKeyDistributionMessage) CancelFinalizer() { @@ -92,7 +101,7 @@ func (sc *SenderKeyDistributionMessage) CancelFinalizer() { func (sc *SenderKeyDistributionMessage) Serialize() ([]byte, error) { var serialized C.SignalOwnedBuffer = C.SignalOwnedBuffer{} - signalFfiError := C.signal_sender_key_distribution_message_serialize(&serialized, sc.ptr) + signalFfiError := C.signal_sender_key_distribution_message_serialize(&serialized, sc.constPtr()) if signalFfiError != nil { return nil, wrapError(signalFfiError) } @@ -103,8 +112,8 @@ func (sc *SenderKeyDistributionMessage) Process(ctx context.Context, sender *Add callbackCtx := NewCallbackContext(ctx) defer callbackCtx.Unref() signalFfiError := C.signal_process_sender_key_distribution_message( - sender.ptr, - sc.ptr, + sender.constPtr(), + sc.constPtr(), callbackCtx.wrapSenderKeyStore(store), ) runtime.KeepAlive(sender) diff --git a/pkg/libsignalgo/senderkeyrecord.go b/pkg/libsignalgo/senderkeyrecord.go index cc487df..7299ae5 100644 --- a/pkg/libsignalgo/senderkeyrecord.go +++ b/pkg/libsignalgo/senderkeyrecord.go @@ -1,5 +1,6 @@ // mautrix-signal - A Matrix-signal puppeting bridge. // Copyright (C) 2023 Sumner Evans +// Copyright (C) 2025 Tulir Asokan // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU Affero General Public License as published by @@ -37,18 +38,18 @@ func wrapSenderKeyRecord(ptr *C.SignalSenderKeyRecord) *SenderKeyRecord { } func DeserializeSenderKeyRecord(serialized []byte) (*SenderKeyRecord, error) { - var sc *C.SignalSenderKeyRecord + var sc C.SignalMutPointerSenderKeyRecord signalFfiError := C.signal_sender_key_record_deserialize(&sc, BytesToBuffer(serialized)) runtime.KeepAlive(serialized) if signalFfiError != nil { return nil, wrapError(signalFfiError) } - return wrapSenderKeyRecord(sc), nil + return wrapSenderKeyRecord(sc.raw), nil } func (skr *SenderKeyRecord) Serialize() ([]byte, error) { var serialized C.SignalOwnedBuffer = C.SignalOwnedBuffer{} - signalFfiError := C.signal_sender_key_record_serialize(&serialized, skr.ptr) + signalFfiError := C.signal_sender_key_record_serialize(&serialized, skr.constPtr()) runtime.KeepAlive(skr) if signalFfiError != nil { return nil, wrapError(signalFfiError) @@ -56,19 +57,27 @@ func (skr *SenderKeyRecord) Serialize() ([]byte, error) { return CopySignalOwnedBufferToBytes(serialized), nil } +func (skr *SenderKeyRecord) mutPtr() C.SignalMutPointerSenderKeyRecord { + return C.SignalMutPointerSenderKeyRecord{skr.ptr} +} + +func (skr *SenderKeyRecord) constPtr() C.SignalConstPointerSenderKeyRecord { + return C.SignalConstPointerSenderKeyRecord{skr.ptr} +} + func (skr *SenderKeyRecord) Clone() (*SenderKeyRecord, error) { - var cloned *C.SignalSenderKeyRecord - signalFfiError := C.signal_sender_key_record_clone(&cloned, skr.ptr) + var cloned C.SignalMutPointerSenderKeyRecord + signalFfiError := C.signal_sender_key_record_clone(&cloned, skr.constPtr()) runtime.KeepAlive(skr) if signalFfiError != nil { return nil, wrapError(signalFfiError) } - return wrapSenderKeyRecord(cloned), nil + return wrapSenderKeyRecord(cloned.raw), nil } func (skr *SenderKeyRecord) Destroy() error { skr.CancelFinalizer() - return wrapError(C.signal_sender_key_record_destroy(skr.ptr)) + return wrapError(C.signal_sender_key_record_destroy(skr.mutPtr())) } func (skr *SenderKeyRecord) CancelFinalizer() { diff --git a/pkg/libsignalgo/senderkeystore.go b/pkg/libsignalgo/senderkeystore.go index 3d05fc2..d3bda2f 100644 --- a/pkg/libsignalgo/senderkeystore.go +++ b/pkg/libsignalgo/senderkeystore.go @@ -1,5 +1,6 @@ // mautrix-signal - A Matrix-signal puppeting bridge. // Copyright (C) 2023 Sumner Evans +// Copyright (C) 2025 Tulir Asokan // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU Affero General Public License as published by @@ -68,10 +69,10 @@ func signal_store_sender_key_callback(storeCtx unsafe.Pointer, address *C.const_ }) } -func (ctx *CallbackContext) wrapSenderKeyStore(store SenderKeyStore) *C.SignalSenderKeyStore { - return &C.SignalSenderKeyStore{ +func (ctx *CallbackContext) wrapSenderKeyStore(store SenderKeyStore) C.SignalConstPointerFfiSenderKeyStoreStruct { + return C.SignalConstPointerFfiSenderKeyStoreStruct{&C.SignalSenderKeyStore{ ctx: wrapStore(ctx, store), load_sender_key: C.SignalLoadSenderKey(C.signal_load_sender_key_callback), store_sender_key: C.SignalStoreSenderKey(C.signal_store_sender_key_callback), - } + }} } diff --git a/pkg/libsignalgo/servercertificate.go b/pkg/libsignalgo/servercertificate.go index 64ba57a..da56b0b 100644 --- a/pkg/libsignalgo/servercertificate.go +++ b/pkg/libsignalgo/servercertificate.go @@ -1,5 +1,6 @@ // mautrix-signal - A Matrix-signal puppeting bridge. // Copyright (C) 2023 Sumner Evans +// Copyright (C) 2025 Tulir Asokan // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU Affero General Public License as published by @@ -37,39 +38,52 @@ func wrapServerCertificate(ptr *C.SignalServerCertificate) *ServerCertificate { // NewServerCertificate should only be used for testing (at least according to // the Swift bindings). func NewServerCertificate(keyID uint32, publicKey *PublicKey, trustRoot *PrivateKey) (*ServerCertificate, error) { - var serverCertificate *C.SignalServerCertificate - signalFfiError := C.signal_server_certificate_new(&serverCertificate, C.uint32_t(keyID), publicKey.ptr, trustRoot.ptr) + var serverCertificate C.SignalMutPointerServerCertificate + signalFfiError := C.signal_server_certificate_new( + &serverCertificate, + C.uint32_t(keyID), + publicKey.constPtr(), + trustRoot.constPtr(), + ) runtime.KeepAlive(publicKey) runtime.KeepAlive(trustRoot) if signalFfiError != nil { return nil, wrapError(signalFfiError) } - return wrapServerCertificate(serverCertificate), nil + return wrapServerCertificate(serverCertificate.raw), nil } func DeserializeServerCertificate(serialized []byte) (*ServerCertificate, error) { - var serverCertificate *C.SignalServerCertificate + var serverCertificate C.SignalMutPointerServerCertificate signalFfiError := C.signal_server_certificate_deserialize(&serverCertificate, BytesToBuffer(serialized)) runtime.KeepAlive(serialized) if signalFfiError != nil { return nil, wrapError(signalFfiError) } - return wrapServerCertificate(serverCertificate), nil + return wrapServerCertificate(serverCertificate.raw), nil +} + +func (sc *ServerCertificate) mutPtr() C.SignalMutPointerServerCertificate { + return C.SignalMutPointerServerCertificate{sc.ptr} +} + +func (sc *ServerCertificate) constPtr() C.SignalConstPointerServerCertificate { + return C.SignalConstPointerServerCertificate{sc.ptr} } func (sc *ServerCertificate) Clone() (*ServerCertificate, error) { - var cloned *C.SignalServerCertificate - signalFfiError := C.signal_server_certificate_clone(&cloned, sc.ptr) + var cloned C.SignalMutPointerServerCertificate + signalFfiError := C.signal_server_certificate_clone(&cloned, sc.constPtr()) runtime.KeepAlive(sc) if signalFfiError != nil { return nil, wrapError(signalFfiError) } - return wrapServerCertificate(cloned), nil + return wrapServerCertificate(cloned.raw), nil } func (sc *ServerCertificate) Destroy() error { sc.CancelFinalizer() - return wrapError(C.signal_server_certificate_destroy(sc.ptr)) + return wrapError(C.signal_server_certificate_destroy(sc.mutPtr())) } func (sc *ServerCertificate) CancelFinalizer() { @@ -78,7 +92,7 @@ func (sc *ServerCertificate) CancelFinalizer() { func (sc *ServerCertificate) Serialize() ([]byte, error) { var serialized C.SignalOwnedBuffer = C.SignalOwnedBuffer{} - signalFfiError := C.signal_server_certificate_get_serialized(&serialized, sc.ptr) + signalFfiError := C.signal_server_certificate_get_serialized(&serialized, sc.constPtr()) runtime.KeepAlive(sc) if signalFfiError != nil { return nil, wrapError(signalFfiError) @@ -88,7 +102,7 @@ func (sc *ServerCertificate) Serialize() ([]byte, error) { func (sc *ServerCertificate) GetCertificate() ([]byte, error) { var certificate C.SignalOwnedBuffer = C.SignalOwnedBuffer{} - signalFfiError := C.signal_server_certificate_get_certificate(&certificate, sc.ptr) + signalFfiError := C.signal_server_certificate_get_certificate(&certificate, sc.constPtr()) runtime.KeepAlive(sc) if signalFfiError != nil { return nil, wrapError(signalFfiError) @@ -98,7 +112,7 @@ func (sc *ServerCertificate) GetCertificate() ([]byte, error) { func (sc *ServerCertificate) GetSignature() ([]byte, error) { var signature C.SignalOwnedBuffer = C.SignalOwnedBuffer{} - signalFfiError := C.signal_server_certificate_get_signature(&signature, sc.ptr) + signalFfiError := C.signal_server_certificate_get_signature(&signature, sc.constPtr()) runtime.KeepAlive(sc) if signalFfiError != nil { return nil, wrapError(signalFfiError) @@ -108,7 +122,7 @@ func (sc *ServerCertificate) GetSignature() ([]byte, error) { func (sc *ServerCertificate) GetKeyID() (uint32, error) { var keyID C.uint32_t - signalFfiError := C.signal_server_certificate_get_key_id(&keyID, sc.ptr) + signalFfiError := C.signal_server_certificate_get_key_id(&keyID, sc.constPtr()) runtime.KeepAlive(sc) if signalFfiError != nil { return 0, wrapError(signalFfiError) @@ -117,11 +131,11 @@ func (sc *ServerCertificate) GetKeyID() (uint32, error) { } func (sc *ServerCertificate) GetKey() (*PublicKey, error) { - var key *C.SignalPublicKey - signalFfiError := C.signal_server_certificate_get_key(&key, sc.ptr) + var key C.SignalMutPointerPublicKey + signalFfiError := C.signal_server_certificate_get_key(&key, sc.constPtr()) runtime.KeepAlive(sc) if signalFfiError != nil { return nil, wrapError(signalFfiError) } - return wrapPublicKey(key), nil + return wrapPublicKey(key.raw), nil } diff --git a/pkg/libsignalgo/serverpublicparams.go b/pkg/libsignalgo/serverpublicparams.go index 6e99471..fc046c1 100644 --- a/pkg/libsignalgo/serverpublicparams.go +++ b/pkg/libsignalgo/serverpublicparams.go @@ -31,16 +31,16 @@ import ( type ServerPublicParams = C.SignalServerPublicParams type NotarySignature [C.SignalSIGNATURE_LEN]byte -func DeserializeServerPublicParams(params []byte) (out *ServerPublicParams, err error) { +func DeserializeServerPublicParams(params []byte) (*ServerPublicParams, error) { if len(params) != C.SignalSERVER_PUBLIC_PARAMS_LEN { - err = fmt.Errorf("invalid server public params length: %d (expected %d)", len(params), int(C.SignalSERVER_PUBLIC_PARAMS_LEN)) - return + return nil, fmt.Errorf("invalid server public params length: %d (expected %d)", len(params), int(C.SignalSERVER_PUBLIC_PARAMS_LEN)) } + var out C.SignalMutPointerServerPublicParams signalFfiError := C.signal_server_public_params_deserialize(&out, BytesToBuffer(params[:])) if signalFfiError != nil { - err = wrapError(signalFfiError) + return nil, wrapError(signalFfiError) } - return + return out.raw, nil } func ServerPublicParamsVerifySignature( @@ -50,7 +50,7 @@ func ServerPublicParamsVerifySignature( ) error { c_notarySignature := (*[C.SignalSIGNATURE_LEN]C.uint8_t)(unsafe.Pointer(&NotarySignature[0])) signalFfiError := C.signal_server_public_params_verify_signature( - serverPublicParams, + C.SignalConstPointerServerPublicParams{serverPublicParams}, BytesToBuffer(messageBytes), c_notarySignature, ) diff --git a/pkg/libsignalgo/sessionrecord.go b/pkg/libsignalgo/sessionrecord.go index f47e524..3523f62 100644 --- a/pkg/libsignalgo/sessionrecord.go +++ b/pkg/libsignalgo/sessionrecord.go @@ -1,5 +1,6 @@ // mautrix-signal - A Matrix-signal puppeting bridge. // Copyright (C) 2023 Sumner Evans +// Copyright (C) 2025 Tulir Asokan // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU Affero General Public License as published by @@ -38,28 +39,39 @@ func wrapSessionRecord(ptr *C.SignalSessionRecord) *SessionRecord { } func DeserializeSessionRecord(serialized []byte) (*SessionRecord, error) { - var ptr *C.SignalSessionRecord + var ptr C.SignalMutPointerSessionRecord signalFfiError := C.signal_session_record_deserialize(&ptr, BytesToBuffer(serialized)) runtime.KeepAlive(serialized) if signalFfiError != nil { return nil, wrapError(signalFfiError) } - return wrapSessionRecord(ptr), nil + return wrapSessionRecord(ptr.raw), nil +} + +func (sr *SessionRecord) mutPtr() C.SignalMutPointerSessionRecord { + return C.SignalMutPointerSessionRecord{sr.ptr} +} + +func (sr *SessionRecord) constPtr() C.SignalConstPointerSessionRecord { + return C.SignalConstPointerSessionRecord{sr.ptr} } func (sr *SessionRecord) Clone() (*SessionRecord, error) { - var clone *C.SignalSessionRecord - signalFfiError := C.signal_session_record_clone(&clone, sr.ptr) + var clone C.SignalMutPointerSessionRecord + signalFfiError := C.signal_session_record_clone( + &clone, + sr.constPtr(), + ) runtime.KeepAlive(sr) if signalFfiError != nil { return nil, wrapError(signalFfiError) } - return wrapSessionRecord(clone), nil + return wrapSessionRecord(clone.raw), nil } func (sr *SessionRecord) Destroy() error { sr.CancelFinalizer() - return wrapError(C.signal_session_record_destroy(sr.ptr)) + return wrapError(C.signal_session_record_destroy(sr.mutPtr())) } func (sr *SessionRecord) CancelFinalizer() { @@ -68,12 +80,16 @@ func (sr *SessionRecord) CancelFinalizer() { func (sr *SessionRecord) ArchiveCurrentState() error { defer runtime.KeepAlive(sr) - return wrapError(C.signal_session_record_archive_current_state(sr.ptr)) + return wrapError(C.signal_session_record_archive_current_state(sr.mutPtr())) } func (sr *SessionRecord) CurrentRatchetKeyMatches(key *PublicKey) (bool, error) { var result C.bool - signalFfiError := C.signal_session_record_current_ratchet_key_matches(&result, sr.ptr, key.ptr) + signalFfiError := C.signal_session_record_current_ratchet_key_matches( + &result, + sr.constPtr(), + key.constPtr(), + ) runtime.KeepAlive(sr) runtime.KeepAlive(key) if signalFfiError != nil { @@ -84,7 +100,11 @@ func (sr *SessionRecord) CurrentRatchetKeyMatches(key *PublicKey) (bool, error) func (sr *SessionRecord) HasCurrentState() (bool, error) { var result C.bool - signalFfiError := C.signal_session_record_has_usable_sender_chain(&result, sr.ptr, C.uint64_t(time.Now().Unix())) + signalFfiError := C.signal_session_record_has_usable_sender_chain( + &result, + sr.constPtr(), + C.uint64_t(time.Now().Unix()), + ) runtime.KeepAlive(sr) if signalFfiError != nil { return false, wrapError(signalFfiError) @@ -94,7 +114,7 @@ func (sr *SessionRecord) HasCurrentState() (bool, error) { func (sr *SessionRecord) Serialize() ([]byte, error) { var serialized C.SignalOwnedBuffer = C.SignalOwnedBuffer{} - signalFfiError := C.signal_session_record_serialize(&serialized, sr.ptr) + signalFfiError := C.signal_session_record_serialize(&serialized, sr.constPtr()) runtime.KeepAlive(sr) if signalFfiError != nil { return nil, wrapError(signalFfiError) @@ -104,7 +124,7 @@ func (sr *SessionRecord) Serialize() ([]byte, error) { func (sr *SessionRecord) GetLocalRegistrationID() (uint32, error) { var result C.uint32_t - signalFfiError := C.signal_session_record_get_local_registration_id(&result, sr.ptr) + signalFfiError := C.signal_session_record_get_local_registration_id(&result, sr.constPtr()) runtime.KeepAlive(sr) if signalFfiError != nil { return 0, wrapError(signalFfiError) @@ -114,7 +134,7 @@ func (sr *SessionRecord) GetLocalRegistrationID() (uint32, error) { func (sr *SessionRecord) GetRemoteRegistrationID() (uint32, error) { var result C.uint32_t - signalFfiError := C.signal_session_record_get_remote_registration_id(&result, sr.ptr) + signalFfiError := C.signal_session_record_get_remote_registration_id(&result, sr.constPtr()) runtime.KeepAlive(sr) if signalFfiError != nil { return 0, wrapError(signalFfiError) diff --git a/pkg/libsignalgo/sessionstore.go b/pkg/libsignalgo/sessionstore.go index c02aa58..ad88d62 100644 --- a/pkg/libsignalgo/sessionstore.go +++ b/pkg/libsignalgo/sessionstore.go @@ -1,5 +1,6 @@ // mautrix-signal - A Matrix-signal puppeting bridge. // Copyright (C) 2023 Sumner Evans +// Copyright (C) 2025 Tulir Asokan // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU Affero General Public License as published by @@ -61,10 +62,10 @@ func signal_store_session_callback(storeCtx unsafe.Pointer, address *C.const_add }) } -func (ctx *CallbackContext) wrapSessionStore(store SessionStore) *C.SignalSessionStore { - return &C.SignalSessionStore{ +func (ctx *CallbackContext) wrapSessionStore(store SessionStore) C.SignalConstPointerFfiSessionStoreStruct { + return C.SignalConstPointerFfiSessionStoreStruct{&C.SignalSessionStore{ ctx: wrapStore(ctx, store), load_session: C.SignalLoadSession(C.signal_load_session_callback), store_session: C.SignalStoreSession(C.signal_store_session_callback), - } + }} } diff --git a/pkg/libsignalgo/sgxclient.go b/pkg/libsignalgo/sgxclient.go index c85f058..a2ba553 100644 --- a/pkg/libsignalgo/sgxclient.go +++ b/pkg/libsignalgo/sgxclient.go @@ -38,7 +38,7 @@ func wrapSGXClientState(ptr *C.SignalSgxClientState) *SGXClientState { } func NewCDS2ClientState(mrenclave, attestationMessage []byte, currentTime time.Time) (*SGXClientState, error) { - var cds *C.SignalSgxClientState + var cds C.SignalMutPointerSgxClientState signalFfiError := C.signal_cds2_client_state_new( &cds, BytesToBuffer(mrenclave), @@ -50,17 +50,25 @@ func NewCDS2ClientState(mrenclave, attestationMessage []byte, currentTime time.T if signalFfiError != nil { return nil, wrapError(signalFfiError) } - return wrapSGXClientState(cds), nil + return wrapSGXClientState(cds.raw), nil +} + +func (cds *SGXClientState) mutPtr() C.SignalMutPointerSgxClientState { + return C.SignalMutPointerSgxClientState{cds.ptr} +} + +func (cds *SGXClientState) constPtr() C.SignalConstPointerSgxClientState { + return C.SignalConstPointerSgxClientState{cds.ptr} } func (cds *SGXClientState) Destroy() error { runtime.SetFinalizer(cds, nil) - return wrapError(C.signal_sgx_client_state_destroy(cds.ptr)) + return wrapError(C.signal_sgx_client_state_destroy(cds.mutPtr())) } func (cds *SGXClientState) InitialRequest() ([]byte, error) { var resp C.SignalOwnedBuffer - signalFfiError := C.signal_sgx_client_state_initial_request(&resp, cds.ptr) + signalFfiError := C.signal_sgx_client_state_initial_request(&resp, cds.constPtr()) runtime.KeepAlive(cds) if signalFfiError != nil { return nil, wrapError(signalFfiError) @@ -69,7 +77,7 @@ func (cds *SGXClientState) InitialRequest() ([]byte, error) { } func (cds *SGXClientState) CompleteHandshake(handshakeReceived []byte) error { - signalFfiError := C.signal_sgx_client_state_complete_handshake(cds.ptr, BytesToBuffer(handshakeReceived)) + signalFfiError := C.signal_sgx_client_state_complete_handshake(cds.mutPtr(), BytesToBuffer(handshakeReceived)) runtime.KeepAlive(cds) runtime.KeepAlive(handshakeReceived) return wrapError(signalFfiError) @@ -77,7 +85,11 @@ func (cds *SGXClientState) CompleteHandshake(handshakeReceived []byte) error { func (cds *SGXClientState) EstablishedSend(plaintext []byte) ([]byte, error) { var resp C.SignalOwnedBuffer - signalFfiError := C.signal_sgx_client_state_established_send(&resp, cds.ptr, BytesToBuffer(plaintext)) + signalFfiError := C.signal_sgx_client_state_established_send( + &resp, + cds.mutPtr(), + BytesToBuffer(plaintext), + ) runtime.KeepAlive(cds) runtime.KeepAlive(plaintext) if signalFfiError != nil { @@ -88,7 +100,11 @@ func (cds *SGXClientState) EstablishedSend(plaintext []byte) ([]byte, error) { func (cds *SGXClientState) EstablishedReceive(ciphertext []byte) ([]byte, error) { var resp C.SignalOwnedBuffer - signalFfiError := C.signal_sgx_client_state_established_recv(&resp, cds.ptr, BytesToBuffer(ciphertext)) + signalFfiError := C.signal_sgx_client_state_established_recv( + &resp, + cds.mutPtr(), + BytesToBuffer(ciphertext), + ) runtime.KeepAlive(cds) runtime.KeepAlive(ciphertext) if signalFfiError != nil { diff --git a/pkg/libsignalgo/signedprekey.go b/pkg/libsignalgo/signedprekey.go index e3aa926..ca86ce3 100644 --- a/pkg/libsignalgo/signedprekey.go +++ b/pkg/libsignalgo/signedprekey.go @@ -1,5 +1,6 @@ // mautrix-signal - A Matrix-signal puppeting bridge. // Copyright (C) 2023 Sumner Evans +// Copyright (C) 2025 Tulir Asokan // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU Affero General Public License as published by @@ -38,15 +39,22 @@ func wrapSignedPreKeyRecord(ptr *C.SignalSignedPreKeyRecord) *SignedPreKeyRecord } func NewSignedPreKeyRecord(id uint32, timestamp time.Time, publicKey *PublicKey, privateKey *PrivateKey, signature []byte) (*SignedPreKeyRecord, error) { - var spkr *C.SignalSignedPreKeyRecord - signalFfiError := C.signal_signed_pre_key_record_new(&spkr, C.uint32_t(id), C.uint64_t(timestamp.UnixMilli()), publicKey.ptr, privateKey.ptr, BytesToBuffer(signature)) + var spkr C.SignalMutPointerSignedPreKeyRecord + signalFfiError := C.signal_signed_pre_key_record_new( + &spkr, + C.uint32_t(id), + C.uint64_t(timestamp.UnixMilli()), + publicKey.constPtr(), + privateKey.constPtr(), + BytesToBuffer(signature), + ) runtime.KeepAlive(publicKey) runtime.KeepAlive(privateKey) runtime.KeepAlive(signature) if signalFfiError != nil { return nil, wrapError(signalFfiError) } - return wrapSignedPreKeyRecord(spkr), nil + return wrapSignedPreKeyRecord(spkr.raw), nil } func NewSignedPreKeyRecordFromPrivateKey(id uint32, timestamp time.Time, privateKey *PrivateKey, signature []byte) (*SignedPreKeyRecord, error) { @@ -58,28 +66,36 @@ func NewSignedPreKeyRecordFromPrivateKey(id uint32, timestamp time.Time, private } func DeserializeSignedPreKeyRecord(serialized []byte) (*SignedPreKeyRecord, error) { - var spkr *C.SignalSignedPreKeyRecord + var spkr C.SignalMutPointerSignedPreKeyRecord signalFfiError := C.signal_signed_pre_key_record_deserialize(&spkr, BytesToBuffer(serialized)) runtime.KeepAlive(serialized) if signalFfiError != nil { return nil, wrapError(signalFfiError) } - return wrapSignedPreKeyRecord(spkr), nil + return wrapSignedPreKeyRecord(spkr.raw), nil +} + +func (spkr *SignedPreKeyRecord) mutPtr() C.SignalMutPointerSignedPreKeyRecord { + return C.SignalMutPointerSignedPreKeyRecord{spkr.ptr} +} + +func (spkr *SignedPreKeyRecord) constPtr() C.SignalConstPointerSignedPreKeyRecord { + return C.SignalConstPointerSignedPreKeyRecord{spkr.ptr} } func (spkr *SignedPreKeyRecord) Clone() (*SignedPreKeyRecord, error) { - var cloned *C.SignalSignedPreKeyRecord - signalFfiError := C.signal_signed_pre_key_record_clone(&cloned, spkr.ptr) + var cloned C.SignalMutPointerSignedPreKeyRecord + signalFfiError := C.signal_signed_pre_key_record_clone(&cloned, spkr.constPtr()) runtime.KeepAlive(spkr) if signalFfiError != nil { return nil, wrapError(signalFfiError) } - return wrapSignedPreKeyRecord(cloned), nil + return wrapSignedPreKeyRecord(cloned.raw), nil } func (spkr *SignedPreKeyRecord) Destroy() error { spkr.CancelFinalizer() - return wrapError(C.signal_signed_pre_key_record_destroy(spkr.ptr)) + return wrapError(C.signal_signed_pre_key_record_destroy(spkr.mutPtr())) } func (spkr *SignedPreKeyRecord) CancelFinalizer() { @@ -88,7 +104,7 @@ func (spkr *SignedPreKeyRecord) CancelFinalizer() { func (spkr *SignedPreKeyRecord) Serialize() ([]byte, error) { var serialized C.SignalOwnedBuffer = C.SignalOwnedBuffer{} - signalFfiError := C.signal_signed_pre_key_record_serialize(&serialized, spkr.ptr) + signalFfiError := C.signal_signed_pre_key_record_serialize(&serialized, spkr.constPtr()) runtime.KeepAlive(spkr) if signalFfiError != nil { return nil, wrapError(signalFfiError) @@ -98,7 +114,7 @@ func (spkr *SignedPreKeyRecord) Serialize() ([]byte, error) { func (spkr *SignedPreKeyRecord) GetSignature() ([]byte, error) { var signature C.SignalOwnedBuffer = C.SignalOwnedBuffer{} - signalFfiError := C.signal_signed_pre_key_record_get_signature(&signature, spkr.ptr) + signalFfiError := C.signal_signed_pre_key_record_get_signature(&signature, spkr.constPtr()) runtime.KeepAlive(spkr) if signalFfiError != nil { return nil, wrapError(signalFfiError) @@ -108,7 +124,7 @@ func (spkr *SignedPreKeyRecord) GetSignature() ([]byte, error) { func (spkr *SignedPreKeyRecord) GetID() (uint32, error) { var id C.uint32_t - signalFfiError := C.signal_signed_pre_key_record_get_id(&id, spkr.ptr) + signalFfiError := C.signal_signed_pre_key_record_get_id(&id, spkr.constPtr()) runtime.KeepAlive(spkr) if signalFfiError != nil { return 0, wrapError(signalFfiError) @@ -118,7 +134,7 @@ func (spkr *SignedPreKeyRecord) GetID() (uint32, error) { func (spkr *SignedPreKeyRecord) GetTimestamp() (time.Time, error) { var ts C.uint64_t - signalFfiError := C.signal_signed_pre_key_record_get_timestamp(&ts, spkr.ptr) + signalFfiError := C.signal_signed_pre_key_record_get_timestamp(&ts, spkr.constPtr()) runtime.KeepAlive(spkr) if signalFfiError != nil { return time.Time{}, wrapError(signalFfiError) @@ -127,21 +143,24 @@ func (spkr *SignedPreKeyRecord) GetTimestamp() (time.Time, error) { } func (spkr *SignedPreKeyRecord) GetPublicKey() (*PublicKey, error) { - var pub *C.SignalPublicKey - signalFfiError := C.signal_signed_pre_key_record_get_public_key(&pub, spkr.ptr) + var pub C.SignalMutPointerPublicKey + signalFfiError := C.signal_signed_pre_key_record_get_public_key( + &pub, + spkr.constPtr(), + ) runtime.KeepAlive(spkr) if signalFfiError != nil { return nil, wrapError(signalFfiError) } - return wrapPublicKey(pub), nil + return wrapPublicKey(pub.raw), nil } func (spkr *SignedPreKeyRecord) GetPrivateKey() (*PrivateKey, error) { - var priv *C.SignalPrivateKey - signalFfiError := C.signal_signed_pre_key_record_get_private_key(&priv, spkr.ptr) + var priv C.SignalMutPointerPrivateKey + signalFfiError := C.signal_signed_pre_key_record_get_private_key(&priv, spkr.constPtr()) runtime.KeepAlive(spkr) if signalFfiError != nil { return nil, wrapError(signalFfiError) } - return wrapPrivateKey(priv), nil + return wrapPrivateKey(priv.raw), nil } diff --git a/pkg/libsignalgo/signedprekeystore.go b/pkg/libsignalgo/signedprekeystore.go index cf3ecca..8ee8ef5 100644 --- a/pkg/libsignalgo/signedprekeystore.go +++ b/pkg/libsignalgo/signedprekeystore.go @@ -1,5 +1,6 @@ // mautrix-signal - A Matrix-signal puppeting bridge. // Copyright (C) 2023 Sumner Evans +// Copyright (C) 2025 Tulir Asokan // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU Affero General Public License as published by @@ -60,10 +61,10 @@ func signal_store_signed_pre_key_callback(storeCtx unsafe.Pointer, id C.uint32_t }) } -func (ctx *CallbackContext) wrapSignedPreKeyStore(store SignedPreKeyStore) *C.SignalSignedPreKeyStore { - return &C.SignalSignedPreKeyStore{ +func (ctx *CallbackContext) wrapSignedPreKeyStore(store SignedPreKeyStore) C.SignalConstPointerFfiSignedPreKeyStoreStruct { + return C.SignalConstPointerFfiSignedPreKeyStoreStruct{&C.SignalSignedPreKeyStore{ ctx: wrapStore(ctx, store), load_signed_pre_key: C.SignalLoadSignedPreKey(C.signal_load_signed_pre_key_callback), store_signed_pre_key: C.SignalStoreSignedPreKey(C.signal_store_signed_pre_key_callback), - } + }} } diff --git a/pkg/libsignalgo/version.go b/pkg/libsignalgo/version.go index 5bcef1b..528ebe6 100644 --- a/pkg/libsignalgo/version.go +++ b/pkg/libsignalgo/version.go @@ -2,4 +2,4 @@ package libsignalgo -const Version = "v0.64.1" +const Version = "v0.65.2" From 22a18a74184ca04cb4aa1a083ffcfc578f75be78 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Fri, 17 Jan 2025 20:05:42 +0200 Subject: [PATCH 255/580] libsignalgo: remove duplicate cflags --- pkg/libsignalgo/accountentropy.go | 1 - pkg/libsignalgo/address.go | 1 - pkg/libsignalgo/aes256gcmsiv.go | 1 - pkg/libsignalgo/authcredential.go | 1 - pkg/libsignalgo/buffer.go | 1 - pkg/libsignalgo/cflags.go | 6 ++++++ pkg/libsignalgo/ciphertextmessage.go | 1 - pkg/libsignalgo/conversions.go | 1 - pkg/libsignalgo/decryptionerrormessage.go | 1 - pkg/libsignalgo/devicetransfer.go | 1 - pkg/libsignalgo/error.go | 1 - pkg/libsignalgo/fingerprint.go | 1 - pkg/libsignalgo/groupcipher.go | 1 - pkg/libsignalgo/groupsecretparams.go | 1 - pkg/libsignalgo/hsmenclave.go | 1 - pkg/libsignalgo/identitykey.go | 1 - pkg/libsignalgo/identitykeystore.go | 1 - pkg/libsignalgo/kdf.go | 1 - pkg/libsignalgo/kyberprekey.go | 1 - pkg/libsignalgo/kyberprekeystore.go | 1 - pkg/libsignalgo/logging.go | 1 - pkg/libsignalgo/message.go | 1 - pkg/libsignalgo/plaintextcontent.go | 1 - pkg/libsignalgo/prekey.go | 1 - pkg/libsignalgo/prekeybundle.go | 1 - pkg/libsignalgo/prekeymessage.go | 1 - pkg/libsignalgo/prekeystore.go | 1 - pkg/libsignalgo/privatekey.go | 1 - pkg/libsignalgo/profilekey.go | 1 - pkg/libsignalgo/publickey.go | 1 - pkg/libsignalgo/sealedsender.go | 1 - pkg/libsignalgo/sendercertificate.go | 1 - pkg/libsignalgo/senderkeydistributionmessage.go | 1 - pkg/libsignalgo/senderkeyrecord.go | 1 - pkg/libsignalgo/senderkeystore.go | 1 - pkg/libsignalgo/servercertificate.go | 1 - pkg/libsignalgo/serverpublicparams.go | 1 - pkg/libsignalgo/serviceid.go | 1 - pkg/libsignalgo/serviceid_clang.go | 1 - pkg/libsignalgo/serviceid_gcc.go | 1 - pkg/libsignalgo/sessionrecord.go | 1 - pkg/libsignalgo/sessionstore.go | 1 - pkg/libsignalgo/sgxclient.go | 1 - pkg/libsignalgo/signedprekey.go | 1 - pkg/libsignalgo/signedprekeystore.go | 1 - pkg/libsignalgo/storeutil.go | 1 - 46 files changed, 6 insertions(+), 45 deletions(-) create mode 100644 pkg/libsignalgo/cflags.go diff --git a/pkg/libsignalgo/accountentropy.go b/pkg/libsignalgo/accountentropy.go index 3160d64..d1ffe35 100644 --- a/pkg/libsignalgo/accountentropy.go +++ b/pkg/libsignalgo/accountentropy.go @@ -17,7 +17,6 @@ package libsignalgo /* -#cgo LDFLAGS: -lsignal_ffi -ldl -lm #include "./libsignal-ffi.h" */ import "C" diff --git a/pkg/libsignalgo/address.go b/pkg/libsignalgo/address.go index 95e4249..cfc6e58 100644 --- a/pkg/libsignalgo/address.go +++ b/pkg/libsignalgo/address.go @@ -18,7 +18,6 @@ package libsignalgo /* -#cgo LDFLAGS: -lsignal_ffi -ldl -lm #include "./libsignal-ffi.h" */ import "C" diff --git a/pkg/libsignalgo/aes256gcmsiv.go b/pkg/libsignalgo/aes256gcmsiv.go index b4d0924..0fddea2 100644 --- a/pkg/libsignalgo/aes256gcmsiv.go +++ b/pkg/libsignalgo/aes256gcmsiv.go @@ -18,7 +18,6 @@ package libsignalgo /* -#cgo LDFLAGS: -lsignal_ffi -ldl -lm #include "./libsignal-ffi.h" */ import "C" diff --git a/pkg/libsignalgo/authcredential.go b/pkg/libsignalgo/authcredential.go index 65b9a67..ab759b2 100644 --- a/pkg/libsignalgo/authcredential.go +++ b/pkg/libsignalgo/authcredential.go @@ -18,7 +18,6 @@ package libsignalgo /* -#cgo LDFLAGS: -lsignal_ffi -ldl -lm #include "./libsignal-ffi.h" #include */ diff --git a/pkg/libsignalgo/buffer.go b/pkg/libsignalgo/buffer.go index 2758590..e6aafdd 100644 --- a/pkg/libsignalgo/buffer.go +++ b/pkg/libsignalgo/buffer.go @@ -17,7 +17,6 @@ package libsignalgo /* -#cgo LDFLAGS: -lsignal_ffi -ldl -lm #include "./libsignal-ffi.h" */ import "C" diff --git a/pkg/libsignalgo/cflags.go b/pkg/libsignalgo/cflags.go new file mode 100644 index 0000000..b86e973 --- /dev/null +++ b/pkg/libsignalgo/cflags.go @@ -0,0 +1,6 @@ +package libsignalgo + +/* +#cgo LDFLAGS: -lsignal_ffi -ldl -lm +*/ +import "C" diff --git a/pkg/libsignalgo/ciphertextmessage.go b/pkg/libsignalgo/ciphertextmessage.go index e1c1bdb..f74fcd5 100644 --- a/pkg/libsignalgo/ciphertextmessage.go +++ b/pkg/libsignalgo/ciphertextmessage.go @@ -18,7 +18,6 @@ package libsignalgo /* -#cgo LDFLAGS: -lsignal_ffi -ldl -lm #include "./libsignal-ffi.h" */ import "C" diff --git a/pkg/libsignalgo/conversions.go b/pkg/libsignalgo/conversions.go index a2da098..d17fa28 100644 --- a/pkg/libsignalgo/conversions.go +++ b/pkg/libsignalgo/conversions.go @@ -17,7 +17,6 @@ package libsignalgo /* -#cgo LDFLAGS: -lsignal_ffi -ldl -lm #include "./libsignal-ffi.h" */ import "C" diff --git a/pkg/libsignalgo/decryptionerrormessage.go b/pkg/libsignalgo/decryptionerrormessage.go index 5e4e3b9..105fffc 100644 --- a/pkg/libsignalgo/decryptionerrormessage.go +++ b/pkg/libsignalgo/decryptionerrormessage.go @@ -18,7 +18,6 @@ package libsignalgo /* -#cgo LDFLAGS: -lsignal_ffi -ldl -lm #include "./libsignal-ffi.h" */ import "C" diff --git a/pkg/libsignalgo/devicetransfer.go b/pkg/libsignalgo/devicetransfer.go index fb50971..f994e51 100644 --- a/pkg/libsignalgo/devicetransfer.go +++ b/pkg/libsignalgo/devicetransfer.go @@ -17,7 +17,6 @@ package libsignalgo /* -#cgo LDFLAGS: -lsignal_ffi -ldl -lm #include "./libsignal-ffi.h" */ import "C" diff --git a/pkg/libsignalgo/error.go b/pkg/libsignalgo/error.go index 9e2a872..8b83a48 100644 --- a/pkg/libsignalgo/error.go +++ b/pkg/libsignalgo/error.go @@ -17,7 +17,6 @@ package libsignalgo /* -#cgo LDFLAGS: -lsignal_ffi -ldl -lm #include "./libsignal-ffi.h" */ import "C" diff --git a/pkg/libsignalgo/fingerprint.go b/pkg/libsignalgo/fingerprint.go index 4bbf24c..b2ef8ce 100644 --- a/pkg/libsignalgo/fingerprint.go +++ b/pkg/libsignalgo/fingerprint.go @@ -18,7 +18,6 @@ package libsignalgo /* -#cgo LDFLAGS: -lsignal_ffi -ldl -lm #include "./libsignal-ffi.h" */ import "C" diff --git a/pkg/libsignalgo/groupcipher.go b/pkg/libsignalgo/groupcipher.go index 33e18aa..7b58207 100644 --- a/pkg/libsignalgo/groupcipher.go +++ b/pkg/libsignalgo/groupcipher.go @@ -18,7 +18,6 @@ package libsignalgo /* -#cgo LDFLAGS: -lsignal_ffi -ldl -lm #include "./libsignal-ffi.h" */ import "C" diff --git a/pkg/libsignalgo/groupsecretparams.go b/pkg/libsignalgo/groupsecretparams.go index 943dfda..8ad9b39 100644 --- a/pkg/libsignalgo/groupsecretparams.go +++ b/pkg/libsignalgo/groupsecretparams.go @@ -18,7 +18,6 @@ package libsignalgo /* -#cgo LDFLAGS: -lsignal_ffi -ldl -lm #include "./libsignal-ffi.h" */ import "C" diff --git a/pkg/libsignalgo/hsmenclave.go b/pkg/libsignalgo/hsmenclave.go index 15a44fa..2eb61cd 100644 --- a/pkg/libsignalgo/hsmenclave.go +++ b/pkg/libsignalgo/hsmenclave.go @@ -18,7 +18,6 @@ package libsignalgo /* -#cgo LDFLAGS: -lsignal_ffi -ldl -lm #include "./libsignal-ffi.h" */ import "C" diff --git a/pkg/libsignalgo/identitykey.go b/pkg/libsignalgo/identitykey.go index 9cd8425..7877d22 100644 --- a/pkg/libsignalgo/identitykey.go +++ b/pkg/libsignalgo/identitykey.go @@ -18,7 +18,6 @@ package libsignalgo /* -#cgo LDFLAGS: -lsignal_ffi -ldl -lm #include "./libsignal-ffi.h" */ import "C" diff --git a/pkg/libsignalgo/identitykeystore.go b/pkg/libsignalgo/identitykeystore.go index 88e5eaa..c59b660 100644 --- a/pkg/libsignalgo/identitykeystore.go +++ b/pkg/libsignalgo/identitykeystore.go @@ -18,7 +18,6 @@ package libsignalgo /* -#cgo LDFLAGS: -lsignal_ffi -ldl -lm #include "./libsignal-ffi.h" typedef const SignalProtocolAddress const_address; diff --git a/pkg/libsignalgo/kdf.go b/pkg/libsignalgo/kdf.go index d64e819..2f6a497 100644 --- a/pkg/libsignalgo/kdf.go +++ b/pkg/libsignalgo/kdf.go @@ -17,7 +17,6 @@ package libsignalgo /* -#cgo LDFLAGS: -lsignal_ffi -ldl -lm #include "./libsignal-ffi.h" */ import "C" diff --git a/pkg/libsignalgo/kyberprekey.go b/pkg/libsignalgo/kyberprekey.go index 7f9c7b4..707db76 100644 --- a/pkg/libsignalgo/kyberprekey.go +++ b/pkg/libsignalgo/kyberprekey.go @@ -18,7 +18,6 @@ package libsignalgo /* -#cgo LDFLAGS: -lsignal_ffi -ldl -lm #include "./libsignal-ffi.h" */ import "C" diff --git a/pkg/libsignalgo/kyberprekeystore.go b/pkg/libsignalgo/kyberprekeystore.go index 39beed7..072db99 100644 --- a/pkg/libsignalgo/kyberprekeystore.go +++ b/pkg/libsignalgo/kyberprekeystore.go @@ -18,7 +18,6 @@ package libsignalgo /* -#cgo LDFLAGS: -lsignal_ffi -ldl -lm #include "./libsignal-ffi.h" typedef const SignalKyberPreKeyRecord const_kyber_pre_key_record; diff --git a/pkg/libsignalgo/logging.go b/pkg/libsignalgo/logging.go index e0a2351..9d21afa 100644 --- a/pkg/libsignalgo/logging.go +++ b/pkg/libsignalgo/logging.go @@ -17,7 +17,6 @@ package libsignalgo /* -#cgo LDFLAGS: -lsignal_ffi -ldl -lm #include <./libsignal-ffi.h> extern void signal_log_callback(void *ctx, SignalLogLevel level, char *file, uint32_t line, char *message); diff --git a/pkg/libsignalgo/message.go b/pkg/libsignalgo/message.go index d512d6f..f016daa 100644 --- a/pkg/libsignalgo/message.go +++ b/pkg/libsignalgo/message.go @@ -18,7 +18,6 @@ package libsignalgo /* -#cgo LDFLAGS: -lsignal_ffi -ldl -lm #include "./libsignal-ffi.h" */ import "C" diff --git a/pkg/libsignalgo/plaintextcontent.go b/pkg/libsignalgo/plaintextcontent.go index f395f0b..346f0c9 100644 --- a/pkg/libsignalgo/plaintextcontent.go +++ b/pkg/libsignalgo/plaintextcontent.go @@ -18,7 +18,6 @@ package libsignalgo /* -#cgo LDFLAGS: -lsignal_ffi -ldl -lm #include "./libsignal-ffi.h" */ import "C" diff --git a/pkg/libsignalgo/prekey.go b/pkg/libsignalgo/prekey.go index 0c56c71..4d01f89 100644 --- a/pkg/libsignalgo/prekey.go +++ b/pkg/libsignalgo/prekey.go @@ -18,7 +18,6 @@ package libsignalgo /* -#cgo LDFLAGS: -lsignal_ffi -ldl -lm #include "./libsignal-ffi.h" */ import "C" diff --git a/pkg/libsignalgo/prekeybundle.go b/pkg/libsignalgo/prekeybundle.go index 7fd2e34..4cd5547 100644 --- a/pkg/libsignalgo/prekeybundle.go +++ b/pkg/libsignalgo/prekeybundle.go @@ -18,7 +18,6 @@ package libsignalgo /* -#cgo LDFLAGS: -lsignal_ffi -ldl -lm #include "./libsignal-ffi.h" */ import "C" diff --git a/pkg/libsignalgo/prekeymessage.go b/pkg/libsignalgo/prekeymessage.go index 6bff0bb..7261933 100644 --- a/pkg/libsignalgo/prekeymessage.go +++ b/pkg/libsignalgo/prekeymessage.go @@ -18,7 +18,6 @@ package libsignalgo /* -#cgo LDFLAGS: -lsignal_ffi -ldl -lm #include "./libsignal-ffi.h" */ import "C" diff --git a/pkg/libsignalgo/prekeystore.go b/pkg/libsignalgo/prekeystore.go index c9b0469..643e286 100644 --- a/pkg/libsignalgo/prekeystore.go +++ b/pkg/libsignalgo/prekeystore.go @@ -18,7 +18,6 @@ package libsignalgo /* -#cgo LDFLAGS: -lsignal_ffi -ldl -lm #include "./libsignal-ffi.h" typedef const SignalPreKeyRecord const_pre_key_record; diff --git a/pkg/libsignalgo/privatekey.go b/pkg/libsignalgo/privatekey.go index 3703727..829d3f0 100644 --- a/pkg/libsignalgo/privatekey.go +++ b/pkg/libsignalgo/privatekey.go @@ -18,7 +18,6 @@ package libsignalgo /* -#cgo LDFLAGS: -lsignal_ffi -ldl -lm #include "./libsignal-ffi.h" */ import "C" diff --git a/pkg/libsignalgo/profilekey.go b/pkg/libsignalgo/profilekey.go index c78c9d1..8d2ae04 100644 --- a/pkg/libsignalgo/profilekey.go +++ b/pkg/libsignalgo/profilekey.go @@ -18,7 +18,6 @@ package libsignalgo /* -#cgo LDFLAGS: -lsignal_ffi -ldl -lm #include "./libsignal-ffi.h" #include */ diff --git a/pkg/libsignalgo/publickey.go b/pkg/libsignalgo/publickey.go index 8c4c98f..dcf9647 100644 --- a/pkg/libsignalgo/publickey.go +++ b/pkg/libsignalgo/publickey.go @@ -18,7 +18,6 @@ package libsignalgo /* -#cgo LDFLAGS: -lsignal_ffi -ldl -lm #include "./libsignal-ffi.h" */ import "C" diff --git a/pkg/libsignalgo/sealedsender.go b/pkg/libsignalgo/sealedsender.go index 4912977..1e93410 100644 --- a/pkg/libsignalgo/sealedsender.go +++ b/pkg/libsignalgo/sealedsender.go @@ -18,7 +18,6 @@ package libsignalgo /* -#cgo LDFLAGS: -lsignal_ffi -ldl -lm #include "./libsignal-ffi.h" */ import "C" diff --git a/pkg/libsignalgo/sendercertificate.go b/pkg/libsignalgo/sendercertificate.go index 46caf1c..1d7422f 100644 --- a/pkg/libsignalgo/sendercertificate.go +++ b/pkg/libsignalgo/sendercertificate.go @@ -18,7 +18,6 @@ package libsignalgo /* -#cgo LDFLAGS: -lsignal_ffi -ldl -lm #include "./libsignal-ffi.h" */ import "C" diff --git a/pkg/libsignalgo/senderkeydistributionmessage.go b/pkg/libsignalgo/senderkeydistributionmessage.go index e772c58..d07c558 100644 --- a/pkg/libsignalgo/senderkeydistributionmessage.go +++ b/pkg/libsignalgo/senderkeydistributionmessage.go @@ -18,7 +18,6 @@ package libsignalgo /* -#cgo LDFLAGS: -lsignal_ffi -ldl -lm #include "./libsignal-ffi.h" */ import "C" diff --git a/pkg/libsignalgo/senderkeyrecord.go b/pkg/libsignalgo/senderkeyrecord.go index 7299ae5..b40c46f 100644 --- a/pkg/libsignalgo/senderkeyrecord.go +++ b/pkg/libsignalgo/senderkeyrecord.go @@ -18,7 +18,6 @@ package libsignalgo /* -#cgo LDFLAGS: -lsignal_ffi -ldl -lm #include "./libsignal-ffi.h" */ import "C" diff --git a/pkg/libsignalgo/senderkeystore.go b/pkg/libsignalgo/senderkeystore.go index d3bda2f..30df4ad 100644 --- a/pkg/libsignalgo/senderkeystore.go +++ b/pkg/libsignalgo/senderkeystore.go @@ -18,7 +18,6 @@ package libsignalgo /* -#cgo LDFLAGS: -lsignal_ffi -ldl -lm #include "./libsignal-ffi.h" typedef const SignalProtocolAddress const_address; diff --git a/pkg/libsignalgo/servercertificate.go b/pkg/libsignalgo/servercertificate.go index da56b0b..bf46009 100644 --- a/pkg/libsignalgo/servercertificate.go +++ b/pkg/libsignalgo/servercertificate.go @@ -18,7 +18,6 @@ package libsignalgo /* -#cgo LDFLAGS: -lsignal_ffi -ldl -lm #include "./libsignal-ffi.h" */ import "C" diff --git a/pkg/libsignalgo/serverpublicparams.go b/pkg/libsignalgo/serverpublicparams.go index fc046c1..c1de0cd 100644 --- a/pkg/libsignalgo/serverpublicparams.go +++ b/pkg/libsignalgo/serverpublicparams.go @@ -17,7 +17,6 @@ package libsignalgo /* -#cgo LDFLAGS: -lsignal_ffi -ldl -lm #include "./libsignal-ffi.h" #include */ diff --git a/pkg/libsignalgo/serviceid.go b/pkg/libsignalgo/serviceid.go index 5308af1..19513de 100644 --- a/pkg/libsignalgo/serviceid.go +++ b/pkg/libsignalgo/serviceid.go @@ -17,7 +17,6 @@ package libsignalgo /* -#cgo LDFLAGS: -lsignal_ffi -ldl -lm #include "./libsignal-ffi.h" #include */ diff --git a/pkg/libsignalgo/serviceid_clang.go b/pkg/libsignalgo/serviceid_clang.go index 3e9ae17..72c9ed3 100644 --- a/pkg/libsignalgo/serviceid_clang.go +++ b/pkg/libsignalgo/serviceid_clang.go @@ -3,7 +3,6 @@ package libsignalgo /* -#cgo LDFLAGS: -lsignal_ffi -ldl -lm #include "./libsignal-ffi.h" #include */ diff --git a/pkg/libsignalgo/serviceid_gcc.go b/pkg/libsignalgo/serviceid_gcc.go index 9ff97bc..b8dbbee 100644 --- a/pkg/libsignalgo/serviceid_gcc.go +++ b/pkg/libsignalgo/serviceid_gcc.go @@ -3,7 +3,6 @@ package libsignalgo /* -#cgo LDFLAGS: -lsignal_ffi -ldl -lm #include "./libsignal-ffi.h" #include */ diff --git a/pkg/libsignalgo/sessionrecord.go b/pkg/libsignalgo/sessionrecord.go index 3523f62..a2ee9dd 100644 --- a/pkg/libsignalgo/sessionrecord.go +++ b/pkg/libsignalgo/sessionrecord.go @@ -18,7 +18,6 @@ package libsignalgo /* -#cgo LDFLAGS: -lsignal_ffi -ldl -lm #include "./libsignal-ffi.h" */ import "C" diff --git a/pkg/libsignalgo/sessionstore.go b/pkg/libsignalgo/sessionstore.go index ad88d62..da430c1 100644 --- a/pkg/libsignalgo/sessionstore.go +++ b/pkg/libsignalgo/sessionstore.go @@ -18,7 +18,6 @@ package libsignalgo /* -#cgo LDFLAGS: -lsignal_ffi -ldl -lm #include "./libsignal-ffi.h" typedef const SignalSessionRecord const_session_record; diff --git a/pkg/libsignalgo/sgxclient.go b/pkg/libsignalgo/sgxclient.go index a2ba553..e2d817e 100644 --- a/pkg/libsignalgo/sgxclient.go +++ b/pkg/libsignalgo/sgxclient.go @@ -17,7 +17,6 @@ package libsignalgo /* -#cgo LDFLAGS: -lsignal_ffi -ldl -lm #include "./libsignal-ffi.h" */ import "C" diff --git a/pkg/libsignalgo/signedprekey.go b/pkg/libsignalgo/signedprekey.go index ca86ce3..32afc37 100644 --- a/pkg/libsignalgo/signedprekey.go +++ b/pkg/libsignalgo/signedprekey.go @@ -18,7 +18,6 @@ package libsignalgo /* -#cgo LDFLAGS: -lsignal_ffi -ldl -lm #include "./libsignal-ffi.h" */ import "C" diff --git a/pkg/libsignalgo/signedprekeystore.go b/pkg/libsignalgo/signedprekeystore.go index 8ee8ef5..b595578 100644 --- a/pkg/libsignalgo/signedprekeystore.go +++ b/pkg/libsignalgo/signedprekeystore.go @@ -18,7 +18,6 @@ package libsignalgo /* -#cgo LDFLAGS: -lsignal_ffi -ldl -lm #include "./libsignal-ffi.h" typedef const SignalSignedPreKeyRecord const_signed_pre_key_record; diff --git a/pkg/libsignalgo/storeutil.go b/pkg/libsignalgo/storeutil.go index cc99ddf..4041c9b 100644 --- a/pkg/libsignalgo/storeutil.go +++ b/pkg/libsignalgo/storeutil.go @@ -17,7 +17,6 @@ package libsignalgo /* -#cgo LDFLAGS: -lsignal_ffi -ldl -lm #include "./libsignal-ffi.h" */ import "C" From 853171f4fcda854236afa89103f4375cccf7c29a Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Sat, 18 Jan 2025 01:01:05 +0200 Subject: [PATCH 256/580] signalmeow/storageservice: fix ssre2 implementation --- pkg/signalmeow/storageservice.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/pkg/signalmeow/storageservice.go b/pkg/signalmeow/storageservice.go index 1902c4b..ae003ae 100644 --- a/pkg/signalmeow/storageservice.go +++ b/pkg/signalmeow/storageservice.go @@ -182,13 +182,13 @@ func deriveStorageManifestKey(storageKey []byte, version uint64) []byte { const storageServiceItemKeyInfoPrefix = "20240801_SIGNAL_STORAGE_SERVICE_ITEM_" const storageServiceItemKeyLen = 32 -func deriveStorageItemKey(storageKey, recordIKM []byte, itemID string) []byte { +func deriveStorageItemKey(storageKey, recordIKM, rawItemID []byte, b64ItemID string) []byte { if recordIKM == nil { h := hmac.New(sha256.New, storageKey) - exerrors.Must(fmt.Fprintf(h, "Item_%s", itemID)) + exerrors.Must(fmt.Fprintf(h, "Item_%s", b64ItemID)) return h.Sum(nil) } else { - h := hkdf.New(sha256.New, recordIKM, []byte{}, append([]byte(storageServiceItemKeyInfoPrefix), itemID...)) + h := hkdf.New(sha256.New, recordIKM, []byte{}, append([]byte(storageServiceItemKeyInfoPrefix), rawItemID...)) out := make([]byte, storageServiceItemKeyLen) exerrors.Must(io.ReadFull(h, out)) return out @@ -278,7 +278,7 @@ func (cli *Client) fetchStorageRecords( log.Warn().Int("item_index", i).Str("item_key", base64Key).Msg("Received unexpected storage item") continue } - itemKey := deriveStorageItemKey(storageKey, recordIKM, base64Key) + itemKey := deriveStorageItemKey(storageKey, recordIKM, encryptedItem.GetKey(), base64Key) decryptedItemBytes, err := decryptBytes(itemKey, encryptedItem.GetValue()) if err != nil { log.Warn().Err(err). From 0a0e0d50d36722f2fbe34dbf808a633a7ecdce87 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Sat, 18 Jan 2025 02:58:43 +0200 Subject: [PATCH 257/580] signalmeow: add support for receiving history transfers --- pkg/connector/login.go | 2 +- pkg/libsignalgo/backupkey.go | 140 + pkg/libsignalgo/messagebackupkey.go | 103 + pkg/signalmeow/attachments.go | 20 +- pkg/signalmeow/attachments_stream.go | 178 + pkg/signalmeow/backup.go | 275 + pkg/signalmeow/protobuf/backuppb/Backup.pb.go | 11548 ++++++++++++++++ .../protobuf/backuppb/Backup.pb.raw | Bin 0 -> 31334 bytes pkg/signalmeow/protobuf/backuppb/Backup.proto | 1260 ++ pkg/signalmeow/protobuf/build-protos.sh | 5 + pkg/signalmeow/protobuf/update-protos.sh | 18 +- pkg/signalmeow/provisioning.go | 26 +- pkg/signalmeow/store/container.go | 26 +- pkg/signalmeow/store/device.go | 3 + pkg/signalmeow/store/upgrades/00-latest.sql | 9 +- .../store/upgrades/18-store-backup-keys.sql | 4 + 16 files changed, 13585 insertions(+), 32 deletions(-) create mode 100644 pkg/libsignalgo/backupkey.go create mode 100644 pkg/libsignalgo/messagebackupkey.go create mode 100644 pkg/signalmeow/attachments_stream.go create mode 100644 pkg/signalmeow/backup.go create mode 100644 pkg/signalmeow/protobuf/backuppb/Backup.pb.go create mode 100644 pkg/signalmeow/protobuf/backuppb/Backup.pb.raw create mode 100644 pkg/signalmeow/protobuf/backuppb/Backup.proto create mode 100644 pkg/signalmeow/store/upgrades/18-store-backup-keys.sql diff --git a/pkg/connector/login.go b/pkg/connector/login.go index da1b66a..e2f2e98 100644 --- a/pkg/connector/login.go +++ b/pkg/connector/login.go @@ -79,7 +79,7 @@ func (qr *QRLogin) Start(ctx context.Context) (*bridgev2.LoginStep, error) { provCtx, cancel := context.WithCancel(log.WithContext(context.Background())) qr.cancelChan = cancel // Don't use the start context here: the channel will outlive the start request. - qr.ProvChan = signalmeow.PerformProvisioning(provCtx, qr.Main.Store, qr.Main.Config.DeviceName) + qr.ProvChan = signalmeow.PerformProvisioning(provCtx, qr.Main.Store, qr.Main.Config.DeviceName, false) var resp signalmeow.ProvisioningResponse select { case resp = <-qr.ProvChan: diff --git a/pkg/libsignalgo/backupkey.go b/pkg/libsignalgo/backupkey.go new file mode 100644 index 0000000..fd8a800 --- /dev/null +++ b/pkg/libsignalgo/backupkey.go @@ -0,0 +1,140 @@ +// mautrix-signal - A Matrix-signal puppeting bridge. +// Copyright (C) 2025 Tulir Asokan +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +package libsignalgo + +/* +#include "./libsignal-ffi.h" +*/ +import "C" +import ( + "runtime" + "unsafe" + + "go.mau.fi/util/random" +) + +type BackupKey [C.SignalBACKUP_KEY_LEN]byte + +func (bk *BackupKey) Slice() []byte { + if bk == nil { + return nil + } + return bk[:] +} + +const BackupIDLength = 16 + +type BackupID [BackupIDLength]byte +type BackupMetadataKey [C.SignalLOCAL_BACKUP_METADATA_KEY_LEN]byte +type BackupMediaID [C.SignalMEDIA_ID_LEN]byte +type BackupMediaKey [C.SignalMEDIA_ENCRYPTION_KEY_LEN]byte + +func GenerateRandomBackupKey() *BackupKey { + return (*BackupKey)(random.Bytes(C.SignalBACKUP_KEY_LEN)) +} + +func BytesToBackupKey(bytes []byte) *BackupKey { + if len(bytes) != C.SignalBACKUP_KEY_LEN { + return nil + } + return (*BackupKey)(bytes) +} + +func (bk *BackupKey) DeriveBackupID(aci ServiceID) (*BackupID, error) { + var out BackupID + signalFfiError := C.signal_backup_key_derive_backup_id( + (*[BackupIDLength]C.uint8_t)(unsafe.Pointer(&out)), + (*[C.SignalBACKUP_KEY_LEN]C.uint8_t)(unsafe.Pointer(bk)), + aci.CFixedBytes(), + ) + runtime.KeepAlive(bk) + if signalFfiError != nil { + return nil, wrapError(signalFfiError) + } + return &out, nil +} + +func (bk *BackupKey) DeriveECKey(aci ServiceID) (*PrivateKey, error) { + var out C.SignalMutPointerPrivateKey + signalFfiError := C.signal_backup_key_derive_ec_key( + &out, + (*[C.SignalBACKUP_KEY_LEN]C.uint8_t)(unsafe.Pointer(&bk)), + aci.CFixedBytes(), + ) + runtime.KeepAlive(bk) + if signalFfiError != nil { + return nil, wrapError(signalFfiError) + } + return wrapPrivateKey(out.raw), nil +} + +func (bk *BackupKey) DeriveLocalBackupMetadataKey() (*BackupMetadataKey, error) { + var out BackupMetadataKey + signalFfiError := C.signal_backup_key_derive_local_backup_metadata_key( + (*[C.SignalLOCAL_BACKUP_METADATA_KEY_LEN]C.uint8_t)(unsafe.Pointer(&out)), + (*[C.SignalBACKUP_KEY_LEN]C.uint8_t)(unsafe.Pointer(bk)), + ) + runtime.KeepAlive(bk) + if signalFfiError != nil { + return nil, wrapError(signalFfiError) + } + return &out, nil +} + +func (bk *BackupKey) DeriveMediaID(mediaName string) (*BackupMediaID, error) { + var out BackupMediaID + signalFfiError := C.signal_backup_key_derive_media_id( + (*[C.SignalMEDIA_ID_LEN]C.uint8_t)(unsafe.Pointer(&out)), + (*[C.SignalBACKUP_KEY_LEN]C.uint8_t)(unsafe.Pointer(bk)), + C.CString(mediaName), + ) + runtime.KeepAlive(bk) + if signalFfiError != nil { + return nil, wrapError(signalFfiError) + } + return &out, nil +} + +func (bk *BackupKey) DeriveMediaEncryptionKey(mediaID *BackupMediaID) (*BackupMediaKey, error) { + var out BackupMediaKey + signalFfiError := C.signal_backup_key_derive_media_encryption_key( + (*[C.SignalMEDIA_ENCRYPTION_KEY_LEN]C.uint8_t)(unsafe.Pointer(&out)), + (*[C.SignalBACKUP_KEY_LEN]C.uint8_t)(unsafe.Pointer(bk)), + (*[C.SignalMEDIA_ID_LEN]C.uint8_t)(unsafe.Pointer(mediaID)), + ) + runtime.KeepAlive(bk) + runtime.KeepAlive(mediaID) + if signalFfiError != nil { + return nil, wrapError(signalFfiError) + } + return &out, nil +} + +func (bk *BackupKey) DeriveThumbnailTransitEncryptionKey(mediaID *BackupMediaID) (*BackupMediaKey, error) { + var out BackupMediaKey + signalFfiError := C.signal_backup_key_derive_thumbnail_transit_encryption_key( + (*[C.SignalMEDIA_ENCRYPTION_KEY_LEN]C.uint8_t)(unsafe.Pointer(&out)), + (*[C.SignalBACKUP_KEY_LEN]C.uint8_t)(unsafe.Pointer(bk)), + (*[C.SignalMEDIA_ID_LEN]C.uint8_t)(unsafe.Pointer(mediaID)), + ) + runtime.KeepAlive(bk) + runtime.KeepAlive(mediaID) + if signalFfiError != nil { + return nil, wrapError(signalFfiError) + } + return &out, nil +} diff --git a/pkg/libsignalgo/messagebackupkey.go b/pkg/libsignalgo/messagebackupkey.go new file mode 100644 index 0000000..87f2b4f --- /dev/null +++ b/pkg/libsignalgo/messagebackupkey.go @@ -0,0 +1,103 @@ +// mautrix-signal - A Matrix-signal puppeting bridge. +// Copyright (C) 2025 Tulir Asokan +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +package libsignalgo + +/* +#include "./libsignal-ffi.h" +*/ +import "C" +import ( + "runtime" + "unsafe" +) + +type MessageBackupKey struct { + nc noCopy + ptr *C.SignalMessageBackupKey +} + +func wrapMessageBackupKey(ptr *C.SignalMessageBackupKey) *MessageBackupKey { + backupKey := &MessageBackupKey{ptr: ptr} + runtime.SetFinalizer(backupKey, (*MessageBackupKey).Destroy) + return backupKey +} + +func MessageBackupKeyFromAccountEntropyPool(aep AccountEntropyPool, aci ServiceID) (*MessageBackupKey, error) { + var bk C.SignalMutPointerMessageBackupKey + signalFfiError := C.signal_message_backup_key_from_account_entropy_pool( + &bk, + C.CString(string(aep)), + aci.CFixedBytes(), + ) + runtime.KeepAlive(aep) + if signalFfiError != nil { + return nil, wrapError(signalFfiError) + } + return wrapMessageBackupKey(bk.raw), nil +} + +func MessageBackupKeyFromBackupKeyAndID(backupKey *BackupKey, backupID *BackupID) (*MessageBackupKey, error) { + var bk C.SignalMutPointerMessageBackupKey + signalFfiError := C.signal_message_backup_key_from_backup_key_and_backup_id( + &bk, + (*[C.SignalBACKUP_KEY_LEN]C.uint8_t)(unsafe.Pointer(backupKey)), + (*[BackupIDLength]C.uint8_t)(unsafe.Pointer(backupID)), + ) + runtime.KeepAlive(backupKey) + runtime.KeepAlive(backupID) + if signalFfiError != nil { + return nil, wrapError(signalFfiError) + } + return wrapMessageBackupKey(bk.raw), nil +} + +func (bk *MessageBackupKey) mutPtr() C.SignalMutPointerMessageBackupKey { + return C.SignalMutPointerMessageBackupKey{bk.ptr} +} + +func (bk *MessageBackupKey) constPtr() C.SignalConstPointerMessageBackupKey { + return C.SignalConstPointerMessageBackupKey{bk.ptr} +} + +func (bk *MessageBackupKey) Destroy() error { + runtime.SetFinalizer(bk, nil) + return wrapError(C.signal_message_backup_key_destroy(bk.mutPtr())) +} + +func (bk *MessageBackupKey) GetHMACKey() ([32]byte, error) { + var out [32]byte + signalFfiError := C.signal_message_backup_key_get_hmac_key( + (*[32]C.uint8_t)(unsafe.Pointer(&out)), + bk.constPtr(), + ) + if signalFfiError != nil { + return out, wrapError(signalFfiError) + } + return out, nil +} + +func (bk *MessageBackupKey) GetAESKey() ([32]byte, error) { + var out [32]byte + signalFfiError := C.signal_message_backup_key_get_aes_key( + (*[32]C.uint8_t)(unsafe.Pointer(&out)), + bk.constPtr(), + ) + if signalFfiError != nil { + return out, wrapError(signalFfiError) + } + return out, nil +} diff --git a/pkg/signalmeow/attachments.go b/pkg/signalmeow/attachments.go index ca56634..4d5d6d6 100644 --- a/pkg/signalmeow/attachments.go +++ b/pkg/signalmeow/attachments.go @@ -47,11 +47,11 @@ const ( attachmentIDDownloadPath = "/attachments/%d" ) -func getAttachmentPath(id uint64, key string, cdnNumber uint32) (string, error) { +func getAttachmentPath(id uint64, key string) string { if id != 0 { - return fmt.Sprintf(attachmentIDDownloadPath, id), nil + return fmt.Sprintf(attachmentIDDownloadPath, id) } - return fmt.Sprintf(attachmentKeyDownloadPath, key), nil + return fmt.Sprintf(attachmentKeyDownloadPath, key) } // ErrInvalidMACForAttachment signals that the downloaded attachment has an invalid MAC. @@ -59,10 +59,7 @@ var ErrInvalidMACForAttachment = errors.New("invalid MAC for attachment") var ErrInvalidDigestForAttachment = errors.New("invalid digest for attachment") func DownloadAttachment(ctx context.Context, a *signalpb.AttachmentPointer) ([]byte, error) { - path, err := getAttachmentPath(a.GetCdnId(), a.GetCdnKey(), a.GetCdnNumber()) - if err != nil { - return nil, err - } + path := getAttachmentPath(a.GetCdnId(), a.GetCdnKey()) resp, err := web.GetAttachment(ctx, path, a.GetCdnNumber(), nil) if err != nil { return nil, err @@ -86,17 +83,20 @@ func DownloadAttachment(ctx context.Context, a *signalpb.AttachmentPointer) ([]b return decryptAttachment(body, a.Key, a.Digest, *a.Size) } +const MACLength = 32 +const IVLength = 16 + func decryptAttachment(body, key, digest []byte, size uint32) ([]byte, error) { hash := sha256.Sum256(body) if !hmac.Equal(hash[:], digest) { return nil, ErrInvalidDigestForAttachment } - l := len(body) - 32 - if !verifyMAC(key[32:], body[:l], body[l:]) { + l := len(body) - MACLength + if !verifyMAC(key[MACLength:], body[:l], body[l:]) { return nil, ErrInvalidMACForAttachment } - decrypted, err := aesDecrypt(key[:32], body[:l]) + decrypted, err := aesDecrypt(key[:MACLength], body[:l]) if err != nil { return nil, err } diff --git a/pkg/signalmeow/attachments_stream.go b/pkg/signalmeow/attachments_stream.go new file mode 100644 index 0000000..a410df0 --- /dev/null +++ b/pkg/signalmeow/attachments_stream.go @@ -0,0 +1,178 @@ +// mautrix-signal - A Matrix-signal puppeting bridge. +// Copyright (C) 2025 Tulir Asokan +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +package signalmeow + +import ( + "bufio" + "crypto/aes" + "crypto/cipher" + "crypto/hmac" + "crypto/sha256" + "encoding/binary" + "errors" + "fmt" + "hash" + "io" + "os" + + "google.golang.org/protobuf/proto" +) + +func verifyMACStream(hmacKey [32]byte, input io.Reader, totalSize int64) (bool, error) { + if totalSize <= 0 { + file, ok := input.(*os.File) + if ok { + stat, err := file.Stat() + if err != nil { + return false, fmt.Errorf("failed to stat file: %w", err) + } + totalSize = stat.Size() + } else { + return false, fmt.Errorf("total size is unknown") + } + } + hasher := hmac.New(sha256.New, hmacKey[:]) + _, err := io.CopyN(hasher, input, totalSize-MACLength) + if err != nil { + return false, fmt.Errorf("failed to hash file: %w", err) + } + actualHash := hasher.Sum(nil) + expectedHash := make([]byte, MACLength) + _, err = io.ReadFull(input, expectedHash) + if err != nil { + return false, fmt.Errorf("failed to read hash: %w", err) + } + return hmac.Equal(expectedHash, actualHash), nil +} + +type decryptingReader struct { + input io.Reader + cipher cipher.BlockMode + hasher hash.Hash + aesKey *[32]byte + remainingSize int64 +} + +func (dr *decryptingReader) Read(p []byte) (int, error) { + if dr.remainingSize == 0 { + return 0, io.EOF + } else if len(p) < aes.BlockSize { + return 0, fmt.Errorf("buffer too small (must be at least %d bytes)", aes.BlockSize) + } + if dr.cipher == nil { + iv := make([]byte, IVLength) + _, err := io.ReadFull(dr.input, iv) + if err != nil { + return 0, fmt.Errorf("failed to read IV: %w", err) + } + block, err := aes.NewCipher(dr.aesKey[:]) + if err != nil { + return 0, fmt.Errorf("failed to create cipher: %w", err) + } + dr.cipher = cipher.NewCBCDecrypter(block, iv) + dr.hasher.Write(iv) + } + maxLen := int64(len(p) - len(p)%aes.BlockSize) + if maxLen > dr.remainingSize { + maxLen = dr.remainingSize + } + p = p[:maxLen] + _, err := io.ReadFull(dr.input, p) + if err != nil { + return 0, err + } + dr.remainingSize -= maxLen + dr.hasher.Write(p) + dr.cipher.CryptBlocks(p, p) + if dr.remainingSize == 0 { + p, err = UnpadPKCS7(p) + if err != nil { + return 0, fmt.Errorf("failed to unpad: %w", err) + } + expectedMAC := make([]byte, MACLength) + _, err = io.ReadFull(dr.input, expectedMAC) + if err != nil { + return 0, fmt.Errorf("failed to read MAC: %w", err) + } + actualMAC := dr.hasher.Sum(nil) + if !hmac.Equal(expectedMAC, actualMAC) { + return 0, fmt.Errorf("hmac mismatch") + } + } + return len(p), nil +} + +func (dr *decryptingReader) Close() error { + if dr.remainingSize != 0 { + return fmt.Errorf("unexpected remaining size %d", dr.remainingSize) + } + return nil +} + +func aesDecryptStream(aesKey, macKey [32]byte, input io.Reader, totalSize int64) io.ReadCloser { + return &decryptingReader{ + aesKey: &aesKey, + hasher: hmac.New(sha256.New, macKey[:]), + input: input, + remainingSize: totalSize - MACLength - IVLength, + } +} + +func splitChunksStream(input io.Reader, callback func([]byte) error) error { + byteReader, ok := input.(io.ByteReader) + if !ok { + bufInput := bufio.NewReader(input) + byteReader = bufInput + input = bufInput + } + var cachedBuf []byte + for { + msgLen, err := binary.ReadUvarint(byteReader) + if errors.Is(err, io.EOF) { + return nil + } else if err != nil { + return fmt.Errorf("failed to read chunk length: %w", err) + } + if msgLen == 0 { + continue + } + if msgLen > uint64(len(cachedBuf)) { + cachedBuf = make([]byte, min(msgLen, 8192)) + } + buf := cachedBuf[:msgLen] + _, err = io.ReadFull(input, buf) + if err != nil { + return fmt.Errorf("failed to read chunk: %w", err) + } + err = callback(buf) + if err != nil { + return err + } + } +} + +func splitProtoChunksStream[ChunkType proto.Message](input io.Reader, callback func(ChunkType) error) error { + protoReflect := (*new(ChunkType)).ProtoReflect() + return splitChunksStream(input, func(buf []byte) error { + msg := protoReflect.New().Interface().(ChunkType) + err := proto.Unmarshal(buf, msg) + if err != nil { + return fmt.Errorf("failed to unmarshal chunk: %w", err) + } + return callback(msg) + }) +} diff --git a/pkg/signalmeow/backup.go b/pkg/signalmeow/backup.go new file mode 100644 index 0000000..536302d --- /dev/null +++ b/pkg/signalmeow/backup.go @@ -0,0 +1,275 @@ +// mautrix-signal - A Matrix-signal puppeting bridge. +// Copyright (C) 2025 Tulir Asokan +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +package signalmeow + +import ( + "bufio" + "compress/gzip" + "context" + "crypto/hmac" + "encoding/json" + "errors" + "fmt" + "io" + "net/http" + "os" + "strconv" + "time" + + "github.com/rs/zerolog" + "google.golang.org/protobuf/proto" + + "go.mau.fi/mautrix-signal/pkg/libsignalgo" + "go.mau.fi/mautrix-signal/pkg/signalmeow/protobuf/backuppb" + "go.mau.fi/mautrix-signal/pkg/signalmeow/web" +) + +const transferArchiveFetchTimeout = 1 * time.Hour + +var ( + ErrTransferRelinkRequested = errors.New("relink requested") + ErrTransferContinueWithoutUpload = errors.New("continue without upload") + + ErrNoEphemeralBackupKey = errors.New("no ephemeral backup key") +) + +type TransferArchiveMetadata struct { + CDN uint32 `json:"cdn"` + Key string `json:"key"` + Error string `json:"error"` // RELINK_REQUESTED or CONTINUE_WITHOUT_UPLOAD +} + +func (cli *Client) FetchAndProcessTransfer(ctx context.Context, meta *TransferArchiveMetadata) error { + if meta.Error != "" { + switch meta.Error { + case "RELINK_REQUESTED": + return ErrTransferRelinkRequested + case "CONTINUE_WITHOUT_UPLOAD": + return ErrTransferContinueWithoutUpload + default: + return fmt.Errorf("transfer archive error: %s", meta.Error) + } + } + aesKey, hmacKey, err := cli.deriveTransferKeys() + if err != nil { + return fmt.Errorf("failed to derive transfer keys: %w", err) + } + file, err := os.CreateTemp("", "signalmeow-transfer-archive-*") + if err != nil { + return fmt.Errorf("failed to create temporary file: %w", err) + } + defer func() { + _ = file.Close() + _ = os.Remove(file.Name()) + }() + err = downloadTransferArchive(ctx, meta, file) + if err != nil { + return err + } + _, err = file.Seek(0, io.SeekStart) + if err != nil { + return fmt.Errorf("failed to seek to start of file: %w", err) + } + stat, err := file.Stat() + if err != nil { + return fmt.Errorf("failed to stat file: %w", err) + } + ok, err := verifyMACStream(hmacKey, file, stat.Size()) + if err != nil { + return fmt.Errorf("failed to verify MAC: %w", err) + } else if !ok { + return fmt.Errorf("checksum mismatch") + } + _, err = file.Seek(0, io.SeekStart) + if err != nil { + return fmt.Errorf("failed to seek to start of file: %w", err) + } + err = cli.processTransferArchive(ctx, aesKey, hmacKey, file, stat.Size()) + if err != nil { + return err + } + cli.Store.EphemeralBackupKey = nil + err = cli.Store.DeviceStore.PutDevice(ctx, &cli.Store.DeviceData) + if err != nil { + return fmt.Errorf("failed to save device data after clearing ephemeral backup key: %w", err) + } + return nil +} + +func (cli *Client) processTransferArchive(ctx context.Context, aesKey, hmacKey [32]byte, file io.Reader, size int64) error { + decrypter := aesDecryptStream(aesKey, hmacKey, file, size) + bufDecrypted := bufio.NewReader(decrypter) + decompressor, err := gzip.NewReader(bufDecrypted) + if err != nil { + return fmt.Errorf("failed to create gzip reader: %w", err) + } + // There's an unknown amount of zero padding after the gzip stream, + // so tell gzip not to try to read another stream after the first one. + decompressor.Multistream(false) + err = splitChunksStream(decompressor, (&archiveChunkProcessor{cli: cli, ctx: ctx}).processChunk) + if err != nil { + return err + } + err = decompressor.Close() + if err != nil { + return fmt.Errorf("failed to close gzip reader: %w", err) + } + zeroBuf := make([]byte, 256) + var n int + // Validate that the zero padding is really all zeroes. This will also finish the hmac checking. + for { + n, err = bufDecrypted.Read(zeroBuf) + if errors.Is(err, io.EOF) && n == 0 { + break + } else if err != nil { + return fmt.Errorf("failed to read zero buffer: %w", err) + } + for i := 0; i < n; i++ { + if zeroBuf[i] != 0 { + return fmt.Errorf("unexpected data after decompression") + } + } + } + err = decrypter.Close() + if err != nil { + return fmt.Errorf("failed to close decryption reader: %w", err) + } + return nil +} + +type archiveChunkProcessor struct { + cli *Client + ctx context.Context + info *backuppb.BackupInfo +} + +const BackupVersion = 1 + +func (acp *archiveChunkProcessor) processChunk(buf []byte) error { + if acp.ctx.Err() != nil { + return acp.ctx.Err() + } + if acp.info == nil { + acp.info = &backuppb.BackupInfo{} + err := proto.Unmarshal(buf, acp.info) + if err != nil { + return fmt.Errorf("failed to unmarshal backup info: %w", err) + } else if acp.info.GetVersion() != BackupVersion { + return fmt.Errorf("unsupported backup version: %d", acp.info.GetVersion()) + } else if !hmac.Equal(acp.info.GetMediaRootBackupKey(), acp.cli.Store.MediaRootBackupKey[:]) { + return fmt.Errorf("media root backup key mismatch") + } + zerolog.Ctx(acp.ctx).Info().Any("backup_info", acp.info).Msg("Received backup info") + return nil + } + var frame backuppb.Frame + err := proto.Unmarshal(buf, &frame) + if err != nil { + return fmt.Errorf("failed to unmarshal frame: %w", err) + } + return acp.processFrame(&frame) +} + +func (acp *archiveChunkProcessor) processFrame(frame *backuppb.Frame) error { + acp.cli.Log.Info().Any("backup_frame", frame).Msg("Received backup frame") + return nil +} + +func (cli *Client) deriveTransferKeys() (aesKey, hmacKey [32]byte, err error) { + var backupID *libsignalgo.BackupID + var mbk *libsignalgo.MessageBackupKey + if cli.Store.EphemeralBackupKey == nil { + err = ErrNoEphemeralBackupKey + } else if backupID, err = cli.Store.EphemeralBackupKey.DeriveBackupID(cli.Store.ACIServiceID()); err != nil { + err = fmt.Errorf("failed to derive backup ID: %w", err) + } else if mbk, err = libsignalgo.MessageBackupKeyFromBackupKeyAndID(cli.Store.EphemeralBackupKey, backupID); err != nil { + err = fmt.Errorf("failed to derive message backup key: %w", err) + } else if aesKey, err = mbk.GetAESKey(); err != nil { + err = fmt.Errorf("failed to get AES key: %w", err) + } else if hmacKey, err = mbk.GetHMACKey(); err != nil { + err = fmt.Errorf("failed to get HMAC key: %w", err) + } + return +} + +func downloadTransferArchive(ctx context.Context, meta *TransferArchiveMetadata, writeTo io.Writer) error { + resp, err := web.GetAttachment(ctx, getAttachmentPath(0, meta.Key), meta.CDN, nil) + if err != nil { + return fmt.Errorf("failed to download transfer archive: %w", err) + } + if writeToFile, ok := writeTo.(*os.File); ok { + fileInfo, err := writeToFile.Stat() + if err != nil { + return fmt.Errorf("failed to stat destination file: %w", err) + } + if size := fileInfo.Size(); size > 0 { + zerolog.Ctx(ctx).Debug().Int64("skip_count", size).Msg("Transfer archive already exists, skipping bytes") + _, err = io.CopyN(io.Discard, resp.Body, size) + if err != nil { + return fmt.Errorf("failed to skip existing bytes: %w", err) + } + } + } + _, err = io.Copy(writeTo, resp.Body) + if err != nil { + return fmt.Errorf("failed to write transfer archive to disk: %w", err) + } + return nil +} + +func (cli *Client) WaitForTransfer(ctx context.Context) (*TransferArchiveMetadata, error) { + if cli.Store.EphemeralBackupKey == nil { + return nil, ErrNoEphemeralBackupKey + } + timeout := time.Now().Add(transferArchiveFetchTimeout) + + for { + remainingTime := time.Until(timeout) + if remainingTime < 0 { + return nil, fmt.Errorf("timed out") + } + resp, err := cli.tryRequestTransferArchive(ctx, min(remainingTime, 5*time.Minute)) + if resp != nil || err != nil { + return resp, err + } + } +} + +func (cli *Client) tryRequestTransferArchive(ctx context.Context, timeout time.Duration) (respBody *TransferArchiveMetadata, err error) { + reqCtx, cancel := context.WithTimeout(ctx, timeout+15*time.Second) + defer cancel() + path := "/v1/devices/transfer_archive?timeout=" + strconv.Itoa(int(timeout.Seconds())) + username, password := cli.Store.BasicAuthCreds() + opts := &web.HTTPReqOpt{Username: &username, Password: &password} + resp, err := web.SendHTTPRequest(reqCtx, http.MethodGet, path, opts) + defer func() { + if resp != nil && resp.Body != nil { + _ = resp.Body.Close() + } + }() + if err != nil { + return nil, err + } else if resp.StatusCode == http.StatusNoContent { + return nil, nil + } else if resp.StatusCode != http.StatusOK { + return nil, fmt.Errorf("unexpected status code %d", resp.StatusCode) + } else if err = json.NewDecoder(resp.Body).Decode(&respBody); err != nil { + return nil, fmt.Errorf("failed to decode response: %w", err) + } else { + return respBody, nil + } +} diff --git a/pkg/signalmeow/protobuf/backuppb/Backup.pb.go b/pkg/signalmeow/protobuf/backuppb/Backup.pb.go new file mode 100644 index 0000000..1df6d19 --- /dev/null +++ b/pkg/signalmeow/protobuf/backuppb/Backup.pb.go @@ -0,0 +1,11548 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.36.1 +// protoc v3.21.12 +// source: backuppb/Backup.proto + +package backuppb + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" +) + +import _ "embed" + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +type GroupV2AccessLevel int32 + +const ( + GroupV2AccessLevel_UNKNOWN GroupV2AccessLevel = 0 + GroupV2AccessLevel_ANY GroupV2AccessLevel = 1 + GroupV2AccessLevel_MEMBER GroupV2AccessLevel = 2 + GroupV2AccessLevel_ADMINISTRATOR GroupV2AccessLevel = 3 + GroupV2AccessLevel_UNSATISFIABLE GroupV2AccessLevel = 4 +) + +// Enum value maps for GroupV2AccessLevel. +var ( + GroupV2AccessLevel_name = map[int32]string{ + 0: "UNKNOWN", + 1: "ANY", + 2: "MEMBER", + 3: "ADMINISTRATOR", + 4: "UNSATISFIABLE", + } + GroupV2AccessLevel_value = map[string]int32{ + "UNKNOWN": 0, + "ANY": 1, + "MEMBER": 2, + "ADMINISTRATOR": 3, + "UNSATISFIABLE": 4, + } +) + +func (x GroupV2AccessLevel) Enum() *GroupV2AccessLevel { + p := new(GroupV2AccessLevel) + *p = x + return p +} + +func (x GroupV2AccessLevel) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (GroupV2AccessLevel) Descriptor() protoreflect.EnumDescriptor { + return file_backuppb_Backup_proto_enumTypes[0].Descriptor() +} + +func (GroupV2AccessLevel) Type() protoreflect.EnumType { + return &file_backuppb_Backup_proto_enumTypes[0] +} + +func (x GroupV2AccessLevel) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use GroupV2AccessLevel.Descriptor instead. +func (GroupV2AccessLevel) EnumDescriptor() ([]byte, []int) { + return file_backuppb_Backup_proto_rawDescGZIP(), []int{0} +} + +type AccountData_PhoneNumberSharingMode int32 + +const ( + AccountData_UNKNOWN AccountData_PhoneNumberSharingMode = 0 + AccountData_EVERYBODY AccountData_PhoneNumberSharingMode = 1 + AccountData_NOBODY AccountData_PhoneNumberSharingMode = 2 +) + +// Enum value maps for AccountData_PhoneNumberSharingMode. +var ( + AccountData_PhoneNumberSharingMode_name = map[int32]string{ + 0: "UNKNOWN", + 1: "EVERYBODY", + 2: "NOBODY", + } + AccountData_PhoneNumberSharingMode_value = map[string]int32{ + "UNKNOWN": 0, + "EVERYBODY": 1, + "NOBODY": 2, + } +) + +func (x AccountData_PhoneNumberSharingMode) Enum() *AccountData_PhoneNumberSharingMode { + p := new(AccountData_PhoneNumberSharingMode) + *p = x + return p +} + +func (x AccountData_PhoneNumberSharingMode) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (AccountData_PhoneNumberSharingMode) Descriptor() protoreflect.EnumDescriptor { + return file_backuppb_Backup_proto_enumTypes[1].Descriptor() +} + +func (AccountData_PhoneNumberSharingMode) Type() protoreflect.EnumType { + return &file_backuppb_Backup_proto_enumTypes[1] +} + +func (x AccountData_PhoneNumberSharingMode) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use AccountData_PhoneNumberSharingMode.Descriptor instead. +func (AccountData_PhoneNumberSharingMode) EnumDescriptor() ([]byte, []int) { + return file_backuppb_Backup_proto_rawDescGZIP(), []int{2, 0} +} + +type AccountData_UsernameLink_Color int32 + +const ( + AccountData_UsernameLink_UNKNOWN AccountData_UsernameLink_Color = 0 + AccountData_UsernameLink_BLUE AccountData_UsernameLink_Color = 1 + AccountData_UsernameLink_WHITE AccountData_UsernameLink_Color = 2 + AccountData_UsernameLink_GREY AccountData_UsernameLink_Color = 3 + AccountData_UsernameLink_OLIVE AccountData_UsernameLink_Color = 4 + AccountData_UsernameLink_GREEN AccountData_UsernameLink_Color = 5 + AccountData_UsernameLink_ORANGE AccountData_UsernameLink_Color = 6 + AccountData_UsernameLink_PINK AccountData_UsernameLink_Color = 7 + AccountData_UsernameLink_PURPLE AccountData_UsernameLink_Color = 8 +) + +// Enum value maps for AccountData_UsernameLink_Color. +var ( + AccountData_UsernameLink_Color_name = map[int32]string{ + 0: "UNKNOWN", + 1: "BLUE", + 2: "WHITE", + 3: "GREY", + 4: "OLIVE", + 5: "GREEN", + 6: "ORANGE", + 7: "PINK", + 8: "PURPLE", + } + AccountData_UsernameLink_Color_value = map[string]int32{ + "UNKNOWN": 0, + "BLUE": 1, + "WHITE": 2, + "GREY": 3, + "OLIVE": 4, + "GREEN": 5, + "ORANGE": 6, + "PINK": 7, + "PURPLE": 8, + } +) + +func (x AccountData_UsernameLink_Color) Enum() *AccountData_UsernameLink_Color { + p := new(AccountData_UsernameLink_Color) + *p = x + return p +} + +func (x AccountData_UsernameLink_Color) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (AccountData_UsernameLink_Color) Descriptor() protoreflect.EnumDescriptor { + return file_backuppb_Backup_proto_enumTypes[2].Descriptor() +} + +func (AccountData_UsernameLink_Color) Type() protoreflect.EnumType { + return &file_backuppb_Backup_proto_enumTypes[2] +} + +func (x AccountData_UsernameLink_Color) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use AccountData_UsernameLink_Color.Descriptor instead. +func (AccountData_UsernameLink_Color) EnumDescriptor() ([]byte, []int) { + return file_backuppb_Backup_proto_rawDescGZIP(), []int{2, 0, 0} +} + +type Contact_IdentityState int32 + +const ( + Contact_DEFAULT Contact_IdentityState = 0 + Contact_VERIFIED Contact_IdentityState = 1 + Contact_UNVERIFIED Contact_IdentityState = 2 +) + +// Enum value maps for Contact_IdentityState. +var ( + Contact_IdentityState_name = map[int32]string{ + 0: "DEFAULT", + 1: "VERIFIED", + 2: "UNVERIFIED", + } + Contact_IdentityState_value = map[string]int32{ + "DEFAULT": 0, + "VERIFIED": 1, + "UNVERIFIED": 2, + } +) + +func (x Contact_IdentityState) Enum() *Contact_IdentityState { + p := new(Contact_IdentityState) + *p = x + return p +} + +func (x Contact_IdentityState) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (Contact_IdentityState) Descriptor() protoreflect.EnumDescriptor { + return file_backuppb_Backup_proto_enumTypes[3].Descriptor() +} + +func (Contact_IdentityState) Type() protoreflect.EnumType { + return &file_backuppb_Backup_proto_enumTypes[3] +} + +func (x Contact_IdentityState) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use Contact_IdentityState.Descriptor instead. +func (Contact_IdentityState) EnumDescriptor() ([]byte, []int) { + return file_backuppb_Backup_proto_rawDescGZIP(), []int{4, 0} +} + +type Contact_Visibility int32 + +const ( + Contact_VISIBLE Contact_Visibility = 0 + Contact_HIDDEN Contact_Visibility = 1 + Contact_HIDDEN_MESSAGE_REQUEST Contact_Visibility = 2 +) + +// Enum value maps for Contact_Visibility. +var ( + Contact_Visibility_name = map[int32]string{ + 0: "VISIBLE", + 1: "HIDDEN", + 2: "HIDDEN_MESSAGE_REQUEST", + } + Contact_Visibility_value = map[string]int32{ + "VISIBLE": 0, + "HIDDEN": 1, + "HIDDEN_MESSAGE_REQUEST": 2, + } +) + +func (x Contact_Visibility) Enum() *Contact_Visibility { + p := new(Contact_Visibility) + *p = x + return p +} + +func (x Contact_Visibility) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (Contact_Visibility) Descriptor() protoreflect.EnumDescriptor { + return file_backuppb_Backup_proto_enumTypes[4].Descriptor() +} + +func (Contact_Visibility) Type() protoreflect.EnumType { + return &file_backuppb_Backup_proto_enumTypes[4] +} + +func (x Contact_Visibility) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use Contact_Visibility.Descriptor instead. +func (Contact_Visibility) EnumDescriptor() ([]byte, []int) { + return file_backuppb_Backup_proto_rawDescGZIP(), []int{4, 1} +} + +type Group_StorySendMode int32 + +const ( + Group_DEFAULT Group_StorySendMode = 0 + Group_DISABLED Group_StorySendMode = 1 + Group_ENABLED Group_StorySendMode = 2 +) + +// Enum value maps for Group_StorySendMode. +var ( + Group_StorySendMode_name = map[int32]string{ + 0: "DEFAULT", + 1: "DISABLED", + 2: "ENABLED", + } + Group_StorySendMode_value = map[string]int32{ + "DEFAULT": 0, + "DISABLED": 1, + "ENABLED": 2, + } +) + +func (x Group_StorySendMode) Enum() *Group_StorySendMode { + p := new(Group_StorySendMode) + *p = x + return p +} + +func (x Group_StorySendMode) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (Group_StorySendMode) Descriptor() protoreflect.EnumDescriptor { + return file_backuppb_Backup_proto_enumTypes[5].Descriptor() +} + +func (Group_StorySendMode) Type() protoreflect.EnumType { + return &file_backuppb_Backup_proto_enumTypes[5] +} + +func (x Group_StorySendMode) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use Group_StorySendMode.Descriptor instead. +func (Group_StorySendMode) EnumDescriptor() ([]byte, []int) { + return file_backuppb_Backup_proto_rawDescGZIP(), []int{5, 0} +} + +type Group_Member_Role int32 + +const ( + Group_Member_UNKNOWN Group_Member_Role = 0 + Group_Member_DEFAULT Group_Member_Role = 1 + Group_Member_ADMINISTRATOR Group_Member_Role = 2 +) + +// Enum value maps for Group_Member_Role. +var ( + Group_Member_Role_name = map[int32]string{ + 0: "UNKNOWN", + 1: "DEFAULT", + 2: "ADMINISTRATOR", + } + Group_Member_Role_value = map[string]int32{ + "UNKNOWN": 0, + "DEFAULT": 1, + "ADMINISTRATOR": 2, + } +) + +func (x Group_Member_Role) Enum() *Group_Member_Role { + p := new(Group_Member_Role) + *p = x + return p +} + +func (x Group_Member_Role) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (Group_Member_Role) Descriptor() protoreflect.EnumDescriptor { + return file_backuppb_Backup_proto_enumTypes[6].Descriptor() +} + +func (Group_Member_Role) Type() protoreflect.EnumType { + return &file_backuppb_Backup_proto_enumTypes[6] +} + +func (x Group_Member_Role) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use Group_Member_Role.Descriptor instead. +func (Group_Member_Role) EnumDescriptor() ([]byte, []int) { + return file_backuppb_Backup_proto_rawDescGZIP(), []int{5, 2, 0} +} + +type Group_AccessControl_AccessRequired int32 + +const ( + Group_AccessControl_UNKNOWN Group_AccessControl_AccessRequired = 0 + Group_AccessControl_ANY Group_AccessControl_AccessRequired = 1 + Group_AccessControl_MEMBER Group_AccessControl_AccessRequired = 2 + Group_AccessControl_ADMINISTRATOR Group_AccessControl_AccessRequired = 3 + Group_AccessControl_UNSATISFIABLE Group_AccessControl_AccessRequired = 4 +) + +// Enum value maps for Group_AccessControl_AccessRequired. +var ( + Group_AccessControl_AccessRequired_name = map[int32]string{ + 0: "UNKNOWN", + 1: "ANY", + 2: "MEMBER", + 3: "ADMINISTRATOR", + 4: "UNSATISFIABLE", + } + Group_AccessControl_AccessRequired_value = map[string]int32{ + "UNKNOWN": 0, + "ANY": 1, + "MEMBER": 2, + "ADMINISTRATOR": 3, + "UNSATISFIABLE": 4, + } +) + +func (x Group_AccessControl_AccessRequired) Enum() *Group_AccessControl_AccessRequired { + p := new(Group_AccessControl_AccessRequired) + *p = x + return p +} + +func (x Group_AccessControl_AccessRequired) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (Group_AccessControl_AccessRequired) Descriptor() protoreflect.EnumDescriptor { + return file_backuppb_Backup_proto_enumTypes[7].Descriptor() +} + +func (Group_AccessControl_AccessRequired) Type() protoreflect.EnumType { + return &file_backuppb_Backup_proto_enumTypes[7] +} + +func (x Group_AccessControl_AccessRequired) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use Group_AccessControl_AccessRequired.Descriptor instead. +func (Group_AccessControl_AccessRequired) EnumDescriptor() ([]byte, []int) { + return file_backuppb_Backup_proto_rawDescGZIP(), []int{5, 6, 0} +} + +type CallLink_Restrictions int32 + +const ( + CallLink_UNKNOWN CallLink_Restrictions = 0 + CallLink_NONE CallLink_Restrictions = 1 + CallLink_ADMIN_APPROVAL CallLink_Restrictions = 2 +) + +// Enum value maps for CallLink_Restrictions. +var ( + CallLink_Restrictions_name = map[int32]string{ + 0: "UNKNOWN", + 1: "NONE", + 2: "ADMIN_APPROVAL", + } + CallLink_Restrictions_value = map[string]int32{ + "UNKNOWN": 0, + "NONE": 1, + "ADMIN_APPROVAL": 2, + } +) + +func (x CallLink_Restrictions) Enum() *CallLink_Restrictions { + p := new(CallLink_Restrictions) + *p = x + return p +} + +func (x CallLink_Restrictions) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (CallLink_Restrictions) Descriptor() protoreflect.EnumDescriptor { + return file_backuppb_Backup_proto_enumTypes[8].Descriptor() +} + +func (CallLink_Restrictions) Type() protoreflect.EnumType { + return &file_backuppb_Backup_proto_enumTypes[8] +} + +func (x CallLink_Restrictions) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use CallLink_Restrictions.Descriptor instead. +func (CallLink_Restrictions) EnumDescriptor() ([]byte, []int) { + return file_backuppb_Backup_proto_rawDescGZIP(), []int{9, 0} +} + +type AdHocCall_State int32 + +const ( + AdHocCall_UNKNOWN_STATE AdHocCall_State = 0 + AdHocCall_GENERIC AdHocCall_State = 1 +) + +// Enum value maps for AdHocCall_State. +var ( + AdHocCall_State_name = map[int32]string{ + 0: "UNKNOWN_STATE", + 1: "GENERIC", + } + AdHocCall_State_value = map[string]int32{ + "UNKNOWN_STATE": 0, + "GENERIC": 1, + } +) + +func (x AdHocCall_State) Enum() *AdHocCall_State { + p := new(AdHocCall_State) + *p = x + return p +} + +func (x AdHocCall_State) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (AdHocCall_State) Descriptor() protoreflect.EnumDescriptor { + return file_backuppb_Backup_proto_enumTypes[9].Descriptor() +} + +func (AdHocCall_State) Type() protoreflect.EnumType { + return &file_backuppb_Backup_proto_enumTypes[9] +} + +func (x AdHocCall_State) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use AdHocCall_State.Descriptor instead. +func (AdHocCall_State) EnumDescriptor() ([]byte, []int) { + return file_backuppb_Backup_proto_rawDescGZIP(), []int{10, 0} +} + +type DistributionList_PrivacyMode int32 + +const ( + DistributionList_UNKNOWN DistributionList_PrivacyMode = 0 + DistributionList_ONLY_WITH DistributionList_PrivacyMode = 1 + DistributionList_ALL_EXCEPT DistributionList_PrivacyMode = 2 + DistributionList_ALL DistributionList_PrivacyMode = 3 +) + +// Enum value maps for DistributionList_PrivacyMode. +var ( + DistributionList_PrivacyMode_name = map[int32]string{ + 0: "UNKNOWN", + 1: "ONLY_WITH", + 2: "ALL_EXCEPT", + 3: "ALL", + } + DistributionList_PrivacyMode_value = map[string]int32{ + "UNKNOWN": 0, + "ONLY_WITH": 1, + "ALL_EXCEPT": 2, + "ALL": 3, + } +) + +func (x DistributionList_PrivacyMode) Enum() *DistributionList_PrivacyMode { + p := new(DistributionList_PrivacyMode) + *p = x + return p +} + +func (x DistributionList_PrivacyMode) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (DistributionList_PrivacyMode) Descriptor() protoreflect.EnumDescriptor { + return file_backuppb_Backup_proto_enumTypes[10].Descriptor() +} + +func (DistributionList_PrivacyMode) Type() protoreflect.EnumType { + return &file_backuppb_Backup_proto_enumTypes[10] +} + +func (x DistributionList_PrivacyMode) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use DistributionList_PrivacyMode.Descriptor instead. +func (DistributionList_PrivacyMode) EnumDescriptor() ([]byte, []int) { + return file_backuppb_Backup_proto_rawDescGZIP(), []int{12, 0} +} + +type SendStatus_Failed_FailureReason int32 + +const ( + SendStatus_Failed_UNKNOWN SendStatus_Failed_FailureReason = 0 // A valid value -- could indicate a crash or lack of information + SendStatus_Failed_NETWORK SendStatus_Failed_FailureReason = 1 + SendStatus_Failed_IDENTITY_KEY_MISMATCH SendStatus_Failed_FailureReason = 2 +) + +// Enum value maps for SendStatus_Failed_FailureReason. +var ( + SendStatus_Failed_FailureReason_name = map[int32]string{ + 0: "UNKNOWN", + 1: "NETWORK", + 2: "IDENTITY_KEY_MISMATCH", + } + SendStatus_Failed_FailureReason_value = map[string]int32{ + "UNKNOWN": 0, + "NETWORK": 1, + "IDENTITY_KEY_MISMATCH": 2, + } +) + +func (x SendStatus_Failed_FailureReason) Enum() *SendStatus_Failed_FailureReason { + p := new(SendStatus_Failed_FailureReason) + *p = x + return p +} + +func (x SendStatus_Failed_FailureReason) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (SendStatus_Failed_FailureReason) Descriptor() protoreflect.EnumDescriptor { + return file_backuppb_Backup_proto_enumTypes[11].Descriptor() +} + +func (SendStatus_Failed_FailureReason) Type() protoreflect.EnumType { + return &file_backuppb_Backup_proto_enumTypes[11] +} + +func (x SendStatus_Failed_FailureReason) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use SendStatus_Failed_FailureReason.Descriptor instead. +func (SendStatus_Failed_FailureReason) EnumDescriptor() ([]byte, []int) { + return file_backuppb_Backup_proto_rawDescGZIP(), []int{14, 6, 0} +} + +type PaymentNotification_TransactionDetails_FailedTransaction_FailureReason int32 + +const ( + PaymentNotification_TransactionDetails_FailedTransaction_GENERIC PaymentNotification_TransactionDetails_FailedTransaction_FailureReason = 0 + PaymentNotification_TransactionDetails_FailedTransaction_NETWORK PaymentNotification_TransactionDetails_FailedTransaction_FailureReason = 1 + PaymentNotification_TransactionDetails_FailedTransaction_INSUFFICIENT_FUNDS PaymentNotification_TransactionDetails_FailedTransaction_FailureReason = 2 +) + +// Enum value maps for PaymentNotification_TransactionDetails_FailedTransaction_FailureReason. +var ( + PaymentNotification_TransactionDetails_FailedTransaction_FailureReason_name = map[int32]string{ + 0: "GENERIC", + 1: "NETWORK", + 2: "INSUFFICIENT_FUNDS", + } + PaymentNotification_TransactionDetails_FailedTransaction_FailureReason_value = map[string]int32{ + "GENERIC": 0, + "NETWORK": 1, + "INSUFFICIENT_FUNDS": 2, + } +) + +func (x PaymentNotification_TransactionDetails_FailedTransaction_FailureReason) Enum() *PaymentNotification_TransactionDetails_FailedTransaction_FailureReason { + p := new(PaymentNotification_TransactionDetails_FailedTransaction_FailureReason) + *p = x + return p +} + +func (x PaymentNotification_TransactionDetails_FailedTransaction_FailureReason) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (PaymentNotification_TransactionDetails_FailedTransaction_FailureReason) Descriptor() protoreflect.EnumDescriptor { + return file_backuppb_Backup_proto_enumTypes[12].Descriptor() +} + +func (PaymentNotification_TransactionDetails_FailedTransaction_FailureReason) Type() protoreflect.EnumType { + return &file_backuppb_Backup_proto_enumTypes[12] +} + +func (x PaymentNotification_TransactionDetails_FailedTransaction_FailureReason) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use PaymentNotification_TransactionDetails_FailedTransaction_FailureReason.Descriptor instead. +func (PaymentNotification_TransactionDetails_FailedTransaction_FailureReason) EnumDescriptor() ([]byte, []int) { + return file_backuppb_Backup_proto_rawDescGZIP(), []int{19, 0, 1, 0} +} + +type PaymentNotification_TransactionDetails_Transaction_Status int32 + +const ( + PaymentNotification_TransactionDetails_Transaction_INITIAL PaymentNotification_TransactionDetails_Transaction_Status = 0 + PaymentNotification_TransactionDetails_Transaction_SUBMITTED PaymentNotification_TransactionDetails_Transaction_Status = 1 + PaymentNotification_TransactionDetails_Transaction_SUCCESSFUL PaymentNotification_TransactionDetails_Transaction_Status = 2 +) + +// Enum value maps for PaymentNotification_TransactionDetails_Transaction_Status. +var ( + PaymentNotification_TransactionDetails_Transaction_Status_name = map[int32]string{ + 0: "INITIAL", + 1: "SUBMITTED", + 2: "SUCCESSFUL", + } + PaymentNotification_TransactionDetails_Transaction_Status_value = map[string]int32{ + "INITIAL": 0, + "SUBMITTED": 1, + "SUCCESSFUL": 2, + } +) + +func (x PaymentNotification_TransactionDetails_Transaction_Status) Enum() *PaymentNotification_TransactionDetails_Transaction_Status { + p := new(PaymentNotification_TransactionDetails_Transaction_Status) + *p = x + return p +} + +func (x PaymentNotification_TransactionDetails_Transaction_Status) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (PaymentNotification_TransactionDetails_Transaction_Status) Descriptor() protoreflect.EnumDescriptor { + return file_backuppb_Backup_proto_enumTypes[13].Descriptor() +} + +func (PaymentNotification_TransactionDetails_Transaction_Status) Type() protoreflect.EnumType { + return &file_backuppb_Backup_proto_enumTypes[13] +} + +func (x PaymentNotification_TransactionDetails_Transaction_Status) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use PaymentNotification_TransactionDetails_Transaction_Status.Descriptor instead. +func (PaymentNotification_TransactionDetails_Transaction_Status) EnumDescriptor() ([]byte, []int) { + return file_backuppb_Backup_proto_rawDescGZIP(), []int{19, 0, 2, 0} +} + +type GiftBadge_State int32 + +const ( + GiftBadge_UNOPENED GiftBadge_State = 0 + GiftBadge_OPENED GiftBadge_State = 1 + GiftBadge_REDEEMED GiftBadge_State = 2 + GiftBadge_FAILED GiftBadge_State = 3 +) + +// Enum value maps for GiftBadge_State. +var ( + GiftBadge_State_name = map[int32]string{ + 0: "UNOPENED", + 1: "OPENED", + 2: "REDEEMED", + 3: "FAILED", + } + GiftBadge_State_value = map[string]int32{ + "UNOPENED": 0, + "OPENED": 1, + "REDEEMED": 2, + "FAILED": 3, + } +) + +func (x GiftBadge_State) Enum() *GiftBadge_State { + p := new(GiftBadge_State) + *p = x + return p +} + +func (x GiftBadge_State) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (GiftBadge_State) Descriptor() protoreflect.EnumDescriptor { + return file_backuppb_Backup_proto_enumTypes[14].Descriptor() +} + +func (GiftBadge_State) Type() protoreflect.EnumType { + return &file_backuppb_Backup_proto_enumTypes[14] +} + +func (x GiftBadge_State) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use GiftBadge_State.Descriptor instead. +func (GiftBadge_State) EnumDescriptor() ([]byte, []int) { + return file_backuppb_Backup_proto_rawDescGZIP(), []int{20, 0} +} + +type ContactAttachment_Phone_Type int32 + +const ( + ContactAttachment_Phone_UNKNOWN ContactAttachment_Phone_Type = 0 + ContactAttachment_Phone_HOME ContactAttachment_Phone_Type = 1 + ContactAttachment_Phone_MOBILE ContactAttachment_Phone_Type = 2 + ContactAttachment_Phone_WORK ContactAttachment_Phone_Type = 3 + ContactAttachment_Phone_CUSTOM ContactAttachment_Phone_Type = 4 +) + +// Enum value maps for ContactAttachment_Phone_Type. +var ( + ContactAttachment_Phone_Type_name = map[int32]string{ + 0: "UNKNOWN", + 1: "HOME", + 2: "MOBILE", + 3: "WORK", + 4: "CUSTOM", + } + ContactAttachment_Phone_Type_value = map[string]int32{ + "UNKNOWN": 0, + "HOME": 1, + "MOBILE": 2, + "WORK": 3, + "CUSTOM": 4, + } +) + +func (x ContactAttachment_Phone_Type) Enum() *ContactAttachment_Phone_Type { + p := new(ContactAttachment_Phone_Type) + *p = x + return p +} + +func (x ContactAttachment_Phone_Type) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (ContactAttachment_Phone_Type) Descriptor() protoreflect.EnumDescriptor { + return file_backuppb_Backup_proto_enumTypes[15].Descriptor() +} + +func (ContactAttachment_Phone_Type) Type() protoreflect.EnumType { + return &file_backuppb_Backup_proto_enumTypes[15] +} + +func (x ContactAttachment_Phone_Type) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use ContactAttachment_Phone_Type.Descriptor instead. +func (ContactAttachment_Phone_Type) EnumDescriptor() ([]byte, []int) { + return file_backuppb_Backup_proto_rawDescGZIP(), []int{22, 1, 0} +} + +type ContactAttachment_Email_Type int32 + +const ( + ContactAttachment_Email_UNKNOWN ContactAttachment_Email_Type = 0 + ContactAttachment_Email_HOME ContactAttachment_Email_Type = 1 + ContactAttachment_Email_MOBILE ContactAttachment_Email_Type = 2 + ContactAttachment_Email_WORK ContactAttachment_Email_Type = 3 + ContactAttachment_Email_CUSTOM ContactAttachment_Email_Type = 4 +) + +// Enum value maps for ContactAttachment_Email_Type. +var ( + ContactAttachment_Email_Type_name = map[int32]string{ + 0: "UNKNOWN", + 1: "HOME", + 2: "MOBILE", + 3: "WORK", + 4: "CUSTOM", + } + ContactAttachment_Email_Type_value = map[string]int32{ + "UNKNOWN": 0, + "HOME": 1, + "MOBILE": 2, + "WORK": 3, + "CUSTOM": 4, + } +) + +func (x ContactAttachment_Email_Type) Enum() *ContactAttachment_Email_Type { + p := new(ContactAttachment_Email_Type) + *p = x + return p +} + +func (x ContactAttachment_Email_Type) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (ContactAttachment_Email_Type) Descriptor() protoreflect.EnumDescriptor { + return file_backuppb_Backup_proto_enumTypes[16].Descriptor() +} + +func (ContactAttachment_Email_Type) Type() protoreflect.EnumType { + return &file_backuppb_Backup_proto_enumTypes[16] +} + +func (x ContactAttachment_Email_Type) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use ContactAttachment_Email_Type.Descriptor instead. +func (ContactAttachment_Email_Type) EnumDescriptor() ([]byte, []int) { + return file_backuppb_Backup_proto_rawDescGZIP(), []int{22, 2, 0} +} + +type ContactAttachment_PostalAddress_Type int32 + +const ( + ContactAttachment_PostalAddress_UNKNOWN ContactAttachment_PostalAddress_Type = 0 + ContactAttachment_PostalAddress_HOME ContactAttachment_PostalAddress_Type = 1 + ContactAttachment_PostalAddress_WORK ContactAttachment_PostalAddress_Type = 2 + ContactAttachment_PostalAddress_CUSTOM ContactAttachment_PostalAddress_Type = 3 +) + +// Enum value maps for ContactAttachment_PostalAddress_Type. +var ( + ContactAttachment_PostalAddress_Type_name = map[int32]string{ + 0: "UNKNOWN", + 1: "HOME", + 2: "WORK", + 3: "CUSTOM", + } + ContactAttachment_PostalAddress_Type_value = map[string]int32{ + "UNKNOWN": 0, + "HOME": 1, + "WORK": 2, + "CUSTOM": 3, + } +) + +func (x ContactAttachment_PostalAddress_Type) Enum() *ContactAttachment_PostalAddress_Type { + p := new(ContactAttachment_PostalAddress_Type) + *p = x + return p +} + +func (x ContactAttachment_PostalAddress_Type) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (ContactAttachment_PostalAddress_Type) Descriptor() protoreflect.EnumDescriptor { + return file_backuppb_Backup_proto_enumTypes[17].Descriptor() +} + +func (ContactAttachment_PostalAddress_Type) Type() protoreflect.EnumType { + return &file_backuppb_Backup_proto_enumTypes[17] +} + +func (x ContactAttachment_PostalAddress_Type) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use ContactAttachment_PostalAddress_Type.Descriptor instead. +func (ContactAttachment_PostalAddress_Type) EnumDescriptor() ([]byte, []int) { + return file_backuppb_Backup_proto_rawDescGZIP(), []int{22, 3, 0} +} + +// Similar to SignalService.AttachmentPointer.Flags, +// but explicitly mutually exclusive. Note the different raw values +// (non-zero starting values are not supported in proto3.) +type MessageAttachment_Flag int32 + +const ( + MessageAttachment_NONE MessageAttachment_Flag = 0 + MessageAttachment_VOICE_MESSAGE MessageAttachment_Flag = 1 + MessageAttachment_BORDERLESS MessageAttachment_Flag = 2 + MessageAttachment_GIF MessageAttachment_Flag = 3 +) + +// Enum value maps for MessageAttachment_Flag. +var ( + MessageAttachment_Flag_name = map[int32]string{ + 0: "NONE", + 1: "VOICE_MESSAGE", + 2: "BORDERLESS", + 3: "GIF", + } + MessageAttachment_Flag_value = map[string]int32{ + "NONE": 0, + "VOICE_MESSAGE": 1, + "BORDERLESS": 2, + "GIF": 3, + } +) + +func (x MessageAttachment_Flag) Enum() *MessageAttachment_Flag { + p := new(MessageAttachment_Flag) + *p = x + return p +} + +func (x MessageAttachment_Flag) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (MessageAttachment_Flag) Descriptor() protoreflect.EnumDescriptor { + return file_backuppb_Backup_proto_enumTypes[18].Descriptor() +} + +func (MessageAttachment_Flag) Type() protoreflect.EnumType { + return &file_backuppb_Backup_proto_enumTypes[18] +} + +func (x MessageAttachment_Flag) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use MessageAttachment_Flag.Descriptor instead. +func (MessageAttachment_Flag) EnumDescriptor() ([]byte, []int) { + return file_backuppb_Backup_proto_rawDescGZIP(), []int{27, 0} +} + +type Quote_Type int32 + +const ( + Quote_UNKNOWN Quote_Type = 0 + Quote_NORMAL Quote_Type = 1 + Quote_GIFT_BADGE Quote_Type = 2 + Quote_VIEW_ONCE Quote_Type = 3 +) + +// Enum value maps for Quote_Type. +var ( + Quote_Type_name = map[int32]string{ + 0: "UNKNOWN", + 1: "NORMAL", + 2: "GIFT_BADGE", + 3: "VIEW_ONCE", + } + Quote_Type_value = map[string]int32{ + "UNKNOWN": 0, + "NORMAL": 1, + "GIFT_BADGE": 2, + "VIEW_ONCE": 3, + } +) + +func (x Quote_Type) Enum() *Quote_Type { + p := new(Quote_Type) + *p = x + return p +} + +func (x Quote_Type) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (Quote_Type) Descriptor() protoreflect.EnumDescriptor { + return file_backuppb_Backup_proto_enumTypes[19].Descriptor() +} + +func (Quote_Type) Type() protoreflect.EnumType { + return &file_backuppb_Backup_proto_enumTypes[19] +} + +func (x Quote_Type) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use Quote_Type.Descriptor instead. +func (Quote_Type) EnumDescriptor() ([]byte, []int) { + return file_backuppb_Backup_proto_rawDescGZIP(), []int{29, 0} +} + +type BodyRange_Style int32 + +const ( + BodyRange_NONE BodyRange_Style = 0 + BodyRange_BOLD BodyRange_Style = 1 + BodyRange_ITALIC BodyRange_Style = 2 + BodyRange_SPOILER BodyRange_Style = 3 + BodyRange_STRIKETHROUGH BodyRange_Style = 4 + BodyRange_MONOSPACE BodyRange_Style = 5 +) + +// Enum value maps for BodyRange_Style. +var ( + BodyRange_Style_name = map[int32]string{ + 0: "NONE", + 1: "BOLD", + 2: "ITALIC", + 3: "SPOILER", + 4: "STRIKETHROUGH", + 5: "MONOSPACE", + } + BodyRange_Style_value = map[string]int32{ + "NONE": 0, + "BOLD": 1, + "ITALIC": 2, + "SPOILER": 3, + "STRIKETHROUGH": 4, + "MONOSPACE": 5, + } +) + +func (x BodyRange_Style) Enum() *BodyRange_Style { + p := new(BodyRange_Style) + *p = x + return p +} + +func (x BodyRange_Style) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (BodyRange_Style) Descriptor() protoreflect.EnumDescriptor { + return file_backuppb_Backup_proto_enumTypes[20].Descriptor() +} + +func (BodyRange_Style) Type() protoreflect.EnumType { + return &file_backuppb_Backup_proto_enumTypes[20] +} + +func (x BodyRange_Style) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use BodyRange_Style.Descriptor instead. +func (BodyRange_Style) EnumDescriptor() ([]byte, []int) { + return file_backuppb_Backup_proto_rawDescGZIP(), []int{30, 0} +} + +type IndividualCall_Type int32 + +const ( + IndividualCall_UNKNOWN_TYPE IndividualCall_Type = 0 + IndividualCall_AUDIO_CALL IndividualCall_Type = 1 + IndividualCall_VIDEO_CALL IndividualCall_Type = 2 +) + +// Enum value maps for IndividualCall_Type. +var ( + IndividualCall_Type_name = map[int32]string{ + 0: "UNKNOWN_TYPE", + 1: "AUDIO_CALL", + 2: "VIDEO_CALL", + } + IndividualCall_Type_value = map[string]int32{ + "UNKNOWN_TYPE": 0, + "AUDIO_CALL": 1, + "VIDEO_CALL": 2, + } +) + +func (x IndividualCall_Type) Enum() *IndividualCall_Type { + p := new(IndividualCall_Type) + *p = x + return p +} + +func (x IndividualCall_Type) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (IndividualCall_Type) Descriptor() protoreflect.EnumDescriptor { + return file_backuppb_Backup_proto_enumTypes[21].Descriptor() +} + +func (IndividualCall_Type) Type() protoreflect.EnumType { + return &file_backuppb_Backup_proto_enumTypes[21] +} + +func (x IndividualCall_Type) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use IndividualCall_Type.Descriptor instead. +func (IndividualCall_Type) EnumDescriptor() ([]byte, []int) { + return file_backuppb_Backup_proto_rawDescGZIP(), []int{33, 0} +} + +type IndividualCall_Direction int32 + +const ( + IndividualCall_UNKNOWN_DIRECTION IndividualCall_Direction = 0 + IndividualCall_INCOMING IndividualCall_Direction = 1 + IndividualCall_OUTGOING IndividualCall_Direction = 2 +) + +// Enum value maps for IndividualCall_Direction. +var ( + IndividualCall_Direction_name = map[int32]string{ + 0: "UNKNOWN_DIRECTION", + 1: "INCOMING", + 2: "OUTGOING", + } + IndividualCall_Direction_value = map[string]int32{ + "UNKNOWN_DIRECTION": 0, + "INCOMING": 1, + "OUTGOING": 2, + } +) + +func (x IndividualCall_Direction) Enum() *IndividualCall_Direction { + p := new(IndividualCall_Direction) + *p = x + return p +} + +func (x IndividualCall_Direction) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (IndividualCall_Direction) Descriptor() protoreflect.EnumDescriptor { + return file_backuppb_Backup_proto_enumTypes[22].Descriptor() +} + +func (IndividualCall_Direction) Type() protoreflect.EnumType { + return &file_backuppb_Backup_proto_enumTypes[22] +} + +func (x IndividualCall_Direction) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use IndividualCall_Direction.Descriptor instead. +func (IndividualCall_Direction) EnumDescriptor() ([]byte, []int) { + return file_backuppb_Backup_proto_rawDescGZIP(), []int{33, 1} +} + +type IndividualCall_State int32 + +const ( + IndividualCall_UNKNOWN_STATE IndividualCall_State = 0 + IndividualCall_ACCEPTED IndividualCall_State = 1 + IndividualCall_NOT_ACCEPTED IndividualCall_State = 2 + // An incoming call that is no longer ongoing, which we neither accepted + // not actively declined. For example, it expired, was canceled by the + // sender, or was rejected due to being in another call. + IndividualCall_MISSED IndividualCall_State = 3 + // We auto-declined an incoming call due to a notification profile. + IndividualCall_MISSED_NOTIFICATION_PROFILE IndividualCall_State = 4 +) + +// Enum value maps for IndividualCall_State. +var ( + IndividualCall_State_name = map[int32]string{ + 0: "UNKNOWN_STATE", + 1: "ACCEPTED", + 2: "NOT_ACCEPTED", + 3: "MISSED", + 4: "MISSED_NOTIFICATION_PROFILE", + } + IndividualCall_State_value = map[string]int32{ + "UNKNOWN_STATE": 0, + "ACCEPTED": 1, + "NOT_ACCEPTED": 2, + "MISSED": 3, + "MISSED_NOTIFICATION_PROFILE": 4, + } +) + +func (x IndividualCall_State) Enum() *IndividualCall_State { + p := new(IndividualCall_State) + *p = x + return p +} + +func (x IndividualCall_State) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (IndividualCall_State) Descriptor() protoreflect.EnumDescriptor { + return file_backuppb_Backup_proto_enumTypes[23].Descriptor() +} + +func (IndividualCall_State) Type() protoreflect.EnumType { + return &file_backuppb_Backup_proto_enumTypes[23] +} + +func (x IndividualCall_State) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use IndividualCall_State.Descriptor instead. +func (IndividualCall_State) EnumDescriptor() ([]byte, []int) { + return file_backuppb_Backup_proto_rawDescGZIP(), []int{33, 2} +} + +type GroupCall_State int32 + +const ( + GroupCall_UNKNOWN_STATE GroupCall_State = 0 + // A group call was started without ringing. + GroupCall_GENERIC GroupCall_State = 1 + // We joined a group call that was started without ringing. + GroupCall_JOINED GroupCall_State = 2 + // An incoming group call is actively ringing. + GroupCall_RINGING GroupCall_State = 3 + // We accepted an incoming group ring. + GroupCall_ACCEPTED GroupCall_State = 4 + // We declined an incoming group ring. + GroupCall_DECLINED GroupCall_State = 5 + // We missed an incoming group ring, for example because it expired. + GroupCall_MISSED GroupCall_State = 6 + // We auto-declined an incoming group ring due to a notification profile. + GroupCall_MISSED_NOTIFICATION_PROFILE GroupCall_State = 7 + // An outgoing ring was started. We don't track any state for outgoing rings + // beyond that they started. + GroupCall_OUTGOING_RING GroupCall_State = 8 +) + +// Enum value maps for GroupCall_State. +var ( + GroupCall_State_name = map[int32]string{ + 0: "UNKNOWN_STATE", + 1: "GENERIC", + 2: "JOINED", + 3: "RINGING", + 4: "ACCEPTED", + 5: "DECLINED", + 6: "MISSED", + 7: "MISSED_NOTIFICATION_PROFILE", + 8: "OUTGOING_RING", + } + GroupCall_State_value = map[string]int32{ + "UNKNOWN_STATE": 0, + "GENERIC": 1, + "JOINED": 2, + "RINGING": 3, + "ACCEPTED": 4, + "DECLINED": 5, + "MISSED": 6, + "MISSED_NOTIFICATION_PROFILE": 7, + "OUTGOING_RING": 8, + } +) + +func (x GroupCall_State) Enum() *GroupCall_State { + p := new(GroupCall_State) + *p = x + return p +} + +func (x GroupCall_State) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (GroupCall_State) Descriptor() protoreflect.EnumDescriptor { + return file_backuppb_Backup_proto_enumTypes[24].Descriptor() +} + +func (GroupCall_State) Type() protoreflect.EnumType { + return &file_backuppb_Backup_proto_enumTypes[24] +} + +func (x GroupCall_State) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use GroupCall_State.Descriptor instead. +func (GroupCall_State) EnumDescriptor() ([]byte, []int) { + return file_backuppb_Backup_proto_rawDescGZIP(), []int{34, 0} +} + +type SimpleChatUpdate_Type int32 + +const ( + SimpleChatUpdate_UNKNOWN SimpleChatUpdate_Type = 0 + SimpleChatUpdate_JOINED_SIGNAL SimpleChatUpdate_Type = 1 + SimpleChatUpdate_IDENTITY_UPDATE SimpleChatUpdate_Type = 2 + SimpleChatUpdate_IDENTITY_VERIFIED SimpleChatUpdate_Type = 3 + SimpleChatUpdate_IDENTITY_DEFAULT SimpleChatUpdate_Type = 4 // marking as unverified + SimpleChatUpdate_CHANGE_NUMBER SimpleChatUpdate_Type = 5 + SimpleChatUpdate_RELEASE_CHANNEL_DONATION_REQUEST SimpleChatUpdate_Type = 6 + SimpleChatUpdate_END_SESSION SimpleChatUpdate_Type = 7 + SimpleChatUpdate_CHAT_SESSION_REFRESH SimpleChatUpdate_Type = 8 + SimpleChatUpdate_BAD_DECRYPT SimpleChatUpdate_Type = 9 + SimpleChatUpdate_PAYMENTS_ACTIVATED SimpleChatUpdate_Type = 10 + SimpleChatUpdate_PAYMENT_ACTIVATION_REQUEST SimpleChatUpdate_Type = 11 + SimpleChatUpdate_UNSUPPORTED_PROTOCOL_MESSAGE SimpleChatUpdate_Type = 12 + SimpleChatUpdate_REPORTED_SPAM SimpleChatUpdate_Type = 13 + SimpleChatUpdate_BLOCKED SimpleChatUpdate_Type = 14 + SimpleChatUpdate_UNBLOCKED SimpleChatUpdate_Type = 15 + SimpleChatUpdate_MESSAGE_REQUEST_ACCEPTED SimpleChatUpdate_Type = 16 +) + +// Enum value maps for SimpleChatUpdate_Type. +var ( + SimpleChatUpdate_Type_name = map[int32]string{ + 0: "UNKNOWN", + 1: "JOINED_SIGNAL", + 2: "IDENTITY_UPDATE", + 3: "IDENTITY_VERIFIED", + 4: "IDENTITY_DEFAULT", + 5: "CHANGE_NUMBER", + 6: "RELEASE_CHANNEL_DONATION_REQUEST", + 7: "END_SESSION", + 8: "CHAT_SESSION_REFRESH", + 9: "BAD_DECRYPT", + 10: "PAYMENTS_ACTIVATED", + 11: "PAYMENT_ACTIVATION_REQUEST", + 12: "UNSUPPORTED_PROTOCOL_MESSAGE", + 13: "REPORTED_SPAM", + 14: "BLOCKED", + 15: "UNBLOCKED", + 16: "MESSAGE_REQUEST_ACCEPTED", + } + SimpleChatUpdate_Type_value = map[string]int32{ + "UNKNOWN": 0, + "JOINED_SIGNAL": 1, + "IDENTITY_UPDATE": 2, + "IDENTITY_VERIFIED": 3, + "IDENTITY_DEFAULT": 4, + "CHANGE_NUMBER": 5, + "RELEASE_CHANNEL_DONATION_REQUEST": 6, + "END_SESSION": 7, + "CHAT_SESSION_REFRESH": 8, + "BAD_DECRYPT": 9, + "PAYMENTS_ACTIVATED": 10, + "PAYMENT_ACTIVATION_REQUEST": 11, + "UNSUPPORTED_PROTOCOL_MESSAGE": 12, + "REPORTED_SPAM": 13, + "BLOCKED": 14, + "UNBLOCKED": 15, + "MESSAGE_REQUEST_ACCEPTED": 16, + } +) + +func (x SimpleChatUpdate_Type) Enum() *SimpleChatUpdate_Type { + p := new(SimpleChatUpdate_Type) + *p = x + return p +} + +func (x SimpleChatUpdate_Type) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (SimpleChatUpdate_Type) Descriptor() protoreflect.EnumDescriptor { + return file_backuppb_Backup_proto_enumTypes[25].Descriptor() +} + +func (SimpleChatUpdate_Type) Type() protoreflect.EnumType { + return &file_backuppb_Backup_proto_enumTypes[25] +} + +func (x SimpleChatUpdate_Type) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use SimpleChatUpdate_Type.Descriptor instead. +func (SimpleChatUpdate_Type) EnumDescriptor() ([]byte, []int) { + return file_backuppb_Backup_proto_rawDescGZIP(), []int{35, 0} +} + +type ChatStyle_WallpaperPreset int32 + +const ( + ChatStyle_UNKNOWN_WALLPAPER_PRESET ChatStyle_WallpaperPreset = 0 + ChatStyle_SOLID_BLUSH ChatStyle_WallpaperPreset = 1 + ChatStyle_SOLID_COPPER ChatStyle_WallpaperPreset = 2 + ChatStyle_SOLID_DUST ChatStyle_WallpaperPreset = 3 + ChatStyle_SOLID_CELADON ChatStyle_WallpaperPreset = 4 + ChatStyle_SOLID_RAINFOREST ChatStyle_WallpaperPreset = 5 + ChatStyle_SOLID_PACIFIC ChatStyle_WallpaperPreset = 6 + ChatStyle_SOLID_FROST ChatStyle_WallpaperPreset = 7 + ChatStyle_SOLID_NAVY ChatStyle_WallpaperPreset = 8 + ChatStyle_SOLID_LILAC ChatStyle_WallpaperPreset = 9 + ChatStyle_SOLID_PINK ChatStyle_WallpaperPreset = 10 + ChatStyle_SOLID_EGGPLANT ChatStyle_WallpaperPreset = 11 + ChatStyle_SOLID_SILVER ChatStyle_WallpaperPreset = 12 + ChatStyle_GRADIENT_SUNSET ChatStyle_WallpaperPreset = 13 + ChatStyle_GRADIENT_NOIR ChatStyle_WallpaperPreset = 14 + ChatStyle_GRADIENT_HEATMAP ChatStyle_WallpaperPreset = 15 + ChatStyle_GRADIENT_AQUA ChatStyle_WallpaperPreset = 16 + ChatStyle_GRADIENT_IRIDESCENT ChatStyle_WallpaperPreset = 17 + ChatStyle_GRADIENT_MONSTERA ChatStyle_WallpaperPreset = 18 + ChatStyle_GRADIENT_BLISS ChatStyle_WallpaperPreset = 19 + ChatStyle_GRADIENT_SKY ChatStyle_WallpaperPreset = 20 + ChatStyle_GRADIENT_PEACH ChatStyle_WallpaperPreset = 21 +) + +// Enum value maps for ChatStyle_WallpaperPreset. +var ( + ChatStyle_WallpaperPreset_name = map[int32]string{ + 0: "UNKNOWN_WALLPAPER_PRESET", + 1: "SOLID_BLUSH", + 2: "SOLID_COPPER", + 3: "SOLID_DUST", + 4: "SOLID_CELADON", + 5: "SOLID_RAINFOREST", + 6: "SOLID_PACIFIC", + 7: "SOLID_FROST", + 8: "SOLID_NAVY", + 9: "SOLID_LILAC", + 10: "SOLID_PINK", + 11: "SOLID_EGGPLANT", + 12: "SOLID_SILVER", + 13: "GRADIENT_SUNSET", + 14: "GRADIENT_NOIR", + 15: "GRADIENT_HEATMAP", + 16: "GRADIENT_AQUA", + 17: "GRADIENT_IRIDESCENT", + 18: "GRADIENT_MONSTERA", + 19: "GRADIENT_BLISS", + 20: "GRADIENT_SKY", + 21: "GRADIENT_PEACH", + } + ChatStyle_WallpaperPreset_value = map[string]int32{ + "UNKNOWN_WALLPAPER_PRESET": 0, + "SOLID_BLUSH": 1, + "SOLID_COPPER": 2, + "SOLID_DUST": 3, + "SOLID_CELADON": 4, + "SOLID_RAINFOREST": 5, + "SOLID_PACIFIC": 6, + "SOLID_FROST": 7, + "SOLID_NAVY": 8, + "SOLID_LILAC": 9, + "SOLID_PINK": 10, + "SOLID_EGGPLANT": 11, + "SOLID_SILVER": 12, + "GRADIENT_SUNSET": 13, + "GRADIENT_NOIR": 14, + "GRADIENT_HEATMAP": 15, + "GRADIENT_AQUA": 16, + "GRADIENT_IRIDESCENT": 17, + "GRADIENT_MONSTERA": 18, + "GRADIENT_BLISS": 19, + "GRADIENT_SKY": 20, + "GRADIENT_PEACH": 21, + } +) + +func (x ChatStyle_WallpaperPreset) Enum() *ChatStyle_WallpaperPreset { + p := new(ChatStyle_WallpaperPreset) + *p = x + return p +} + +func (x ChatStyle_WallpaperPreset) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (ChatStyle_WallpaperPreset) Descriptor() protoreflect.EnumDescriptor { + return file_backuppb_Backup_proto_enumTypes[26].Descriptor() +} + +func (ChatStyle_WallpaperPreset) Type() protoreflect.EnumType { + return &file_backuppb_Backup_proto_enumTypes[26] +} + +func (x ChatStyle_WallpaperPreset) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use ChatStyle_WallpaperPreset.Descriptor instead. +func (ChatStyle_WallpaperPreset) EnumDescriptor() ([]byte, []int) { + return file_backuppb_Backup_proto_rawDescGZIP(), []int{77, 0} +} + +type ChatStyle_BubbleColorPreset int32 + +const ( + ChatStyle_UNKNOWN_BUBBLE_COLOR_PRESET ChatStyle_BubbleColorPreset = 0 + ChatStyle_SOLID_ULTRAMARINE ChatStyle_BubbleColorPreset = 1 + ChatStyle_SOLID_CRIMSON ChatStyle_BubbleColorPreset = 2 + ChatStyle_SOLID_VERMILION ChatStyle_BubbleColorPreset = 3 + ChatStyle_SOLID_BURLAP ChatStyle_BubbleColorPreset = 4 + ChatStyle_SOLID_FOREST ChatStyle_BubbleColorPreset = 5 + ChatStyle_SOLID_WINTERGREEN ChatStyle_BubbleColorPreset = 6 + ChatStyle_SOLID_TEAL ChatStyle_BubbleColorPreset = 7 + ChatStyle_SOLID_BLUE ChatStyle_BubbleColorPreset = 8 + ChatStyle_SOLID_INDIGO ChatStyle_BubbleColorPreset = 9 + ChatStyle_SOLID_VIOLET ChatStyle_BubbleColorPreset = 10 + ChatStyle_SOLID_PLUM ChatStyle_BubbleColorPreset = 11 + ChatStyle_SOLID_TAUPE ChatStyle_BubbleColorPreset = 12 + ChatStyle_SOLID_STEEL ChatStyle_BubbleColorPreset = 13 + ChatStyle_GRADIENT_EMBER ChatStyle_BubbleColorPreset = 14 + ChatStyle_GRADIENT_MIDNIGHT ChatStyle_BubbleColorPreset = 15 + ChatStyle_GRADIENT_INFRARED ChatStyle_BubbleColorPreset = 16 + ChatStyle_GRADIENT_LAGOON ChatStyle_BubbleColorPreset = 17 + ChatStyle_GRADIENT_FLUORESCENT ChatStyle_BubbleColorPreset = 18 + ChatStyle_GRADIENT_BASIL ChatStyle_BubbleColorPreset = 19 + ChatStyle_GRADIENT_SUBLIME ChatStyle_BubbleColorPreset = 20 + ChatStyle_GRADIENT_SEA ChatStyle_BubbleColorPreset = 21 + ChatStyle_GRADIENT_TANGERINE ChatStyle_BubbleColorPreset = 22 +) + +// Enum value maps for ChatStyle_BubbleColorPreset. +var ( + ChatStyle_BubbleColorPreset_name = map[int32]string{ + 0: "UNKNOWN_BUBBLE_COLOR_PRESET", + 1: "SOLID_ULTRAMARINE", + 2: "SOLID_CRIMSON", + 3: "SOLID_VERMILION", + 4: "SOLID_BURLAP", + 5: "SOLID_FOREST", + 6: "SOLID_WINTERGREEN", + 7: "SOLID_TEAL", + 8: "SOLID_BLUE", + 9: "SOLID_INDIGO", + 10: "SOLID_VIOLET", + 11: "SOLID_PLUM", + 12: "SOLID_TAUPE", + 13: "SOLID_STEEL", + 14: "GRADIENT_EMBER", + 15: "GRADIENT_MIDNIGHT", + 16: "GRADIENT_INFRARED", + 17: "GRADIENT_LAGOON", + 18: "GRADIENT_FLUORESCENT", + 19: "GRADIENT_BASIL", + 20: "GRADIENT_SUBLIME", + 21: "GRADIENT_SEA", + 22: "GRADIENT_TANGERINE", + } + ChatStyle_BubbleColorPreset_value = map[string]int32{ + "UNKNOWN_BUBBLE_COLOR_PRESET": 0, + "SOLID_ULTRAMARINE": 1, + "SOLID_CRIMSON": 2, + "SOLID_VERMILION": 3, + "SOLID_BURLAP": 4, + "SOLID_FOREST": 5, + "SOLID_WINTERGREEN": 6, + "SOLID_TEAL": 7, + "SOLID_BLUE": 8, + "SOLID_INDIGO": 9, + "SOLID_VIOLET": 10, + "SOLID_PLUM": 11, + "SOLID_TAUPE": 12, + "SOLID_STEEL": 13, + "GRADIENT_EMBER": 14, + "GRADIENT_MIDNIGHT": 15, + "GRADIENT_INFRARED": 16, + "GRADIENT_LAGOON": 17, + "GRADIENT_FLUORESCENT": 18, + "GRADIENT_BASIL": 19, + "GRADIENT_SUBLIME": 20, + "GRADIENT_SEA": 21, + "GRADIENT_TANGERINE": 22, + } +) + +func (x ChatStyle_BubbleColorPreset) Enum() *ChatStyle_BubbleColorPreset { + p := new(ChatStyle_BubbleColorPreset) + *p = x + return p +} + +func (x ChatStyle_BubbleColorPreset) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (ChatStyle_BubbleColorPreset) Descriptor() protoreflect.EnumDescriptor { + return file_backuppb_Backup_proto_enumTypes[27].Descriptor() +} + +func (ChatStyle_BubbleColorPreset) Type() protoreflect.EnumType { + return &file_backuppb_Backup_proto_enumTypes[27] +} + +func (x ChatStyle_BubbleColorPreset) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use ChatStyle_BubbleColorPreset.Descriptor instead. +func (ChatStyle_BubbleColorPreset) EnumDescriptor() ([]byte, []int) { + return file_backuppb_Backup_proto_rawDescGZIP(), []int{77, 1} +} + +type NotificationProfile_DayOfWeek int32 + +const ( + NotificationProfile_UNKNOWN NotificationProfile_DayOfWeek = 0 + NotificationProfile_MONDAY NotificationProfile_DayOfWeek = 1 + NotificationProfile_TUESDAY NotificationProfile_DayOfWeek = 2 + NotificationProfile_WEDNESDAY NotificationProfile_DayOfWeek = 3 + NotificationProfile_THURSDAY NotificationProfile_DayOfWeek = 4 + NotificationProfile_FRIDAY NotificationProfile_DayOfWeek = 5 + NotificationProfile_SATURDAY NotificationProfile_DayOfWeek = 6 + NotificationProfile_SUNDAY NotificationProfile_DayOfWeek = 7 +) + +// Enum value maps for NotificationProfile_DayOfWeek. +var ( + NotificationProfile_DayOfWeek_name = map[int32]string{ + 0: "UNKNOWN", + 1: "MONDAY", + 2: "TUESDAY", + 3: "WEDNESDAY", + 4: "THURSDAY", + 5: "FRIDAY", + 6: "SATURDAY", + 7: "SUNDAY", + } + NotificationProfile_DayOfWeek_value = map[string]int32{ + "UNKNOWN": 0, + "MONDAY": 1, + "TUESDAY": 2, + "WEDNESDAY": 3, + "THURSDAY": 4, + "FRIDAY": 5, + "SATURDAY": 6, + "SUNDAY": 7, + } +) + +func (x NotificationProfile_DayOfWeek) Enum() *NotificationProfile_DayOfWeek { + p := new(NotificationProfile_DayOfWeek) + *p = x + return p +} + +func (x NotificationProfile_DayOfWeek) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (NotificationProfile_DayOfWeek) Descriptor() protoreflect.EnumDescriptor { + return file_backuppb_Backup_proto_enumTypes[28].Descriptor() +} + +func (NotificationProfile_DayOfWeek) Type() protoreflect.EnumType { + return &file_backuppb_Backup_proto_enumTypes[28] +} + +func (x NotificationProfile_DayOfWeek) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use NotificationProfile_DayOfWeek.Descriptor instead. +func (NotificationProfile_DayOfWeek) EnumDescriptor() ([]byte, []int) { + return file_backuppb_Backup_proto_rawDescGZIP(), []int{78, 0} +} + +// Represents the default "All chats" folder record vs all other custom folders +type ChatFolder_FolderType int32 + +const ( + ChatFolder_UNKNOWN ChatFolder_FolderType = 0 + ChatFolder_ALL ChatFolder_FolderType = 1 + ChatFolder_CUSTOM ChatFolder_FolderType = 2 +) + +// Enum value maps for ChatFolder_FolderType. +var ( + ChatFolder_FolderType_name = map[int32]string{ + 0: "UNKNOWN", + 1: "ALL", + 2: "CUSTOM", + } + ChatFolder_FolderType_value = map[string]int32{ + "UNKNOWN": 0, + "ALL": 1, + "CUSTOM": 2, + } +) + +func (x ChatFolder_FolderType) Enum() *ChatFolder_FolderType { + p := new(ChatFolder_FolderType) + *p = x + return p +} + +func (x ChatFolder_FolderType) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (ChatFolder_FolderType) Descriptor() protoreflect.EnumDescriptor { + return file_backuppb_Backup_proto_enumTypes[29].Descriptor() +} + +func (ChatFolder_FolderType) Type() protoreflect.EnumType { + return &file_backuppb_Backup_proto_enumTypes[29] +} + +func (x ChatFolder_FolderType) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use ChatFolder_FolderType.Descriptor instead. +func (ChatFolder_FolderType) EnumDescriptor() ([]byte, []int) { + return file_backuppb_Backup_proto_rawDescGZIP(), []int{79, 0} +} + +type BackupInfo struct { + state protoimpl.MessageState `protogen:"open.v1"` + Version uint64 `protobuf:"varint,1,opt,name=version,proto3" json:"version,omitempty"` + BackupTimeMs uint64 `protobuf:"varint,2,opt,name=backupTimeMs,proto3" json:"backupTimeMs,omitempty"` + MediaRootBackupKey []byte `protobuf:"bytes,3,opt,name=mediaRootBackupKey,proto3" json:"mediaRootBackupKey,omitempty"` // 32-byte random value generated when the backup is uploaded for the first time. + CurrentAppVersion string `protobuf:"bytes,4,opt,name=currentAppVersion,proto3" json:"currentAppVersion,omitempty"` + FirstAppVersion string `protobuf:"bytes,5,opt,name=firstAppVersion,proto3" json:"firstAppVersion,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *BackupInfo) Reset() { + *x = BackupInfo{} + mi := &file_backuppb_Backup_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *BackupInfo) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*BackupInfo) ProtoMessage() {} + +func (x *BackupInfo) ProtoReflect() protoreflect.Message { + mi := &file_backuppb_Backup_proto_msgTypes[0] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use BackupInfo.ProtoReflect.Descriptor instead. +func (*BackupInfo) Descriptor() ([]byte, []int) { + return file_backuppb_Backup_proto_rawDescGZIP(), []int{0} +} + +func (x *BackupInfo) GetVersion() uint64 { + if x != nil { + return x.Version + } + return 0 +} + +func (x *BackupInfo) GetBackupTimeMs() uint64 { + if x != nil { + return x.BackupTimeMs + } + return 0 +} + +func (x *BackupInfo) GetMediaRootBackupKey() []byte { + if x != nil { + return x.MediaRootBackupKey + } + return nil +} + +func (x *BackupInfo) GetCurrentAppVersion() string { + if x != nil { + return x.CurrentAppVersion + } + return "" +} + +func (x *BackupInfo) GetFirstAppVersion() string { + if x != nil { + return x.FirstAppVersion + } + return "" +} + +// Frames must follow in the following ordering rules: +// +// 1. There is exactly one AccountData and it is the first frame. +// 2. A frame referenced by ID must come before the referencing frame. +// e.g. a Recipient must come before any Chat referencing it. +// 3. All ChatItems must appear in global Chat rendering order. +// (The order in which they were received by the client.) +// 4. ChatFolders must appear in render order (e.g., left to right for +// LTR locales), but can appear anywhere relative to other frames respecting +// rule 2 (after Recipients and Chats). +// +// Recipients, Chats, StickerPacks, AdHocCalls, and NotificationProfiles +// can be in any order. (But must respect rule 2.) +// +// For example, Chats may all be together at the beginning, +// or may each immediately precede its first ChatItem. +type Frame struct { + state protoimpl.MessageState `protogen:"open.v1"` + // Types that are valid to be assigned to Item: + // + // *Frame_Account + // *Frame_Recipient + // *Frame_Chat + // *Frame_ChatItem + // *Frame_StickerPack + // *Frame_AdHocCall + // *Frame_NotificationProfile + // *Frame_ChatFolder + Item isFrame_Item `protobuf_oneof:"item"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *Frame) Reset() { + *x = Frame{} + mi := &file_backuppb_Backup_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *Frame) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Frame) ProtoMessage() {} + +func (x *Frame) ProtoReflect() protoreflect.Message { + mi := &file_backuppb_Backup_proto_msgTypes[1] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Frame.ProtoReflect.Descriptor instead. +func (*Frame) Descriptor() ([]byte, []int) { + return file_backuppb_Backup_proto_rawDescGZIP(), []int{1} +} + +func (x *Frame) GetItem() isFrame_Item { + if x != nil { + return x.Item + } + return nil +} + +func (x *Frame) GetAccount() *AccountData { + if x != nil { + if x, ok := x.Item.(*Frame_Account); ok { + return x.Account + } + } + return nil +} + +func (x *Frame) GetRecipient() *Recipient { + if x != nil { + if x, ok := x.Item.(*Frame_Recipient); ok { + return x.Recipient + } + } + return nil +} + +func (x *Frame) GetChat() *Chat { + if x != nil { + if x, ok := x.Item.(*Frame_Chat); ok { + return x.Chat + } + } + return nil +} + +func (x *Frame) GetChatItem() *ChatItem { + if x != nil { + if x, ok := x.Item.(*Frame_ChatItem); ok { + return x.ChatItem + } + } + return nil +} + +func (x *Frame) GetStickerPack() *StickerPack { + if x != nil { + if x, ok := x.Item.(*Frame_StickerPack); ok { + return x.StickerPack + } + } + return nil +} + +func (x *Frame) GetAdHocCall() *AdHocCall { + if x != nil { + if x, ok := x.Item.(*Frame_AdHocCall); ok { + return x.AdHocCall + } + } + return nil +} + +func (x *Frame) GetNotificationProfile() *NotificationProfile { + if x != nil { + if x, ok := x.Item.(*Frame_NotificationProfile); ok { + return x.NotificationProfile + } + } + return nil +} + +func (x *Frame) GetChatFolder() *ChatFolder { + if x != nil { + if x, ok := x.Item.(*Frame_ChatFolder); ok { + return x.ChatFolder + } + } + return nil +} + +type isFrame_Item interface { + isFrame_Item() +} + +type Frame_Account struct { + Account *AccountData `protobuf:"bytes,1,opt,name=account,proto3,oneof"` +} + +type Frame_Recipient struct { + Recipient *Recipient `protobuf:"bytes,2,opt,name=recipient,proto3,oneof"` +} + +type Frame_Chat struct { + Chat *Chat `protobuf:"bytes,3,opt,name=chat,proto3,oneof"` +} + +type Frame_ChatItem struct { + ChatItem *ChatItem `protobuf:"bytes,4,opt,name=chatItem,proto3,oneof"` +} + +type Frame_StickerPack struct { + StickerPack *StickerPack `protobuf:"bytes,5,opt,name=stickerPack,proto3,oneof"` +} + +type Frame_AdHocCall struct { + AdHocCall *AdHocCall `protobuf:"bytes,6,opt,name=adHocCall,proto3,oneof"` +} + +type Frame_NotificationProfile struct { + NotificationProfile *NotificationProfile `protobuf:"bytes,7,opt,name=notificationProfile,proto3,oneof"` +} + +type Frame_ChatFolder struct { + ChatFolder *ChatFolder `protobuf:"bytes,8,opt,name=chatFolder,proto3,oneof"` +} + +func (*Frame_Account) isFrame_Item() {} + +func (*Frame_Recipient) isFrame_Item() {} + +func (*Frame_Chat) isFrame_Item() {} + +func (*Frame_ChatItem) isFrame_Item() {} + +func (*Frame_StickerPack) isFrame_Item() {} + +func (*Frame_AdHocCall) isFrame_Item() {} + +func (*Frame_NotificationProfile) isFrame_Item() {} + +func (*Frame_ChatFolder) isFrame_Item() {} + +type AccountData struct { + state protoimpl.MessageState `protogen:"open.v1"` + ProfileKey []byte `protobuf:"bytes,1,opt,name=profileKey,proto3" json:"profileKey,omitempty"` + Username *string `protobuf:"bytes,2,opt,name=username,proto3,oneof" json:"username,omitempty"` + UsernameLink *AccountData_UsernameLink `protobuf:"bytes,3,opt,name=usernameLink,proto3" json:"usernameLink,omitempty"` + GivenName string `protobuf:"bytes,4,opt,name=givenName,proto3" json:"givenName,omitempty"` + FamilyName string `protobuf:"bytes,5,opt,name=familyName,proto3" json:"familyName,omitempty"` + AvatarUrlPath string `protobuf:"bytes,6,opt,name=avatarUrlPath,proto3" json:"avatarUrlPath,omitempty"` + DonationSubscriberData *AccountData_SubscriberData `protobuf:"bytes,7,opt,name=donationSubscriberData,proto3" json:"donationSubscriberData,omitempty"` + AccountSettings *AccountData_AccountSettings `protobuf:"bytes,9,opt,name=accountSettings,proto3" json:"accountSettings,omitempty"` + BackupsSubscriberData *AccountData_IAPSubscriberData `protobuf:"bytes,10,opt,name=backupsSubscriberData,proto3" json:"backupsSubscriberData,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *AccountData) Reset() { + *x = AccountData{} + mi := &file_backuppb_Backup_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *AccountData) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*AccountData) ProtoMessage() {} + +func (x *AccountData) ProtoReflect() protoreflect.Message { + mi := &file_backuppb_Backup_proto_msgTypes[2] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use AccountData.ProtoReflect.Descriptor instead. +func (*AccountData) Descriptor() ([]byte, []int) { + return file_backuppb_Backup_proto_rawDescGZIP(), []int{2} +} + +func (x *AccountData) GetProfileKey() []byte { + if x != nil { + return x.ProfileKey + } + return nil +} + +func (x *AccountData) GetUsername() string { + if x != nil && x.Username != nil { + return *x.Username + } + return "" +} + +func (x *AccountData) GetUsernameLink() *AccountData_UsernameLink { + if x != nil { + return x.UsernameLink + } + return nil +} + +func (x *AccountData) GetGivenName() string { + if x != nil { + return x.GivenName + } + return "" +} + +func (x *AccountData) GetFamilyName() string { + if x != nil { + return x.FamilyName + } + return "" +} + +func (x *AccountData) GetAvatarUrlPath() string { + if x != nil { + return x.AvatarUrlPath + } + return "" +} + +func (x *AccountData) GetDonationSubscriberData() *AccountData_SubscriberData { + if x != nil { + return x.DonationSubscriberData + } + return nil +} + +func (x *AccountData) GetAccountSettings() *AccountData_AccountSettings { + if x != nil { + return x.AccountSettings + } + return nil +} + +func (x *AccountData) GetBackupsSubscriberData() *AccountData_IAPSubscriberData { + if x != nil { + return x.BackupsSubscriberData + } + return nil +} + +type Recipient struct { + state protoimpl.MessageState `protogen:"open.v1"` + Id uint64 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"` // generated id for reference only within this file + // Types that are valid to be assigned to Destination: + // + // *Recipient_Contact + // *Recipient_Group + // *Recipient_DistributionList + // *Recipient_Self + // *Recipient_ReleaseNotes + // *Recipient_CallLink + Destination isRecipient_Destination `protobuf_oneof:"destination"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *Recipient) Reset() { + *x = Recipient{} + mi := &file_backuppb_Backup_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *Recipient) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Recipient) ProtoMessage() {} + +func (x *Recipient) ProtoReflect() protoreflect.Message { + mi := &file_backuppb_Backup_proto_msgTypes[3] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Recipient.ProtoReflect.Descriptor instead. +func (*Recipient) Descriptor() ([]byte, []int) { + return file_backuppb_Backup_proto_rawDescGZIP(), []int{3} +} + +func (x *Recipient) GetId() uint64 { + if x != nil { + return x.Id + } + return 0 +} + +func (x *Recipient) GetDestination() isRecipient_Destination { + if x != nil { + return x.Destination + } + return nil +} + +func (x *Recipient) GetContact() *Contact { + if x != nil { + if x, ok := x.Destination.(*Recipient_Contact); ok { + return x.Contact + } + } + return nil +} + +func (x *Recipient) GetGroup() *Group { + if x != nil { + if x, ok := x.Destination.(*Recipient_Group); ok { + return x.Group + } + } + return nil +} + +func (x *Recipient) GetDistributionList() *DistributionListItem { + if x != nil { + if x, ok := x.Destination.(*Recipient_DistributionList); ok { + return x.DistributionList + } + } + return nil +} + +func (x *Recipient) GetSelf() *Self { + if x != nil { + if x, ok := x.Destination.(*Recipient_Self); ok { + return x.Self + } + } + return nil +} + +func (x *Recipient) GetReleaseNotes() *ReleaseNotes { + if x != nil { + if x, ok := x.Destination.(*Recipient_ReleaseNotes); ok { + return x.ReleaseNotes + } + } + return nil +} + +func (x *Recipient) GetCallLink() *CallLink { + if x != nil { + if x, ok := x.Destination.(*Recipient_CallLink); ok { + return x.CallLink + } + } + return nil +} + +type isRecipient_Destination interface { + isRecipient_Destination() +} + +type Recipient_Contact struct { + Contact *Contact `protobuf:"bytes,2,opt,name=contact,proto3,oneof"` +} + +type Recipient_Group struct { + Group *Group `protobuf:"bytes,3,opt,name=group,proto3,oneof"` +} + +type Recipient_DistributionList struct { + DistributionList *DistributionListItem `protobuf:"bytes,4,opt,name=distributionList,proto3,oneof"` +} + +type Recipient_Self struct { + Self *Self `protobuf:"bytes,5,opt,name=self,proto3,oneof"` +} + +type Recipient_ReleaseNotes struct { + ReleaseNotes *ReleaseNotes `protobuf:"bytes,6,opt,name=releaseNotes,proto3,oneof"` +} + +type Recipient_CallLink struct { + CallLink *CallLink `protobuf:"bytes,7,opt,name=callLink,proto3,oneof"` +} + +func (*Recipient_Contact) isRecipient_Destination() {} + +func (*Recipient_Group) isRecipient_Destination() {} + +func (*Recipient_DistributionList) isRecipient_Destination() {} + +func (*Recipient_Self) isRecipient_Destination() {} + +func (*Recipient_ReleaseNotes) isRecipient_Destination() {} + +func (*Recipient_CallLink) isRecipient_Destination() {} + +type Contact struct { + state protoimpl.MessageState `protogen:"open.v1"` + Aci []byte `protobuf:"bytes,1,opt,name=aci,proto3,oneof" json:"aci,omitempty"` // should be 16 bytes + Pni []byte `protobuf:"bytes,2,opt,name=pni,proto3,oneof" json:"pni,omitempty"` // should be 16 bytes + Username *string `protobuf:"bytes,3,opt,name=username,proto3,oneof" json:"username,omitempty"` + E164 *uint64 `protobuf:"varint,4,opt,name=e164,proto3,oneof" json:"e164,omitempty"` + Blocked bool `protobuf:"varint,5,opt,name=blocked,proto3" json:"blocked,omitempty"` + Visibility Contact_Visibility `protobuf:"varint,6,opt,name=visibility,proto3,enum=signal.backup.Contact_Visibility" json:"visibility,omitempty"` + // Types that are valid to be assigned to Registration: + // + // *Contact_Registered_ + // *Contact_NotRegistered_ + Registration isContact_Registration `protobuf_oneof:"registration"` + ProfileKey []byte `protobuf:"bytes,9,opt,name=profileKey,proto3,oneof" json:"profileKey,omitempty"` + ProfileSharing bool `protobuf:"varint,10,opt,name=profileSharing,proto3" json:"profileSharing,omitempty"` + ProfileGivenName *string `protobuf:"bytes,11,opt,name=profileGivenName,proto3,oneof" json:"profileGivenName,omitempty"` + ProfileFamilyName *string `protobuf:"bytes,12,opt,name=profileFamilyName,proto3,oneof" json:"profileFamilyName,omitempty"` + HideStory bool `protobuf:"varint,13,opt,name=hideStory,proto3" json:"hideStory,omitempty"` + IdentityKey []byte `protobuf:"bytes,14,opt,name=identityKey,proto3,oneof" json:"identityKey,omitempty"` + IdentityState Contact_IdentityState `protobuf:"varint,15,opt,name=identityState,proto3,enum=signal.backup.Contact_IdentityState" json:"identityState,omitempty"` + Nickname *Contact_Name `protobuf:"bytes,16,opt,name=nickname,proto3" json:"nickname,omitempty"` // absent iff both `given` and `family` are empty + Note string `protobuf:"bytes,17,opt,name=note,proto3" json:"note,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *Contact) Reset() { + *x = Contact{} + mi := &file_backuppb_Backup_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *Contact) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Contact) ProtoMessage() {} + +func (x *Contact) ProtoReflect() protoreflect.Message { + mi := &file_backuppb_Backup_proto_msgTypes[4] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Contact.ProtoReflect.Descriptor instead. +func (*Contact) Descriptor() ([]byte, []int) { + return file_backuppb_Backup_proto_rawDescGZIP(), []int{4} +} + +func (x *Contact) GetAci() []byte { + if x != nil { + return x.Aci + } + return nil +} + +func (x *Contact) GetPni() []byte { + if x != nil { + return x.Pni + } + return nil +} + +func (x *Contact) GetUsername() string { + if x != nil && x.Username != nil { + return *x.Username + } + return "" +} + +func (x *Contact) GetE164() uint64 { + if x != nil && x.E164 != nil { + return *x.E164 + } + return 0 +} + +func (x *Contact) GetBlocked() bool { + if x != nil { + return x.Blocked + } + return false +} + +func (x *Contact) GetVisibility() Contact_Visibility { + if x != nil { + return x.Visibility + } + return Contact_VISIBLE +} + +func (x *Contact) GetRegistration() isContact_Registration { + if x != nil { + return x.Registration + } + return nil +} + +func (x *Contact) GetRegistered() *Contact_Registered { + if x != nil { + if x, ok := x.Registration.(*Contact_Registered_); ok { + return x.Registered + } + } + return nil +} + +func (x *Contact) GetNotRegistered() *Contact_NotRegistered { + if x != nil { + if x, ok := x.Registration.(*Contact_NotRegistered_); ok { + return x.NotRegistered + } + } + return nil +} + +func (x *Contact) GetProfileKey() []byte { + if x != nil { + return x.ProfileKey + } + return nil +} + +func (x *Contact) GetProfileSharing() bool { + if x != nil { + return x.ProfileSharing + } + return false +} + +func (x *Contact) GetProfileGivenName() string { + if x != nil && x.ProfileGivenName != nil { + return *x.ProfileGivenName + } + return "" +} + +func (x *Contact) GetProfileFamilyName() string { + if x != nil && x.ProfileFamilyName != nil { + return *x.ProfileFamilyName + } + return "" +} + +func (x *Contact) GetHideStory() bool { + if x != nil { + return x.HideStory + } + return false +} + +func (x *Contact) GetIdentityKey() []byte { + if x != nil { + return x.IdentityKey + } + return nil +} + +func (x *Contact) GetIdentityState() Contact_IdentityState { + if x != nil { + return x.IdentityState + } + return Contact_DEFAULT +} + +func (x *Contact) GetNickname() *Contact_Name { + if x != nil { + return x.Nickname + } + return nil +} + +func (x *Contact) GetNote() string { + if x != nil { + return x.Note + } + return "" +} + +type isContact_Registration interface { + isContact_Registration() +} + +type Contact_Registered_ struct { + Registered *Contact_Registered `protobuf:"bytes,7,opt,name=registered,proto3,oneof"` +} + +type Contact_NotRegistered_ struct { + NotRegistered *Contact_NotRegistered `protobuf:"bytes,8,opt,name=notRegistered,proto3,oneof"` +} + +func (*Contact_Registered_) isContact_Registration() {} + +func (*Contact_NotRegistered_) isContact_Registration() {} + +type Group struct { + state protoimpl.MessageState `protogen:"open.v1"` + MasterKey []byte `protobuf:"bytes,1,opt,name=masterKey,proto3" json:"masterKey,omitempty"` + Whitelisted bool `protobuf:"varint,2,opt,name=whitelisted,proto3" json:"whitelisted,omitempty"` + HideStory bool `protobuf:"varint,3,opt,name=hideStory,proto3" json:"hideStory,omitempty"` + StorySendMode Group_StorySendMode `protobuf:"varint,4,opt,name=storySendMode,proto3,enum=signal.backup.Group_StorySendMode" json:"storySendMode,omitempty"` + Snapshot *Group_GroupSnapshot `protobuf:"bytes,5,opt,name=snapshot,proto3" json:"snapshot,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *Group) Reset() { + *x = Group{} + mi := &file_backuppb_Backup_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *Group) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Group) ProtoMessage() {} + +func (x *Group) ProtoReflect() protoreflect.Message { + mi := &file_backuppb_Backup_proto_msgTypes[5] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Group.ProtoReflect.Descriptor instead. +func (*Group) Descriptor() ([]byte, []int) { + return file_backuppb_Backup_proto_rawDescGZIP(), []int{5} +} + +func (x *Group) GetMasterKey() []byte { + if x != nil { + return x.MasterKey + } + return nil +} + +func (x *Group) GetWhitelisted() bool { + if x != nil { + return x.Whitelisted + } + return false +} + +func (x *Group) GetHideStory() bool { + if x != nil { + return x.HideStory + } + return false +} + +func (x *Group) GetStorySendMode() Group_StorySendMode { + if x != nil { + return x.StorySendMode + } + return Group_DEFAULT +} + +func (x *Group) GetSnapshot() *Group_GroupSnapshot { + if x != nil { + return x.Snapshot + } + return nil +} + +type Self struct { + state protoimpl.MessageState `protogen:"open.v1"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *Self) Reset() { + *x = Self{} + mi := &file_backuppb_Backup_proto_msgTypes[6] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *Self) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Self) ProtoMessage() {} + +func (x *Self) ProtoReflect() protoreflect.Message { + mi := &file_backuppb_Backup_proto_msgTypes[6] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Self.ProtoReflect.Descriptor instead. +func (*Self) Descriptor() ([]byte, []int) { + return file_backuppb_Backup_proto_rawDescGZIP(), []int{6} +} + +type ReleaseNotes struct { + state protoimpl.MessageState `protogen:"open.v1"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ReleaseNotes) Reset() { + *x = ReleaseNotes{} + mi := &file_backuppb_Backup_proto_msgTypes[7] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ReleaseNotes) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ReleaseNotes) ProtoMessage() {} + +func (x *ReleaseNotes) ProtoReflect() protoreflect.Message { + mi := &file_backuppb_Backup_proto_msgTypes[7] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ReleaseNotes.ProtoReflect.Descriptor instead. +func (*ReleaseNotes) Descriptor() ([]byte, []int) { + return file_backuppb_Backup_proto_rawDescGZIP(), []int{7} +} + +type Chat struct { + state protoimpl.MessageState `protogen:"open.v1"` + Id uint64 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"` // generated id for reference only within this file + RecipientId uint64 `protobuf:"varint,2,opt,name=recipientId,proto3" json:"recipientId,omitempty"` + Archived bool `protobuf:"varint,3,opt,name=archived,proto3" json:"archived,omitempty"` + PinnedOrder *uint32 `protobuf:"varint,4,opt,name=pinnedOrder,proto3,oneof" json:"pinnedOrder,omitempty"` // will be displayed in ascending order + ExpirationTimerMs *uint64 `protobuf:"varint,5,opt,name=expirationTimerMs,proto3,oneof" json:"expirationTimerMs,omitempty"` + MuteUntilMs *uint64 `protobuf:"varint,6,opt,name=muteUntilMs,proto3,oneof" json:"muteUntilMs,omitempty"` // INT64_MAX (2^63 - 1) = "always muted". + MarkedUnread bool `protobuf:"varint,7,opt,name=markedUnread,proto3" json:"markedUnread,omitempty"` + DontNotifyForMentionsIfMuted bool `protobuf:"varint,8,opt,name=dontNotifyForMentionsIfMuted,proto3" json:"dontNotifyForMentionsIfMuted,omitempty"` + Style *ChatStyle `protobuf:"bytes,9,opt,name=style,proto3" json:"style,omitempty"` + ExpireTimerVersion uint32 `protobuf:"varint,10,opt,name=expireTimerVersion,proto3" json:"expireTimerVersion,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *Chat) Reset() { + *x = Chat{} + mi := &file_backuppb_Backup_proto_msgTypes[8] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *Chat) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Chat) ProtoMessage() {} + +func (x *Chat) ProtoReflect() protoreflect.Message { + mi := &file_backuppb_Backup_proto_msgTypes[8] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Chat.ProtoReflect.Descriptor instead. +func (*Chat) Descriptor() ([]byte, []int) { + return file_backuppb_Backup_proto_rawDescGZIP(), []int{8} +} + +func (x *Chat) GetId() uint64 { + if x != nil { + return x.Id + } + return 0 +} + +func (x *Chat) GetRecipientId() uint64 { + if x != nil { + return x.RecipientId + } + return 0 +} + +func (x *Chat) GetArchived() bool { + if x != nil { + return x.Archived + } + return false +} + +func (x *Chat) GetPinnedOrder() uint32 { + if x != nil && x.PinnedOrder != nil { + return *x.PinnedOrder + } + return 0 +} + +func (x *Chat) GetExpirationTimerMs() uint64 { + if x != nil && x.ExpirationTimerMs != nil { + return *x.ExpirationTimerMs + } + return 0 +} + +func (x *Chat) GetMuteUntilMs() uint64 { + if x != nil && x.MuteUntilMs != nil { + return *x.MuteUntilMs + } + return 0 +} + +func (x *Chat) GetMarkedUnread() bool { + if x != nil { + return x.MarkedUnread + } + return false +} + +func (x *Chat) GetDontNotifyForMentionsIfMuted() bool { + if x != nil { + return x.DontNotifyForMentionsIfMuted + } + return false +} + +func (x *Chat) GetStyle() *ChatStyle { + if x != nil { + return x.Style + } + return nil +} + +func (x *Chat) GetExpireTimerVersion() uint32 { + if x != nil { + return x.ExpireTimerVersion + } + return 0 +} + +// * +// Call Links have some associated data including a call, but unlike other recipients +// are not tied to threads because they do not have messages associated with them. +// +// note: +// - room id can be derived from the root key +// - the presence of an admin key means this user is a call admin +type CallLink struct { + state protoimpl.MessageState `protogen:"open.v1"` + RootKey []byte `protobuf:"bytes,1,opt,name=rootKey,proto3" json:"rootKey,omitempty"` + AdminKey []byte `protobuf:"bytes,2,opt,name=adminKey,proto3,oneof" json:"adminKey,omitempty"` // Only present if the user is an admin + Name string `protobuf:"bytes,3,opt,name=name,proto3" json:"name,omitempty"` + Restrictions CallLink_Restrictions `protobuf:"varint,4,opt,name=restrictions,proto3,enum=signal.backup.CallLink_Restrictions" json:"restrictions,omitempty"` + ExpirationMs uint64 `protobuf:"varint,5,opt,name=expirationMs,proto3" json:"expirationMs,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *CallLink) Reset() { + *x = CallLink{} + mi := &file_backuppb_Backup_proto_msgTypes[9] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *CallLink) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CallLink) ProtoMessage() {} + +func (x *CallLink) ProtoReflect() protoreflect.Message { + mi := &file_backuppb_Backup_proto_msgTypes[9] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use CallLink.ProtoReflect.Descriptor instead. +func (*CallLink) Descriptor() ([]byte, []int) { + return file_backuppb_Backup_proto_rawDescGZIP(), []int{9} +} + +func (x *CallLink) GetRootKey() []byte { + if x != nil { + return x.RootKey + } + return nil +} + +func (x *CallLink) GetAdminKey() []byte { + if x != nil { + return x.AdminKey + } + return nil +} + +func (x *CallLink) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *CallLink) GetRestrictions() CallLink_Restrictions { + if x != nil { + return x.Restrictions + } + return CallLink_UNKNOWN +} + +func (x *CallLink) GetExpirationMs() uint64 { + if x != nil { + return x.ExpirationMs + } + return 0 +} + +type AdHocCall struct { + state protoimpl.MessageState `protogen:"open.v1"` + CallId uint64 `protobuf:"varint,1,opt,name=callId,proto3" json:"callId,omitempty"` + // Refers to a `CallLink` recipient. + RecipientId uint64 `protobuf:"varint,2,opt,name=recipientId,proto3" json:"recipientId,omitempty"` + State AdHocCall_State `protobuf:"varint,3,opt,name=state,proto3,enum=signal.backup.AdHocCall_State" json:"state,omitempty"` + CallTimestamp uint64 `protobuf:"varint,4,opt,name=callTimestamp,proto3" json:"callTimestamp,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *AdHocCall) Reset() { + *x = AdHocCall{} + mi := &file_backuppb_Backup_proto_msgTypes[10] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *AdHocCall) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*AdHocCall) ProtoMessage() {} + +func (x *AdHocCall) ProtoReflect() protoreflect.Message { + mi := &file_backuppb_Backup_proto_msgTypes[10] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use AdHocCall.ProtoReflect.Descriptor instead. +func (*AdHocCall) Descriptor() ([]byte, []int) { + return file_backuppb_Backup_proto_rawDescGZIP(), []int{10} +} + +func (x *AdHocCall) GetCallId() uint64 { + if x != nil { + return x.CallId + } + return 0 +} + +func (x *AdHocCall) GetRecipientId() uint64 { + if x != nil { + return x.RecipientId + } + return 0 +} + +func (x *AdHocCall) GetState() AdHocCall_State { + if x != nil { + return x.State + } + return AdHocCall_UNKNOWN_STATE +} + +func (x *AdHocCall) GetCallTimestamp() uint64 { + if x != nil { + return x.CallTimestamp + } + return 0 +} + +type DistributionListItem struct { + state protoimpl.MessageState `protogen:"open.v1"` + // distribution ids are UUIDv4s. "My Story" is represented + // by an all-0 UUID (00000000-0000-0000-0000-000000000000). + DistributionId []byte `protobuf:"bytes,1,opt,name=distributionId,proto3" json:"distributionId,omitempty"` // distribution list ids are uuids + // Types that are valid to be assigned to Item: + // + // *DistributionListItem_DeletionTimestamp + // *DistributionListItem_DistributionList + Item isDistributionListItem_Item `protobuf_oneof:"item"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *DistributionListItem) Reset() { + *x = DistributionListItem{} + mi := &file_backuppb_Backup_proto_msgTypes[11] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *DistributionListItem) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*DistributionListItem) ProtoMessage() {} + +func (x *DistributionListItem) ProtoReflect() protoreflect.Message { + mi := &file_backuppb_Backup_proto_msgTypes[11] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use DistributionListItem.ProtoReflect.Descriptor instead. +func (*DistributionListItem) Descriptor() ([]byte, []int) { + return file_backuppb_Backup_proto_rawDescGZIP(), []int{11} +} + +func (x *DistributionListItem) GetDistributionId() []byte { + if x != nil { + return x.DistributionId + } + return nil +} + +func (x *DistributionListItem) GetItem() isDistributionListItem_Item { + if x != nil { + return x.Item + } + return nil +} + +func (x *DistributionListItem) GetDeletionTimestamp() uint64 { + if x != nil { + if x, ok := x.Item.(*DistributionListItem_DeletionTimestamp); ok { + return x.DeletionTimestamp + } + } + return 0 +} + +func (x *DistributionListItem) GetDistributionList() *DistributionList { + if x != nil { + if x, ok := x.Item.(*DistributionListItem_DistributionList); ok { + return x.DistributionList + } + } + return nil +} + +type isDistributionListItem_Item interface { + isDistributionListItem_Item() +} + +type DistributionListItem_DeletionTimestamp struct { + DeletionTimestamp uint64 `protobuf:"varint,2,opt,name=deletionTimestamp,proto3,oneof"` +} + +type DistributionListItem_DistributionList struct { + DistributionList *DistributionList `protobuf:"bytes,3,opt,name=distributionList,proto3,oneof"` +} + +func (*DistributionListItem_DeletionTimestamp) isDistributionListItem_Item() {} + +func (*DistributionListItem_DistributionList) isDistributionListItem_Item() {} + +type DistributionList struct { + state protoimpl.MessageState `protogen:"open.v1"` + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + AllowReplies bool `protobuf:"varint,2,opt,name=allowReplies,proto3" json:"allowReplies,omitempty"` + PrivacyMode DistributionList_PrivacyMode `protobuf:"varint,3,opt,name=privacyMode,proto3,enum=signal.backup.DistributionList_PrivacyMode" json:"privacyMode,omitempty"` + MemberRecipientIds []uint64 `protobuf:"varint,4,rep,packed,name=memberRecipientIds,proto3" json:"memberRecipientIds,omitempty"` // generated recipient id + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *DistributionList) Reset() { + *x = DistributionList{} + mi := &file_backuppb_Backup_proto_msgTypes[12] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *DistributionList) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*DistributionList) ProtoMessage() {} + +func (x *DistributionList) ProtoReflect() protoreflect.Message { + mi := &file_backuppb_Backup_proto_msgTypes[12] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use DistributionList.ProtoReflect.Descriptor instead. +func (*DistributionList) Descriptor() ([]byte, []int) { + return file_backuppb_Backup_proto_rawDescGZIP(), []int{12} +} + +func (x *DistributionList) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *DistributionList) GetAllowReplies() bool { + if x != nil { + return x.AllowReplies + } + return false +} + +func (x *DistributionList) GetPrivacyMode() DistributionList_PrivacyMode { + if x != nil { + return x.PrivacyMode + } + return DistributionList_UNKNOWN +} + +func (x *DistributionList) GetMemberRecipientIds() []uint64 { + if x != nil { + return x.MemberRecipientIds + } + return nil +} + +type ChatItem struct { + state protoimpl.MessageState `protogen:"open.v1"` + ChatId uint64 `protobuf:"varint,1,opt,name=chatId,proto3" json:"chatId,omitempty"` // conversation id + AuthorId uint64 `protobuf:"varint,2,opt,name=authorId,proto3" json:"authorId,omitempty"` // recipient id + DateSent uint64 `protobuf:"varint,3,opt,name=dateSent,proto3" json:"dateSent,omitempty"` + ExpireStartDate *uint64 `protobuf:"varint,4,opt,name=expireStartDate,proto3,oneof" json:"expireStartDate,omitempty"` // timestamp of when expiration timer started ticking down + ExpiresInMs *uint64 `protobuf:"varint,5,opt,name=expiresInMs,proto3,oneof" json:"expiresInMs,omitempty"` // how long timer of message is (ms) + Revisions []*ChatItem `protobuf:"bytes,6,rep,name=revisions,proto3" json:"revisions,omitempty"` // ordered from oldest to newest + Sms bool `protobuf:"varint,7,opt,name=sms,proto3" json:"sms,omitempty"` + // Types that are valid to be assigned to DirectionalDetails: + // + // *ChatItem_Incoming + // *ChatItem_Outgoing + // *ChatItem_Directionless + DirectionalDetails isChatItem_DirectionalDetails `protobuf_oneof:"directionalDetails"` + // Types that are valid to be assigned to Item: + // + // *ChatItem_StandardMessage + // *ChatItem_ContactMessage + // *ChatItem_StickerMessage + // *ChatItem_RemoteDeletedMessage + // *ChatItem_UpdateMessage + // *ChatItem_PaymentNotification + // *ChatItem_GiftBadge + // *ChatItem_ViewOnceMessage + // *ChatItem_DirectStoryReplyMessage + Item isChatItem_Item `protobuf_oneof:"item"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ChatItem) Reset() { + *x = ChatItem{} + mi := &file_backuppb_Backup_proto_msgTypes[13] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ChatItem) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ChatItem) ProtoMessage() {} + +func (x *ChatItem) ProtoReflect() protoreflect.Message { + mi := &file_backuppb_Backup_proto_msgTypes[13] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ChatItem.ProtoReflect.Descriptor instead. +func (*ChatItem) Descriptor() ([]byte, []int) { + return file_backuppb_Backup_proto_rawDescGZIP(), []int{13} +} + +func (x *ChatItem) GetChatId() uint64 { + if x != nil { + return x.ChatId + } + return 0 +} + +func (x *ChatItem) GetAuthorId() uint64 { + if x != nil { + return x.AuthorId + } + return 0 +} + +func (x *ChatItem) GetDateSent() uint64 { + if x != nil { + return x.DateSent + } + return 0 +} + +func (x *ChatItem) GetExpireStartDate() uint64 { + if x != nil && x.ExpireStartDate != nil { + return *x.ExpireStartDate + } + return 0 +} + +func (x *ChatItem) GetExpiresInMs() uint64 { + if x != nil && x.ExpiresInMs != nil { + return *x.ExpiresInMs + } + return 0 +} + +func (x *ChatItem) GetRevisions() []*ChatItem { + if x != nil { + return x.Revisions + } + return nil +} + +func (x *ChatItem) GetSms() bool { + if x != nil { + return x.Sms + } + return false +} + +func (x *ChatItem) GetDirectionalDetails() isChatItem_DirectionalDetails { + if x != nil { + return x.DirectionalDetails + } + return nil +} + +func (x *ChatItem) GetIncoming() *ChatItem_IncomingMessageDetails { + if x != nil { + if x, ok := x.DirectionalDetails.(*ChatItem_Incoming); ok { + return x.Incoming + } + } + return nil +} + +func (x *ChatItem) GetOutgoing() *ChatItem_OutgoingMessageDetails { + if x != nil { + if x, ok := x.DirectionalDetails.(*ChatItem_Outgoing); ok { + return x.Outgoing + } + } + return nil +} + +func (x *ChatItem) GetDirectionless() *ChatItem_DirectionlessMessageDetails { + if x != nil { + if x, ok := x.DirectionalDetails.(*ChatItem_Directionless); ok { + return x.Directionless + } + } + return nil +} + +func (x *ChatItem) GetItem() isChatItem_Item { + if x != nil { + return x.Item + } + return nil +} + +func (x *ChatItem) GetStandardMessage() *StandardMessage { + if x != nil { + if x, ok := x.Item.(*ChatItem_StandardMessage); ok { + return x.StandardMessage + } + } + return nil +} + +func (x *ChatItem) GetContactMessage() *ContactMessage { + if x != nil { + if x, ok := x.Item.(*ChatItem_ContactMessage); ok { + return x.ContactMessage + } + } + return nil +} + +func (x *ChatItem) GetStickerMessage() *StickerMessage { + if x != nil { + if x, ok := x.Item.(*ChatItem_StickerMessage); ok { + return x.StickerMessage + } + } + return nil +} + +func (x *ChatItem) GetRemoteDeletedMessage() *RemoteDeletedMessage { + if x != nil { + if x, ok := x.Item.(*ChatItem_RemoteDeletedMessage); ok { + return x.RemoteDeletedMessage + } + } + return nil +} + +func (x *ChatItem) GetUpdateMessage() *ChatUpdateMessage { + if x != nil { + if x, ok := x.Item.(*ChatItem_UpdateMessage); ok { + return x.UpdateMessage + } + } + return nil +} + +func (x *ChatItem) GetPaymentNotification() *PaymentNotification { + if x != nil { + if x, ok := x.Item.(*ChatItem_PaymentNotification); ok { + return x.PaymentNotification + } + } + return nil +} + +func (x *ChatItem) GetGiftBadge() *GiftBadge { + if x != nil { + if x, ok := x.Item.(*ChatItem_GiftBadge); ok { + return x.GiftBadge + } + } + return nil +} + +func (x *ChatItem) GetViewOnceMessage() *ViewOnceMessage { + if x != nil { + if x, ok := x.Item.(*ChatItem_ViewOnceMessage); ok { + return x.ViewOnceMessage + } + } + return nil +} + +func (x *ChatItem) GetDirectStoryReplyMessage() *DirectStoryReplyMessage { + if x != nil { + if x, ok := x.Item.(*ChatItem_DirectStoryReplyMessage); ok { + return x.DirectStoryReplyMessage + } + } + return nil +} + +type isChatItem_DirectionalDetails interface { + isChatItem_DirectionalDetails() +} + +type ChatItem_Incoming struct { + Incoming *ChatItem_IncomingMessageDetails `protobuf:"bytes,8,opt,name=incoming,proto3,oneof"` +} + +type ChatItem_Outgoing struct { + Outgoing *ChatItem_OutgoingMessageDetails `protobuf:"bytes,9,opt,name=outgoing,proto3,oneof"` +} + +type ChatItem_Directionless struct { + Directionless *ChatItem_DirectionlessMessageDetails `protobuf:"bytes,10,opt,name=directionless,proto3,oneof"` +} + +func (*ChatItem_Incoming) isChatItem_DirectionalDetails() {} + +func (*ChatItem_Outgoing) isChatItem_DirectionalDetails() {} + +func (*ChatItem_Directionless) isChatItem_DirectionalDetails() {} + +type isChatItem_Item interface { + isChatItem_Item() +} + +type ChatItem_StandardMessage struct { + StandardMessage *StandardMessage `protobuf:"bytes,11,opt,name=standardMessage,proto3,oneof"` +} + +type ChatItem_ContactMessage struct { + ContactMessage *ContactMessage `protobuf:"bytes,12,opt,name=contactMessage,proto3,oneof"` +} + +type ChatItem_StickerMessage struct { + StickerMessage *StickerMessage `protobuf:"bytes,13,opt,name=stickerMessage,proto3,oneof"` +} + +type ChatItem_RemoteDeletedMessage struct { + RemoteDeletedMessage *RemoteDeletedMessage `protobuf:"bytes,14,opt,name=remoteDeletedMessage,proto3,oneof"` +} + +type ChatItem_UpdateMessage struct { + UpdateMessage *ChatUpdateMessage `protobuf:"bytes,15,opt,name=updateMessage,proto3,oneof"` +} + +type ChatItem_PaymentNotification struct { + PaymentNotification *PaymentNotification `protobuf:"bytes,16,opt,name=paymentNotification,proto3,oneof"` +} + +type ChatItem_GiftBadge struct { + GiftBadge *GiftBadge `protobuf:"bytes,17,opt,name=giftBadge,proto3,oneof"` +} + +type ChatItem_ViewOnceMessage struct { + ViewOnceMessage *ViewOnceMessage `protobuf:"bytes,18,opt,name=viewOnceMessage,proto3,oneof"` +} + +type ChatItem_DirectStoryReplyMessage struct { + DirectStoryReplyMessage *DirectStoryReplyMessage `protobuf:"bytes,19,opt,name=directStoryReplyMessage,proto3,oneof"` // group story reply messages are not backed up +} + +func (*ChatItem_StandardMessage) isChatItem_Item() {} + +func (*ChatItem_ContactMessage) isChatItem_Item() {} + +func (*ChatItem_StickerMessage) isChatItem_Item() {} + +func (*ChatItem_RemoteDeletedMessage) isChatItem_Item() {} + +func (*ChatItem_UpdateMessage) isChatItem_Item() {} + +func (*ChatItem_PaymentNotification) isChatItem_Item() {} + +func (*ChatItem_GiftBadge) isChatItem_Item() {} + +func (*ChatItem_ViewOnceMessage) isChatItem_Item() {} + +func (*ChatItem_DirectStoryReplyMessage) isChatItem_Item() {} + +type SendStatus struct { + state protoimpl.MessageState `protogen:"open.v1"` + RecipientId uint64 `protobuf:"varint,1,opt,name=recipientId,proto3" json:"recipientId,omitempty"` + Timestamp uint64 `protobuf:"varint,2,opt,name=timestamp,proto3" json:"timestamp,omitempty"` // the time the status was last updated -- if from a receipt, it should be the sentTime of the receipt + // Types that are valid to be assigned to DeliveryStatus: + // + // *SendStatus_Pending_ + // *SendStatus_Sent_ + // *SendStatus_Delivered_ + // *SendStatus_Read_ + // *SendStatus_Viewed_ + // *SendStatus_Skipped_ + // *SendStatus_Failed_ + DeliveryStatus isSendStatus_DeliveryStatus `protobuf_oneof:"deliveryStatus"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *SendStatus) Reset() { + *x = SendStatus{} + mi := &file_backuppb_Backup_proto_msgTypes[14] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *SendStatus) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SendStatus) ProtoMessage() {} + +func (x *SendStatus) ProtoReflect() protoreflect.Message { + mi := &file_backuppb_Backup_proto_msgTypes[14] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use SendStatus.ProtoReflect.Descriptor instead. +func (*SendStatus) Descriptor() ([]byte, []int) { + return file_backuppb_Backup_proto_rawDescGZIP(), []int{14} +} + +func (x *SendStatus) GetRecipientId() uint64 { + if x != nil { + return x.RecipientId + } + return 0 +} + +func (x *SendStatus) GetTimestamp() uint64 { + if x != nil { + return x.Timestamp + } + return 0 +} + +func (x *SendStatus) GetDeliveryStatus() isSendStatus_DeliveryStatus { + if x != nil { + return x.DeliveryStatus + } + return nil +} + +func (x *SendStatus) GetPending() *SendStatus_Pending { + if x != nil { + if x, ok := x.DeliveryStatus.(*SendStatus_Pending_); ok { + return x.Pending + } + } + return nil +} + +func (x *SendStatus) GetSent() *SendStatus_Sent { + if x != nil { + if x, ok := x.DeliveryStatus.(*SendStatus_Sent_); ok { + return x.Sent + } + } + return nil +} + +func (x *SendStatus) GetDelivered() *SendStatus_Delivered { + if x != nil { + if x, ok := x.DeliveryStatus.(*SendStatus_Delivered_); ok { + return x.Delivered + } + } + return nil +} + +func (x *SendStatus) GetRead() *SendStatus_Read { + if x != nil { + if x, ok := x.DeliveryStatus.(*SendStatus_Read_); ok { + return x.Read + } + } + return nil +} + +func (x *SendStatus) GetViewed() *SendStatus_Viewed { + if x != nil { + if x, ok := x.DeliveryStatus.(*SendStatus_Viewed_); ok { + return x.Viewed + } + } + return nil +} + +func (x *SendStatus) GetSkipped() *SendStatus_Skipped { + if x != nil { + if x, ok := x.DeliveryStatus.(*SendStatus_Skipped_); ok { + return x.Skipped + } + } + return nil +} + +func (x *SendStatus) GetFailed() *SendStatus_Failed { + if x != nil { + if x, ok := x.DeliveryStatus.(*SendStatus_Failed_); ok { + return x.Failed + } + } + return nil +} + +type isSendStatus_DeliveryStatus interface { + isSendStatus_DeliveryStatus() +} + +type SendStatus_Pending_ struct { + Pending *SendStatus_Pending `protobuf:"bytes,3,opt,name=pending,proto3,oneof"` +} + +type SendStatus_Sent_ struct { + Sent *SendStatus_Sent `protobuf:"bytes,4,opt,name=sent,proto3,oneof"` +} + +type SendStatus_Delivered_ struct { + Delivered *SendStatus_Delivered `protobuf:"bytes,5,opt,name=delivered,proto3,oneof"` +} + +type SendStatus_Read_ struct { + Read *SendStatus_Read `protobuf:"bytes,6,opt,name=read,proto3,oneof"` +} + +type SendStatus_Viewed_ struct { + Viewed *SendStatus_Viewed `protobuf:"bytes,7,opt,name=viewed,proto3,oneof"` +} + +type SendStatus_Skipped_ struct { + Skipped *SendStatus_Skipped `protobuf:"bytes,8,opt,name=skipped,proto3,oneof"` +} + +type SendStatus_Failed_ struct { + Failed *SendStatus_Failed `protobuf:"bytes,9,opt,name=failed,proto3,oneof"` +} + +func (*SendStatus_Pending_) isSendStatus_DeliveryStatus() {} + +func (*SendStatus_Sent_) isSendStatus_DeliveryStatus() {} + +func (*SendStatus_Delivered_) isSendStatus_DeliveryStatus() {} + +func (*SendStatus_Read_) isSendStatus_DeliveryStatus() {} + +func (*SendStatus_Viewed_) isSendStatus_DeliveryStatus() {} + +func (*SendStatus_Skipped_) isSendStatus_DeliveryStatus() {} + +func (*SendStatus_Failed_) isSendStatus_DeliveryStatus() {} + +type Text struct { + state protoimpl.MessageState `protogen:"open.v1"` + Body string `protobuf:"bytes,1,opt,name=body,proto3" json:"body,omitempty"` + BodyRanges []*BodyRange `protobuf:"bytes,2,rep,name=bodyRanges,proto3" json:"bodyRanges,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *Text) Reset() { + *x = Text{} + mi := &file_backuppb_Backup_proto_msgTypes[15] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *Text) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Text) ProtoMessage() {} + +func (x *Text) ProtoReflect() protoreflect.Message { + mi := &file_backuppb_Backup_proto_msgTypes[15] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Text.ProtoReflect.Descriptor instead. +func (*Text) Descriptor() ([]byte, []int) { + return file_backuppb_Backup_proto_rawDescGZIP(), []int{15} +} + +func (x *Text) GetBody() string { + if x != nil { + return x.Body + } + return "" +} + +func (x *Text) GetBodyRanges() []*BodyRange { + if x != nil { + return x.BodyRanges + } + return nil +} + +type StandardMessage struct { + state protoimpl.MessageState `protogen:"open.v1"` + Quote *Quote `protobuf:"bytes,1,opt,name=quote,proto3,oneof" json:"quote,omitempty"` + Text *Text `protobuf:"bytes,2,opt,name=text,proto3,oneof" json:"text,omitempty"` + Attachments []*MessageAttachment `protobuf:"bytes,3,rep,name=attachments,proto3" json:"attachments,omitempty"` + LinkPreview []*LinkPreview `protobuf:"bytes,4,rep,name=linkPreview,proto3" json:"linkPreview,omitempty"` + LongText *FilePointer `protobuf:"bytes,5,opt,name=longText,proto3,oneof" json:"longText,omitempty"` + Reactions []*Reaction `protobuf:"bytes,6,rep,name=reactions,proto3" json:"reactions,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *StandardMessage) Reset() { + *x = StandardMessage{} + mi := &file_backuppb_Backup_proto_msgTypes[16] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *StandardMessage) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*StandardMessage) ProtoMessage() {} + +func (x *StandardMessage) ProtoReflect() protoreflect.Message { + mi := &file_backuppb_Backup_proto_msgTypes[16] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use StandardMessage.ProtoReflect.Descriptor instead. +func (*StandardMessage) Descriptor() ([]byte, []int) { + return file_backuppb_Backup_proto_rawDescGZIP(), []int{16} +} + +func (x *StandardMessage) GetQuote() *Quote { + if x != nil { + return x.Quote + } + return nil +} + +func (x *StandardMessage) GetText() *Text { + if x != nil { + return x.Text + } + return nil +} + +func (x *StandardMessage) GetAttachments() []*MessageAttachment { + if x != nil { + return x.Attachments + } + return nil +} + +func (x *StandardMessage) GetLinkPreview() []*LinkPreview { + if x != nil { + return x.LinkPreview + } + return nil +} + +func (x *StandardMessage) GetLongText() *FilePointer { + if x != nil { + return x.LongText + } + return nil +} + +func (x *StandardMessage) GetReactions() []*Reaction { + if x != nil { + return x.Reactions + } + return nil +} + +type ContactMessage struct { + state protoimpl.MessageState `protogen:"open.v1"` + Contact *ContactAttachment `protobuf:"bytes,1,opt,name=contact,proto3" json:"contact,omitempty"` + Reactions []*Reaction `protobuf:"bytes,2,rep,name=reactions,proto3" json:"reactions,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ContactMessage) Reset() { + *x = ContactMessage{} + mi := &file_backuppb_Backup_proto_msgTypes[17] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ContactMessage) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ContactMessage) ProtoMessage() {} + +func (x *ContactMessage) ProtoReflect() protoreflect.Message { + mi := &file_backuppb_Backup_proto_msgTypes[17] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ContactMessage.ProtoReflect.Descriptor instead. +func (*ContactMessage) Descriptor() ([]byte, []int) { + return file_backuppb_Backup_proto_rawDescGZIP(), []int{17} +} + +func (x *ContactMessage) GetContact() *ContactAttachment { + if x != nil { + return x.Contact + } + return nil +} + +func (x *ContactMessage) GetReactions() []*Reaction { + if x != nil { + return x.Reactions + } + return nil +} + +type DirectStoryReplyMessage struct { + state protoimpl.MessageState `protogen:"open.v1"` + // Types that are valid to be assigned to Reply: + // + // *DirectStoryReplyMessage_TextReply_ + // *DirectStoryReplyMessage_Emoji + Reply isDirectStoryReplyMessage_Reply `protobuf_oneof:"reply"` + Reactions []*Reaction `protobuf:"bytes,3,rep,name=reactions,proto3" json:"reactions,omitempty"` + StorySentTimestamp *uint64 `protobuf:"varint,4,opt,name=storySentTimestamp,proto3,oneof" json:"storySentTimestamp,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *DirectStoryReplyMessage) Reset() { + *x = DirectStoryReplyMessage{} + mi := &file_backuppb_Backup_proto_msgTypes[18] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *DirectStoryReplyMessage) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*DirectStoryReplyMessage) ProtoMessage() {} + +func (x *DirectStoryReplyMessage) ProtoReflect() protoreflect.Message { + mi := &file_backuppb_Backup_proto_msgTypes[18] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use DirectStoryReplyMessage.ProtoReflect.Descriptor instead. +func (*DirectStoryReplyMessage) Descriptor() ([]byte, []int) { + return file_backuppb_Backup_proto_rawDescGZIP(), []int{18} +} + +func (x *DirectStoryReplyMessage) GetReply() isDirectStoryReplyMessage_Reply { + if x != nil { + return x.Reply + } + return nil +} + +func (x *DirectStoryReplyMessage) GetTextReply() *DirectStoryReplyMessage_TextReply { + if x != nil { + if x, ok := x.Reply.(*DirectStoryReplyMessage_TextReply_); ok { + return x.TextReply + } + } + return nil +} + +func (x *DirectStoryReplyMessage) GetEmoji() string { + if x != nil { + if x, ok := x.Reply.(*DirectStoryReplyMessage_Emoji); ok { + return x.Emoji + } + } + return "" +} + +func (x *DirectStoryReplyMessage) GetReactions() []*Reaction { + if x != nil { + return x.Reactions + } + return nil +} + +func (x *DirectStoryReplyMessage) GetStorySentTimestamp() uint64 { + if x != nil && x.StorySentTimestamp != nil { + return *x.StorySentTimestamp + } + return 0 +} + +type isDirectStoryReplyMessage_Reply interface { + isDirectStoryReplyMessage_Reply() +} + +type DirectStoryReplyMessage_TextReply_ struct { + TextReply *DirectStoryReplyMessage_TextReply `protobuf:"bytes,1,opt,name=textReply,proto3,oneof"` +} + +type DirectStoryReplyMessage_Emoji struct { + Emoji string `protobuf:"bytes,2,opt,name=emoji,proto3,oneof"` +} + +func (*DirectStoryReplyMessage_TextReply_) isDirectStoryReplyMessage_Reply() {} + +func (*DirectStoryReplyMessage_Emoji) isDirectStoryReplyMessage_Reply() {} + +type PaymentNotification struct { + state protoimpl.MessageState `protogen:"open.v1"` + AmountMob *string `protobuf:"bytes,1,opt,name=amountMob,proto3,oneof" json:"amountMob,omitempty"` // stored as a decimal string, e.g. 1.00001 + FeeMob *string `protobuf:"bytes,2,opt,name=feeMob,proto3,oneof" json:"feeMob,omitempty"` // stored as a decimal string, e.g. 1.00001 + Note *string `protobuf:"bytes,3,opt,name=note,proto3,oneof" json:"note,omitempty"` + TransactionDetails *PaymentNotification_TransactionDetails `protobuf:"bytes,4,opt,name=transactionDetails,proto3" json:"transactionDetails,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *PaymentNotification) Reset() { + *x = PaymentNotification{} + mi := &file_backuppb_Backup_proto_msgTypes[19] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *PaymentNotification) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*PaymentNotification) ProtoMessage() {} + +func (x *PaymentNotification) ProtoReflect() protoreflect.Message { + mi := &file_backuppb_Backup_proto_msgTypes[19] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use PaymentNotification.ProtoReflect.Descriptor instead. +func (*PaymentNotification) Descriptor() ([]byte, []int) { + return file_backuppb_Backup_proto_rawDescGZIP(), []int{19} +} + +func (x *PaymentNotification) GetAmountMob() string { + if x != nil && x.AmountMob != nil { + return *x.AmountMob + } + return "" +} + +func (x *PaymentNotification) GetFeeMob() string { + if x != nil && x.FeeMob != nil { + return *x.FeeMob + } + return "" +} + +func (x *PaymentNotification) GetNote() string { + if x != nil && x.Note != nil { + return *x.Note + } + return "" +} + +func (x *PaymentNotification) GetTransactionDetails() *PaymentNotification_TransactionDetails { + if x != nil { + return x.TransactionDetails + } + return nil +} + +type GiftBadge struct { + state protoimpl.MessageState `protogen:"open.v1"` + ReceiptCredentialPresentation []byte `protobuf:"bytes,1,opt,name=receiptCredentialPresentation,proto3" json:"receiptCredentialPresentation,omitempty"` + State GiftBadge_State `protobuf:"varint,2,opt,name=state,proto3,enum=signal.backup.GiftBadge_State" json:"state,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *GiftBadge) Reset() { + *x = GiftBadge{} + mi := &file_backuppb_Backup_proto_msgTypes[20] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *GiftBadge) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GiftBadge) ProtoMessage() {} + +func (x *GiftBadge) ProtoReflect() protoreflect.Message { + mi := &file_backuppb_Backup_proto_msgTypes[20] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GiftBadge.ProtoReflect.Descriptor instead. +func (*GiftBadge) Descriptor() ([]byte, []int) { + return file_backuppb_Backup_proto_rawDescGZIP(), []int{20} +} + +func (x *GiftBadge) GetReceiptCredentialPresentation() []byte { + if x != nil { + return x.ReceiptCredentialPresentation + } + return nil +} + +func (x *GiftBadge) GetState() GiftBadge_State { + if x != nil { + return x.State + } + return GiftBadge_UNOPENED +} + +type ViewOnceMessage struct { + state protoimpl.MessageState `protogen:"open.v1"` + // Will be null for viewed messages + Attachment *MessageAttachment `protobuf:"bytes,1,opt,name=attachment,proto3" json:"attachment,omitempty"` + Reactions []*Reaction `protobuf:"bytes,2,rep,name=reactions,proto3" json:"reactions,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ViewOnceMessage) Reset() { + *x = ViewOnceMessage{} + mi := &file_backuppb_Backup_proto_msgTypes[21] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ViewOnceMessage) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ViewOnceMessage) ProtoMessage() {} + +func (x *ViewOnceMessage) ProtoReflect() protoreflect.Message { + mi := &file_backuppb_Backup_proto_msgTypes[21] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ViewOnceMessage.ProtoReflect.Descriptor instead. +func (*ViewOnceMessage) Descriptor() ([]byte, []int) { + return file_backuppb_Backup_proto_rawDescGZIP(), []int{21} +} + +func (x *ViewOnceMessage) GetAttachment() *MessageAttachment { + if x != nil { + return x.Attachment + } + return nil +} + +func (x *ViewOnceMessage) GetReactions() []*Reaction { + if x != nil { + return x.Reactions + } + return nil +} + +type ContactAttachment struct { + state protoimpl.MessageState `protogen:"open.v1"` + Name *ContactAttachment_Name `protobuf:"bytes,1,opt,name=name,proto3,oneof" json:"name,omitempty"` + Number []*ContactAttachment_Phone `protobuf:"bytes,3,rep,name=number,proto3" json:"number,omitempty"` + Email []*ContactAttachment_Email `protobuf:"bytes,4,rep,name=email,proto3" json:"email,omitempty"` + Address []*ContactAttachment_PostalAddress `protobuf:"bytes,5,rep,name=address,proto3" json:"address,omitempty"` + Avatar *FilePointer `protobuf:"bytes,6,opt,name=avatar,proto3,oneof" json:"avatar,omitempty"` + Organization string `protobuf:"bytes,7,opt,name=organization,proto3" json:"organization,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ContactAttachment) Reset() { + *x = ContactAttachment{} + mi := &file_backuppb_Backup_proto_msgTypes[22] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ContactAttachment) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ContactAttachment) ProtoMessage() {} + +func (x *ContactAttachment) ProtoReflect() protoreflect.Message { + mi := &file_backuppb_Backup_proto_msgTypes[22] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ContactAttachment.ProtoReflect.Descriptor instead. +func (*ContactAttachment) Descriptor() ([]byte, []int) { + return file_backuppb_Backup_proto_rawDescGZIP(), []int{22} +} + +func (x *ContactAttachment) GetName() *ContactAttachment_Name { + if x != nil { + return x.Name + } + return nil +} + +func (x *ContactAttachment) GetNumber() []*ContactAttachment_Phone { + if x != nil { + return x.Number + } + return nil +} + +func (x *ContactAttachment) GetEmail() []*ContactAttachment_Email { + if x != nil { + return x.Email + } + return nil +} + +func (x *ContactAttachment) GetAddress() []*ContactAttachment_PostalAddress { + if x != nil { + return x.Address + } + return nil +} + +func (x *ContactAttachment) GetAvatar() *FilePointer { + if x != nil { + return x.Avatar + } + return nil +} + +func (x *ContactAttachment) GetOrganization() string { + if x != nil { + return x.Organization + } + return "" +} + +type StickerMessage struct { + state protoimpl.MessageState `protogen:"open.v1"` + Sticker *Sticker `protobuf:"bytes,1,opt,name=sticker,proto3" json:"sticker,omitempty"` + Reactions []*Reaction `protobuf:"bytes,2,rep,name=reactions,proto3" json:"reactions,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *StickerMessage) Reset() { + *x = StickerMessage{} + mi := &file_backuppb_Backup_proto_msgTypes[23] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *StickerMessage) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*StickerMessage) ProtoMessage() {} + +func (x *StickerMessage) ProtoReflect() protoreflect.Message { + mi := &file_backuppb_Backup_proto_msgTypes[23] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use StickerMessage.ProtoReflect.Descriptor instead. +func (*StickerMessage) Descriptor() ([]byte, []int) { + return file_backuppb_Backup_proto_rawDescGZIP(), []int{23} +} + +func (x *StickerMessage) GetSticker() *Sticker { + if x != nil { + return x.Sticker + } + return nil +} + +func (x *StickerMessage) GetReactions() []*Reaction { + if x != nil { + return x.Reactions + } + return nil +} + +// Tombstone for remote delete +type RemoteDeletedMessage struct { + state protoimpl.MessageState `protogen:"open.v1"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *RemoteDeletedMessage) Reset() { + *x = RemoteDeletedMessage{} + mi := &file_backuppb_Backup_proto_msgTypes[24] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *RemoteDeletedMessage) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*RemoteDeletedMessage) ProtoMessage() {} + +func (x *RemoteDeletedMessage) ProtoReflect() protoreflect.Message { + mi := &file_backuppb_Backup_proto_msgTypes[24] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use RemoteDeletedMessage.ProtoReflect.Descriptor instead. +func (*RemoteDeletedMessage) Descriptor() ([]byte, []int) { + return file_backuppb_Backup_proto_rawDescGZIP(), []int{24} +} + +type Sticker struct { + state protoimpl.MessageState `protogen:"open.v1"` + PackId []byte `protobuf:"bytes,1,opt,name=packId,proto3" json:"packId,omitempty"` + PackKey []byte `protobuf:"bytes,2,opt,name=packKey,proto3" json:"packKey,omitempty"` + StickerId uint32 `protobuf:"varint,3,opt,name=stickerId,proto3" json:"stickerId,omitempty"` + Emoji *string `protobuf:"bytes,4,opt,name=emoji,proto3,oneof" json:"emoji,omitempty"` + // Stickers are uploaded to be sent as attachments; we also + // back them up as normal attachments when they are in messages. + // DO NOT treat this as the definitive source of a sticker in + // an installed StickerPack that shares the same packId. + Data *FilePointer `protobuf:"bytes,5,opt,name=data,proto3" json:"data,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *Sticker) Reset() { + *x = Sticker{} + mi := &file_backuppb_Backup_proto_msgTypes[25] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *Sticker) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Sticker) ProtoMessage() {} + +func (x *Sticker) ProtoReflect() protoreflect.Message { + mi := &file_backuppb_Backup_proto_msgTypes[25] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Sticker.ProtoReflect.Descriptor instead. +func (*Sticker) Descriptor() ([]byte, []int) { + return file_backuppb_Backup_proto_rawDescGZIP(), []int{25} +} + +func (x *Sticker) GetPackId() []byte { + if x != nil { + return x.PackId + } + return nil +} + +func (x *Sticker) GetPackKey() []byte { + if x != nil { + return x.PackKey + } + return nil +} + +func (x *Sticker) GetStickerId() uint32 { + if x != nil { + return x.StickerId + } + return 0 +} + +func (x *Sticker) GetEmoji() string { + if x != nil && x.Emoji != nil { + return *x.Emoji + } + return "" +} + +func (x *Sticker) GetData() *FilePointer { + if x != nil { + return x.Data + } + return nil +} + +type LinkPreview struct { + state protoimpl.MessageState `protogen:"open.v1"` + Url string `protobuf:"bytes,1,opt,name=url,proto3" json:"url,omitempty"` + Title *string `protobuf:"bytes,2,opt,name=title,proto3,oneof" json:"title,omitempty"` + Image *FilePointer `protobuf:"bytes,3,opt,name=image,proto3,oneof" json:"image,omitempty"` + Description *string `protobuf:"bytes,4,opt,name=description,proto3,oneof" json:"description,omitempty"` + Date *uint64 `protobuf:"varint,5,opt,name=date,proto3,oneof" json:"date,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *LinkPreview) Reset() { + *x = LinkPreview{} + mi := &file_backuppb_Backup_proto_msgTypes[26] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *LinkPreview) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*LinkPreview) ProtoMessage() {} + +func (x *LinkPreview) ProtoReflect() protoreflect.Message { + mi := &file_backuppb_Backup_proto_msgTypes[26] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use LinkPreview.ProtoReflect.Descriptor instead. +func (*LinkPreview) Descriptor() ([]byte, []int) { + return file_backuppb_Backup_proto_rawDescGZIP(), []int{26} +} + +func (x *LinkPreview) GetUrl() string { + if x != nil { + return x.Url + } + return "" +} + +func (x *LinkPreview) GetTitle() string { + if x != nil && x.Title != nil { + return *x.Title + } + return "" +} + +func (x *LinkPreview) GetImage() *FilePointer { + if x != nil { + return x.Image + } + return nil +} + +func (x *LinkPreview) GetDescription() string { + if x != nil && x.Description != nil { + return *x.Description + } + return "" +} + +func (x *LinkPreview) GetDate() uint64 { + if x != nil && x.Date != nil { + return *x.Date + } + return 0 +} + +// A FilePointer on a message that has additional +// metadata that applies only to message attachments. +type MessageAttachment struct { + state protoimpl.MessageState `protogen:"open.v1"` + Pointer *FilePointer `protobuf:"bytes,1,opt,name=pointer,proto3" json:"pointer,omitempty"` + Flag MessageAttachment_Flag `protobuf:"varint,2,opt,name=flag,proto3,enum=signal.backup.MessageAttachment_Flag" json:"flag,omitempty"` + WasDownloaded bool `protobuf:"varint,3,opt,name=wasDownloaded,proto3" json:"wasDownloaded,omitempty"` + // Cross-client identifier for this attachment among all attachments on the + // owning message. See: SignalService.AttachmentPointer.clientUuid. + ClientUuid []byte `protobuf:"bytes,4,opt,name=clientUuid,proto3,oneof" json:"clientUuid,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *MessageAttachment) Reset() { + *x = MessageAttachment{} + mi := &file_backuppb_Backup_proto_msgTypes[27] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *MessageAttachment) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*MessageAttachment) ProtoMessage() {} + +func (x *MessageAttachment) ProtoReflect() protoreflect.Message { + mi := &file_backuppb_Backup_proto_msgTypes[27] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use MessageAttachment.ProtoReflect.Descriptor instead. +func (*MessageAttachment) Descriptor() ([]byte, []int) { + return file_backuppb_Backup_proto_rawDescGZIP(), []int{27} +} + +func (x *MessageAttachment) GetPointer() *FilePointer { + if x != nil { + return x.Pointer + } + return nil +} + +func (x *MessageAttachment) GetFlag() MessageAttachment_Flag { + if x != nil { + return x.Flag + } + return MessageAttachment_NONE +} + +func (x *MessageAttachment) GetWasDownloaded() bool { + if x != nil { + return x.WasDownloaded + } + return false +} + +func (x *MessageAttachment) GetClientUuid() []byte { + if x != nil { + return x.ClientUuid + } + return nil +} + +type FilePointer struct { + state protoimpl.MessageState `protogen:"open.v1"` + // Types that are valid to be assigned to Locator: + // + // *FilePointer_BackupLocator_ + // *FilePointer_AttachmentLocator_ + // *FilePointer_InvalidAttachmentLocator_ + Locator isFilePointer_Locator `protobuf_oneof:"locator"` + ContentType *string `protobuf:"bytes,4,opt,name=contentType,proto3,oneof" json:"contentType,omitempty"` + IncrementalMac []byte `protobuf:"bytes,5,opt,name=incrementalMac,proto3,oneof" json:"incrementalMac,omitempty"` + IncrementalMacChunkSize *uint32 `protobuf:"varint,6,opt,name=incrementalMacChunkSize,proto3,oneof" json:"incrementalMacChunkSize,omitempty"` + FileName *string `protobuf:"bytes,7,opt,name=fileName,proto3,oneof" json:"fileName,omitempty"` + Width *uint32 `protobuf:"varint,8,opt,name=width,proto3,oneof" json:"width,omitempty"` + Height *uint32 `protobuf:"varint,9,opt,name=height,proto3,oneof" json:"height,omitempty"` + Caption *string `protobuf:"bytes,10,opt,name=caption,proto3,oneof" json:"caption,omitempty"` + BlurHash *string `protobuf:"bytes,11,opt,name=blurHash,proto3,oneof" json:"blurHash,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *FilePointer) Reset() { + *x = FilePointer{} + mi := &file_backuppb_Backup_proto_msgTypes[28] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *FilePointer) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*FilePointer) ProtoMessage() {} + +func (x *FilePointer) ProtoReflect() protoreflect.Message { + mi := &file_backuppb_Backup_proto_msgTypes[28] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use FilePointer.ProtoReflect.Descriptor instead. +func (*FilePointer) Descriptor() ([]byte, []int) { + return file_backuppb_Backup_proto_rawDescGZIP(), []int{28} +} + +func (x *FilePointer) GetLocator() isFilePointer_Locator { + if x != nil { + return x.Locator + } + return nil +} + +func (x *FilePointer) GetBackupLocator() *FilePointer_BackupLocator { + if x != nil { + if x, ok := x.Locator.(*FilePointer_BackupLocator_); ok { + return x.BackupLocator + } + } + return nil +} + +func (x *FilePointer) GetAttachmentLocator() *FilePointer_AttachmentLocator { + if x != nil { + if x, ok := x.Locator.(*FilePointer_AttachmentLocator_); ok { + return x.AttachmentLocator + } + } + return nil +} + +func (x *FilePointer) GetInvalidAttachmentLocator() *FilePointer_InvalidAttachmentLocator { + if x != nil { + if x, ok := x.Locator.(*FilePointer_InvalidAttachmentLocator_); ok { + return x.InvalidAttachmentLocator + } + } + return nil +} + +func (x *FilePointer) GetContentType() string { + if x != nil && x.ContentType != nil { + return *x.ContentType + } + return "" +} + +func (x *FilePointer) GetIncrementalMac() []byte { + if x != nil { + return x.IncrementalMac + } + return nil +} + +func (x *FilePointer) GetIncrementalMacChunkSize() uint32 { + if x != nil && x.IncrementalMacChunkSize != nil { + return *x.IncrementalMacChunkSize + } + return 0 +} + +func (x *FilePointer) GetFileName() string { + if x != nil && x.FileName != nil { + return *x.FileName + } + return "" +} + +func (x *FilePointer) GetWidth() uint32 { + if x != nil && x.Width != nil { + return *x.Width + } + return 0 +} + +func (x *FilePointer) GetHeight() uint32 { + if x != nil && x.Height != nil { + return *x.Height + } + return 0 +} + +func (x *FilePointer) GetCaption() string { + if x != nil && x.Caption != nil { + return *x.Caption + } + return "" +} + +func (x *FilePointer) GetBlurHash() string { + if x != nil && x.BlurHash != nil { + return *x.BlurHash + } + return "" +} + +type isFilePointer_Locator interface { + isFilePointer_Locator() +} + +type FilePointer_BackupLocator_ struct { + BackupLocator *FilePointer_BackupLocator `protobuf:"bytes,1,opt,name=backupLocator,proto3,oneof"` +} + +type FilePointer_AttachmentLocator_ struct { + AttachmentLocator *FilePointer_AttachmentLocator `protobuf:"bytes,2,opt,name=attachmentLocator,proto3,oneof"` +} + +type FilePointer_InvalidAttachmentLocator_ struct { + InvalidAttachmentLocator *FilePointer_InvalidAttachmentLocator `protobuf:"bytes,3,opt,name=invalidAttachmentLocator,proto3,oneof"` +} + +func (*FilePointer_BackupLocator_) isFilePointer_Locator() {} + +func (*FilePointer_AttachmentLocator_) isFilePointer_Locator() {} + +func (*FilePointer_InvalidAttachmentLocator_) isFilePointer_Locator() {} + +type Quote struct { + state protoimpl.MessageState `protogen:"open.v1"` + TargetSentTimestamp *uint64 `protobuf:"varint,1,opt,name=targetSentTimestamp,proto3,oneof" json:"targetSentTimestamp,omitempty"` // null if the target message could not be found at time of quote insert + AuthorId uint64 `protobuf:"varint,2,opt,name=authorId,proto3" json:"authorId,omitempty"` + Text *Text `protobuf:"bytes,3,opt,name=text,proto3,oneof" json:"text,omitempty"` + Attachments []*Quote_QuotedAttachment `protobuf:"bytes,4,rep,name=attachments,proto3" json:"attachments,omitempty"` + Type Quote_Type `protobuf:"varint,5,opt,name=type,proto3,enum=signal.backup.Quote_Type" json:"type,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *Quote) Reset() { + *x = Quote{} + mi := &file_backuppb_Backup_proto_msgTypes[29] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *Quote) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Quote) ProtoMessage() {} + +func (x *Quote) ProtoReflect() protoreflect.Message { + mi := &file_backuppb_Backup_proto_msgTypes[29] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Quote.ProtoReflect.Descriptor instead. +func (*Quote) Descriptor() ([]byte, []int) { + return file_backuppb_Backup_proto_rawDescGZIP(), []int{29} +} + +func (x *Quote) GetTargetSentTimestamp() uint64 { + if x != nil && x.TargetSentTimestamp != nil { + return *x.TargetSentTimestamp + } + return 0 +} + +func (x *Quote) GetAuthorId() uint64 { + if x != nil { + return x.AuthorId + } + return 0 +} + +func (x *Quote) GetText() *Text { + if x != nil { + return x.Text + } + return nil +} + +func (x *Quote) GetAttachments() []*Quote_QuotedAttachment { + if x != nil { + return x.Attachments + } + return nil +} + +func (x *Quote) GetType() Quote_Type { + if x != nil { + return x.Type + } + return Quote_UNKNOWN +} + +type BodyRange struct { + state protoimpl.MessageState `protogen:"open.v1"` + Start *uint32 `protobuf:"varint,1,opt,name=start,proto3,oneof" json:"start,omitempty"` + Length *uint32 `protobuf:"varint,2,opt,name=length,proto3,oneof" json:"length,omitempty"` + // Types that are valid to be assigned to AssociatedValue: + // + // *BodyRange_MentionAci + // *BodyRange_Style_ + AssociatedValue isBodyRange_AssociatedValue `protobuf_oneof:"associatedValue"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *BodyRange) Reset() { + *x = BodyRange{} + mi := &file_backuppb_Backup_proto_msgTypes[30] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *BodyRange) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*BodyRange) ProtoMessage() {} + +func (x *BodyRange) ProtoReflect() protoreflect.Message { + mi := &file_backuppb_Backup_proto_msgTypes[30] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use BodyRange.ProtoReflect.Descriptor instead. +func (*BodyRange) Descriptor() ([]byte, []int) { + return file_backuppb_Backup_proto_rawDescGZIP(), []int{30} +} + +func (x *BodyRange) GetStart() uint32 { + if x != nil && x.Start != nil { + return *x.Start + } + return 0 +} + +func (x *BodyRange) GetLength() uint32 { + if x != nil && x.Length != nil { + return *x.Length + } + return 0 +} + +func (x *BodyRange) GetAssociatedValue() isBodyRange_AssociatedValue { + if x != nil { + return x.AssociatedValue + } + return nil +} + +func (x *BodyRange) GetMentionAci() []byte { + if x != nil { + if x, ok := x.AssociatedValue.(*BodyRange_MentionAci); ok { + return x.MentionAci + } + } + return nil +} + +func (x *BodyRange) GetStyle() BodyRange_Style { + if x != nil { + if x, ok := x.AssociatedValue.(*BodyRange_Style_); ok { + return x.Style + } + } + return BodyRange_NONE +} + +type isBodyRange_AssociatedValue interface { + isBodyRange_AssociatedValue() +} + +type BodyRange_MentionAci struct { + MentionAci []byte `protobuf:"bytes,3,opt,name=mentionAci,proto3,oneof"` +} + +type BodyRange_Style_ struct { + Style BodyRange_Style `protobuf:"varint,4,opt,name=style,proto3,enum=signal.backup.BodyRange_Style,oneof"` +} + +func (*BodyRange_MentionAci) isBodyRange_AssociatedValue() {} + +func (*BodyRange_Style_) isBodyRange_AssociatedValue() {} + +type Reaction struct { + state protoimpl.MessageState `protogen:"open.v1"` + Emoji string `protobuf:"bytes,1,opt,name=emoji,proto3" json:"emoji,omitempty"` + AuthorId uint64 `protobuf:"varint,2,opt,name=authorId,proto3" json:"authorId,omitempty"` + SentTimestamp uint64 `protobuf:"varint,3,opt,name=sentTimestamp,proto3" json:"sentTimestamp,omitempty"` + // A higher sort order means that a reaction is more recent. Some clients may export this as + // incrementing numbers (e.g. 1, 2, 3), others as timestamps. + SortOrder uint64 `protobuf:"varint,4,opt,name=sortOrder,proto3" json:"sortOrder,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *Reaction) Reset() { + *x = Reaction{} + mi := &file_backuppb_Backup_proto_msgTypes[31] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *Reaction) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Reaction) ProtoMessage() {} + +func (x *Reaction) ProtoReflect() protoreflect.Message { + mi := &file_backuppb_Backup_proto_msgTypes[31] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Reaction.ProtoReflect.Descriptor instead. +func (*Reaction) Descriptor() ([]byte, []int) { + return file_backuppb_Backup_proto_rawDescGZIP(), []int{31} +} + +func (x *Reaction) GetEmoji() string { + if x != nil { + return x.Emoji + } + return "" +} + +func (x *Reaction) GetAuthorId() uint64 { + if x != nil { + return x.AuthorId + } + return 0 +} + +func (x *Reaction) GetSentTimestamp() uint64 { + if x != nil { + return x.SentTimestamp + } + return 0 +} + +func (x *Reaction) GetSortOrder() uint64 { + if x != nil { + return x.SortOrder + } + return 0 +} + +type ChatUpdateMessage struct { + state protoimpl.MessageState `protogen:"open.v1"` + // Types that are valid to be assigned to Update: + // + // *ChatUpdateMessage_SimpleUpdate + // *ChatUpdateMessage_GroupChange + // *ChatUpdateMessage_ExpirationTimerChange + // *ChatUpdateMessage_ProfileChange + // *ChatUpdateMessage_ThreadMerge + // *ChatUpdateMessage_SessionSwitchover + // *ChatUpdateMessage_IndividualCall + // *ChatUpdateMessage_GroupCall + // *ChatUpdateMessage_LearnedProfileChange + Update isChatUpdateMessage_Update `protobuf_oneof:"update"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ChatUpdateMessage) Reset() { + *x = ChatUpdateMessage{} + mi := &file_backuppb_Backup_proto_msgTypes[32] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ChatUpdateMessage) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ChatUpdateMessage) ProtoMessage() {} + +func (x *ChatUpdateMessage) ProtoReflect() protoreflect.Message { + mi := &file_backuppb_Backup_proto_msgTypes[32] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ChatUpdateMessage.ProtoReflect.Descriptor instead. +func (*ChatUpdateMessage) Descriptor() ([]byte, []int) { + return file_backuppb_Backup_proto_rawDescGZIP(), []int{32} +} + +func (x *ChatUpdateMessage) GetUpdate() isChatUpdateMessage_Update { + if x != nil { + return x.Update + } + return nil +} + +func (x *ChatUpdateMessage) GetSimpleUpdate() *SimpleChatUpdate { + if x != nil { + if x, ok := x.Update.(*ChatUpdateMessage_SimpleUpdate); ok { + return x.SimpleUpdate + } + } + return nil +} + +func (x *ChatUpdateMessage) GetGroupChange() *GroupChangeChatUpdate { + if x != nil { + if x, ok := x.Update.(*ChatUpdateMessage_GroupChange); ok { + return x.GroupChange + } + } + return nil +} + +func (x *ChatUpdateMessage) GetExpirationTimerChange() *ExpirationTimerChatUpdate { + if x != nil { + if x, ok := x.Update.(*ChatUpdateMessage_ExpirationTimerChange); ok { + return x.ExpirationTimerChange + } + } + return nil +} + +func (x *ChatUpdateMessage) GetProfileChange() *ProfileChangeChatUpdate { + if x != nil { + if x, ok := x.Update.(*ChatUpdateMessage_ProfileChange); ok { + return x.ProfileChange + } + } + return nil +} + +func (x *ChatUpdateMessage) GetThreadMerge() *ThreadMergeChatUpdate { + if x != nil { + if x, ok := x.Update.(*ChatUpdateMessage_ThreadMerge); ok { + return x.ThreadMerge + } + } + return nil +} + +func (x *ChatUpdateMessage) GetSessionSwitchover() *SessionSwitchoverChatUpdate { + if x != nil { + if x, ok := x.Update.(*ChatUpdateMessage_SessionSwitchover); ok { + return x.SessionSwitchover + } + } + return nil +} + +func (x *ChatUpdateMessage) GetIndividualCall() *IndividualCall { + if x != nil { + if x, ok := x.Update.(*ChatUpdateMessage_IndividualCall); ok { + return x.IndividualCall + } + } + return nil +} + +func (x *ChatUpdateMessage) GetGroupCall() *GroupCall { + if x != nil { + if x, ok := x.Update.(*ChatUpdateMessage_GroupCall); ok { + return x.GroupCall + } + } + return nil +} + +func (x *ChatUpdateMessage) GetLearnedProfileChange() *LearnedProfileChatUpdate { + if x != nil { + if x, ok := x.Update.(*ChatUpdateMessage_LearnedProfileChange); ok { + return x.LearnedProfileChange + } + } + return nil +} + +type isChatUpdateMessage_Update interface { + isChatUpdateMessage_Update() +} + +type ChatUpdateMessage_SimpleUpdate struct { + SimpleUpdate *SimpleChatUpdate `protobuf:"bytes,1,opt,name=simpleUpdate,proto3,oneof"` +} + +type ChatUpdateMessage_GroupChange struct { + GroupChange *GroupChangeChatUpdate `protobuf:"bytes,2,opt,name=groupChange,proto3,oneof"` +} + +type ChatUpdateMessage_ExpirationTimerChange struct { + ExpirationTimerChange *ExpirationTimerChatUpdate `protobuf:"bytes,3,opt,name=expirationTimerChange,proto3,oneof"` +} + +type ChatUpdateMessage_ProfileChange struct { + ProfileChange *ProfileChangeChatUpdate `protobuf:"bytes,4,opt,name=profileChange,proto3,oneof"` +} + +type ChatUpdateMessage_ThreadMerge struct { + ThreadMerge *ThreadMergeChatUpdate `protobuf:"bytes,5,opt,name=threadMerge,proto3,oneof"` +} + +type ChatUpdateMessage_SessionSwitchover struct { + SessionSwitchover *SessionSwitchoverChatUpdate `protobuf:"bytes,6,opt,name=sessionSwitchover,proto3,oneof"` +} + +type ChatUpdateMessage_IndividualCall struct { + IndividualCall *IndividualCall `protobuf:"bytes,7,opt,name=individualCall,proto3,oneof"` +} + +type ChatUpdateMessage_GroupCall struct { + GroupCall *GroupCall `protobuf:"bytes,8,opt,name=groupCall,proto3,oneof"` +} + +type ChatUpdateMessage_LearnedProfileChange struct { + LearnedProfileChange *LearnedProfileChatUpdate `protobuf:"bytes,9,opt,name=learnedProfileChange,proto3,oneof"` +} + +func (*ChatUpdateMessage_SimpleUpdate) isChatUpdateMessage_Update() {} + +func (*ChatUpdateMessage_GroupChange) isChatUpdateMessage_Update() {} + +func (*ChatUpdateMessage_ExpirationTimerChange) isChatUpdateMessage_Update() {} + +func (*ChatUpdateMessage_ProfileChange) isChatUpdateMessage_Update() {} + +func (*ChatUpdateMessage_ThreadMerge) isChatUpdateMessage_Update() {} + +func (*ChatUpdateMessage_SessionSwitchover) isChatUpdateMessage_Update() {} + +func (*ChatUpdateMessage_IndividualCall) isChatUpdateMessage_Update() {} + +func (*ChatUpdateMessage_GroupCall) isChatUpdateMessage_Update() {} + +func (*ChatUpdateMessage_LearnedProfileChange) isChatUpdateMessage_Update() {} + +type IndividualCall struct { + state protoimpl.MessageState `protogen:"open.v1"` + CallId *uint64 `protobuf:"varint,1,opt,name=callId,proto3,oneof" json:"callId,omitempty"` + Type IndividualCall_Type `protobuf:"varint,2,opt,name=type,proto3,enum=signal.backup.IndividualCall_Type" json:"type,omitempty"` + Direction IndividualCall_Direction `protobuf:"varint,3,opt,name=direction,proto3,enum=signal.backup.IndividualCall_Direction" json:"direction,omitempty"` + State IndividualCall_State `protobuf:"varint,4,opt,name=state,proto3,enum=signal.backup.IndividualCall_State" json:"state,omitempty"` + StartedCallTimestamp uint64 `protobuf:"varint,5,opt,name=startedCallTimestamp,proto3" json:"startedCallTimestamp,omitempty"` + Read bool `protobuf:"varint,6,opt,name=read,proto3" json:"read,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *IndividualCall) Reset() { + *x = IndividualCall{} + mi := &file_backuppb_Backup_proto_msgTypes[33] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *IndividualCall) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*IndividualCall) ProtoMessage() {} + +func (x *IndividualCall) ProtoReflect() protoreflect.Message { + mi := &file_backuppb_Backup_proto_msgTypes[33] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use IndividualCall.ProtoReflect.Descriptor instead. +func (*IndividualCall) Descriptor() ([]byte, []int) { + return file_backuppb_Backup_proto_rawDescGZIP(), []int{33} +} + +func (x *IndividualCall) GetCallId() uint64 { + if x != nil && x.CallId != nil { + return *x.CallId + } + return 0 +} + +func (x *IndividualCall) GetType() IndividualCall_Type { + if x != nil { + return x.Type + } + return IndividualCall_UNKNOWN_TYPE +} + +func (x *IndividualCall) GetDirection() IndividualCall_Direction { + if x != nil { + return x.Direction + } + return IndividualCall_UNKNOWN_DIRECTION +} + +func (x *IndividualCall) GetState() IndividualCall_State { + if x != nil { + return x.State + } + return IndividualCall_UNKNOWN_STATE +} + +func (x *IndividualCall) GetStartedCallTimestamp() uint64 { + if x != nil { + return x.StartedCallTimestamp + } + return 0 +} + +func (x *IndividualCall) GetRead() bool { + if x != nil { + return x.Read + } + return false +} + +type GroupCall struct { + state protoimpl.MessageState `protogen:"open.v1"` + CallId *uint64 `protobuf:"varint,1,opt,name=callId,proto3,oneof" json:"callId,omitempty"` + State GroupCall_State `protobuf:"varint,2,opt,name=state,proto3,enum=signal.backup.GroupCall_State" json:"state,omitempty"` + RingerRecipientId *uint64 `protobuf:"varint,3,opt,name=ringerRecipientId,proto3,oneof" json:"ringerRecipientId,omitempty"` + StartedCallRecipientId *uint64 `protobuf:"varint,4,opt,name=startedCallRecipientId,proto3,oneof" json:"startedCallRecipientId,omitempty"` + StartedCallTimestamp uint64 `protobuf:"varint,5,opt,name=startedCallTimestamp,proto3" json:"startedCallTimestamp,omitempty"` + EndedCallTimestamp *uint64 `protobuf:"varint,6,opt,name=endedCallTimestamp,proto3,oneof" json:"endedCallTimestamp,omitempty"` // The time the call ended. + Read bool `protobuf:"varint,7,opt,name=read,proto3" json:"read,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *GroupCall) Reset() { + *x = GroupCall{} + mi := &file_backuppb_Backup_proto_msgTypes[34] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *GroupCall) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GroupCall) ProtoMessage() {} + +func (x *GroupCall) ProtoReflect() protoreflect.Message { + mi := &file_backuppb_Backup_proto_msgTypes[34] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GroupCall.ProtoReflect.Descriptor instead. +func (*GroupCall) Descriptor() ([]byte, []int) { + return file_backuppb_Backup_proto_rawDescGZIP(), []int{34} +} + +func (x *GroupCall) GetCallId() uint64 { + if x != nil && x.CallId != nil { + return *x.CallId + } + return 0 +} + +func (x *GroupCall) GetState() GroupCall_State { + if x != nil { + return x.State + } + return GroupCall_UNKNOWN_STATE +} + +func (x *GroupCall) GetRingerRecipientId() uint64 { + if x != nil && x.RingerRecipientId != nil { + return *x.RingerRecipientId + } + return 0 +} + +func (x *GroupCall) GetStartedCallRecipientId() uint64 { + if x != nil && x.StartedCallRecipientId != nil { + return *x.StartedCallRecipientId + } + return 0 +} + +func (x *GroupCall) GetStartedCallTimestamp() uint64 { + if x != nil { + return x.StartedCallTimestamp + } + return 0 +} + +func (x *GroupCall) GetEndedCallTimestamp() uint64 { + if x != nil && x.EndedCallTimestamp != nil { + return *x.EndedCallTimestamp + } + return 0 +} + +func (x *GroupCall) GetRead() bool { + if x != nil { + return x.Read + } + return false +} + +type SimpleChatUpdate struct { + state protoimpl.MessageState `protogen:"open.v1"` + Type SimpleChatUpdate_Type `protobuf:"varint,1,opt,name=type,proto3,enum=signal.backup.SimpleChatUpdate_Type" json:"type,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *SimpleChatUpdate) Reset() { + *x = SimpleChatUpdate{} + mi := &file_backuppb_Backup_proto_msgTypes[35] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *SimpleChatUpdate) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SimpleChatUpdate) ProtoMessage() {} + +func (x *SimpleChatUpdate) ProtoReflect() protoreflect.Message { + mi := &file_backuppb_Backup_proto_msgTypes[35] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use SimpleChatUpdate.ProtoReflect.Descriptor instead. +func (*SimpleChatUpdate) Descriptor() ([]byte, []int) { + return file_backuppb_Backup_proto_rawDescGZIP(), []int{35} +} + +func (x *SimpleChatUpdate) GetType() SimpleChatUpdate_Type { + if x != nil { + return x.Type + } + return SimpleChatUpdate_UNKNOWN +} + +// For 1:1 chat updates only. +// For group thread updates use GroupExpirationTimerUpdate. +type ExpirationTimerChatUpdate struct { + state protoimpl.MessageState `protogen:"open.v1"` + ExpiresInMs uint64 `protobuf:"varint,1,opt,name=expiresInMs,proto3" json:"expiresInMs,omitempty"` // 0 means the expiration timer was disabled + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ExpirationTimerChatUpdate) Reset() { + *x = ExpirationTimerChatUpdate{} + mi := &file_backuppb_Backup_proto_msgTypes[36] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ExpirationTimerChatUpdate) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ExpirationTimerChatUpdate) ProtoMessage() {} + +func (x *ExpirationTimerChatUpdate) ProtoReflect() protoreflect.Message { + mi := &file_backuppb_Backup_proto_msgTypes[36] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ExpirationTimerChatUpdate.ProtoReflect.Descriptor instead. +func (*ExpirationTimerChatUpdate) Descriptor() ([]byte, []int) { + return file_backuppb_Backup_proto_rawDescGZIP(), []int{36} +} + +func (x *ExpirationTimerChatUpdate) GetExpiresInMs() uint64 { + if x != nil { + return x.ExpiresInMs + } + return 0 +} + +type ProfileChangeChatUpdate struct { + state protoimpl.MessageState `protogen:"open.v1"` + PreviousName string `protobuf:"bytes,1,opt,name=previousName,proto3" json:"previousName,omitempty"` + NewName string `protobuf:"bytes,2,opt,name=newName,proto3" json:"newName,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ProfileChangeChatUpdate) Reset() { + *x = ProfileChangeChatUpdate{} + mi := &file_backuppb_Backup_proto_msgTypes[37] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ProfileChangeChatUpdate) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ProfileChangeChatUpdate) ProtoMessage() {} + +func (x *ProfileChangeChatUpdate) ProtoReflect() protoreflect.Message { + mi := &file_backuppb_Backup_proto_msgTypes[37] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ProfileChangeChatUpdate.ProtoReflect.Descriptor instead. +func (*ProfileChangeChatUpdate) Descriptor() ([]byte, []int) { + return file_backuppb_Backup_proto_rawDescGZIP(), []int{37} +} + +func (x *ProfileChangeChatUpdate) GetPreviousName() string { + if x != nil { + return x.PreviousName + } + return "" +} + +func (x *ProfileChangeChatUpdate) GetNewName() string { + if x != nil { + return x.NewName + } + return "" +} + +type LearnedProfileChatUpdate struct { + state protoimpl.MessageState `protogen:"open.v1"` + // Types that are valid to be assigned to PreviousName: + // + // *LearnedProfileChatUpdate_E164 + // *LearnedProfileChatUpdate_Username + PreviousName isLearnedProfileChatUpdate_PreviousName `protobuf_oneof:"previousName"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *LearnedProfileChatUpdate) Reset() { + *x = LearnedProfileChatUpdate{} + mi := &file_backuppb_Backup_proto_msgTypes[38] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *LearnedProfileChatUpdate) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*LearnedProfileChatUpdate) ProtoMessage() {} + +func (x *LearnedProfileChatUpdate) ProtoReflect() protoreflect.Message { + mi := &file_backuppb_Backup_proto_msgTypes[38] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use LearnedProfileChatUpdate.ProtoReflect.Descriptor instead. +func (*LearnedProfileChatUpdate) Descriptor() ([]byte, []int) { + return file_backuppb_Backup_proto_rawDescGZIP(), []int{38} +} + +func (x *LearnedProfileChatUpdate) GetPreviousName() isLearnedProfileChatUpdate_PreviousName { + if x != nil { + return x.PreviousName + } + return nil +} + +func (x *LearnedProfileChatUpdate) GetE164() uint64 { + if x != nil { + if x, ok := x.PreviousName.(*LearnedProfileChatUpdate_E164); ok { + return x.E164 + } + } + return 0 +} + +func (x *LearnedProfileChatUpdate) GetUsername() string { + if x != nil { + if x, ok := x.PreviousName.(*LearnedProfileChatUpdate_Username); ok { + return x.Username + } + } + return "" +} + +type isLearnedProfileChatUpdate_PreviousName interface { + isLearnedProfileChatUpdate_PreviousName() +} + +type LearnedProfileChatUpdate_E164 struct { + E164 uint64 `protobuf:"varint,1,opt,name=e164,proto3,oneof"` +} + +type LearnedProfileChatUpdate_Username struct { + Username string `protobuf:"bytes,2,opt,name=username,proto3,oneof"` +} + +func (*LearnedProfileChatUpdate_E164) isLearnedProfileChatUpdate_PreviousName() {} + +func (*LearnedProfileChatUpdate_Username) isLearnedProfileChatUpdate_PreviousName() {} + +type ThreadMergeChatUpdate struct { + state protoimpl.MessageState `protogen:"open.v1"` + PreviousE164 uint64 `protobuf:"varint,1,opt,name=previousE164,proto3" json:"previousE164,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ThreadMergeChatUpdate) Reset() { + *x = ThreadMergeChatUpdate{} + mi := &file_backuppb_Backup_proto_msgTypes[39] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ThreadMergeChatUpdate) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ThreadMergeChatUpdate) ProtoMessage() {} + +func (x *ThreadMergeChatUpdate) ProtoReflect() protoreflect.Message { + mi := &file_backuppb_Backup_proto_msgTypes[39] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ThreadMergeChatUpdate.ProtoReflect.Descriptor instead. +func (*ThreadMergeChatUpdate) Descriptor() ([]byte, []int) { + return file_backuppb_Backup_proto_rawDescGZIP(), []int{39} +} + +func (x *ThreadMergeChatUpdate) GetPreviousE164() uint64 { + if x != nil { + return x.PreviousE164 + } + return 0 +} + +type SessionSwitchoverChatUpdate struct { + state protoimpl.MessageState `protogen:"open.v1"` + E164 uint64 `protobuf:"varint,1,opt,name=e164,proto3" json:"e164,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *SessionSwitchoverChatUpdate) Reset() { + *x = SessionSwitchoverChatUpdate{} + mi := &file_backuppb_Backup_proto_msgTypes[40] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *SessionSwitchoverChatUpdate) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SessionSwitchoverChatUpdate) ProtoMessage() {} + +func (x *SessionSwitchoverChatUpdate) ProtoReflect() protoreflect.Message { + mi := &file_backuppb_Backup_proto_msgTypes[40] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use SessionSwitchoverChatUpdate.ProtoReflect.Descriptor instead. +func (*SessionSwitchoverChatUpdate) Descriptor() ([]byte, []int) { + return file_backuppb_Backup_proto_rawDescGZIP(), []int{40} +} + +func (x *SessionSwitchoverChatUpdate) GetE164() uint64 { + if x != nil { + return x.E164 + } + return 0 +} + +type GroupChangeChatUpdate struct { + state protoimpl.MessageState `protogen:"open.v1"` + // Must be one or more; all updates batched together came from + // a single batched group state update. + Updates []*GroupChangeChatUpdate_Update `protobuf:"bytes,1,rep,name=updates,proto3" json:"updates,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *GroupChangeChatUpdate) Reset() { + *x = GroupChangeChatUpdate{} + mi := &file_backuppb_Backup_proto_msgTypes[41] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *GroupChangeChatUpdate) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GroupChangeChatUpdate) ProtoMessage() {} + +func (x *GroupChangeChatUpdate) ProtoReflect() protoreflect.Message { + mi := &file_backuppb_Backup_proto_msgTypes[41] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GroupChangeChatUpdate.ProtoReflect.Descriptor instead. +func (*GroupChangeChatUpdate) Descriptor() ([]byte, []int) { + return file_backuppb_Backup_proto_rawDescGZIP(), []int{41} +} + +func (x *GroupChangeChatUpdate) GetUpdates() []*GroupChangeChatUpdate_Update { + if x != nil { + return x.Updates + } + return nil +} + +type GenericGroupUpdate struct { + state protoimpl.MessageState `protogen:"open.v1"` + UpdaterAci []byte `protobuf:"bytes,1,opt,name=updaterAci,proto3,oneof" json:"updaterAci,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *GenericGroupUpdate) Reset() { + *x = GenericGroupUpdate{} + mi := &file_backuppb_Backup_proto_msgTypes[42] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *GenericGroupUpdate) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GenericGroupUpdate) ProtoMessage() {} + +func (x *GenericGroupUpdate) ProtoReflect() protoreflect.Message { + mi := &file_backuppb_Backup_proto_msgTypes[42] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GenericGroupUpdate.ProtoReflect.Descriptor instead. +func (*GenericGroupUpdate) Descriptor() ([]byte, []int) { + return file_backuppb_Backup_proto_rawDescGZIP(), []int{42} +} + +func (x *GenericGroupUpdate) GetUpdaterAci() []byte { + if x != nil { + return x.UpdaterAci + } + return nil +} + +type GroupCreationUpdate struct { + state protoimpl.MessageState `protogen:"open.v1"` + UpdaterAci []byte `protobuf:"bytes,1,opt,name=updaterAci,proto3,oneof" json:"updaterAci,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *GroupCreationUpdate) Reset() { + *x = GroupCreationUpdate{} + mi := &file_backuppb_Backup_proto_msgTypes[43] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *GroupCreationUpdate) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GroupCreationUpdate) ProtoMessage() {} + +func (x *GroupCreationUpdate) ProtoReflect() protoreflect.Message { + mi := &file_backuppb_Backup_proto_msgTypes[43] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GroupCreationUpdate.ProtoReflect.Descriptor instead. +func (*GroupCreationUpdate) Descriptor() ([]byte, []int) { + return file_backuppb_Backup_proto_rawDescGZIP(), []int{43} +} + +func (x *GroupCreationUpdate) GetUpdaterAci() []byte { + if x != nil { + return x.UpdaterAci + } + return nil +} + +type GroupNameUpdate struct { + state protoimpl.MessageState `protogen:"open.v1"` + UpdaterAci []byte `protobuf:"bytes,1,opt,name=updaterAci,proto3,oneof" json:"updaterAci,omitempty"` + // Null value means the group name was removed. + NewGroupName *string `protobuf:"bytes,2,opt,name=newGroupName,proto3,oneof" json:"newGroupName,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *GroupNameUpdate) Reset() { + *x = GroupNameUpdate{} + mi := &file_backuppb_Backup_proto_msgTypes[44] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *GroupNameUpdate) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GroupNameUpdate) ProtoMessage() {} + +func (x *GroupNameUpdate) ProtoReflect() protoreflect.Message { + mi := &file_backuppb_Backup_proto_msgTypes[44] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GroupNameUpdate.ProtoReflect.Descriptor instead. +func (*GroupNameUpdate) Descriptor() ([]byte, []int) { + return file_backuppb_Backup_proto_rawDescGZIP(), []int{44} +} + +func (x *GroupNameUpdate) GetUpdaterAci() []byte { + if x != nil { + return x.UpdaterAci + } + return nil +} + +func (x *GroupNameUpdate) GetNewGroupName() string { + if x != nil && x.NewGroupName != nil { + return *x.NewGroupName + } + return "" +} + +type GroupAvatarUpdate struct { + state protoimpl.MessageState `protogen:"open.v1"` + UpdaterAci []byte `protobuf:"bytes,1,opt,name=updaterAci,proto3,oneof" json:"updaterAci,omitempty"` + WasRemoved bool `protobuf:"varint,2,opt,name=wasRemoved,proto3" json:"wasRemoved,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *GroupAvatarUpdate) Reset() { + *x = GroupAvatarUpdate{} + mi := &file_backuppb_Backup_proto_msgTypes[45] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *GroupAvatarUpdate) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GroupAvatarUpdate) ProtoMessage() {} + +func (x *GroupAvatarUpdate) ProtoReflect() protoreflect.Message { + mi := &file_backuppb_Backup_proto_msgTypes[45] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GroupAvatarUpdate.ProtoReflect.Descriptor instead. +func (*GroupAvatarUpdate) Descriptor() ([]byte, []int) { + return file_backuppb_Backup_proto_rawDescGZIP(), []int{45} +} + +func (x *GroupAvatarUpdate) GetUpdaterAci() []byte { + if x != nil { + return x.UpdaterAci + } + return nil +} + +func (x *GroupAvatarUpdate) GetWasRemoved() bool { + if x != nil { + return x.WasRemoved + } + return false +} + +type GroupDescriptionUpdate struct { + state protoimpl.MessageState `protogen:"open.v1"` + UpdaterAci []byte `protobuf:"bytes,1,opt,name=updaterAci,proto3,oneof" json:"updaterAci,omitempty"` + // Null value means the group description was removed. + NewDescription *string `protobuf:"bytes,2,opt,name=newDescription,proto3,oneof" json:"newDescription,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *GroupDescriptionUpdate) Reset() { + *x = GroupDescriptionUpdate{} + mi := &file_backuppb_Backup_proto_msgTypes[46] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *GroupDescriptionUpdate) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GroupDescriptionUpdate) ProtoMessage() {} + +func (x *GroupDescriptionUpdate) ProtoReflect() protoreflect.Message { + mi := &file_backuppb_Backup_proto_msgTypes[46] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GroupDescriptionUpdate.ProtoReflect.Descriptor instead. +func (*GroupDescriptionUpdate) Descriptor() ([]byte, []int) { + return file_backuppb_Backup_proto_rawDescGZIP(), []int{46} +} + +func (x *GroupDescriptionUpdate) GetUpdaterAci() []byte { + if x != nil { + return x.UpdaterAci + } + return nil +} + +func (x *GroupDescriptionUpdate) GetNewDescription() string { + if x != nil && x.NewDescription != nil { + return *x.NewDescription + } + return "" +} + +type GroupMembershipAccessLevelChangeUpdate struct { + state protoimpl.MessageState `protogen:"open.v1"` + UpdaterAci []byte `protobuf:"bytes,1,opt,name=updaterAci,proto3,oneof" json:"updaterAci,omitempty"` + AccessLevel GroupV2AccessLevel `protobuf:"varint,2,opt,name=accessLevel,proto3,enum=signal.backup.GroupV2AccessLevel" json:"accessLevel,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *GroupMembershipAccessLevelChangeUpdate) Reset() { + *x = GroupMembershipAccessLevelChangeUpdate{} + mi := &file_backuppb_Backup_proto_msgTypes[47] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *GroupMembershipAccessLevelChangeUpdate) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GroupMembershipAccessLevelChangeUpdate) ProtoMessage() {} + +func (x *GroupMembershipAccessLevelChangeUpdate) ProtoReflect() protoreflect.Message { + mi := &file_backuppb_Backup_proto_msgTypes[47] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GroupMembershipAccessLevelChangeUpdate.ProtoReflect.Descriptor instead. +func (*GroupMembershipAccessLevelChangeUpdate) Descriptor() ([]byte, []int) { + return file_backuppb_Backup_proto_rawDescGZIP(), []int{47} +} + +func (x *GroupMembershipAccessLevelChangeUpdate) GetUpdaterAci() []byte { + if x != nil { + return x.UpdaterAci + } + return nil +} + +func (x *GroupMembershipAccessLevelChangeUpdate) GetAccessLevel() GroupV2AccessLevel { + if x != nil { + return x.AccessLevel + } + return GroupV2AccessLevel_UNKNOWN +} + +type GroupAttributesAccessLevelChangeUpdate struct { + state protoimpl.MessageState `protogen:"open.v1"` + UpdaterAci []byte `protobuf:"bytes,1,opt,name=updaterAci,proto3,oneof" json:"updaterAci,omitempty"` + AccessLevel GroupV2AccessLevel `protobuf:"varint,2,opt,name=accessLevel,proto3,enum=signal.backup.GroupV2AccessLevel" json:"accessLevel,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *GroupAttributesAccessLevelChangeUpdate) Reset() { + *x = GroupAttributesAccessLevelChangeUpdate{} + mi := &file_backuppb_Backup_proto_msgTypes[48] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *GroupAttributesAccessLevelChangeUpdate) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GroupAttributesAccessLevelChangeUpdate) ProtoMessage() {} + +func (x *GroupAttributesAccessLevelChangeUpdate) ProtoReflect() protoreflect.Message { + mi := &file_backuppb_Backup_proto_msgTypes[48] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GroupAttributesAccessLevelChangeUpdate.ProtoReflect.Descriptor instead. +func (*GroupAttributesAccessLevelChangeUpdate) Descriptor() ([]byte, []int) { + return file_backuppb_Backup_proto_rawDescGZIP(), []int{48} +} + +func (x *GroupAttributesAccessLevelChangeUpdate) GetUpdaterAci() []byte { + if x != nil { + return x.UpdaterAci + } + return nil +} + +func (x *GroupAttributesAccessLevelChangeUpdate) GetAccessLevel() GroupV2AccessLevel { + if x != nil { + return x.AccessLevel + } + return GroupV2AccessLevel_UNKNOWN +} + +type GroupAnnouncementOnlyChangeUpdate struct { + state protoimpl.MessageState `protogen:"open.v1"` + UpdaterAci []byte `protobuf:"bytes,1,opt,name=updaterAci,proto3,oneof" json:"updaterAci,omitempty"` + IsAnnouncementOnly bool `protobuf:"varint,2,opt,name=isAnnouncementOnly,proto3" json:"isAnnouncementOnly,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *GroupAnnouncementOnlyChangeUpdate) Reset() { + *x = GroupAnnouncementOnlyChangeUpdate{} + mi := &file_backuppb_Backup_proto_msgTypes[49] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *GroupAnnouncementOnlyChangeUpdate) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GroupAnnouncementOnlyChangeUpdate) ProtoMessage() {} + +func (x *GroupAnnouncementOnlyChangeUpdate) ProtoReflect() protoreflect.Message { + mi := &file_backuppb_Backup_proto_msgTypes[49] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GroupAnnouncementOnlyChangeUpdate.ProtoReflect.Descriptor instead. +func (*GroupAnnouncementOnlyChangeUpdate) Descriptor() ([]byte, []int) { + return file_backuppb_Backup_proto_rawDescGZIP(), []int{49} +} + +func (x *GroupAnnouncementOnlyChangeUpdate) GetUpdaterAci() []byte { + if x != nil { + return x.UpdaterAci + } + return nil +} + +func (x *GroupAnnouncementOnlyChangeUpdate) GetIsAnnouncementOnly() bool { + if x != nil { + return x.IsAnnouncementOnly + } + return false +} + +type GroupAdminStatusUpdate struct { + state protoimpl.MessageState `protogen:"open.v1"` + UpdaterAci []byte `protobuf:"bytes,1,opt,name=updaterAci,proto3,oneof" json:"updaterAci,omitempty"` + // The aci who had admin status granted or revoked. + MemberAci []byte `protobuf:"bytes,2,opt,name=memberAci,proto3" json:"memberAci,omitempty"` + WasAdminStatusGranted bool `protobuf:"varint,3,opt,name=wasAdminStatusGranted,proto3" json:"wasAdminStatusGranted,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *GroupAdminStatusUpdate) Reset() { + *x = GroupAdminStatusUpdate{} + mi := &file_backuppb_Backup_proto_msgTypes[50] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *GroupAdminStatusUpdate) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GroupAdminStatusUpdate) ProtoMessage() {} + +func (x *GroupAdminStatusUpdate) ProtoReflect() protoreflect.Message { + mi := &file_backuppb_Backup_proto_msgTypes[50] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GroupAdminStatusUpdate.ProtoReflect.Descriptor instead. +func (*GroupAdminStatusUpdate) Descriptor() ([]byte, []int) { + return file_backuppb_Backup_proto_rawDescGZIP(), []int{50} +} + +func (x *GroupAdminStatusUpdate) GetUpdaterAci() []byte { + if x != nil { + return x.UpdaterAci + } + return nil +} + +func (x *GroupAdminStatusUpdate) GetMemberAci() []byte { + if x != nil { + return x.MemberAci + } + return nil +} + +func (x *GroupAdminStatusUpdate) GetWasAdminStatusGranted() bool { + if x != nil { + return x.WasAdminStatusGranted + } + return false +} + +type GroupMemberLeftUpdate struct { + state protoimpl.MessageState `protogen:"open.v1"` + Aci []byte `protobuf:"bytes,1,opt,name=aci,proto3" json:"aci,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *GroupMemberLeftUpdate) Reset() { + *x = GroupMemberLeftUpdate{} + mi := &file_backuppb_Backup_proto_msgTypes[51] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *GroupMemberLeftUpdate) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GroupMemberLeftUpdate) ProtoMessage() {} + +func (x *GroupMemberLeftUpdate) ProtoReflect() protoreflect.Message { + mi := &file_backuppb_Backup_proto_msgTypes[51] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GroupMemberLeftUpdate.ProtoReflect.Descriptor instead. +func (*GroupMemberLeftUpdate) Descriptor() ([]byte, []int) { + return file_backuppb_Backup_proto_rawDescGZIP(), []int{51} +} + +func (x *GroupMemberLeftUpdate) GetAci() []byte { + if x != nil { + return x.Aci + } + return nil +} + +type GroupMemberRemovedUpdate struct { + state protoimpl.MessageState `protogen:"open.v1"` + RemoverAci []byte `protobuf:"bytes,1,opt,name=removerAci,proto3,oneof" json:"removerAci,omitempty"` + RemovedAci []byte `protobuf:"bytes,2,opt,name=removedAci,proto3" json:"removedAci,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *GroupMemberRemovedUpdate) Reset() { + *x = GroupMemberRemovedUpdate{} + mi := &file_backuppb_Backup_proto_msgTypes[52] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *GroupMemberRemovedUpdate) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GroupMemberRemovedUpdate) ProtoMessage() {} + +func (x *GroupMemberRemovedUpdate) ProtoReflect() protoreflect.Message { + mi := &file_backuppb_Backup_proto_msgTypes[52] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GroupMemberRemovedUpdate.ProtoReflect.Descriptor instead. +func (*GroupMemberRemovedUpdate) Descriptor() ([]byte, []int) { + return file_backuppb_Backup_proto_rawDescGZIP(), []int{52} +} + +func (x *GroupMemberRemovedUpdate) GetRemoverAci() []byte { + if x != nil { + return x.RemoverAci + } + return nil +} + +func (x *GroupMemberRemovedUpdate) GetRemovedAci() []byte { + if x != nil { + return x.RemovedAci + } + return nil +} + +type SelfInvitedToGroupUpdate struct { + state protoimpl.MessageState `protogen:"open.v1"` + InviterAci []byte `protobuf:"bytes,1,opt,name=inviterAci,proto3,oneof" json:"inviterAci,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *SelfInvitedToGroupUpdate) Reset() { + *x = SelfInvitedToGroupUpdate{} + mi := &file_backuppb_Backup_proto_msgTypes[53] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *SelfInvitedToGroupUpdate) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SelfInvitedToGroupUpdate) ProtoMessage() {} + +func (x *SelfInvitedToGroupUpdate) ProtoReflect() protoreflect.Message { + mi := &file_backuppb_Backup_proto_msgTypes[53] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use SelfInvitedToGroupUpdate.ProtoReflect.Descriptor instead. +func (*SelfInvitedToGroupUpdate) Descriptor() ([]byte, []int) { + return file_backuppb_Backup_proto_rawDescGZIP(), []int{53} +} + +func (x *SelfInvitedToGroupUpdate) GetInviterAci() []byte { + if x != nil { + return x.InviterAci + } + return nil +} + +type SelfInvitedOtherUserToGroupUpdate struct { + state protoimpl.MessageState `protogen:"open.v1"` + // If no invitee id available, use GroupUnknownInviteeUpdate + InviteeServiceId []byte `protobuf:"bytes,1,opt,name=inviteeServiceId,proto3" json:"inviteeServiceId,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *SelfInvitedOtherUserToGroupUpdate) Reset() { + *x = SelfInvitedOtherUserToGroupUpdate{} + mi := &file_backuppb_Backup_proto_msgTypes[54] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *SelfInvitedOtherUserToGroupUpdate) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SelfInvitedOtherUserToGroupUpdate) ProtoMessage() {} + +func (x *SelfInvitedOtherUserToGroupUpdate) ProtoReflect() protoreflect.Message { + mi := &file_backuppb_Backup_proto_msgTypes[54] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use SelfInvitedOtherUserToGroupUpdate.ProtoReflect.Descriptor instead. +func (*SelfInvitedOtherUserToGroupUpdate) Descriptor() ([]byte, []int) { + return file_backuppb_Backup_proto_rawDescGZIP(), []int{54} +} + +func (x *SelfInvitedOtherUserToGroupUpdate) GetInviteeServiceId() []byte { + if x != nil { + return x.InviteeServiceId + } + return nil +} + +type GroupUnknownInviteeUpdate struct { + state protoimpl.MessageState `protogen:"open.v1"` + // Can be the self user. + InviterAci []byte `protobuf:"bytes,1,opt,name=inviterAci,proto3,oneof" json:"inviterAci,omitempty"` + InviteeCount uint32 `protobuf:"varint,2,opt,name=inviteeCount,proto3" json:"inviteeCount,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *GroupUnknownInviteeUpdate) Reset() { + *x = GroupUnknownInviteeUpdate{} + mi := &file_backuppb_Backup_proto_msgTypes[55] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *GroupUnknownInviteeUpdate) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GroupUnknownInviteeUpdate) ProtoMessage() {} + +func (x *GroupUnknownInviteeUpdate) ProtoReflect() protoreflect.Message { + mi := &file_backuppb_Backup_proto_msgTypes[55] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GroupUnknownInviteeUpdate.ProtoReflect.Descriptor instead. +func (*GroupUnknownInviteeUpdate) Descriptor() ([]byte, []int) { + return file_backuppb_Backup_proto_rawDescGZIP(), []int{55} +} + +func (x *GroupUnknownInviteeUpdate) GetInviterAci() []byte { + if x != nil { + return x.InviterAci + } + return nil +} + +func (x *GroupUnknownInviteeUpdate) GetInviteeCount() uint32 { + if x != nil { + return x.InviteeCount + } + return 0 +} + +type GroupInvitationAcceptedUpdate struct { + state protoimpl.MessageState `protogen:"open.v1"` + InviterAci []byte `protobuf:"bytes,1,opt,name=inviterAci,proto3,oneof" json:"inviterAci,omitempty"` + NewMemberAci []byte `protobuf:"bytes,2,opt,name=newMemberAci,proto3" json:"newMemberAci,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *GroupInvitationAcceptedUpdate) Reset() { + *x = GroupInvitationAcceptedUpdate{} + mi := &file_backuppb_Backup_proto_msgTypes[56] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *GroupInvitationAcceptedUpdate) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GroupInvitationAcceptedUpdate) ProtoMessage() {} + +func (x *GroupInvitationAcceptedUpdate) ProtoReflect() protoreflect.Message { + mi := &file_backuppb_Backup_proto_msgTypes[56] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GroupInvitationAcceptedUpdate.ProtoReflect.Descriptor instead. +func (*GroupInvitationAcceptedUpdate) Descriptor() ([]byte, []int) { + return file_backuppb_Backup_proto_rawDescGZIP(), []int{56} +} + +func (x *GroupInvitationAcceptedUpdate) GetInviterAci() []byte { + if x != nil { + return x.InviterAci + } + return nil +} + +func (x *GroupInvitationAcceptedUpdate) GetNewMemberAci() []byte { + if x != nil { + return x.NewMemberAci + } + return nil +} + +type GroupInvitationDeclinedUpdate struct { + state protoimpl.MessageState `protogen:"open.v1"` + InviterAci []byte `protobuf:"bytes,1,opt,name=inviterAci,proto3,oneof" json:"inviterAci,omitempty"` + // Note: if invited by pni, just set inviteeAci to nil. + InviteeAci []byte `protobuf:"bytes,2,opt,name=inviteeAci,proto3,oneof" json:"inviteeAci,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *GroupInvitationDeclinedUpdate) Reset() { + *x = GroupInvitationDeclinedUpdate{} + mi := &file_backuppb_Backup_proto_msgTypes[57] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *GroupInvitationDeclinedUpdate) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GroupInvitationDeclinedUpdate) ProtoMessage() {} + +func (x *GroupInvitationDeclinedUpdate) ProtoReflect() protoreflect.Message { + mi := &file_backuppb_Backup_proto_msgTypes[57] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GroupInvitationDeclinedUpdate.ProtoReflect.Descriptor instead. +func (*GroupInvitationDeclinedUpdate) Descriptor() ([]byte, []int) { + return file_backuppb_Backup_proto_rawDescGZIP(), []int{57} +} + +func (x *GroupInvitationDeclinedUpdate) GetInviterAci() []byte { + if x != nil { + return x.InviterAci + } + return nil +} + +func (x *GroupInvitationDeclinedUpdate) GetInviteeAci() []byte { + if x != nil { + return x.InviteeAci + } + return nil +} + +type GroupMemberJoinedUpdate struct { + state protoimpl.MessageState `protogen:"open.v1"` + NewMemberAci []byte `protobuf:"bytes,1,opt,name=newMemberAci,proto3" json:"newMemberAci,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *GroupMemberJoinedUpdate) Reset() { + *x = GroupMemberJoinedUpdate{} + mi := &file_backuppb_Backup_proto_msgTypes[58] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *GroupMemberJoinedUpdate) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GroupMemberJoinedUpdate) ProtoMessage() {} + +func (x *GroupMemberJoinedUpdate) ProtoReflect() protoreflect.Message { + mi := &file_backuppb_Backup_proto_msgTypes[58] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GroupMemberJoinedUpdate.ProtoReflect.Descriptor instead. +func (*GroupMemberJoinedUpdate) Descriptor() ([]byte, []int) { + return file_backuppb_Backup_proto_rawDescGZIP(), []int{58} +} + +func (x *GroupMemberJoinedUpdate) GetNewMemberAci() []byte { + if x != nil { + return x.NewMemberAci + } + return nil +} + +type GroupMemberAddedUpdate struct { + state protoimpl.MessageState `protogen:"open.v1"` + UpdaterAci []byte `protobuf:"bytes,1,opt,name=updaterAci,proto3,oneof" json:"updaterAci,omitempty"` + NewMemberAci []byte `protobuf:"bytes,2,opt,name=newMemberAci,proto3" json:"newMemberAci,omitempty"` + HadOpenInvitation bool `protobuf:"varint,3,opt,name=hadOpenInvitation,proto3" json:"hadOpenInvitation,omitempty"` + // If hadOpenInvitation is true, optionally include aci of the inviter. + InviterAci []byte `protobuf:"bytes,4,opt,name=inviterAci,proto3,oneof" json:"inviterAci,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *GroupMemberAddedUpdate) Reset() { + *x = GroupMemberAddedUpdate{} + mi := &file_backuppb_Backup_proto_msgTypes[59] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *GroupMemberAddedUpdate) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GroupMemberAddedUpdate) ProtoMessage() {} + +func (x *GroupMemberAddedUpdate) ProtoReflect() protoreflect.Message { + mi := &file_backuppb_Backup_proto_msgTypes[59] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GroupMemberAddedUpdate.ProtoReflect.Descriptor instead. +func (*GroupMemberAddedUpdate) Descriptor() ([]byte, []int) { + return file_backuppb_Backup_proto_rawDescGZIP(), []int{59} +} + +func (x *GroupMemberAddedUpdate) GetUpdaterAci() []byte { + if x != nil { + return x.UpdaterAci + } + return nil +} + +func (x *GroupMemberAddedUpdate) GetNewMemberAci() []byte { + if x != nil { + return x.NewMemberAci + } + return nil +} + +func (x *GroupMemberAddedUpdate) GetHadOpenInvitation() bool { + if x != nil { + return x.HadOpenInvitation + } + return false +} + +func (x *GroupMemberAddedUpdate) GetInviterAci() []byte { + if x != nil { + return x.InviterAci + } + return nil +} + +// An invitation to self was revoked. +type GroupSelfInvitationRevokedUpdate struct { + state protoimpl.MessageState `protogen:"open.v1"` + RevokerAci []byte `protobuf:"bytes,1,opt,name=revokerAci,proto3,oneof" json:"revokerAci,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *GroupSelfInvitationRevokedUpdate) Reset() { + *x = GroupSelfInvitationRevokedUpdate{} + mi := &file_backuppb_Backup_proto_msgTypes[60] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *GroupSelfInvitationRevokedUpdate) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GroupSelfInvitationRevokedUpdate) ProtoMessage() {} + +func (x *GroupSelfInvitationRevokedUpdate) ProtoReflect() protoreflect.Message { + mi := &file_backuppb_Backup_proto_msgTypes[60] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GroupSelfInvitationRevokedUpdate.ProtoReflect.Descriptor instead. +func (*GroupSelfInvitationRevokedUpdate) Descriptor() ([]byte, []int) { + return file_backuppb_Backup_proto_rawDescGZIP(), []int{60} +} + +func (x *GroupSelfInvitationRevokedUpdate) GetRevokerAci() []byte { + if x != nil { + return x.RevokerAci + } + return nil +} + +// These invitees should never be the local user. +// Use GroupSelfInvitationRevokedUpdate in those cases. +// The inviter or updater can be the local user. +type GroupInvitationRevokedUpdate struct { + state protoimpl.MessageState `protogen:"open.v1"` + // The member that revoked the invite(s), not the inviter! + // Assumed to be an admin (at the time, may no longer be an + // admin or even a member). + UpdaterAci []byte `protobuf:"bytes,1,opt,name=updaterAci,proto3,oneof" json:"updaterAci,omitempty"` + Invitees []*GroupInvitationRevokedUpdate_Invitee `protobuf:"bytes,2,rep,name=invitees,proto3" json:"invitees,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *GroupInvitationRevokedUpdate) Reset() { + *x = GroupInvitationRevokedUpdate{} + mi := &file_backuppb_Backup_proto_msgTypes[61] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *GroupInvitationRevokedUpdate) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GroupInvitationRevokedUpdate) ProtoMessage() {} + +func (x *GroupInvitationRevokedUpdate) ProtoReflect() protoreflect.Message { + mi := &file_backuppb_Backup_proto_msgTypes[61] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GroupInvitationRevokedUpdate.ProtoReflect.Descriptor instead. +func (*GroupInvitationRevokedUpdate) Descriptor() ([]byte, []int) { + return file_backuppb_Backup_proto_rawDescGZIP(), []int{61} +} + +func (x *GroupInvitationRevokedUpdate) GetUpdaterAci() []byte { + if x != nil { + return x.UpdaterAci + } + return nil +} + +func (x *GroupInvitationRevokedUpdate) GetInvitees() []*GroupInvitationRevokedUpdate_Invitee { + if x != nil { + return x.Invitees + } + return nil +} + +type GroupJoinRequestUpdate struct { + state protoimpl.MessageState `protogen:"open.v1"` + RequestorAci []byte `protobuf:"bytes,1,opt,name=requestorAci,proto3" json:"requestorAci,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *GroupJoinRequestUpdate) Reset() { + *x = GroupJoinRequestUpdate{} + mi := &file_backuppb_Backup_proto_msgTypes[62] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *GroupJoinRequestUpdate) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GroupJoinRequestUpdate) ProtoMessage() {} + +func (x *GroupJoinRequestUpdate) ProtoReflect() protoreflect.Message { + mi := &file_backuppb_Backup_proto_msgTypes[62] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GroupJoinRequestUpdate.ProtoReflect.Descriptor instead. +func (*GroupJoinRequestUpdate) Descriptor() ([]byte, []int) { + return file_backuppb_Backup_proto_rawDescGZIP(), []int{62} +} + +func (x *GroupJoinRequestUpdate) GetRequestorAci() []byte { + if x != nil { + return x.RequestorAci + } + return nil +} + +type GroupJoinRequestApprovalUpdate struct { + state protoimpl.MessageState `protogen:"open.v1"` + RequestorAci []byte `protobuf:"bytes,1,opt,name=requestorAci,proto3" json:"requestorAci,omitempty"` + // The aci that approved or rejected the request. + UpdaterAci []byte `protobuf:"bytes,2,opt,name=updaterAci,proto3,oneof" json:"updaterAci,omitempty"` + WasApproved bool `protobuf:"varint,3,opt,name=wasApproved,proto3" json:"wasApproved,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *GroupJoinRequestApprovalUpdate) Reset() { + *x = GroupJoinRequestApprovalUpdate{} + mi := &file_backuppb_Backup_proto_msgTypes[63] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *GroupJoinRequestApprovalUpdate) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GroupJoinRequestApprovalUpdate) ProtoMessage() {} + +func (x *GroupJoinRequestApprovalUpdate) ProtoReflect() protoreflect.Message { + mi := &file_backuppb_Backup_proto_msgTypes[63] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GroupJoinRequestApprovalUpdate.ProtoReflect.Descriptor instead. +func (*GroupJoinRequestApprovalUpdate) Descriptor() ([]byte, []int) { + return file_backuppb_Backup_proto_rawDescGZIP(), []int{63} +} + +func (x *GroupJoinRequestApprovalUpdate) GetRequestorAci() []byte { + if x != nil { + return x.RequestorAci + } + return nil +} + +func (x *GroupJoinRequestApprovalUpdate) GetUpdaterAci() []byte { + if x != nil { + return x.UpdaterAci + } + return nil +} + +func (x *GroupJoinRequestApprovalUpdate) GetWasApproved() bool { + if x != nil { + return x.WasApproved + } + return false +} + +type GroupJoinRequestCanceledUpdate struct { + state protoimpl.MessageState `protogen:"open.v1"` + RequestorAci []byte `protobuf:"bytes,1,opt,name=requestorAci,proto3" json:"requestorAci,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *GroupJoinRequestCanceledUpdate) Reset() { + *x = GroupJoinRequestCanceledUpdate{} + mi := &file_backuppb_Backup_proto_msgTypes[64] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *GroupJoinRequestCanceledUpdate) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GroupJoinRequestCanceledUpdate) ProtoMessage() {} + +func (x *GroupJoinRequestCanceledUpdate) ProtoReflect() protoreflect.Message { + mi := &file_backuppb_Backup_proto_msgTypes[64] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GroupJoinRequestCanceledUpdate.ProtoReflect.Descriptor instead. +func (*GroupJoinRequestCanceledUpdate) Descriptor() ([]byte, []int) { + return file_backuppb_Backup_proto_rawDescGZIP(), []int{64} +} + +func (x *GroupJoinRequestCanceledUpdate) GetRequestorAci() []byte { + if x != nil { + return x.RequestorAci + } + return nil +} + +// A single requestor has requested to join and cancelled +// their request repeatedly with no other updates in between. +// The last action encompassed by this update is always a +// cancellation; if there was another open request immediately +// after, it will be a separate GroupJoinRequestUpdate, either +// in the same frame or in a subsequent frame. +type GroupSequenceOfRequestsAndCancelsUpdate struct { + state protoimpl.MessageState `protogen:"open.v1"` + RequestorAci []byte `protobuf:"bytes,1,opt,name=requestorAci,proto3" json:"requestorAci,omitempty"` + Count uint32 `protobuf:"varint,2,opt,name=count,proto3" json:"count,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *GroupSequenceOfRequestsAndCancelsUpdate) Reset() { + *x = GroupSequenceOfRequestsAndCancelsUpdate{} + mi := &file_backuppb_Backup_proto_msgTypes[65] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *GroupSequenceOfRequestsAndCancelsUpdate) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GroupSequenceOfRequestsAndCancelsUpdate) ProtoMessage() {} + +func (x *GroupSequenceOfRequestsAndCancelsUpdate) ProtoReflect() protoreflect.Message { + mi := &file_backuppb_Backup_proto_msgTypes[65] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GroupSequenceOfRequestsAndCancelsUpdate.ProtoReflect.Descriptor instead. +func (*GroupSequenceOfRequestsAndCancelsUpdate) Descriptor() ([]byte, []int) { + return file_backuppb_Backup_proto_rawDescGZIP(), []int{65} +} + +func (x *GroupSequenceOfRequestsAndCancelsUpdate) GetRequestorAci() []byte { + if x != nil { + return x.RequestorAci + } + return nil +} + +func (x *GroupSequenceOfRequestsAndCancelsUpdate) GetCount() uint32 { + if x != nil { + return x.Count + } + return 0 +} + +type GroupInviteLinkResetUpdate struct { + state protoimpl.MessageState `protogen:"open.v1"` + UpdaterAci []byte `protobuf:"bytes,1,opt,name=updaterAci,proto3,oneof" json:"updaterAci,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *GroupInviteLinkResetUpdate) Reset() { + *x = GroupInviteLinkResetUpdate{} + mi := &file_backuppb_Backup_proto_msgTypes[66] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *GroupInviteLinkResetUpdate) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GroupInviteLinkResetUpdate) ProtoMessage() {} + +func (x *GroupInviteLinkResetUpdate) ProtoReflect() protoreflect.Message { + mi := &file_backuppb_Backup_proto_msgTypes[66] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GroupInviteLinkResetUpdate.ProtoReflect.Descriptor instead. +func (*GroupInviteLinkResetUpdate) Descriptor() ([]byte, []int) { + return file_backuppb_Backup_proto_rawDescGZIP(), []int{66} +} + +func (x *GroupInviteLinkResetUpdate) GetUpdaterAci() []byte { + if x != nil { + return x.UpdaterAci + } + return nil +} + +type GroupInviteLinkEnabledUpdate struct { + state protoimpl.MessageState `protogen:"open.v1"` + UpdaterAci []byte `protobuf:"bytes,1,opt,name=updaterAci,proto3,oneof" json:"updaterAci,omitempty"` + LinkRequiresAdminApproval bool `protobuf:"varint,2,opt,name=linkRequiresAdminApproval,proto3" json:"linkRequiresAdminApproval,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *GroupInviteLinkEnabledUpdate) Reset() { + *x = GroupInviteLinkEnabledUpdate{} + mi := &file_backuppb_Backup_proto_msgTypes[67] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *GroupInviteLinkEnabledUpdate) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GroupInviteLinkEnabledUpdate) ProtoMessage() {} + +func (x *GroupInviteLinkEnabledUpdate) ProtoReflect() protoreflect.Message { + mi := &file_backuppb_Backup_proto_msgTypes[67] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GroupInviteLinkEnabledUpdate.ProtoReflect.Descriptor instead. +func (*GroupInviteLinkEnabledUpdate) Descriptor() ([]byte, []int) { + return file_backuppb_Backup_proto_rawDescGZIP(), []int{67} +} + +func (x *GroupInviteLinkEnabledUpdate) GetUpdaterAci() []byte { + if x != nil { + return x.UpdaterAci + } + return nil +} + +func (x *GroupInviteLinkEnabledUpdate) GetLinkRequiresAdminApproval() bool { + if x != nil { + return x.LinkRequiresAdminApproval + } + return false +} + +type GroupInviteLinkAdminApprovalUpdate struct { + state protoimpl.MessageState `protogen:"open.v1"` + UpdaterAci []byte `protobuf:"bytes,1,opt,name=updaterAci,proto3,oneof" json:"updaterAci,omitempty"` + LinkRequiresAdminApproval bool `protobuf:"varint,2,opt,name=linkRequiresAdminApproval,proto3" json:"linkRequiresAdminApproval,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *GroupInviteLinkAdminApprovalUpdate) Reset() { + *x = GroupInviteLinkAdminApprovalUpdate{} + mi := &file_backuppb_Backup_proto_msgTypes[68] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *GroupInviteLinkAdminApprovalUpdate) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GroupInviteLinkAdminApprovalUpdate) ProtoMessage() {} + +func (x *GroupInviteLinkAdminApprovalUpdate) ProtoReflect() protoreflect.Message { + mi := &file_backuppb_Backup_proto_msgTypes[68] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GroupInviteLinkAdminApprovalUpdate.ProtoReflect.Descriptor instead. +func (*GroupInviteLinkAdminApprovalUpdate) Descriptor() ([]byte, []int) { + return file_backuppb_Backup_proto_rawDescGZIP(), []int{68} +} + +func (x *GroupInviteLinkAdminApprovalUpdate) GetUpdaterAci() []byte { + if x != nil { + return x.UpdaterAci + } + return nil +} + +func (x *GroupInviteLinkAdminApprovalUpdate) GetLinkRequiresAdminApproval() bool { + if x != nil { + return x.LinkRequiresAdminApproval + } + return false +} + +type GroupInviteLinkDisabledUpdate struct { + state protoimpl.MessageState `protogen:"open.v1"` + UpdaterAci []byte `protobuf:"bytes,1,opt,name=updaterAci,proto3,oneof" json:"updaterAci,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *GroupInviteLinkDisabledUpdate) Reset() { + *x = GroupInviteLinkDisabledUpdate{} + mi := &file_backuppb_Backup_proto_msgTypes[69] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *GroupInviteLinkDisabledUpdate) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GroupInviteLinkDisabledUpdate) ProtoMessage() {} + +func (x *GroupInviteLinkDisabledUpdate) ProtoReflect() protoreflect.Message { + mi := &file_backuppb_Backup_proto_msgTypes[69] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GroupInviteLinkDisabledUpdate.ProtoReflect.Descriptor instead. +func (*GroupInviteLinkDisabledUpdate) Descriptor() ([]byte, []int) { + return file_backuppb_Backup_proto_rawDescGZIP(), []int{69} +} + +func (x *GroupInviteLinkDisabledUpdate) GetUpdaterAci() []byte { + if x != nil { + return x.UpdaterAci + } + return nil +} + +type GroupMemberJoinedByLinkUpdate struct { + state protoimpl.MessageState `protogen:"open.v1"` + NewMemberAci []byte `protobuf:"bytes,1,opt,name=newMemberAci,proto3" json:"newMemberAci,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *GroupMemberJoinedByLinkUpdate) Reset() { + *x = GroupMemberJoinedByLinkUpdate{} + mi := &file_backuppb_Backup_proto_msgTypes[70] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *GroupMemberJoinedByLinkUpdate) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GroupMemberJoinedByLinkUpdate) ProtoMessage() {} + +func (x *GroupMemberJoinedByLinkUpdate) ProtoReflect() protoreflect.Message { + mi := &file_backuppb_Backup_proto_msgTypes[70] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GroupMemberJoinedByLinkUpdate.ProtoReflect.Descriptor instead. +func (*GroupMemberJoinedByLinkUpdate) Descriptor() ([]byte, []int) { + return file_backuppb_Backup_proto_rawDescGZIP(), []int{70} +} + +func (x *GroupMemberJoinedByLinkUpdate) GetNewMemberAci() []byte { + if x != nil { + return x.NewMemberAci + } + return nil +} + +// A gv1->gv2 migration occurred. +type GroupV2MigrationUpdate struct { + state protoimpl.MessageState `protogen:"open.v1"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *GroupV2MigrationUpdate) Reset() { + *x = GroupV2MigrationUpdate{} + mi := &file_backuppb_Backup_proto_msgTypes[71] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *GroupV2MigrationUpdate) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GroupV2MigrationUpdate) ProtoMessage() {} + +func (x *GroupV2MigrationUpdate) ProtoReflect() protoreflect.Message { + mi := &file_backuppb_Backup_proto_msgTypes[71] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GroupV2MigrationUpdate.ProtoReflect.Descriptor instead. +func (*GroupV2MigrationUpdate) Descriptor() ([]byte, []int) { + return file_backuppb_Backup_proto_rawDescGZIP(), []int{71} +} + +// Another user migrated gv1->gv2 but was unable to add +// the local user and invited them instead. +type GroupV2MigrationSelfInvitedUpdate struct { + state protoimpl.MessageState `protogen:"open.v1"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *GroupV2MigrationSelfInvitedUpdate) Reset() { + *x = GroupV2MigrationSelfInvitedUpdate{} + mi := &file_backuppb_Backup_proto_msgTypes[72] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *GroupV2MigrationSelfInvitedUpdate) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GroupV2MigrationSelfInvitedUpdate) ProtoMessage() {} + +func (x *GroupV2MigrationSelfInvitedUpdate) ProtoReflect() protoreflect.Message { + mi := &file_backuppb_Backup_proto_msgTypes[72] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GroupV2MigrationSelfInvitedUpdate.ProtoReflect.Descriptor instead. +func (*GroupV2MigrationSelfInvitedUpdate) Descriptor() ([]byte, []int) { + return file_backuppb_Backup_proto_rawDescGZIP(), []int{72} +} + +// The local user migrated gv1->gv2 but was unable to +// add some members and invited them instead. +// (Happens if we don't have the invitee's profile key) +type GroupV2MigrationInvitedMembersUpdate struct { + state protoimpl.MessageState `protogen:"open.v1"` + InvitedMembersCount uint32 `protobuf:"varint,1,opt,name=invitedMembersCount,proto3" json:"invitedMembersCount,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *GroupV2MigrationInvitedMembersUpdate) Reset() { + *x = GroupV2MigrationInvitedMembersUpdate{} + mi := &file_backuppb_Backup_proto_msgTypes[73] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *GroupV2MigrationInvitedMembersUpdate) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GroupV2MigrationInvitedMembersUpdate) ProtoMessage() {} + +func (x *GroupV2MigrationInvitedMembersUpdate) ProtoReflect() protoreflect.Message { + mi := &file_backuppb_Backup_proto_msgTypes[73] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GroupV2MigrationInvitedMembersUpdate.ProtoReflect.Descriptor instead. +func (*GroupV2MigrationInvitedMembersUpdate) Descriptor() ([]byte, []int) { + return file_backuppb_Backup_proto_rawDescGZIP(), []int{73} +} + +func (x *GroupV2MigrationInvitedMembersUpdate) GetInvitedMembersCount() uint32 { + if x != nil { + return x.InvitedMembersCount + } + return 0 +} + +// The local user migrated gv1->gv2 but was unable to +// add or invite some members and dropped them instead. +// (Happens for e164 members where we don't have an aci). +type GroupV2MigrationDroppedMembersUpdate struct { + state protoimpl.MessageState `protogen:"open.v1"` + DroppedMembersCount uint32 `protobuf:"varint,1,opt,name=droppedMembersCount,proto3" json:"droppedMembersCount,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *GroupV2MigrationDroppedMembersUpdate) Reset() { + *x = GroupV2MigrationDroppedMembersUpdate{} + mi := &file_backuppb_Backup_proto_msgTypes[74] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *GroupV2MigrationDroppedMembersUpdate) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GroupV2MigrationDroppedMembersUpdate) ProtoMessage() {} + +func (x *GroupV2MigrationDroppedMembersUpdate) ProtoReflect() protoreflect.Message { + mi := &file_backuppb_Backup_proto_msgTypes[74] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GroupV2MigrationDroppedMembersUpdate.ProtoReflect.Descriptor instead. +func (*GroupV2MigrationDroppedMembersUpdate) Descriptor() ([]byte, []int) { + return file_backuppb_Backup_proto_rawDescGZIP(), []int{74} +} + +func (x *GroupV2MigrationDroppedMembersUpdate) GetDroppedMembersCount() uint32 { + if x != nil { + return x.DroppedMembersCount + } + return 0 +} + +// For 1:1 timer updates, use ExpirationTimerChatUpdate. +type GroupExpirationTimerUpdate struct { + state protoimpl.MessageState `protogen:"open.v1"` + ExpiresInMs uint64 `protobuf:"varint,1,opt,name=expiresInMs,proto3" json:"expiresInMs,omitempty"` // 0 means the expiration timer was disabled + UpdaterAci []byte `protobuf:"bytes,2,opt,name=updaterAci,proto3,oneof" json:"updaterAci,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *GroupExpirationTimerUpdate) Reset() { + *x = GroupExpirationTimerUpdate{} + mi := &file_backuppb_Backup_proto_msgTypes[75] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *GroupExpirationTimerUpdate) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GroupExpirationTimerUpdate) ProtoMessage() {} + +func (x *GroupExpirationTimerUpdate) ProtoReflect() protoreflect.Message { + mi := &file_backuppb_Backup_proto_msgTypes[75] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GroupExpirationTimerUpdate.ProtoReflect.Descriptor instead. +func (*GroupExpirationTimerUpdate) Descriptor() ([]byte, []int) { + return file_backuppb_Backup_proto_rawDescGZIP(), []int{75} +} + +func (x *GroupExpirationTimerUpdate) GetExpiresInMs() uint64 { + if x != nil { + return x.ExpiresInMs + } + return 0 +} + +func (x *GroupExpirationTimerUpdate) GetUpdaterAci() []byte { + if x != nil { + return x.UpdaterAci + } + return nil +} + +type StickerPack struct { + state protoimpl.MessageState `protogen:"open.v1"` + PackId []byte `protobuf:"bytes,1,opt,name=packId,proto3" json:"packId,omitempty"` + PackKey []byte `protobuf:"bytes,2,opt,name=packKey,proto3" json:"packKey,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *StickerPack) Reset() { + *x = StickerPack{} + mi := &file_backuppb_Backup_proto_msgTypes[76] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *StickerPack) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*StickerPack) ProtoMessage() {} + +func (x *StickerPack) ProtoReflect() protoreflect.Message { + mi := &file_backuppb_Backup_proto_msgTypes[76] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use StickerPack.ProtoReflect.Descriptor instead. +func (*StickerPack) Descriptor() ([]byte, []int) { + return file_backuppb_Backup_proto_rawDescGZIP(), []int{76} +} + +func (x *StickerPack) GetPackId() []byte { + if x != nil { + return x.PackId + } + return nil +} + +func (x *StickerPack) GetPackKey() []byte { + if x != nil { + return x.PackKey + } + return nil +} + +type ChatStyle struct { + state protoimpl.MessageState `protogen:"open.v1"` + // Types that are valid to be assigned to Wallpaper: + // + // *ChatStyle_WallpaperPreset_ + // *ChatStyle_WallpaperPhoto + Wallpaper isChatStyle_Wallpaper `protobuf_oneof:"wallpaper"` + // Types that are valid to be assigned to BubbleColor: + // + // *ChatStyle_AutoBubbleColor + // *ChatStyle_BubbleColorPreset_ + // *ChatStyle_CustomColorId + BubbleColor isChatStyle_BubbleColor `protobuf_oneof:"bubbleColor"` + DimWallpaperInDarkMode bool `protobuf:"varint,7,opt,name=dimWallpaperInDarkMode,proto3" json:"dimWallpaperInDarkMode,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ChatStyle) Reset() { + *x = ChatStyle{} + mi := &file_backuppb_Backup_proto_msgTypes[77] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ChatStyle) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ChatStyle) ProtoMessage() {} + +func (x *ChatStyle) ProtoReflect() protoreflect.Message { + mi := &file_backuppb_Backup_proto_msgTypes[77] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ChatStyle.ProtoReflect.Descriptor instead. +func (*ChatStyle) Descriptor() ([]byte, []int) { + return file_backuppb_Backup_proto_rawDescGZIP(), []int{77} +} + +func (x *ChatStyle) GetWallpaper() isChatStyle_Wallpaper { + if x != nil { + return x.Wallpaper + } + return nil +} + +func (x *ChatStyle) GetWallpaperPreset() ChatStyle_WallpaperPreset { + if x != nil { + if x, ok := x.Wallpaper.(*ChatStyle_WallpaperPreset_); ok { + return x.WallpaperPreset + } + } + return ChatStyle_UNKNOWN_WALLPAPER_PRESET +} + +func (x *ChatStyle) GetWallpaperPhoto() *FilePointer { + if x != nil { + if x, ok := x.Wallpaper.(*ChatStyle_WallpaperPhoto); ok { + return x.WallpaperPhoto + } + } + return nil +} + +func (x *ChatStyle) GetBubbleColor() isChatStyle_BubbleColor { + if x != nil { + return x.BubbleColor + } + return nil +} + +func (x *ChatStyle) GetAutoBubbleColor() *ChatStyle_AutomaticBubbleColor { + if x != nil { + if x, ok := x.BubbleColor.(*ChatStyle_AutoBubbleColor); ok { + return x.AutoBubbleColor + } + } + return nil +} + +func (x *ChatStyle) GetBubbleColorPreset() ChatStyle_BubbleColorPreset { + if x != nil { + if x, ok := x.BubbleColor.(*ChatStyle_BubbleColorPreset_); ok { + return x.BubbleColorPreset + } + } + return ChatStyle_UNKNOWN_BUBBLE_COLOR_PRESET +} + +func (x *ChatStyle) GetCustomColorId() uint64 { + if x != nil { + if x, ok := x.BubbleColor.(*ChatStyle_CustomColorId); ok { + return x.CustomColorId + } + } + return 0 +} + +func (x *ChatStyle) GetDimWallpaperInDarkMode() bool { + if x != nil { + return x.DimWallpaperInDarkMode + } + return false +} + +type isChatStyle_Wallpaper interface { + isChatStyle_Wallpaper() +} + +type ChatStyle_WallpaperPreset_ struct { + WallpaperPreset ChatStyle_WallpaperPreset `protobuf:"varint,1,opt,name=wallpaperPreset,proto3,enum=signal.backup.ChatStyle_WallpaperPreset,oneof"` +} + +type ChatStyle_WallpaperPhoto struct { + // This `FilePointer` is expected not to contain a `fileName`, `width`, + // `height`, or `caption`. + WallpaperPhoto *FilePointer `protobuf:"bytes,2,opt,name=wallpaperPhoto,proto3,oneof"` +} + +func (*ChatStyle_WallpaperPreset_) isChatStyle_Wallpaper() {} + +func (*ChatStyle_WallpaperPhoto) isChatStyle_Wallpaper() {} + +type isChatStyle_BubbleColor interface { + isChatStyle_BubbleColor() +} + +type ChatStyle_AutoBubbleColor struct { + // Bubble setting is automatically determined based on the wallpaper setting, + // or `SOLID_ULTRAMARINE` for `noWallpaper` + AutoBubbleColor *ChatStyle_AutomaticBubbleColor `protobuf:"bytes,3,opt,name=autoBubbleColor,proto3,oneof"` +} + +type ChatStyle_BubbleColorPreset_ struct { + BubbleColorPreset ChatStyle_BubbleColorPreset `protobuf:"varint,4,opt,name=bubbleColorPreset,proto3,enum=signal.backup.ChatStyle_BubbleColorPreset,oneof"` +} + +type ChatStyle_CustomColorId struct { + // See AccountSettings.customChatColors + CustomColorId uint64 `protobuf:"varint,5,opt,name=customColorId,proto3,oneof"` +} + +func (*ChatStyle_AutoBubbleColor) isChatStyle_BubbleColor() {} + +func (*ChatStyle_BubbleColorPreset_) isChatStyle_BubbleColor() {} + +func (*ChatStyle_CustomColorId) isChatStyle_BubbleColor() {} + +type NotificationProfile struct { + state protoimpl.MessageState `protogen:"open.v1"` + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + Emoji *string `protobuf:"bytes,2,opt,name=emoji,proto3,oneof" json:"emoji,omitempty"` + Color uint32 `protobuf:"fixed32,3,opt,name=color,proto3" json:"color,omitempty"` // 0xAARRGGBB + CreatedAtMs uint64 `protobuf:"varint,4,opt,name=createdAtMs,proto3" json:"createdAtMs,omitempty"` + AllowAllCalls bool `protobuf:"varint,5,opt,name=allowAllCalls,proto3" json:"allowAllCalls,omitempty"` + AllowAllMentions bool `protobuf:"varint,6,opt,name=allowAllMentions,proto3" json:"allowAllMentions,omitempty"` + AllowedMembers []uint64 `protobuf:"varint,7,rep,packed,name=allowedMembers,proto3" json:"allowedMembers,omitempty"` // generated recipient id for allowed groups and contacts + ScheduleEnabled bool `protobuf:"varint,8,opt,name=scheduleEnabled,proto3" json:"scheduleEnabled,omitempty"` + ScheduleStartTime uint32 `protobuf:"varint,9,opt,name=scheduleStartTime,proto3" json:"scheduleStartTime,omitempty"` // 24-hour clock int, 0000-2359 (e.g., 15, 900, 1130, 2345) + ScheduleEndTime uint32 `protobuf:"varint,10,opt,name=scheduleEndTime,proto3" json:"scheduleEndTime,omitempty"` // 24-hour clock int, 0000-2359 (e.g., 15, 900, 1130, 2345) + ScheduleDaysEnabled []NotificationProfile_DayOfWeek `protobuf:"varint,11,rep,packed,name=scheduleDaysEnabled,proto3,enum=signal.backup.NotificationProfile_DayOfWeek" json:"scheduleDaysEnabled,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *NotificationProfile) Reset() { + *x = NotificationProfile{} + mi := &file_backuppb_Backup_proto_msgTypes[78] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *NotificationProfile) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*NotificationProfile) ProtoMessage() {} + +func (x *NotificationProfile) ProtoReflect() protoreflect.Message { + mi := &file_backuppb_Backup_proto_msgTypes[78] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use NotificationProfile.ProtoReflect.Descriptor instead. +func (*NotificationProfile) Descriptor() ([]byte, []int) { + return file_backuppb_Backup_proto_rawDescGZIP(), []int{78} +} + +func (x *NotificationProfile) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *NotificationProfile) GetEmoji() string { + if x != nil && x.Emoji != nil { + return *x.Emoji + } + return "" +} + +func (x *NotificationProfile) GetColor() uint32 { + if x != nil { + return x.Color + } + return 0 +} + +func (x *NotificationProfile) GetCreatedAtMs() uint64 { + if x != nil { + return x.CreatedAtMs + } + return 0 +} + +func (x *NotificationProfile) GetAllowAllCalls() bool { + if x != nil { + return x.AllowAllCalls + } + return false +} + +func (x *NotificationProfile) GetAllowAllMentions() bool { + if x != nil { + return x.AllowAllMentions + } + return false +} + +func (x *NotificationProfile) GetAllowedMembers() []uint64 { + if x != nil { + return x.AllowedMembers + } + return nil +} + +func (x *NotificationProfile) GetScheduleEnabled() bool { + if x != nil { + return x.ScheduleEnabled + } + return false +} + +func (x *NotificationProfile) GetScheduleStartTime() uint32 { + if x != nil { + return x.ScheduleStartTime + } + return 0 +} + +func (x *NotificationProfile) GetScheduleEndTime() uint32 { + if x != nil { + return x.ScheduleEndTime + } + return 0 +} + +func (x *NotificationProfile) GetScheduleDaysEnabled() []NotificationProfile_DayOfWeek { + if x != nil { + return x.ScheduleDaysEnabled + } + return nil +} + +type ChatFolder struct { + state protoimpl.MessageState `protogen:"open.v1"` + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + ShowOnlyUnread bool `protobuf:"varint,2,opt,name=showOnlyUnread,proto3" json:"showOnlyUnread,omitempty"` + ShowMutedChats bool `protobuf:"varint,3,opt,name=showMutedChats,proto3" json:"showMutedChats,omitempty"` + // Folder includes all 1:1 chats, unless excluded + IncludeAllIndividualChats bool `protobuf:"varint,4,opt,name=includeAllIndividualChats,proto3" json:"includeAllIndividualChats,omitempty"` + // Folder includes all group chats, unless excluded + IncludeAllGroupChats bool `protobuf:"varint,5,opt,name=includeAllGroupChats,proto3" json:"includeAllGroupChats,omitempty"` + FolderType ChatFolder_FolderType `protobuf:"varint,6,opt,name=folderType,proto3,enum=signal.backup.ChatFolder_FolderType" json:"folderType,omitempty"` + IncludedRecipientIds []uint64 `protobuf:"varint,7,rep,packed,name=includedRecipientIds,proto3" json:"includedRecipientIds,omitempty"` // generated recipient id of groups, contacts, and/or note to self + ExcludedRecipientIds []uint64 `protobuf:"varint,8,rep,packed,name=excludedRecipientIds,proto3" json:"excludedRecipientIds,omitempty"` // generated recipient id of groups, contacts, and/or note to self + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ChatFolder) Reset() { + *x = ChatFolder{} + mi := &file_backuppb_Backup_proto_msgTypes[79] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ChatFolder) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ChatFolder) ProtoMessage() {} + +func (x *ChatFolder) ProtoReflect() protoreflect.Message { + mi := &file_backuppb_Backup_proto_msgTypes[79] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ChatFolder.ProtoReflect.Descriptor instead. +func (*ChatFolder) Descriptor() ([]byte, []int) { + return file_backuppb_Backup_proto_rawDescGZIP(), []int{79} +} + +func (x *ChatFolder) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *ChatFolder) GetShowOnlyUnread() bool { + if x != nil { + return x.ShowOnlyUnread + } + return false +} + +func (x *ChatFolder) GetShowMutedChats() bool { + if x != nil { + return x.ShowMutedChats + } + return false +} + +func (x *ChatFolder) GetIncludeAllIndividualChats() bool { + if x != nil { + return x.IncludeAllIndividualChats + } + return false +} + +func (x *ChatFolder) GetIncludeAllGroupChats() bool { + if x != nil { + return x.IncludeAllGroupChats + } + return false +} + +func (x *ChatFolder) GetFolderType() ChatFolder_FolderType { + if x != nil { + return x.FolderType + } + return ChatFolder_UNKNOWN +} + +func (x *ChatFolder) GetIncludedRecipientIds() []uint64 { + if x != nil { + return x.IncludedRecipientIds + } + return nil +} + +func (x *ChatFolder) GetExcludedRecipientIds() []uint64 { + if x != nil { + return x.ExcludedRecipientIds + } + return nil +} + +type AccountData_UsernameLink struct { + state protoimpl.MessageState `protogen:"open.v1"` + Entropy []byte `protobuf:"bytes,1,opt,name=entropy,proto3" json:"entropy,omitempty"` // 32 bytes of entropy used for encryption + ServerId []byte `protobuf:"bytes,2,opt,name=serverId,proto3" json:"serverId,omitempty"` // 16 bytes of encoded UUID provided by the server + Color AccountData_UsernameLink_Color `protobuf:"varint,3,opt,name=color,proto3,enum=signal.backup.AccountData_UsernameLink_Color" json:"color,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *AccountData_UsernameLink) Reset() { + *x = AccountData_UsernameLink{} + mi := &file_backuppb_Backup_proto_msgTypes[80] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *AccountData_UsernameLink) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*AccountData_UsernameLink) ProtoMessage() {} + +func (x *AccountData_UsernameLink) ProtoReflect() protoreflect.Message { + mi := &file_backuppb_Backup_proto_msgTypes[80] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use AccountData_UsernameLink.ProtoReflect.Descriptor instead. +func (*AccountData_UsernameLink) Descriptor() ([]byte, []int) { + return file_backuppb_Backup_proto_rawDescGZIP(), []int{2, 0} +} + +func (x *AccountData_UsernameLink) GetEntropy() []byte { + if x != nil { + return x.Entropy + } + return nil +} + +func (x *AccountData_UsernameLink) GetServerId() []byte { + if x != nil { + return x.ServerId + } + return nil +} + +func (x *AccountData_UsernameLink) GetColor() AccountData_UsernameLink_Color { + if x != nil { + return x.Color + } + return AccountData_UsernameLink_UNKNOWN +} + +type AccountData_AccountSettings struct { + state protoimpl.MessageState `protogen:"open.v1"` + ReadReceipts bool `protobuf:"varint,1,opt,name=readReceipts,proto3" json:"readReceipts,omitempty"` + SealedSenderIndicators bool `protobuf:"varint,2,opt,name=sealedSenderIndicators,proto3" json:"sealedSenderIndicators,omitempty"` + TypingIndicators bool `protobuf:"varint,3,opt,name=typingIndicators,proto3" json:"typingIndicators,omitempty"` + LinkPreviews bool `protobuf:"varint,4,opt,name=linkPreviews,proto3" json:"linkPreviews,omitempty"` + NotDiscoverableByPhoneNumber bool `protobuf:"varint,5,opt,name=notDiscoverableByPhoneNumber,proto3" json:"notDiscoverableByPhoneNumber,omitempty"` + PreferContactAvatars bool `protobuf:"varint,6,opt,name=preferContactAvatars,proto3" json:"preferContactAvatars,omitempty"` + UniversalExpireTimerSeconds uint32 `protobuf:"varint,7,opt,name=universalExpireTimerSeconds,proto3" json:"universalExpireTimerSeconds,omitempty"` // 0 means no universal expire timer. + PreferredReactionEmoji []string `protobuf:"bytes,8,rep,name=preferredReactionEmoji,proto3" json:"preferredReactionEmoji,omitempty"` + DisplayBadgesOnProfile bool `protobuf:"varint,9,opt,name=displayBadgesOnProfile,proto3" json:"displayBadgesOnProfile,omitempty"` + KeepMutedChatsArchived bool `protobuf:"varint,10,opt,name=keepMutedChatsArchived,proto3" json:"keepMutedChatsArchived,omitempty"` + HasSetMyStoriesPrivacy bool `protobuf:"varint,11,opt,name=hasSetMyStoriesPrivacy,proto3" json:"hasSetMyStoriesPrivacy,omitempty"` + HasViewedOnboardingStory bool `protobuf:"varint,12,opt,name=hasViewedOnboardingStory,proto3" json:"hasViewedOnboardingStory,omitempty"` + StoriesDisabled bool `protobuf:"varint,13,opt,name=storiesDisabled,proto3" json:"storiesDisabled,omitempty"` + StoryViewReceiptsEnabled *bool `protobuf:"varint,14,opt,name=storyViewReceiptsEnabled,proto3,oneof" json:"storyViewReceiptsEnabled,omitempty"` + HasSeenGroupStoryEducationSheet bool `protobuf:"varint,15,opt,name=hasSeenGroupStoryEducationSheet,proto3" json:"hasSeenGroupStoryEducationSheet,omitempty"` + HasCompletedUsernameOnboarding bool `protobuf:"varint,16,opt,name=hasCompletedUsernameOnboarding,proto3" json:"hasCompletedUsernameOnboarding,omitempty"` + PhoneNumberSharingMode AccountData_PhoneNumberSharingMode `protobuf:"varint,17,opt,name=phoneNumberSharingMode,proto3,enum=signal.backup.AccountData_PhoneNumberSharingMode" json:"phoneNumberSharingMode,omitempty"` + DefaultChatStyle *ChatStyle `protobuf:"bytes,18,opt,name=defaultChatStyle,proto3" json:"defaultChatStyle,omitempty"` + CustomChatColors []*ChatStyle_CustomChatColor `protobuf:"bytes,19,rep,name=customChatColors,proto3" json:"customChatColors,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *AccountData_AccountSettings) Reset() { + *x = AccountData_AccountSettings{} + mi := &file_backuppb_Backup_proto_msgTypes[81] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *AccountData_AccountSettings) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*AccountData_AccountSettings) ProtoMessage() {} + +func (x *AccountData_AccountSettings) ProtoReflect() protoreflect.Message { + mi := &file_backuppb_Backup_proto_msgTypes[81] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use AccountData_AccountSettings.ProtoReflect.Descriptor instead. +func (*AccountData_AccountSettings) Descriptor() ([]byte, []int) { + return file_backuppb_Backup_proto_rawDescGZIP(), []int{2, 1} +} + +func (x *AccountData_AccountSettings) GetReadReceipts() bool { + if x != nil { + return x.ReadReceipts + } + return false +} + +func (x *AccountData_AccountSettings) GetSealedSenderIndicators() bool { + if x != nil { + return x.SealedSenderIndicators + } + return false +} + +func (x *AccountData_AccountSettings) GetTypingIndicators() bool { + if x != nil { + return x.TypingIndicators + } + return false +} + +func (x *AccountData_AccountSettings) GetLinkPreviews() bool { + if x != nil { + return x.LinkPreviews + } + return false +} + +func (x *AccountData_AccountSettings) GetNotDiscoverableByPhoneNumber() bool { + if x != nil { + return x.NotDiscoverableByPhoneNumber + } + return false +} + +func (x *AccountData_AccountSettings) GetPreferContactAvatars() bool { + if x != nil { + return x.PreferContactAvatars + } + return false +} + +func (x *AccountData_AccountSettings) GetUniversalExpireTimerSeconds() uint32 { + if x != nil { + return x.UniversalExpireTimerSeconds + } + return 0 +} + +func (x *AccountData_AccountSettings) GetPreferredReactionEmoji() []string { + if x != nil { + return x.PreferredReactionEmoji + } + return nil +} + +func (x *AccountData_AccountSettings) GetDisplayBadgesOnProfile() bool { + if x != nil { + return x.DisplayBadgesOnProfile + } + return false +} + +func (x *AccountData_AccountSettings) GetKeepMutedChatsArchived() bool { + if x != nil { + return x.KeepMutedChatsArchived + } + return false +} + +func (x *AccountData_AccountSettings) GetHasSetMyStoriesPrivacy() bool { + if x != nil { + return x.HasSetMyStoriesPrivacy + } + return false +} + +func (x *AccountData_AccountSettings) GetHasViewedOnboardingStory() bool { + if x != nil { + return x.HasViewedOnboardingStory + } + return false +} + +func (x *AccountData_AccountSettings) GetStoriesDisabled() bool { + if x != nil { + return x.StoriesDisabled + } + return false +} + +func (x *AccountData_AccountSettings) GetStoryViewReceiptsEnabled() bool { + if x != nil && x.StoryViewReceiptsEnabled != nil { + return *x.StoryViewReceiptsEnabled + } + return false +} + +func (x *AccountData_AccountSettings) GetHasSeenGroupStoryEducationSheet() bool { + if x != nil { + return x.HasSeenGroupStoryEducationSheet + } + return false +} + +func (x *AccountData_AccountSettings) GetHasCompletedUsernameOnboarding() bool { + if x != nil { + return x.HasCompletedUsernameOnboarding + } + return false +} + +func (x *AccountData_AccountSettings) GetPhoneNumberSharingMode() AccountData_PhoneNumberSharingMode { + if x != nil { + return x.PhoneNumberSharingMode + } + return AccountData_UNKNOWN +} + +func (x *AccountData_AccountSettings) GetDefaultChatStyle() *ChatStyle { + if x != nil { + return x.DefaultChatStyle + } + return nil +} + +func (x *AccountData_AccountSettings) GetCustomChatColors() []*ChatStyle_CustomChatColor { + if x != nil { + return x.CustomChatColors + } + return nil +} + +type AccountData_SubscriberData struct { + state protoimpl.MessageState `protogen:"open.v1"` + SubscriberId []byte `protobuf:"bytes,1,opt,name=subscriberId,proto3" json:"subscriberId,omitempty"` + CurrencyCode string `protobuf:"bytes,2,opt,name=currencyCode,proto3" json:"currencyCode,omitempty"` + ManuallyCancelled bool `protobuf:"varint,3,opt,name=manuallyCancelled,proto3" json:"manuallyCancelled,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *AccountData_SubscriberData) Reset() { + *x = AccountData_SubscriberData{} + mi := &file_backuppb_Backup_proto_msgTypes[82] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *AccountData_SubscriberData) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*AccountData_SubscriberData) ProtoMessage() {} + +func (x *AccountData_SubscriberData) ProtoReflect() protoreflect.Message { + mi := &file_backuppb_Backup_proto_msgTypes[82] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use AccountData_SubscriberData.ProtoReflect.Descriptor instead. +func (*AccountData_SubscriberData) Descriptor() ([]byte, []int) { + return file_backuppb_Backup_proto_rawDescGZIP(), []int{2, 2} +} + +func (x *AccountData_SubscriberData) GetSubscriberId() []byte { + if x != nil { + return x.SubscriberId + } + return nil +} + +func (x *AccountData_SubscriberData) GetCurrencyCode() string { + if x != nil { + return x.CurrencyCode + } + return "" +} + +func (x *AccountData_SubscriberData) GetManuallyCancelled() bool { + if x != nil { + return x.ManuallyCancelled + } + return false +} + +type AccountData_IAPSubscriberData struct { + state protoimpl.MessageState `protogen:"open.v1"` + SubscriberId []byte `protobuf:"bytes,1,opt,name=subscriberId,proto3" json:"subscriberId,omitempty"` + // Types that are valid to be assigned to IapSubscriptionId: + // + // *AccountData_IAPSubscriberData_PurchaseToken + // *AccountData_IAPSubscriberData_OriginalTransactionId + IapSubscriptionId isAccountData_IAPSubscriberData_IapSubscriptionId `protobuf_oneof:"iapSubscriptionId"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *AccountData_IAPSubscriberData) Reset() { + *x = AccountData_IAPSubscriberData{} + mi := &file_backuppb_Backup_proto_msgTypes[83] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *AccountData_IAPSubscriberData) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*AccountData_IAPSubscriberData) ProtoMessage() {} + +func (x *AccountData_IAPSubscriberData) ProtoReflect() protoreflect.Message { + mi := &file_backuppb_Backup_proto_msgTypes[83] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use AccountData_IAPSubscriberData.ProtoReflect.Descriptor instead. +func (*AccountData_IAPSubscriberData) Descriptor() ([]byte, []int) { + return file_backuppb_Backup_proto_rawDescGZIP(), []int{2, 3} +} + +func (x *AccountData_IAPSubscriberData) GetSubscriberId() []byte { + if x != nil { + return x.SubscriberId + } + return nil +} + +func (x *AccountData_IAPSubscriberData) GetIapSubscriptionId() isAccountData_IAPSubscriberData_IapSubscriptionId { + if x != nil { + return x.IapSubscriptionId + } + return nil +} + +func (x *AccountData_IAPSubscriberData) GetPurchaseToken() string { + if x != nil { + if x, ok := x.IapSubscriptionId.(*AccountData_IAPSubscriberData_PurchaseToken); ok { + return x.PurchaseToken + } + } + return "" +} + +func (x *AccountData_IAPSubscriberData) GetOriginalTransactionId() uint64 { + if x != nil { + if x, ok := x.IapSubscriptionId.(*AccountData_IAPSubscriberData_OriginalTransactionId); ok { + return x.OriginalTransactionId + } + } + return 0 +} + +type isAccountData_IAPSubscriberData_IapSubscriptionId interface { + isAccountData_IAPSubscriberData_IapSubscriptionId() +} + +type AccountData_IAPSubscriberData_PurchaseToken struct { + // Identifies an Android Play Store IAP subscription. + PurchaseToken string `protobuf:"bytes,2,opt,name=purchaseToken,proto3,oneof"` +} + +type AccountData_IAPSubscriberData_OriginalTransactionId struct { + // Identifies an iOS App Store IAP subscription. + OriginalTransactionId uint64 `protobuf:"varint,3,opt,name=originalTransactionId,proto3,oneof"` +} + +func (*AccountData_IAPSubscriberData_PurchaseToken) isAccountData_IAPSubscriberData_IapSubscriptionId() { +} + +func (*AccountData_IAPSubscriberData_OriginalTransactionId) isAccountData_IAPSubscriberData_IapSubscriptionId() { +} + +type Contact_Registered struct { + state protoimpl.MessageState `protogen:"open.v1"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *Contact_Registered) Reset() { + *x = Contact_Registered{} + mi := &file_backuppb_Backup_proto_msgTypes[84] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *Contact_Registered) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Contact_Registered) ProtoMessage() {} + +func (x *Contact_Registered) ProtoReflect() protoreflect.Message { + mi := &file_backuppb_Backup_proto_msgTypes[84] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Contact_Registered.ProtoReflect.Descriptor instead. +func (*Contact_Registered) Descriptor() ([]byte, []int) { + return file_backuppb_Backup_proto_rawDescGZIP(), []int{4, 0} +} + +type Contact_NotRegistered struct { + state protoimpl.MessageState `protogen:"open.v1"` + UnregisteredTimestamp uint64 `protobuf:"varint,1,opt,name=unregisteredTimestamp,proto3" json:"unregisteredTimestamp,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *Contact_NotRegistered) Reset() { + *x = Contact_NotRegistered{} + mi := &file_backuppb_Backup_proto_msgTypes[85] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *Contact_NotRegistered) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Contact_NotRegistered) ProtoMessage() {} + +func (x *Contact_NotRegistered) ProtoReflect() protoreflect.Message { + mi := &file_backuppb_Backup_proto_msgTypes[85] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Contact_NotRegistered.ProtoReflect.Descriptor instead. +func (*Contact_NotRegistered) Descriptor() ([]byte, []int) { + return file_backuppb_Backup_proto_rawDescGZIP(), []int{4, 1} +} + +func (x *Contact_NotRegistered) GetUnregisteredTimestamp() uint64 { + if x != nil { + return x.UnregisteredTimestamp + } + return 0 +} + +type Contact_Name struct { + state protoimpl.MessageState `protogen:"open.v1"` + Given string `protobuf:"bytes,1,opt,name=given,proto3" json:"given,omitempty"` + Family string `protobuf:"bytes,2,opt,name=family,proto3" json:"family,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *Contact_Name) Reset() { + *x = Contact_Name{} + mi := &file_backuppb_Backup_proto_msgTypes[86] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *Contact_Name) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Contact_Name) ProtoMessage() {} + +func (x *Contact_Name) ProtoReflect() protoreflect.Message { + mi := &file_backuppb_Backup_proto_msgTypes[86] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Contact_Name.ProtoReflect.Descriptor instead. +func (*Contact_Name) Descriptor() ([]byte, []int) { + return file_backuppb_Backup_proto_rawDescGZIP(), []int{4, 2} +} + +func (x *Contact_Name) GetGiven() string { + if x != nil { + return x.Given + } + return "" +} + +func (x *Contact_Name) GetFamily() string { + if x != nil { + return x.Family + } + return "" +} + +// These are simply plaintext copies of the groups proto from Groups.proto. +// They should be kept completely in-sync with Groups.proto. +// These exist to allow us to have the latest snapshot of a group during restoration without having to hit the network. +// We would use Groups.proto if we could, but we want a plaintext version to improve export readability. +// For documentation, defer to Groups.proto. The only name change is Group -> GroupSnapshot to avoid the naming conflict. +type Group_GroupSnapshot struct { + state protoimpl.MessageState `protogen:"open.v1"` + Title *Group_GroupAttributeBlob `protobuf:"bytes,2,opt,name=title,proto3" json:"title,omitempty"` + Description *Group_GroupAttributeBlob `protobuf:"bytes,11,opt,name=description,proto3" json:"description,omitempty"` + AvatarUrl string `protobuf:"bytes,3,opt,name=avatarUrl,proto3" json:"avatarUrl,omitempty"` + DisappearingMessagesTimer *Group_GroupAttributeBlob `protobuf:"bytes,4,opt,name=disappearingMessagesTimer,proto3" json:"disappearingMessagesTimer,omitempty"` + AccessControl *Group_AccessControl `protobuf:"bytes,5,opt,name=accessControl,proto3" json:"accessControl,omitempty"` + Version uint32 `protobuf:"varint,6,opt,name=version,proto3" json:"version,omitempty"` + Members []*Group_Member `protobuf:"bytes,7,rep,name=members,proto3" json:"members,omitempty"` + MembersPendingProfileKey []*Group_MemberPendingProfileKey `protobuf:"bytes,8,rep,name=membersPendingProfileKey,proto3" json:"membersPendingProfileKey,omitempty"` + MembersPendingAdminApproval []*Group_MemberPendingAdminApproval `protobuf:"bytes,9,rep,name=membersPendingAdminApproval,proto3" json:"membersPendingAdminApproval,omitempty"` + InviteLinkPassword []byte `protobuf:"bytes,10,opt,name=inviteLinkPassword,proto3" json:"inviteLinkPassword,omitempty"` + AnnouncementsOnly bool `protobuf:"varint,12,opt,name=announcements_only,json=announcementsOnly,proto3" json:"announcements_only,omitempty"` + MembersBanned []*Group_MemberBanned `protobuf:"bytes,13,rep,name=members_banned,json=membersBanned,proto3" json:"members_banned,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *Group_GroupSnapshot) Reset() { + *x = Group_GroupSnapshot{} + mi := &file_backuppb_Backup_proto_msgTypes[87] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *Group_GroupSnapshot) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Group_GroupSnapshot) ProtoMessage() {} + +func (x *Group_GroupSnapshot) ProtoReflect() protoreflect.Message { + mi := &file_backuppb_Backup_proto_msgTypes[87] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Group_GroupSnapshot.ProtoReflect.Descriptor instead. +func (*Group_GroupSnapshot) Descriptor() ([]byte, []int) { + return file_backuppb_Backup_proto_rawDescGZIP(), []int{5, 0} +} + +func (x *Group_GroupSnapshot) GetTitle() *Group_GroupAttributeBlob { + if x != nil { + return x.Title + } + return nil +} + +func (x *Group_GroupSnapshot) GetDescription() *Group_GroupAttributeBlob { + if x != nil { + return x.Description + } + return nil +} + +func (x *Group_GroupSnapshot) GetAvatarUrl() string { + if x != nil { + return x.AvatarUrl + } + return "" +} + +func (x *Group_GroupSnapshot) GetDisappearingMessagesTimer() *Group_GroupAttributeBlob { + if x != nil { + return x.DisappearingMessagesTimer + } + return nil +} + +func (x *Group_GroupSnapshot) GetAccessControl() *Group_AccessControl { + if x != nil { + return x.AccessControl + } + return nil +} + +func (x *Group_GroupSnapshot) GetVersion() uint32 { + if x != nil { + return x.Version + } + return 0 +} + +func (x *Group_GroupSnapshot) GetMembers() []*Group_Member { + if x != nil { + return x.Members + } + return nil +} + +func (x *Group_GroupSnapshot) GetMembersPendingProfileKey() []*Group_MemberPendingProfileKey { + if x != nil { + return x.MembersPendingProfileKey + } + return nil +} + +func (x *Group_GroupSnapshot) GetMembersPendingAdminApproval() []*Group_MemberPendingAdminApproval { + if x != nil { + return x.MembersPendingAdminApproval + } + return nil +} + +func (x *Group_GroupSnapshot) GetInviteLinkPassword() []byte { + if x != nil { + return x.InviteLinkPassword + } + return nil +} + +func (x *Group_GroupSnapshot) GetAnnouncementsOnly() bool { + if x != nil { + return x.AnnouncementsOnly + } + return false +} + +func (x *Group_GroupSnapshot) GetMembersBanned() []*Group_MemberBanned { + if x != nil { + return x.MembersBanned + } + return nil +} + +type Group_GroupAttributeBlob struct { + state protoimpl.MessageState `protogen:"open.v1"` + // Types that are valid to be assigned to Content: + // + // *Group_GroupAttributeBlob_Title + // *Group_GroupAttributeBlob_Avatar + // *Group_GroupAttributeBlob_DisappearingMessagesDuration + // *Group_GroupAttributeBlob_DescriptionText + Content isGroup_GroupAttributeBlob_Content `protobuf_oneof:"content"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *Group_GroupAttributeBlob) Reset() { + *x = Group_GroupAttributeBlob{} + mi := &file_backuppb_Backup_proto_msgTypes[88] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *Group_GroupAttributeBlob) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Group_GroupAttributeBlob) ProtoMessage() {} + +func (x *Group_GroupAttributeBlob) ProtoReflect() protoreflect.Message { + mi := &file_backuppb_Backup_proto_msgTypes[88] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Group_GroupAttributeBlob.ProtoReflect.Descriptor instead. +func (*Group_GroupAttributeBlob) Descriptor() ([]byte, []int) { + return file_backuppb_Backup_proto_rawDescGZIP(), []int{5, 1} +} + +func (x *Group_GroupAttributeBlob) GetContent() isGroup_GroupAttributeBlob_Content { + if x != nil { + return x.Content + } + return nil +} + +func (x *Group_GroupAttributeBlob) GetTitle() string { + if x != nil { + if x, ok := x.Content.(*Group_GroupAttributeBlob_Title); ok { + return x.Title + } + } + return "" +} + +func (x *Group_GroupAttributeBlob) GetAvatar() []byte { + if x != nil { + if x, ok := x.Content.(*Group_GroupAttributeBlob_Avatar); ok { + return x.Avatar + } + } + return nil +} + +func (x *Group_GroupAttributeBlob) GetDisappearingMessagesDuration() uint32 { + if x != nil { + if x, ok := x.Content.(*Group_GroupAttributeBlob_DisappearingMessagesDuration); ok { + return x.DisappearingMessagesDuration + } + } + return 0 +} + +func (x *Group_GroupAttributeBlob) GetDescriptionText() string { + if x != nil { + if x, ok := x.Content.(*Group_GroupAttributeBlob_DescriptionText); ok { + return x.DescriptionText + } + } + return "" +} + +type isGroup_GroupAttributeBlob_Content interface { + isGroup_GroupAttributeBlob_Content() +} + +type Group_GroupAttributeBlob_Title struct { + Title string `protobuf:"bytes,1,opt,name=title,proto3,oneof"` +} + +type Group_GroupAttributeBlob_Avatar struct { + Avatar []byte `protobuf:"bytes,2,opt,name=avatar,proto3,oneof"` +} + +type Group_GroupAttributeBlob_DisappearingMessagesDuration struct { + DisappearingMessagesDuration uint32 `protobuf:"varint,3,opt,name=disappearingMessagesDuration,proto3,oneof"` +} + +type Group_GroupAttributeBlob_DescriptionText struct { + DescriptionText string `protobuf:"bytes,4,opt,name=descriptionText,proto3,oneof"` +} + +func (*Group_GroupAttributeBlob_Title) isGroup_GroupAttributeBlob_Content() {} + +func (*Group_GroupAttributeBlob_Avatar) isGroup_GroupAttributeBlob_Content() {} + +func (*Group_GroupAttributeBlob_DisappearingMessagesDuration) isGroup_GroupAttributeBlob_Content() {} + +func (*Group_GroupAttributeBlob_DescriptionText) isGroup_GroupAttributeBlob_Content() {} + +type Group_Member struct { + state protoimpl.MessageState `protogen:"open.v1"` + UserId []byte `protobuf:"bytes,1,opt,name=userId,proto3" json:"userId,omitempty"` + Role Group_Member_Role `protobuf:"varint,2,opt,name=role,proto3,enum=signal.backup.Group_Member_Role" json:"role,omitempty"` + JoinedAtVersion uint32 `protobuf:"varint,5,opt,name=joinedAtVersion,proto3" json:"joinedAtVersion,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *Group_Member) Reset() { + *x = Group_Member{} + mi := &file_backuppb_Backup_proto_msgTypes[89] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *Group_Member) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Group_Member) ProtoMessage() {} + +func (x *Group_Member) ProtoReflect() protoreflect.Message { + mi := &file_backuppb_Backup_proto_msgTypes[89] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Group_Member.ProtoReflect.Descriptor instead. +func (*Group_Member) Descriptor() ([]byte, []int) { + return file_backuppb_Backup_proto_rawDescGZIP(), []int{5, 2} +} + +func (x *Group_Member) GetUserId() []byte { + if x != nil { + return x.UserId + } + return nil +} + +func (x *Group_Member) GetRole() Group_Member_Role { + if x != nil { + return x.Role + } + return Group_Member_UNKNOWN +} + +func (x *Group_Member) GetJoinedAtVersion() uint32 { + if x != nil { + return x.JoinedAtVersion + } + return 0 +} + +type Group_MemberPendingProfileKey struct { + state protoimpl.MessageState `protogen:"open.v1"` + Member *Group_Member `protobuf:"bytes,1,opt,name=member,proto3" json:"member,omitempty"` + AddedByUserId []byte `protobuf:"bytes,2,opt,name=addedByUserId,proto3" json:"addedByUserId,omitempty"` + Timestamp uint64 `protobuf:"varint,3,opt,name=timestamp,proto3" json:"timestamp,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *Group_MemberPendingProfileKey) Reset() { + *x = Group_MemberPendingProfileKey{} + mi := &file_backuppb_Backup_proto_msgTypes[90] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *Group_MemberPendingProfileKey) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Group_MemberPendingProfileKey) ProtoMessage() {} + +func (x *Group_MemberPendingProfileKey) ProtoReflect() protoreflect.Message { + mi := &file_backuppb_Backup_proto_msgTypes[90] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Group_MemberPendingProfileKey.ProtoReflect.Descriptor instead. +func (*Group_MemberPendingProfileKey) Descriptor() ([]byte, []int) { + return file_backuppb_Backup_proto_rawDescGZIP(), []int{5, 3} +} + +func (x *Group_MemberPendingProfileKey) GetMember() *Group_Member { + if x != nil { + return x.Member + } + return nil +} + +func (x *Group_MemberPendingProfileKey) GetAddedByUserId() []byte { + if x != nil { + return x.AddedByUserId + } + return nil +} + +func (x *Group_MemberPendingProfileKey) GetTimestamp() uint64 { + if x != nil { + return x.Timestamp + } + return 0 +} + +type Group_MemberPendingAdminApproval struct { + state protoimpl.MessageState `protogen:"open.v1"` + UserId []byte `protobuf:"bytes,1,opt,name=userId,proto3" json:"userId,omitempty"` + Timestamp uint64 `protobuf:"varint,4,opt,name=timestamp,proto3" json:"timestamp,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *Group_MemberPendingAdminApproval) Reset() { + *x = Group_MemberPendingAdminApproval{} + mi := &file_backuppb_Backup_proto_msgTypes[91] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *Group_MemberPendingAdminApproval) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Group_MemberPendingAdminApproval) ProtoMessage() {} + +func (x *Group_MemberPendingAdminApproval) ProtoReflect() protoreflect.Message { + mi := &file_backuppb_Backup_proto_msgTypes[91] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Group_MemberPendingAdminApproval.ProtoReflect.Descriptor instead. +func (*Group_MemberPendingAdminApproval) Descriptor() ([]byte, []int) { + return file_backuppb_Backup_proto_rawDescGZIP(), []int{5, 4} +} + +func (x *Group_MemberPendingAdminApproval) GetUserId() []byte { + if x != nil { + return x.UserId + } + return nil +} + +func (x *Group_MemberPendingAdminApproval) GetTimestamp() uint64 { + if x != nil { + return x.Timestamp + } + return 0 +} + +type Group_MemberBanned struct { + state protoimpl.MessageState `protogen:"open.v1"` + UserId []byte `protobuf:"bytes,1,opt,name=userId,proto3" json:"userId,omitempty"` + Timestamp uint64 `protobuf:"varint,2,opt,name=timestamp,proto3" json:"timestamp,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *Group_MemberBanned) Reset() { + *x = Group_MemberBanned{} + mi := &file_backuppb_Backup_proto_msgTypes[92] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *Group_MemberBanned) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Group_MemberBanned) ProtoMessage() {} + +func (x *Group_MemberBanned) ProtoReflect() protoreflect.Message { + mi := &file_backuppb_Backup_proto_msgTypes[92] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Group_MemberBanned.ProtoReflect.Descriptor instead. +func (*Group_MemberBanned) Descriptor() ([]byte, []int) { + return file_backuppb_Backup_proto_rawDescGZIP(), []int{5, 5} +} + +func (x *Group_MemberBanned) GetUserId() []byte { + if x != nil { + return x.UserId + } + return nil +} + +func (x *Group_MemberBanned) GetTimestamp() uint64 { + if x != nil { + return x.Timestamp + } + return 0 +} + +type Group_AccessControl struct { + state protoimpl.MessageState `protogen:"open.v1"` + Attributes Group_AccessControl_AccessRequired `protobuf:"varint,1,opt,name=attributes,proto3,enum=signal.backup.Group_AccessControl_AccessRequired" json:"attributes,omitempty"` + Members Group_AccessControl_AccessRequired `protobuf:"varint,2,opt,name=members,proto3,enum=signal.backup.Group_AccessControl_AccessRequired" json:"members,omitempty"` + AddFromInviteLink Group_AccessControl_AccessRequired `protobuf:"varint,3,opt,name=addFromInviteLink,proto3,enum=signal.backup.Group_AccessControl_AccessRequired" json:"addFromInviteLink,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *Group_AccessControl) Reset() { + *x = Group_AccessControl{} + mi := &file_backuppb_Backup_proto_msgTypes[93] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *Group_AccessControl) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Group_AccessControl) ProtoMessage() {} + +func (x *Group_AccessControl) ProtoReflect() protoreflect.Message { + mi := &file_backuppb_Backup_proto_msgTypes[93] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Group_AccessControl.ProtoReflect.Descriptor instead. +func (*Group_AccessControl) Descriptor() ([]byte, []int) { + return file_backuppb_Backup_proto_rawDescGZIP(), []int{5, 6} +} + +func (x *Group_AccessControl) GetAttributes() Group_AccessControl_AccessRequired { + if x != nil { + return x.Attributes + } + return Group_AccessControl_UNKNOWN +} + +func (x *Group_AccessControl) GetMembers() Group_AccessControl_AccessRequired { + if x != nil { + return x.Members + } + return Group_AccessControl_UNKNOWN +} + +func (x *Group_AccessControl) GetAddFromInviteLink() Group_AccessControl_AccessRequired { + if x != nil { + return x.AddFromInviteLink + } + return Group_AccessControl_UNKNOWN +} + +type ChatItem_IncomingMessageDetails struct { + state protoimpl.MessageState `protogen:"open.v1"` + DateReceived uint64 `protobuf:"varint,1,opt,name=dateReceived,proto3" json:"dateReceived,omitempty"` + DateServerSent *uint64 `protobuf:"varint,2,opt,name=dateServerSent,proto3,oneof" json:"dateServerSent,omitempty"` + Read bool `protobuf:"varint,3,opt,name=read,proto3" json:"read,omitempty"` + SealedSender bool `protobuf:"varint,4,opt,name=sealedSender,proto3" json:"sealedSender,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ChatItem_IncomingMessageDetails) Reset() { + *x = ChatItem_IncomingMessageDetails{} + mi := &file_backuppb_Backup_proto_msgTypes[94] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ChatItem_IncomingMessageDetails) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ChatItem_IncomingMessageDetails) ProtoMessage() {} + +func (x *ChatItem_IncomingMessageDetails) ProtoReflect() protoreflect.Message { + mi := &file_backuppb_Backup_proto_msgTypes[94] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ChatItem_IncomingMessageDetails.ProtoReflect.Descriptor instead. +func (*ChatItem_IncomingMessageDetails) Descriptor() ([]byte, []int) { + return file_backuppb_Backup_proto_rawDescGZIP(), []int{13, 0} +} + +func (x *ChatItem_IncomingMessageDetails) GetDateReceived() uint64 { + if x != nil { + return x.DateReceived + } + return 0 +} + +func (x *ChatItem_IncomingMessageDetails) GetDateServerSent() uint64 { + if x != nil && x.DateServerSent != nil { + return *x.DateServerSent + } + return 0 +} + +func (x *ChatItem_IncomingMessageDetails) GetRead() bool { + if x != nil { + return x.Read + } + return false +} + +func (x *ChatItem_IncomingMessageDetails) GetSealedSender() bool { + if x != nil { + return x.SealedSender + } + return false +} + +type ChatItem_OutgoingMessageDetails struct { + state protoimpl.MessageState `protogen:"open.v1"` + SendStatus []*SendStatus `protobuf:"bytes,1,rep,name=sendStatus,proto3" json:"sendStatus,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ChatItem_OutgoingMessageDetails) Reset() { + *x = ChatItem_OutgoingMessageDetails{} + mi := &file_backuppb_Backup_proto_msgTypes[95] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ChatItem_OutgoingMessageDetails) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ChatItem_OutgoingMessageDetails) ProtoMessage() {} + +func (x *ChatItem_OutgoingMessageDetails) ProtoReflect() protoreflect.Message { + mi := &file_backuppb_Backup_proto_msgTypes[95] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ChatItem_OutgoingMessageDetails.ProtoReflect.Descriptor instead. +func (*ChatItem_OutgoingMessageDetails) Descriptor() ([]byte, []int) { + return file_backuppb_Backup_proto_rawDescGZIP(), []int{13, 1} +} + +func (x *ChatItem_OutgoingMessageDetails) GetSendStatus() []*SendStatus { + if x != nil { + return x.SendStatus + } + return nil +} + +type ChatItem_DirectionlessMessageDetails struct { + state protoimpl.MessageState `protogen:"open.v1"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ChatItem_DirectionlessMessageDetails) Reset() { + *x = ChatItem_DirectionlessMessageDetails{} + mi := &file_backuppb_Backup_proto_msgTypes[96] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ChatItem_DirectionlessMessageDetails) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ChatItem_DirectionlessMessageDetails) ProtoMessage() {} + +func (x *ChatItem_DirectionlessMessageDetails) ProtoReflect() protoreflect.Message { + mi := &file_backuppb_Backup_proto_msgTypes[96] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ChatItem_DirectionlessMessageDetails.ProtoReflect.Descriptor instead. +func (*ChatItem_DirectionlessMessageDetails) Descriptor() ([]byte, []int) { + return file_backuppb_Backup_proto_rawDescGZIP(), []int{13, 2} +} + +type SendStatus_Pending struct { + state protoimpl.MessageState `protogen:"open.v1"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *SendStatus_Pending) Reset() { + *x = SendStatus_Pending{} + mi := &file_backuppb_Backup_proto_msgTypes[97] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *SendStatus_Pending) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SendStatus_Pending) ProtoMessage() {} + +func (x *SendStatus_Pending) ProtoReflect() protoreflect.Message { + mi := &file_backuppb_Backup_proto_msgTypes[97] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use SendStatus_Pending.ProtoReflect.Descriptor instead. +func (*SendStatus_Pending) Descriptor() ([]byte, []int) { + return file_backuppb_Backup_proto_rawDescGZIP(), []int{14, 0} +} + +type SendStatus_Sent struct { + state protoimpl.MessageState `protogen:"open.v1"` + SealedSender bool `protobuf:"varint,1,opt,name=sealedSender,proto3" json:"sealedSender,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *SendStatus_Sent) Reset() { + *x = SendStatus_Sent{} + mi := &file_backuppb_Backup_proto_msgTypes[98] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *SendStatus_Sent) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SendStatus_Sent) ProtoMessage() {} + +func (x *SendStatus_Sent) ProtoReflect() protoreflect.Message { + mi := &file_backuppb_Backup_proto_msgTypes[98] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use SendStatus_Sent.ProtoReflect.Descriptor instead. +func (*SendStatus_Sent) Descriptor() ([]byte, []int) { + return file_backuppb_Backup_proto_rawDescGZIP(), []int{14, 1} +} + +func (x *SendStatus_Sent) GetSealedSender() bool { + if x != nil { + return x.SealedSender + } + return false +} + +type SendStatus_Delivered struct { + state protoimpl.MessageState `protogen:"open.v1"` + SealedSender bool `protobuf:"varint,1,opt,name=sealedSender,proto3" json:"sealedSender,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *SendStatus_Delivered) Reset() { + *x = SendStatus_Delivered{} + mi := &file_backuppb_Backup_proto_msgTypes[99] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *SendStatus_Delivered) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SendStatus_Delivered) ProtoMessage() {} + +func (x *SendStatus_Delivered) ProtoReflect() protoreflect.Message { + mi := &file_backuppb_Backup_proto_msgTypes[99] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use SendStatus_Delivered.ProtoReflect.Descriptor instead. +func (*SendStatus_Delivered) Descriptor() ([]byte, []int) { + return file_backuppb_Backup_proto_rawDescGZIP(), []int{14, 2} +} + +func (x *SendStatus_Delivered) GetSealedSender() bool { + if x != nil { + return x.SealedSender + } + return false +} + +type SendStatus_Read struct { + state protoimpl.MessageState `protogen:"open.v1"` + SealedSender bool `protobuf:"varint,1,opt,name=sealedSender,proto3" json:"sealedSender,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *SendStatus_Read) Reset() { + *x = SendStatus_Read{} + mi := &file_backuppb_Backup_proto_msgTypes[100] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *SendStatus_Read) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SendStatus_Read) ProtoMessage() {} + +func (x *SendStatus_Read) ProtoReflect() protoreflect.Message { + mi := &file_backuppb_Backup_proto_msgTypes[100] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use SendStatus_Read.ProtoReflect.Descriptor instead. +func (*SendStatus_Read) Descriptor() ([]byte, []int) { + return file_backuppb_Backup_proto_rawDescGZIP(), []int{14, 3} +} + +func (x *SendStatus_Read) GetSealedSender() bool { + if x != nil { + return x.SealedSender + } + return false +} + +type SendStatus_Viewed struct { + state protoimpl.MessageState `protogen:"open.v1"` + SealedSender bool `protobuf:"varint,1,opt,name=sealedSender,proto3" json:"sealedSender,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *SendStatus_Viewed) Reset() { + *x = SendStatus_Viewed{} + mi := &file_backuppb_Backup_proto_msgTypes[101] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *SendStatus_Viewed) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SendStatus_Viewed) ProtoMessage() {} + +func (x *SendStatus_Viewed) ProtoReflect() protoreflect.Message { + mi := &file_backuppb_Backup_proto_msgTypes[101] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use SendStatus_Viewed.ProtoReflect.Descriptor instead. +func (*SendStatus_Viewed) Descriptor() ([]byte, []int) { + return file_backuppb_Backup_proto_rawDescGZIP(), []int{14, 4} +} + +func (x *SendStatus_Viewed) GetSealedSender() bool { + if x != nil { + return x.SealedSender + } + return false +} + +// e.g. user in group was blocked, so we skipped sending to them +type SendStatus_Skipped struct { + state protoimpl.MessageState `protogen:"open.v1"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *SendStatus_Skipped) Reset() { + *x = SendStatus_Skipped{} + mi := &file_backuppb_Backup_proto_msgTypes[102] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *SendStatus_Skipped) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SendStatus_Skipped) ProtoMessage() {} + +func (x *SendStatus_Skipped) ProtoReflect() protoreflect.Message { + mi := &file_backuppb_Backup_proto_msgTypes[102] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use SendStatus_Skipped.ProtoReflect.Descriptor instead. +func (*SendStatus_Skipped) Descriptor() ([]byte, []int) { + return file_backuppb_Backup_proto_rawDescGZIP(), []int{14, 5} +} + +type SendStatus_Failed struct { + state protoimpl.MessageState `protogen:"open.v1"` + Reason SendStatus_Failed_FailureReason `protobuf:"varint,1,opt,name=reason,proto3,enum=signal.backup.SendStatus_Failed_FailureReason" json:"reason,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *SendStatus_Failed) Reset() { + *x = SendStatus_Failed{} + mi := &file_backuppb_Backup_proto_msgTypes[103] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *SendStatus_Failed) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SendStatus_Failed) ProtoMessage() {} + +func (x *SendStatus_Failed) ProtoReflect() protoreflect.Message { + mi := &file_backuppb_Backup_proto_msgTypes[103] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use SendStatus_Failed.ProtoReflect.Descriptor instead. +func (*SendStatus_Failed) Descriptor() ([]byte, []int) { + return file_backuppb_Backup_proto_rawDescGZIP(), []int{14, 6} +} + +func (x *SendStatus_Failed) GetReason() SendStatus_Failed_FailureReason { + if x != nil { + return x.Reason + } + return SendStatus_Failed_UNKNOWN +} + +type DirectStoryReplyMessage_TextReply struct { + state protoimpl.MessageState `protogen:"open.v1"` + Text *Text `protobuf:"bytes,1,opt,name=text,proto3" json:"text,omitempty"` + LongText *FilePointer `protobuf:"bytes,2,opt,name=longText,proto3" json:"longText,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *DirectStoryReplyMessage_TextReply) Reset() { + *x = DirectStoryReplyMessage_TextReply{} + mi := &file_backuppb_Backup_proto_msgTypes[104] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *DirectStoryReplyMessage_TextReply) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*DirectStoryReplyMessage_TextReply) ProtoMessage() {} + +func (x *DirectStoryReplyMessage_TextReply) ProtoReflect() protoreflect.Message { + mi := &file_backuppb_Backup_proto_msgTypes[104] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use DirectStoryReplyMessage_TextReply.ProtoReflect.Descriptor instead. +func (*DirectStoryReplyMessage_TextReply) Descriptor() ([]byte, []int) { + return file_backuppb_Backup_proto_rawDescGZIP(), []int{18, 0} +} + +func (x *DirectStoryReplyMessage_TextReply) GetText() *Text { + if x != nil { + return x.Text + } + return nil +} + +func (x *DirectStoryReplyMessage_TextReply) GetLongText() *FilePointer { + if x != nil { + return x.LongText + } + return nil +} + +type PaymentNotification_TransactionDetails struct { + state protoimpl.MessageState `protogen:"open.v1"` + // Types that are valid to be assigned to Payment: + // + // *PaymentNotification_TransactionDetails_Transaction_ + // *PaymentNotification_TransactionDetails_FailedTransaction_ + Payment isPaymentNotification_TransactionDetails_Payment `protobuf_oneof:"payment"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *PaymentNotification_TransactionDetails) Reset() { + *x = PaymentNotification_TransactionDetails{} + mi := &file_backuppb_Backup_proto_msgTypes[105] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *PaymentNotification_TransactionDetails) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*PaymentNotification_TransactionDetails) ProtoMessage() {} + +func (x *PaymentNotification_TransactionDetails) ProtoReflect() protoreflect.Message { + mi := &file_backuppb_Backup_proto_msgTypes[105] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use PaymentNotification_TransactionDetails.ProtoReflect.Descriptor instead. +func (*PaymentNotification_TransactionDetails) Descriptor() ([]byte, []int) { + return file_backuppb_Backup_proto_rawDescGZIP(), []int{19, 0} +} + +func (x *PaymentNotification_TransactionDetails) GetPayment() isPaymentNotification_TransactionDetails_Payment { + if x != nil { + return x.Payment + } + return nil +} + +func (x *PaymentNotification_TransactionDetails) GetTransaction() *PaymentNotification_TransactionDetails_Transaction { + if x != nil { + if x, ok := x.Payment.(*PaymentNotification_TransactionDetails_Transaction_); ok { + return x.Transaction + } + } + return nil +} + +func (x *PaymentNotification_TransactionDetails) GetFailedTransaction() *PaymentNotification_TransactionDetails_FailedTransaction { + if x != nil { + if x, ok := x.Payment.(*PaymentNotification_TransactionDetails_FailedTransaction_); ok { + return x.FailedTransaction + } + } + return nil +} + +type isPaymentNotification_TransactionDetails_Payment interface { + isPaymentNotification_TransactionDetails_Payment() +} + +type PaymentNotification_TransactionDetails_Transaction_ struct { + Transaction *PaymentNotification_TransactionDetails_Transaction `protobuf:"bytes,1,opt,name=transaction,proto3,oneof"` +} + +type PaymentNotification_TransactionDetails_FailedTransaction_ struct { + FailedTransaction *PaymentNotification_TransactionDetails_FailedTransaction `protobuf:"bytes,2,opt,name=failedTransaction,proto3,oneof"` +} + +func (*PaymentNotification_TransactionDetails_Transaction_) isPaymentNotification_TransactionDetails_Payment() { +} + +func (*PaymentNotification_TransactionDetails_FailedTransaction_) isPaymentNotification_TransactionDetails_Payment() { +} + +type PaymentNotification_TransactionDetails_MobileCoinTxoIdentification struct { + state protoimpl.MessageState `protogen:"open.v1"` + PublicKey [][]byte `protobuf:"bytes,1,rep,name=publicKey,proto3" json:"publicKey,omitempty"` // for received transactions + KeyImages [][]byte `protobuf:"bytes,2,rep,name=keyImages,proto3" json:"keyImages,omitempty"` // for sent transactions + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *PaymentNotification_TransactionDetails_MobileCoinTxoIdentification) Reset() { + *x = PaymentNotification_TransactionDetails_MobileCoinTxoIdentification{} + mi := &file_backuppb_Backup_proto_msgTypes[106] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *PaymentNotification_TransactionDetails_MobileCoinTxoIdentification) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*PaymentNotification_TransactionDetails_MobileCoinTxoIdentification) ProtoMessage() {} + +func (x *PaymentNotification_TransactionDetails_MobileCoinTxoIdentification) ProtoReflect() protoreflect.Message { + mi := &file_backuppb_Backup_proto_msgTypes[106] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use PaymentNotification_TransactionDetails_MobileCoinTxoIdentification.ProtoReflect.Descriptor instead. +func (*PaymentNotification_TransactionDetails_MobileCoinTxoIdentification) Descriptor() ([]byte, []int) { + return file_backuppb_Backup_proto_rawDescGZIP(), []int{19, 0, 0} +} + +func (x *PaymentNotification_TransactionDetails_MobileCoinTxoIdentification) GetPublicKey() [][]byte { + if x != nil { + return x.PublicKey + } + return nil +} + +func (x *PaymentNotification_TransactionDetails_MobileCoinTxoIdentification) GetKeyImages() [][]byte { + if x != nil { + return x.KeyImages + } + return nil +} + +type PaymentNotification_TransactionDetails_FailedTransaction struct { + state protoimpl.MessageState `protogen:"open.v1"` + Reason PaymentNotification_TransactionDetails_FailedTransaction_FailureReason `protobuf:"varint,1,opt,name=reason,proto3,enum=signal.backup.PaymentNotification_TransactionDetails_FailedTransaction_FailureReason" json:"reason,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *PaymentNotification_TransactionDetails_FailedTransaction) Reset() { + *x = PaymentNotification_TransactionDetails_FailedTransaction{} + mi := &file_backuppb_Backup_proto_msgTypes[107] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *PaymentNotification_TransactionDetails_FailedTransaction) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*PaymentNotification_TransactionDetails_FailedTransaction) ProtoMessage() {} + +func (x *PaymentNotification_TransactionDetails_FailedTransaction) ProtoReflect() protoreflect.Message { + mi := &file_backuppb_Backup_proto_msgTypes[107] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use PaymentNotification_TransactionDetails_FailedTransaction.ProtoReflect.Descriptor instead. +func (*PaymentNotification_TransactionDetails_FailedTransaction) Descriptor() ([]byte, []int) { + return file_backuppb_Backup_proto_rawDescGZIP(), []int{19, 0, 1} +} + +func (x *PaymentNotification_TransactionDetails_FailedTransaction) GetReason() PaymentNotification_TransactionDetails_FailedTransaction_FailureReason { + if x != nil { + return x.Reason + } + return PaymentNotification_TransactionDetails_FailedTransaction_GENERIC +} + +type PaymentNotification_TransactionDetails_Transaction struct { + state protoimpl.MessageState `protogen:"open.v1"` + Status PaymentNotification_TransactionDetails_Transaction_Status `protobuf:"varint,1,opt,name=status,proto3,enum=signal.backup.PaymentNotification_TransactionDetails_Transaction_Status" json:"status,omitempty"` + // This identification is used to map the payment table to the ledger + // and is likely required otherwise we may have issues reconciling with + // the ledger + MobileCoinIdentification *PaymentNotification_TransactionDetails_MobileCoinTxoIdentification `protobuf:"bytes,2,opt,name=mobileCoinIdentification,proto3" json:"mobileCoinIdentification,omitempty"` + Timestamp *uint64 `protobuf:"varint,3,opt,name=timestamp,proto3,oneof" json:"timestamp,omitempty"` + BlockIndex *uint64 `protobuf:"varint,4,opt,name=blockIndex,proto3,oneof" json:"blockIndex,omitempty"` + BlockTimestamp *uint64 `protobuf:"varint,5,opt,name=blockTimestamp,proto3,oneof" json:"blockTimestamp,omitempty"` + Transaction []byte `protobuf:"bytes,6,opt,name=transaction,proto3,oneof" json:"transaction,omitempty"` // mobile coin blobs + Receipt []byte `protobuf:"bytes,7,opt,name=receipt,proto3,oneof" json:"receipt,omitempty"` // mobile coin blobs + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *PaymentNotification_TransactionDetails_Transaction) Reset() { + *x = PaymentNotification_TransactionDetails_Transaction{} + mi := &file_backuppb_Backup_proto_msgTypes[108] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *PaymentNotification_TransactionDetails_Transaction) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*PaymentNotification_TransactionDetails_Transaction) ProtoMessage() {} + +func (x *PaymentNotification_TransactionDetails_Transaction) ProtoReflect() protoreflect.Message { + mi := &file_backuppb_Backup_proto_msgTypes[108] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use PaymentNotification_TransactionDetails_Transaction.ProtoReflect.Descriptor instead. +func (*PaymentNotification_TransactionDetails_Transaction) Descriptor() ([]byte, []int) { + return file_backuppb_Backup_proto_rawDescGZIP(), []int{19, 0, 2} +} + +func (x *PaymentNotification_TransactionDetails_Transaction) GetStatus() PaymentNotification_TransactionDetails_Transaction_Status { + if x != nil { + return x.Status + } + return PaymentNotification_TransactionDetails_Transaction_INITIAL +} + +func (x *PaymentNotification_TransactionDetails_Transaction) GetMobileCoinIdentification() *PaymentNotification_TransactionDetails_MobileCoinTxoIdentification { + if x != nil { + return x.MobileCoinIdentification + } + return nil +} + +func (x *PaymentNotification_TransactionDetails_Transaction) GetTimestamp() uint64 { + if x != nil && x.Timestamp != nil { + return *x.Timestamp + } + return 0 +} + +func (x *PaymentNotification_TransactionDetails_Transaction) GetBlockIndex() uint64 { + if x != nil && x.BlockIndex != nil { + return *x.BlockIndex + } + return 0 +} + +func (x *PaymentNotification_TransactionDetails_Transaction) GetBlockTimestamp() uint64 { + if x != nil && x.BlockTimestamp != nil { + return *x.BlockTimestamp + } + return 0 +} + +func (x *PaymentNotification_TransactionDetails_Transaction) GetTransaction() []byte { + if x != nil { + return x.Transaction + } + return nil +} + +func (x *PaymentNotification_TransactionDetails_Transaction) GetReceipt() []byte { + if x != nil { + return x.Receipt + } + return nil +} + +type ContactAttachment_Name struct { + state protoimpl.MessageState `protogen:"open.v1"` + GivenName string `protobuf:"bytes,1,opt,name=givenName,proto3" json:"givenName,omitempty"` + FamilyName string `protobuf:"bytes,2,opt,name=familyName,proto3" json:"familyName,omitempty"` + Prefix string `protobuf:"bytes,3,opt,name=prefix,proto3" json:"prefix,omitempty"` + Suffix string `protobuf:"bytes,4,opt,name=suffix,proto3" json:"suffix,omitempty"` + MiddleName string `protobuf:"bytes,5,opt,name=middleName,proto3" json:"middleName,omitempty"` + Nickname string `protobuf:"bytes,6,opt,name=nickname,proto3" json:"nickname,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ContactAttachment_Name) Reset() { + *x = ContactAttachment_Name{} + mi := &file_backuppb_Backup_proto_msgTypes[109] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ContactAttachment_Name) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ContactAttachment_Name) ProtoMessage() {} + +func (x *ContactAttachment_Name) ProtoReflect() protoreflect.Message { + mi := &file_backuppb_Backup_proto_msgTypes[109] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ContactAttachment_Name.ProtoReflect.Descriptor instead. +func (*ContactAttachment_Name) Descriptor() ([]byte, []int) { + return file_backuppb_Backup_proto_rawDescGZIP(), []int{22, 0} +} + +func (x *ContactAttachment_Name) GetGivenName() string { + if x != nil { + return x.GivenName + } + return "" +} + +func (x *ContactAttachment_Name) GetFamilyName() string { + if x != nil { + return x.FamilyName + } + return "" +} + +func (x *ContactAttachment_Name) GetPrefix() string { + if x != nil { + return x.Prefix + } + return "" +} + +func (x *ContactAttachment_Name) GetSuffix() string { + if x != nil { + return x.Suffix + } + return "" +} + +func (x *ContactAttachment_Name) GetMiddleName() string { + if x != nil { + return x.MiddleName + } + return "" +} + +func (x *ContactAttachment_Name) GetNickname() string { + if x != nil { + return x.Nickname + } + return "" +} + +type ContactAttachment_Phone struct { + state protoimpl.MessageState `protogen:"open.v1"` + Value string `protobuf:"bytes,1,opt,name=value,proto3" json:"value,omitempty"` + Type ContactAttachment_Phone_Type `protobuf:"varint,2,opt,name=type,proto3,enum=signal.backup.ContactAttachment_Phone_Type" json:"type,omitempty"` + Label string `protobuf:"bytes,3,opt,name=label,proto3" json:"label,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ContactAttachment_Phone) Reset() { + *x = ContactAttachment_Phone{} + mi := &file_backuppb_Backup_proto_msgTypes[110] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ContactAttachment_Phone) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ContactAttachment_Phone) ProtoMessage() {} + +func (x *ContactAttachment_Phone) ProtoReflect() protoreflect.Message { + mi := &file_backuppb_Backup_proto_msgTypes[110] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ContactAttachment_Phone.ProtoReflect.Descriptor instead. +func (*ContactAttachment_Phone) Descriptor() ([]byte, []int) { + return file_backuppb_Backup_proto_rawDescGZIP(), []int{22, 1} +} + +func (x *ContactAttachment_Phone) GetValue() string { + if x != nil { + return x.Value + } + return "" +} + +func (x *ContactAttachment_Phone) GetType() ContactAttachment_Phone_Type { + if x != nil { + return x.Type + } + return ContactAttachment_Phone_UNKNOWN +} + +func (x *ContactAttachment_Phone) GetLabel() string { + if x != nil { + return x.Label + } + return "" +} + +type ContactAttachment_Email struct { + state protoimpl.MessageState `protogen:"open.v1"` + Value string `protobuf:"bytes,1,opt,name=value,proto3" json:"value,omitempty"` + Type ContactAttachment_Email_Type `protobuf:"varint,2,opt,name=type,proto3,enum=signal.backup.ContactAttachment_Email_Type" json:"type,omitempty"` + Label string `protobuf:"bytes,3,opt,name=label,proto3" json:"label,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ContactAttachment_Email) Reset() { + *x = ContactAttachment_Email{} + mi := &file_backuppb_Backup_proto_msgTypes[111] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ContactAttachment_Email) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ContactAttachment_Email) ProtoMessage() {} + +func (x *ContactAttachment_Email) ProtoReflect() protoreflect.Message { + mi := &file_backuppb_Backup_proto_msgTypes[111] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ContactAttachment_Email.ProtoReflect.Descriptor instead. +func (*ContactAttachment_Email) Descriptor() ([]byte, []int) { + return file_backuppb_Backup_proto_rawDescGZIP(), []int{22, 2} +} + +func (x *ContactAttachment_Email) GetValue() string { + if x != nil { + return x.Value + } + return "" +} + +func (x *ContactAttachment_Email) GetType() ContactAttachment_Email_Type { + if x != nil { + return x.Type + } + return ContactAttachment_Email_UNKNOWN +} + +func (x *ContactAttachment_Email) GetLabel() string { + if x != nil { + return x.Label + } + return "" +} + +type ContactAttachment_PostalAddress struct { + state protoimpl.MessageState `protogen:"open.v1"` + Type ContactAttachment_PostalAddress_Type `protobuf:"varint,1,opt,name=type,proto3,enum=signal.backup.ContactAttachment_PostalAddress_Type" json:"type,omitempty"` + Label string `protobuf:"bytes,2,opt,name=label,proto3" json:"label,omitempty"` + Street string `protobuf:"bytes,3,opt,name=street,proto3" json:"street,omitempty"` + Pobox string `protobuf:"bytes,4,opt,name=pobox,proto3" json:"pobox,omitempty"` + Neighborhood string `protobuf:"bytes,5,opt,name=neighborhood,proto3" json:"neighborhood,omitempty"` + City string `protobuf:"bytes,6,opt,name=city,proto3" json:"city,omitempty"` + Region string `protobuf:"bytes,7,opt,name=region,proto3" json:"region,omitempty"` + Postcode string `protobuf:"bytes,8,opt,name=postcode,proto3" json:"postcode,omitempty"` + Country string `protobuf:"bytes,9,opt,name=country,proto3" json:"country,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ContactAttachment_PostalAddress) Reset() { + *x = ContactAttachment_PostalAddress{} + mi := &file_backuppb_Backup_proto_msgTypes[112] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ContactAttachment_PostalAddress) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ContactAttachment_PostalAddress) ProtoMessage() {} + +func (x *ContactAttachment_PostalAddress) ProtoReflect() protoreflect.Message { + mi := &file_backuppb_Backup_proto_msgTypes[112] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ContactAttachment_PostalAddress.ProtoReflect.Descriptor instead. +func (*ContactAttachment_PostalAddress) Descriptor() ([]byte, []int) { + return file_backuppb_Backup_proto_rawDescGZIP(), []int{22, 3} +} + +func (x *ContactAttachment_PostalAddress) GetType() ContactAttachment_PostalAddress_Type { + if x != nil { + return x.Type + } + return ContactAttachment_PostalAddress_UNKNOWN +} + +func (x *ContactAttachment_PostalAddress) GetLabel() string { + if x != nil { + return x.Label + } + return "" +} + +func (x *ContactAttachment_PostalAddress) GetStreet() string { + if x != nil { + return x.Street + } + return "" +} + +func (x *ContactAttachment_PostalAddress) GetPobox() string { + if x != nil { + return x.Pobox + } + return "" +} + +func (x *ContactAttachment_PostalAddress) GetNeighborhood() string { + if x != nil { + return x.Neighborhood + } + return "" +} + +func (x *ContactAttachment_PostalAddress) GetCity() string { + if x != nil { + return x.City + } + return "" +} + +func (x *ContactAttachment_PostalAddress) GetRegion() string { + if x != nil { + return x.Region + } + return "" +} + +func (x *ContactAttachment_PostalAddress) GetPostcode() string { + if x != nil { + return x.Postcode + } + return "" +} + +func (x *ContactAttachment_PostalAddress) GetCountry() string { + if x != nil { + return x.Country + } + return "" +} + +// References attachments in the backup (media) storage tier. +type FilePointer_BackupLocator struct { + state protoimpl.MessageState `protogen:"open.v1"` + MediaName string `protobuf:"bytes,1,opt,name=mediaName,proto3" json:"mediaName,omitempty"` + // If present, the cdn number of the succesful upload. + // If empty/0, may still have been uploaded, and clients + // can discover the cdn number via the list endpoint. + CdnNumber *uint32 `protobuf:"varint,2,opt,name=cdnNumber,proto3,oneof" json:"cdnNumber,omitempty"` + Key []byte `protobuf:"bytes,3,opt,name=key,proto3" json:"key,omitempty"` + Digest []byte `protobuf:"bytes,4,opt,name=digest,proto3" json:"digest,omitempty"` + Size uint32 `protobuf:"varint,5,opt,name=size,proto3" json:"size,omitempty"` + // Fallback in case backup tier upload failed. + TransitCdnKey *string `protobuf:"bytes,6,opt,name=transitCdnKey,proto3,oneof" json:"transitCdnKey,omitempty"` + TransitCdnNumber *uint32 `protobuf:"varint,7,opt,name=transitCdnNumber,proto3,oneof" json:"transitCdnNumber,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *FilePointer_BackupLocator) Reset() { + *x = FilePointer_BackupLocator{} + mi := &file_backuppb_Backup_proto_msgTypes[113] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *FilePointer_BackupLocator) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*FilePointer_BackupLocator) ProtoMessage() {} + +func (x *FilePointer_BackupLocator) ProtoReflect() protoreflect.Message { + mi := &file_backuppb_Backup_proto_msgTypes[113] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use FilePointer_BackupLocator.ProtoReflect.Descriptor instead. +func (*FilePointer_BackupLocator) Descriptor() ([]byte, []int) { + return file_backuppb_Backup_proto_rawDescGZIP(), []int{28, 0} +} + +func (x *FilePointer_BackupLocator) GetMediaName() string { + if x != nil { + return x.MediaName + } + return "" +} + +func (x *FilePointer_BackupLocator) GetCdnNumber() uint32 { + if x != nil && x.CdnNumber != nil { + return *x.CdnNumber + } + return 0 +} + +func (x *FilePointer_BackupLocator) GetKey() []byte { + if x != nil { + return x.Key + } + return nil +} + +func (x *FilePointer_BackupLocator) GetDigest() []byte { + if x != nil { + return x.Digest + } + return nil +} + +func (x *FilePointer_BackupLocator) GetSize() uint32 { + if x != nil { + return x.Size + } + return 0 +} + +func (x *FilePointer_BackupLocator) GetTransitCdnKey() string { + if x != nil && x.TransitCdnKey != nil { + return *x.TransitCdnKey + } + return "" +} + +func (x *FilePointer_BackupLocator) GetTransitCdnNumber() uint32 { + if x != nil && x.TransitCdnNumber != nil { + return *x.TransitCdnNumber + } + return 0 +} + +// References attachments in the transit storage tier. +// May be downloaded or not when the backup is generated; +// primarily for free-tier users who cannot copy the +// attachments to the backup (media) storage tier. +type FilePointer_AttachmentLocator struct { + state protoimpl.MessageState `protogen:"open.v1"` + CdnKey string `protobuf:"bytes,1,opt,name=cdnKey,proto3" json:"cdnKey,omitempty"` + CdnNumber uint32 `protobuf:"varint,2,opt,name=cdnNumber,proto3" json:"cdnNumber,omitempty"` + UploadTimestamp *uint64 `protobuf:"varint,3,opt,name=uploadTimestamp,proto3,oneof" json:"uploadTimestamp,omitempty"` + Key []byte `protobuf:"bytes,4,opt,name=key,proto3" json:"key,omitempty"` + Digest []byte `protobuf:"bytes,5,opt,name=digest,proto3" json:"digest,omitempty"` + Size uint32 `protobuf:"varint,6,opt,name=size,proto3" json:"size,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *FilePointer_AttachmentLocator) Reset() { + *x = FilePointer_AttachmentLocator{} + mi := &file_backuppb_Backup_proto_msgTypes[114] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *FilePointer_AttachmentLocator) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*FilePointer_AttachmentLocator) ProtoMessage() {} + +func (x *FilePointer_AttachmentLocator) ProtoReflect() protoreflect.Message { + mi := &file_backuppb_Backup_proto_msgTypes[114] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use FilePointer_AttachmentLocator.ProtoReflect.Descriptor instead. +func (*FilePointer_AttachmentLocator) Descriptor() ([]byte, []int) { + return file_backuppb_Backup_proto_rawDescGZIP(), []int{28, 1} +} + +func (x *FilePointer_AttachmentLocator) GetCdnKey() string { + if x != nil { + return x.CdnKey + } + return "" +} + +func (x *FilePointer_AttachmentLocator) GetCdnNumber() uint32 { + if x != nil { + return x.CdnNumber + } + return 0 +} + +func (x *FilePointer_AttachmentLocator) GetUploadTimestamp() uint64 { + if x != nil && x.UploadTimestamp != nil { + return *x.UploadTimestamp + } + return 0 +} + +func (x *FilePointer_AttachmentLocator) GetKey() []byte { + if x != nil { + return x.Key + } + return nil +} + +func (x *FilePointer_AttachmentLocator) GetDigest() []byte { + if x != nil { + return x.Digest + } + return nil +} + +func (x *FilePointer_AttachmentLocator) GetSize() uint32 { + if x != nil { + return x.Size + } + return 0 +} + +// References attachments that are invalid in such a way where download +// cannot be attempted. Could range from missing digests to missing +// CDN keys or anything else that makes download attempts impossible. +// This serves as a 'tombstone' so that the UX can show that an attachment +// did exist, but for whatever reason it's not retrievable. +type FilePointer_InvalidAttachmentLocator struct { + state protoimpl.MessageState `protogen:"open.v1"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *FilePointer_InvalidAttachmentLocator) Reset() { + *x = FilePointer_InvalidAttachmentLocator{} + mi := &file_backuppb_Backup_proto_msgTypes[115] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *FilePointer_InvalidAttachmentLocator) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*FilePointer_InvalidAttachmentLocator) ProtoMessage() {} + +func (x *FilePointer_InvalidAttachmentLocator) ProtoReflect() protoreflect.Message { + mi := &file_backuppb_Backup_proto_msgTypes[115] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use FilePointer_InvalidAttachmentLocator.ProtoReflect.Descriptor instead. +func (*FilePointer_InvalidAttachmentLocator) Descriptor() ([]byte, []int) { + return file_backuppb_Backup_proto_rawDescGZIP(), []int{28, 2} +} + +type Quote_QuotedAttachment struct { + state protoimpl.MessageState `protogen:"open.v1"` + ContentType *string `protobuf:"bytes,1,opt,name=contentType,proto3,oneof" json:"contentType,omitempty"` + FileName *string `protobuf:"bytes,2,opt,name=fileName,proto3,oneof" json:"fileName,omitempty"` + Thumbnail *MessageAttachment `protobuf:"bytes,3,opt,name=thumbnail,proto3,oneof" json:"thumbnail,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *Quote_QuotedAttachment) Reset() { + *x = Quote_QuotedAttachment{} + mi := &file_backuppb_Backup_proto_msgTypes[116] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *Quote_QuotedAttachment) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Quote_QuotedAttachment) ProtoMessage() {} + +func (x *Quote_QuotedAttachment) ProtoReflect() protoreflect.Message { + mi := &file_backuppb_Backup_proto_msgTypes[116] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Quote_QuotedAttachment.ProtoReflect.Descriptor instead. +func (*Quote_QuotedAttachment) Descriptor() ([]byte, []int) { + return file_backuppb_Backup_proto_rawDescGZIP(), []int{29, 0} +} + +func (x *Quote_QuotedAttachment) GetContentType() string { + if x != nil && x.ContentType != nil { + return *x.ContentType + } + return "" +} + +func (x *Quote_QuotedAttachment) GetFileName() string { + if x != nil && x.FileName != nil { + return *x.FileName + } + return "" +} + +func (x *Quote_QuotedAttachment) GetThumbnail() *MessageAttachment { + if x != nil { + return x.Thumbnail + } + return nil +} + +type GroupChangeChatUpdate_Update struct { + state protoimpl.MessageState `protogen:"open.v1"` + // Types that are valid to be assigned to Update: + // + // *GroupChangeChatUpdate_Update_GenericGroupUpdate + // *GroupChangeChatUpdate_Update_GroupCreationUpdate + // *GroupChangeChatUpdate_Update_GroupNameUpdate + // *GroupChangeChatUpdate_Update_GroupAvatarUpdate + // *GroupChangeChatUpdate_Update_GroupDescriptionUpdate + // *GroupChangeChatUpdate_Update_GroupMembershipAccessLevelChangeUpdate + // *GroupChangeChatUpdate_Update_GroupAttributesAccessLevelChangeUpdate + // *GroupChangeChatUpdate_Update_GroupAnnouncementOnlyChangeUpdate + // *GroupChangeChatUpdate_Update_GroupAdminStatusUpdate + // *GroupChangeChatUpdate_Update_GroupMemberLeftUpdate + // *GroupChangeChatUpdate_Update_GroupMemberRemovedUpdate + // *GroupChangeChatUpdate_Update_SelfInvitedToGroupUpdate + // *GroupChangeChatUpdate_Update_SelfInvitedOtherUserToGroupUpdate + // *GroupChangeChatUpdate_Update_GroupUnknownInviteeUpdate + // *GroupChangeChatUpdate_Update_GroupInvitationAcceptedUpdate + // *GroupChangeChatUpdate_Update_GroupInvitationDeclinedUpdate + // *GroupChangeChatUpdate_Update_GroupMemberJoinedUpdate + // *GroupChangeChatUpdate_Update_GroupMemberAddedUpdate + // *GroupChangeChatUpdate_Update_GroupSelfInvitationRevokedUpdate + // *GroupChangeChatUpdate_Update_GroupInvitationRevokedUpdate + // *GroupChangeChatUpdate_Update_GroupJoinRequestUpdate + // *GroupChangeChatUpdate_Update_GroupJoinRequestApprovalUpdate + // *GroupChangeChatUpdate_Update_GroupJoinRequestCanceledUpdate + // *GroupChangeChatUpdate_Update_GroupInviteLinkResetUpdate + // *GroupChangeChatUpdate_Update_GroupInviteLinkEnabledUpdate + // *GroupChangeChatUpdate_Update_GroupInviteLinkAdminApprovalUpdate + // *GroupChangeChatUpdate_Update_GroupInviteLinkDisabledUpdate + // *GroupChangeChatUpdate_Update_GroupMemberJoinedByLinkUpdate + // *GroupChangeChatUpdate_Update_GroupV2MigrationUpdate + // *GroupChangeChatUpdate_Update_GroupV2MigrationSelfInvitedUpdate + // *GroupChangeChatUpdate_Update_GroupV2MigrationInvitedMembersUpdate + // *GroupChangeChatUpdate_Update_GroupV2MigrationDroppedMembersUpdate + // *GroupChangeChatUpdate_Update_GroupSequenceOfRequestsAndCancelsUpdate + // *GroupChangeChatUpdate_Update_GroupExpirationTimerUpdate + Update isGroupChangeChatUpdate_Update_Update `protobuf_oneof:"update"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *GroupChangeChatUpdate_Update) Reset() { + *x = GroupChangeChatUpdate_Update{} + mi := &file_backuppb_Backup_proto_msgTypes[117] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *GroupChangeChatUpdate_Update) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GroupChangeChatUpdate_Update) ProtoMessage() {} + +func (x *GroupChangeChatUpdate_Update) ProtoReflect() protoreflect.Message { + mi := &file_backuppb_Backup_proto_msgTypes[117] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GroupChangeChatUpdate_Update.ProtoReflect.Descriptor instead. +func (*GroupChangeChatUpdate_Update) Descriptor() ([]byte, []int) { + return file_backuppb_Backup_proto_rawDescGZIP(), []int{41, 0} +} + +func (x *GroupChangeChatUpdate_Update) GetUpdate() isGroupChangeChatUpdate_Update_Update { + if x != nil { + return x.Update + } + return nil +} + +func (x *GroupChangeChatUpdate_Update) GetGenericGroupUpdate() *GenericGroupUpdate { + if x != nil { + if x, ok := x.Update.(*GroupChangeChatUpdate_Update_GenericGroupUpdate); ok { + return x.GenericGroupUpdate + } + } + return nil +} + +func (x *GroupChangeChatUpdate_Update) GetGroupCreationUpdate() *GroupCreationUpdate { + if x != nil { + if x, ok := x.Update.(*GroupChangeChatUpdate_Update_GroupCreationUpdate); ok { + return x.GroupCreationUpdate + } + } + return nil +} + +func (x *GroupChangeChatUpdate_Update) GetGroupNameUpdate() *GroupNameUpdate { + if x != nil { + if x, ok := x.Update.(*GroupChangeChatUpdate_Update_GroupNameUpdate); ok { + return x.GroupNameUpdate + } + } + return nil +} + +func (x *GroupChangeChatUpdate_Update) GetGroupAvatarUpdate() *GroupAvatarUpdate { + if x != nil { + if x, ok := x.Update.(*GroupChangeChatUpdate_Update_GroupAvatarUpdate); ok { + return x.GroupAvatarUpdate + } + } + return nil +} + +func (x *GroupChangeChatUpdate_Update) GetGroupDescriptionUpdate() *GroupDescriptionUpdate { + if x != nil { + if x, ok := x.Update.(*GroupChangeChatUpdate_Update_GroupDescriptionUpdate); ok { + return x.GroupDescriptionUpdate + } + } + return nil +} + +func (x *GroupChangeChatUpdate_Update) GetGroupMembershipAccessLevelChangeUpdate() *GroupMembershipAccessLevelChangeUpdate { + if x != nil { + if x, ok := x.Update.(*GroupChangeChatUpdate_Update_GroupMembershipAccessLevelChangeUpdate); ok { + return x.GroupMembershipAccessLevelChangeUpdate + } + } + return nil +} + +func (x *GroupChangeChatUpdate_Update) GetGroupAttributesAccessLevelChangeUpdate() *GroupAttributesAccessLevelChangeUpdate { + if x != nil { + if x, ok := x.Update.(*GroupChangeChatUpdate_Update_GroupAttributesAccessLevelChangeUpdate); ok { + return x.GroupAttributesAccessLevelChangeUpdate + } + } + return nil +} + +func (x *GroupChangeChatUpdate_Update) GetGroupAnnouncementOnlyChangeUpdate() *GroupAnnouncementOnlyChangeUpdate { + if x != nil { + if x, ok := x.Update.(*GroupChangeChatUpdate_Update_GroupAnnouncementOnlyChangeUpdate); ok { + return x.GroupAnnouncementOnlyChangeUpdate + } + } + return nil +} + +func (x *GroupChangeChatUpdate_Update) GetGroupAdminStatusUpdate() *GroupAdminStatusUpdate { + if x != nil { + if x, ok := x.Update.(*GroupChangeChatUpdate_Update_GroupAdminStatusUpdate); ok { + return x.GroupAdminStatusUpdate + } + } + return nil +} + +func (x *GroupChangeChatUpdate_Update) GetGroupMemberLeftUpdate() *GroupMemberLeftUpdate { + if x != nil { + if x, ok := x.Update.(*GroupChangeChatUpdate_Update_GroupMemberLeftUpdate); ok { + return x.GroupMemberLeftUpdate + } + } + return nil +} + +func (x *GroupChangeChatUpdate_Update) GetGroupMemberRemovedUpdate() *GroupMemberRemovedUpdate { + if x != nil { + if x, ok := x.Update.(*GroupChangeChatUpdate_Update_GroupMemberRemovedUpdate); ok { + return x.GroupMemberRemovedUpdate + } + } + return nil +} + +func (x *GroupChangeChatUpdate_Update) GetSelfInvitedToGroupUpdate() *SelfInvitedToGroupUpdate { + if x != nil { + if x, ok := x.Update.(*GroupChangeChatUpdate_Update_SelfInvitedToGroupUpdate); ok { + return x.SelfInvitedToGroupUpdate + } + } + return nil +} + +func (x *GroupChangeChatUpdate_Update) GetSelfInvitedOtherUserToGroupUpdate() *SelfInvitedOtherUserToGroupUpdate { + if x != nil { + if x, ok := x.Update.(*GroupChangeChatUpdate_Update_SelfInvitedOtherUserToGroupUpdate); ok { + return x.SelfInvitedOtherUserToGroupUpdate + } + } + return nil +} + +func (x *GroupChangeChatUpdate_Update) GetGroupUnknownInviteeUpdate() *GroupUnknownInviteeUpdate { + if x != nil { + if x, ok := x.Update.(*GroupChangeChatUpdate_Update_GroupUnknownInviteeUpdate); ok { + return x.GroupUnknownInviteeUpdate + } + } + return nil +} + +func (x *GroupChangeChatUpdate_Update) GetGroupInvitationAcceptedUpdate() *GroupInvitationAcceptedUpdate { + if x != nil { + if x, ok := x.Update.(*GroupChangeChatUpdate_Update_GroupInvitationAcceptedUpdate); ok { + return x.GroupInvitationAcceptedUpdate + } + } + return nil +} + +func (x *GroupChangeChatUpdate_Update) GetGroupInvitationDeclinedUpdate() *GroupInvitationDeclinedUpdate { + if x != nil { + if x, ok := x.Update.(*GroupChangeChatUpdate_Update_GroupInvitationDeclinedUpdate); ok { + return x.GroupInvitationDeclinedUpdate + } + } + return nil +} + +func (x *GroupChangeChatUpdate_Update) GetGroupMemberJoinedUpdate() *GroupMemberJoinedUpdate { + if x != nil { + if x, ok := x.Update.(*GroupChangeChatUpdate_Update_GroupMemberJoinedUpdate); ok { + return x.GroupMemberJoinedUpdate + } + } + return nil +} + +func (x *GroupChangeChatUpdate_Update) GetGroupMemberAddedUpdate() *GroupMemberAddedUpdate { + if x != nil { + if x, ok := x.Update.(*GroupChangeChatUpdate_Update_GroupMemberAddedUpdate); ok { + return x.GroupMemberAddedUpdate + } + } + return nil +} + +func (x *GroupChangeChatUpdate_Update) GetGroupSelfInvitationRevokedUpdate() *GroupSelfInvitationRevokedUpdate { + if x != nil { + if x, ok := x.Update.(*GroupChangeChatUpdate_Update_GroupSelfInvitationRevokedUpdate); ok { + return x.GroupSelfInvitationRevokedUpdate + } + } + return nil +} + +func (x *GroupChangeChatUpdate_Update) GetGroupInvitationRevokedUpdate() *GroupInvitationRevokedUpdate { + if x != nil { + if x, ok := x.Update.(*GroupChangeChatUpdate_Update_GroupInvitationRevokedUpdate); ok { + return x.GroupInvitationRevokedUpdate + } + } + return nil +} + +func (x *GroupChangeChatUpdate_Update) GetGroupJoinRequestUpdate() *GroupJoinRequestUpdate { + if x != nil { + if x, ok := x.Update.(*GroupChangeChatUpdate_Update_GroupJoinRequestUpdate); ok { + return x.GroupJoinRequestUpdate + } + } + return nil +} + +func (x *GroupChangeChatUpdate_Update) GetGroupJoinRequestApprovalUpdate() *GroupJoinRequestApprovalUpdate { + if x != nil { + if x, ok := x.Update.(*GroupChangeChatUpdate_Update_GroupJoinRequestApprovalUpdate); ok { + return x.GroupJoinRequestApprovalUpdate + } + } + return nil +} + +func (x *GroupChangeChatUpdate_Update) GetGroupJoinRequestCanceledUpdate() *GroupJoinRequestCanceledUpdate { + if x != nil { + if x, ok := x.Update.(*GroupChangeChatUpdate_Update_GroupJoinRequestCanceledUpdate); ok { + return x.GroupJoinRequestCanceledUpdate + } + } + return nil +} + +func (x *GroupChangeChatUpdate_Update) GetGroupInviteLinkResetUpdate() *GroupInviteLinkResetUpdate { + if x != nil { + if x, ok := x.Update.(*GroupChangeChatUpdate_Update_GroupInviteLinkResetUpdate); ok { + return x.GroupInviteLinkResetUpdate + } + } + return nil +} + +func (x *GroupChangeChatUpdate_Update) GetGroupInviteLinkEnabledUpdate() *GroupInviteLinkEnabledUpdate { + if x != nil { + if x, ok := x.Update.(*GroupChangeChatUpdate_Update_GroupInviteLinkEnabledUpdate); ok { + return x.GroupInviteLinkEnabledUpdate + } + } + return nil +} + +func (x *GroupChangeChatUpdate_Update) GetGroupInviteLinkAdminApprovalUpdate() *GroupInviteLinkAdminApprovalUpdate { + if x != nil { + if x, ok := x.Update.(*GroupChangeChatUpdate_Update_GroupInviteLinkAdminApprovalUpdate); ok { + return x.GroupInviteLinkAdminApprovalUpdate + } + } + return nil +} + +func (x *GroupChangeChatUpdate_Update) GetGroupInviteLinkDisabledUpdate() *GroupInviteLinkDisabledUpdate { + if x != nil { + if x, ok := x.Update.(*GroupChangeChatUpdate_Update_GroupInviteLinkDisabledUpdate); ok { + return x.GroupInviteLinkDisabledUpdate + } + } + return nil +} + +func (x *GroupChangeChatUpdate_Update) GetGroupMemberJoinedByLinkUpdate() *GroupMemberJoinedByLinkUpdate { + if x != nil { + if x, ok := x.Update.(*GroupChangeChatUpdate_Update_GroupMemberJoinedByLinkUpdate); ok { + return x.GroupMemberJoinedByLinkUpdate + } + } + return nil +} + +func (x *GroupChangeChatUpdate_Update) GetGroupV2MigrationUpdate() *GroupV2MigrationUpdate { + if x != nil { + if x, ok := x.Update.(*GroupChangeChatUpdate_Update_GroupV2MigrationUpdate); ok { + return x.GroupV2MigrationUpdate + } + } + return nil +} + +func (x *GroupChangeChatUpdate_Update) GetGroupV2MigrationSelfInvitedUpdate() *GroupV2MigrationSelfInvitedUpdate { + if x != nil { + if x, ok := x.Update.(*GroupChangeChatUpdate_Update_GroupV2MigrationSelfInvitedUpdate); ok { + return x.GroupV2MigrationSelfInvitedUpdate + } + } + return nil +} + +func (x *GroupChangeChatUpdate_Update) GetGroupV2MigrationInvitedMembersUpdate() *GroupV2MigrationInvitedMembersUpdate { + if x != nil { + if x, ok := x.Update.(*GroupChangeChatUpdate_Update_GroupV2MigrationInvitedMembersUpdate); ok { + return x.GroupV2MigrationInvitedMembersUpdate + } + } + return nil +} + +func (x *GroupChangeChatUpdate_Update) GetGroupV2MigrationDroppedMembersUpdate() *GroupV2MigrationDroppedMembersUpdate { + if x != nil { + if x, ok := x.Update.(*GroupChangeChatUpdate_Update_GroupV2MigrationDroppedMembersUpdate); ok { + return x.GroupV2MigrationDroppedMembersUpdate + } + } + return nil +} + +func (x *GroupChangeChatUpdate_Update) GetGroupSequenceOfRequestsAndCancelsUpdate() *GroupSequenceOfRequestsAndCancelsUpdate { + if x != nil { + if x, ok := x.Update.(*GroupChangeChatUpdate_Update_GroupSequenceOfRequestsAndCancelsUpdate); ok { + return x.GroupSequenceOfRequestsAndCancelsUpdate + } + } + return nil +} + +func (x *GroupChangeChatUpdate_Update) GetGroupExpirationTimerUpdate() *GroupExpirationTimerUpdate { + if x != nil { + if x, ok := x.Update.(*GroupChangeChatUpdate_Update_GroupExpirationTimerUpdate); ok { + return x.GroupExpirationTimerUpdate + } + } + return nil +} + +type isGroupChangeChatUpdate_Update_Update interface { + isGroupChangeChatUpdate_Update_Update() +} + +type GroupChangeChatUpdate_Update_GenericGroupUpdate struct { + GenericGroupUpdate *GenericGroupUpdate `protobuf:"bytes,1,opt,name=genericGroupUpdate,proto3,oneof"` +} + +type GroupChangeChatUpdate_Update_GroupCreationUpdate struct { + GroupCreationUpdate *GroupCreationUpdate `protobuf:"bytes,2,opt,name=groupCreationUpdate,proto3,oneof"` +} + +type GroupChangeChatUpdate_Update_GroupNameUpdate struct { + GroupNameUpdate *GroupNameUpdate `protobuf:"bytes,3,opt,name=groupNameUpdate,proto3,oneof"` +} + +type GroupChangeChatUpdate_Update_GroupAvatarUpdate struct { + GroupAvatarUpdate *GroupAvatarUpdate `protobuf:"bytes,4,opt,name=groupAvatarUpdate,proto3,oneof"` +} + +type GroupChangeChatUpdate_Update_GroupDescriptionUpdate struct { + GroupDescriptionUpdate *GroupDescriptionUpdate `protobuf:"bytes,5,opt,name=groupDescriptionUpdate,proto3,oneof"` +} + +type GroupChangeChatUpdate_Update_GroupMembershipAccessLevelChangeUpdate struct { + GroupMembershipAccessLevelChangeUpdate *GroupMembershipAccessLevelChangeUpdate `protobuf:"bytes,6,opt,name=groupMembershipAccessLevelChangeUpdate,proto3,oneof"` +} + +type GroupChangeChatUpdate_Update_GroupAttributesAccessLevelChangeUpdate struct { + GroupAttributesAccessLevelChangeUpdate *GroupAttributesAccessLevelChangeUpdate `protobuf:"bytes,7,opt,name=groupAttributesAccessLevelChangeUpdate,proto3,oneof"` +} + +type GroupChangeChatUpdate_Update_GroupAnnouncementOnlyChangeUpdate struct { + GroupAnnouncementOnlyChangeUpdate *GroupAnnouncementOnlyChangeUpdate `protobuf:"bytes,8,opt,name=groupAnnouncementOnlyChangeUpdate,proto3,oneof"` +} + +type GroupChangeChatUpdate_Update_GroupAdminStatusUpdate struct { + GroupAdminStatusUpdate *GroupAdminStatusUpdate `protobuf:"bytes,9,opt,name=groupAdminStatusUpdate,proto3,oneof"` +} + +type GroupChangeChatUpdate_Update_GroupMemberLeftUpdate struct { + GroupMemberLeftUpdate *GroupMemberLeftUpdate `protobuf:"bytes,10,opt,name=groupMemberLeftUpdate,proto3,oneof"` +} + +type GroupChangeChatUpdate_Update_GroupMemberRemovedUpdate struct { + GroupMemberRemovedUpdate *GroupMemberRemovedUpdate `protobuf:"bytes,11,opt,name=groupMemberRemovedUpdate,proto3,oneof"` +} + +type GroupChangeChatUpdate_Update_SelfInvitedToGroupUpdate struct { + SelfInvitedToGroupUpdate *SelfInvitedToGroupUpdate `protobuf:"bytes,12,opt,name=selfInvitedToGroupUpdate,proto3,oneof"` +} + +type GroupChangeChatUpdate_Update_SelfInvitedOtherUserToGroupUpdate struct { + SelfInvitedOtherUserToGroupUpdate *SelfInvitedOtherUserToGroupUpdate `protobuf:"bytes,13,opt,name=selfInvitedOtherUserToGroupUpdate,proto3,oneof"` +} + +type GroupChangeChatUpdate_Update_GroupUnknownInviteeUpdate struct { + GroupUnknownInviteeUpdate *GroupUnknownInviteeUpdate `protobuf:"bytes,14,opt,name=groupUnknownInviteeUpdate,proto3,oneof"` +} + +type GroupChangeChatUpdate_Update_GroupInvitationAcceptedUpdate struct { + GroupInvitationAcceptedUpdate *GroupInvitationAcceptedUpdate `protobuf:"bytes,15,opt,name=groupInvitationAcceptedUpdate,proto3,oneof"` +} + +type GroupChangeChatUpdate_Update_GroupInvitationDeclinedUpdate struct { + GroupInvitationDeclinedUpdate *GroupInvitationDeclinedUpdate `protobuf:"bytes,16,opt,name=groupInvitationDeclinedUpdate,proto3,oneof"` +} + +type GroupChangeChatUpdate_Update_GroupMemberJoinedUpdate struct { + GroupMemberJoinedUpdate *GroupMemberJoinedUpdate `protobuf:"bytes,17,opt,name=groupMemberJoinedUpdate,proto3,oneof"` +} + +type GroupChangeChatUpdate_Update_GroupMemberAddedUpdate struct { + GroupMemberAddedUpdate *GroupMemberAddedUpdate `protobuf:"bytes,18,opt,name=groupMemberAddedUpdate,proto3,oneof"` +} + +type GroupChangeChatUpdate_Update_GroupSelfInvitationRevokedUpdate struct { + GroupSelfInvitationRevokedUpdate *GroupSelfInvitationRevokedUpdate `protobuf:"bytes,19,opt,name=groupSelfInvitationRevokedUpdate,proto3,oneof"` +} + +type GroupChangeChatUpdate_Update_GroupInvitationRevokedUpdate struct { + GroupInvitationRevokedUpdate *GroupInvitationRevokedUpdate `protobuf:"bytes,20,opt,name=groupInvitationRevokedUpdate,proto3,oneof"` +} + +type GroupChangeChatUpdate_Update_GroupJoinRequestUpdate struct { + GroupJoinRequestUpdate *GroupJoinRequestUpdate `protobuf:"bytes,21,opt,name=groupJoinRequestUpdate,proto3,oneof"` +} + +type GroupChangeChatUpdate_Update_GroupJoinRequestApprovalUpdate struct { + GroupJoinRequestApprovalUpdate *GroupJoinRequestApprovalUpdate `protobuf:"bytes,22,opt,name=groupJoinRequestApprovalUpdate,proto3,oneof"` +} + +type GroupChangeChatUpdate_Update_GroupJoinRequestCanceledUpdate struct { + GroupJoinRequestCanceledUpdate *GroupJoinRequestCanceledUpdate `protobuf:"bytes,23,opt,name=groupJoinRequestCanceledUpdate,proto3,oneof"` +} + +type GroupChangeChatUpdate_Update_GroupInviteLinkResetUpdate struct { + GroupInviteLinkResetUpdate *GroupInviteLinkResetUpdate `protobuf:"bytes,24,opt,name=groupInviteLinkResetUpdate,proto3,oneof"` +} + +type GroupChangeChatUpdate_Update_GroupInviteLinkEnabledUpdate struct { + GroupInviteLinkEnabledUpdate *GroupInviteLinkEnabledUpdate `protobuf:"bytes,25,opt,name=groupInviteLinkEnabledUpdate,proto3,oneof"` +} + +type GroupChangeChatUpdate_Update_GroupInviteLinkAdminApprovalUpdate struct { + GroupInviteLinkAdminApprovalUpdate *GroupInviteLinkAdminApprovalUpdate `protobuf:"bytes,26,opt,name=groupInviteLinkAdminApprovalUpdate,proto3,oneof"` +} + +type GroupChangeChatUpdate_Update_GroupInviteLinkDisabledUpdate struct { + GroupInviteLinkDisabledUpdate *GroupInviteLinkDisabledUpdate `protobuf:"bytes,27,opt,name=groupInviteLinkDisabledUpdate,proto3,oneof"` +} + +type GroupChangeChatUpdate_Update_GroupMemberJoinedByLinkUpdate struct { + GroupMemberJoinedByLinkUpdate *GroupMemberJoinedByLinkUpdate `protobuf:"bytes,28,opt,name=groupMemberJoinedByLinkUpdate,proto3,oneof"` +} + +type GroupChangeChatUpdate_Update_GroupV2MigrationUpdate struct { + GroupV2MigrationUpdate *GroupV2MigrationUpdate `protobuf:"bytes,29,opt,name=groupV2MigrationUpdate,proto3,oneof"` +} + +type GroupChangeChatUpdate_Update_GroupV2MigrationSelfInvitedUpdate struct { + GroupV2MigrationSelfInvitedUpdate *GroupV2MigrationSelfInvitedUpdate `protobuf:"bytes,30,opt,name=groupV2MigrationSelfInvitedUpdate,proto3,oneof"` +} + +type GroupChangeChatUpdate_Update_GroupV2MigrationInvitedMembersUpdate struct { + GroupV2MigrationInvitedMembersUpdate *GroupV2MigrationInvitedMembersUpdate `protobuf:"bytes,31,opt,name=groupV2MigrationInvitedMembersUpdate,proto3,oneof"` +} + +type GroupChangeChatUpdate_Update_GroupV2MigrationDroppedMembersUpdate struct { + GroupV2MigrationDroppedMembersUpdate *GroupV2MigrationDroppedMembersUpdate `protobuf:"bytes,32,opt,name=groupV2MigrationDroppedMembersUpdate,proto3,oneof"` +} + +type GroupChangeChatUpdate_Update_GroupSequenceOfRequestsAndCancelsUpdate struct { + GroupSequenceOfRequestsAndCancelsUpdate *GroupSequenceOfRequestsAndCancelsUpdate `protobuf:"bytes,33,opt,name=groupSequenceOfRequestsAndCancelsUpdate,proto3,oneof"` +} + +type GroupChangeChatUpdate_Update_GroupExpirationTimerUpdate struct { + GroupExpirationTimerUpdate *GroupExpirationTimerUpdate `protobuf:"bytes,34,opt,name=groupExpirationTimerUpdate,proto3,oneof"` +} + +func (*GroupChangeChatUpdate_Update_GenericGroupUpdate) isGroupChangeChatUpdate_Update_Update() {} + +func (*GroupChangeChatUpdate_Update_GroupCreationUpdate) isGroupChangeChatUpdate_Update_Update() {} + +func (*GroupChangeChatUpdate_Update_GroupNameUpdate) isGroupChangeChatUpdate_Update_Update() {} + +func (*GroupChangeChatUpdate_Update_GroupAvatarUpdate) isGroupChangeChatUpdate_Update_Update() {} + +func (*GroupChangeChatUpdate_Update_GroupDescriptionUpdate) isGroupChangeChatUpdate_Update_Update() {} + +func (*GroupChangeChatUpdate_Update_GroupMembershipAccessLevelChangeUpdate) isGroupChangeChatUpdate_Update_Update() { +} + +func (*GroupChangeChatUpdate_Update_GroupAttributesAccessLevelChangeUpdate) isGroupChangeChatUpdate_Update_Update() { +} + +func (*GroupChangeChatUpdate_Update_GroupAnnouncementOnlyChangeUpdate) isGroupChangeChatUpdate_Update_Update() { +} + +func (*GroupChangeChatUpdate_Update_GroupAdminStatusUpdate) isGroupChangeChatUpdate_Update_Update() {} + +func (*GroupChangeChatUpdate_Update_GroupMemberLeftUpdate) isGroupChangeChatUpdate_Update_Update() {} + +func (*GroupChangeChatUpdate_Update_GroupMemberRemovedUpdate) isGroupChangeChatUpdate_Update_Update() { +} + +func (*GroupChangeChatUpdate_Update_SelfInvitedToGroupUpdate) isGroupChangeChatUpdate_Update_Update() { +} + +func (*GroupChangeChatUpdate_Update_SelfInvitedOtherUserToGroupUpdate) isGroupChangeChatUpdate_Update_Update() { +} + +func (*GroupChangeChatUpdate_Update_GroupUnknownInviteeUpdate) isGroupChangeChatUpdate_Update_Update() { +} + +func (*GroupChangeChatUpdate_Update_GroupInvitationAcceptedUpdate) isGroupChangeChatUpdate_Update_Update() { +} + +func (*GroupChangeChatUpdate_Update_GroupInvitationDeclinedUpdate) isGroupChangeChatUpdate_Update_Update() { +} + +func (*GroupChangeChatUpdate_Update_GroupMemberJoinedUpdate) isGroupChangeChatUpdate_Update_Update() { +} + +func (*GroupChangeChatUpdate_Update_GroupMemberAddedUpdate) isGroupChangeChatUpdate_Update_Update() {} + +func (*GroupChangeChatUpdate_Update_GroupSelfInvitationRevokedUpdate) isGroupChangeChatUpdate_Update_Update() { +} + +func (*GroupChangeChatUpdate_Update_GroupInvitationRevokedUpdate) isGroupChangeChatUpdate_Update_Update() { +} + +func (*GroupChangeChatUpdate_Update_GroupJoinRequestUpdate) isGroupChangeChatUpdate_Update_Update() {} + +func (*GroupChangeChatUpdate_Update_GroupJoinRequestApprovalUpdate) isGroupChangeChatUpdate_Update_Update() { +} + +func (*GroupChangeChatUpdate_Update_GroupJoinRequestCanceledUpdate) isGroupChangeChatUpdate_Update_Update() { +} + +func (*GroupChangeChatUpdate_Update_GroupInviteLinkResetUpdate) isGroupChangeChatUpdate_Update_Update() { +} + +func (*GroupChangeChatUpdate_Update_GroupInviteLinkEnabledUpdate) isGroupChangeChatUpdate_Update_Update() { +} + +func (*GroupChangeChatUpdate_Update_GroupInviteLinkAdminApprovalUpdate) isGroupChangeChatUpdate_Update_Update() { +} + +func (*GroupChangeChatUpdate_Update_GroupInviteLinkDisabledUpdate) isGroupChangeChatUpdate_Update_Update() { +} + +func (*GroupChangeChatUpdate_Update_GroupMemberJoinedByLinkUpdate) isGroupChangeChatUpdate_Update_Update() { +} + +func (*GroupChangeChatUpdate_Update_GroupV2MigrationUpdate) isGroupChangeChatUpdate_Update_Update() {} + +func (*GroupChangeChatUpdate_Update_GroupV2MigrationSelfInvitedUpdate) isGroupChangeChatUpdate_Update_Update() { +} + +func (*GroupChangeChatUpdate_Update_GroupV2MigrationInvitedMembersUpdate) isGroupChangeChatUpdate_Update_Update() { +} + +func (*GroupChangeChatUpdate_Update_GroupV2MigrationDroppedMembersUpdate) isGroupChangeChatUpdate_Update_Update() { +} + +func (*GroupChangeChatUpdate_Update_GroupSequenceOfRequestsAndCancelsUpdate) isGroupChangeChatUpdate_Update_Update() { +} + +func (*GroupChangeChatUpdate_Update_GroupExpirationTimerUpdate) isGroupChangeChatUpdate_Update_Update() { +} + +type GroupInvitationRevokedUpdate_Invitee struct { + state protoimpl.MessageState `protogen:"open.v1"` + InviterAci []byte `protobuf:"bytes,1,opt,name=inviterAci,proto3,oneof" json:"inviterAci,omitempty"` + // Prefer to use aci over pni. No need to set + // pni if aci is set. Both can be missing. + InviteeAci []byte `protobuf:"bytes,2,opt,name=inviteeAci,proto3,oneof" json:"inviteeAci,omitempty"` + InviteePni []byte `protobuf:"bytes,3,opt,name=inviteePni,proto3,oneof" json:"inviteePni,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *GroupInvitationRevokedUpdate_Invitee) Reset() { + *x = GroupInvitationRevokedUpdate_Invitee{} + mi := &file_backuppb_Backup_proto_msgTypes[118] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *GroupInvitationRevokedUpdate_Invitee) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GroupInvitationRevokedUpdate_Invitee) ProtoMessage() {} + +func (x *GroupInvitationRevokedUpdate_Invitee) ProtoReflect() protoreflect.Message { + mi := &file_backuppb_Backup_proto_msgTypes[118] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GroupInvitationRevokedUpdate_Invitee.ProtoReflect.Descriptor instead. +func (*GroupInvitationRevokedUpdate_Invitee) Descriptor() ([]byte, []int) { + return file_backuppb_Backup_proto_rawDescGZIP(), []int{61, 0} +} + +func (x *GroupInvitationRevokedUpdate_Invitee) GetInviterAci() []byte { + if x != nil { + return x.InviterAci + } + return nil +} + +func (x *GroupInvitationRevokedUpdate_Invitee) GetInviteeAci() []byte { + if x != nil { + return x.InviteeAci + } + return nil +} + +func (x *GroupInvitationRevokedUpdate_Invitee) GetInviteePni() []byte { + if x != nil { + return x.InviteePni + } + return nil +} + +type ChatStyle_Gradient struct { + state protoimpl.MessageState `protogen:"open.v1"` + Angle uint32 `protobuf:"varint,1,opt,name=angle,proto3" json:"angle,omitempty"` // degrees + Colors []uint32 `protobuf:"fixed32,2,rep,packed,name=colors,proto3" json:"colors,omitempty"` // 0xAARRGGBB + Positions []float32 `protobuf:"fixed32,3,rep,packed,name=positions,proto3" json:"positions,omitempty"` // percent from 0 to 1 + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ChatStyle_Gradient) Reset() { + *x = ChatStyle_Gradient{} + mi := &file_backuppb_Backup_proto_msgTypes[119] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ChatStyle_Gradient) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ChatStyle_Gradient) ProtoMessage() {} + +func (x *ChatStyle_Gradient) ProtoReflect() protoreflect.Message { + mi := &file_backuppb_Backup_proto_msgTypes[119] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ChatStyle_Gradient.ProtoReflect.Descriptor instead. +func (*ChatStyle_Gradient) Descriptor() ([]byte, []int) { + return file_backuppb_Backup_proto_rawDescGZIP(), []int{77, 0} +} + +func (x *ChatStyle_Gradient) GetAngle() uint32 { + if x != nil { + return x.Angle + } + return 0 +} + +func (x *ChatStyle_Gradient) GetColors() []uint32 { + if x != nil { + return x.Colors + } + return nil +} + +func (x *ChatStyle_Gradient) GetPositions() []float32 { + if x != nil { + return x.Positions + } + return nil +} + +type ChatStyle_CustomChatColor struct { + state protoimpl.MessageState `protogen:"open.v1"` + Id uint64 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"` + // Types that are valid to be assigned to Color: + // + // *ChatStyle_CustomChatColor_Solid + // *ChatStyle_CustomChatColor_Gradient + Color isChatStyle_CustomChatColor_Color `protobuf_oneof:"color"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ChatStyle_CustomChatColor) Reset() { + *x = ChatStyle_CustomChatColor{} + mi := &file_backuppb_Backup_proto_msgTypes[120] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ChatStyle_CustomChatColor) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ChatStyle_CustomChatColor) ProtoMessage() {} + +func (x *ChatStyle_CustomChatColor) ProtoReflect() protoreflect.Message { + mi := &file_backuppb_Backup_proto_msgTypes[120] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ChatStyle_CustomChatColor.ProtoReflect.Descriptor instead. +func (*ChatStyle_CustomChatColor) Descriptor() ([]byte, []int) { + return file_backuppb_Backup_proto_rawDescGZIP(), []int{77, 1} +} + +func (x *ChatStyle_CustomChatColor) GetId() uint64 { + if x != nil { + return x.Id + } + return 0 +} + +func (x *ChatStyle_CustomChatColor) GetColor() isChatStyle_CustomChatColor_Color { + if x != nil { + return x.Color + } + return nil +} + +func (x *ChatStyle_CustomChatColor) GetSolid() uint32 { + if x != nil { + if x, ok := x.Color.(*ChatStyle_CustomChatColor_Solid); ok { + return x.Solid + } + } + return 0 +} + +func (x *ChatStyle_CustomChatColor) GetGradient() *ChatStyle_Gradient { + if x != nil { + if x, ok := x.Color.(*ChatStyle_CustomChatColor_Gradient); ok { + return x.Gradient + } + } + return nil +} + +type isChatStyle_CustomChatColor_Color interface { + isChatStyle_CustomChatColor_Color() +} + +type ChatStyle_CustomChatColor_Solid struct { + Solid uint32 `protobuf:"fixed32,2,opt,name=solid,proto3,oneof"` // 0xAARRGGBB +} + +type ChatStyle_CustomChatColor_Gradient struct { + Gradient *ChatStyle_Gradient `protobuf:"bytes,3,opt,name=gradient,proto3,oneof"` +} + +func (*ChatStyle_CustomChatColor_Solid) isChatStyle_CustomChatColor_Color() {} + +func (*ChatStyle_CustomChatColor_Gradient) isChatStyle_CustomChatColor_Color() {} + +type ChatStyle_AutomaticBubbleColor struct { + state protoimpl.MessageState `protogen:"open.v1"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ChatStyle_AutomaticBubbleColor) Reset() { + *x = ChatStyle_AutomaticBubbleColor{} + mi := &file_backuppb_Backup_proto_msgTypes[121] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ChatStyle_AutomaticBubbleColor) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ChatStyle_AutomaticBubbleColor) ProtoMessage() {} + +func (x *ChatStyle_AutomaticBubbleColor) ProtoReflect() protoreflect.Message { + mi := &file_backuppb_Backup_proto_msgTypes[121] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ChatStyle_AutomaticBubbleColor.ProtoReflect.Descriptor instead. +func (*ChatStyle_AutomaticBubbleColor) Descriptor() ([]byte, []int) { + return file_backuppb_Backup_proto_rawDescGZIP(), []int{77, 2} +} + +var File_backuppb_Backup_proto protoreflect.FileDescriptor + +//go:embed Backup.pb.raw +var file_backuppb_Backup_proto_rawDesc []byte + +var ( + file_backuppb_Backup_proto_rawDescOnce sync.Once + file_backuppb_Backup_proto_rawDescData = file_backuppb_Backup_proto_rawDesc +) + +func file_backuppb_Backup_proto_rawDescGZIP() []byte { + file_backuppb_Backup_proto_rawDescOnce.Do(func() { + file_backuppb_Backup_proto_rawDescData = protoimpl.X.CompressGZIP(file_backuppb_Backup_proto_rawDescData) + }) + return file_backuppb_Backup_proto_rawDescData +} + +var file_backuppb_Backup_proto_enumTypes = make([]protoimpl.EnumInfo, 30) +var file_backuppb_Backup_proto_msgTypes = make([]protoimpl.MessageInfo, 122) +var file_backuppb_Backup_proto_goTypes = []any{ + (GroupV2AccessLevel)(0), // 0: signal.backup.GroupV2AccessLevel + (AccountData_PhoneNumberSharingMode)(0), // 1: signal.backup.AccountData.PhoneNumberSharingMode + (AccountData_UsernameLink_Color)(0), // 2: signal.backup.AccountData.UsernameLink.Color + (Contact_IdentityState)(0), // 3: signal.backup.Contact.IdentityState + (Contact_Visibility)(0), // 4: signal.backup.Contact.Visibility + (Group_StorySendMode)(0), // 5: signal.backup.Group.StorySendMode + (Group_Member_Role)(0), // 6: signal.backup.Group.Member.Role + (Group_AccessControl_AccessRequired)(0), // 7: signal.backup.Group.AccessControl.AccessRequired + (CallLink_Restrictions)(0), // 8: signal.backup.CallLink.Restrictions + (AdHocCall_State)(0), // 9: signal.backup.AdHocCall.State + (DistributionList_PrivacyMode)(0), // 10: signal.backup.DistributionList.PrivacyMode + (SendStatus_Failed_FailureReason)(0), // 11: signal.backup.SendStatus.Failed.FailureReason + (PaymentNotification_TransactionDetails_FailedTransaction_FailureReason)(0), // 12: signal.backup.PaymentNotification.TransactionDetails.FailedTransaction.FailureReason + (PaymentNotification_TransactionDetails_Transaction_Status)(0), // 13: signal.backup.PaymentNotification.TransactionDetails.Transaction.Status + (GiftBadge_State)(0), // 14: signal.backup.GiftBadge.State + (ContactAttachment_Phone_Type)(0), // 15: signal.backup.ContactAttachment.Phone.Type + (ContactAttachment_Email_Type)(0), // 16: signal.backup.ContactAttachment.Email.Type + (ContactAttachment_PostalAddress_Type)(0), // 17: signal.backup.ContactAttachment.PostalAddress.Type + (MessageAttachment_Flag)(0), // 18: signal.backup.MessageAttachment.Flag + (Quote_Type)(0), // 19: signal.backup.Quote.Type + (BodyRange_Style)(0), // 20: signal.backup.BodyRange.Style + (IndividualCall_Type)(0), // 21: signal.backup.IndividualCall.Type + (IndividualCall_Direction)(0), // 22: signal.backup.IndividualCall.Direction + (IndividualCall_State)(0), // 23: signal.backup.IndividualCall.State + (GroupCall_State)(0), // 24: signal.backup.GroupCall.State + (SimpleChatUpdate_Type)(0), // 25: signal.backup.SimpleChatUpdate.Type + (ChatStyle_WallpaperPreset)(0), // 26: signal.backup.ChatStyle.WallpaperPreset + (ChatStyle_BubbleColorPreset)(0), // 27: signal.backup.ChatStyle.BubbleColorPreset + (NotificationProfile_DayOfWeek)(0), // 28: signal.backup.NotificationProfile.DayOfWeek + (ChatFolder_FolderType)(0), // 29: signal.backup.ChatFolder.FolderType + (*BackupInfo)(nil), // 30: signal.backup.BackupInfo + (*Frame)(nil), // 31: signal.backup.Frame + (*AccountData)(nil), // 32: signal.backup.AccountData + (*Recipient)(nil), // 33: signal.backup.Recipient + (*Contact)(nil), // 34: signal.backup.Contact + (*Group)(nil), // 35: signal.backup.Group + (*Self)(nil), // 36: signal.backup.Self + (*ReleaseNotes)(nil), // 37: signal.backup.ReleaseNotes + (*Chat)(nil), // 38: signal.backup.Chat + (*CallLink)(nil), // 39: signal.backup.CallLink + (*AdHocCall)(nil), // 40: signal.backup.AdHocCall + (*DistributionListItem)(nil), // 41: signal.backup.DistributionListItem + (*DistributionList)(nil), // 42: signal.backup.DistributionList + (*ChatItem)(nil), // 43: signal.backup.ChatItem + (*SendStatus)(nil), // 44: signal.backup.SendStatus + (*Text)(nil), // 45: signal.backup.Text + (*StandardMessage)(nil), // 46: signal.backup.StandardMessage + (*ContactMessage)(nil), // 47: signal.backup.ContactMessage + (*DirectStoryReplyMessage)(nil), // 48: signal.backup.DirectStoryReplyMessage + (*PaymentNotification)(nil), // 49: signal.backup.PaymentNotification + (*GiftBadge)(nil), // 50: signal.backup.GiftBadge + (*ViewOnceMessage)(nil), // 51: signal.backup.ViewOnceMessage + (*ContactAttachment)(nil), // 52: signal.backup.ContactAttachment + (*StickerMessage)(nil), // 53: signal.backup.StickerMessage + (*RemoteDeletedMessage)(nil), // 54: signal.backup.RemoteDeletedMessage + (*Sticker)(nil), // 55: signal.backup.Sticker + (*LinkPreview)(nil), // 56: signal.backup.LinkPreview + (*MessageAttachment)(nil), // 57: signal.backup.MessageAttachment + (*FilePointer)(nil), // 58: signal.backup.FilePointer + (*Quote)(nil), // 59: signal.backup.Quote + (*BodyRange)(nil), // 60: signal.backup.BodyRange + (*Reaction)(nil), // 61: signal.backup.Reaction + (*ChatUpdateMessage)(nil), // 62: signal.backup.ChatUpdateMessage + (*IndividualCall)(nil), // 63: signal.backup.IndividualCall + (*GroupCall)(nil), // 64: signal.backup.GroupCall + (*SimpleChatUpdate)(nil), // 65: signal.backup.SimpleChatUpdate + (*ExpirationTimerChatUpdate)(nil), // 66: signal.backup.ExpirationTimerChatUpdate + (*ProfileChangeChatUpdate)(nil), // 67: signal.backup.ProfileChangeChatUpdate + (*LearnedProfileChatUpdate)(nil), // 68: signal.backup.LearnedProfileChatUpdate + (*ThreadMergeChatUpdate)(nil), // 69: signal.backup.ThreadMergeChatUpdate + (*SessionSwitchoverChatUpdate)(nil), // 70: signal.backup.SessionSwitchoverChatUpdate + (*GroupChangeChatUpdate)(nil), // 71: signal.backup.GroupChangeChatUpdate + (*GenericGroupUpdate)(nil), // 72: signal.backup.GenericGroupUpdate + (*GroupCreationUpdate)(nil), // 73: signal.backup.GroupCreationUpdate + (*GroupNameUpdate)(nil), // 74: signal.backup.GroupNameUpdate + (*GroupAvatarUpdate)(nil), // 75: signal.backup.GroupAvatarUpdate + (*GroupDescriptionUpdate)(nil), // 76: signal.backup.GroupDescriptionUpdate + (*GroupMembershipAccessLevelChangeUpdate)(nil), // 77: signal.backup.GroupMembershipAccessLevelChangeUpdate + (*GroupAttributesAccessLevelChangeUpdate)(nil), // 78: signal.backup.GroupAttributesAccessLevelChangeUpdate + (*GroupAnnouncementOnlyChangeUpdate)(nil), // 79: signal.backup.GroupAnnouncementOnlyChangeUpdate + (*GroupAdminStatusUpdate)(nil), // 80: signal.backup.GroupAdminStatusUpdate + (*GroupMemberLeftUpdate)(nil), // 81: signal.backup.GroupMemberLeftUpdate + (*GroupMemberRemovedUpdate)(nil), // 82: signal.backup.GroupMemberRemovedUpdate + (*SelfInvitedToGroupUpdate)(nil), // 83: signal.backup.SelfInvitedToGroupUpdate + (*SelfInvitedOtherUserToGroupUpdate)(nil), // 84: signal.backup.SelfInvitedOtherUserToGroupUpdate + (*GroupUnknownInviteeUpdate)(nil), // 85: signal.backup.GroupUnknownInviteeUpdate + (*GroupInvitationAcceptedUpdate)(nil), // 86: signal.backup.GroupInvitationAcceptedUpdate + (*GroupInvitationDeclinedUpdate)(nil), // 87: signal.backup.GroupInvitationDeclinedUpdate + (*GroupMemberJoinedUpdate)(nil), // 88: signal.backup.GroupMemberJoinedUpdate + (*GroupMemberAddedUpdate)(nil), // 89: signal.backup.GroupMemberAddedUpdate + (*GroupSelfInvitationRevokedUpdate)(nil), // 90: signal.backup.GroupSelfInvitationRevokedUpdate + (*GroupInvitationRevokedUpdate)(nil), // 91: signal.backup.GroupInvitationRevokedUpdate + (*GroupJoinRequestUpdate)(nil), // 92: signal.backup.GroupJoinRequestUpdate + (*GroupJoinRequestApprovalUpdate)(nil), // 93: signal.backup.GroupJoinRequestApprovalUpdate + (*GroupJoinRequestCanceledUpdate)(nil), // 94: signal.backup.GroupJoinRequestCanceledUpdate + (*GroupSequenceOfRequestsAndCancelsUpdate)(nil), // 95: signal.backup.GroupSequenceOfRequestsAndCancelsUpdate + (*GroupInviteLinkResetUpdate)(nil), // 96: signal.backup.GroupInviteLinkResetUpdate + (*GroupInviteLinkEnabledUpdate)(nil), // 97: signal.backup.GroupInviteLinkEnabledUpdate + (*GroupInviteLinkAdminApprovalUpdate)(nil), // 98: signal.backup.GroupInviteLinkAdminApprovalUpdate + (*GroupInviteLinkDisabledUpdate)(nil), // 99: signal.backup.GroupInviteLinkDisabledUpdate + (*GroupMemberJoinedByLinkUpdate)(nil), // 100: signal.backup.GroupMemberJoinedByLinkUpdate + (*GroupV2MigrationUpdate)(nil), // 101: signal.backup.GroupV2MigrationUpdate + (*GroupV2MigrationSelfInvitedUpdate)(nil), // 102: signal.backup.GroupV2MigrationSelfInvitedUpdate + (*GroupV2MigrationInvitedMembersUpdate)(nil), // 103: signal.backup.GroupV2MigrationInvitedMembersUpdate + (*GroupV2MigrationDroppedMembersUpdate)(nil), // 104: signal.backup.GroupV2MigrationDroppedMembersUpdate + (*GroupExpirationTimerUpdate)(nil), // 105: signal.backup.GroupExpirationTimerUpdate + (*StickerPack)(nil), // 106: signal.backup.StickerPack + (*ChatStyle)(nil), // 107: signal.backup.ChatStyle + (*NotificationProfile)(nil), // 108: signal.backup.NotificationProfile + (*ChatFolder)(nil), // 109: signal.backup.ChatFolder + (*AccountData_UsernameLink)(nil), // 110: signal.backup.AccountData.UsernameLink + (*AccountData_AccountSettings)(nil), // 111: signal.backup.AccountData.AccountSettings + (*AccountData_SubscriberData)(nil), // 112: signal.backup.AccountData.SubscriberData + (*AccountData_IAPSubscriberData)(nil), // 113: signal.backup.AccountData.IAPSubscriberData + (*Contact_Registered)(nil), // 114: signal.backup.Contact.Registered + (*Contact_NotRegistered)(nil), // 115: signal.backup.Contact.NotRegistered + (*Contact_Name)(nil), // 116: signal.backup.Contact.Name + (*Group_GroupSnapshot)(nil), // 117: signal.backup.Group.GroupSnapshot + (*Group_GroupAttributeBlob)(nil), // 118: signal.backup.Group.GroupAttributeBlob + (*Group_Member)(nil), // 119: signal.backup.Group.Member + (*Group_MemberPendingProfileKey)(nil), // 120: signal.backup.Group.MemberPendingProfileKey + (*Group_MemberPendingAdminApproval)(nil), // 121: signal.backup.Group.MemberPendingAdminApproval + (*Group_MemberBanned)(nil), // 122: signal.backup.Group.MemberBanned + (*Group_AccessControl)(nil), // 123: signal.backup.Group.AccessControl + (*ChatItem_IncomingMessageDetails)(nil), // 124: signal.backup.ChatItem.IncomingMessageDetails + (*ChatItem_OutgoingMessageDetails)(nil), // 125: signal.backup.ChatItem.OutgoingMessageDetails + (*ChatItem_DirectionlessMessageDetails)(nil), // 126: signal.backup.ChatItem.DirectionlessMessageDetails + (*SendStatus_Pending)(nil), // 127: signal.backup.SendStatus.Pending + (*SendStatus_Sent)(nil), // 128: signal.backup.SendStatus.Sent + (*SendStatus_Delivered)(nil), // 129: signal.backup.SendStatus.Delivered + (*SendStatus_Read)(nil), // 130: signal.backup.SendStatus.Read + (*SendStatus_Viewed)(nil), // 131: signal.backup.SendStatus.Viewed + (*SendStatus_Skipped)(nil), // 132: signal.backup.SendStatus.Skipped + (*SendStatus_Failed)(nil), // 133: signal.backup.SendStatus.Failed + (*DirectStoryReplyMessage_TextReply)(nil), // 134: signal.backup.DirectStoryReplyMessage.TextReply + (*PaymentNotification_TransactionDetails)(nil), // 135: signal.backup.PaymentNotification.TransactionDetails + (*PaymentNotification_TransactionDetails_MobileCoinTxoIdentification)(nil), // 136: signal.backup.PaymentNotification.TransactionDetails.MobileCoinTxoIdentification + (*PaymentNotification_TransactionDetails_FailedTransaction)(nil), // 137: signal.backup.PaymentNotification.TransactionDetails.FailedTransaction + (*PaymentNotification_TransactionDetails_Transaction)(nil), // 138: signal.backup.PaymentNotification.TransactionDetails.Transaction + (*ContactAttachment_Name)(nil), // 139: signal.backup.ContactAttachment.Name + (*ContactAttachment_Phone)(nil), // 140: signal.backup.ContactAttachment.Phone + (*ContactAttachment_Email)(nil), // 141: signal.backup.ContactAttachment.Email + (*ContactAttachment_PostalAddress)(nil), // 142: signal.backup.ContactAttachment.PostalAddress + (*FilePointer_BackupLocator)(nil), // 143: signal.backup.FilePointer.BackupLocator + (*FilePointer_AttachmentLocator)(nil), // 144: signal.backup.FilePointer.AttachmentLocator + (*FilePointer_InvalidAttachmentLocator)(nil), // 145: signal.backup.FilePointer.InvalidAttachmentLocator + (*Quote_QuotedAttachment)(nil), // 146: signal.backup.Quote.QuotedAttachment + (*GroupChangeChatUpdate_Update)(nil), // 147: signal.backup.GroupChangeChatUpdate.Update + (*GroupInvitationRevokedUpdate_Invitee)(nil), // 148: signal.backup.GroupInvitationRevokedUpdate.Invitee + (*ChatStyle_Gradient)(nil), // 149: signal.backup.ChatStyle.Gradient + (*ChatStyle_CustomChatColor)(nil), // 150: signal.backup.ChatStyle.CustomChatColor + (*ChatStyle_AutomaticBubbleColor)(nil), // 151: signal.backup.ChatStyle.AutomaticBubbleColor +} +var file_backuppb_Backup_proto_depIdxs = []int32{ + 32, // 0: signal.backup.Frame.account:type_name -> signal.backup.AccountData + 33, // 1: signal.backup.Frame.recipient:type_name -> signal.backup.Recipient + 38, // 2: signal.backup.Frame.chat:type_name -> signal.backup.Chat + 43, // 3: signal.backup.Frame.chatItem:type_name -> signal.backup.ChatItem + 106, // 4: signal.backup.Frame.stickerPack:type_name -> signal.backup.StickerPack + 40, // 5: signal.backup.Frame.adHocCall:type_name -> signal.backup.AdHocCall + 108, // 6: signal.backup.Frame.notificationProfile:type_name -> signal.backup.NotificationProfile + 109, // 7: signal.backup.Frame.chatFolder:type_name -> signal.backup.ChatFolder + 110, // 8: signal.backup.AccountData.usernameLink:type_name -> signal.backup.AccountData.UsernameLink + 112, // 9: signal.backup.AccountData.donationSubscriberData:type_name -> signal.backup.AccountData.SubscriberData + 111, // 10: signal.backup.AccountData.accountSettings:type_name -> signal.backup.AccountData.AccountSettings + 113, // 11: signal.backup.AccountData.backupsSubscriberData:type_name -> signal.backup.AccountData.IAPSubscriberData + 34, // 12: signal.backup.Recipient.contact:type_name -> signal.backup.Contact + 35, // 13: signal.backup.Recipient.group:type_name -> signal.backup.Group + 41, // 14: signal.backup.Recipient.distributionList:type_name -> signal.backup.DistributionListItem + 36, // 15: signal.backup.Recipient.self:type_name -> signal.backup.Self + 37, // 16: signal.backup.Recipient.releaseNotes:type_name -> signal.backup.ReleaseNotes + 39, // 17: signal.backup.Recipient.callLink:type_name -> signal.backup.CallLink + 4, // 18: signal.backup.Contact.visibility:type_name -> signal.backup.Contact.Visibility + 114, // 19: signal.backup.Contact.registered:type_name -> signal.backup.Contact.Registered + 115, // 20: signal.backup.Contact.notRegistered:type_name -> signal.backup.Contact.NotRegistered + 3, // 21: signal.backup.Contact.identityState:type_name -> signal.backup.Contact.IdentityState + 116, // 22: signal.backup.Contact.nickname:type_name -> signal.backup.Contact.Name + 5, // 23: signal.backup.Group.storySendMode:type_name -> signal.backup.Group.StorySendMode + 117, // 24: signal.backup.Group.snapshot:type_name -> signal.backup.Group.GroupSnapshot + 107, // 25: signal.backup.Chat.style:type_name -> signal.backup.ChatStyle + 8, // 26: signal.backup.CallLink.restrictions:type_name -> signal.backup.CallLink.Restrictions + 9, // 27: signal.backup.AdHocCall.state:type_name -> signal.backup.AdHocCall.State + 42, // 28: signal.backup.DistributionListItem.distributionList:type_name -> signal.backup.DistributionList + 10, // 29: signal.backup.DistributionList.privacyMode:type_name -> signal.backup.DistributionList.PrivacyMode + 43, // 30: signal.backup.ChatItem.revisions:type_name -> signal.backup.ChatItem + 124, // 31: signal.backup.ChatItem.incoming:type_name -> signal.backup.ChatItem.IncomingMessageDetails + 125, // 32: signal.backup.ChatItem.outgoing:type_name -> signal.backup.ChatItem.OutgoingMessageDetails + 126, // 33: signal.backup.ChatItem.directionless:type_name -> signal.backup.ChatItem.DirectionlessMessageDetails + 46, // 34: signal.backup.ChatItem.standardMessage:type_name -> signal.backup.StandardMessage + 47, // 35: signal.backup.ChatItem.contactMessage:type_name -> signal.backup.ContactMessage + 53, // 36: signal.backup.ChatItem.stickerMessage:type_name -> signal.backup.StickerMessage + 54, // 37: signal.backup.ChatItem.remoteDeletedMessage:type_name -> signal.backup.RemoteDeletedMessage + 62, // 38: signal.backup.ChatItem.updateMessage:type_name -> signal.backup.ChatUpdateMessage + 49, // 39: signal.backup.ChatItem.paymentNotification:type_name -> signal.backup.PaymentNotification + 50, // 40: signal.backup.ChatItem.giftBadge:type_name -> signal.backup.GiftBadge + 51, // 41: signal.backup.ChatItem.viewOnceMessage:type_name -> signal.backup.ViewOnceMessage + 48, // 42: signal.backup.ChatItem.directStoryReplyMessage:type_name -> signal.backup.DirectStoryReplyMessage + 127, // 43: signal.backup.SendStatus.pending:type_name -> signal.backup.SendStatus.Pending + 128, // 44: signal.backup.SendStatus.sent:type_name -> signal.backup.SendStatus.Sent + 129, // 45: signal.backup.SendStatus.delivered:type_name -> signal.backup.SendStatus.Delivered + 130, // 46: signal.backup.SendStatus.read:type_name -> signal.backup.SendStatus.Read + 131, // 47: signal.backup.SendStatus.viewed:type_name -> signal.backup.SendStatus.Viewed + 132, // 48: signal.backup.SendStatus.skipped:type_name -> signal.backup.SendStatus.Skipped + 133, // 49: signal.backup.SendStatus.failed:type_name -> signal.backup.SendStatus.Failed + 60, // 50: signal.backup.Text.bodyRanges:type_name -> signal.backup.BodyRange + 59, // 51: signal.backup.StandardMessage.quote:type_name -> signal.backup.Quote + 45, // 52: signal.backup.StandardMessage.text:type_name -> signal.backup.Text + 57, // 53: signal.backup.StandardMessage.attachments:type_name -> signal.backup.MessageAttachment + 56, // 54: signal.backup.StandardMessage.linkPreview:type_name -> signal.backup.LinkPreview + 58, // 55: signal.backup.StandardMessage.longText:type_name -> signal.backup.FilePointer + 61, // 56: signal.backup.StandardMessage.reactions:type_name -> signal.backup.Reaction + 52, // 57: signal.backup.ContactMessage.contact:type_name -> signal.backup.ContactAttachment + 61, // 58: signal.backup.ContactMessage.reactions:type_name -> signal.backup.Reaction + 134, // 59: signal.backup.DirectStoryReplyMessage.textReply:type_name -> signal.backup.DirectStoryReplyMessage.TextReply + 61, // 60: signal.backup.DirectStoryReplyMessage.reactions:type_name -> signal.backup.Reaction + 135, // 61: signal.backup.PaymentNotification.transactionDetails:type_name -> signal.backup.PaymentNotification.TransactionDetails + 14, // 62: signal.backup.GiftBadge.state:type_name -> signal.backup.GiftBadge.State + 57, // 63: signal.backup.ViewOnceMessage.attachment:type_name -> signal.backup.MessageAttachment + 61, // 64: signal.backup.ViewOnceMessage.reactions:type_name -> signal.backup.Reaction + 139, // 65: signal.backup.ContactAttachment.name:type_name -> signal.backup.ContactAttachment.Name + 140, // 66: signal.backup.ContactAttachment.number:type_name -> signal.backup.ContactAttachment.Phone + 141, // 67: signal.backup.ContactAttachment.email:type_name -> signal.backup.ContactAttachment.Email + 142, // 68: signal.backup.ContactAttachment.address:type_name -> signal.backup.ContactAttachment.PostalAddress + 58, // 69: signal.backup.ContactAttachment.avatar:type_name -> signal.backup.FilePointer + 55, // 70: signal.backup.StickerMessage.sticker:type_name -> signal.backup.Sticker + 61, // 71: signal.backup.StickerMessage.reactions:type_name -> signal.backup.Reaction + 58, // 72: signal.backup.Sticker.data:type_name -> signal.backup.FilePointer + 58, // 73: signal.backup.LinkPreview.image:type_name -> signal.backup.FilePointer + 58, // 74: signal.backup.MessageAttachment.pointer:type_name -> signal.backup.FilePointer + 18, // 75: signal.backup.MessageAttachment.flag:type_name -> signal.backup.MessageAttachment.Flag + 143, // 76: signal.backup.FilePointer.backupLocator:type_name -> signal.backup.FilePointer.BackupLocator + 144, // 77: signal.backup.FilePointer.attachmentLocator:type_name -> signal.backup.FilePointer.AttachmentLocator + 145, // 78: signal.backup.FilePointer.invalidAttachmentLocator:type_name -> signal.backup.FilePointer.InvalidAttachmentLocator + 45, // 79: signal.backup.Quote.text:type_name -> signal.backup.Text + 146, // 80: signal.backup.Quote.attachments:type_name -> signal.backup.Quote.QuotedAttachment + 19, // 81: signal.backup.Quote.type:type_name -> signal.backup.Quote.Type + 20, // 82: signal.backup.BodyRange.style:type_name -> signal.backup.BodyRange.Style + 65, // 83: signal.backup.ChatUpdateMessage.simpleUpdate:type_name -> signal.backup.SimpleChatUpdate + 71, // 84: signal.backup.ChatUpdateMessage.groupChange:type_name -> signal.backup.GroupChangeChatUpdate + 66, // 85: signal.backup.ChatUpdateMessage.expirationTimerChange:type_name -> signal.backup.ExpirationTimerChatUpdate + 67, // 86: signal.backup.ChatUpdateMessage.profileChange:type_name -> signal.backup.ProfileChangeChatUpdate + 69, // 87: signal.backup.ChatUpdateMessage.threadMerge:type_name -> signal.backup.ThreadMergeChatUpdate + 70, // 88: signal.backup.ChatUpdateMessage.sessionSwitchover:type_name -> signal.backup.SessionSwitchoverChatUpdate + 63, // 89: signal.backup.ChatUpdateMessage.individualCall:type_name -> signal.backup.IndividualCall + 64, // 90: signal.backup.ChatUpdateMessage.groupCall:type_name -> signal.backup.GroupCall + 68, // 91: signal.backup.ChatUpdateMessage.learnedProfileChange:type_name -> signal.backup.LearnedProfileChatUpdate + 21, // 92: signal.backup.IndividualCall.type:type_name -> signal.backup.IndividualCall.Type + 22, // 93: signal.backup.IndividualCall.direction:type_name -> signal.backup.IndividualCall.Direction + 23, // 94: signal.backup.IndividualCall.state:type_name -> signal.backup.IndividualCall.State + 24, // 95: signal.backup.GroupCall.state:type_name -> signal.backup.GroupCall.State + 25, // 96: signal.backup.SimpleChatUpdate.type:type_name -> signal.backup.SimpleChatUpdate.Type + 147, // 97: signal.backup.GroupChangeChatUpdate.updates:type_name -> signal.backup.GroupChangeChatUpdate.Update + 0, // 98: signal.backup.GroupMembershipAccessLevelChangeUpdate.accessLevel:type_name -> signal.backup.GroupV2AccessLevel + 0, // 99: signal.backup.GroupAttributesAccessLevelChangeUpdate.accessLevel:type_name -> signal.backup.GroupV2AccessLevel + 148, // 100: signal.backup.GroupInvitationRevokedUpdate.invitees:type_name -> signal.backup.GroupInvitationRevokedUpdate.Invitee + 26, // 101: signal.backup.ChatStyle.wallpaperPreset:type_name -> signal.backup.ChatStyle.WallpaperPreset + 58, // 102: signal.backup.ChatStyle.wallpaperPhoto:type_name -> signal.backup.FilePointer + 151, // 103: signal.backup.ChatStyle.autoBubbleColor:type_name -> signal.backup.ChatStyle.AutomaticBubbleColor + 27, // 104: signal.backup.ChatStyle.bubbleColorPreset:type_name -> signal.backup.ChatStyle.BubbleColorPreset + 28, // 105: signal.backup.NotificationProfile.scheduleDaysEnabled:type_name -> signal.backup.NotificationProfile.DayOfWeek + 29, // 106: signal.backup.ChatFolder.folderType:type_name -> signal.backup.ChatFolder.FolderType + 2, // 107: signal.backup.AccountData.UsernameLink.color:type_name -> signal.backup.AccountData.UsernameLink.Color + 1, // 108: signal.backup.AccountData.AccountSettings.phoneNumberSharingMode:type_name -> signal.backup.AccountData.PhoneNumberSharingMode + 107, // 109: signal.backup.AccountData.AccountSettings.defaultChatStyle:type_name -> signal.backup.ChatStyle + 150, // 110: signal.backup.AccountData.AccountSettings.customChatColors:type_name -> signal.backup.ChatStyle.CustomChatColor + 118, // 111: signal.backup.Group.GroupSnapshot.title:type_name -> signal.backup.Group.GroupAttributeBlob + 118, // 112: signal.backup.Group.GroupSnapshot.description:type_name -> signal.backup.Group.GroupAttributeBlob + 118, // 113: signal.backup.Group.GroupSnapshot.disappearingMessagesTimer:type_name -> signal.backup.Group.GroupAttributeBlob + 123, // 114: signal.backup.Group.GroupSnapshot.accessControl:type_name -> signal.backup.Group.AccessControl + 119, // 115: signal.backup.Group.GroupSnapshot.members:type_name -> signal.backup.Group.Member + 120, // 116: signal.backup.Group.GroupSnapshot.membersPendingProfileKey:type_name -> signal.backup.Group.MemberPendingProfileKey + 121, // 117: signal.backup.Group.GroupSnapshot.membersPendingAdminApproval:type_name -> signal.backup.Group.MemberPendingAdminApproval + 122, // 118: signal.backup.Group.GroupSnapshot.members_banned:type_name -> signal.backup.Group.MemberBanned + 6, // 119: signal.backup.Group.Member.role:type_name -> signal.backup.Group.Member.Role + 119, // 120: signal.backup.Group.MemberPendingProfileKey.member:type_name -> signal.backup.Group.Member + 7, // 121: signal.backup.Group.AccessControl.attributes:type_name -> signal.backup.Group.AccessControl.AccessRequired + 7, // 122: signal.backup.Group.AccessControl.members:type_name -> signal.backup.Group.AccessControl.AccessRequired + 7, // 123: signal.backup.Group.AccessControl.addFromInviteLink:type_name -> signal.backup.Group.AccessControl.AccessRequired + 44, // 124: signal.backup.ChatItem.OutgoingMessageDetails.sendStatus:type_name -> signal.backup.SendStatus + 11, // 125: signal.backup.SendStatus.Failed.reason:type_name -> signal.backup.SendStatus.Failed.FailureReason + 45, // 126: signal.backup.DirectStoryReplyMessage.TextReply.text:type_name -> signal.backup.Text + 58, // 127: signal.backup.DirectStoryReplyMessage.TextReply.longText:type_name -> signal.backup.FilePointer + 138, // 128: signal.backup.PaymentNotification.TransactionDetails.transaction:type_name -> signal.backup.PaymentNotification.TransactionDetails.Transaction + 137, // 129: signal.backup.PaymentNotification.TransactionDetails.failedTransaction:type_name -> signal.backup.PaymentNotification.TransactionDetails.FailedTransaction + 12, // 130: signal.backup.PaymentNotification.TransactionDetails.FailedTransaction.reason:type_name -> signal.backup.PaymentNotification.TransactionDetails.FailedTransaction.FailureReason + 13, // 131: signal.backup.PaymentNotification.TransactionDetails.Transaction.status:type_name -> signal.backup.PaymentNotification.TransactionDetails.Transaction.Status + 136, // 132: signal.backup.PaymentNotification.TransactionDetails.Transaction.mobileCoinIdentification:type_name -> signal.backup.PaymentNotification.TransactionDetails.MobileCoinTxoIdentification + 15, // 133: signal.backup.ContactAttachment.Phone.type:type_name -> signal.backup.ContactAttachment.Phone.Type + 16, // 134: signal.backup.ContactAttachment.Email.type:type_name -> signal.backup.ContactAttachment.Email.Type + 17, // 135: signal.backup.ContactAttachment.PostalAddress.type:type_name -> signal.backup.ContactAttachment.PostalAddress.Type + 57, // 136: signal.backup.Quote.QuotedAttachment.thumbnail:type_name -> signal.backup.MessageAttachment + 72, // 137: signal.backup.GroupChangeChatUpdate.Update.genericGroupUpdate:type_name -> signal.backup.GenericGroupUpdate + 73, // 138: signal.backup.GroupChangeChatUpdate.Update.groupCreationUpdate:type_name -> signal.backup.GroupCreationUpdate + 74, // 139: signal.backup.GroupChangeChatUpdate.Update.groupNameUpdate:type_name -> signal.backup.GroupNameUpdate + 75, // 140: signal.backup.GroupChangeChatUpdate.Update.groupAvatarUpdate:type_name -> signal.backup.GroupAvatarUpdate + 76, // 141: signal.backup.GroupChangeChatUpdate.Update.groupDescriptionUpdate:type_name -> signal.backup.GroupDescriptionUpdate + 77, // 142: signal.backup.GroupChangeChatUpdate.Update.groupMembershipAccessLevelChangeUpdate:type_name -> signal.backup.GroupMembershipAccessLevelChangeUpdate + 78, // 143: signal.backup.GroupChangeChatUpdate.Update.groupAttributesAccessLevelChangeUpdate:type_name -> signal.backup.GroupAttributesAccessLevelChangeUpdate + 79, // 144: signal.backup.GroupChangeChatUpdate.Update.groupAnnouncementOnlyChangeUpdate:type_name -> signal.backup.GroupAnnouncementOnlyChangeUpdate + 80, // 145: signal.backup.GroupChangeChatUpdate.Update.groupAdminStatusUpdate:type_name -> signal.backup.GroupAdminStatusUpdate + 81, // 146: signal.backup.GroupChangeChatUpdate.Update.groupMemberLeftUpdate:type_name -> signal.backup.GroupMemberLeftUpdate + 82, // 147: signal.backup.GroupChangeChatUpdate.Update.groupMemberRemovedUpdate:type_name -> signal.backup.GroupMemberRemovedUpdate + 83, // 148: signal.backup.GroupChangeChatUpdate.Update.selfInvitedToGroupUpdate:type_name -> signal.backup.SelfInvitedToGroupUpdate + 84, // 149: signal.backup.GroupChangeChatUpdate.Update.selfInvitedOtherUserToGroupUpdate:type_name -> signal.backup.SelfInvitedOtherUserToGroupUpdate + 85, // 150: signal.backup.GroupChangeChatUpdate.Update.groupUnknownInviteeUpdate:type_name -> signal.backup.GroupUnknownInviteeUpdate + 86, // 151: signal.backup.GroupChangeChatUpdate.Update.groupInvitationAcceptedUpdate:type_name -> signal.backup.GroupInvitationAcceptedUpdate + 87, // 152: signal.backup.GroupChangeChatUpdate.Update.groupInvitationDeclinedUpdate:type_name -> signal.backup.GroupInvitationDeclinedUpdate + 88, // 153: signal.backup.GroupChangeChatUpdate.Update.groupMemberJoinedUpdate:type_name -> signal.backup.GroupMemberJoinedUpdate + 89, // 154: signal.backup.GroupChangeChatUpdate.Update.groupMemberAddedUpdate:type_name -> signal.backup.GroupMemberAddedUpdate + 90, // 155: signal.backup.GroupChangeChatUpdate.Update.groupSelfInvitationRevokedUpdate:type_name -> signal.backup.GroupSelfInvitationRevokedUpdate + 91, // 156: signal.backup.GroupChangeChatUpdate.Update.groupInvitationRevokedUpdate:type_name -> signal.backup.GroupInvitationRevokedUpdate + 92, // 157: signal.backup.GroupChangeChatUpdate.Update.groupJoinRequestUpdate:type_name -> signal.backup.GroupJoinRequestUpdate + 93, // 158: signal.backup.GroupChangeChatUpdate.Update.groupJoinRequestApprovalUpdate:type_name -> signal.backup.GroupJoinRequestApprovalUpdate + 94, // 159: signal.backup.GroupChangeChatUpdate.Update.groupJoinRequestCanceledUpdate:type_name -> signal.backup.GroupJoinRequestCanceledUpdate + 96, // 160: signal.backup.GroupChangeChatUpdate.Update.groupInviteLinkResetUpdate:type_name -> signal.backup.GroupInviteLinkResetUpdate + 97, // 161: signal.backup.GroupChangeChatUpdate.Update.groupInviteLinkEnabledUpdate:type_name -> signal.backup.GroupInviteLinkEnabledUpdate + 98, // 162: signal.backup.GroupChangeChatUpdate.Update.groupInviteLinkAdminApprovalUpdate:type_name -> signal.backup.GroupInviteLinkAdminApprovalUpdate + 99, // 163: signal.backup.GroupChangeChatUpdate.Update.groupInviteLinkDisabledUpdate:type_name -> signal.backup.GroupInviteLinkDisabledUpdate + 100, // 164: signal.backup.GroupChangeChatUpdate.Update.groupMemberJoinedByLinkUpdate:type_name -> signal.backup.GroupMemberJoinedByLinkUpdate + 101, // 165: signal.backup.GroupChangeChatUpdate.Update.groupV2MigrationUpdate:type_name -> signal.backup.GroupV2MigrationUpdate + 102, // 166: signal.backup.GroupChangeChatUpdate.Update.groupV2MigrationSelfInvitedUpdate:type_name -> signal.backup.GroupV2MigrationSelfInvitedUpdate + 103, // 167: signal.backup.GroupChangeChatUpdate.Update.groupV2MigrationInvitedMembersUpdate:type_name -> signal.backup.GroupV2MigrationInvitedMembersUpdate + 104, // 168: signal.backup.GroupChangeChatUpdate.Update.groupV2MigrationDroppedMembersUpdate:type_name -> signal.backup.GroupV2MigrationDroppedMembersUpdate + 95, // 169: signal.backup.GroupChangeChatUpdate.Update.groupSequenceOfRequestsAndCancelsUpdate:type_name -> signal.backup.GroupSequenceOfRequestsAndCancelsUpdate + 105, // 170: signal.backup.GroupChangeChatUpdate.Update.groupExpirationTimerUpdate:type_name -> signal.backup.GroupExpirationTimerUpdate + 149, // 171: signal.backup.ChatStyle.CustomChatColor.gradient:type_name -> signal.backup.ChatStyle.Gradient + 172, // [172:172] is the sub-list for method output_type + 172, // [172:172] is the sub-list for method input_type + 172, // [172:172] is the sub-list for extension type_name + 172, // [172:172] is the sub-list for extension extendee + 0, // [0:172] is the sub-list for field type_name +} + +func init() { file_backuppb_Backup_proto_init() } +func file_backuppb_Backup_proto_init() { + if File_backuppb_Backup_proto != nil { + return + } + file_backuppb_Backup_proto_msgTypes[1].OneofWrappers = []any{ + (*Frame_Account)(nil), + (*Frame_Recipient)(nil), + (*Frame_Chat)(nil), + (*Frame_ChatItem)(nil), + (*Frame_StickerPack)(nil), + (*Frame_AdHocCall)(nil), + (*Frame_NotificationProfile)(nil), + (*Frame_ChatFolder)(nil), + } + file_backuppb_Backup_proto_msgTypes[2].OneofWrappers = []any{} + file_backuppb_Backup_proto_msgTypes[3].OneofWrappers = []any{ + (*Recipient_Contact)(nil), + (*Recipient_Group)(nil), + (*Recipient_DistributionList)(nil), + (*Recipient_Self)(nil), + (*Recipient_ReleaseNotes)(nil), + (*Recipient_CallLink)(nil), + } + file_backuppb_Backup_proto_msgTypes[4].OneofWrappers = []any{ + (*Contact_Registered_)(nil), + (*Contact_NotRegistered_)(nil), + } + file_backuppb_Backup_proto_msgTypes[8].OneofWrappers = []any{} + file_backuppb_Backup_proto_msgTypes[9].OneofWrappers = []any{} + file_backuppb_Backup_proto_msgTypes[11].OneofWrappers = []any{ + (*DistributionListItem_DeletionTimestamp)(nil), + (*DistributionListItem_DistributionList)(nil), + } + file_backuppb_Backup_proto_msgTypes[13].OneofWrappers = []any{ + (*ChatItem_Incoming)(nil), + (*ChatItem_Outgoing)(nil), + (*ChatItem_Directionless)(nil), + (*ChatItem_StandardMessage)(nil), + (*ChatItem_ContactMessage)(nil), + (*ChatItem_StickerMessage)(nil), + (*ChatItem_RemoteDeletedMessage)(nil), + (*ChatItem_UpdateMessage)(nil), + (*ChatItem_PaymentNotification)(nil), + (*ChatItem_GiftBadge)(nil), + (*ChatItem_ViewOnceMessage)(nil), + (*ChatItem_DirectStoryReplyMessage)(nil), + } + file_backuppb_Backup_proto_msgTypes[14].OneofWrappers = []any{ + (*SendStatus_Pending_)(nil), + (*SendStatus_Sent_)(nil), + (*SendStatus_Delivered_)(nil), + (*SendStatus_Read_)(nil), + (*SendStatus_Viewed_)(nil), + (*SendStatus_Skipped_)(nil), + (*SendStatus_Failed_)(nil), + } + file_backuppb_Backup_proto_msgTypes[16].OneofWrappers = []any{} + file_backuppb_Backup_proto_msgTypes[18].OneofWrappers = []any{ + (*DirectStoryReplyMessage_TextReply_)(nil), + (*DirectStoryReplyMessage_Emoji)(nil), + } + file_backuppb_Backup_proto_msgTypes[19].OneofWrappers = []any{} + file_backuppb_Backup_proto_msgTypes[22].OneofWrappers = []any{} + file_backuppb_Backup_proto_msgTypes[25].OneofWrappers = []any{} + file_backuppb_Backup_proto_msgTypes[26].OneofWrappers = []any{} + file_backuppb_Backup_proto_msgTypes[27].OneofWrappers = []any{} + file_backuppb_Backup_proto_msgTypes[28].OneofWrappers = []any{ + (*FilePointer_BackupLocator_)(nil), + (*FilePointer_AttachmentLocator_)(nil), + (*FilePointer_InvalidAttachmentLocator_)(nil), + } + file_backuppb_Backup_proto_msgTypes[29].OneofWrappers = []any{} + file_backuppb_Backup_proto_msgTypes[30].OneofWrappers = []any{ + (*BodyRange_MentionAci)(nil), + (*BodyRange_Style_)(nil), + } + file_backuppb_Backup_proto_msgTypes[32].OneofWrappers = []any{ + (*ChatUpdateMessage_SimpleUpdate)(nil), + (*ChatUpdateMessage_GroupChange)(nil), + (*ChatUpdateMessage_ExpirationTimerChange)(nil), + (*ChatUpdateMessage_ProfileChange)(nil), + (*ChatUpdateMessage_ThreadMerge)(nil), + (*ChatUpdateMessage_SessionSwitchover)(nil), + (*ChatUpdateMessage_IndividualCall)(nil), + (*ChatUpdateMessage_GroupCall)(nil), + (*ChatUpdateMessage_LearnedProfileChange)(nil), + } + file_backuppb_Backup_proto_msgTypes[33].OneofWrappers = []any{} + file_backuppb_Backup_proto_msgTypes[34].OneofWrappers = []any{} + file_backuppb_Backup_proto_msgTypes[38].OneofWrappers = []any{ + (*LearnedProfileChatUpdate_E164)(nil), + (*LearnedProfileChatUpdate_Username)(nil), + } + file_backuppb_Backup_proto_msgTypes[42].OneofWrappers = []any{} + file_backuppb_Backup_proto_msgTypes[43].OneofWrappers = []any{} + file_backuppb_Backup_proto_msgTypes[44].OneofWrappers = []any{} + file_backuppb_Backup_proto_msgTypes[45].OneofWrappers = []any{} + file_backuppb_Backup_proto_msgTypes[46].OneofWrappers = []any{} + file_backuppb_Backup_proto_msgTypes[47].OneofWrappers = []any{} + file_backuppb_Backup_proto_msgTypes[48].OneofWrappers = []any{} + file_backuppb_Backup_proto_msgTypes[49].OneofWrappers = []any{} + file_backuppb_Backup_proto_msgTypes[50].OneofWrappers = []any{} + file_backuppb_Backup_proto_msgTypes[52].OneofWrappers = []any{} + file_backuppb_Backup_proto_msgTypes[53].OneofWrappers = []any{} + file_backuppb_Backup_proto_msgTypes[55].OneofWrappers = []any{} + file_backuppb_Backup_proto_msgTypes[56].OneofWrappers = []any{} + file_backuppb_Backup_proto_msgTypes[57].OneofWrappers = []any{} + file_backuppb_Backup_proto_msgTypes[59].OneofWrappers = []any{} + file_backuppb_Backup_proto_msgTypes[60].OneofWrappers = []any{} + file_backuppb_Backup_proto_msgTypes[61].OneofWrappers = []any{} + file_backuppb_Backup_proto_msgTypes[63].OneofWrappers = []any{} + file_backuppb_Backup_proto_msgTypes[66].OneofWrappers = []any{} + file_backuppb_Backup_proto_msgTypes[67].OneofWrappers = []any{} + file_backuppb_Backup_proto_msgTypes[68].OneofWrappers = []any{} + file_backuppb_Backup_proto_msgTypes[69].OneofWrappers = []any{} + file_backuppb_Backup_proto_msgTypes[75].OneofWrappers = []any{} + file_backuppb_Backup_proto_msgTypes[77].OneofWrappers = []any{ + (*ChatStyle_WallpaperPreset_)(nil), + (*ChatStyle_WallpaperPhoto)(nil), + (*ChatStyle_AutoBubbleColor)(nil), + (*ChatStyle_BubbleColorPreset_)(nil), + (*ChatStyle_CustomColorId)(nil), + } + file_backuppb_Backup_proto_msgTypes[78].OneofWrappers = []any{} + file_backuppb_Backup_proto_msgTypes[81].OneofWrappers = []any{} + file_backuppb_Backup_proto_msgTypes[83].OneofWrappers = []any{ + (*AccountData_IAPSubscriberData_PurchaseToken)(nil), + (*AccountData_IAPSubscriberData_OriginalTransactionId)(nil), + } + file_backuppb_Backup_proto_msgTypes[88].OneofWrappers = []any{ + (*Group_GroupAttributeBlob_Title)(nil), + (*Group_GroupAttributeBlob_Avatar)(nil), + (*Group_GroupAttributeBlob_DisappearingMessagesDuration)(nil), + (*Group_GroupAttributeBlob_DescriptionText)(nil), + } + file_backuppb_Backup_proto_msgTypes[94].OneofWrappers = []any{} + file_backuppb_Backup_proto_msgTypes[105].OneofWrappers = []any{ + (*PaymentNotification_TransactionDetails_Transaction_)(nil), + (*PaymentNotification_TransactionDetails_FailedTransaction_)(nil), + } + file_backuppb_Backup_proto_msgTypes[108].OneofWrappers = []any{} + file_backuppb_Backup_proto_msgTypes[113].OneofWrappers = []any{} + file_backuppb_Backup_proto_msgTypes[114].OneofWrappers = []any{} + file_backuppb_Backup_proto_msgTypes[116].OneofWrappers = []any{} + file_backuppb_Backup_proto_msgTypes[117].OneofWrappers = []any{ + (*GroupChangeChatUpdate_Update_GenericGroupUpdate)(nil), + (*GroupChangeChatUpdate_Update_GroupCreationUpdate)(nil), + (*GroupChangeChatUpdate_Update_GroupNameUpdate)(nil), + (*GroupChangeChatUpdate_Update_GroupAvatarUpdate)(nil), + (*GroupChangeChatUpdate_Update_GroupDescriptionUpdate)(nil), + (*GroupChangeChatUpdate_Update_GroupMembershipAccessLevelChangeUpdate)(nil), + (*GroupChangeChatUpdate_Update_GroupAttributesAccessLevelChangeUpdate)(nil), + (*GroupChangeChatUpdate_Update_GroupAnnouncementOnlyChangeUpdate)(nil), + (*GroupChangeChatUpdate_Update_GroupAdminStatusUpdate)(nil), + (*GroupChangeChatUpdate_Update_GroupMemberLeftUpdate)(nil), + (*GroupChangeChatUpdate_Update_GroupMemberRemovedUpdate)(nil), + (*GroupChangeChatUpdate_Update_SelfInvitedToGroupUpdate)(nil), + (*GroupChangeChatUpdate_Update_SelfInvitedOtherUserToGroupUpdate)(nil), + (*GroupChangeChatUpdate_Update_GroupUnknownInviteeUpdate)(nil), + (*GroupChangeChatUpdate_Update_GroupInvitationAcceptedUpdate)(nil), + (*GroupChangeChatUpdate_Update_GroupInvitationDeclinedUpdate)(nil), + (*GroupChangeChatUpdate_Update_GroupMemberJoinedUpdate)(nil), + (*GroupChangeChatUpdate_Update_GroupMemberAddedUpdate)(nil), + (*GroupChangeChatUpdate_Update_GroupSelfInvitationRevokedUpdate)(nil), + (*GroupChangeChatUpdate_Update_GroupInvitationRevokedUpdate)(nil), + (*GroupChangeChatUpdate_Update_GroupJoinRequestUpdate)(nil), + (*GroupChangeChatUpdate_Update_GroupJoinRequestApprovalUpdate)(nil), + (*GroupChangeChatUpdate_Update_GroupJoinRequestCanceledUpdate)(nil), + (*GroupChangeChatUpdate_Update_GroupInviteLinkResetUpdate)(nil), + (*GroupChangeChatUpdate_Update_GroupInviteLinkEnabledUpdate)(nil), + (*GroupChangeChatUpdate_Update_GroupInviteLinkAdminApprovalUpdate)(nil), + (*GroupChangeChatUpdate_Update_GroupInviteLinkDisabledUpdate)(nil), + (*GroupChangeChatUpdate_Update_GroupMemberJoinedByLinkUpdate)(nil), + (*GroupChangeChatUpdate_Update_GroupV2MigrationUpdate)(nil), + (*GroupChangeChatUpdate_Update_GroupV2MigrationSelfInvitedUpdate)(nil), + (*GroupChangeChatUpdate_Update_GroupV2MigrationInvitedMembersUpdate)(nil), + (*GroupChangeChatUpdate_Update_GroupV2MigrationDroppedMembersUpdate)(nil), + (*GroupChangeChatUpdate_Update_GroupSequenceOfRequestsAndCancelsUpdate)(nil), + (*GroupChangeChatUpdate_Update_GroupExpirationTimerUpdate)(nil), + } + file_backuppb_Backup_proto_msgTypes[118].OneofWrappers = []any{} + file_backuppb_Backup_proto_msgTypes[120].OneofWrappers = []any{ + (*ChatStyle_CustomChatColor_Solid)(nil), + (*ChatStyle_CustomChatColor_Gradient)(nil), + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_backuppb_Backup_proto_rawDesc, + NumEnums: 30, + NumMessages: 122, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_backuppb_Backup_proto_goTypes, + DependencyIndexes: file_backuppb_Backup_proto_depIdxs, + EnumInfos: file_backuppb_Backup_proto_enumTypes, + MessageInfos: file_backuppb_Backup_proto_msgTypes, + }.Build() + File_backuppb_Backup_proto = out.File + file_backuppb_Backup_proto_rawDesc = nil + file_backuppb_Backup_proto_goTypes = nil + file_backuppb_Backup_proto_depIdxs = nil +} diff --git a/pkg/signalmeow/protobuf/backuppb/Backup.pb.raw b/pkg/signalmeow/protobuf/backuppb/Backup.pb.raw new file mode 100644 index 0000000000000000000000000000000000000000..fa51eb6b784f0b88b8fbe3fc0af1a0b5b0eb0b1b GIT binary patch literal 31334 zcmc(IOKf9Hdfuf(NmNmksM9Ys`##T%=gwTuXl69`j_nzbZN4ONnj(1*Nwqt1hM~wK ziEfJI@X>u`Ac%nklQ@XszzZ(|8+jn!1x6OmCP;u7i8skEStLP#0NLfW$|8#Z0rLHS z)j6k5okL1)43bT^PSyYa_4@07)n7&N=%U+uwU|sUzFFWu4ky#`d~9WAgR4<@cqnV_ zf0GbG)>lTCW9vX{y>_Rw!FY6#_%QL+q~m>Bw%CyQI?=D6AW|Kj=E+ z@mvyp?%p1(19HcSsj)aXet_=f(Ea?F}Xa^o@s_J~}Wk z9j_jE0kHKok?dV}=RE54(E|gih$_G{i1nFB5ol%Z-W<@V(??HYz^NK2KB)CeB0ZZA zdavAR0}FdVa}XU@Gk^fHjzDAU_D{#XVs|(^*ko*TY|4ue*wG~|tBRES4SuL@r_EXcH&j+Kc*}*n1 z*C#7zt10p@9Fv4~A(XJ1g}ZSenD*CK(5~bgVH_u(RPKKz#E!l`B4#rnh!jBqT@T+ONb0e_Ls>)vi6S)nC-I z?^r33EL7X&Y{J?W8!t{Pt#Wpa3QwH!%j`N8)~l8CayChSqOe@cZdgKW)}4Iqq@3L( z*hZ!HJiA4ujkeRMmb0ncA8(62V+BZ5i~1 zE2BPb`|(tY{*<$%*7`(b=eHBEhK4~ZAmv2LsUJh^mB!S4J#gR5cw?X+dYM%a??UL5 z2D9E6OVYg9!{q2r8_N-NAqrPp6AUp<8733V(YA5 z5ziJQY}x6oJ1l=O8BAT$eAA}e8;|-k-clK76$s6sY<22ls?jWDX8C6P>jQ|mb?CSy zwS?Cn%qGL`ZK2!0a%Xj4($ZeT%*WRf-YeIgoGs>VpTy-XKkZ#(1byB|z>BXXyzA}^ z+w<(Ui3J|Gv&MAry4$-wNXz!(Ypw5z1Js;j<=lRKbTRHu`&f1&aeJ`Cm`m$Pna^Zf zSXo-s{y~OO%wp@8#Q{OyQac{QmPZn0mrx+LmqL&nKNTPF0Nl~Zbi9~w|H}P^)M3qQ z*PS2ianpB!S;yjiP%4gZCPNo<>}~L1><3vUbO)3*0AmCk+`R5iF>hz%zI(6_{N1B( zuaGJl>uZSMrC5SiNo4!(Wp^>06Gt@Xx6s!X8j0F7e!UaHfY{IW7FdNF0%FlMJ9q#d zP9J^M=&DcUuoy;gA`}YG#M92QrOo{$A$G%(outLg*K3f?Qm2Q?2u7Nez1t#9D4D6- zPNKhTTa&;`k-Rn z*d?yoK3xwRyH7;Y{q}c1M|0J4~Qw!(5$M+z(5G9l>_nRC0)T92CyI% zMz+2bavMnD?woGujss1~SH!OJEtCva8rCSazA3T_?!-6#NvCd~ZaR?~BK&Q!uMmy{ ze}Hu9_UV=rts)e77T1Hm%W6&O(4fHj8IeZiXpSW!H;5GG&S}cg3yH`NMaBbb&bxD$ zHRA5kvN^0Mk__vFQLUd7sS(^$cC1JrMz@N`73A$WKCoqpBohtX8fp zGNI+OJ{6A^qp8msWTDOG-J1#Ti=-1@nfp{EscGvWgb=L@LvKUa(1-O{Y)WTLDG&8! ze@|pW<0gSxDj(!Wc0_^j5Nc5go zN+nqH33wil<=>sNaoGQ3ZpBMT3Ow z@*!<&=|F+sw4yM_O1-Ob?5W7GQ9y17+eG9o?;e@q1@6irbG--Ygb@)aNzF#x$?SSO zS7JV%2$O0mNcei{uiT$*icF}^`hnQMPJ#(VW<~nQj0MO(@xS@GR6}lIIKFTsmQ`VK z4!@k0HCxwz1|p;iJY1SXKO(?7bQ^&hFGOIu;wkiHcQSFMY3a^pT{sf#z$nFe@4hdm z1j{;uXaI=QhMtaxD`y!#XaI@Oh5o6>9VsG}3F3~QiLD!#96fTm$l^5huAKBUhH*St z>slNrvUI-LlPvy__kWAQB9QoesP7$KlJ9l!1l5gwt&zG*0< zn8reA&MKM|XB~`QV~>$N(df=*Z^l#UZri7?y3=WE>Me2oZ&&3npq!2fdQS2LX@Ad9uwKM+`mW&i(x~X0&-SuCbHux`lfct zf!LIstgM)K9Q6%n=G{29E-j=;-N~+D4c4J} zyDo>GD~TORUoz$WDAG7|in;%`hN%t7tj~q$dQx77(4wBZ+#(@7I&y#@ble{=5L4r~XPHS?`X^SF{Hn<#1joXCVUd&JZ#Rhk4!rWW|WT$3MbHjE;2-E0^yx<6+B z+jWto&_u*{g|#yE4ssOxCLO(qqQPA+jwX#2|C_99L^`o`>r*bJm6x+?6gA0;qZ! z1yFG;Fo)qhxV$|cPtV957>{O^OO6z>yMzGhDi~;-jTy&|WVGKrFY=>4jsznO#lw;@ zQ%|f>I6vdW)UdIs%_N(ok$GV#ZC32xSraKb#UeFGCd3ryj)6_;eUkIrC7n!FET6DM zehJMYIUaN_!=5o55AqF8$=s$`0*7s7XgbCrQmr348Z7z#0Vb_cFcfd$olu$m3&gJ) z4wyQ0Fi@-4=wQIYjwA8j$u}BK{XAcVUqIm+Z+P~L`O!PaL z{!?0S@&jo~c8}gSRGHrd3~)fvs^dS>2GkyLxb(uLTn-o7ABzpfk{h2-KRV4;9>*Q; z&}Kd<*WgDLvkCi86XIc9JcrzG*a3c=$JfI~DY$UIkEjfBd(bDA?BIZCm30;qW}*p5 zAAMj7)0|o`!%x$v`7QDwV<` zM2ApOLMod=0TH1vn)OmVoVqs%UX@7Rxc(3+-j+TxgVat8D2T?AASZhIIQFotmxs= ziB}IA0WdKI9sJhen0lj=hf^j~(BYp31u7;Yk_eti?q$o7MCh$Y^8wG;R}Aiu>>Ggw z?PY{=f1D7H8m#2)3a%GgTNkQ~ z9iKXBXYy=tLP6-~^o4z~*9o_hYl_G5+u!;HA!dk=kUn0J4?}{@%)FuSngnn(;M{xS z*$M$b7MxrTh|KO#2`^727A%qN7-E{OJ5B7`|9w-4pl#D=k@KtDF=02;bl?!X+nUHw z5F0h=$XP|u)}iu_A!|Jx^6fEG-m#O(pBgUy99AIXUgm18Xc|cdeV|HS`JULMz2%>)nBfSmUD{nPVJZxotJ$jo!iRmOq|DHd zhTN2ZG*=1-i2;b2Bk`)Ql+uc(j~R}dmKZriT-5C6J|SlglZdUQb2!H*46e_8Q*8UQ zcP|7Gr|G&E?AOJnoT7U{V+3kWa=(X|ksKj%2R5;VXDYFB_sCS#+Kft!L;7zqg+w7N zM`7C~kqK3VO)%KcwQ}o4-FXfJ?5TKE!MQ@K(t6o>UVhm*t2EE@t>P)1hAbqJWHzLH z(B8LOB1xezvP&<1azwQ!1&~kl74E(6CSumg)AcIn;^0PQ5ib zP-zAPBo&~eBU!&F(!(GxiOu0?iX{hMW#*EjgCm_WH5`wwII<}ByqR@+jLp%2)rK<^ z*rh(SZ)wU5fMu2@ID&07vNRQBAtg3DJga>4L(|2Mq1O-luOOX59lNQqW0!iT@oFW^ zNmB6IBzXwZ9`<@E8N#%OV|r=-pEdDhiQ2Uq2oj>(thiN&zI8v1eMmFScwn1=2waN| z7+OfTBF5nWGk=CVFZtshokxJwno%MW$)v!YWEU6w7gLAj%nil1-#hDL#mJKJ&71>< zV>U)ch|d#>>sN44z(2J1Q!;!CkHiC+S`+H5{U3#R5M$U`AK^6VhO(s3#uq&IG+RLt z@#Qnfbl0VNIhzScZ2qQ7WDoGkE!isD;AsA$3RhS-uk=z{loh~cOZwuIfZ#Z>vXYF6(F=0>M$y%GDDtj4r1sAW5OyT+sj(8!_5XdAhg z;u#hMvZM%E()wa7kEgx#Y_f+Yi;Ll)Cu3sk2+RisRQt-kt=!PTAbQKSenAegm;FdD ztQ$j#wSP*(TcYdoF}ltR4{@w0&~=Z6RjD=G$H$do1uCy|+^&_HID7i1Ns-p((fW&G zbLJVl6xlj`yAfz4IRv(tIf}0J+X);!`l}LN62%ptzg?p%)*9!NOPZv;J@*50v_UDO zEGVK~ikuhD@j=F}`vvb#3QTKd1O(@WfdbJdBiL(>QBJ@JU(bVm&z9>Bg;lgd0(%cJ zTbYB*$v-=%xNxEhP;GxIHl=k!Mh*_OS`|b*-?0#9YPJh!l~&8kwP?1BMI=ldw<#cs zl#z}U(D|QonVGCFB&nh!?CQ4=LLRT+c|vcfTYyM>2a{s(&*y5T(F5m5#!KeF)0} zB41gCccYgH+L1_z=xpI&4y-_jKxCbozCcX#V@R!GUSi>zlKcayR^Cy$^bJ>73E0pI zmL|X!JLBn9cQp77$%~Yeh%{NfEccHRDoqNSf-|FN7NvDSF&uT7#kjk|#(|^XUBMv) zWx)@=P{%9kivqv1#U+)K3AGLR$zMe8X3*~sU2cwK%(kPIQ1I7JFQZX!2N`6!f1D5- zyi%0fh3t!k*I)U8T=FFDCU^(*X4E`p+9|2}umu$O7xn@?*dR+VVOI>d zF;44ebZUdmbyhE6cgg!4?47MsX|dgG)z7j??l-f@PpRKb>;FN&{~Zp+8#-$uqAF*Y zcINI;By=nTvVli&7{ZS2vE(Q@)66vUDW&YQsYyzgzG&Je+x6yV8G>i8Tq?CFMk#OF8xidP^uk#b-6Fp7qQ+1qwP^*Io(nN>v`XF{K)qVarc4F zNVh4~83y(Ama;ZhaR>N>If8|-;)r#rRIuMz(a3Zd`xY7T@>-wg!hH*I8d;)bvYC0U z;1QaUU~emiAB%@^L2LVu5(suE(zMZWA<;jLQ(rVQRPLX?BBmxk$plsX0un7~#t8}# zzEJKP%Lj;W`AOpIP$UuJ?5c>`3aRHX9DB#?``P~~A<~-TPA4>r=}<{E`jeUsa{Pj{ zBx?3Eu`wWfnfn?I2_;>)%!sXtj5jDoSv6-KD5As3%VGCQ*&e2vjkI!j3}A;*=qUJ2 zcUBs|84br>Bna`8rJQgf8J<0ybdKij#h}jG7URoH>@u<@jFoLy)8FKEO5AKN0WtrMaS8F{U_I_BGLYI@9TEgH(9 zyxFYa(cLfs>(`KWNkkkq;4`2lTi9lP(*D)LcuNP{j=lHpQN7p19~eh4{6WI z=0S<1m_vrjeuQ;tNT5V2f(!>3gYt`J&u@Xn5Hy5eKxh4n3CWkhC-od$vqGCmV&KS3 z(ws$Sk|s;dBp+EBt>tp!VA+-;#XXcVg@v`Yh1dxVvws1UI^iOJM{pq5V|P{o%-U=j zNKR&#Rq-uDdn{@HQBrJhKpnd40TLpv+<7P>$kR;$fw)SVGs=EjmWJWQ<)z$-3ul7Q z{J8u{I4(~qCg~$nr*K~n`Cm=Ig@g0oP$niV*>2>tQc@sEB~5l>xU5OglxfU#m<3a& z>2ikcPz)#}XK=nZzlJ9{B4<#}!<}w1wo`ya`-pB@=dqNrBYg1$dauK_@MK*w^Sp%>O3iT?bf?^^nt$Y>9V{7D#H5+v}T@LQf!(c!{bme)u zb?VgHC#SeWkBK>}*Xqqi9uu=cTM~KntnD?&fb#Ky4enK!; z1HwWZXq>jgOHDN7qbug2u3Tu;1ASZa1wO35ARgj6>=b#=p}AG3{pQW0stKy{lt43< z3~fA_@nru&QtXDuL2^gWX$2AWO>*bEq4pvMrr{;CvAEhjGDl$``>8KT z)bKFjFOhsy8Hc-(v@e51lR&-H*(33gWer|#zzhfSfs|a*iLE1hkGPc?OJxYzKd%%- z7O$Pimqj|Qmkmm-#g)W-yHu%nij;-Pn&KSk0qT1Vs%6_B6s{5Pd+4Q#Q!chDb$X%% zLE}oTSVso(2`J#J-fo@L>1)lt@?y@M&mT_f1!Nu(`i2bHqi?l(tK*k&Nj)LI4IAKG8hK470(E${#0}dc2SSOb7mo-UWrE;;#fc#XATI9{U z7I}+$;PF<6$Y)d9y7Tpb$mAEEiYGYqj+=Tu506d~T?@&YDiLx~4`G_}-vrmh2tAV! zW1e9say_}D2o zPqQfkg&Enw5;`xD!MzPH&1&Rdp5c78iQU_(oTKBVtU$;xz+Ob}nX_$lW;)YMV z(WpB>psn1h7wc6&e6vHtamuP1CfQjwLk3)-S}#6F3%g{kwQJtz9t@-dybNruw@38j16FT|6OS_>311(b1?@p>>`%rt*KR7T;>k^6?L*=2CNPy0vW zV3{t&D$Dm5$dV*~jK45W|3xx3#V8!1C8FE4jLaGhLrl8lY0PtIf` zz@WW^jP*MS@fB`CUb~!K4<_=SVAXx?4#6f+sH#QMQqfExZt+fJ^x&S&1U*9Ji64=1 zXUlp-3UNt~?nL%`bSI<*Kk_4vA>eG?Ysp-JUr&D<8 zObvkESXuJ2f@~lJjy9H(qGsrwAcXmF-@e}(b1zjh^45vzDbNMfIB;ra87bxmt+GD9 zcBgcuI^3YVonrEX)?hpyTK?!x;&?LQDNks7^lF528#x4TqsogcrqeDbBL*HVE+=Nq z#e3WmH^GvZcH;!|t0q=nafyAQVHpluTun5l)sl;oA$YN>Rry%W9j%6OVpM;trLwcH)=jn%cGT&h)(S_1T?sUT$p9JG4*Don%t+{+;WzQ zqM$*IWuo;KQtWMGfUFaZWzBKR<`a*`Kw}Wm{yoTtr5yJXSC9F%Of~Xn-2QSY7lVVQ zHQ5>i;J2#Ft->uWnQHaj<*hEm@mpO6;BV6NqqD)4d|g2`_Z~MFyGbL!Xh+JuNKIg+ zX;r>3^Y_d9+?c7Ac|}*@pM7 z+^dP$zLfBSGVY0m`|{zv`Vxm4*Oxdr3s2d6%=6MD>5L1c^-CqEXZaC=sPwLVCfR?3*i>=kd#VH-a zk>k#Xa6uX3fSeu^l-L#VfTsm1%bG|0R;2#2*ke+GdwVZ3xFmxFy*ECpihCp|Z7(Q| zcD=ACG94WR0qK3FqI<;m>jF|xk-VgQ1nxk}(Mrro`Nne%&kL;GUl>V)vc<7JcZG8$3VKylNcU2UzBm`F*_G zQ@#%yWG+2I@{ z(iJ2KD7uAFYty_0wV_<@QWG8&<%UwJ<>=DWRA@bK%sWE%Ly(D4P z>;*t8*iHj#;4N;M{mc>G9bqSVfNsf)e|0CG=gwBtv0~ zdlAL$w5LN3mhcOcQnP#OtBj820Ooq&2@Bg8WlV75|3k-`x*Ca#N!&*Wo1-l%qEe(w zm7vElB0`(j)lduvYIkZLyWE}jmy|`R)%b$e(>-`r^UFNp8juuGVJF-AmUtlLhgU9j zKlLc%#8t&nj`giUxgT=tLzH8x?5Wxcv7YMPXYL03#LE(Mt$tag)zu^V9W+WI|Fc~` zvVRj<1$1aF6H4*ZR&S7cHR(?9!)myki92RAmAfl`;^ajb9@5Vwfm^`40aZLiKIRR$ z`tA@?^};xKUThCp*yF6~QzrVs-B^~+wDStSJdBER5dG|CV7y~99N>#iF$f|*p z>9BibrYZ)+HJTCwl%r(uPGd&>Yz+PS6)a%RW&>=v7-@U>NuwKoHY=kN-ZbUs4P|=L zlG@z4NWoX>(*+{R#l^WY5{f1N%MZR+KyAwx4z`dh$X}FUi<^4`eg_p(x&Bq;Wcvj< zL~{3xpRb8L9E-Xa{4JD#>>}xf%LvczEO6NXH#yL>9+}x$kW7chm|_`eKBPA(4CSUSx~Gu z0Ey%yWCzNU67Hm`jA=$GmaBQB5g}t5iAWN}$yaK}br5gi2gs1QBTJD;P1$-`PBD^2 z$4(tETLJM}{`{p(ERq1#N;O|ZVv*lE|9+W3w#lvpD4(1(s`*+gn-2QitW=R6mEEzB zMRnrjOZ?tL6A4BbYliyc7uM<(2gyU|xLZV`TeEu@~Fa*^o=kfm1Bm2Lui~YzZ zqO3S?6$|YG-Z$Exe1;07r6_+E~#%I1MYRvk%^#s8(>P`yma_r_n6uvyUh{&M#?E zY96o7W4e&zi*wRpnz*(9eNsHoA7fOBXBc?!zybXf3KEHe`>>=QgXfIM%4Yi%VvZ%w zmin1NQoFd1M;99MbG&WJ>8H5j5)|?C?eySme#n{R@=^btO zJ&5qj0LY$&5Gm#9ZFFQgw(tWl^ud>PUX)8U`N_$&t<$!{l}XCEJ%&sI;07hu;=%N` zLtmRz1Mx?HZ}FuSdDHoyuM0t{M*e7OEJtCn@Z%_WSaW!*-VZ0%N;yU;Eh@nUKP+q zbo-NVDCdGNhiQ0P%Y7|hTmIk(lJ8ZoLUn}We!*i6mE$4>J)Im|XCDd?^dQU=>TzVg z!=xSoSo`GH)bD15;_6Ynw|iv2@O|+K-upPj8_NsahQ%+-+_;A`7r&n8;-O;o`_PB4 bkL2%0|C6;Hd9M``YCi5<;1v)2|DFE}gw`FM literal 0 HcmV?d00001 diff --git a/pkg/signalmeow/protobuf/backuppb/Backup.proto b/pkg/signalmeow/protobuf/backuppb/Backup.proto new file mode 100644 index 0000000..48a6f24 --- /dev/null +++ b/pkg/signalmeow/protobuf/backuppb/Backup.proto @@ -0,0 +1,1260 @@ +syntax = "proto3"; + +package signal.backup; + +option java_package = "org.thoughtcrime.securesms.backup.v2.proto"; +option swift_prefix = "BackupProto_"; + +message BackupInfo { + uint64 version = 1; + uint64 backupTimeMs = 2; + bytes mediaRootBackupKey = 3; // 32-byte random value generated when the backup is uploaded for the first time. + string currentAppVersion = 4; + string firstAppVersion = 5; +} + +// Frames must follow in the following ordering rules: +// +// 1. There is exactly one AccountData and it is the first frame. +// 2. A frame referenced by ID must come before the referencing frame. +// e.g. a Recipient must come before any Chat referencing it. +// 3. All ChatItems must appear in global Chat rendering order. +// (The order in which they were received by the client.) +// 4. ChatFolders must appear in render order (e.g., left to right for +// LTR locales), but can appear anywhere relative to other frames respecting +// rule 2 (after Recipients and Chats). +// +// Recipients, Chats, StickerPacks, AdHocCalls, and NotificationProfiles +// can be in any order. (But must respect rule 2.) +// +// For example, Chats may all be together at the beginning, +// or may each immediately precede its first ChatItem. +message Frame { + oneof item { + AccountData account = 1; + Recipient recipient = 2; + Chat chat = 3; + ChatItem chatItem = 4; + StickerPack stickerPack = 5; + AdHocCall adHocCall = 6; + NotificationProfile notificationProfile = 7; + ChatFolder chatFolder = 8; + } +} + +message AccountData { + enum PhoneNumberSharingMode { + UNKNOWN = 0; + EVERYBODY = 1; + NOBODY = 2; + } + message UsernameLink { + enum Color { + UNKNOWN = 0; + BLUE = 1; + WHITE = 2; + GREY = 3; + OLIVE = 4; + GREEN = 5; + ORANGE = 6; + PINK = 7; + PURPLE = 8; + } + + bytes entropy = 1; // 32 bytes of entropy used for encryption + bytes serverId = 2; // 16 bytes of encoded UUID provided by the server + Color color = 3; + } + + message AccountSettings { + bool readReceipts = 1; + bool sealedSenderIndicators = 2; + bool typingIndicators = 3; + bool linkPreviews = 4; + bool notDiscoverableByPhoneNumber = 5; + bool preferContactAvatars = 6; + uint32 universalExpireTimerSeconds = 7; // 0 means no universal expire timer. + repeated string preferredReactionEmoji = 8; + bool displayBadgesOnProfile = 9; + bool keepMutedChatsArchived = 10; + bool hasSetMyStoriesPrivacy = 11; + bool hasViewedOnboardingStory = 12; + bool storiesDisabled = 13; + optional bool storyViewReceiptsEnabled = 14; + bool hasSeenGroupStoryEducationSheet = 15; + bool hasCompletedUsernameOnboarding = 16; + PhoneNumberSharingMode phoneNumberSharingMode = 17; + ChatStyle defaultChatStyle = 18; + repeated ChatStyle.CustomChatColor customChatColors = 19; + } + + message SubscriberData { + bytes subscriberId = 1; + string currencyCode = 2; + bool manuallyCancelled = 3; + } + + message IAPSubscriberData { + bytes subscriberId = 1; + + oneof iapSubscriptionId { + // Identifies an Android Play Store IAP subscription. + string purchaseToken = 2; + // Identifies an iOS App Store IAP subscription. + uint64 originalTransactionId = 3; + } + } + + bytes profileKey = 1; + optional string username = 2; + UsernameLink usernameLink = 3; + string givenName = 4; + string familyName = 5; + string avatarUrlPath = 6; + SubscriberData donationSubscriberData = 7; + reserved /*backupsSubscriberData*/ 8; // A deprecated format + AccountSettings accountSettings = 9; + IAPSubscriberData backupsSubscriberData = 10; +} + +message Recipient { + uint64 id = 1; // generated id for reference only within this file + oneof destination { + Contact contact = 2; + Group group = 3; + DistributionListItem distributionList = 4; + Self self = 5; + ReleaseNotes releaseNotes = 6; + CallLink callLink = 7; + } +} + +message Contact { + enum IdentityState { + DEFAULT = 0; + VERIFIED = 1; + UNVERIFIED = 2; + } + + message Registered {} + message NotRegistered { + uint64 unregisteredTimestamp = 1; + } + + enum Visibility { + VISIBLE = 0; + HIDDEN = 1; + HIDDEN_MESSAGE_REQUEST = 2; + } + + message Name { + string given = 1; + string family = 2; + } + + optional bytes aci = 1; // should be 16 bytes + optional bytes pni = 2; // should be 16 bytes + optional string username = 3; + optional uint64 e164 = 4; + bool blocked = 5; + Visibility visibility = 6; + + oneof registration { + Registered registered = 7; + NotRegistered notRegistered = 8; + } + + optional bytes profileKey = 9; + bool profileSharing = 10; + optional string profileGivenName = 11; + optional string profileFamilyName = 12; + bool hideStory = 13; + optional bytes identityKey = 14; + IdentityState identityState = 15; + Name nickname = 16; // absent iff both `given` and `family` are empty + string note = 17; +} + +message Group { + enum StorySendMode { + DEFAULT = 0; + DISABLED = 1; + ENABLED = 2; + } + + bytes masterKey = 1; + bool whitelisted = 2; + bool hideStory = 3; + StorySendMode storySendMode = 4; + GroupSnapshot snapshot = 5; + + // These are simply plaintext copies of the groups proto from Groups.proto. + // They should be kept completely in-sync with Groups.proto. + // These exist to allow us to have the latest snapshot of a group during restoration without having to hit the network. + // We would use Groups.proto if we could, but we want a plaintext version to improve export readability. + // For documentation, defer to Groups.proto. The only name change is Group -> GroupSnapshot to avoid the naming conflict. + message GroupSnapshot { + reserved /*publicKey*/ 1; // The field is deprecated in the context of static group state + GroupAttributeBlob title = 2; + GroupAttributeBlob description = 11; + string avatarUrl = 3; + GroupAttributeBlob disappearingMessagesTimer = 4; + AccessControl accessControl = 5; + uint32 version = 6; + repeated Member members = 7; + repeated MemberPendingProfileKey membersPendingProfileKey = 8; + repeated MemberPendingAdminApproval membersPendingAdminApproval = 9; + bytes inviteLinkPassword = 10; + bool announcements_only = 12; + repeated MemberBanned members_banned = 13; + } + + message GroupAttributeBlob { + oneof content { + string title = 1; + bytes avatar = 2; + uint32 disappearingMessagesDuration = 3; + string descriptionText = 4; + } + } + + message Member { + enum Role { + UNKNOWN = 0; + DEFAULT = 1; + ADMINISTRATOR = 2; + } + + bytes userId = 1; + Role role = 2; + reserved /*profileKey*/ 3; // This field is ignored in Backups, in favor of Contact frames for members + reserved /*presentation*/ 4; // This field is deprecated in the context of static group state + uint32 joinedAtVersion = 5; + } + + message MemberPendingProfileKey { + Member member = 1; + bytes addedByUserId = 2; + uint64 timestamp = 3; + } + + message MemberPendingAdminApproval { + bytes userId = 1; + reserved /*profileKey*/ 2; // This field is ignored in Backups, in favor of Contact frames for members + reserved /*presentation*/ 3; // This field is deprecated in the context of static group state + uint64 timestamp = 4; + } + + message MemberBanned { + bytes userId = 1; + uint64 timestamp = 2; + } + + message AccessControl { + enum AccessRequired { + UNKNOWN = 0; + ANY = 1; + MEMBER = 2; + ADMINISTRATOR = 3; + UNSATISFIABLE = 4; + } + + AccessRequired attributes = 1; + AccessRequired members = 2; + AccessRequired addFromInviteLink = 3; + } +} + +message Self {} + +message ReleaseNotes {} + +message Chat { + uint64 id = 1; // generated id for reference only within this file + uint64 recipientId = 2; + bool archived = 3; + optional uint32 pinnedOrder = 4; // will be displayed in ascending order + optional uint64 expirationTimerMs = 5; + optional uint64 muteUntilMs = 6; // INT64_MAX (2^63 - 1) = "always muted". + bool markedUnread = 7; + bool dontNotifyForMentionsIfMuted = 8; + ChatStyle style = 9; + uint32 expireTimerVersion = 10; +} + +/** + * Call Links have some associated data including a call, but unlike other recipients + * are not tied to threads because they do not have messages associated with them. + * + * note: + * - room id can be derived from the root key + * - the presence of an admin key means this user is a call admin + */ +message CallLink { + enum Restrictions { + UNKNOWN = 0; + NONE = 1; + ADMIN_APPROVAL = 2; + } + + bytes rootKey = 1; + optional bytes adminKey = 2; // Only present if the user is an admin + string name = 3; + Restrictions restrictions = 4; + uint64 expirationMs = 5; +} + +message AdHocCall { + enum State { + UNKNOWN_STATE = 0; + GENERIC = 1; + } + + uint64 callId = 1; + // Refers to a `CallLink` recipient. + uint64 recipientId = 2; + State state = 3; + uint64 callTimestamp = 4; +} + +message DistributionListItem { + // distribution ids are UUIDv4s. "My Story" is represented + // by an all-0 UUID (00000000-0000-0000-0000-000000000000). + bytes distributionId = 1; // distribution list ids are uuids + + oneof item { + uint64 deletionTimestamp = 2; + DistributionList distributionList = 3; + } +} + +message DistributionList { + enum PrivacyMode { + UNKNOWN = 0; + ONLY_WITH = 1; + ALL_EXCEPT = 2; + ALL = 3; + } + + string name = 1; + bool allowReplies = 2; + PrivacyMode privacyMode = 3; + repeated uint64 memberRecipientIds = 4; // generated recipient id +} + +message ChatItem { + message IncomingMessageDetails { + uint64 dateReceived = 1; + optional uint64 dateServerSent = 2; + bool read = 3; + bool sealedSender = 4; + } + + message OutgoingMessageDetails { + repeated SendStatus sendStatus = 1; + } + + message DirectionlessMessageDetails { + } + + uint64 chatId = 1; // conversation id + uint64 authorId = 2; // recipient id + uint64 dateSent = 3; + optional uint64 expireStartDate = 4; // timestamp of when expiration timer started ticking down + optional uint64 expiresInMs = 5; // how long timer of message is (ms) + repeated ChatItem revisions = 6; // ordered from oldest to newest + bool sms = 7; + + oneof directionalDetails { + IncomingMessageDetails incoming = 8; + OutgoingMessageDetails outgoing = 9; + DirectionlessMessageDetails directionless = 10; + } + + oneof item { + StandardMessage standardMessage = 11; + ContactMessage contactMessage = 12; + StickerMessage stickerMessage = 13; + RemoteDeletedMessage remoteDeletedMessage = 14; + ChatUpdateMessage updateMessage = 15; + PaymentNotification paymentNotification = 16; + GiftBadge giftBadge = 17; + ViewOnceMessage viewOnceMessage = 18; + DirectStoryReplyMessage directStoryReplyMessage = 19; // group story reply messages are not backed up + } +} + +message SendStatus { + message Pending {} + + message Sent { + bool sealedSender = 1; + } + + message Delivered { + bool sealedSender = 1; + } + + message Read { + bool sealedSender = 1; + } + + message Viewed { + bool sealedSender = 1; + } + + // e.g. user in group was blocked, so we skipped sending to them + message Skipped {} + + message Failed { + enum FailureReason { + UNKNOWN = 0; // A valid value -- could indicate a crash or lack of information + NETWORK = 1; + IDENTITY_KEY_MISMATCH = 2; + } + + FailureReason reason = 1; + } + + uint64 recipientId = 1; + uint64 timestamp = 2; // the time the status was last updated -- if from a receipt, it should be the sentTime of the receipt + + oneof deliveryStatus { + Pending pending = 3; + Sent sent = 4; + Delivered delivered = 5; + Read read = 6; + Viewed viewed = 7; + Skipped skipped = 8; + Failed failed = 9; + } +} + +message Text { + string body = 1; + repeated BodyRange bodyRanges = 2; +} + +message StandardMessage { + optional Quote quote = 1; + optional Text text = 2; + repeated MessageAttachment attachments = 3; + repeated LinkPreview linkPreview = 4; + optional FilePointer longText = 5; + repeated Reaction reactions = 6; +} + +message ContactMessage { + ContactAttachment contact = 1; + repeated Reaction reactions = 2; +} + +message DirectStoryReplyMessage { + message TextReply { + Text text = 1; + FilePointer longText = 2; + } + + oneof reply { + TextReply textReply = 1; + string emoji = 2; + } + + repeated Reaction reactions = 3; + optional uint64 storySentTimestamp = 4; +} + +message PaymentNotification { + message TransactionDetails { + message MobileCoinTxoIdentification { // Used to map to payments on the ledger + repeated bytes publicKey = 1; // for received transactions + repeated bytes keyImages = 2; // for sent transactions + } + + message FailedTransaction { // Failed payments can't be synced from the ledger + enum FailureReason { + GENERIC = 0; + NETWORK = 1; + INSUFFICIENT_FUNDS = 2; + } + FailureReason reason = 1; + } + + message Transaction { + enum Status { + INITIAL = 0; + SUBMITTED = 1; + SUCCESSFUL = 2; + } + Status status = 1; + + // This identification is used to map the payment table to the ledger + // and is likely required otherwise we may have issues reconciling with + // the ledger + MobileCoinTxoIdentification mobileCoinIdentification = 2; + optional uint64 timestamp = 3; + optional uint64 blockIndex = 4; + optional uint64 blockTimestamp = 5; + optional bytes transaction = 6; // mobile coin blobs + optional bytes receipt = 7; // mobile coin blobs + } + + oneof payment { + Transaction transaction = 1; + FailedTransaction failedTransaction = 2; + } + } + + optional string amountMob = 1; // stored as a decimal string, e.g. 1.00001 + optional string feeMob = 2; // stored as a decimal string, e.g. 1.00001 + optional string note = 3; + TransactionDetails transactionDetails = 4; +} + +message GiftBadge { + enum State { + UNOPENED = 0; + OPENED = 1; + REDEEMED = 2; + FAILED = 3; + } + + bytes receiptCredentialPresentation = 1; + State state = 2; +} + +message ViewOnceMessage { + // Will be null for viewed messages + MessageAttachment attachment = 1; + repeated Reaction reactions = 2; +} + +message ContactAttachment { + message Name { + string givenName = 1; + string familyName = 2; + string prefix = 3; + string suffix = 4; + string middleName = 5; + string nickname = 6; + } + + message Phone { + enum Type { + UNKNOWN = 0; + HOME = 1; + MOBILE = 2; + WORK = 3; + CUSTOM = 4; + } + + string value = 1; + Type type = 2; + string label = 3; + } + + message Email { + enum Type { + UNKNOWN = 0; + HOME = 1; + MOBILE = 2; + WORK = 3; + CUSTOM = 4; + } + + string value = 1; + Type type = 2; + string label = 3; + } + + message PostalAddress { + enum Type { + UNKNOWN = 0; + HOME = 1; + WORK = 2; + CUSTOM = 3; + } + + Type type = 1; + string label = 2; + string street = 3; + string pobox = 4; + string neighborhood = 5; + string city = 6; + string region = 7; + string postcode = 8; + string country = 9; + } + + optional Name name = 1; + repeated Phone number = 3; + repeated Email email = 4; + repeated PostalAddress address = 5; + optional FilePointer avatar = 6; + string organization = 7; +} + +message StickerMessage { + Sticker sticker = 1; + repeated Reaction reactions = 2; +} + +// Tombstone for remote delete +message RemoteDeletedMessage {} + +message Sticker { + bytes packId = 1; + bytes packKey = 2; + uint32 stickerId = 3; + optional string emoji = 4; + // Stickers are uploaded to be sent as attachments; we also + // back them up as normal attachments when they are in messages. + // DO NOT treat this as the definitive source of a sticker in + // an installed StickerPack that shares the same packId. + FilePointer data = 5; +} + +message LinkPreview { + string url = 1; + optional string title = 2; + optional FilePointer image = 3; + optional string description = 4; + optional uint64 date = 5; +} + +// A FilePointer on a message that has additional +// metadata that applies only to message attachments. +message MessageAttachment { + // Similar to SignalService.AttachmentPointer.Flags, + // but explicitly mutually exclusive. Note the different raw values + // (non-zero starting values are not supported in proto3.) + enum Flag { + NONE = 0; + VOICE_MESSAGE = 1; + BORDERLESS = 2; + GIF = 3; + } + + FilePointer pointer = 1; + Flag flag = 2; + bool wasDownloaded = 3; + // Cross-client identifier for this attachment among all attachments on the + // owning message. See: SignalService.AttachmentPointer.clientUuid. + optional bytes clientUuid = 4; +} + +message FilePointer { + // References attachments in the backup (media) storage tier. + message BackupLocator { + string mediaName = 1; + // If present, the cdn number of the succesful upload. + // If empty/0, may still have been uploaded, and clients + // can discover the cdn number via the list endpoint. + optional uint32 cdnNumber = 2; + bytes key = 3; + bytes digest = 4; + uint32 size = 5; + // Fallback in case backup tier upload failed. + optional string transitCdnKey = 6; + optional uint32 transitCdnNumber = 7; + } + + // References attachments in the transit storage tier. + // May be downloaded or not when the backup is generated; + // primarily for free-tier users who cannot copy the + // attachments to the backup (media) storage tier. + message AttachmentLocator { + string cdnKey = 1; + uint32 cdnNumber = 2; + optional uint64 uploadTimestamp = 3; + bytes key = 4; + bytes digest = 5; + uint32 size = 6; + } + + // References attachments that are invalid in such a way where download + // cannot be attempted. Could range from missing digests to missing + // CDN keys or anything else that makes download attempts impossible. + // This serves as a 'tombstone' so that the UX can show that an attachment + // did exist, but for whatever reason it's not retrievable. + message InvalidAttachmentLocator { + } + + oneof locator { + BackupLocator backupLocator = 1; + AttachmentLocator attachmentLocator = 2; + InvalidAttachmentLocator invalidAttachmentLocator = 3; + } + + optional string contentType = 4; + optional bytes incrementalMac = 5; + optional uint32 incrementalMacChunkSize = 6; + optional string fileName = 7; + optional uint32 width = 8; + optional uint32 height = 9; + optional string caption = 10; + optional string blurHash = 11; +} + +message Quote { + enum Type { + UNKNOWN = 0; + NORMAL = 1; + GIFT_BADGE = 2; + VIEW_ONCE = 3; + } + + message QuotedAttachment { + optional string contentType = 1; + optional string fileName = 2; + optional MessageAttachment thumbnail = 3; + } + + optional uint64 targetSentTimestamp = 1; // null if the target message could not be found at time of quote insert + uint64 authorId = 2; + optional Text text = 3; + repeated QuotedAttachment attachments = 4; + Type type = 5; +} + +message BodyRange { + enum Style { + NONE = 0; + BOLD = 1; + ITALIC = 2; + SPOILER = 3; + STRIKETHROUGH = 4; + MONOSPACE = 5; + } + + optional uint32 start = 1; + optional uint32 length = 2; + + oneof associatedValue { + bytes mentionAci = 3; + Style style = 4; + } +} + +message Reaction { + string emoji = 1; + uint64 authorId = 2; + uint64 sentTimestamp = 3; + // A higher sort order means that a reaction is more recent. Some clients may export this as + // incrementing numbers (e.g. 1, 2, 3), others as timestamps. + uint64 sortOrder = 4; +} + +message ChatUpdateMessage { + oneof update { + SimpleChatUpdate simpleUpdate = 1; + GroupChangeChatUpdate groupChange = 2; + ExpirationTimerChatUpdate expirationTimerChange = 3; + ProfileChangeChatUpdate profileChange = 4; + ThreadMergeChatUpdate threadMerge = 5; + SessionSwitchoverChatUpdate sessionSwitchover = 6; + IndividualCall individualCall = 7; + GroupCall groupCall = 8; + LearnedProfileChatUpdate learnedProfileChange = 9; + } +} + +message IndividualCall { + enum Type { + UNKNOWN_TYPE = 0; + AUDIO_CALL = 1; + VIDEO_CALL = 2; + } + + enum Direction { + UNKNOWN_DIRECTION = 0; + INCOMING = 1; + OUTGOING = 2; + } + + enum State { + UNKNOWN_STATE = 0; + ACCEPTED = 1; + NOT_ACCEPTED = 2; + // An incoming call that is no longer ongoing, which we neither accepted + // not actively declined. For example, it expired, was canceled by the + // sender, or was rejected due to being in another call. + MISSED = 3; + // We auto-declined an incoming call due to a notification profile. + MISSED_NOTIFICATION_PROFILE = 4; + } + + optional uint64 callId = 1; + Type type = 2; + Direction direction = 3; + State state = 4; + uint64 startedCallTimestamp = 5; + bool read = 6; +} + +message GroupCall { + enum State { + UNKNOWN_STATE = 0; + // A group call was started without ringing. + GENERIC = 1; + // We joined a group call that was started without ringing. + JOINED = 2; + // An incoming group call is actively ringing. + RINGING = 3; + // We accepted an incoming group ring. + ACCEPTED = 4; + // We declined an incoming group ring. + DECLINED = 5; + // We missed an incoming group ring, for example because it expired. + MISSED = 6; + // We auto-declined an incoming group ring due to a notification profile. + MISSED_NOTIFICATION_PROFILE = 7; + // An outgoing ring was started. We don't track any state for outgoing rings + // beyond that they started. + OUTGOING_RING = 8; + } + + optional uint64 callId = 1; + State state = 2; + optional uint64 ringerRecipientId = 3; + optional uint64 startedCallRecipientId = 4; + uint64 startedCallTimestamp = 5; + optional uint64 endedCallTimestamp = 6; // The time the call ended. + bool read = 7; +} + +message SimpleChatUpdate { + enum Type { + UNKNOWN = 0; + JOINED_SIGNAL = 1; + IDENTITY_UPDATE = 2; + IDENTITY_VERIFIED = 3; + IDENTITY_DEFAULT = 4; // marking as unverified + CHANGE_NUMBER = 5; + RELEASE_CHANNEL_DONATION_REQUEST = 6; + END_SESSION = 7; + CHAT_SESSION_REFRESH = 8; + BAD_DECRYPT = 9; + PAYMENTS_ACTIVATED = 10; + PAYMENT_ACTIVATION_REQUEST = 11; + UNSUPPORTED_PROTOCOL_MESSAGE = 12; + REPORTED_SPAM = 13; + BLOCKED = 14; + UNBLOCKED = 15; + MESSAGE_REQUEST_ACCEPTED = 16; + } + + Type type = 1; +} + +// For 1:1 chat updates only. +// For group thread updates use GroupExpirationTimerUpdate. +message ExpirationTimerChatUpdate { + uint64 expiresInMs = 1; // 0 means the expiration timer was disabled +} + +message ProfileChangeChatUpdate { + string previousName = 1; + string newName = 2; +} + +message LearnedProfileChatUpdate { + oneof previousName { + uint64 e164 = 1; + string username = 2; + } +} + +message ThreadMergeChatUpdate { + uint64 previousE164 = 1; +} + +message SessionSwitchoverChatUpdate { + uint64 e164 = 1; +} + +message GroupChangeChatUpdate { + message Update { + oneof update { + GenericGroupUpdate genericGroupUpdate = 1; + GroupCreationUpdate groupCreationUpdate = 2; + GroupNameUpdate groupNameUpdate = 3; + GroupAvatarUpdate groupAvatarUpdate = 4; + GroupDescriptionUpdate groupDescriptionUpdate = 5; + GroupMembershipAccessLevelChangeUpdate groupMembershipAccessLevelChangeUpdate = 6; + GroupAttributesAccessLevelChangeUpdate groupAttributesAccessLevelChangeUpdate = 7; + GroupAnnouncementOnlyChangeUpdate groupAnnouncementOnlyChangeUpdate = 8; + GroupAdminStatusUpdate groupAdminStatusUpdate = 9; + GroupMemberLeftUpdate groupMemberLeftUpdate = 10; + GroupMemberRemovedUpdate groupMemberRemovedUpdate = 11; + SelfInvitedToGroupUpdate selfInvitedToGroupUpdate = 12; + SelfInvitedOtherUserToGroupUpdate selfInvitedOtherUserToGroupUpdate = 13; + GroupUnknownInviteeUpdate groupUnknownInviteeUpdate = 14; + GroupInvitationAcceptedUpdate groupInvitationAcceptedUpdate = 15; + GroupInvitationDeclinedUpdate groupInvitationDeclinedUpdate = 16; + GroupMemberJoinedUpdate groupMemberJoinedUpdate = 17; + GroupMemberAddedUpdate groupMemberAddedUpdate = 18; + GroupSelfInvitationRevokedUpdate groupSelfInvitationRevokedUpdate = 19; + GroupInvitationRevokedUpdate groupInvitationRevokedUpdate = 20; + GroupJoinRequestUpdate groupJoinRequestUpdate = 21; + GroupJoinRequestApprovalUpdate groupJoinRequestApprovalUpdate = 22; + GroupJoinRequestCanceledUpdate groupJoinRequestCanceledUpdate = 23; + GroupInviteLinkResetUpdate groupInviteLinkResetUpdate = 24; + GroupInviteLinkEnabledUpdate groupInviteLinkEnabledUpdate = 25; + GroupInviteLinkAdminApprovalUpdate groupInviteLinkAdminApprovalUpdate = 26; + GroupInviteLinkDisabledUpdate groupInviteLinkDisabledUpdate = 27; + GroupMemberJoinedByLinkUpdate groupMemberJoinedByLinkUpdate = 28; + GroupV2MigrationUpdate groupV2MigrationUpdate = 29; + GroupV2MigrationSelfInvitedUpdate groupV2MigrationSelfInvitedUpdate = 30; + GroupV2MigrationInvitedMembersUpdate groupV2MigrationInvitedMembersUpdate = 31; + GroupV2MigrationDroppedMembersUpdate groupV2MigrationDroppedMembersUpdate = 32; + GroupSequenceOfRequestsAndCancelsUpdate groupSequenceOfRequestsAndCancelsUpdate = 33; + GroupExpirationTimerUpdate groupExpirationTimerUpdate = 34; + } + } + + // Must be one or more; all updates batched together came from + // a single batched group state update. + repeated Update updates = 1; +} + +message GenericGroupUpdate { + optional bytes updaterAci = 1; +} + +message GroupCreationUpdate { + optional bytes updaterAci = 1; +} + +message GroupNameUpdate { + optional bytes updaterAci = 1; + // Null value means the group name was removed. + optional string newGroupName = 2; +} + +message GroupAvatarUpdate { + optional bytes updaterAci = 1; + bool wasRemoved = 2; +} + +message GroupDescriptionUpdate { + optional bytes updaterAci = 1; + // Null value means the group description was removed. + optional string newDescription = 2; +} + +enum GroupV2AccessLevel { + UNKNOWN = 0; + ANY = 1; + MEMBER = 2; + ADMINISTRATOR = 3; + UNSATISFIABLE = 4; +} + +message GroupMembershipAccessLevelChangeUpdate { + optional bytes updaterAci = 1; + GroupV2AccessLevel accessLevel = 2; +} + +message GroupAttributesAccessLevelChangeUpdate { + optional bytes updaterAci = 1; + GroupV2AccessLevel accessLevel = 2; +} + +message GroupAnnouncementOnlyChangeUpdate { + optional bytes updaterAci = 1; + bool isAnnouncementOnly = 2; +} + +message GroupAdminStatusUpdate { + optional bytes updaterAci = 1; + // The aci who had admin status granted or revoked. + bytes memberAci = 2; + bool wasAdminStatusGranted = 3; +} + +message GroupMemberLeftUpdate { + bytes aci = 1; +} + +message GroupMemberRemovedUpdate { + optional bytes removerAci = 1; + bytes removedAci = 2; +} + +message SelfInvitedToGroupUpdate { + optional bytes inviterAci = 1; +} + +message SelfInvitedOtherUserToGroupUpdate { + // If no invitee id available, use GroupUnknownInviteeUpdate + bytes inviteeServiceId = 1; +} + +message GroupUnknownInviteeUpdate { + // Can be the self user. + optional bytes inviterAci = 1; + uint32 inviteeCount = 2; +} + +message GroupInvitationAcceptedUpdate { + optional bytes inviterAci = 1; + bytes newMemberAci = 2; +} + +message GroupInvitationDeclinedUpdate { + optional bytes inviterAci = 1; + // Note: if invited by pni, just set inviteeAci to nil. + optional bytes inviteeAci = 2; +} + +message GroupMemberJoinedUpdate { + bytes newMemberAci = 1; +} + +message GroupMemberAddedUpdate { + optional bytes updaterAci = 1; + bytes newMemberAci = 2; + bool hadOpenInvitation = 3; + // If hadOpenInvitation is true, optionally include aci of the inviter. + optional bytes inviterAci = 4; +} + +// An invitation to self was revoked. +message GroupSelfInvitationRevokedUpdate { + optional bytes revokerAci = 1; +} + +// These invitees should never be the local user. +// Use GroupSelfInvitationRevokedUpdate in those cases. +// The inviter or updater can be the local user. +message GroupInvitationRevokedUpdate { + message Invitee { + optional bytes inviterAci = 1; + // Prefer to use aci over pni. No need to set + // pni if aci is set. Both can be missing. + optional bytes inviteeAci = 2; + optional bytes inviteePni = 3; + } + + // The member that revoked the invite(s), not the inviter! + // Assumed to be an admin (at the time, may no longer be an + // admin or even a member). + optional bytes updaterAci = 1; + repeated Invitee invitees = 2; +} + +message GroupJoinRequestUpdate { + bytes requestorAci = 1; +} + +message GroupJoinRequestApprovalUpdate { + bytes requestorAci = 1; + // The aci that approved or rejected the request. + optional bytes updaterAci = 2; + bool wasApproved = 3; +} + +message GroupJoinRequestCanceledUpdate { + bytes requestorAci = 1; +} + +// A single requestor has requested to join and cancelled +// their request repeatedly with no other updates in between. +// The last action encompassed by this update is always a +// cancellation; if there was another open request immediately +// after, it will be a separate GroupJoinRequestUpdate, either +// in the same frame or in a subsequent frame. +message GroupSequenceOfRequestsAndCancelsUpdate { + bytes requestorAci = 1; + uint32 count = 2; +} + +message GroupInviteLinkResetUpdate { + optional bytes updaterAci = 1; +} + +message GroupInviteLinkEnabledUpdate { + optional bytes updaterAci = 1; + bool linkRequiresAdminApproval = 2; +} + +message GroupInviteLinkAdminApprovalUpdate { + optional bytes updaterAci = 1; + bool linkRequiresAdminApproval = 2; +} + +message GroupInviteLinkDisabledUpdate { + optional bytes updaterAci = 1; +} + +message GroupMemberJoinedByLinkUpdate { + bytes newMemberAci = 1; +} + +// A gv1->gv2 migration occurred. +message GroupV2MigrationUpdate {} + +// Another user migrated gv1->gv2 but was unable to add +// the local user and invited them instead. +message GroupV2MigrationSelfInvitedUpdate {} + +// The local user migrated gv1->gv2 but was unable to +// add some members and invited them instead. +// (Happens if we don't have the invitee's profile key) +message GroupV2MigrationInvitedMembersUpdate { + uint32 invitedMembersCount = 1; +} + +// The local user migrated gv1->gv2 but was unable to +// add or invite some members and dropped them instead. +// (Happens for e164 members where we don't have an aci). +message GroupV2MigrationDroppedMembersUpdate { + uint32 droppedMembersCount = 1; +} + +// For 1:1 timer updates, use ExpirationTimerChatUpdate. +message GroupExpirationTimerUpdate { + uint64 expiresInMs = 1; // 0 means the expiration timer was disabled + optional bytes updaterAci = 2; +} + +message StickerPack { + bytes packId = 1; + bytes packKey = 2; +} + +message ChatStyle { + message Gradient { + uint32 angle = 1; // degrees + repeated fixed32 colors = 2; // 0xAARRGGBB + repeated float positions = 3; // percent from 0 to 1 + } + + message CustomChatColor { + uint64 id = 1; + + oneof color { + fixed32 solid = 2; // 0xAARRGGBB + Gradient gradient = 3; + } + } + + message AutomaticBubbleColor { + } + + enum WallpaperPreset { + UNKNOWN_WALLPAPER_PRESET = 0; + SOLID_BLUSH = 1; + SOLID_COPPER = 2; + SOLID_DUST = 3; + SOLID_CELADON = 4; + SOLID_RAINFOREST = 5; + SOLID_PACIFIC = 6; + SOLID_FROST = 7; + SOLID_NAVY = 8; + SOLID_LILAC = 9; + SOLID_PINK = 10; + SOLID_EGGPLANT = 11; + SOLID_SILVER = 12; + GRADIENT_SUNSET = 13; + GRADIENT_NOIR = 14; + GRADIENT_HEATMAP = 15; + GRADIENT_AQUA = 16; + GRADIENT_IRIDESCENT = 17; + GRADIENT_MONSTERA = 18; + GRADIENT_BLISS = 19; + GRADIENT_SKY = 20; + GRADIENT_PEACH = 21; + } + + enum BubbleColorPreset { + UNKNOWN_BUBBLE_COLOR_PRESET = 0; + SOLID_ULTRAMARINE = 1; + SOLID_CRIMSON = 2; + SOLID_VERMILION = 3; + SOLID_BURLAP = 4; + SOLID_FOREST = 5; + SOLID_WINTERGREEN = 6; + SOLID_TEAL = 7; + SOLID_BLUE = 8; + SOLID_INDIGO = 9; + SOLID_VIOLET = 10; + SOLID_PLUM = 11; + SOLID_TAUPE = 12; + SOLID_STEEL = 13; + GRADIENT_EMBER = 14; + GRADIENT_MIDNIGHT = 15; + GRADIENT_INFRARED = 16; + GRADIENT_LAGOON = 17; + GRADIENT_FLUORESCENT = 18; + GRADIENT_BASIL = 19; + GRADIENT_SUBLIME = 20; + GRADIENT_SEA = 21; + GRADIENT_TANGERINE = 22; + } + + oneof wallpaper { + WallpaperPreset wallpaperPreset = 1; + // This `FilePointer` is expected not to contain a `fileName`, `width`, + // `height`, or `caption`. + FilePointer wallpaperPhoto = 2; + } + + oneof bubbleColor { + // Bubble setting is automatically determined based on the wallpaper setting, + // or `SOLID_ULTRAMARINE` for `noWallpaper` + AutomaticBubbleColor autoBubbleColor = 3; + BubbleColorPreset bubbleColorPreset = 4; + + // See AccountSettings.customChatColors + uint64 customColorId = 5; + } + + bool dimWallpaperInDarkMode = 7; +} + +message NotificationProfile { + enum DayOfWeek { + UNKNOWN = 0; + MONDAY = 1; + TUESDAY = 2; + WEDNESDAY = 3; + THURSDAY = 4; + FRIDAY = 5; + SATURDAY = 6; + SUNDAY = 7; + } + + string name = 1; + optional string emoji = 2; + fixed32 color = 3; // 0xAARRGGBB + uint64 createdAtMs = 4; + bool allowAllCalls = 5; + bool allowAllMentions = 6; + repeated uint64 allowedMembers = 7; // generated recipient id for allowed groups and contacts + bool scheduleEnabled = 8; + uint32 scheduleStartTime = 9; // 24-hour clock int, 0000-2359 (e.g., 15, 900, 1130, 2345) + uint32 scheduleEndTime = 10; // 24-hour clock int, 0000-2359 (e.g., 15, 900, 1130, 2345) + repeated DayOfWeek scheduleDaysEnabled = 11; +} + +message ChatFolder { + // Represents the default "All chats" folder record vs all other custom folders + enum FolderType { + UNKNOWN = 0; + ALL = 1; + CUSTOM = 2; + } + + string name = 1; + bool showOnlyUnread = 2; + bool showMutedChats = 3; + // Folder includes all 1:1 chats, unless excluded + bool includeAllIndividualChats = 4; + // Folder includes all group chats, unless excluded + bool includeAllGroupChats = 5; + FolderType folderType = 6; + repeated uint64 includedRecipientIds = 7; // generated recipient id of groups, contacts, and/or note to self + repeated uint64 excludedRecipientIds = 8; // generated recipient id of groups, contacts, and/or note to self +} diff --git a/pkg/signalmeow/protobuf/build-protos.sh b/pkg/signalmeow/protobuf/build-protos.sh index 8b9554e..86cc261 100755 --- a/pkg/signalmeow/protobuf/build-protos.sh +++ b/pkg/signalmeow/protobuf/build-protos.sh @@ -9,4 +9,9 @@ do --go_opt=embed_raw=true \ $file done +protoc --go_out=. \ + --go_opt=Mbackuppb/Backup.proto=$PKG_IMPORT_PATH/backuppb \ + --go_opt=paths=source_relative \ + --go_opt=embed_raw=true \ + backuppb/Backup.proto pre-commit run -a diff --git a/pkg/signalmeow/protobuf/update-protos.sh b/pkg/signalmeow/protobuf/update-protos.sh index 1d81f0a..cf47a8c 100755 --- a/pkg/signalmeow/protobuf/update-protos.sh +++ b/pkg/signalmeow/protobuf/update-protos.sh @@ -1,22 +1,29 @@ #!/bin/bash set -euo pipefail -ANDROID_GIT_REVISION=${1:-35a6c1e5c98a6adaf207e96161536624577106cd} -DESKTOP_GIT_REVISION=${1:-bfb53efb72bcbf799992805f63cdccbd937ad99c} +ANDROID_GIT_REVISION=${1:-50db945ef1673da9990affeff022da64e4caa264} +DESKTOP_GIT_REVISION=${1:-ca1d17354db10a14f9f5558dcb546af9f3bba578} update_proto() { case "$1" in Signal-Android) + REPO="Signal-Android" prefix="libsignal-service/src/main/protowire/" GIT_REVISION=$ANDROID_GIT_REVISION ;; + Signal-Android-App) + REPO="Signal-Android" + prefix="app/src/main/protowire/" + GIT_REVISION=$ANDROID_GIT_REVISION + ;; Signal-Desktop) + REPO="Signal-Desktop" prefix="protos/" GIT_REVISION=$DESKTOP_GIT_REVISION ;; esac - echo https://raw.githubusercontent.com/signalapp/${1}/${GIT_REVISION}/${prefix}${2} - curl -LOf https://raw.githubusercontent.com/signalapp/${1}/${GIT_REVISION}/${prefix}${2} + echo https://raw.githubusercontent.com/signalapp/${REPO}/${GIT_REVISION}/${prefix}${2} + curl -LOf https://raw.githubusercontent.com/signalapp/${REPO}/${GIT_REVISION}/${prefix}${2} } @@ -27,6 +34,9 @@ update_proto Signal-Android StickerResources.proto update_proto Signal-Android WebSocketResources.proto update_proto Signal-Android StorageService.proto +update_proto Signal-Android-App Backup.proto +mv Backup.proto backuppb/Backup.proto + update_proto Signal-Desktop DeviceName.proto update_proto Signal-Desktop UnidentifiedDelivery.proto # Android has CDSI.proto too, but the types have more generic names (since android uses a different package name) diff --git a/pkg/signalmeow/provisioning.go b/pkg/signalmeow/provisioning.go index 4aedc44..d6774ae 100644 --- a/pkg/signalmeow/provisioning.go +++ b/pkg/signalmeow/provisioning.go @@ -18,6 +18,7 @@ package signalmeow import ( "context" + "crypto/hmac" "encoding/base64" "encoding/json" "fmt" @@ -79,7 +80,7 @@ type ProvisioningResponse struct { Err error } -func PerformProvisioning(ctx context.Context, deviceStore store.DeviceStore, deviceName string) chan ProvisioningResponse { +func PerformProvisioning(ctx context.Context, deviceStore store.DeviceStore, deviceName string, allowBackup bool) chan ProvisioningResponse { log := zerolog.Ctx(ctx).With().Str("action", "perform provisioning").Logger() c := make(chan ProvisioningResponse, 4) go func() { @@ -100,7 +101,7 @@ func PerformProvisioning(ctx context.Context, deviceStore store.DeviceStore, dev defer ws.Close(websocket.StatusInternalError, "Websocket StatusInternalError") provisioningCipher := NewProvisioningCipher() - provisioningURL, err := startProvisioning(timeoutCtx, ws, provisioningCipher) + provisioningURL, err := startProvisioning(timeoutCtx, ws, provisioningCipher, allowBackup) if err != nil { log.Err(err).Msg("startProvisioning error") c <- ProvisioningResponse{State: StateProvisioningError, Err: err} @@ -169,14 +170,23 @@ func PerformProvisioning(ctx context.Context, deviceStore store.DeviceStore, dev Number: *provisioningMessage.Number, Password: password, MasterKey: provisioningMessage.GetMasterKey(), + AccountEntropyPool: libsignalgo.AccountEntropyPool(provisioningMessage.GetAccountEntropyPool()), + EphemeralBackupKey: libsignalgo.BytesToBackupKey(provisioningMessage.GetEphemeralBackupKey()), + MediaRootBackupKey: libsignalgo.BytesToBackupKey(provisioningMessage.GetMediaRootBackupKey()), } - if provisioningMessage.GetMasterKey() == nil && provisioningMessage.GetAccountEntropyPool() != "" { - data.MasterKey, err = libsignalgo.AccountEntropyPool(provisioningMessage.GetAccountEntropyPool()).DeriveSVRKey() + if provisioningMessage.GetAccountEntropyPool() != "" { + var masterKey []byte + masterKey, err = libsignalgo.AccountEntropyPool(provisioningMessage.GetAccountEntropyPool()).DeriveSVRKey() if err != nil { log.Err(err).Msg("Failed to derive master key from account entropy pool") } else { log.Debug().Msg("Derived master key from account entropy pool") } + if data.MasterKey == nil { + data.MasterKey = masterKey + } else if !hmac.Equal(data.MasterKey, masterKey) { + log.Warn().Msg("Master key mismatch") + } } // Store the provisioning data @@ -267,7 +277,7 @@ func PerformProvisioning(ctx context.Context, deviceStore store.DeviceStore, dev } // Returns the provisioningUrl and an error -func startProvisioning(ctx context.Context, ws *websocket.Conn, provisioningCipher *ProvisioningCipher) (string, error) { +func startProvisioning(ctx context.Context, ws *websocket.Conn, provisioningCipher *ProvisioningCipher, allowBackup bool) (string, error) { log := zerolog.Ctx(ctx).With().Str("action", "start provisioning").Logger() pubKey := provisioningCipher.GetPublicKey() @@ -289,13 +299,17 @@ func startProvisioning(ctx context.Context, ws *websocket.Conn, provisioningCiph return "", fmt.Errorf("failed to unmarshal provisioning UUID: %w", err) } + linkCapabilities := []string{"backup"} + if !allowBackup { + linkCapabilities = []string{} + } provisioningURL := (&url.URL{ Scheme: "sgnl", Host: "linkdevice", RawQuery: url.Values{ "uuid": []string{provisioningBody.GetAddress()}, "pub_key": []string{base64.StdEncoding.EncodeToString(exerrors.Must(pubKey.Serialize()))}, - "capabilities": []string{""}, // Will contain "backup" in the future + "capabilities": linkCapabilities, }.Encode(), }).String() diff --git a/pkg/signalmeow/store/container.go b/pkg/signalmeow/store/container.go index 8f81490..7437ac5 100644 --- a/pkg/signalmeow/store/container.go +++ b/pkg/signalmeow/store/container.go @@ -37,7 +37,8 @@ const getAllDevicesQuery = ` SELECT aci_uuid, aci_identity_key_pair, registration_id, pni_uuid, pni_identity_key_pair, pni_registration_id, - device_id, number, password, master_key, account_record + device_id, number, password, master_key, account_record, + account_entropy_pool, ephemeral_backup_key, media_root_backup_key FROM signalmeow_device ` @@ -50,13 +51,14 @@ func (c *Container) Upgrade(ctx context.Context) error { func (c *Container) scanDevice(row dbutil.Scannable) (*Device, error) { var device Device - var aciIdentityKeyPair, pniIdentityKeyPair, accountRecordBytes []byte + var accountEntropyPool sql.NullString + var aciIdentityKeyPair, pniIdentityKeyPair, accountRecordBytes, ephemeralBackupKey, mediaRootBackupKey []byte err := row.Scan( &device.ACI, &aciIdentityKeyPair, &device.ACIRegistrationID, &device.PNI, &pniIdentityKeyPair, &device.PNIRegistrationID, - &device.DeviceID, &device.Number, &device.Password, &device.MasterKey, - &accountRecordBytes, + &device.DeviceID, &device.Number, &device.Password, &device.MasterKey, &accountRecordBytes, + &accountEntropyPool, &ephemeralBackupKey, &mediaRootBackupKey, ) if err != nil { return nil, fmt.Errorf("failed to scan session: %w", err) @@ -80,6 +82,9 @@ func (c *Container) scanDevice(row dbutil.Scannable) (*Device, error) { return nil, fmt.Errorf("failed to unmarshal account record: %w", err) } } + device.AccountEntropyPool = libsignalgo.AccountEntropyPool(accountEntropyPool.String) + device.EphemeralBackupKey = libsignalgo.BytesToBackupKey(ephemeralBackupKey) + device.MediaRootBackupKey = libsignalgo.BytesToBackupKey(mediaRootBackupKey) baseStore := &sqlStore{Container: c, AccountID: device.ACI} aciStore := &scopedSQLStore{Container: c, AccountID: device.ACI, ServiceID: device.ACIServiceID()} pniStore := &scopedSQLStore{Container: c, AccountID: device.ACI, ServiceID: device.PNIServiceID()} @@ -147,9 +152,10 @@ const ( INSERT INTO signalmeow_device ( aci_uuid, aci_identity_key_pair, registration_id, pni_uuid, pni_identity_key_pair, pni_registration_id, - device_id, number, password, master_key, account_record + device_id, number, password, master_key, account_record, + account_entropy_pool, ephemeral_backup_key, media_root_backup_key ) - VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11) + VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14) ON CONFLICT (aci_uuid) DO UPDATE SET aci_identity_key_pair=excluded.aci_identity_key_pair, registration_id=excluded.registration_id, @@ -160,7 +166,10 @@ const ( number=excluded.number, password=excluded.password, master_key=excluded.master_key, - account_record=excluded.account_record + account_record=excluded.account_record, + account_entropy_pool=excluded.account_entropy_pool, + ephemeral_backup_key=excluded.ephemeral_backup_key, + media_root_backup_key=excluded.media_root_backup_key ` deleteDeviceQuery = `DELETE FROM signalmeow_device WHERE aci_uuid=$1` ) @@ -194,7 +203,8 @@ func (c *Container) PutDevice(ctx context.Context, device *DeviceData) error { device.ACI, aciIdentityKeyPair, device.ACIRegistrationID, device.PNI, pniIdentityKeyPair, device.PNIRegistrationID, device.DeviceID, device.Number, device.Password, device.MasterKey, - accountRecordBytes, + accountRecordBytes, device.AccountEntropyPool, + device.EphemeralBackupKey.Slice(), device.MediaRootBackupKey.Slice(), ) if err != nil { zerolog.Ctx(ctx).Err(err).Msg("failed to insert device") diff --git a/pkg/signalmeow/store/device.go b/pkg/signalmeow/store/device.go index eb823c8..262f868 100644 --- a/pkg/signalmeow/store/device.go +++ b/pkg/signalmeow/store/device.go @@ -37,6 +37,9 @@ type DeviceData struct { Password string MasterKey []byte AccountRecord *signalpb.AccountRecord + AccountEntropyPool libsignalgo.AccountEntropyPool + EphemeralBackupKey *libsignalgo.BackupKey + MediaRootBackupKey *libsignalgo.BackupKey } func (d *DeviceData) ACIServiceID() libsignalgo.ServiceID { diff --git a/pkg/signalmeow/store/upgrades/00-latest.sql b/pkg/signalmeow/store/upgrades/00-latest.sql index 38ed5b2..05dd524 100644 --- a/pkg/signalmeow/store/upgrades/00-latest.sql +++ b/pkg/signalmeow/store/upgrades/00-latest.sql @@ -1,4 +1,4 @@ --- v0 -> v17 (compatible with v13+): Latest revision +-- v0 -> v18 (compatible with v13+): Latest revision CREATE TABLE signalmeow_device ( aci_uuid TEXT PRIMARY KEY, @@ -13,8 +13,11 @@ CREATE TABLE signalmeow_device ( number TEXT NOT NULL DEFAULT '', password TEXT NOT NULL DEFAULT '', - master_key bytea, - account_record bytea + master_key bytea, + account_record bytea, + account_entropy_pool TEXT, + ephemeral_backup_key bytea, + media_root_backup_key bytea ); CREATE TABLE signalmeow_pre_keys ( diff --git a/pkg/signalmeow/store/upgrades/18-store-backup-keys.sql b/pkg/signalmeow/store/upgrades/18-store-backup-keys.sql new file mode 100644 index 0000000..e478324 --- /dev/null +++ b/pkg/signalmeow/store/upgrades/18-store-backup-keys.sql @@ -0,0 +1,4 @@ +-- v18 (compatible with v13+): Store account entropy pool and ephemeral backup keys +ALTER TABLE signalmeow_device ADD COLUMN account_entropy_pool TEXT; +ALTER TABLE signalmeow_device ADD COLUMN ephemeral_backup_key bytea; +ALTER TABLE signalmeow_device ADD COLUMN media_root_backup_key bytea; From 33c1b7910a07d883d81ad92801cc25d9d61b5f81 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Sat, 18 Jan 2025 15:17:30 +0200 Subject: [PATCH 258/580] msgconv: add utilities for converting backup messages --- pkg/connector/handlesignal.go | 4 +- pkg/msgconv/from-signal-backup.go | 251 ++++++++++++++++++++++++++++++ pkg/msgconv/from-signal.go | 57 ++++--- pkg/msgconv/urlpreview.go | 8 +- 4 files changed, 295 insertions(+), 25 deletions(-) create mode 100644 pkg/msgconv/from-signal-backup.go diff --git a/pkg/connector/handlesignal.go b/pkg/connector/handlesignal.go index d39f250..16cfb50 100644 --- a/pkg/connector/handlesignal.go +++ b/pkg/connector/handlesignal.go @@ -315,7 +315,7 @@ func (evt *Bv2ChatEvent) ConvertMessage(ctx context.Context, portal *bridgev2.Po if !ok { return nil, fmt.Errorf("ConvertMessage() called for non-DataMessage event") } - converted := evt.s.Main.MsgConv.ToMatrix(ctx, evt.s.Client, portal, intent, dataMsg) + converted := evt.s.Main.MsgConv.ToMatrix(ctx, evt.s.Client, portal, intent, dataMsg, nil) if converted.Disappear.Type != "" { evtTS := evt.GetTimestamp() if !dataMsg.GetIsViewOnce() { @@ -334,7 +334,7 @@ func (evt *Bv2ChatEvent) ConvertEdit(ctx context.Context, portal *bridgev2.Porta return nil, fmt.Errorf("ConvertEdit() called for non-EditMessage event") } // TODO tell converter about existing parts to avoid reupload? - converted := evt.s.Main.MsgConv.ToMatrix(ctx, evt.s.Client, portal, intent, editMsg.GetDataMessage()) + converted := evt.s.Main.MsgConv.ToMatrix(ctx, evt.s.Client, portal, intent, editMsg.GetDataMessage(), nil) // TODO can anything other than the text be edited? editPart := converted.Parts[len(converted.Parts)-1].ToEditPart(existing[len(existing)-1]) editPart.Part.EditCount++ diff --git a/pkg/msgconv/from-signal-backup.go b/pkg/msgconv/from-signal-backup.go new file mode 100644 index 0000000..1b99b85 --- /dev/null +++ b/pkg/msgconv/from-signal-backup.go @@ -0,0 +1,251 @@ +// mautrix-signal - A Matrix-Signal puppeting bridge. +// Copyright (C) 2025 Tulir Asokan +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +package msgconv + +import ( + "github.com/google/uuid" + "go.mau.fi/util/exslices" + "go.mau.fi/util/ptr" + "golang.org/x/exp/slices" + + signalpb "go.mau.fi/mautrix-signal/pkg/signalmeow/protobuf" + "go.mau.fi/mautrix-signal/pkg/signalmeow/protobuf/backuppb" +) + +func boolToInt(b bool) int { + if b { + return 1 + } + return 0 +} + +type AttachmentMap map[uuid.UUID]*backuppb.FilePointer_BackupLocator + +func BackupToDataMessage(ci *backuppb.ChatItem, attMap AttachmentMap) (*signalpb.DataMessage, []*backuppb.Reaction) { + var dm signalpb.DataMessage + var reactions []*backuppb.Reaction + switch ti := ci.Item.(type) { + case *backuppb.ChatItem_StandardMessage: + reactions = ti.StandardMessage.Reactions + if text := ti.StandardMessage.Text; text != nil { + dm.Body = &text.Body + dm.BodyRanges = slices.DeleteFunc(exslices.CastFunc(text.BodyRanges, backupToSignalBodyRange), deleteNil) + } + dm.Attachments = make([]*signalpb.AttachmentPointer, 0, len(ti.StandardMessage.Attachments)+boolToInt(ti.StandardMessage.LongText != nil)) + if ti.StandardMessage.LongText != nil { + randomUUID := uuid.New() + dm.Attachments = append( + dm.Attachments, + backupToSignalAttachment(ti.StandardMessage.LongText, 0, randomUUID, attMap), + ) + } + for _, att := range ti.StandardMessage.Attachments { + var clientUUID uuid.UUID + if len(att.ClientUuid) == 16 { + clientUUID = uuid.UUID(att.ClientUuid) + } else { + clientUUID = uuid.New() + } + dm.Attachments = append( + dm.Attachments, + backupToSignalAttachment(att.Pointer, att.Flag, clientUUID, attMap), + ) + } + dm.Preview = exslices.CastFunc(ti.StandardMessage.LinkPreview, func(from *backuppb.LinkPreview) *signalpb.Preview { + return backupToSignalLinkPreview(from, attMap) + }) + case *backuppb.ChatItem_ContactMessage: + reactions = ti.ContactMessage.Reactions + dm.Contact = []*signalpb.DataMessage_Contact{backupToSignalContact(ti.ContactMessage.Contact, attMap)} + case *backuppb.ChatItem_StickerMessage: + reactions = ti.StickerMessage.Reactions + dm.Sticker = &signalpb.DataMessage_Sticker{ + PackId: ti.StickerMessage.Sticker.PackId, + PackKey: ti.StickerMessage.Sticker.PackKey, + StickerId: &ti.StickerMessage.Sticker.StickerId, + Emoji: ti.StickerMessage.Sticker.Emoji, + Data: backupToSignalAttachment(ti.StickerMessage.Sticker.Data, 0, uuid.New(), attMap), + } + case *backuppb.ChatItem_RemoteDeletedMessage: + // TODO handle some other way? (also disappeared view-once messages) + return nil, nil + case *backuppb.ChatItem_PaymentNotification: + dm.Payment = &signalpb.DataMessage_Payment{ + Item: &signalpb.DataMessage_Payment_Notification_{ + Notification: &signalpb.DataMessage_Payment_Notification{ + Transaction: nil, + Note: ti.PaymentNotification.Note, + }, + }, + } + case *backuppb.ChatItem_GiftBadge: + dm.GiftBadge = &signalpb.DataMessage_GiftBadge{ + ReceiptCredentialPresentation: ti.GiftBadge.ReceiptCredentialPresentation, + } + case *backuppb.ChatItem_ViewOnceMessage: + reactions = ti.ViewOnceMessage.Reactions + if ti.ViewOnceMessage.Attachment == nil { + // TODO handle some other way? + return nil, reactions + } + dm.IsViewOnce = ptr.Ptr(true) + var clientUUID uuid.UUID + if len(ti.ViewOnceMessage.Attachment.ClientUuid) == 16 { + clientUUID = uuid.UUID(ti.ViewOnceMessage.Attachment.ClientUuid) + } else { + clientUUID = uuid.New() + } + dm.Attachments = []*signalpb.AttachmentPointer{backupToSignalAttachment( + ti.ViewOnceMessage.Attachment.Pointer, + ti.ViewOnceMessage.Attachment.Flag, + clientUUID, + attMap, + )} + } + return &dm, reactions +} + +func backupToSignalContact(from *backuppb.ContactAttachment, attMap AttachmentMap) *signalpb.DataMessage_Contact { + var contact signalpb.DataMessage_Contact + if from.Name != nil { + contact.Name = &signalpb.DataMessage_Contact_Name{ + GivenName: &from.Name.GivenName, + FamilyName: &from.Name.FamilyName, + Prefix: &from.Name.Prefix, + Suffix: &from.Name.Suffix, + MiddleName: &from.Name.MiddleName, + Nickname: &from.Name.Nickname, + } + } + contact.Number = exslices.CastFunc(from.Number, func(from *backuppb.ContactAttachment_Phone) *signalpb.DataMessage_Contact_Phone { + return &signalpb.DataMessage_Contact_Phone{ + Value: &from.Value, + Type: ptr.NonZero(signalpb.DataMessage_Contact_Phone_Type(from.Type)), + Label: &from.Label, + } + }) + contact.Email = exslices.CastFunc(from.Email, func(from *backuppb.ContactAttachment_Email) *signalpb.DataMessage_Contact_Email { + return &signalpb.DataMessage_Contact_Email{ + Value: &from.Value, + Type: ptr.NonZero(signalpb.DataMessage_Contact_Email_Type(from.Type)), + Label: &from.Label, + } + }) + contact.Address = exslices.CastFunc(from.Address, func(from *backuppb.ContactAttachment_PostalAddress) *signalpb.DataMessage_Contact_PostalAddress { + return &signalpb.DataMessage_Contact_PostalAddress{ + Type: ptr.NonZero(signalpb.DataMessage_Contact_PostalAddress_Type(from.Type)), + Label: &from.Label, + Street: &from.Street, + Pobox: &from.Pobox, + Neighborhood: &from.Neighborhood, + City: &from.City, + Region: &from.Region, + Postcode: &from.Postcode, + Country: &from.Country, + } + }) + if from.Avatar != nil { + contact.Avatar = &signalpb.DataMessage_Contact_Avatar{ + Avatar: backupToSignalAttachment(from.Avatar, 0, uuid.New(), attMap), + } + } + contact.Organization = ptr.NonZero(from.Organization) + return &contact +} + +func backupToSignalLinkPreview(from *backuppb.LinkPreview, attMap AttachmentMap) *signalpb.Preview { + var ap *signalpb.AttachmentPointer + if from.Image != nil { + ap = backupToSignalAttachment(from.Image, 0, uuid.New(), attMap) + } + return &signalpb.Preview{ + Url: &from.Url, + Title: from.Title, + Image: ap, + Description: from.Description, + Date: from.Date, + } +} + +func backupToSignalAttachment( + fp *backuppb.FilePointer, + flag backuppb.MessageAttachment_Flag, + clientUUID uuid.UUID, + atts map[uuid.UUID]*backuppb.FilePointer_BackupLocator, +) *signalpb.AttachmentPointer { + sig := &signalpb.AttachmentPointer{ + ContentType: fp.ContentType, + IncrementalMac: fp.IncrementalMac, + IncrementalMacChunkSize: fp.IncrementalMacChunkSize, + FileName: fp.FileName, + Flags: ptr.NonZero(uint32(backupToSignalAttachmentFlag(flag))), + Width: fp.Width, + Height: fp.Height, + Caption: nil, // is this field deprecated or something? + BlurHash: fp.BlurHash, + Uuid: clientUUID[:], + } + switch loc := fp.Locator.(type) { + case *backuppb.FilePointer_AttachmentLocator_: + sig.AttachmentIdentifier = &signalpb.AttachmentPointer_CdnKey{CdnKey: loc.AttachmentLocator.CdnKey} + sig.Key = loc.AttachmentLocator.Key + sig.Size = &loc.AttachmentLocator.Size + sig.Digest = loc.AttachmentLocator.Digest + sig.CdnNumber = &loc.AttachmentLocator.CdnNumber + case *backuppb.FilePointer_BackupLocator_: + atts[clientUUID] = loc.BackupLocator + case *backuppb.FilePointer_InvalidAttachmentLocator_: + atts[clientUUID] = nil + } + return sig +} + +func backupToSignalAttachmentFlag(flag backuppb.MessageAttachment_Flag) signalpb.AttachmentPointer_Flags { + switch flag { + case backuppb.MessageAttachment_VOICE_MESSAGE: + return signalpb.AttachmentPointer_VOICE_MESSAGE + case backuppb.MessageAttachment_BORDERLESS: + return signalpb.AttachmentPointer_BORDERLESS + case backuppb.MessageAttachment_GIF: + return compatFlagGIF + case backuppb.MessageAttachment_NONE: + fallthrough + default: + return 0 + } +} + +func deleteNil(bodyRange *signalpb.BodyRange) bool { + return bodyRange == nil +} + +func backupToSignalBodyRange(from *backuppb.BodyRange) *signalpb.BodyRange { + var out signalpb.BodyRange + out.Start = from.Start + out.Length = from.Length + switch av := from.AssociatedValue.(type) { + case *backuppb.BodyRange_MentionAci: + // TODO confirm this is correct + if len(av.MentionAci) != 16 { + return nil + } + out.AssociatedValue = &signalpb.BodyRange_MentionAci{MentionAci: uuid.UUID(av.MentionAci).String()} + case *backuppb.BodyRange_Style_: + out.AssociatedValue = &signalpb.BodyRange_Style_{Style: signalpb.BodyRange_Style(av.Style)} + } + return &out +} diff --git a/pkg/msgconv/from-signal.go b/pkg/msgconv/from-signal.go index a7ceb0d..714b723 100644 --- a/pkg/msgconv/from-signal.go +++ b/pkg/msgconv/from-signal.go @@ -83,6 +83,7 @@ func (mc *MessageConverter) ToMatrix( portal *bridgev2.Portal, intent bridgev2.MatrixAPI, dm *signalpb.DataMessage, + attMap AttachmentMap, ) *bridgev2.ConvertedMessage { ctx = context.WithValue(ctx, contextKeyClient, client) ctx = context.WithValue(ctx, contextKeyPortal, portal) @@ -102,15 +103,15 @@ func (mc *MessageConverter) ToMatrix( cm.Disappear.Timer = time.Duration(dm.GetExpireTimer()) * time.Second } if dm.Sticker != nil { - cm.Parts = append(cm.Parts, mc.convertStickerToMatrix(ctx, dm.Sticker)) + cm.Parts = append(cm.Parts, mc.convertStickerToMatrix(ctx, dm.Sticker, attMap)) // Don't allow any other parts in a sticker message return cm } for i, att := range dm.GetAttachments() { if att.GetContentType() != "text/x-signal-plain" { - cm.Parts = append(cm.Parts, mc.convertAttachmentToMatrix(ctx, i, att)) + cm.Parts = append(cm.Parts, mc.convertAttachmentToMatrix(ctx, i, att, attMap)) } else { - longBody, err := mc.downloadSignalLongText(ctx, att) + longBody, err := mc.downloadSignalLongText(ctx, att, attMap) if err == nil { dm.Body = longBody } else { @@ -119,7 +120,7 @@ func (mc *MessageConverter) ToMatrix( } } for _, contact := range dm.GetContact() { - cm.Parts = append(cm.Parts, mc.convertContactToMatrix(ctx, contact)) + cm.Parts = append(cm.Parts, mc.convertContactToMatrix(ctx, contact, attMap)) } if dm.Payment != nil { cm.Parts = append(cm.Parts, mc.convertPaymentToMatrix(ctx, dm.Payment)) @@ -128,7 +129,7 @@ func (mc *MessageConverter) ToMatrix( cm.Parts = append(cm.Parts, mc.convertGiftBadgeToMatrix(ctx, dm.GiftBadge)) } if dm.Body != nil { - cm.Parts = append(cm.Parts, mc.convertTextToMatrix(ctx, dm)) + cm.Parts = append(cm.Parts, mc.convertTextToMatrix(ctx, dm, attMap)) } if len(cm.Parts) == 0 && dm.GetRequiredProtocolVersion() > uint32(signalpb.DataMessage_CURRENT) { cm.Parts = append(cm.Parts, &bridgev2.ConvertedMessagePart{ @@ -205,11 +206,11 @@ func (mc *MessageConverter) ConvertDisappearingTimerChangeToMatrix(ctx context.C return part } -func (mc *MessageConverter) convertTextToMatrix(ctx context.Context, dm *signalpb.DataMessage) *bridgev2.ConvertedMessagePart { +func (mc *MessageConverter) convertTextToMatrix(ctx context.Context, dm *signalpb.DataMessage, attMap AttachmentMap) *bridgev2.ConvertedMessagePart { content := signalfmt.Parse(ctx, dm.GetBody(), dm.GetBodyRanges(), mc.SignalFmtParams) extra := map[string]any{} if len(dm.Preview) > 0 { - content.BeeperLinkPreviews = mc.convertURLPreviewsToBeeper(ctx, dm.Preview) + content.BeeperLinkPreviews = mc.convertURLPreviewsToBeeper(ctx, dm.Preview, attMap) } return &bridgev2.ConvertedMessagePart{ Type: event.EventMessage, @@ -244,7 +245,7 @@ func (mc *MessageConverter) convertGiftBadgeToMatrix(_ context.Context, giftBadg } } -func (mc *MessageConverter) convertContactToVCard(ctx context.Context, contact *signalpb.DataMessage_Contact) vcard.Card { +func (mc *MessageConverter) convertContactToVCard(ctx context.Context, contact *signalpb.DataMessage_Contact, attMap AttachmentMap) vcard.Card { card := make(vcard.Card) card.SetValue(vcard.FieldVersion, "4.0") name := contact.GetName() @@ -306,7 +307,7 @@ func (mc *MessageConverter) convertContactToVCard(ctx context.Context, contact * card.Add(vcard.FieldTelephone, &field) } if contact.GetAvatar().GetAvatar() != nil { - avatarData, err := signalmeow.DownloadAttachment(ctx, contact.GetAvatar().GetAvatar()) + avatarData, err := mc.downloadAttachment(ctx, contact.GetAvatar().GetAvatar(), attMap) if err != nil { zerolog.Ctx(ctx).Err(err).Msg("Failed to download contact avatar") } else { @@ -320,8 +321,8 @@ func (mc *MessageConverter) convertContactToVCard(ctx context.Context, contact * return card } -func (mc *MessageConverter) convertContactToMatrix(ctx context.Context, contact *signalpb.DataMessage_Contact) *bridgev2.ConvertedMessagePart { - card := mc.convertContactToVCard(ctx, contact) +func (mc *MessageConverter) convertContactToMatrix(ctx context.Context, contact *signalpb.DataMessage_Contact, attMap AttachmentMap) *bridgev2.ConvertedMessagePart { + card := mc.convertContactToVCard(ctx, contact, attMap) contact.Avatar = nil extraData := map[string]any{ "fi.mau.signal.contact": contact, @@ -380,8 +381,8 @@ func (mc *MessageConverter) convertContactToMatrix(ctx context.Context, contact } } -func (mc *MessageConverter) convertAttachmentToMatrix(ctx context.Context, index int, att *signalpb.AttachmentPointer) *bridgev2.ConvertedMessagePart { - part, err := mc.reuploadAttachment(ctx, att) +func (mc *MessageConverter) convertAttachmentToMatrix(ctx context.Context, index int, att *signalpb.AttachmentPointer, attMap AttachmentMap) *bridgev2.ConvertedMessagePart { + part, err := mc.reuploadAttachment(ctx, att, attMap) if err != nil { zerolog.Ctx(ctx).Err(err).Int("attachment_index", index).Msg("Failed to handle attachment") return &bridgev2.ConvertedMessagePart{ @@ -395,8 +396,8 @@ func (mc *MessageConverter) convertAttachmentToMatrix(ctx context.Context, index return part } -func (mc *MessageConverter) convertStickerToMatrix(ctx context.Context, sticker *signalpb.DataMessage_Sticker) *bridgev2.ConvertedMessagePart { - converted, err := mc.reuploadAttachment(ctx, sticker.GetData()) +func (mc *MessageConverter) convertStickerToMatrix(ctx context.Context, sticker *signalpb.DataMessage_Sticker, attMap AttachmentMap) *bridgev2.ConvertedMessagePart { + converted, err := mc.reuploadAttachment(ctx, sticker.GetData(), attMap) if err != nil { zerolog.Ctx(ctx).Err(err).Msg("Failed to handle sticker") return &bridgev2.ConvertedMessagePart{ @@ -430,8 +431,8 @@ func (mc *MessageConverter) convertStickerToMatrix(ctx context.Context, sticker return converted } -func (mc *MessageConverter) downloadSignalLongText(ctx context.Context, att *signalpb.AttachmentPointer) (*string, error) { - data, err := signalmeow.DownloadAttachment(ctx, att) +func (mc *MessageConverter) downloadSignalLongText(ctx context.Context, att *signalpb.AttachmentPointer, attMap AttachmentMap) (*string, error) { + data, err := mc.downloadAttachment(ctx, att, attMap) if err != nil { return nil, fmt.Errorf("failed to download attachment: %w", err) } @@ -439,8 +440,26 @@ func (mc *MessageConverter) downloadSignalLongText(ctx context.Context, att *sig return &longBody, nil } -func (mc *MessageConverter) reuploadAttachment(ctx context.Context, att *signalpb.AttachmentPointer) (*bridgev2.ConvertedMessagePart, error) { - data, err := signalmeow.DownloadAttachment(ctx, att) +func (mc *MessageConverter) downloadAttachment(ctx context.Context, att *signalpb.AttachmentPointer, attMap AttachmentMap) ([]byte, error) { + if att.AttachmentIdentifier == nil { + if len(att.GetUuid()) != 16 { + return nil, fmt.Errorf("no attachment identifier found") + } + target, ok := attMap[uuid.UUID(att.GetUuid())] + if !ok { + return nil, fmt.Errorf("no attachment identifier and attachment not found in map") + } else if target == nil { + return nil, fmt.Errorf("attachment not available in backup") + } else { + // TODO add support for downloading attachments from backup + return nil, fmt.Errorf("downloading attachments from backup is not yet supported") + } + } + return signalmeow.DownloadAttachment(ctx, att) +} + +func (mc *MessageConverter) reuploadAttachment(ctx context.Context, att *signalpb.AttachmentPointer, attMap AttachmentMap) (*bridgev2.ConvertedMessagePart, error) { + data, err := mc.downloadAttachment(ctx, att, attMap) if err != nil { return nil, fmt.Errorf("failed to download attachment: %w", err) } diff --git a/pkg/msgconv/urlpreview.go b/pkg/msgconv/urlpreview.go index 5731a0b..fcb32fb 100644 --- a/pkg/msgconv/urlpreview.go +++ b/pkg/msgconv/urlpreview.go @@ -27,15 +27,15 @@ import ( signalpb "go.mau.fi/mautrix-signal/pkg/signalmeow/protobuf" ) -func (mc *MessageConverter) convertURLPreviewsToBeeper(ctx context.Context, preview []*signalpb.Preview) []*event.BeeperLinkPreview { +func (mc *MessageConverter) convertURLPreviewsToBeeper(ctx context.Context, preview []*signalpb.Preview, attMap AttachmentMap) []*event.BeeperLinkPreview { output := make([]*event.BeeperLinkPreview, len(preview)) for i, p := range preview { - output[i] = mc.convertURLPreviewToBeeper(ctx, p) + output[i] = mc.convertURLPreviewToBeeper(ctx, p, attMap) } return output } -func (mc *MessageConverter) convertURLPreviewToBeeper(ctx context.Context, preview *signalpb.Preview) *event.BeeperLinkPreview { +func (mc *MessageConverter) convertURLPreviewToBeeper(ctx context.Context, preview *signalpb.Preview, attMap AttachmentMap) *event.BeeperLinkPreview { output := &event.BeeperLinkPreview{ MatchedURL: preview.GetUrl(), LinkPreview: event.LinkPreview{ @@ -45,7 +45,7 @@ func (mc *MessageConverter) convertURLPreviewToBeeper(ctx context.Context, previ }, } if preview.Image != nil { - msg, err := mc.reuploadAttachment(ctx, preview.Image) + msg, err := mc.reuploadAttachment(ctx, preview.Image, attMap) if err != nil { zerolog.Ctx(ctx).Err(err).Msg("Failed to reupload link preview image") } else { From fc6a95375e095b1658261c45a2cf84bee581527e Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Sat, 18 Jan 2025 15:19:24 +0200 Subject: [PATCH 259/580] msgconv: switch from exp/slices to stdlib slices --- pkg/msgconv/from-signal-backup.go | 3 ++- pkg/msgconv/matrixfmt/html.go | 2 +- pkg/msgconv/signalfmt/convert.go | 2 +- pkg/signalmeow/storageservice.go | 2 +- 4 files changed, 5 insertions(+), 4 deletions(-) diff --git a/pkg/msgconv/from-signal-backup.go b/pkg/msgconv/from-signal-backup.go index 1b99b85..bf479ac 100644 --- a/pkg/msgconv/from-signal-backup.go +++ b/pkg/msgconv/from-signal-backup.go @@ -17,10 +17,11 @@ package msgconv import ( + "slices" + "github.com/google/uuid" "go.mau.fi/util/exslices" "go.mau.fi/util/ptr" - "golang.org/x/exp/slices" signalpb "go.mau.fi/mautrix-signal/pkg/signalmeow/protobuf" "go.mau.fi/mautrix-signal/pkg/signalmeow/protobuf/backuppb" diff --git a/pkg/msgconv/matrixfmt/html.go b/pkg/msgconv/matrixfmt/html.go index 5c4a37f..958ccc3 100644 --- a/pkg/msgconv/matrixfmt/html.go +++ b/pkg/msgconv/matrixfmt/html.go @@ -4,11 +4,11 @@ import ( "context" "fmt" "math" + "slices" "strconv" "strings" "github.com/google/uuid" - "golang.org/x/exp/slices" "golang.org/x/net/html" "maunium.net/go/mautrix/event" "maunium.net/go/mautrix/id" diff --git a/pkg/msgconv/signalfmt/convert.go b/pkg/msgconv/signalfmt/convert.go index 06bbe7b..f950a59 100644 --- a/pkg/msgconv/signalfmt/convert.go +++ b/pkg/msgconv/signalfmt/convert.go @@ -19,11 +19,11 @@ package signalfmt import ( "context" "html" + "slices" "strings" "github.com/google/uuid" "golang.org/x/exp/maps" - "golang.org/x/exp/slices" "maunium.net/go/mautrix/event" "maunium.net/go/mautrix/id" diff --git a/pkg/signalmeow/storageservice.go b/pkg/signalmeow/storageservice.go index ae003ae..28412b6 100644 --- a/pkg/signalmeow/storageservice.go +++ b/pkg/signalmeow/storageservice.go @@ -24,6 +24,7 @@ import ( "fmt" "io" "net/http" + "slices" "strings" "github.com/google/uuid" @@ -31,7 +32,6 @@ import ( "go.mau.fi/util/exerrors" "golang.org/x/crypto/hkdf" "golang.org/x/exp/maps" - "golang.org/x/exp/slices" "google.golang.org/protobuf/proto" "go.mau.fi/mautrix-signal/pkg/libsignalgo" From 8cdc01f21d65b24a961b7e99c3f50adb3fa3c022 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Sat, 18 Jan 2025 23:39:15 +0200 Subject: [PATCH 260/580] chatinfo: stop using deprecated Members list --- pkg/connector/chatinfo.go | 14 +++++++----- pkg/connector/groupinfo.go | 45 +++++++++++++++++++++----------------- 2 files changed, 33 insertions(+), 26 deletions(-) diff --git a/pkg/connector/chatinfo.go b/pkg/connector/chatinfo.go index 7bd392f..4071e68 100644 --- a/pkg/connector/chatinfo.go +++ b/pkg/connector/chatinfo.go @@ -227,11 +227,12 @@ func (s *SignalClient) GetContactList(ctx context.Context) ([]*bridgev2.ResolveI func (s *SignalClient) makeCreateDMResponse(recipient *types.Recipient) *bridgev2.CreateChatResponse { name := "" topic := PrivateChatTopic + selfUser := s.makeEventSender(s.Client.Store.ACI) members := &bridgev2.ChatMemberList{ IsFull: true, - Members: []bridgev2.ChatMember{ - { - EventSender: s.makeEventSender(s.Client.Store.ACI), + MemberMap: map[networkid.UserID]bridgev2.ChatMember{ + selfUser.Sender: { + EventSender: selfUser, Membership: event.MembershipJoin, PowerLevel: &moderatorPL, }, @@ -257,11 +258,12 @@ func (s *SignalClient) makeCreateDMResponse(recipient *types.Recipient) *bridgev } } else { // The other user is only present if their ACI is known - members.Members = append(members.Members, bridgev2.ChatMember{ - EventSender: s.makeEventSender(recipient.ACI), + recipientUser := s.makeEventSender(recipient.ACI) + members.MemberMap[recipientUser.Sender] = bridgev2.ChatMember{ + EventSender: recipientUser, Membership: event.MembershipJoin, PowerLevel: &moderatorPL, - }) + } } serviceID = libsignalgo.NewACIServiceID(recipient.ACI) } diff --git a/pkg/connector/groupinfo.go b/pkg/connector/groupinfo.go index 843a18e..e5c1fc5 100644 --- a/pkg/connector/groupinfo.go +++ b/pkg/connector/groupinfo.go @@ -25,6 +25,7 @@ import ( "go.mau.fi/util/ptr" "maunium.net/go/mautrix/bridgev2" "maunium.net/go/mautrix/bridgev2/database" + "maunium.net/go/mautrix/bridgev2/networkid" "maunium.net/go/mautrix/event" "go.mau.fi/mautrix-signal/pkg/libsignalgo" @@ -47,7 +48,7 @@ func roleToPL(role signalmeow.GroupMemberRole) *int { } } -func applyAnnouncementsOnly(plc *bridgev2.PowerLevelChanges, announcementsOnly bool) { +func applyAnnouncementsOnly(plc *bridgev2.PowerLevelOverrides, announcementsOnly bool) { if announcementsOnly { plc.EventsDefault = &moderatorPL } else { @@ -55,7 +56,7 @@ func applyAnnouncementsOnly(plc *bridgev2.PowerLevelChanges, announcementsOnly b } } -func applyAttributesAccess(plc *bridgev2.PowerLevelChanges, attributeAccess signalmeow.AccessControl) { +func applyAttributesAccess(plc *bridgev2.PowerLevelOverrides, attributeAccess signalmeow.AccessControl) { attributePL := defaultPL if attributeAccess == signalmeow.AccessControl_ADMINISTRATOR { attributePL = moderatorPL @@ -65,7 +66,7 @@ func applyAttributesAccess(plc *bridgev2.PowerLevelChanges, attributeAccess sign plc.Events[event.StateTopic] = attributePL } -func applyMembersAccess(plc *bridgev2.PowerLevelChanges, memberAccess signalmeow.AccessControl) { +func applyMembersAccess(plc *bridgev2.PowerLevelOverrides, memberAccess signalmeow.AccessControl) { if memberAccess == signalmeow.AccessControl_ADMINISTRATOR { plc.Invite = &moderatorPL } else { @@ -98,9 +99,9 @@ func (s *SignalClient) getGroupInfo(ctx context.Context, groupID types.GroupIden return nil, err } members := &bridgev2.ChatMemberList{ - IsFull: true, - Members: make([]bridgev2.ChatMember, len(groupInfo.Members), len(groupInfo.Members)+len(groupInfo.PendingMembers)+len(groupInfo.RequestingMembers)+len(groupInfo.BannedMembers)), - PowerLevels: &bridgev2.PowerLevelChanges{ + IsFull: true, + MemberMap: make(map[networkid.UserID]bridgev2.ChatMember, len(groupInfo.Members)+len(groupInfo.PendingMembers)+len(groupInfo.RequestingMembers)+len(groupInfo.BannedMembers)), + PowerLevels: &bridgev2.PowerLevelOverrides{ Events: map[event.Type]int{ event.StatePowerLevels: moderatorPL, }, @@ -113,9 +114,10 @@ func (s *SignalClient) getGroupInfo(ctx context.Context, groupID types.GroupIden applyMembersAccess(members.PowerLevels, groupInfo.AccessControl.Members) joinRule = inviteLinkToJoinRule(groupInfo.AccessControl.AddFromInviteLink) } - for i, member := range groupInfo.Members { - members.Members[i] = bridgev2.ChatMember{ - EventSender: s.makeEventSender(member.ACI), + for _, member := range groupInfo.Members { + evtSender := s.makeEventSender(member.ACI) + members.MemberMap[evtSender.Sender] = bridgev2.ChatMember{ + EventSender: evtSender, PowerLevel: roleToPL(member.Role), Membership: event.MembershipJoin, } @@ -125,27 +127,30 @@ func (s *SignalClient) getGroupInfo(ctx context.Context, groupID types.GroupIden if aci == nil { continue } - members.Members = append(members.Members, bridgev2.ChatMember{ - EventSender: s.makeEventSender(*aci), + evtSender := s.makeEventSender(*aci) + members.MemberMap[evtSender.Sender] = bridgev2.ChatMember{ + EventSender: evtSender, PowerLevel: roleToPL(member.Role), Membership: event.MembershipInvite, - }) + } } for _, member := range groupInfo.RequestingMembers { - members.Members = append(members.Members, bridgev2.ChatMember{ - EventSender: s.makeEventSender(member.ACI), + evtSender := s.makeEventSender(member.ACI) + members.MemberMap[evtSender.Sender] = bridgev2.ChatMember{ + EventSender: evtSender, Membership: event.MembershipKnock, - }) + } } for _, member := range groupInfo.BannedMembers { aci := s.maybeResolvePNItoACI(ctx, &member.ServiceID) if aci == nil { continue } - members.Members = append(members.Members, bridgev2.ChatMember{ - EventSender: s.makeEventSender(*aci), + evtSender := s.makeEventSender(*aci) + members.MemberMap[evtSender.Sender] = bridgev2.ChatMember{ + EventSender: evtSender, Membership: event.MembershipBan, - }) + } } return &bridgev2.ChatInfo{ Name: &groupInfo.Title, @@ -203,11 +208,11 @@ func (s *SignalClient) groupChangeToChatInfoChange(ctx context.Context, rev uint } } - var pls *bridgev2.PowerLevelChanges + var pls *bridgev2.PowerLevelOverrides if groupChange.ModifyAnnouncementsOnly != nil || groupChange.ModifyAttributesAccess != nil || groupChange.ModifyMemberAccess != nil { - pls = &bridgev2.PowerLevelChanges{Events: make(map[event.Type]int)} + pls = &bridgev2.PowerLevelOverrides{Events: make(map[event.Type]int)} if groupChange.ModifyAnnouncementsOnly != nil { applyAnnouncementsOnly(pls, *groupChange.ModifyAnnouncementsOnly) } From 030c83c197ea3499b924fa753204c4c8caac25aa Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Sun, 19 Jan 2025 13:58:03 +0200 Subject: [PATCH 261/580] chatinfo: only clear avatar after fetching profile with no avatar --- pkg/connector/chatinfo.go | 10 +++++----- pkg/signalmeow/profile.go | 6 +++++- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/pkg/connector/chatinfo.go b/pkg/connector/chatinfo.go index 4071e68..e3eef59 100644 --- a/pkg/connector/chatinfo.go +++ b/pkg/connector/chatinfo.go @@ -102,6 +102,11 @@ func (s *SignalClient) contactToUserInfo(contact *types.Recipient) *bridgev2.Use return contact.ContactAvatar.Image, nil }, } + } else if contact.Profile.AvatarPath == "clear" { + ui.Avatar = &bridgev2.Avatar{ + ID: "", + Remove: true, + } } else if contact.Profile.AvatarPath != "" { ui.Avatar = &bridgev2.Avatar{ ID: makeAvatarPathID(contact.Profile.AvatarPath), @@ -109,11 +114,6 @@ func (s *SignalClient) contactToUserInfo(contact *types.Recipient) *bridgev2.Use return s.Client.DownloadUserAvatar(ctx, contact.Profile.AvatarPath, contact.Profile.Key) }, } - } else { - ui.Avatar = &bridgev2.Avatar{ - ID: "", - Remove: true, - } } return ui } diff --git a/pkg/signalmeow/profile.go b/pkg/signalmeow/profile.go index 1a7571c..440fe1b 100644 --- a/pkg/signalmeow/profile.go +++ b/pkg/signalmeow/profile.go @@ -243,7 +243,11 @@ func (cli *Client) fetchProfileWithRequestAndKey(ctx context.Context, signalID u } } // TODO store other metadata fields? - profile.AvatarPath = profileResponse.Avatar + if profileResponse.Avatar == "" { + profile.AvatarPath = "clear" + } else { + profile.AvatarPath = profileResponse.Avatar + } profile.Credential = profileResponse.Credential profile.Key = *profileKey From dd3aab051fe9a25f10d6deb6f28c0120764de031 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Sat, 18 Jan 2025 16:29:20 +0200 Subject: [PATCH 262/580] signalmeow: store history transfer data in db --- pkg/libsignalgo/groupsecretparams.go | 13 + pkg/signalmeow/backup.go | 66 +++- pkg/signalmeow/groups.go | 13 +- pkg/signalmeow/store/backup_store.go | 331 ++++++++++++++++++ pkg/signalmeow/store/container.go | 4 + pkg/signalmeow/store/device.go | 3 + pkg/signalmeow/store/upgrades/00-latest.sql | 77 +++- .../store/upgrades/19-store-backup-data.sql | 52 +++ 8 files changed, 515 insertions(+), 44 deletions(-) create mode 100644 pkg/signalmeow/store/backup_store.go create mode 100644 pkg/signalmeow/store/upgrades/19-store-backup-data.sql diff --git a/pkg/libsignalgo/groupsecretparams.go b/pkg/libsignalgo/groupsecretparams.go index 8ad9b39..c6189af 100644 --- a/pkg/libsignalgo/groupsecretparams.go +++ b/pkg/libsignalgo/groupsecretparams.go @@ -23,6 +23,7 @@ package libsignalgo import "C" import ( "crypto/rand" + "fmt" "runtime" "unsafe" @@ -54,6 +55,18 @@ func GenerateGroupSecretParams() (GroupSecretParams, error) { return GenerateGroupSecretParamsWithRandomness(GenerateRandomness()) } +func (gmk GroupMasterKey) GroupIdentifier() (*GroupIdentifier, error) { + if groupSecretParams, err := DeriveGroupSecretParamsFromMasterKey(gmk); err != nil { + return nil, fmt.Errorf("DeriveGroupSecretParamsFromMasterKey error: %w", err) + } else if groupPublicParams, err := groupSecretParams.GetPublicParams(); err != nil { + return nil, fmt.Errorf("GetPublicParams error: %w", err) + } else if groupIdentifier, err := GetGroupIdentifier(*groupPublicParams); err != nil { + return nil, fmt.Errorf("GetGroupIdentifier error: %w", err) + } else { + return groupIdentifier, nil + } +} + func GenerateGroupSecretParamsWithRandomness(randomness Randomness) (GroupSecretParams, error) { var params [C.SignalGROUP_SECRET_PARAMS_LEN]C.uchar signalFfiError := C.signal_group_secret_params_generate_deterministic(¶ms, (*[C.SignalRANDOMNESS_LEN]C.uint8_t)(unsafe.Pointer(&randomness))) diff --git a/pkg/signalmeow/backup.go b/pkg/signalmeow/backup.go index 536302d..d69a729 100644 --- a/pkg/signalmeow/backup.go +++ b/pkg/signalmeow/backup.go @@ -41,12 +41,14 @@ import ( const transferArchiveFetchTimeout = 1 * time.Hour var ( - ErrTransferRelinkRequested = errors.New("relink requested") - ErrTransferContinueWithoutUpload = errors.New("continue without upload") - ErrNoEphemeralBackupKey = errors.New("no ephemeral backup key") ) +const ( + TransferErrorRelinkRequested = "RELINK_REQUESTED" + TransferErrorContinueWithoutUpload = "CONTINUE_WITHOUT_UPLOAD" +) + type TransferArchiveMetadata struct { CDN uint32 `json:"cdn"` Key string `json:"key"` @@ -55,14 +57,7 @@ type TransferArchiveMetadata struct { func (cli *Client) FetchAndProcessTransfer(ctx context.Context, meta *TransferArchiveMetadata) error { if meta.Error != "" { - switch meta.Error { - case "RELINK_REQUESTED": - return ErrTransferRelinkRequested - case "CONTINUE_WITHOUT_UPLOAD": - return ErrTransferContinueWithoutUpload - default: - return fmt.Errorf("transfer archive error: %s", meta.Error) - } + return fmt.Errorf("transfer archive error: %s", meta.Error) } aesKey, hmacKey, err := cli.deriveTransferKeys() if err != nil { @@ -98,15 +93,29 @@ func (cli *Client) FetchAndProcessTransfer(ctx context.Context, meta *TransferAr if err != nil { return fmt.Errorf("failed to seek to start of file: %w", err) } - err = cli.processTransferArchive(ctx, aesKey, hmacKey, file, stat.Size()) + err = cli.Store.DoTxn(ctx, func(ctx context.Context) error { + err = cli.Store.BackupStore.ClearBackup(ctx) + if err != nil { + return fmt.Errorf("failed to clear backup: %w", err) + } + err = cli.processTransferArchive(ctx, aesKey, hmacKey, file, stat.Size()) + if err != nil { + return err + } + err = cli.Store.BackupStore.RecalculateChatCounts(ctx) + if err != nil { + return fmt.Errorf("failed to calculate message counts: %w", err) + } + cli.Store.EphemeralBackupKey = nil + err = cli.Store.DeviceStore.PutDevice(ctx, &cli.Store.DeviceData) + if err != nil { + return fmt.Errorf("failed to save device data after clearing ephemeral backup key: %w", err) + } + return nil + }) if err != nil { return err } - cli.Store.EphemeralBackupKey = nil - err = cli.Store.DeviceStore.PutDevice(ctx, &cli.Store.DeviceData) - if err != nil { - return fmt.Errorf("failed to save device data after clearing ephemeral backup key: %w", err) - } return nil } @@ -185,8 +194,27 @@ func (acp *archiveChunkProcessor) processChunk(buf []byte) error { } func (acp *archiveChunkProcessor) processFrame(frame *backuppb.Frame) error { - acp.cli.Log.Info().Any("backup_frame", frame).Msg("Received backup frame") - return nil + acp.cli.Log.Trace().Any("backup_frame", frame).Msg("Processing backup frame") + switch item := frame.Item.(type) { + case *backuppb.Frame_Recipient: + return acp.cli.Store.BackupStore.AddBackupRecipient(acp.ctx, item.Recipient) + case *backuppb.Frame_Chat: + return acp.cli.Store.BackupStore.AddBackupChat(acp.ctx, item.Chat) + case *backuppb.Frame_ChatItem: + switch item.ChatItem.Item.(type) { + case *backuppb.ChatItem_DirectStoryReplyMessage, *backuppb.ChatItem_UpdateMessage: + zerolog.Ctx(acp.ctx).Debug(). + Uint64("chat_id", item.ChatItem.ChatId). + Uint64("message_id", item.ChatItem.DateSent). + Type("frame_type", item). + Msg("Not saving unsupported chat item type") + return nil + } + return acp.cli.Store.BackupStore.AddBackupChatItem(acp.ctx, item.ChatItem) + default: + zerolog.Ctx(acp.ctx).Debug().Type("frame_type", item).Msg("Ignoring backup frame") + return nil + } } func (cli *Client) deriveTransferKeys() (aesKey, hmacKey [32]byte, err error) { diff --git a/pkg/signalmeow/groups.go b/pkg/signalmeow/groups.go index 9031194..7037b9c 100644 --- a/pkg/signalmeow/groups.go +++ b/pkg/signalmeow/groups.go @@ -469,18 +469,9 @@ func InviteLinkPasswordFromBytes(inviteLinkPassword []byte) types.SerializedInvi } func groupIdentifierFromMasterKey(masterKey types.SerializedGroupMasterKey) (types.GroupIdentifier, error) { - groupSecretParams, err := libsignalgo.DeriveGroupSecretParamsFromMasterKey(masterKeyToBytes(masterKey)) + groupIdentifier, err := masterKeyToBytes(masterKey).GroupIdentifier() if err != nil { - return "", fmt.Errorf("DeriveGroupSecretParamsFromMasterKey error: %w", err) - } - // Get the "group identifier" that isn't just the master key - groupPublicParams, err := groupSecretParams.GetPublicParams() - if err != nil { - return "", fmt.Errorf("GetPublicParams error: %w", err) - } - groupIdentifier, err := libsignalgo.GetGroupIdentifier(*groupPublicParams) - if err != nil { - return "", fmt.Errorf("GetGroupIdentifier error: %w", err) + return "", err } base64GroupIdentifier := base64.StdEncoding.EncodeToString(groupIdentifier[:]) gid := types.GroupIdentifier(base64GroupIdentifier) diff --git a/pkg/signalmeow/store/backup_store.go b/pkg/signalmeow/store/backup_store.go new file mode 100644 index 0000000..823fe54 --- /dev/null +++ b/pkg/signalmeow/store/backup_store.go @@ -0,0 +1,331 @@ +// mautrix-signal - A Matrix-signal puppeting bridge. +// Copyright (C) 2025 Tulir Asokan +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +package store + +import ( + "context" + "database/sql" + "encoding/base64" + "errors" + "fmt" + "strings" + "time" + + "github.com/google/uuid" + "github.com/rs/zerolog" + "go.mau.fi/util/dbutil" + "go.mau.fi/util/ptr" + "google.golang.org/protobuf/proto" + + "go.mau.fi/mautrix-signal/pkg/libsignalgo" + "go.mau.fi/mautrix-signal/pkg/signalmeow/protobuf/backuppb" + "go.mau.fi/mautrix-signal/pkg/signalmeow/types" +) + +type BackupChat struct { + *backuppb.Chat + TotalMessages int + LatestMessageID uint64 +} + +type BackupStore interface { + AddBackupRecipient(ctx context.Context, recipient *backuppb.Recipient) error + AddBackupChat(ctx context.Context, chat *backuppb.Chat) error + AddBackupChatItem(ctx context.Context, item *backuppb.ChatItem) error + RecalculateChatCounts(ctx context.Context) error + ClearBackup(ctx context.Context) error + + GetBackupRecipient(ctx context.Context, recipientID uint64) (*backuppb.Recipient, error) + GetBackupChatByUserID(ctx context.Context, userID libsignalgo.ServiceID) (*BackupChat, error) + GetBackupChatByGroupID(ctx context.Context, groupID types.GroupIdentifier) (*BackupChat, error) + GetBackupChats(ctx context.Context) ([]*BackupChat, error) + GetBackupChatItems(ctx context.Context, chatID uint64, anchor time.Time, forward bool, limit int) ([]*backuppb.ChatItem, error) + DeleteBackupChat(ctx context.Context, chatID uint64) error + DeleteBackupChatItems(ctx context.Context, chatID uint64, minTime time.Time) error +} + +var _ BackupStore = (*sqlStore)(nil) + +const ( + addBackupRecipientQuery = ` + INSERT INTO signalmeow_backup_recipient (account_id, recipient_id, aci_uuid, pni_uuid, group_master_key, data) + VALUES ($1, $2, $3, $4, $5, $6) + ` + addBackupChatQuery = ` + INSERT INTO signalmeow_backup_chat (account_id, chat_id, recipient_id, data) + VALUES ($1, $2, $3, $4) + ` + addBackupChatItemQuery = ` + INSERT INTO signalmeow_backup_message (account_id, chat_id, sender_id, message_id, data) + VALUES ($1, $2, $3, $4, $5) + ON CONFLICT DO NOTHING + ` + + getBackupRecipientQuery = ` + SELECT data FROM signalmeow_backup_recipient WHERE account_id=$1 AND recipient_id=$2 + ` + getBackupChatByACIQuery = ` + SELECT chat.data, chat.latest_message_id, chat.total_message_count FROM signalmeow_backup_recipient rcp + INNER JOIN signalmeow_backup_chat chat ON rcp.account_id=chat.account_id AND rcp.recipient_id=chat.recipient_id + WHERE rcp.account_id=$1 AND rcp.aci_uuid=$2 + ` + getBackupChatByPNIQuery = ` + SELECT chat.data, chat.latest_message_id, chat.total_message_count FROM signalmeow_backup_recipient rcp + INNER JOIN signalmeow_backup_chat chat ON rcp.account_id=chat.account_id AND rcp.recipient_id=chat.recipient_id + WHERE rcp.account_id=$1 AND rcp.pni_uuid=$2 + ` + getBackupChatByGroupIDQuery = ` + SELECT chat.data, chat.latest_message_id, chat.total_message_count FROM signalmeow_groups g + INNER JOIN signalmeow_backup_recipient rcp ON g.account_id=rcp.account_id AND g.master_key=rcp.group_master_key + INNER JOIN signalmeow_backup_chat chat ON rcp.account_id=chat.account_id AND rcp.recipient_id=chat.recipient_id + WHERE g.account_id=$1 AND g.group_identifier=$2 + ` + getAllBackupChatsQuery = ` + SELECT data, latest_message_id, total_message_count + FROM signalmeow_backup_chat + WHERE account_id=$1 + ` + getBackupChatItemsQuery = ` + SELECT data + FROM signalmeow_backup_message + WHERE account_id=$1 AND chat_id=$2 AND message_id > $3 AND message_id < $4 + ORDER BY message_id DESC + LIMIT $5 + ` + deleteBackupChatQuery = ` + DELETE FROM signalmeow_backup_chat WHERE account_id=$1 AND chat_id=$2 + ` + deleteBackupChatItemsQuery = ` + DELETE FROM signalmeow_backup_message WHERE account_id=$1 AND chat_id=$2 AND message_id >= $3 + ` + recalculateChatCountsQuery = ` + UPDATE signalmeow_backup_chat + SET latest_message_id = ( + SELECT message_id + FROM signalmeow_backup_message + WHERE account_id=signalmeow_backup_chat.account_id AND chat_id=signalmeow_backup_chat.chat_id + ORDER BY message_id DESC + LIMIT 1 + ), + total_message_count = ( + SELECT COUNT(*) + FROM signalmeow_backup_message + WHERE account_id=signalmeow_backup_chat.account_id AND chat_id=signalmeow_backup_chat.chat_id + ) + WHERE account_id=$1 + ` +) + +func tryCastUUID(b []byte) uuid.UUID { + if len(b) == 16 { + return uuid.UUID(b) + } + return uuid.Nil +} + +func (s *sqlStore) AddBackupRecipient(ctx context.Context, recipient *backuppb.Recipient) error { + recipientData, err := proto.Marshal(recipient) + if err != nil { + return fmt.Errorf("failed to marshal recipient %d: %w", recipient.Id, err) + } + var aci, pni uuid.UUID + var groupMasterKey types.SerializedGroupMasterKey + switch dest := recipient.Destination.(type) { + case *backuppb.Recipient_Contact: + aci = tryCastUUID(dest.Contact.Aci) + pni = tryCastUUID(dest.Contact.Pni) + // TODO save identity key + trust level + if aci != uuid.Nil || pni != uuid.Nil { + _, err := s.LoadAndUpdateRecipient(ctx, aci, pni, func(recipient *types.Recipient) (changed bool, err error) { + oldRecipient := ptr.Clone(recipient) + if dest.Contact.E164 != nil { + recipient.E164 = fmt.Sprintf("+%d", *dest.Contact.E164) + } + if len(dest.Contact.ProfileKey) == libsignalgo.ProfileKeyLength { + recipient.Profile.Key = libsignalgo.ProfileKey(dest.Contact.ProfileKey) + } + if dest.Contact.ProfileGivenName != nil || dest.Contact.ProfileFamilyName != nil { + recipient.Profile.Name = strings.TrimSpace(fmt.Sprintf("%s %s", dest.Contact.GetProfileGivenName(), dest.Contact.GetProfileFamilyName())) + } + changed = oldRecipient.E164 != recipient.E164 || + oldRecipient.Profile.Key != recipient.Profile.Key || + oldRecipient.Profile.Name != recipient.Profile.Name + return + }) + if err != nil { + return fmt.Errorf("failed to save info for recipient %d: %w", recipient.Id, err) + } + } else if dest.Contact.GetRegistered() != nil { + zerolog.Ctx(ctx).Warn(). + Uint64("recipient_id", recipient.Id). + Any("entry", dest.Contact). + Msg("Both ACI and PNI are invalid for registered contact recipient") + } + case *backuppb.Recipient_Group: + groupMasterKey = types.SerializedGroupMasterKey(base64.StdEncoding.EncodeToString(dest.Group.MasterKey)) + if len(dest.Group.MasterKey) == libsignalgo.GroupMasterKeyLength { + gid, err := libsignalgo.GroupMasterKey(dest.Group.MasterKey).GroupIdentifier() + if err != nil { + zerolog.Ctx(ctx).Err(err). + Uint64("recipient_id", recipient.Id). + Msg("Failed to get group identifier from master key") + } else if err = s.StoreMasterKey(ctx, types.GroupIdentifier(base64.StdEncoding.EncodeToString(gid[:])), groupMasterKey); err != nil { + return fmt.Errorf("failed to save group master key for recipient %d: %w", recipient.Id, err) + } + } else { + zerolog.Ctx(ctx).Warn(). + Uint64("recipient_id", recipient.Id). + Msg("Invalid group master key length") + } + case *backuppb.Recipient_Self: + aci = s.AccountID + default: + } + _, err = s.db.Exec(ctx, addBackupRecipientQuery, s.AccountID, recipient.Id, ptr.NonZero(aci), ptr.NonZero(pni), ptr.NonZero(groupMasterKey), recipientData) + if err != nil { + return fmt.Errorf("failed to add backup recipient %d: %w", recipient.Id, err) + } + return nil +} + +func (s *sqlStore) AddBackupChat(ctx context.Context, chat *backuppb.Chat) error { + chatData, err := proto.Marshal(chat) + if err != nil { + return fmt.Errorf("failed to marshal chat %d: %w", chat.Id, err) + } + _, err = s.db.Exec(ctx, addBackupChatQuery, s.AccountID, chat.Id, chat.RecipientId, chatData) + if err != nil { + return fmt.Errorf("failed to add backup chat %d: %w", chat.Id, err) + } + return nil +} + +func (s *sqlStore) AddBackupChatItem(ctx context.Context, item *backuppb.ChatItem) error { + itemData, err := proto.Marshal(item) + if err != nil { + return fmt.Errorf("failed to marshal chat item %d: %w", item.DateSent, err) + } + _, err = s.db.Exec(ctx, addBackupChatItemQuery, s.AccountID, item.ChatId, item.AuthorId, item.DateSent, itemData) + if err != nil { + return fmt.Errorf("failed to add backup chat item %d: %w", item.DateSent, err) + } + return nil +} + +func (s *sqlStore) ClearBackup(ctx context.Context) error { + _, err := s.db.Exec(ctx, "DELETE FROM signalmeow_backup_message WHERE account_id=$1", s.AccountID) + if err != nil { + return err + } + _, err = s.db.Exec(ctx, "DELETE FROM signalmeow_backup_chat WHERE account_id=$1", s.AccountID) + if err != nil { + return err + } + _, err = s.db.Exec(ctx, "DELETE FROM signalmeow_backup_recipient WHERE account_id=$1", s.AccountID) + return err +} + +func scanProto[T proto.Message](row dbutil.Scannable) (val T, err error) { + var data []byte + err = row.Scan(&data) + if err != nil { + if errors.Is(err, sql.ErrNoRows) { + err = nil + } + return + } + val = val.ProtoReflect().New().Interface().(T) + err = proto.Unmarshal(data, val) + return +} + +func scanChat(row dbutil.Scannable) (*BackupChat, error) { + var data []byte + var latestMessageID, totalMessageCount sql.NullInt64 + err := row.Scan(&data, &latestMessageID, &totalMessageCount) + if err != nil { + if errors.Is(err, sql.ErrNoRows) { + return nil, nil + } + return nil, err + } + var chat backuppb.Chat + err = proto.Unmarshal(data, &chat) + if err != nil { + return nil, err + } + return &BackupChat{ + Chat: &chat, + TotalMessages: int(totalMessageCount.Int64), + LatestMessageID: uint64(totalMessageCount.Int64), + }, nil +} + +var chatScanner = dbutil.ConvertRowFn[*BackupChat](scanChat) +var messageScanner = dbutil.ConvertRowFn[*backuppb.ChatItem](scanProto[*backuppb.ChatItem]) + +func (s *sqlStore) GetBackupRecipient(ctx context.Context, recipientID uint64) (*backuppb.Recipient, error) { + return scanProto[*backuppb.Recipient](s.db.QueryRow(ctx, getBackupRecipientQuery, s.AccountID, recipientID)) +} + +func (s *sqlStore) GetBackupChatByUserID(ctx context.Context, userID libsignalgo.ServiceID) (*BackupChat, error) { + query := getBackupChatByACIQuery + if userID.Type == libsignalgo.ServiceIDTypePNI { + query = getBackupChatByPNIQuery + } + return scanChat(s.db.QueryRow(ctx, query, s.AccountID, userID.UUID)) +} + +func (s *sqlStore) GetBackupChatByGroupID(ctx context.Context, groupID types.GroupIdentifier) (*BackupChat, error) { + return scanChat(s.db.QueryRow(ctx, getBackupChatByGroupIDQuery, s.AccountID, groupID)) +} + +func (s *sqlStore) GetBackupChats(ctx context.Context) ([]*BackupChat, error) { + return chatScanner.NewRowIter(s.db.Query(ctx, getAllBackupChatsQuery, s.AccountID)).AsList() +} + +func (s *sqlStore) GetBackupChatItems(ctx context.Context, chatID uint64, anchor time.Time, forward bool, limit int) ([]*backuppb.ChatItem, error) { + var minTS, maxTS int64 + if anchor.IsZero() { + maxTS = time.Now().Add(24 * time.Hour).UnixMilli() + } else if forward { + minTS = anchor.UnixMilli() + maxTS = time.Now().Add(24 * time.Hour).UnixMilli() + } else { + maxTS = anchor.UnixMilli() + } + return messageScanner.NewRowIter(s.db.Query(ctx, getBackupChatItemsQuery, s.AccountID, chatID, minTS, maxTS, limit)).AsList() +} + +func (s *sqlStore) DeleteBackupChatItems(ctx context.Context, chatID uint64, minTime time.Time) error { + anchorTS := minTime.UnixMilli() + if minTime.IsZero() { + anchorTS = 0 + } + _, err := s.db.Exec(ctx, deleteBackupChatItemsQuery, s.AccountID, chatID, anchorTS) + return err +} + +func (s *sqlStore) DeleteBackupChat(ctx context.Context, chatID uint64) error { + _, err := s.db.Exec(ctx, deleteBackupChatQuery, s.AccountID, chatID) + return err +} + +func (s *sqlStore) RecalculateChatCounts(ctx context.Context) error { + _, err := s.db.Exec(ctx, recalculateChatCountsQuery, s.AccountID) + return err +} diff --git a/pkg/signalmeow/store/container.go b/pkg/signalmeow/store/container.go index 7437ac5..0839689 100644 --- a/pkg/signalmeow/store/container.go +++ b/pkg/signalmeow/store/container.go @@ -107,6 +107,10 @@ func (c *Container) scanDevice(row dbutil.Scannable) (*Device, error) { device.GroupStore = baseStore device.RecipientStore = baseStore device.DeviceStore = baseStore + device.BackupStore = baseStore + device.DoTxn = func(ctx context.Context, fn func(context.Context) error) error { + return c.db.DoTxn(ctx, nil, fn) + } return &device, nil } diff --git a/pkg/signalmeow/store/device.go b/pkg/signalmeow/store/device.go index 262f868..bcd4a88 100644 --- a/pkg/signalmeow/store/device.go +++ b/pkg/signalmeow/store/device.go @@ -77,6 +77,9 @@ type Device struct { GroupStore GroupStore RecipientStore RecipientStore DeviceStore DeviceStore + BackupStore BackupStore + + DoTxn func(context.Context, func(context.Context) error) error } func (d *Device) ClearDeviceKeys(ctx context.Context) error { diff --git a/pkg/signalmeow/store/upgrades/00-latest.sql b/pkg/signalmeow/store/upgrades/00-latest.sql index 05dd524..f4839d1 100644 --- a/pkg/signalmeow/store/upgrades/00-latest.sql +++ b/pkg/signalmeow/store/upgrades/00-latest.sql @@ -1,4 +1,4 @@ --- v0 -> v18 (compatible with v13+): Latest revision +-- v0 -> v19 (compatible with v13+): Latest revision CREATE TABLE signalmeow_device ( aci_uuid TEXT PRIMARY KEY, @@ -43,10 +43,10 @@ CREATE TABLE signalmeow_kyber_pre_keys ( ); CREATE TABLE signalmeow_identity_keys ( - account_id TEXT NOT NULL, - their_service_id TEXT NOT NULL, - key bytea NOT NULL, - trust_level TEXT NOT NULL, + account_id TEXT NOT NULL, + their_service_id TEXT NOT NULL, + key bytea NOT NULL, + trust_level TEXT NOT NULL, PRIMARY KEY (account_id, their_service_id), FOREIGN KEY (account_id) REFERENCES signalmeow_device (aci_uuid) ON DELETE CASCADE ON UPDATE CASCADE @@ -84,7 +84,7 @@ CREATE TABLE signalmeow_sender_keys ( ); CREATE TABLE signalmeow_groups ( - account_id TEXT NOT NULL, + account_id TEXT NOT NULL, group_identifier TEXT NOT NULL, master_key TEXT NOT NULL, @@ -92,17 +92,17 @@ CREATE TABLE signalmeow_groups ( ); CREATE TABLE signalmeow_recipients ( - account_id TEXT NOT NULL, + account_id TEXT NOT NULL, aci_uuid TEXT, pni_uuid TEXT, - e164_number TEXT NOT NULL DEFAULT '', - contact_name TEXT NOT NULL DEFAULT '', - contact_avatar_hash TEXT NOT NULL DEFAULT '', + e164_number TEXT NOT NULL DEFAULT '', + contact_name TEXT NOT NULL DEFAULT '', + contact_avatar_hash TEXT NOT NULL DEFAULT '', profile_key bytea, - profile_name TEXT NOT NULL DEFAULT '', - profile_about TEXT NOT NULL DEFAULT '', - profile_about_emoji TEXT NOT NULL DEFAULT '', - profile_avatar_path TEXT NOT NULL DEFAULT '', + profile_name TEXT NOT NULL DEFAULT '', + profile_about TEXT NOT NULL DEFAULT '', + profile_about_emoji TEXT NOT NULL DEFAULT '', + profile_avatar_path TEXT NOT NULL DEFAULT '', profile_fetched_at BIGINT, needs_pni_signature BOOLEAN NOT NULL DEFAULT false, @@ -111,3 +111,52 @@ CREATE TABLE signalmeow_recipients ( CONSTRAINT signalmeow_contacts_aci_unique UNIQUE (account_id, aci_uuid), CONSTRAINT signalmeow_contacts_pni_unique UNIQUE (account_id, pni_uuid) ); + +CREATE TABLE signalmeow_backup_recipient ( + account_id TEXT NOT NULL, + recipient_id BIGINT NOT NULL, + + aci_uuid TEXT, + pni_uuid TEXT, + + group_master_key TEXT, + + data bytea NOT NULL, + + PRIMARY KEY (account_id, recipient_id), + CONSTRAINT signalmeow_backup_recipient_device_fkey FOREIGN KEY (account_id) + REFERENCES signalmeow_device (aci_uuid) ON DELETE CASCADE ON UPDATE CASCADE +); +CREATE INDEX signalmeow_backup_recipient_group_idx ON signalmeow_backup_recipient (account_id, group_master_key); +CREATE INDEX signalmeow_backup_recipient_aci_idx ON signalmeow_backup_recipient (account_id, aci_uuid); + +CREATE TABLE signalmeow_backup_chat ( + account_id TEXT NOT NULL, + chat_id BIGINT NOT NULL, + recipient_id BIGINT NOT NULL, + data bytea NOT NULL, + + PRIMARY KEY (account_id, chat_id), + CONSTRAINT signalmeow_backup_chat_device_fkey FOREIGN KEY (account_id) + REFERENCES signalmeow_device (aci_uuid) ON DELETE CASCADE ON UPDATE CASCADE, + CONSTRAINT signalmeow_backup_chat_recipient_fkey FOREIGN KEY (account_id, recipient_id) + REFERENCES signalmeow_backup_recipient (account_id, recipient_id) ON DELETE CASCADE ON UPDATE CASCADE +); +CREATE INDEX signalmeow_backup_chat_recipient_id_idx ON signalmeow_backup_chat (account_id, recipient_id); + +CREATE TABLE signalmeow_backup_message ( + account_id TEXT NOT NULL, + chat_id BIGINT NOT NULL, + sender_id BIGINT NOT NULL, + message_id BIGINT NOT NULL, + data bytea NOT NULL, + + PRIMARY KEY (account_id, sender_id, message_id), + CONSTRAINT signalmeow_backup_message_chat_fkey FOREIGN KEY (account_id, chat_id) + REFERENCES signalmeow_backup_chat (account_id, chat_id) ON DELETE CASCADE ON UPDATE CASCADE, + CONSTRAINT signalmeow_backup_message_sender_fkey FOREIGN KEY (account_id, sender_id) + REFERENCES signalmeow_backup_recipient (account_id, recipient_id) ON DELETE CASCADE ON UPDATE CASCADE, + CONSTRAINT signalmeow_backup_message_device_fkey FOREIGN KEY (account_id) + REFERENCES signalmeow_device (aci_uuid) ON DELETE CASCADE ON UPDATE CASCADE +); +CREATE INDEX signalmeow_backup_chat_recipient_id_idx ON signalmeow_backup_chat (account_id, chat_id); diff --git a/pkg/signalmeow/store/upgrades/19-store-backup-data.sql b/pkg/signalmeow/store/upgrades/19-store-backup-data.sql new file mode 100644 index 0000000..9189337 --- /dev/null +++ b/pkg/signalmeow/store/upgrades/19-store-backup-data.sql @@ -0,0 +1,52 @@ +-- v19 (compatible with v13+): Add tables for caching parsed backup data +CREATE TABLE signalmeow_backup_recipient ( + account_id TEXT NOT NULL, + recipient_id BIGINT NOT NULL, + + aci_uuid TEXT, + pni_uuid TEXT, + + group_master_key TEXT, + + data bytea NOT NULL, + + PRIMARY KEY (account_id, recipient_id), + CONSTRAINT signalmeow_backup_recipient_device_fkey FOREIGN KEY (account_id) + REFERENCES signalmeow_device (aci_uuid) ON DELETE CASCADE ON UPDATE CASCADE +); +CREATE INDEX signalmeow_backup_recipient_group_idx ON signalmeow_backup_recipient (account_id, group_master_key); +CREATE INDEX signalmeow_backup_recipient_aci_idx ON signalmeow_backup_recipient (account_id, aci_uuid); + +CREATE TABLE signalmeow_backup_chat ( + account_id TEXT NOT NULL, + chat_id BIGINT NOT NULL, + recipient_id BIGINT NOT NULL, + data bytea NOT NULL, + + latest_message_id BIGINT, + total_message_count INTEGER, + + PRIMARY KEY (account_id, chat_id), + CONSTRAINT signalmeow_backup_chat_device_fkey FOREIGN KEY (account_id) + REFERENCES signalmeow_device (aci_uuid) ON DELETE CASCADE ON UPDATE CASCADE, + CONSTRAINT signalmeow_backup_chat_recipient_fkey FOREIGN KEY (account_id, recipient_id) + REFERENCES signalmeow_backup_recipient (account_id, recipient_id) ON DELETE CASCADE ON UPDATE CASCADE +); +CREATE INDEX signalmeow_backup_chat_recipient_id_idx ON signalmeow_backup_chat (account_id, recipient_id); + +CREATE TABLE signalmeow_backup_message ( + account_id TEXT NOT NULL, + chat_id BIGINT NOT NULL, + sender_id BIGINT NOT NULL, + message_id BIGINT NOT NULL, + data bytea NOT NULL, + + PRIMARY KEY (account_id, sender_id, message_id), + CONSTRAINT signalmeow_backup_message_chat_fkey FOREIGN KEY (account_id, chat_id) + REFERENCES signalmeow_backup_chat (account_id, chat_id) ON DELETE CASCADE ON UPDATE CASCADE, + CONSTRAINT signalmeow_backup_message_sender_fkey FOREIGN KEY (account_id, sender_id) + REFERENCES signalmeow_backup_recipient (account_id, recipient_id) ON DELETE CASCADE ON UPDATE CASCADE, + CONSTRAINT signalmeow_backup_message_device_fkey FOREIGN KEY (account_id) + REFERENCES signalmeow_device (aci_uuid) ON DELETE CASCADE ON UPDATE CASCADE +); +CREATE INDEX signalmeow_backup_chat_recipient_id_idx ON signalmeow_backup_chat (account_id, chat_id); From dd0f10ab7095f8f6cb10c75fe1bf6fbeebedabf2 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Sun, 19 Jan 2025 13:26:23 +0200 Subject: [PATCH 263/580] connector: implement chat list sync and backfill Fixes #1 --- pkg/connector/backfill.go | 192 ++++++++++++++++++++++++++++++++++ pkg/connector/chatinfo.go | 22 ++-- pkg/connector/chatsync.go | 157 +++++++++++++++++++++++++++ pkg/connector/client.go | 11 ++ pkg/connector/dbmeta.go | 6 +- pkg/connector/groupinfo.go | 13 ++- pkg/connector/login.go | 19 +++- pkg/msgconv/from-signal.go | 31 +++++- pkg/signalid/dbmeta.go | 4 + pkg/signalmeow/attachments.go | 4 + 10 files changed, 440 insertions(+), 19 deletions(-) create mode 100644 pkg/connector/backfill.go create mode 100644 pkg/connector/chatsync.go diff --git a/pkg/connector/backfill.go b/pkg/connector/backfill.go new file mode 100644 index 0000000..c0416b1 --- /dev/null +++ b/pkg/connector/backfill.go @@ -0,0 +1,192 @@ +// mautrix-signal - A Matrix-Signal puppeting bridge. +// Copyright (C) 2025 Tulir Asokan +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +package connector + +import ( + "context" + "fmt" + "slices" + "time" + + "github.com/google/uuid" + "github.com/rs/zerolog" + "go.mau.fi/util/ptr" + "maunium.net/go/mautrix/bridgev2" + "maunium.net/go/mautrix/bridgev2/networkid" + + "go.mau.fi/mautrix-signal/pkg/msgconv" + "go.mau.fi/mautrix-signal/pkg/signalid" + "go.mau.fi/mautrix-signal/pkg/signalmeow/protobuf/backuppb" + "go.mau.fi/mautrix-signal/pkg/signalmeow/store" +) + +var _ bridgev2.BackfillingNetworkAPI = (*SignalClient)(nil) + +func tryCastUUID(b []byte) uuid.UUID { + if len(b) == 16 { + return uuid.UUID(b) + } + return uuid.Nil +} + +func (s *SignalClient) FetchMessages(ctx context.Context, params bridgev2.FetchMessagesParams) (*bridgev2.FetchMessagesResponse, error) { + if !s.IsLoggedIn() { + return nil, bridgev2.ErrNotLoggedIn + } + userID, groupID, err := signalid.ParsePortalID(params.Portal.ID) + if err != nil { + return nil, fmt.Errorf("failed to parse portal ID: %w", err) + } + var chat *store.BackupChat + if groupID != "" { + chat, err = s.Client.Store.BackupStore.GetBackupChatByGroupID(ctx, groupID) + } else { + chat, err = s.Client.Store.BackupStore.GetBackupChatByUserID(ctx, userID) + } + if err != nil { + return nil, fmt.Errorf("failed to get chat: %w", err) + } else if chat == nil { + zerolog.Ctx(ctx).Debug().Msg("Chat not found, returning nil response for backfill") + return nil, nil + } + var anchorTS time.Time + if params.AnchorMessage != nil { + anchorTS = params.AnchorMessage.Timestamp + } + minTS := anchorTS + items, err := s.Client.Store.BackupStore.GetBackupChatItems(ctx, chat.Id, anchorTS, params.Forward, params.Count) + if err != nil { + return nil, fmt.Errorf("failed to get chat items: %w", err) + } + if len(items) > 0 { + minTS = time.UnixMilli(int64(items[0].DateSent)) + } + // GetBackupChatItems returns in reverse chronological order, so flip the list + slices.Reverse(items) + var firstDirectionfulProcessed bool + var isRead bool + convertedMessages := make([]*bridgev2.BackfillMessage, 0, len(items)) + attMap := make(msgconv.AttachmentMap) + recipientMap := make(map[uint64]*backuppb.Recipient) + getRecipientACI := func(id uint64) (uuid.UUID, error) { + recipient, ok := recipientMap[id] + if !ok { + recipient, err = s.Client.Store.BackupStore.GetBackupRecipient(ctx, id) + if err != nil { + return uuid.Nil, fmt.Errorf("failed to get recipient %d: %w", id, err) + } else if len(recipient.GetContact().GetAci()) != 16 && recipient.GetSelf() == nil { + zerolog.Ctx(ctx).Warn(). + Uint64("recipient_id", id). + Type("recipient_type", recipient.GetDestination()). + Msg("ACI not found for recipient") + } + recipientMap[id] = recipient + } + + switch dest := recipient.Destination.(type) { + case *backuppb.Recipient_Self: + return s.Client.Store.ACI, nil + case *backuppb.Recipient_Contact: + if len(dest.Contact.GetAci()) == 16 { + return uuid.UUID(dest.Contact.GetAci()), nil + } + } + return uuid.Nil, nil + } + for _, item := range items { + var streamOrder int64 + switch dt := item.DirectionalDetails.(type) { + case *backuppb.ChatItem_Incoming: + streamOrder = int64(dt.Incoming.GetDateServerSent()) + if !firstDirectionfulProcessed { + firstDirectionfulProcessed = true + isRead = dt.Incoming.Read + } + case *backuppb.ChatItem_Outgoing: + // TODO stream order? + if !firstDirectionfulProcessed { + firstDirectionfulProcessed = true + isRead = true + } + } + if len(attMap) > 0 { + clear(attMap) + } + senderACI, err := getRecipientACI(item.AuthorId) + if err != nil { + return nil, err + } else if senderACI == uuid.Nil { + continue + } + dm, reactions := msgconv.BackupToDataMessage(item, attMap) + if dm == nil { + continue + } + cm := s.Main.MsgConv.ToMatrix(ctx, s.Client, params.Portal, s.Main.Bridge.Bot, dm, attMap) + convertedReactions := make([]*bridgev2.BackfillReaction, 0, len(reactions)) + for _, reaction := range reactions { + reactionSenderACI, err := getRecipientACI(reaction.AuthorId) + if err != nil { + return nil, err + } else if reactionSenderACI == uuid.Nil { + continue + } + convertedReactions = append(convertedReactions, &bridgev2.BackfillReaction{ + TargetPart: ptr.Ptr(networkid.PartID("")), + Timestamp: time.UnixMilli(int64(reaction.SentTimestamp)), + Sender: s.makeEventSender(reactionSenderACI), + Emoji: reaction.GetEmoji(), + }) + } + msgID := signalid.MakeMessageID(senderACI, item.DateSent) + convertedMessages = append(convertedMessages, &bridgev2.BackfillMessage{ + ConvertedMessage: cm, + Sender: s.makeEventSender(senderACI), + ID: msgID, + TxnID: networkid.TransactionID(msgID), + Timestamp: time.UnixMilli(int64(item.DateSent)), + StreamOrder: streamOrder, + Reactions: convertedReactions, + }) + } + return &bridgev2.FetchMessagesResponse{ + Messages: convertedMessages, + HasMore: len(items) >= params.Count, + Forward: params.Forward, + MarkRead: isRead, + ApproxTotalCount: chat.TotalMessages, + CompleteCallback: func() { + // When reaching the last backwards backfill batch, delete the chat from the backup store. + // If backwards backfilling isn't enabled, delete immediately after the first backfill request. + if (!params.Forward && len(items) < params.Count) || !s.Main.Bridge.Config.Backfill.Queue.Enabled { + err := s.Client.Store.BackupStore.DeleteBackupChat(ctx, chat.Id) + if err != nil { + zerolog.Ctx(ctx).Err(err).Msg("Failed to delete chat from backup store") + } else { + zerolog.Ctx(ctx).Debug().Msg("Deleted chat from backup store as backfill seems finished") + } + } else { + err := s.Client.Store.BackupStore.DeleteBackupChatItems(ctx, chat.Id, minTS) + if err != nil { + zerolog.Ctx(ctx).Err(err).Time("min_ts", minTS).Msg("Failed to delete messages from backup store") + } else { + zerolog.Ctx(ctx).Debug().Time("min_ts", minTS).Msg("Deleted messages from backup store") + } + } + }, + }, nil +} diff --git a/pkg/connector/chatinfo.go b/pkg/connector/chatinfo.go index e3eef59..c73b5d5 100644 --- a/pkg/connector/chatinfo.go +++ b/pkg/connector/chatinfo.go @@ -34,6 +34,7 @@ import ( "go.mau.fi/mautrix-signal/pkg/libsignalgo" "go.mau.fi/mautrix-signal/pkg/signalid" + "go.mau.fi/mautrix-signal/pkg/signalmeow/store" "go.mau.fi/mautrix-signal/pkg/signalmeow/types" ) @@ -62,14 +63,14 @@ func (s *SignalClient) GetChatInfo(ctx context.Context, portal *bridgev2.Portal) return nil, err } if groupID != "" { - return s.getGroupInfo(ctx, groupID, 0) + return s.getGroupInfo(ctx, groupID, 0, nil) } else { aci, pni := userID.ToACIAndPNI() contact, err := s.Client.Store.RecipientStore.LoadAndUpdateRecipient(ctx, aci, pni, nil) if err != nil { return nil, err } - return s.makeCreateDMResponse(contact).PortalInfo, nil + return s.makeCreateDMResponse(ctx, contact, nil).PortalInfo, nil } } @@ -182,13 +183,13 @@ func (s *SignalClient) ResolveIdentifier(ctx context.Context, number string, cre UserID: signalid.MakeUserID(aci), UserInfo: s.contactToUserInfo(recipient), Ghost: ghost, - Chat: s.makeCreateDMResponse(recipient), + Chat: s.makeCreateDMResponse(ctx, recipient, nil), }, nil } else { return &bridgev2.ResolveIdentifierResponse{ UserID: signalid.MakeUserIDFromServiceID(libsignalgo.NewPNIServiceID(pni)), UserInfo: s.contactToUserInfo(recipient), - Chat: s.makeCreateDMResponse(recipient), + Chat: s.makeCreateDMResponse(ctx, recipient, nil), }, nil } } @@ -207,7 +208,7 @@ func (s *SignalClient) GetContactList(ctx context.Context) ([]*bridgev2.ResolveI for i, recipient := range recipients { recipientResp := &bridgev2.ResolveIdentifierResponse{ UserInfo: s.contactToUserInfo(recipient), - Chat: s.makeCreateDMResponse(recipient), + Chat: s.makeCreateDMResponse(ctx, recipient, nil), } if recipient.ACI != uuid.Nil { recipientResp.UserID = signalid.MakeUserID(recipient.ACI) @@ -224,7 +225,7 @@ func (s *SignalClient) GetContactList(ctx context.Context) ([]*bridgev2.ResolveI return resp, nil } -func (s *SignalClient) makeCreateDMResponse(recipient *types.Recipient) *bridgev2.CreateChatResponse { +func (s *SignalClient) makeCreateDMResponse(ctx context.Context, recipient *types.Recipient, backupChat *store.BackupChat) *bridgev2.CreateChatResponse { name := "" topic := PrivateChatTopic selfUser := s.makeEventSender(s.Client.Store.ACI) @@ -247,6 +248,13 @@ func (s *SignalClient) makeCreateDMResponse(recipient *types.Recipient) *bridgev name = s.Main.Config.FormatDisplayname(recipient) serviceID = libsignalgo.NewPNIServiceID(recipient.PNI) } else { + if backupChat == nil { + var err error + backupChat, err = s.Client.Store.BackupStore.GetBackupChatByUserID(ctx, libsignalgo.NewACIServiceID(recipient.ACI)) + if err != nil { + zerolog.Ctx(ctx).Warn().Err(err).Msg("Failed to get backup chat for recipient") + } + } members.OtherUserID = signalid.MakeUserID(recipient.ACI) if recipient.ACI == s.Client.Store.ACI { name = NoteToSelfName @@ -275,6 +283,8 @@ func (s *SignalClient) makeCreateDMResponse(recipient *types.Recipient) *bridgev Topic: &topic, Members: members, Type: ptr.Ptr(database.RoomTypeDM), + + CanBackfill: backupChat != nil, }, } } diff --git a/pkg/connector/chatsync.go b/pkg/connector/chatsync.go new file mode 100644 index 0000000..5d982e7 --- /dev/null +++ b/pkg/connector/chatsync.go @@ -0,0 +1,157 @@ +// mautrix-signal - A Matrix-Signal puppeting bridge. +// Copyright (C) 2025 Tulir Asokan +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +package connector + +import ( + "context" + "encoding/base64" + "time" + + "github.com/google/uuid" + "github.com/rs/zerolog" + "maunium.net/go/mautrix/bridgev2" + "maunium.net/go/mautrix/bridgev2/simplevent" + + "go.mau.fi/mautrix-signal/pkg/libsignalgo" + "go.mau.fi/mautrix-signal/pkg/signalid" + "go.mau.fi/mautrix-signal/pkg/signalmeow/protobuf/backuppb" + "go.mau.fi/mautrix-signal/pkg/signalmeow/types" +) + +func (s *SignalClient) syncChats(ctx context.Context) { + if s.UserLogin.Metadata.(*signalid.UserLoginMetadata).ChatsSynced { + return + } + if s.Client.Store.EphemeralBackupKey != nil { + zerolog.Ctx(ctx).Info().Msg("Fetching transfer archive before syncing chats") + meta, err := s.Client.WaitForTransfer(ctx) + if err != nil { + zerolog.Ctx(ctx).Err(err).Msg("Failed to request transfer archive") + return + } else if meta.Error != "" { + zerolog.Ctx(ctx).Error().Str("error_type", meta.Error).Msg("Transfer archive request was rejected") + s.UserLogin.Metadata.(*signalid.UserLoginMetadata).ChatsSynced = true + err = s.UserLogin.Save(ctx) + if err != nil { + zerolog.Ctx(ctx).Err(err).Msg("Failed to save user login metadata after transfer archive request was rejected") + } + return + } + err = s.Client.FetchAndProcessTransfer(ctx, meta) + if err != nil { + zerolog.Ctx(ctx).Err(err).Msg("Failed to fetch and process transfer archive") + return + } + zerolog.Ctx(ctx).Info().Msg("Transfer archive fetched and processed, syncing chats") + } + chats, err := s.Client.Store.BackupStore.GetBackupChats(ctx) + if err != nil { + zerolog.Ctx(ctx).Err(err).Msg("Failed to get chats from backup store") + return + } + zerolog.Ctx(ctx).Info().Int("chat_count", len(chats)).Msg("Fetched chats to sync from database") + for _, chat := range chats { + recipient, err := s.Client.Store.BackupStore.GetBackupRecipient(ctx, chat.RecipientId) + if err != nil { + zerolog.Ctx(ctx).Err(err).Msg("Failed to get recipient for chat") + continue + } + resyncEvt := &simplevent.ChatResync{ + EventMeta: simplevent.EventMeta{ + Type: bridgev2.RemoteEventChatResync, + LogContext: func(c zerolog.Context) zerolog.Context { + return c. + Int("message_count", chat.TotalMessages). + Uint64("backup_chat_id", chat.Id). + Uint64("backup_recipient_id", chat.RecipientId) + }, + CreatePortal: true, + }, + LatestMessageTS: time.UnixMilli(int64(chat.LatestMessageID)), + } + switch dest := recipient.Destination.(type) { + case *backuppb.Recipient_Contact: + aci := tryCastUUID(dest.Contact.GetAci()) + pni := tryCastUUID(dest.Contact.GetPni()) + if chat.TotalMessages == 0 { + zerolog.Ctx(ctx).Debug(). + Stringer("aci", aci). + Stringer("pni", pni). + Uint64("e164", dest.Contact.GetE164()). + Msg("Skipping direct chat with no messages and deleting data") + err = s.Client.Store.BackupStore.DeleteBackupChat(ctx, chat.Id) + if err != nil { + zerolog.Ctx(ctx).Err(err).Msg("Failed to delete chat from backup store") + } + continue + } + processedRecipient, err := s.Client.Store.RecipientStore.LoadAndUpdateRecipient(ctx, aci, pni, nil) + if err != nil { + zerolog.Ctx(ctx).Err(err).Msg("Failed to get full recipient data") + continue + } + dmInfo := s.makeCreateDMResponse(ctx, processedRecipient, chat) + resyncEvt.PortalKey = dmInfo.PortalKey + resyncEvt.ChatInfo = dmInfo.PortalInfo + case *backuppb.Recipient_Self: + processedRecipient, err := s.Client.Store.RecipientStore.LoadAndUpdateRecipient(ctx, s.Client.Store.ACI, uuid.Nil, nil) + if err != nil { + zerolog.Ctx(ctx).Err(err).Msg("Failed to get full recipient data") + continue + } + dmInfo := s.makeCreateDMResponse(ctx, processedRecipient, chat) + resyncEvt.PortalKey = dmInfo.PortalKey + resyncEvt.ChatInfo = dmInfo.PortalInfo + case *backuppb.Recipient_Group: + if len(dest.Group.MasterKey) != libsignalgo.GroupMasterKeyLength { + continue + } + rawGroupID, err := libsignalgo.GroupMasterKey(dest.Group.MasterKey).GroupIdentifier() + if err != nil { + zerolog.Ctx(ctx).Err(err). + Uint64("recipient_id", recipient.Id). + Msg("Failed to get group identifier from master key") + continue + } + groupID := types.GroupIdentifier(base64.StdEncoding.EncodeToString(rawGroupID[:])) + groupInfo, err := s.getGroupInfo(ctx, groupID, dest.Group.GetSnapshot().GetVersion(), chat) + if err != nil { + zerolog.Ctx(ctx).Err(err).Msg("Failed to get full group info") + continue + } + resyncEvt.PortalKey = s.makePortalKey(string(groupID)) + resyncEvt.ChatInfo = groupInfo + default: + zerolog.Ctx(ctx).Debug(). + Type("destination_type", dest). + Uint64("backup_chat_id", chat.Id). + Uint64("backup_recipient_id", chat.RecipientId). + Msg("Ignoring and deleting chat with unsupported destination type") + err = s.Client.Store.BackupStore.DeleteBackupChat(ctx, chat.Id) + if err != nil { + zerolog.Ctx(ctx).Err(err).Msg("Failed to delete chat from backup store") + } + continue + } + s.UserLogin.QueueRemoteEvent(resyncEvt) + } + s.UserLogin.Metadata.(*signalid.UserLoginMetadata).ChatsSynced = true + err = s.UserLogin.Save(ctx) + if err != nil { + zerolog.Ctx(ctx).Err(err).Msg("Failed to save user login metadata after syncing chats") + } +} diff --git a/pkg/connector/client.go b/pkg/connector/client.go index 2f2925c..ece6753 100644 --- a/pkg/connector/client.go +++ b/pkg/connector/client.go @@ -206,6 +206,16 @@ func (s *SignalClient) bridgeStateLoop(statusChan <-chan signalmeow.SignalConnec } } +func (s *SignalClient) postLoginConnect(ctx context.Context) { + // TODO it would be more proper to only connect after syncing, + // but currently syncing will fetch group info online, so it has to be connected. + s.Connect(ctx) + s.syncChats(ctx) + if s.Client.Store.MasterKey != nil { + s.Client.SyncStorage(ctx) + } +} + func (s *SignalClient) Connect(ctx context.Context) { if s.Client == nil { s.UserLogin.BridgeState.Send(status.BridgeState{StateEvent: status.StateBadCredentials, Message: "You're not logged into Signal"}) @@ -283,6 +293,7 @@ func (s *SignalClient) tryConnect(ctx context.Context, retryCount int) { } } else { go s.bridgeStateLoop(ch) + go s.syncChats(ctx) } } diff --git a/pkg/connector/dbmeta.go b/pkg/connector/dbmeta.go index 4ee3b08..d8f644e 100644 --- a/pkg/connector/dbmeta.go +++ b/pkg/connector/dbmeta.go @@ -33,7 +33,9 @@ func (s *SignalConnector) GetDBMetaTypes() database.MetaTypes { Message: func() any { return &signalid.MessageMetadata{} }, - Reaction: nil, - UserLogin: nil, + Reaction: nil, + UserLogin: func() any { + return &signalid.UserLoginMetadata{} + }, } } diff --git a/pkg/connector/groupinfo.go b/pkg/connector/groupinfo.go index e5c1fc5..0cb3ce5 100644 --- a/pkg/connector/groupinfo.go +++ b/pkg/connector/groupinfo.go @@ -31,6 +31,7 @@ import ( "go.mau.fi/mautrix-signal/pkg/libsignalgo" "go.mau.fi/mautrix-signal/pkg/signalid" "go.mau.fi/mautrix-signal/pkg/signalmeow" + "go.mau.fi/mautrix-signal/pkg/signalmeow/store" "go.mau.fi/mautrix-signal/pkg/signalmeow/types" ) @@ -93,7 +94,7 @@ func inviteLinkToJoinRule(inviteLinkAccess signalmeow.AccessControl) event.JoinR } } -func (s *SignalClient) getGroupInfo(ctx context.Context, groupID types.GroupIdentifier, minRevision uint32) (*bridgev2.ChatInfo, error) { +func (s *SignalClient) getGroupInfo(ctx context.Context, groupID types.GroupIdentifier, minRevision uint32, backupChat *store.BackupChat) (*bridgev2.ChatInfo, error) { groupInfo, err := s.Client.RetrieveGroupByID(ctx, groupID, minRevision) if err != nil { return nil, err @@ -152,6 +153,13 @@ func (s *SignalClient) getGroupInfo(ctx context.Context, groupID types.GroupIden Membership: event.MembershipBan, } } + if backupChat == nil { + // TODO allow using backup chat for data too instead of asking server? + backupChat, err = s.Client.Store.BackupStore.GetBackupChatByGroupID(ctx, groupID) + if err != nil { + zerolog.Ctx(ctx).Warn().Err(err).Msg("Failed to get backup chat for group") + } + } return &bridgev2.ChatInfo{ Name: &groupInfo.Title, Topic: &groupInfo.Description, @@ -164,6 +172,7 @@ func (s *SignalClient) getGroupInfo(ctx context.Context, groupID types.GroupIden Type: ptr.Ptr(database.RoomTypeDefault), JoinRule: &event.JoinRulesEventContent{JoinRule: joinRule}, ExtraUpdates: makeRevisionUpdater(groupInfo.Revision), + CanBackfill: backupChat != nil, }, nil } @@ -366,7 +375,7 @@ func (s *SignalClient) catchUpGroup(ctx context.Context, portal *bridgev2.Portal Logger() if fromRevision == 0 { log.Info().Msg("Syncing full group info") - info, err := s.getGroupInfo(ctx, types.GroupIdentifier(portal.ID), toRevision) + info, err := s.getGroupInfo(ctx, types.GroupIdentifier(portal.ID), toRevision, nil) if err != nil { log.Err(err).Msg("Failed to get group info") } else { diff --git a/pkg/connector/login.go b/pkg/connector/login.go index e2f2e98..3b81b0a 100644 --- a/pkg/connector/login.go +++ b/pkg/connector/login.go @@ -79,7 +79,9 @@ func (qr *QRLogin) Start(ctx context.Context) (*bridgev2.LoginStep, error) { provCtx, cancel := context.WithCancel(log.WithContext(context.Background())) qr.cancelChan = cancel // Don't use the start context here: the channel will outlive the start request. - qr.ProvChan = signalmeow.PerformProvisioning(provCtx, qr.Main.Store, qr.Main.Config.DeviceName, false) + qr.ProvChan = signalmeow.PerformProvisioning( + provCtx, qr.Main.Store, qr.Main.Config.DeviceName, qr.Main.Bridge.Config.Backfill.Enabled, + ) var resp signalmeow.ProvisioningResponse select { case resp = <-qr.ProvChan: @@ -165,6 +167,7 @@ func (qr *QRLogin) processingWait(ctx context.Context) (*bridgev2.LoginStep, err RemoteProfile: status.RemoteProfile{ Phone: qr.ProvData.Number, }, + Metadata: &signalid.UserLoginMetadata{}, }, &bridgev2.NewLoginParams{ DeleteOnConflict: true, }) @@ -172,10 +175,16 @@ func (qr *QRLogin) processingWait(ctx context.Context) (*bridgev2.LoginStep, err return nil, fmt.Errorf("failed to create user login: %w", err) } backgroundCtx := ul.Log.WithContext(context.Background()) - ul.Client.Connect(backgroundCtx) - if signalClient := ul.Client.(*SignalClient).Client; signalClient.Store.MasterKey != nil { - zerolog.Ctx(ctx).Info().Msg("Received master key in login, syncing storage immediately") - go signalClient.SyncStorage(backgroundCtx) + signalClient := ul.Client.(*SignalClient).Client + if signalClient.Store.EphemeralBackupKey != nil { + zerolog.Ctx(ctx).Info().Msg("Received ephemeral backup key in login, syncing chats before connecting") + go ul.Client.(*SignalClient).postLoginConnect(backgroundCtx) + } else { + ul.Client.Connect(backgroundCtx) + if signalClient.Store.MasterKey != nil { + zerolog.Ctx(ctx).Info().Msg("Received master key in login, syncing storage immediately") + go signalClient.SyncStorage(backgroundCtx) + } } return &bridgev2.LoginStep{ Type: bridgev2.LoginStepTypeComplete, diff --git a/pkg/msgconv/from-signal.go b/pkg/msgconv/from-signal.go index 714b723..7ee29b7 100644 --- a/pkg/msgconv/from-signal.go +++ b/pkg/msgconv/from-signal.go @@ -20,6 +20,7 @@ import ( "bytes" "context" "encoding/base64" + "errors" "fmt" "net/http" "strings" @@ -41,6 +42,11 @@ import ( signalpb "go.mau.fi/mautrix-signal/pkg/signalmeow/protobuf" ) +var ( + ErrAttachmentNotInBackup = errors.New("attachment not found in backup") + ErrBackupNotSupported = errors.New("downloading attachments from server-side backup is not yet supported") +) + func calculateLength(dm *signalpb.DataMessage) int { if dm.GetFlags()&uint32(signalpb.DataMessage_EXPIRATION_TIMER_UPDATE) != 0 { return 1 @@ -384,6 +390,23 @@ func (mc *MessageConverter) convertContactToMatrix(ctx context.Context, contact func (mc *MessageConverter) convertAttachmentToMatrix(ctx context.Context, index int, att *signalpb.AttachmentPointer, attMap AttachmentMap) *bridgev2.ConvertedMessagePart { part, err := mc.reuploadAttachment(ctx, att, attMap) if err != nil { + if (errors.Is(err, signalmeow.ErrAttachmentNotFound) || errors.Is(err, ErrAttachmentNotInBackup)) && attMap != nil { + return &bridgev2.ConvertedMessagePart{ + Type: event.EventMessage, + Content: &event.MessageEventContent{ + MsgType: event.MsgNotice, + Body: fmt.Sprintf("Attachment no longer available %s", att.GetFileName()), + }, + } + } else if errors.Is(err, ErrBackupNotSupported) { + return &bridgev2.ConvertedMessagePart{ + Type: event.EventMessage, + Content: &event.MessageEventContent{ + MsgType: event.MsgNotice, + Body: "Downloading attachments from backup is not yet supported", + }, + } + } zerolog.Ctx(ctx).Err(err).Int("attachment_index", index).Msg("Failed to handle attachment") return &bridgev2.ConvertedMessagePart{ Type: event.EventMessage, @@ -434,7 +457,7 @@ func (mc *MessageConverter) convertStickerToMatrix(ctx context.Context, sticker func (mc *MessageConverter) downloadSignalLongText(ctx context.Context, att *signalpb.AttachmentPointer, attMap AttachmentMap) (*string, error) { data, err := mc.downloadAttachment(ctx, att, attMap) if err != nil { - return nil, fmt.Errorf("failed to download attachment: %w", err) + return nil, err } longBody := string(data) return &longBody, nil @@ -449,10 +472,10 @@ func (mc *MessageConverter) downloadAttachment(ctx context.Context, att *signalp if !ok { return nil, fmt.Errorf("no attachment identifier and attachment not found in map") } else if target == nil { - return nil, fmt.Errorf("attachment not available in backup") + return nil, ErrAttachmentNotInBackup } else { // TODO add support for downloading attachments from backup - return nil, fmt.Errorf("downloading attachments from backup is not yet supported") + return nil, ErrBackupNotSupported } } return signalmeow.DownloadAttachment(ctx, att) @@ -461,7 +484,7 @@ func (mc *MessageConverter) downloadAttachment(ctx context.Context, att *signalp func (mc *MessageConverter) reuploadAttachment(ctx context.Context, att *signalpb.AttachmentPointer, attMap AttachmentMap) (*bridgev2.ConvertedMessagePart, error) { data, err := mc.downloadAttachment(ctx, att, attMap) if err != nil { - return nil, fmt.Errorf("failed to download attachment: %w", err) + return nil, err } mimeType := att.GetContentType() if mimeType == "" { diff --git a/pkg/signalid/dbmeta.go b/pkg/signalid/dbmeta.go index f3811af..76ee217 100644 --- a/pkg/signalid/dbmeta.go +++ b/pkg/signalid/dbmeta.go @@ -29,6 +29,10 @@ type MessageMetadata struct { ContainsAttachments bool `json:"contains_attachments,omitempty"` } +type UserLoginMetadata struct { + ChatsSynced bool `json:"chats_synced,omitempty"` +} + type GhostMetadata struct { ProfileFetchedAt jsontime.UnixMilli `json:"profile_fetched_at"` } diff --git a/pkg/signalmeow/attachments.go b/pkg/signalmeow/attachments.go index 4d5d6d6..d733b40 100644 --- a/pkg/signalmeow/attachments.go +++ b/pkg/signalmeow/attachments.go @@ -57,6 +57,7 @@ func getAttachmentPath(id uint64, key string) string { // ErrInvalidMACForAttachment signals that the downloaded attachment has an invalid MAC. var ErrInvalidMACForAttachment = errors.New("invalid MAC for attachment") var ErrInvalidDigestForAttachment = errors.New("invalid digest for attachment") +var ErrAttachmentNotFound = errors.New("attachment not found on server") func DownloadAttachment(ctx context.Context, a *signalpb.AttachmentPointer) ([]byte, error) { path := getAttachmentPath(a.GetCdnId(), a.GetCdnKey()) @@ -77,6 +78,9 @@ func DownloadAttachment(ctx context.Context, a *signalpb.AttachmentPointer) ([]b } else if len(body) < 1024 { zerolog.Ctx(ctx).Debug().Bytes("response_data", body).Msg("Failed download response data") } + if resp.StatusCode == http.StatusNotFound { + return nil, ErrAttachmentNotFound + } return nil, fmt.Errorf("unexpected status code %d", resp.StatusCode) } From ee976eaab3ccd6cc7fbcced88e44dc4ae0196fb4 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Sun, 19 Jan 2025 14:21:55 +0200 Subject: [PATCH 264/580] signalmeow: fix caching profile fetch errors --- pkg/signalmeow/profile.go | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/pkg/signalmeow/profile.go b/pkg/signalmeow/profile.go index 440fe1b..5182c23 100644 --- a/pkg/signalmeow/profile.go +++ b/pkg/signalmeow/profile.go @@ -131,16 +131,15 @@ func (cli *Client) RetrieveProfileByID(ctx context.Context, signalID uuid.UUID) } err, ok := cli.ProfileCache.errors[signalID.String()] if ok { - return nil, *err + return nil, fmt.Errorf("%w: %w", ErrCachedError, *err) } } // If we get here, we don't have a cached profile, so fetch it profile, err := cli.fetchProfileByID(ctx, signalID) if err != nil { - // TODO this check is wrong and most likely doesn't work, errors shouldn't use string comparisons // If we get a 401 or 5xx error, we should not retry until the cache expires - if strings.HasPrefix(err.Error(), "401") || strings.HasPrefix(err.Error(), "5") { + if errors.Is(err, ErrProfileUnauthorized) || errors.Is(err, ErrProfileInternalError) { cli.ProfileCache.errors[signalID.String()] = &err cli.ProfileCache.lastFetched[signalID.String()] = time.Now() } @@ -169,6 +168,13 @@ func (cli *Client) fetchProfileByID(ctx context.Context, signalID uuid.UUID) (*t return cli.fetchProfileWithRequestAndKey(ctx, signalID, credentialRequest, profileKey) } +var ( + ErrCachedError = errors.New("cached error") + ErrProfileUnauthorized = errors.New("profile get returned 401") + ErrProfileNotFound = errors.New("profile get returned 404") + ErrProfileInternalError = errors.New("profile get returned") +) + func (cli *Client) fetchProfileWithRequestAndKey(ctx context.Context, signalID uuid.UUID, credentialRequest []byte, profileKey *libsignalgo.ProfileKey) (*types.Profile, error) { log := zerolog.Ctx(ctx) profileKeyVersion, err := profileKey.GetProfileKeyVersion(signalID) @@ -215,7 +221,14 @@ func (cli *Client) fetchProfileWithRequestAndKey(ctx context.Context, signalID u } logEvt.Msg("Got profile response") if *resp.Status < 200 || *resp.Status >= 300 { - return nil, fmt.Errorf("error getting profile (unsuccessful status code %d)", *resp.Status) + if *resp.Status == 401 { + return nil, ErrProfileUnauthorized + } else if *resp.Status == 404 { + return nil, ErrProfileNotFound + } else if *resp.Status >= 500 { + return nil, fmt.Errorf("%w %d", ErrProfileInternalError, *resp.Status) + } + return nil, fmt.Errorf("unexpected status code %d", *resp.Status) } var profileResponse ProfileResponse err = json.Unmarshal(resp.Body, &profileResponse) From 5b0df8b8930a1e3d344113ab50ece7063fa7953d Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Sun, 19 Jan 2025 14:32:44 +0200 Subject: [PATCH 265/580] signalmeow/store: fix constraint in db upgrade --- pkg/signalmeow/store/upgrades/00-latest.sql | 2 +- pkg/signalmeow/store/upgrades/19-store-backup-data.sql | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pkg/signalmeow/store/upgrades/00-latest.sql b/pkg/signalmeow/store/upgrades/00-latest.sql index f4839d1..23c3762 100644 --- a/pkg/signalmeow/store/upgrades/00-latest.sql +++ b/pkg/signalmeow/store/upgrades/00-latest.sql @@ -159,4 +159,4 @@ CREATE TABLE signalmeow_backup_message ( CONSTRAINT signalmeow_backup_message_device_fkey FOREIGN KEY (account_id) REFERENCES signalmeow_device (aci_uuid) ON DELETE CASCADE ON UPDATE CASCADE ); -CREATE INDEX signalmeow_backup_chat_recipient_id_idx ON signalmeow_backup_chat (account_id, chat_id); +CREATE INDEX signalmeow_backup_message_chat_id_idx ON signalmeow_backup_message (account_id, chat_id); diff --git a/pkg/signalmeow/store/upgrades/19-store-backup-data.sql b/pkg/signalmeow/store/upgrades/19-store-backup-data.sql index 9189337..6354ef8 100644 --- a/pkg/signalmeow/store/upgrades/19-store-backup-data.sql +++ b/pkg/signalmeow/store/upgrades/19-store-backup-data.sql @@ -49,4 +49,4 @@ CREATE TABLE signalmeow_backup_message ( CONSTRAINT signalmeow_backup_message_device_fkey FOREIGN KEY (account_id) REFERENCES signalmeow_device (aci_uuid) ON DELETE CASCADE ON UPDATE CASCADE ); -CREATE INDEX signalmeow_backup_chat_recipient_id_idx ON signalmeow_backup_chat (account_id, chat_id); +CREATE INDEX signalmeow_backup_message_chat_id_idx ON signalmeow_backup_message (account_id, chat_id); From 430b7317dbadb529890a224edb4c00b6eb24306e Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Sun, 19 Jan 2025 19:12:20 +0200 Subject: [PATCH 266/580] signalmeow/backup: sleep between requests if server is acting weird --- pkg/signalmeow/backup.go | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/pkg/signalmeow/backup.go b/pkg/signalmeow/backup.go index d69a729..64247db 100644 --- a/pkg/signalmeow/backup.go +++ b/pkg/signalmeow/backup.go @@ -270,10 +270,19 @@ func (cli *Client) WaitForTransfer(ctx context.Context) (*TransferArchiveMetadat if remainingTime < 0 { return nil, fmt.Errorf("timed out") } - resp, err := cli.tryRequestTransferArchive(ctx, min(remainingTime, 5*time.Minute)) + reqStart := time.Now() + reqTimeout := min(remainingTime, 5*time.Minute) + resp, err := cli.tryRequestTransferArchive(ctx, reqTimeout) if resp != nil || err != nil { return resp, err } + reqDuration := time.Since(reqStart) + if reqDuration < reqTimeout-10*time.Second { + // There seems to be a bug or feature when the transfer fails that causes the server to + // immediately return 204 until the user clicks "Continue" on their phone, so sleep for + // a bit to avoid sending requests too often. + time.Sleep(15 * time.Second) + } } } From bd09149e636c85df0d3642f554798633ed133953 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Sun, 19 Jan 2025 19:13:18 +0200 Subject: [PATCH 267/580] changelog: update --- CHANGELOG.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index da0850e..e833eaa 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,8 @@ +# v0.8.0 (unreleased) + +* Added support for history transfer. +* Updated libsignal to v0.65.2. + # v0.7.5 (2025-01-16) * Added support for bridging mp4 gifs in both directions. From 1e622b7bc6d6cb59d28ac89b3f8b0db254fcf685 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Sun, 19 Jan 2025 19:16:21 +0200 Subject: [PATCH 268/580] login: remove duplicate sync chats call --- pkg/connector/client.go | 10 ---------- pkg/connector/login.go | 15 ++++++--------- 2 files changed, 6 insertions(+), 19 deletions(-) diff --git a/pkg/connector/client.go b/pkg/connector/client.go index ece6753..44a1d2a 100644 --- a/pkg/connector/client.go +++ b/pkg/connector/client.go @@ -206,16 +206,6 @@ func (s *SignalClient) bridgeStateLoop(statusChan <-chan signalmeow.SignalConnec } } -func (s *SignalClient) postLoginConnect(ctx context.Context) { - // TODO it would be more proper to only connect after syncing, - // but currently syncing will fetch group info online, so it has to be connected. - s.Connect(ctx) - s.syncChats(ctx) - if s.Client.Store.MasterKey != nil { - s.Client.SyncStorage(ctx) - } -} - func (s *SignalClient) Connect(ctx context.Context) { if s.Client == nil { s.UserLogin.BridgeState.Send(status.BridgeState{StateEvent: status.StateBadCredentials, Message: "You're not logged into Signal"}) diff --git a/pkg/connector/login.go b/pkg/connector/login.go index 3b81b0a..e654971 100644 --- a/pkg/connector/login.go +++ b/pkg/connector/login.go @@ -176,15 +176,12 @@ func (qr *QRLogin) processingWait(ctx context.Context) (*bridgev2.LoginStep, err } backgroundCtx := ul.Log.WithContext(context.Background()) signalClient := ul.Client.(*SignalClient).Client - if signalClient.Store.EphemeralBackupKey != nil { - zerolog.Ctx(ctx).Info().Msg("Received ephemeral backup key in login, syncing chats before connecting") - go ul.Client.(*SignalClient).postLoginConnect(backgroundCtx) - } else { - ul.Client.Connect(backgroundCtx) - if signalClient.Store.MasterKey != nil { - zerolog.Ctx(ctx).Info().Msg("Received master key in login, syncing storage immediately") - go signalClient.SyncStorage(backgroundCtx) - } + // TODO it would be more proper to only connect after syncing, + // but currently syncing will fetch group info online, so it has to be connected. + ul.Client.Connect(backgroundCtx) + if signalClient.Store.MasterKey != nil { + zerolog.Ctx(ctx).Info().Msg("Received master key in login, syncing storage immediately") + go signalClient.SyncStorage(backgroundCtx) } return &bridgev2.LoginStep{ Type: bridgev2.LoginStepTypeComplete, From dceab3c8b340ab78c5198dc917b9007ed3d4d9f2 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Sun, 19 Jan 2025 19:18:44 +0200 Subject: [PATCH 269/580] signalmeow/backup: remove incorrect comment The early returns are caused by duplicate calls to WaitForTransfer --- pkg/signalmeow/backup.go | 3 --- 1 file changed, 3 deletions(-) diff --git a/pkg/signalmeow/backup.go b/pkg/signalmeow/backup.go index 64247db..1d01b90 100644 --- a/pkg/signalmeow/backup.go +++ b/pkg/signalmeow/backup.go @@ -278,9 +278,6 @@ func (cli *Client) WaitForTransfer(ctx context.Context) (*TransferArchiveMetadat } reqDuration := time.Since(reqStart) if reqDuration < reqTimeout-10*time.Second { - // There seems to be a bug or feature when the transfer fails that causes the server to - // immediately return 204 until the user clicks "Continue" on their phone, so sleep for - // a bit to avoid sending requests too often. time.Sleep(15 * time.Second) } } From 3db54fd574d5291be6fbf8609ba9122c50126067 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Sun, 19 Jan 2025 20:47:07 +0200 Subject: [PATCH 270/580] client: unlink device when logging out --- pkg/connector/client.go | 4 ++++ pkg/signalmeow/provisioning.go | 14 ++++++++++++++ 2 files changed, 18 insertions(+) diff --git a/pkg/connector/client.go b/pkg/connector/client.go index 44a1d2a..7bf6884 100644 --- a/pkg/connector/client.go +++ b/pkg/connector/client.go @@ -90,6 +90,10 @@ func (s *SignalClient) LogoutRemote(ctx context.Context) { if err != nil { zerolog.Ctx(ctx).Err(err).Msg("Failed to stop receive loops for logout") } + err = s.Client.Unlink(ctx) + if err != nil { + zerolog.Ctx(ctx).Err(err).Msg("Failed to unlink device") + } err = s.Main.Store.DeleteDevice(context.TODO(), &s.Client.Store.DeviceData) if err != nil { zerolog.Ctx(ctx).Err(err).Msg("Failed to delete device from store") diff --git a/pkg/signalmeow/provisioning.go b/pkg/signalmeow/provisioning.go index d6774ae..f0e4ff8 100644 --- a/pkg/signalmeow/provisioning.go +++ b/pkg/signalmeow/provisioning.go @@ -385,6 +385,20 @@ func (cli *Client) RegisterCapabilities(ctx context.Context) error { return nil } +func (cli *Client) Unlink(ctx context.Context) error { + username, password := cli.Store.BasicAuthCreds() + resp, err := web.SendHTTPRequest(ctx, http.MethodDelete, fmt.Sprintf("/v1/devices/%d", cli.Store.DeviceID), &web.HTTPReqOpt{ + Username: &username, + Password: &password, + }) + if err != nil { + return err + } else if resp.StatusCode >= 400 { + return fmt.Errorf("unexpected status code %d", resp.StatusCode) + } + return nil +} + func confirmDevice( ctx context.Context, username string, From 121945a445ec9f5b36eb53d9cb7c379d8cab78de Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Mon, 20 Jan 2025 19:55:51 +0200 Subject: [PATCH 271/580] signalmeow/storageservice: process updates in transaction --- pkg/signalmeow/groups.go | 2 +- pkg/signalmeow/storageservice.go | 30 ++++++++++++++++++------------ pkg/signalmeow/store/container.go | 2 +- 3 files changed, 20 insertions(+), 14 deletions(-) diff --git a/pkg/signalmeow/groups.go b/pkg/signalmeow/groups.go index 7037b9c..ae44e12 100644 --- a/pkg/signalmeow/groups.go +++ b/pkg/signalmeow/groups.go @@ -767,7 +767,7 @@ func (cli *Client) StoreMasterKey(ctx context.Context, groupMasterKey types.Seri } err = cli.Store.GroupStore.StoreMasterKey(ctx, groupIdentifier, groupMasterKey) if err != nil { - return "", fmt.Errorf("StoreMasterKey error: %w", err) + return groupIdentifier, fmt.Errorf("StoreMasterKey error: %w", err) } return groupIdentifier, nil } diff --git a/pkg/signalmeow/storageservice.go b/pkg/signalmeow/storageservice.go index 28412b6..e8a5e5e 100644 --- a/pkg/signalmeow/storageservice.go +++ b/pkg/signalmeow/storageservice.go @@ -49,6 +49,16 @@ func (cli *Client) SyncStorage(ctx context.Context) { log.Err(err).Msg("Failed to fetch storage") return } + err = cli.Store.DoTxn(ctx, func(ctx context.Context) error { + return cli.processStorageInTxn(ctx, update) + }) + if err != nil { + log.Err(err).Msg("Failed to process storage update") + } +} + +func (cli *Client) processStorageInTxn(ctx context.Context, update *StorageUpdate) error { + log := zerolog.Ctx(ctx) for _, record := range update.NewRecords { switch data := record.StorageRecord.GetRecord().(type) { case *signalpb.StorageRecord_Contact: @@ -64,7 +74,7 @@ func (cli *Client) SyncStorage(ctx context.Context) { continue } contact := data.Contact - _, err = cli.Store.RecipientStore.LoadAndUpdateRecipient(ctx, aci, pni, func(recipient *types.Recipient) (changed bool, err error) { + _, err := cli.Store.RecipientStore.LoadAndUpdateRecipient(ctx, aci, pni, func(recipient *types.Recipient) (changed bool, err error) { if len(contact.ProfileKey) == libsignalgo.ProfileKeyLength { newProfileKey := libsignalgo.ProfileKey(contact.ProfileKey) changed = changed || recipient.Profile.Key != newProfileKey @@ -85,10 +95,7 @@ func (cli *Client) SyncStorage(ctx context.Context) { return }) if err != nil { - log.Err(err). - Stringer("aci", aci). - Stringer("pni", pni). - Msg("Failed to update contact") + return fmt.Errorf("failed to update contact %s/%s: %w", aci, pni, err) } case *signalpb.StorageRecord_GroupV2: if len(data.GroupV2.MasterKey) != libsignalgo.GroupMasterKeyLength { @@ -98,25 +105,24 @@ func (cli *Client) SyncStorage(ctx context.Context) { masterKey := libsignalgo.GroupMasterKey(data.GroupV2.MasterKey) groupID, err := cli.StoreMasterKey(ctx, masterKeyFromBytes(masterKey)) if err != nil { - log.Err(err).Msg("Failed to store group master key from storage service") - } else { - log.Debug().Stringer("group_id", groupID).Msg("Stored group master key from storage service") + return fmt.Errorf("failed to store group master key for %s: %w", groupID, err) } + log.Debug().Stringer("group_id", groupID).Msg("Stored group master key from storage service") case *signalpb.StorageRecord_Account: log.Trace().Any("account_record", data.Account).Msg("Found account record") cli.Store.AccountRecord = data.Account - err = cli.Store.DeviceStore.PutDevice(ctx, &cli.Store.DeviceData) + err := cli.Store.DeviceStore.PutDevice(ctx, &cli.Store.DeviceData) if err != nil { - log.Err(err).Msg("Failed to save device after receiving account record") - } else { - log.Debug().Msg("Saved device after receiving account record") + return fmt.Errorf("failed to save device after receiving account record: %w", err) } + log.Debug().Msg("Saved device after receiving account record") case *signalpb.StorageRecord_GroupV1, *signalpb.StorageRecord_StoryDistributionList: // irrelevant data default: log.Warn().Type("type", data).Str("item_id", record.StorageID).Msg("Unknown storage record type") } } + return nil } type StorageUpdate struct { diff --git a/pkg/signalmeow/store/container.go b/pkg/signalmeow/store/container.go index 0839689..42b8ea5 100644 --- a/pkg/signalmeow/store/container.go +++ b/pkg/signalmeow/store/container.go @@ -109,7 +109,7 @@ func (c *Container) scanDevice(row dbutil.Scannable) (*Device, error) { device.DeviceStore = baseStore device.BackupStore = baseStore device.DoTxn = func(ctx context.Context, fn func(context.Context) error) error { - return c.db.DoTxn(ctx, nil, fn) + return c.db.DoTxn(context.WithValue(ctx, dbutil.ContextKeyDoTxnCallerSkip, 1), nil, fn) } return &device, nil From 0b4d63a62b4d08597753da9609ad82a88f3083fe Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Mon, 20 Jan 2025 20:09:06 +0200 Subject: [PATCH 272/580] login: only sync storage after chats --- pkg/connector/client.go | 27 +++++++++++++++++++++++---- pkg/connector/login.go | 11 +---------- 2 files changed, 24 insertions(+), 14 deletions(-) diff --git a/pkg/connector/client.go b/pkg/connector/client.go index 7bf6884..89901eb 100644 --- a/pkg/connector/client.go +++ b/pkg/connector/client.go @@ -216,7 +216,7 @@ func (s *SignalClient) Connect(ctx context.Context) { return } s.updateRemoteProfile(ctx, false) - s.tryConnect(ctx, 0) + s.tryConnect(ctx, 0, true) } func (s *SignalClient) ConnectBackground(ctx context.Context) error { @@ -266,7 +266,24 @@ func (s *SignalClient) Disconnect() { } } -func (s *SignalClient) tryConnect(ctx context.Context, retryCount int) { +func (s *SignalClient) postLoginConnect() { + ctx := s.UserLogin.Log.WithContext(context.Background()) + // TODO it would be more proper to only connect after syncing, + // but currently syncing will fetch group info online, so it has to be connected. + s.tryConnect(ctx, 0, false) + if s.Client.Store.EphemeralBackupKey != nil { + go func() { + s.syncChats(ctx) + if s.Client.Store.MasterKey != nil { + s.Client.SyncStorage(ctx) + } + }() + } else if s.Client.Store.MasterKey != nil { + go s.Client.SyncStorage(ctx) + } +} + +func (s *SignalClient) tryConnect(ctx context.Context, retryCount int, doSync bool) { err := s.Client.RegisterCapabilities(ctx) if err != nil { zerolog.Ctx(ctx).Err(err).Msg("Failed to register capabilities") @@ -281,13 +298,15 @@ func (s *SignalClient) tryConnect(ctx context.Context, retryCount int) { retryInSeconds := 2 << retryCount zerolog.Ctx(ctx).Debug().Int("retry_in_seconds", retryInSeconds).Msg("Sleeping and retrying connection") time.Sleep(time.Duration(retryInSeconds) * time.Second) - s.tryConnect(ctx, retryCount+1) + s.tryConnect(ctx, retryCount+1, doSync) } else { s.UserLogin.BridgeState.Send(status.BridgeState{StateEvent: status.StateUnknownError, Error: "unknown-websocket-error", Message: err.Error()}) } } else { go s.bridgeStateLoop(ch) - go s.syncChats(ctx) + if doSync { + go s.syncChats(ctx) + } } } diff --git a/pkg/connector/login.go b/pkg/connector/login.go index e654971..8d30da9 100644 --- a/pkg/connector/login.go +++ b/pkg/connector/login.go @@ -21,7 +21,6 @@ import ( "fmt" "github.com/google/uuid" - "github.com/rs/zerolog" "maunium.net/go/mautrix/bridge/status" "maunium.net/go/mautrix/bridgev2" "maunium.net/go/mautrix/bridgev2/database" @@ -174,15 +173,7 @@ func (qr *QRLogin) processingWait(ctx context.Context) (*bridgev2.LoginStep, err if err != nil { return nil, fmt.Errorf("failed to create user login: %w", err) } - backgroundCtx := ul.Log.WithContext(context.Background()) - signalClient := ul.Client.(*SignalClient).Client - // TODO it would be more proper to only connect after syncing, - // but currently syncing will fetch group info online, so it has to be connected. - ul.Client.Connect(backgroundCtx) - if signalClient.Store.MasterKey != nil { - zerolog.Ctx(ctx).Info().Msg("Received master key in login, syncing storage immediately") - go signalClient.SyncStorage(backgroundCtx) - } + ul.Client.(*SignalClient).postLoginConnect() return &bridgev2.LoginStep{ Type: bridgev2.LoginStepTypeComplete, StepID: LoginStepComplete, From 15485eb0fd0e8bb43c54413406aebac6e7c27351 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Wed, 22 Jan 2025 19:05:17 +0200 Subject: [PATCH 273/580] signalmeow/attachments: fix splitting stream with chunks over 8192 bytes --- pkg/signalmeow/attachments_stream.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/signalmeow/attachments_stream.go b/pkg/signalmeow/attachments_stream.go index a410df0..1dcd9f9 100644 --- a/pkg/signalmeow/attachments_stream.go +++ b/pkg/signalmeow/attachments_stream.go @@ -151,7 +151,7 @@ func splitChunksStream(input io.Reader, callback func([]byte) error) error { continue } if msgLen > uint64(len(cachedBuf)) { - cachedBuf = make([]byte, min(msgLen, 8192)) + cachedBuf = make([]byte, max(msgLen, 8192)) } buf := cachedBuf[:msgLen] _, err = io.ReadFull(input, buf) From f5c818b3607cc995a17fe7ba6bf67e27b555eca0 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Thu, 23 Jan 2025 15:08:09 +0200 Subject: [PATCH 274/580] client: update ConnectBackground function signature --- go.mod | 2 +- go.sum | 4 ++-- pkg/connector/client.go | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/go.mod b/go.mod index 040c374..93db751 100644 --- a/go.mod +++ b/go.mod @@ -18,7 +18,7 @@ require ( golang.org/x/exp v0.0.0-20250106191152-7588d65b2ba8 golang.org/x/net v0.34.0 google.golang.org/protobuf v1.36.3 - maunium.net/go/mautrix v0.23.0 + maunium.net/go/mautrix v0.23.1-0.20250123130650-2d79ce4eed56 ) require ( diff --git a/go.sum b/go.sum index 1ee4934..5eaa1a4 100644 --- a/go.sum +++ b/go.sum @@ -100,5 +100,5 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= maunium.net/go/mauflag v1.0.0 h1:YiaRc0tEI3toYtJMRIfjP+jklH45uDHtT80nUamyD4M= maunium.net/go/mauflag v1.0.0/go.mod h1:nLivPOpTpHnpzEh8jEdSL9UqO9+/KBJFmNRlwKfkPeA= -maunium.net/go/mautrix v0.23.0 h1:HNlR19eew5lvrNSL2muhExaGhYdaGk5FfEiA82QqUP4= -maunium.net/go/mautrix v0.23.0/go.mod h1:AGnnaz3ylGikUo1I1MJVn9QLsl2No1/ZNnGDyO0QD5s= +maunium.net/go/mautrix v0.23.1-0.20250123130650-2d79ce4eed56 h1:31T/WEOtfzmtF5CD7jeeSys35EZ9jhSkkZ6gB9eOVyU= +maunium.net/go/mautrix v0.23.1-0.20250123130650-2d79ce4eed56/go.mod h1:AGnnaz3ylGikUo1I1MJVn9QLsl2No1/ZNnGDyO0QD5s= diff --git a/pkg/connector/client.go b/pkg/connector/client.go index 89901eb..2007088 100644 --- a/pkg/connector/client.go +++ b/pkg/connector/client.go @@ -219,7 +219,7 @@ func (s *SignalClient) Connect(ctx context.Context) { s.tryConnect(ctx, 0, true) } -func (s *SignalClient) ConnectBackground(ctx context.Context) error { +func (s *SignalClient) ConnectBackground(ctx context.Context, _ *bridgev2.ConnectBackgroundParams) error { s.queueEmptyWaiter.Clear() ch, err := s.Client.StartAuthedWS(ctx) if err != nil { From e4bb6db825f78f05ccf6a532b759ba84fc5f16f9 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Thu, 30 Jan 2025 12:41:05 +0200 Subject: [PATCH 275/580] signalmeow: update protobufs --- pkg/msgconv/from-signal-backup.go | 4 +- pkg/signalmeow/backup.go | 6 +- pkg/signalmeow/protobuf/backuppb/Backup.pb.go | 138 +++++++++++------- .../protobuf/backuppb/Backup.pb.raw | Bin 31334 -> 31259 bytes pkg/signalmeow/protobuf/backuppb/Backup.proto | 88 ++++++----- pkg/signalmeow/protobuf/update-protos.sh | 4 +- 6 files changed, 153 insertions(+), 87 deletions(-) diff --git a/pkg/msgconv/from-signal-backup.go b/pkg/msgconv/from-signal-backup.go index bf479ac..ccb4e50 100644 --- a/pkg/msgconv/from-signal-backup.go +++ b/pkg/msgconv/from-signal-backup.go @@ -236,8 +236,8 @@ func deleteNil(bodyRange *signalpb.BodyRange) bool { func backupToSignalBodyRange(from *backuppb.BodyRange) *signalpb.BodyRange { var out signalpb.BodyRange - out.Start = from.Start - out.Length = from.Length + out.Start = &from.Start + out.Length = &from.Length switch av := from.AssociatedValue.(type) { case *backuppb.BodyRange_MentionAci: // TODO confirm this is correct diff --git a/pkg/signalmeow/backup.go b/pkg/signalmeow/backup.go index 1d01b90..2302cd5 100644 --- a/pkg/signalmeow/backup.go +++ b/pkg/signalmeow/backup.go @@ -197,12 +197,16 @@ func (acp *archiveChunkProcessor) processFrame(frame *backuppb.Frame) error { acp.cli.Log.Trace().Any("backup_frame", frame).Msg("Processing backup frame") switch item := frame.Item.(type) { case *backuppb.Frame_Recipient: + if item.Recipient.Destination == nil { + zerolog.Ctx(acp.ctx).Debug().Msg("Ignoring recipient frame with no destination") + return nil + } return acp.cli.Store.BackupStore.AddBackupRecipient(acp.ctx, item.Recipient) case *backuppb.Frame_Chat: return acp.cli.Store.BackupStore.AddBackupChat(acp.ctx, item.Chat) case *backuppb.Frame_ChatItem: switch item.ChatItem.Item.(type) { - case *backuppb.ChatItem_DirectStoryReplyMessage, *backuppb.ChatItem_UpdateMessage: + case *backuppb.ChatItem_DirectStoryReplyMessage, *backuppb.ChatItem_UpdateMessage, nil: zerolog.Ctx(acp.ctx).Debug(). Uint64("chat_id", item.ChatItem.ChatId). Uint64("message_id", item.ChatItem.DateSent). diff --git a/pkg/signalmeow/protobuf/backuppb/Backup.pb.go b/pkg/signalmeow/protobuf/backuppb/Backup.pb.go index 1df6d19..a9700d1 100644 --- a/pkg/signalmeow/protobuf/backuppb/Backup.pb.go +++ b/pkg/signalmeow/protobuf/backuppb/Backup.pb.go @@ -25,7 +25,7 @@ const ( type GroupV2AccessLevel int32 const ( - GroupV2AccessLevel_UNKNOWN GroupV2AccessLevel = 0 + GroupV2AccessLevel_UNKNOWN GroupV2AccessLevel = 0 // Interpret as "Unsatisfiable" GroupV2AccessLevel_ANY GroupV2AccessLevel = 1 GroupV2AccessLevel_MEMBER GroupV2AccessLevel = 2 GroupV2AccessLevel_ADMINISTRATOR GroupV2AccessLevel = 3 @@ -80,7 +80,7 @@ func (GroupV2AccessLevel) EnumDescriptor() ([]byte, []int) { type AccountData_PhoneNumberSharingMode int32 const ( - AccountData_UNKNOWN AccountData_PhoneNumberSharingMode = 0 + AccountData_UNKNOWN AccountData_PhoneNumberSharingMode = 0 // Interpret as "Nobody" AccountData_EVERYBODY AccountData_PhoneNumberSharingMode = 1 AccountData_NOBODY AccountData_PhoneNumberSharingMode = 2 ) @@ -129,7 +129,7 @@ func (AccountData_PhoneNumberSharingMode) EnumDescriptor() ([]byte, []int) { type AccountData_UsernameLink_Color int32 const ( - AccountData_UsernameLink_UNKNOWN AccountData_UsernameLink_Color = 0 + AccountData_UsernameLink_UNKNOWN AccountData_UsernameLink_Color = 0 // Interpret as "Blue" AccountData_UsernameLink_BLUE AccountData_UsernameLink_Color = 1 AccountData_UsernameLink_WHITE AccountData_UsernameLink_Color = 2 AccountData_UsernameLink_GREY AccountData_UsernameLink_Color = 3 @@ -196,9 +196,9 @@ func (AccountData_UsernameLink_Color) EnumDescriptor() ([]byte, []int) { type Contact_IdentityState int32 const ( - Contact_DEFAULT Contact_IdentityState = 0 + Contact_DEFAULT Contact_IdentityState = 0 // A valid value -- indicates unset by the user Contact_VERIFIED Contact_IdentityState = 1 - Contact_UNVERIFIED Contact_IdentityState = 2 + Contact_UNVERIFIED Contact_IdentityState = 2 // Was once verified and is now unverified ) // Enum value maps for Contact_IdentityState. @@ -245,7 +245,7 @@ func (Contact_IdentityState) EnumDescriptor() ([]byte, []int) { type Contact_Visibility int32 const ( - Contact_VISIBLE Contact_Visibility = 0 + Contact_VISIBLE Contact_Visibility = 0 // A valid value -- the contact is not hidden Contact_HIDDEN Contact_Visibility = 1 Contact_HIDDEN_MESSAGE_REQUEST Contact_Visibility = 2 ) @@ -294,7 +294,7 @@ func (Contact_Visibility) EnumDescriptor() ([]byte, []int) { type Group_StorySendMode int32 const ( - Group_DEFAULT Group_StorySendMode = 0 + Group_DEFAULT Group_StorySendMode = 0 // A valid value -- indicates unset by the user Group_DISABLED Group_StorySendMode = 1 Group_ENABLED Group_StorySendMode = 2 ) @@ -343,7 +343,7 @@ func (Group_StorySendMode) EnumDescriptor() ([]byte, []int) { type Group_Member_Role int32 const ( - Group_Member_UNKNOWN Group_Member_Role = 0 + Group_Member_UNKNOWN Group_Member_Role = 0 // Intepret as "Default" Group_Member_DEFAULT Group_Member_Role = 1 Group_Member_ADMINISTRATOR Group_Member_Role = 2 ) @@ -392,7 +392,7 @@ func (Group_Member_Role) EnumDescriptor() ([]byte, []int) { type Group_AccessControl_AccessRequired int32 const ( - Group_AccessControl_UNKNOWN Group_AccessControl_AccessRequired = 0 + Group_AccessControl_UNKNOWN Group_AccessControl_AccessRequired = 0 // Intepret as "Unsatisfiable" Group_AccessControl_ANY Group_AccessControl_AccessRequired = 1 Group_AccessControl_MEMBER Group_AccessControl_AccessRequired = 2 Group_AccessControl_ADMINISTRATOR Group_AccessControl_AccessRequired = 3 @@ -447,7 +447,7 @@ func (Group_AccessControl_AccessRequired) EnumDescriptor() ([]byte, []int) { type CallLink_Restrictions int32 const ( - CallLink_UNKNOWN CallLink_Restrictions = 0 + CallLink_UNKNOWN CallLink_Restrictions = 0 // Interpret as "Admin Approval" CallLink_NONE CallLink_Restrictions = 1 CallLink_ADMIN_APPROVAL CallLink_Restrictions = 2 ) @@ -496,7 +496,7 @@ func (CallLink_Restrictions) EnumDescriptor() ([]byte, []int) { type AdHocCall_State int32 const ( - AdHocCall_UNKNOWN_STATE AdHocCall_State = 0 + AdHocCall_UNKNOWN_STATE AdHocCall_State = 0 // Interpret as "Generic" AdHocCall_GENERIC AdHocCall_State = 1 ) @@ -542,7 +542,7 @@ func (AdHocCall_State) EnumDescriptor() ([]byte, []int) { type DistributionList_PrivacyMode int32 const ( - DistributionList_UNKNOWN DistributionList_PrivacyMode = 0 + DistributionList_UNKNOWN DistributionList_PrivacyMode = 0 // Interpret as "Only with" DistributionList_ONLY_WITH DistributionList_PrivacyMode = 1 DistributionList_ALL_EXCEPT DistributionList_PrivacyMode = 2 DistributionList_ALL DistributionList_PrivacyMode = 3 @@ -643,7 +643,7 @@ func (SendStatus_Failed_FailureReason) EnumDescriptor() ([]byte, []int) { type PaymentNotification_TransactionDetails_FailedTransaction_FailureReason int32 const ( - PaymentNotification_TransactionDetails_FailedTransaction_GENERIC PaymentNotification_TransactionDetails_FailedTransaction_FailureReason = 0 + PaymentNotification_TransactionDetails_FailedTransaction_GENERIC PaymentNotification_TransactionDetails_FailedTransaction_FailureReason = 0 // A valid value -- reason unknown PaymentNotification_TransactionDetails_FailedTransaction_NETWORK PaymentNotification_TransactionDetails_FailedTransaction_FailureReason = 1 PaymentNotification_TransactionDetails_FailedTransaction_INSUFFICIENT_FUNDS PaymentNotification_TransactionDetails_FailedTransaction_FailureReason = 2 ) @@ -692,7 +692,7 @@ func (PaymentNotification_TransactionDetails_FailedTransaction_FailureReason) En type PaymentNotification_TransactionDetails_Transaction_Status int32 const ( - PaymentNotification_TransactionDetails_Transaction_INITIAL PaymentNotification_TransactionDetails_Transaction_Status = 0 + PaymentNotification_TransactionDetails_Transaction_INITIAL PaymentNotification_TransactionDetails_Transaction_Status = 0 // A valid value -- state unconfirmed PaymentNotification_TransactionDetails_Transaction_SUBMITTED PaymentNotification_TransactionDetails_Transaction_Status = 1 PaymentNotification_TransactionDetails_Transaction_SUCCESSFUL PaymentNotification_TransactionDetails_Transaction_Status = 2 ) @@ -741,7 +741,7 @@ func (PaymentNotification_TransactionDetails_Transaction_Status) EnumDescriptor( type GiftBadge_State int32 const ( - GiftBadge_UNOPENED GiftBadge_State = 0 + GiftBadge_UNOPENED GiftBadge_State = 0 // A valid state GiftBadge_OPENED GiftBadge_State = 1 GiftBadge_REDEEMED GiftBadge_State = 2 GiftBadge_FAILED GiftBadge_State = 3 @@ -793,7 +793,7 @@ func (GiftBadge_State) EnumDescriptor() ([]byte, []int) { type ContactAttachment_Phone_Type int32 const ( - ContactAttachment_Phone_UNKNOWN ContactAttachment_Phone_Type = 0 + ContactAttachment_Phone_UNKNOWN ContactAttachment_Phone_Type = 0 // Interpret as "Home" ContactAttachment_Phone_HOME ContactAttachment_Phone_Type = 1 ContactAttachment_Phone_MOBILE ContactAttachment_Phone_Type = 2 ContactAttachment_Phone_WORK ContactAttachment_Phone_Type = 3 @@ -848,7 +848,7 @@ func (ContactAttachment_Phone_Type) EnumDescriptor() ([]byte, []int) { type ContactAttachment_Email_Type int32 const ( - ContactAttachment_Email_UNKNOWN ContactAttachment_Email_Type = 0 + ContactAttachment_Email_UNKNOWN ContactAttachment_Email_Type = 0 // Intepret as "Home" ContactAttachment_Email_HOME ContactAttachment_Email_Type = 1 ContactAttachment_Email_MOBILE ContactAttachment_Email_Type = 2 ContactAttachment_Email_WORK ContactAttachment_Email_Type = 3 @@ -903,7 +903,7 @@ func (ContactAttachment_Email_Type) EnumDescriptor() ([]byte, []int) { type ContactAttachment_PostalAddress_Type int32 const ( - ContactAttachment_PostalAddress_UNKNOWN ContactAttachment_PostalAddress_Type = 0 + ContactAttachment_PostalAddress_UNKNOWN ContactAttachment_PostalAddress_Type = 0 // Interpret as "Home" ContactAttachment_PostalAddress_HOME ContactAttachment_PostalAddress_Type = 1 ContactAttachment_PostalAddress_WORK ContactAttachment_PostalAddress_Type = 2 ContactAttachment_PostalAddress_CUSTOM ContactAttachment_PostalAddress_Type = 3 @@ -958,7 +958,7 @@ func (ContactAttachment_PostalAddress_Type) EnumDescriptor() ([]byte, []int) { type MessageAttachment_Flag int32 const ( - MessageAttachment_NONE MessageAttachment_Flag = 0 + MessageAttachment_NONE MessageAttachment_Flag = 0 // A valid value -- no flag applied MessageAttachment_VOICE_MESSAGE MessageAttachment_Flag = 1 MessageAttachment_BORDERLESS MessageAttachment_Flag = 2 MessageAttachment_GIF MessageAttachment_Flag = 3 @@ -1010,7 +1010,7 @@ func (MessageAttachment_Flag) EnumDescriptor() ([]byte, []int) { type Quote_Type int32 const ( - Quote_UNKNOWN Quote_Type = 0 + Quote_UNKNOWN Quote_Type = 0 // Interpret as "Normal" Quote_NORMAL Quote_Type = 1 Quote_GIFT_BADGE Quote_Type = 2 Quote_VIEW_ONCE Quote_Type = 3 @@ -1062,7 +1062,7 @@ func (Quote_Type) EnumDescriptor() ([]byte, []int) { type BodyRange_Style int32 const ( - BodyRange_NONE BodyRange_Style = 0 + BodyRange_NONE BodyRange_Style = 0 // Importers should ignore the body range without throwing an error. BodyRange_BOLD BodyRange_Style = 1 BodyRange_ITALIC BodyRange_Style = 2 BodyRange_SPOILER BodyRange_Style = 3 @@ -1120,7 +1120,7 @@ func (BodyRange_Style) EnumDescriptor() ([]byte, []int) { type IndividualCall_Type int32 const ( - IndividualCall_UNKNOWN_TYPE IndividualCall_Type = 0 + IndividualCall_UNKNOWN_TYPE IndividualCall_Type = 0 // Interpret as "Audio call" IndividualCall_AUDIO_CALL IndividualCall_Type = 1 IndividualCall_VIDEO_CALL IndividualCall_Type = 2 ) @@ -1169,7 +1169,7 @@ func (IndividualCall_Type) EnumDescriptor() ([]byte, []int) { type IndividualCall_Direction int32 const ( - IndividualCall_UNKNOWN_DIRECTION IndividualCall_Direction = 0 + IndividualCall_UNKNOWN_DIRECTION IndividualCall_Direction = 0 // Interpret as "Incoming" IndividualCall_INCOMING IndividualCall_Direction = 1 IndividualCall_OUTGOING IndividualCall_Direction = 2 ) @@ -1218,7 +1218,7 @@ func (IndividualCall_Direction) EnumDescriptor() ([]byte, []int) { type IndividualCall_State int32 const ( - IndividualCall_UNKNOWN_STATE IndividualCall_State = 0 + IndividualCall_UNKNOWN_STATE IndividualCall_State = 0 // Interpret as "Accepted" IndividualCall_ACCEPTED IndividualCall_State = 1 IndividualCall_NOT_ACCEPTED IndividualCall_State = 2 // An incoming call that is no longer ongoing, which we neither accepted @@ -1277,7 +1277,7 @@ func (IndividualCall_State) EnumDescriptor() ([]byte, []int) { type GroupCall_State int32 const ( - GroupCall_UNKNOWN_STATE GroupCall_State = 0 + GroupCall_UNKNOWN_STATE GroupCall_State = 0 // Interpret as "Generic" // A group call was started without ringing. GroupCall_GENERIC GroupCall_State = 1 // We joined a group call that was started without ringing. @@ -1353,7 +1353,7 @@ func (GroupCall_State) EnumDescriptor() ([]byte, []int) { type SimpleChatUpdate_Type int32 const ( - SimpleChatUpdate_UNKNOWN SimpleChatUpdate_Type = 0 + SimpleChatUpdate_UNKNOWN SimpleChatUpdate_Type = 0 // Importers should skip the update without throwing an error. SimpleChatUpdate_JOINED_SIGNAL SimpleChatUpdate_Type = 1 SimpleChatUpdate_IDENTITY_UPDATE SimpleChatUpdate_Type = 2 SimpleChatUpdate_IDENTITY_VERIFIED SimpleChatUpdate_Type = 3 @@ -1444,7 +1444,7 @@ func (SimpleChatUpdate_Type) EnumDescriptor() ([]byte, []int) { type ChatStyle_WallpaperPreset int32 const ( - ChatStyle_UNKNOWN_WALLPAPER_PRESET ChatStyle_WallpaperPreset = 0 + ChatStyle_UNKNOWN_WALLPAPER_PRESET ChatStyle_WallpaperPreset = 0 // Interpret as the wallpaper being unset ChatStyle_SOLID_BLUSH ChatStyle_WallpaperPreset = 1 ChatStyle_SOLID_COPPER ChatStyle_WallpaperPreset = 2 ChatStyle_SOLID_DUST ChatStyle_WallpaperPreset = 3 @@ -1550,7 +1550,7 @@ func (ChatStyle_WallpaperPreset) EnumDescriptor() ([]byte, []int) { type ChatStyle_BubbleColorPreset int32 const ( - ChatStyle_UNKNOWN_BUBBLE_COLOR_PRESET ChatStyle_BubbleColorPreset = 0 + ChatStyle_UNKNOWN_BUBBLE_COLOR_PRESET ChatStyle_BubbleColorPreset = 0 // Interpret as the user's default chat bubble color ChatStyle_SOLID_ULTRAMARINE ChatStyle_BubbleColorPreset = 1 ChatStyle_SOLID_CRIMSON ChatStyle_BubbleColorPreset = 2 ChatStyle_SOLID_VERMILION ChatStyle_BubbleColorPreset = 3 @@ -1659,7 +1659,7 @@ func (ChatStyle_BubbleColorPreset) EnumDescriptor() ([]byte, []int) { type NotificationProfile_DayOfWeek int32 const ( - NotificationProfile_UNKNOWN NotificationProfile_DayOfWeek = 0 + NotificationProfile_UNKNOWN NotificationProfile_DayOfWeek = 0 // Interpret as "Monday" NotificationProfile_MONDAY NotificationProfile_DayOfWeek = 1 NotificationProfile_TUESDAY NotificationProfile_DayOfWeek = 2 NotificationProfile_WEDNESDAY NotificationProfile_DayOfWeek = 3 @@ -1724,7 +1724,7 @@ func (NotificationProfile_DayOfWeek) EnumDescriptor() ([]byte, []int) { type ChatFolder_FolderType int32 const ( - ChatFolder_UNKNOWN ChatFolder_FolderType = 0 + ChatFolder_UNKNOWN ChatFolder_FolderType = 0 // Interpret as "Custom" ChatFolder_ALL ChatFolder_FolderType = 1 ChatFolder_CUSTOM ChatFolder_FolderType = 2 ) @@ -1864,6 +1864,8 @@ func (x *BackupInfo) GetFirstAppVersion() string { // or may each immediately precede its first ChatItem. type Frame struct { state protoimpl.MessageState `protogen:"open.v1"` + // If unset, importers should skip this frame without throwing an error. + // // Types that are valid to be assigned to Item: // // *Frame_Account @@ -2151,6 +2153,8 @@ func (x *AccountData) GetBackupsSubscriberData() *AccountData_IAPSubscriberData type Recipient struct { state protoimpl.MessageState `protogen:"open.v1"` Id uint64 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"` // generated id for reference only within this file + // If unset, importers should skip this frame without throwing an error. + // // Types that are valid to be assigned to Destination: // // *Recipient_Contact @@ -2310,6 +2314,8 @@ type Contact struct { E164 *uint64 `protobuf:"varint,4,opt,name=e164,proto3,oneof" json:"e164,omitempty"` Blocked bool `protobuf:"varint,5,opt,name=blocked,proto3" json:"blocked,omitempty"` Visibility Contact_Visibility `protobuf:"varint,6,opt,name=visibility,proto3,enum=signal.backup.Contact_Visibility" json:"visibility,omitempty"` + // If unset, consider the user to be registered + // // Types that are valid to be assigned to Registration: // // *Contact_Registered_ @@ -2511,6 +2517,7 @@ type Group struct { HideStory bool `protobuf:"varint,3,opt,name=hideStory,proto3" json:"hideStory,omitempty"` StorySendMode Group_StorySendMode `protobuf:"varint,4,opt,name=storySendMode,proto3,enum=signal.backup.Group_StorySendMode" json:"storySendMode,omitempty"` Snapshot *Group_GroupSnapshot `protobuf:"bytes,5,opt,name=snapshot,proto3" json:"snapshot,omitempty"` + Blocked bool `protobuf:"varint,6,opt,name=blocked,proto3" json:"blocked,omitempty"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } @@ -2580,6 +2587,13 @@ func (x *Group) GetSnapshot() *Group_GroupSnapshot { return nil } +func (x *Group) GetBlocked() bool { + if x != nil { + return x.Blocked + } + return false +} + type Self struct { state protoimpl.MessageState `protogen:"open.v1"` unknownFields protoimpl.UnknownFields @@ -2925,6 +2939,8 @@ type DistributionListItem struct { // distribution ids are UUIDv4s. "My Story" is represented // by an all-0 UUID (00000000-0000-0000-0000-000000000000). DistributionId []byte `protobuf:"bytes,1,opt,name=distributionId,proto3" json:"distributionId,omitempty"` // distribution list ids are uuids + // If unset, importers should skip the item entirely without showing an error. + // // Types that are valid to be assigned to Item: // // *DistributionListItem_DeletionTimestamp @@ -3089,12 +3105,16 @@ type ChatItem struct { ExpiresInMs *uint64 `protobuf:"varint,5,opt,name=expiresInMs,proto3,oneof" json:"expiresInMs,omitempty"` // how long timer of message is (ms) Revisions []*ChatItem `protobuf:"bytes,6,rep,name=revisions,proto3" json:"revisions,omitempty"` // ordered from oldest to newest Sms bool `protobuf:"varint,7,opt,name=sms,proto3" json:"sms,omitempty"` + // If unset, importers should skip this item without throwing an error. + // // Types that are valid to be assigned to DirectionalDetails: // // *ChatItem_Incoming // *ChatItem_Outgoing // *ChatItem_Directionless DirectionalDetails isChatItem_DirectionalDetails `protobuf_oneof:"directionalDetails"` + // If unset, importers should skip this item without throwing an error. + // // Types that are valid to be assigned to Item: // // *ChatItem_StandardMessage @@ -3396,6 +3416,8 @@ type SendStatus struct { state protoimpl.MessageState `protogen:"open.v1"` RecipientId uint64 `protobuf:"varint,1,opt,name=recipientId,proto3" json:"recipientId,omitempty"` Timestamp uint64 `protobuf:"varint,2,opt,name=timestamp,proto3" json:"timestamp,omitempty"` // the time the status was last updated -- if from a receipt, it should be the sentTime of the receipt + // If unset, importers should consider the status to be "pending" + // // Types that are valid to be assigned to DeliveryStatus: // // *SendStatus_Pending_ @@ -3760,15 +3782,16 @@ func (x *ContactMessage) GetReactions() []*Reaction { type DirectStoryReplyMessage struct { state protoimpl.MessageState `protogen:"open.v1"` + // If unset, importers should ignore the message without throwing an error. + // // Types that are valid to be assigned to Reply: // // *DirectStoryReplyMessage_TextReply_ // *DirectStoryReplyMessage_Emoji - Reply isDirectStoryReplyMessage_Reply `protobuf_oneof:"reply"` - Reactions []*Reaction `protobuf:"bytes,3,rep,name=reactions,proto3" json:"reactions,omitempty"` - StorySentTimestamp *uint64 `protobuf:"varint,4,opt,name=storySentTimestamp,proto3,oneof" json:"storySentTimestamp,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache + Reply isDirectStoryReplyMessage_Reply `protobuf_oneof:"reply"` + Reactions []*Reaction `protobuf:"bytes,3,rep,name=reactions,proto3" json:"reactions,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } func (x *DirectStoryReplyMessage) Reset() { @@ -3833,13 +3856,6 @@ func (x *DirectStoryReplyMessage) GetReactions() []*Reaction { return nil } -func (x *DirectStoryReplyMessage) GetStorySentTimestamp() uint64 { - if x != nil && x.StorySentTimestamp != nil { - return *x.StorySentTimestamp - } - return 0 -} - type isDirectStoryReplyMessage_Reply interface { isDirectStoryReplyMessage_Reply() } @@ -4432,6 +4448,8 @@ func (x *MessageAttachment) GetClientUuid() []byte { type FilePointer struct { state protoimpl.MessageState `protogen:"open.v1"` + // If unset, importers should consider it to be an InvalidAttachmentLocator without throwing an error. + // // Types that are valid to be assigned to Locator: // // *FilePointer_BackupLocator_ @@ -4669,9 +4687,13 @@ func (x *Quote) GetType() Quote_Type { } type BodyRange struct { - state protoimpl.MessageState `protogen:"open.v1"` - Start *uint32 `protobuf:"varint,1,opt,name=start,proto3,oneof" json:"start,omitempty"` - Length *uint32 `protobuf:"varint,2,opt,name=length,proto3,oneof" json:"length,omitempty"` + state protoimpl.MessageState `protogen:"open.v1"` + // 'start' and 'length' are measured in UTF-16 code units. + // They may refer to offsets in a longText attachment. + Start uint32 `protobuf:"varint,1,opt,name=start,proto3" json:"start,omitempty"` + Length uint32 `protobuf:"varint,2,opt,name=length,proto3" json:"length,omitempty"` + // If unset, importers should ignore the body range without throwing an error. + // // Types that are valid to be assigned to AssociatedValue: // // *BodyRange_MentionAci @@ -4712,15 +4734,15 @@ func (*BodyRange) Descriptor() ([]byte, []int) { } func (x *BodyRange) GetStart() uint32 { - if x != nil && x.Start != nil { - return *x.Start + if x != nil { + return x.Start } return 0 } func (x *BodyRange) GetLength() uint32 { - if x != nil && x.Length != nil { - return *x.Length + if x != nil { + return x.Length } return 0 } @@ -4838,6 +4860,8 @@ func (x *Reaction) GetSortOrder() uint64 { type ChatUpdateMessage struct { state protoimpl.MessageState `protogen:"open.v1"` + // If unset, importers should ignore the update message without throwing an error. + // // Types that are valid to be assigned to Update: // // *ChatUpdateMessage_SimpleUpdate @@ -5350,6 +5374,8 @@ func (x *ProfileChangeChatUpdate) GetNewName() string { type LearnedProfileChatUpdate struct { state protoimpl.MessageState `protogen:"open.v1"` + // If unset, importers should consider the previous name to be an empty string. + // // Types that are valid to be assigned to PreviousName: // // *LearnedProfileChatUpdate_E164 @@ -7305,11 +7331,15 @@ func (x *StickerPack) GetPackKey() []byte { type ChatStyle struct { state protoimpl.MessageState `protogen:"open.v1"` + // If unset, importers should consider there to be no wallpaper. + // // Types that are valid to be assigned to Wallpaper: // // *ChatStyle_WallpaperPreset_ // *ChatStyle_WallpaperPhoto Wallpaper isChatStyle_Wallpaper `protobuf_oneof:"wallpaper"` + // If unset, importers should consider it to be AutomaticBubbleColor + // // Types that are valid to be assigned to BubbleColor: // // *ChatStyle_AutoBubbleColor @@ -7997,6 +8027,8 @@ func (x *AccountData_SubscriberData) GetManuallyCancelled() bool { type AccountData_IAPSubscriberData struct { state protoimpl.MessageState `protogen:"open.v1"` SubscriberId []byte `protobuf:"bytes,1,opt,name=subscriberId,proto3" json:"subscriberId,omitempty"` + // If unset, importers should ignore the subscriber data without throwing an error. + // // Types that are valid to be assigned to IapSubscriptionId: // // *AccountData_IAPSubscriberData_PurchaseToken @@ -8359,6 +8391,8 @@ func (x *Group_GroupSnapshot) GetMembersBanned() []*Group_MemberBanned { type Group_GroupAttributeBlob struct { state protoimpl.MessageState `protogen:"open.v1"` + // If unset, consider the field it represents to not be present + // // Types that are valid to be assigned to Content: // // *Group_GroupAttributeBlob_Title @@ -9250,6 +9284,8 @@ func (x *DirectStoryReplyMessage_TextReply) GetLongText() *FilePointer { type PaymentNotification_TransactionDetails struct { state protoimpl.MessageState `protogen:"open.v1"` + // If unset, importers should treat the transaction as successful with no metadata. + // // Types that are valid to be assigned to Payment: // // *PaymentNotification_TransactionDetails_Transaction_ @@ -10123,6 +10159,8 @@ func (x *Quote_QuotedAttachment) GetThumbnail() *MessageAttachment { type GroupChangeChatUpdate_Update struct { state protoimpl.MessageState `protogen:"open.v1"` + // If unset, importers should consider it to be a GenericGroupUpdate with unset updaterAci + // // Types that are valid to be assigned to Update: // // *GroupChangeChatUpdate_Update_GenericGroupUpdate @@ -10864,6 +10902,8 @@ func (x *ChatStyle_Gradient) GetPositions() []float32 { type ChatStyle_CustomChatColor struct { state protoimpl.MessageState `protogen:"open.v1"` Id uint64 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"` + // If unset, use the default chat color + // // Types that are valid to be assigned to Color: // // *ChatStyle_CustomChatColor_Solid diff --git a/pkg/signalmeow/protobuf/backuppb/Backup.pb.raw b/pkg/signalmeow/protobuf/backuppb/Backup.pb.raw index fa51eb6b784f0b88b8fbe3fc0af1a0b5b0eb0b1b..7a030359a9583e852063511073a9fec4c60b91d5 100644 GIT binary patch delta 146 zcmaF%g>m*5#tnf&jC&>r34M?flHg)b%E?d8PECOKo!zEF##}U{6be*%yljk7pGHxN@Y-DUV5sKBo`~t z*rE~%Mxe30Kw}|Xph-f~Tx>b1dFdq?5=>w@rXVOEWR084QBfxjE;gVwK;2H9T K#hbZZ1xx|mnM4o( diff --git a/pkg/signalmeow/protobuf/backuppb/Backup.proto b/pkg/signalmeow/protobuf/backuppb/Backup.proto index 48a6f24..42f3e8d 100644 --- a/pkg/signalmeow/protobuf/backuppb/Backup.proto +++ b/pkg/signalmeow/protobuf/backuppb/Backup.proto @@ -30,6 +30,7 @@ message BackupInfo { // For example, Chats may all be together at the beginning, // or may each immediately precede its first ChatItem. message Frame { + // If unset, importers should skip this frame without throwing an error. oneof item { AccountData account = 1; Recipient recipient = 2; @@ -44,13 +45,13 @@ message Frame { message AccountData { enum PhoneNumberSharingMode { - UNKNOWN = 0; + UNKNOWN = 0; // Interpret as "Nobody" EVERYBODY = 1; NOBODY = 2; } message UsernameLink { enum Color { - UNKNOWN = 0; + UNKNOWN = 0; // Interpret as "Blue" BLUE = 1; WHITE = 2; GREY = 3; @@ -97,6 +98,7 @@ message AccountData { message IAPSubscriberData { bytes subscriberId = 1; + // If unset, importers should ignore the subscriber data without throwing an error. oneof iapSubscriptionId { // Identifies an Android Play Store IAP subscription. string purchaseToken = 2; @@ -119,6 +121,7 @@ message AccountData { message Recipient { uint64 id = 1; // generated id for reference only within this file + // If unset, importers should skip this frame without throwing an error. oneof destination { Contact contact = 2; Group group = 3; @@ -131,9 +134,9 @@ message Recipient { message Contact { enum IdentityState { - DEFAULT = 0; + DEFAULT = 0; // A valid value -- indicates unset by the user VERIFIED = 1; - UNVERIFIED = 2; + UNVERIFIED = 2; // Was once verified and is now unverified } message Registered {} @@ -142,7 +145,7 @@ message Contact { } enum Visibility { - VISIBLE = 0; + VISIBLE = 0; // A valid value -- the contact is not hidden HIDDEN = 1; HIDDEN_MESSAGE_REQUEST = 2; } @@ -159,6 +162,7 @@ message Contact { bool blocked = 5; Visibility visibility = 6; + // If unset, consider the user to be registered oneof registration { Registered registered = 7; NotRegistered notRegistered = 8; @@ -177,7 +181,7 @@ message Contact { message Group { enum StorySendMode { - DEFAULT = 0; + DEFAULT = 0; // A valid value -- indicates unset by the user DISABLED = 1; ENABLED = 2; } @@ -187,6 +191,7 @@ message Group { bool hideStory = 3; StorySendMode storySendMode = 4; GroupSnapshot snapshot = 5; + bool blocked = 6; // These are simply plaintext copies of the groups proto from Groups.proto. // They should be kept completely in-sync with Groups.proto. @@ -210,6 +215,7 @@ message Group { } message GroupAttributeBlob { + // If unset, consider the field it represents to not be present oneof content { string title = 1; bytes avatar = 2; @@ -220,7 +226,7 @@ message Group { message Member { enum Role { - UNKNOWN = 0; + UNKNOWN = 0; // Intepret as "Default" DEFAULT = 1; ADMINISTRATOR = 2; } @@ -252,7 +258,7 @@ message Group { message AccessControl { enum AccessRequired { - UNKNOWN = 0; + UNKNOWN = 0; // Intepret as "Unsatisfiable" ANY = 1; MEMBER = 2; ADMINISTRATOR = 3; @@ -292,7 +298,7 @@ message Chat { */ message CallLink { enum Restrictions { - UNKNOWN = 0; + UNKNOWN = 0; // Interpret as "Admin Approval" NONE = 1; ADMIN_APPROVAL = 2; } @@ -306,7 +312,7 @@ message CallLink { message AdHocCall { enum State { - UNKNOWN_STATE = 0; + UNKNOWN_STATE = 0; // Interpret as "Generic" GENERIC = 1; } @@ -322,6 +328,7 @@ message DistributionListItem { // by an all-0 UUID (00000000-0000-0000-0000-000000000000). bytes distributionId = 1; // distribution list ids are uuids + // If unset, importers should skip the item entirely without showing an error. oneof item { uint64 deletionTimestamp = 2; DistributionList distributionList = 3; @@ -330,7 +337,7 @@ message DistributionListItem { message DistributionList { enum PrivacyMode { - UNKNOWN = 0; + UNKNOWN = 0; // Interpret as "Only with" ONLY_WITH = 1; ALL_EXCEPT = 2; ALL = 3; @@ -365,12 +372,14 @@ message ChatItem { repeated ChatItem revisions = 6; // ordered from oldest to newest bool sms = 7; + // If unset, importers should skip this item without throwing an error. oneof directionalDetails { IncomingMessageDetails incoming = 8; OutgoingMessageDetails outgoing = 9; DirectionlessMessageDetails directionless = 10; } + // If unset, importers should skip this item without throwing an error. oneof item { StandardMessage standardMessage = 11; ContactMessage contactMessage = 12; @@ -419,6 +428,7 @@ message SendStatus { uint64 recipientId = 1; uint64 timestamp = 2; // the time the status was last updated -- if from a receipt, it should be the sentTime of the receipt + // If unset, importers should consider the status to be "pending" oneof deliveryStatus { Pending pending = 3; Sent sent = 4; @@ -455,13 +465,14 @@ message DirectStoryReplyMessage { FilePointer longText = 2; } + // If unset, importers should ignore the message without throwing an error. oneof reply { TextReply textReply = 1; string emoji = 2; } repeated Reaction reactions = 3; - optional uint64 storySentTimestamp = 4; + reserved /*storySentTimestamp*/ 4; } message PaymentNotification { @@ -473,7 +484,7 @@ message PaymentNotification { message FailedTransaction { // Failed payments can't be synced from the ledger enum FailureReason { - GENERIC = 0; + GENERIC = 0; // A valid value -- reason unknown NETWORK = 1; INSUFFICIENT_FUNDS = 2; } @@ -482,7 +493,7 @@ message PaymentNotification { message Transaction { enum Status { - INITIAL = 0; + INITIAL = 0; // A valid value -- state unconfirmed SUBMITTED = 1; SUCCESSFUL = 2; } @@ -499,6 +510,7 @@ message PaymentNotification { optional bytes receipt = 7; // mobile coin blobs } + // If unset, importers should treat the transaction as successful with no metadata. oneof payment { Transaction transaction = 1; FailedTransaction failedTransaction = 2; @@ -513,7 +525,7 @@ message PaymentNotification { message GiftBadge { enum State { - UNOPENED = 0; + UNOPENED = 0; // A valid state OPENED = 1; REDEEMED = 2; FAILED = 3; @@ -541,7 +553,7 @@ message ContactAttachment { message Phone { enum Type { - UNKNOWN = 0; + UNKNOWN = 0; // Interpret as "Home" HOME = 1; MOBILE = 2; WORK = 3; @@ -555,7 +567,7 @@ message ContactAttachment { message Email { enum Type { - UNKNOWN = 0; + UNKNOWN = 0; // Intepret as "Home" HOME = 1; MOBILE = 2; WORK = 3; @@ -569,7 +581,7 @@ message ContactAttachment { message PostalAddress { enum Type { - UNKNOWN = 0; + UNKNOWN = 0; // Interpret as "Home" HOME = 1; WORK = 2; CUSTOM = 3; @@ -629,7 +641,7 @@ message MessageAttachment { // but explicitly mutually exclusive. Note the different raw values // (non-zero starting values are not supported in proto3.) enum Flag { - NONE = 0; + NONE = 0; // A valid value -- no flag applied VOICE_MESSAGE = 1; BORDERLESS = 2; GIF = 3; @@ -680,6 +692,7 @@ message FilePointer { message InvalidAttachmentLocator { } + // If unset, importers should consider it to be an InvalidAttachmentLocator without throwing an error. oneof locator { BackupLocator backupLocator = 1; AttachmentLocator attachmentLocator = 2; @@ -698,7 +711,7 @@ message FilePointer { message Quote { enum Type { - UNKNOWN = 0; + UNKNOWN = 0; // Interpret as "Normal" NORMAL = 1; GIFT_BADGE = 2; VIEW_ONCE = 3; @@ -719,7 +732,7 @@ message Quote { message BodyRange { enum Style { - NONE = 0; + NONE = 0; // Importers should ignore the body range without throwing an error. BOLD = 1; ITALIC = 2; SPOILER = 3; @@ -727,9 +740,12 @@ message BodyRange { MONOSPACE = 5; } - optional uint32 start = 1; - optional uint32 length = 2; + // 'start' and 'length' are measured in UTF-16 code units. + // They may refer to offsets in a longText attachment. + uint32 start = 1; + uint32 length = 2; + // If unset, importers should ignore the body range without throwing an error. oneof associatedValue { bytes mentionAci = 3; Style style = 4; @@ -746,6 +762,7 @@ message Reaction { } message ChatUpdateMessage { + // If unset, importers should ignore the update message without throwing an error. oneof update { SimpleChatUpdate simpleUpdate = 1; GroupChangeChatUpdate groupChange = 2; @@ -761,19 +778,19 @@ message ChatUpdateMessage { message IndividualCall { enum Type { - UNKNOWN_TYPE = 0; + UNKNOWN_TYPE = 0; // Interpret as "Audio call" AUDIO_CALL = 1; VIDEO_CALL = 2; } enum Direction { - UNKNOWN_DIRECTION = 0; + UNKNOWN_DIRECTION = 0; // Interpret as "Incoming" INCOMING = 1; OUTGOING = 2; } enum State { - UNKNOWN_STATE = 0; + UNKNOWN_STATE = 0; // Interpret as "Accepted" ACCEPTED = 1; NOT_ACCEPTED = 2; // An incoming call that is no longer ongoing, which we neither accepted @@ -794,7 +811,7 @@ message IndividualCall { message GroupCall { enum State { - UNKNOWN_STATE = 0; + UNKNOWN_STATE = 0; // Interpret as "Generic" // A group call was started without ringing. GENERIC = 1; // We joined a group call that was started without ringing. @@ -825,7 +842,7 @@ message GroupCall { message SimpleChatUpdate { enum Type { - UNKNOWN = 0; + UNKNOWN = 0; // Importers should skip the update without throwing an error. JOINED_SIGNAL = 1; IDENTITY_UPDATE = 2; IDENTITY_VERIFIED = 3; @@ -859,6 +876,7 @@ message ProfileChangeChatUpdate { } message LearnedProfileChatUpdate { + // If unset, importers should consider the previous name to be an empty string. oneof previousName { uint64 e164 = 1; string username = 2; @@ -875,6 +893,7 @@ message SessionSwitchoverChatUpdate { message GroupChangeChatUpdate { message Update { + // If unset, importers should consider it to be a GenericGroupUpdate with unset updaterAci oneof update { GenericGroupUpdate genericGroupUpdate = 1; GroupCreationUpdate groupCreationUpdate = 2; @@ -944,7 +963,7 @@ message GroupDescriptionUpdate { } enum GroupV2AccessLevel { - UNKNOWN = 0; + UNKNOWN = 0; // Interpret as "Unsatisfiable" ANY = 1; MEMBER = 2; ADMINISTRATOR = 3; @@ -1134,6 +1153,7 @@ message ChatStyle { message CustomChatColor { uint64 id = 1; + // If unset, use the default chat color oneof color { fixed32 solid = 2; // 0xAARRGGBB Gradient gradient = 3; @@ -1144,7 +1164,7 @@ message ChatStyle { } enum WallpaperPreset { - UNKNOWN_WALLPAPER_PRESET = 0; + UNKNOWN_WALLPAPER_PRESET = 0; // Interpret as the wallpaper being unset SOLID_BLUSH = 1; SOLID_COPPER = 2; SOLID_DUST = 3; @@ -1169,7 +1189,7 @@ message ChatStyle { } enum BubbleColorPreset { - UNKNOWN_BUBBLE_COLOR_PRESET = 0; + UNKNOWN_BUBBLE_COLOR_PRESET = 0; // Interpret as the user's default chat bubble color SOLID_ULTRAMARINE = 1; SOLID_CRIMSON = 2; SOLID_VERMILION = 3; @@ -1194,6 +1214,7 @@ message ChatStyle { GRADIENT_TANGERINE = 22; } + // If unset, importers should consider there to be no wallpaper. oneof wallpaper { WallpaperPreset wallpaperPreset = 1; // This `FilePointer` is expected not to contain a `fileName`, `width`, @@ -1201,6 +1222,7 @@ message ChatStyle { FilePointer wallpaperPhoto = 2; } + // If unset, importers should consider it to be AutomaticBubbleColor oneof bubbleColor { // Bubble setting is automatically determined based on the wallpaper setting, // or `SOLID_ULTRAMARINE` for `noWallpaper` @@ -1216,7 +1238,7 @@ message ChatStyle { message NotificationProfile { enum DayOfWeek { - UNKNOWN = 0; + UNKNOWN = 0; // Interpret as "Monday" MONDAY = 1; TUESDAY = 2; WEDNESDAY = 3; @@ -1242,7 +1264,7 @@ message NotificationProfile { message ChatFolder { // Represents the default "All chats" folder record vs all other custom folders enum FolderType { - UNKNOWN = 0; + UNKNOWN = 0; // Interpret as "Custom" ALL = 1; CUSTOM = 2; } diff --git a/pkg/signalmeow/protobuf/update-protos.sh b/pkg/signalmeow/protobuf/update-protos.sh index cf47a8c..1699017 100755 --- a/pkg/signalmeow/protobuf/update-protos.sh +++ b/pkg/signalmeow/protobuf/update-protos.sh @@ -1,8 +1,8 @@ #!/bin/bash set -euo pipefail -ANDROID_GIT_REVISION=${1:-50db945ef1673da9990affeff022da64e4caa264} -DESKTOP_GIT_REVISION=${1:-ca1d17354db10a14f9f5558dcb546af9f3bba578} +ANDROID_GIT_REVISION=${1:-aa9c87ee67364a28977a2a5ba3bb7f5e715e19a0} +DESKTOP_GIT_REVISION=${1:-3f0536f5a58b6a20949690afd76093f41931843c} update_proto() { case "$1" in From 872c2843f39510bd3ef8791f0367e4597e68513e Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Thu, 30 Jan 2025 12:47:23 +0200 Subject: [PATCH 276/580] libsignal: update to v0.65.4 --- CHANGELOG.md | 2 +- pkg/libsignalgo/libsignal | 2 +- pkg/libsignalgo/version.go | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e833eaa..435e8be 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,7 +1,7 @@ # v0.8.0 (unreleased) * Added support for history transfer. -* Updated libsignal to v0.65.2. +* Updated libsignal to v0.65.4. # v0.7.5 (2025-01-16) diff --git a/pkg/libsignalgo/libsignal b/pkg/libsignalgo/libsignal index 864a1a1..4da852b 160000 --- a/pkg/libsignalgo/libsignal +++ b/pkg/libsignalgo/libsignal @@ -1 +1 @@ -Subproject commit 864a1a1a87d08b30516fdf5734ae426b0508f445 +Subproject commit 4da852be7529372a53123a0a097ed6f252961fce diff --git a/pkg/libsignalgo/version.go b/pkg/libsignalgo/version.go index 528ebe6..8a399dd 100644 --- a/pkg/libsignalgo/version.go +++ b/pkg/libsignalgo/version.go @@ -2,4 +2,4 @@ package libsignalgo -const Version = "v0.65.2" +const Version = "v0.65.4" From 0ca656a5e164ecab5969b538c3b0e85695083621 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Thu, 30 Jan 2025 14:57:16 +0200 Subject: [PATCH 277/580] signalmeow: update backup capability id --- pkg/signalmeow/provisioning.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/signalmeow/provisioning.go b/pkg/signalmeow/provisioning.go index f0e4ff8..94a4176 100644 --- a/pkg/signalmeow/provisioning.go +++ b/pkg/signalmeow/provisioning.go @@ -299,7 +299,7 @@ func startProvisioning(ctx context.Context, ws *websocket.Conn, provisioningCiph return "", fmt.Errorf("failed to unmarshal provisioning UUID: %w", err) } - linkCapabilities := []string{"backup"} + linkCapabilities := []string{"backup3"} if !allowBackup { linkCapabilities = []string{} } From f07723070d8ae4d07347cc4b989f78f9def082a6 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Thu, 30 Jan 2025 18:11:06 +0200 Subject: [PATCH 278/580] signalmeow/store: add logs for recipient updates --- pkg/signalmeow/store/recipient_store.go | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/pkg/signalmeow/store/recipient_store.go b/pkg/signalmeow/store/recipient_store.go index bdcd0c0..84f9af9 100644 --- a/pkg/signalmeow/store/recipient_store.go +++ b/pkg/signalmeow/store/recipient_store.go @@ -25,6 +25,7 @@ import ( "time" "github.com/google/uuid" + "github.com/rs/zerolog" "go.mau.fi/util/dbutil" "go.mau.fi/mautrix-signal/pkg/libsignalgo" @@ -166,6 +167,10 @@ func (s *sqlStore) mergeRecipients(ctx context.Context, first, second *types.Rec first, second = second, first } first.PNI = second.PNI + zerolog.Ctx(ctx).Debug(). + Stringer("aci", first.ACI). + Stringer("pni", first.PNI). + Msg("Merging recipient entries in database") if second.E164 != "" { first.E164 = second.E164 } @@ -247,6 +252,10 @@ func (s *sqlStore) LoadAndUpdateRecipient(ctx context.Context, aci, pni uuid.UUI // SQL only supports one ON CONFLICT clause, which means StoreRecipient will key on the ACI if it's present. // If we're adding an ACI to a PNI row, just delete the PNI row first to avoid conflicts on the PNI key. if outRecipient.PNI != uuid.Nil && outRecipient.ACI == uuid.Nil && aci != uuid.Nil { + zerolog.Ctx(ctx).Debug(). + Stringer("aci", outRecipient.ACI). + Stringer("pni", outRecipient.PNI). + Msg("Deleting old PNI-only row before inserting row with both IDs") err = s.DeleteRecipientByPNI(ctx, outRecipient.PNI) if err != nil { return fmt.Errorf("failed to delete old PNI row: %w", err) @@ -261,6 +270,10 @@ func (s *sqlStore) LoadAndUpdateRecipient(ctx context.Context, aci, pni uuid.UUI changed = true } if changed || len(entries) == 0 { + zerolog.Ctx(ctx).Trace(). + Stringer("aci", outRecipient.ACI). + Stringer("pni", outRecipient.PNI). + Msg("Saving recipient row") err = s.StoreRecipient(ctx, outRecipient) if err != nil { return fmt.Errorf("failed to store updated recipient row: %w", err) From 3781461b28effca4dcecb667c61925f06e8d4469 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Tue, 4 Feb 2025 11:48:31 +0200 Subject: [PATCH 279/580] signalmeow/store: fix locking recipient store --- pkg/signalmeow/backup.go | 2 +- pkg/signalmeow/receiving.go | 38 ++++++++++++++----------- pkg/signalmeow/storageservice.go | 2 +- pkg/signalmeow/store/container.go | 6 ++-- pkg/signalmeow/store/device.go | 18 +++++++++++- pkg/signalmeow/store/recipient_store.go | 6 ++-- 6 files changed, 47 insertions(+), 25 deletions(-) diff --git a/pkg/signalmeow/backup.go b/pkg/signalmeow/backup.go index 2302cd5..43c2f78 100644 --- a/pkg/signalmeow/backup.go +++ b/pkg/signalmeow/backup.go @@ -93,7 +93,7 @@ func (cli *Client) FetchAndProcessTransfer(ctx context.Context, meta *TransferAr if err != nil { return fmt.Errorf("failed to seek to start of file: %w", err) } - err = cli.Store.DoTxn(ctx, func(ctx context.Context) error { + err = cli.Store.DoContactTxn(ctx, func(ctx context.Context) error { err = cli.Store.BackupStore.ClearBackup(ctx) if err != nil { return fmt.Errorf("failed to clear backup: %w", err) diff --git a/pkg/signalmeow/receiving.go b/pkg/signalmeow/receiving.go index 4d913e2..a2aa551 100644 --- a/pkg/signalmeow/receiving.go +++ b/pkg/signalmeow/receiving.go @@ -805,24 +805,30 @@ func (cli *Client) handleDecryptedResult( } log.Debug().Int("contact_count", len(contacts)).Msg("Contacts Sync received contacts") convertedContacts := make([]*types.Recipient, 0, len(contacts)) - for i, signalContact := range contacts { - if signalContact.Aci == nil || *signalContact.Aci == "" { - // TODO lookup PNI via CDSI and store that when ACI is missing? - log.Info(). - Any("contact", signalContact). - Msg("Signal Contact UUID is nil, skipping") - continue + err = cli.Store.DoContactTxn(ctx, func(ctx context.Context) error { + for i, signalContact := range contacts { + if signalContact.Aci == nil || *signalContact.Aci == "" { + // TODO lookup PNI via CDSI and store that when ACI is missing? + log.Info(). + Any("contact", signalContact). + Msg("Signal Contact UUID is nil, skipping") + continue + } + contact, err := cli.StoreContactDetailsAsContact(ctx, signalContact, &avatars[i]) + if err != nil { + return err + } + convertedContacts = append(convertedContacts, contact) } - contact, err := cli.StoreContactDetailsAsContact(ctx, signalContact, &avatars[i]) - if err != nil { - log.Err(err).Msg("StoreContactDetailsAsContact error") - continue - } - convertedContacts = append(convertedContacts, contact) - } - cli.handleEvent(&events.ContactList{ - Contacts: convertedContacts, + return nil }) + if err != nil { + log.Err(err).Msg("Error storing contacts") + } else { + cli.handleEvent(&events.ContactList{ + Contacts: convertedContacts, + }) + } } } if content.SyncMessage.Read != nil { diff --git a/pkg/signalmeow/storageservice.go b/pkg/signalmeow/storageservice.go index e8a5e5e..26d52ff 100644 --- a/pkg/signalmeow/storageservice.go +++ b/pkg/signalmeow/storageservice.go @@ -49,7 +49,7 @@ func (cli *Client) SyncStorage(ctx context.Context) { log.Err(err).Msg("Failed to fetch storage") return } - err = cli.Store.DoTxn(ctx, func(ctx context.Context) error { + err = cli.Store.DoContactTxn(ctx, func(ctx context.Context) error { return cli.processStorageInTxn(ctx, update) }) if err != nil { diff --git a/pkg/signalmeow/store/container.go b/pkg/signalmeow/store/container.go index 42b8ea5..18f9b99 100644 --- a/pkg/signalmeow/store/container.go +++ b/pkg/signalmeow/store/container.go @@ -108,10 +108,8 @@ func (c *Container) scanDevice(row dbutil.Scannable) (*Device, error) { device.RecipientStore = baseStore device.DeviceStore = baseStore device.BackupStore = baseStore - device.DoTxn = func(ctx context.Context, fn func(context.Context) error) error { - return c.db.DoTxn(context.WithValue(ctx, dbutil.ContextKeyDoTxnCallerSkip, 1), nil, fn) - } - + device.sqlStore = baseStore + device.db = c.db return &device, nil } diff --git a/pkg/signalmeow/store/device.go b/pkg/signalmeow/store/device.go index bcd4a88..fc7fac6 100644 --- a/pkg/signalmeow/store/device.go +++ b/pkg/signalmeow/store/device.go @@ -7,6 +7,7 @@ import ( "github.com/google/uuid" "github.com/rs/zerolog" + "go.mau.fi/util/dbutil" "go.mau.fi/mautrix-signal/pkg/libsignalgo" signalpb "go.mau.fi/mautrix-signal/pkg/signalmeow/protobuf" @@ -79,7 +80,22 @@ type Device struct { DeviceStore DeviceStore BackupStore BackupStore - DoTxn func(context.Context, func(context.Context) error) error + sqlStore *sqlStore + db *dbutil.Database +} + +type contextKey int64 + +const ( + contextKeyContactLock contextKey = 1 +) + +func (d *Device) DoContactTxn(ctx context.Context, fn func(context.Context) error) error { + d.sqlStore.contactLock.Lock() + defer d.sqlStore.contactLock.Unlock() + ctx = context.WithValue(ctx, dbutil.ContextKeyDoTxnCallerSkip, 1) + ctx = context.WithValue(ctx, contextKeyContactLock, true) + return d.db.DoTxn(ctx, nil, fn) } func (d *Device) ClearDeviceKeys(ctx context.Context) error { diff --git a/pkg/signalmeow/store/recipient_store.go b/pkg/signalmeow/store/recipient_store.go index 84f9af9..03608a2 100644 --- a/pkg/signalmeow/store/recipient_store.go +++ b/pkg/signalmeow/store/recipient_store.go @@ -204,8 +204,10 @@ func (s *sqlStore) LoadAndUpdateRecipient(ctx context.Context, aci, pni uuid.UUI return false, nil } } - s.contactLock.Lock() - defer s.contactLock.Unlock() + if ctx.Value(contextKeyContactLock) == nil { + s.contactLock.Lock() + defer s.contactLock.Unlock() + } outErr = s.db.DoTxn(ctx, nil, func(ctx context.Context) error { var entries []*types.Recipient var err error From 985898a7084e49d70bc5dfe49af319e6fc82e3b3 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Tue, 4 Feb 2025 11:52:37 +0200 Subject: [PATCH 280/580] build: fix passing arguments to build.sh Fixes #583 --- build-go.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build-go.sh b/build-go.sh index faaac6f..eeab2d7 100755 --- a/build-go.sh +++ b/build-go.sh @@ -6,4 +6,4 @@ if [ "$DBG" = 1 ]; then else GO_LDFLAGS="-s -w ${GO_LDFLAGS}" fi -go build -gcflags="$GO_GCFLAGS" -ldflags="$GO_LDFLAGS" -o mautrix-signal ./cmd/mautrix-signal "$@" +go build -gcflags="$GO_GCFLAGS" -ldflags="$GO_LDFLAGS" -o mautrix-signal "$@" ./cmd/mautrix-signal From 5c7cd643faee575612210cca817c0c2ba0f83c59 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Tue, 4 Feb 2025 12:51:01 +0200 Subject: [PATCH 281/580] dependencies: update mautrix-go --- go.mod | 6 +++--- go.sum | 12 ++++++------ 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/go.mod b/go.mod index 93db751..238c27e 100644 --- a/go.mod +++ b/go.mod @@ -13,12 +13,12 @@ require ( github.com/rs/zerolog v1.33.0 github.com/stretchr/testify v1.10.0 github.com/tidwall/gjson v1.18.0 - go.mau.fi/util v0.8.4 + go.mau.fi/util v0.8.5-0.20250203220331-1c0d19ea6003 golang.org/x/crypto v0.32.0 - golang.org/x/exp v0.0.0-20250106191152-7588d65b2ba8 + golang.org/x/exp v0.0.0-20250128182459-e0ece0dbea4c golang.org/x/net v0.34.0 google.golang.org/protobuf v1.36.3 - maunium.net/go/mautrix v0.23.1-0.20250123130650-2d79ce4eed56 + maunium.net/go/mautrix v0.23.1-0.20250203222456-475c4bf39d91 ) require ( diff --git a/go.sum b/go.sum index 5eaa1a4..5aaee56 100644 --- a/go.sum +++ b/go.sum @@ -70,14 +70,14 @@ github.com/tidwall/sjson v1.2.5 h1:kLy8mja+1c9jlljvWTlSazM7cKDRfJuR/bOJhcY5NcY= github.com/tidwall/sjson v1.2.5/go.mod h1:Fvgq9kS/6ociJEDnK0Fk1cpYF4FIW6ZF7LAe+6jwd28= github.com/yuin/goldmark v1.7.8 h1:iERMLn0/QJeHFhxSt3p6PeN9mGnvIKSpG9YYorDMnic= github.com/yuin/goldmark v1.7.8/go.mod h1:uzxRWxtg69N339t3louHJ7+O03ezfj6PlliRlaOzY1E= -go.mau.fi/util v0.8.4 h1:mVKlJcXWfVo8ZW3f4vqtjGpqtZqJvX4ETekxawt2vnQ= -go.mau.fi/util v0.8.4/go.mod h1:MOfGTs1CBuK6ERTcSL4lb5YU7/ujz09eOPVEDckuazY= +go.mau.fi/util v0.8.5-0.20250203220331-1c0d19ea6003 h1:ye5l+QpYW5CpGVMedb3EHlmflGMQsMtw8mC4K/U8hIw= +go.mau.fi/util v0.8.5-0.20250203220331-1c0d19ea6003/go.mod h1:MOfGTs1CBuK6ERTcSL4lb5YU7/ujz09eOPVEDckuazY= go.mau.fi/zeroconfig v0.1.3 h1:As9wYDKmktjmNZW5i1vn8zvJlmGKHeVxHVIBMXsm4kM= go.mau.fi/zeroconfig v0.1.3/go.mod h1:NcSJkf180JT+1IId76PcMuLTNa1CzsFFZ0nBygIQM70= golang.org/x/crypto v0.32.0 h1:euUpcYgM8WcP71gNpTqQCn6rC2t6ULUPiOzfWaXVVfc= golang.org/x/crypto v0.32.0/go.mod h1:ZnnJkOaASj8g0AjIduWNlq2NRxL0PlBrbKVyZ6V/Ugc= -golang.org/x/exp v0.0.0-20250106191152-7588d65b2ba8 h1:yqrTHse8TCMW1M1ZCP+VAR/l0kKxwaAIqN/il7x4voA= -golang.org/x/exp v0.0.0-20250106191152-7588d65b2ba8/go.mod h1:tujkw807nyEEAamNbDrEGzRav+ilXA7PCRAd6xsmwiU= +golang.org/x/exp v0.0.0-20250128182459-e0ece0dbea4c h1:KL/ZBHXgKGVmuZBZ01Lt57yE5ws8ZPSkkihmEyq7FXc= +golang.org/x/exp v0.0.0-20250128182459-e0ece0dbea4c/go.mod h1:tujkw807nyEEAamNbDrEGzRav+ilXA7PCRAd6xsmwiU= golang.org/x/net v0.34.0 h1:Mb7Mrk043xzHgnRM88suvJFwzVrRfHEHJEl5/71CKw0= golang.org/x/net v0.34.0/go.mod h1:di0qlW3YNM5oh6GqDGQr92MyTozJPmybPK4Ev/Gm31k= golang.org/x/sync v0.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ= @@ -100,5 +100,5 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= maunium.net/go/mauflag v1.0.0 h1:YiaRc0tEI3toYtJMRIfjP+jklH45uDHtT80nUamyD4M= maunium.net/go/mauflag v1.0.0/go.mod h1:nLivPOpTpHnpzEh8jEdSL9UqO9+/KBJFmNRlwKfkPeA= -maunium.net/go/mautrix v0.23.1-0.20250123130650-2d79ce4eed56 h1:31T/WEOtfzmtF5CD7jeeSys35EZ9jhSkkZ6gB9eOVyU= -maunium.net/go/mautrix v0.23.1-0.20250123130650-2d79ce4eed56/go.mod h1:AGnnaz3ylGikUo1I1MJVn9QLsl2No1/ZNnGDyO0QD5s= +maunium.net/go/mautrix v0.23.1-0.20250203222456-475c4bf39d91 h1:jbga2dSYVTd3MgAKugiz5+mIYp+qxUOCDokUGZOEWRg= +maunium.net/go/mautrix v0.23.1-0.20250203222456-475c4bf39d91/go.mod h1:q2U2IRLSFpglDhIpSjd8TnCNVzBNrUJBD8pmYCGQiwc= From 3d5f873cfca36c5af0e271e70a3e4f24fa502ad3 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Wed, 12 Feb 2025 18:43:57 +0200 Subject: [PATCH 282/580] connector: connect unauthed websocket in background mode --- pkg/connector/client.go | 2 +- pkg/signalmeow/receiving.go | 45 ++++++++++++++++++++++--------------- 2 files changed, 28 insertions(+), 19 deletions(-) diff --git a/pkg/connector/client.go b/pkg/connector/client.go index 2007088..4aebc69 100644 --- a/pkg/connector/client.go +++ b/pkg/connector/client.go @@ -221,7 +221,7 @@ func (s *SignalClient) Connect(ctx context.Context) { func (s *SignalClient) ConnectBackground(ctx context.Context, _ *bridgev2.ConnectBackgroundParams) error { s.queueEmptyWaiter.Clear() - ch, err := s.Client.StartAuthedWS(ctx) + ch, _, err := s.Client.StartWebsockets(ctx) if err != nil { return err } diff --git a/pkg/signalmeow/receiving.go b/pkg/signalmeow/receiving.go index a2aa551..2eb622f 100644 --- a/pkg/signalmeow/receiving.go +++ b/pkg/signalmeow/receiving.go @@ -68,34 +68,43 @@ type SignalConnectionStatus struct { Err error } -func (cli *Client) StartAuthedWS(ctx context.Context) (chan web.SignalWebsocketConnectionStatus, error) { - ctx, cancel := context.WithCancel(ctx) - cli.WSCancel = cancel - authChan, err := cli.connectAuthedWS(ctx, cli.incomingRequestHandler) +func (cli *Client) StartWebsockets(ctx context.Context) (authChan, unauthChan chan web.SignalWebsocketConnectionStatus, err error) { + authChan, unauthChan, _, _, err = cli.startWebsocketsInternal(ctx) + return +} + +func (cli *Client) startWebsocketsInternal( + ctx context.Context, +) ( + authChan, unauthChan chan web.SignalWebsocketConnectionStatus, + cancelCtx context.Context, + cancelFunc context.CancelFunc, + err error, +) { + cancelCtx, cancelFunc = context.WithCancel(ctx) + cli.WSCancel = cancelFunc + unauthChan, err = cli.connectUnauthedWS(cancelCtx) if err != nil { - cancel() - return nil, err + cancelFunc() + return + } + zerolog.Ctx(ctx).Info().Msg("Unauthed websocket connecting") + authChan, err = cli.connectAuthedWS(cancelCtx, cli.incomingRequestHandler) + if err != nil { + cancelFunc() + return } zerolog.Ctx(ctx).Info().Msg("Authed websocket connecting") - return authChan, nil + return } func (cli *Client) StartReceiveLoops(ctx context.Context) (chan SignalConnectionStatus, error) { log := zerolog.Ctx(ctx).With().Str("action", "start receive loops").Logger() - ctx, cancel := context.WithCancel(log.WithContext(ctx)) - cli.WSCancel = cancel - authChan, err := cli.connectAuthedWS(ctx, cli.incomingRequestHandler) + ctx = log.WithContext(ctx) + authChan, unauthChan, ctx, cancel, err := cli.startWebsocketsInternal(log.WithContext(ctx)) if err != nil { - cancel() return nil, err } - log.Info().Msg("Authed websocket connecting") - unauthChan, err := cli.connectUnauthedWS(ctx) - if err != nil { - cancel() - return nil, err - } - log.Info().Msg("Unauthed websocket connecting") statusChan := make(chan SignalConnectionStatus, 10000) initialConnectChan := make(chan struct{}) From 6abb21cfac777426e9d114fdffbdac0d8c1f0245 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Wed, 12 Feb 2025 18:44:14 +0200 Subject: [PATCH 283/580] userinfo: don't fetch info in background mode unless necessary --- pkg/connector/chatinfo.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/pkg/connector/chatinfo.go b/pkg/connector/chatinfo.go index c73b5d5..5b142cf 100644 --- a/pkg/connector/chatinfo.go +++ b/pkg/connector/chatinfo.go @@ -46,6 +46,10 @@ func (s *SignalClient) GetUserInfo(ctx context.Context, ghost *bridgev2.Ghost) ( if err != nil { return nil, err } + if ghost.Name != "" && s.Main.Bridge.Background { + // Don't do unnecessary fetches in background mode + return nil, nil + } contact, err := s.Client.ContactByACI(ctx, userID) if err != nil { return nil, err From 36f25e257d38d22560bdabad291cbef731cf0a13 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Wed, 12 Feb 2025 13:50:14 +0200 Subject: [PATCH 284/580] libsignal: update to v0.66.1 --- CHANGELOG.md | 2 +- pkg/libsignalgo/libsignal | 2 +- pkg/libsignalgo/libsignal-ffi.h | 115 ++++++-------------------------- pkg/libsignalgo/version.go | 2 +- 4 files changed, 23 insertions(+), 98 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 435e8be..a2bf687 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,7 +1,7 @@ # v0.8.0 (unreleased) * Added support for history transfer. -* Updated libsignal to v0.65.4. +* Updated libsignal to v0.66.1. # v0.7.5 (2025-01-16) diff --git a/pkg/libsignalgo/libsignal b/pkg/libsignalgo/libsignal index 4da852b..c1ba7d5 160000 --- a/pkg/libsignalgo/libsignal +++ b/pkg/libsignalgo/libsignal @@ -1 +1 @@ -Subproject commit 4da852be7529372a53123a0a097ed6f252961fce +Subproject commit c1ba7d54f16ddcf9b49ddcf2bde7e7419be8ab32 diff --git a/pkg/libsignalgo/libsignal-ffi.h b/pkg/libsignalgo/libsignal-ffi.h index 457d343..b2627d8 100644 --- a/pkg/libsignalgo/libsignal-ffi.h +++ b/pkg/libsignalgo/libsignal-ffi.h @@ -228,10 +228,6 @@ typedef struct SignalAuthenticatedChatConnection SignalAuthenticatedChatConnecti typedef struct SignalCdsiLookup SignalCdsiLookup; -typedef struct SignalChatAuthChatService SignalChatAuthChatService; - -typedef struct SignalChatUnauthChatService SignalChatUnauthChatService; - typedef struct SignalCiphertextMessage SignalCiphertextMessage; /** @@ -241,6 +237,8 @@ typedef struct SignalConnectionInfo SignalConnectionInfo; typedef struct SignalConnectionManager SignalConnectionManager; +typedef struct SignalConnectionProxyConfig SignalConnectionProxyConfig; + typedef struct SignalDecryptionErrorMessage SignalDecryptionErrorMessage; typedef struct SignalFingerprint SignalFingerprint; @@ -789,6 +787,14 @@ typedef struct { SignalConnectionInfo *raw; } SignalMutPointerConnectionInfo; +typedef struct { + SignalConnectionProxyConfig *raw; +} SignalMutPointerConnectionProxyConfig; + +typedef struct { + const SignalConnectionProxyConfig *raw; +} SignalConstPointerConnectionProxyConfig; + typedef struct { SignalConnectionManager *raw; } SignalMutPointerConnectionManager; @@ -854,18 +860,6 @@ typedef struct { SignalCancellationId cancellation_id; } SignalCPromiseFfiCdsiLookupResponse; -typedef SignalChatAuthChatService SignalAuthChat; - -typedef struct { - SignalAuthChat *raw; -} SignalMutPointerAuthChat; - -typedef SignalChatUnauthChatService SignalUnauthChat; - -typedef struct { - SignalUnauthChat *raw; -} SignalMutPointerUnauthChat; - typedef struct { SignalHttpRequest *raw; } SignalMutPointerHttpRequest; @@ -1002,55 +996,6 @@ typedef struct { const SignalAuthenticatedChatConnection *raw; } SignalConstPointerAuthenticatedChatConnection; -typedef struct { - const SignalUnauthChat *raw; -} SignalConstPointerUnauthChat; - -typedef struct { - const SignalAuthChat *raw; -} SignalConstPointerAuthChat; - -typedef struct { - uint8_t raw_ip_type; - double duration_secs; - const char *connection_info; -} SignalFfiChatServiceDebugInfo; - -/** - * A C callback used to report the results of Rust futures. - * - * cbindgen will produce independent C types like `SignalCPromisei32` and - * `SignalCPromiseProtocolAddress`. - * - * This derives Copy because it behaves like a C type; nevertheless, a promise should still only be - * completed once. - */ -typedef struct { - void (*complete)(SignalFfiError *error, const SignalFfiChatServiceDebugInfo *result, const void *context); - const void *context; - SignalCancellationId cancellation_id; -} SignalCPromiseFfiChatServiceDebugInfo; - -typedef struct { - SignalFfiChatResponse response; - SignalFfiChatServiceDebugInfo debug_info; -} SignalFfiResponseAndDebugInfo; - -/** - * A C callback used to report the results of Rust futures. - * - * cbindgen will produce independent C types like `SignalCPromisei32` and - * `SignalCPromiseProtocolAddress`. - * - * This derives Copy because it behaves like a C type; nevertheless, a promise should still only be - * completed once. - */ -typedef struct { - void (*complete)(SignalFfiError *error, const SignalFfiResponseAndDebugInfo *result, const void *context); - const void *context; - SignalCancellationId cancellation_id; -} SignalCPromiseFfiResponseAndDebugInfo; - typedef struct { SignalServerMessageAck *raw; } SignalMutPointerServerMessageAck; @@ -1905,11 +1850,19 @@ SignalFfiError *signal_group_send_full_token_verify(SignalBorrowedBuffer token, SignalFfiError *signal_connection_info_destroy(SignalMutPointerConnectionInfo p); +SignalFfiError *signal_connection_proxy_config_destroy(SignalMutPointerConnectionProxyConfig p); + +SignalFfiError *signal_connection_proxy_config_clone(SignalMutPointerConnectionProxyConfig *new_obj, SignalConstPointerConnectionProxyConfig obj); + +SignalFfiError *signal_connection_proxy_config_new(SignalMutPointerConnectionProxyConfig *out, const char *scheme, const char *host, int32_t port, const char *username, const char *password); + SignalFfiError *signal_connection_manager_destroy(SignalMutPointerConnectionManager p); SignalFfiError *signal_connection_manager_new(SignalMutPointerConnectionManager *out, uint8_t environment, const char *user_agent); -SignalFfiError *signal_connection_manager_set_proxy(SignalConstPointerConnectionManager connection_manager, const char *host, int32_t port); +SignalFfiError *signal_connection_manager_set_proxy(SignalConstPointerConnectionManager connection_manager, SignalConstPointerConnectionProxyConfig proxy); + +SignalFfiError *signal_connection_manager_set_invalid_proxy(SignalConstPointerConnectionManager connection_manager); SignalFfiError *signal_connection_manager_clear_proxy(SignalConstPointerConnectionManager connection_manager); @@ -1941,10 +1894,6 @@ SignalFfiError *signal_cdsi_lookup_token(SignalOwnedBuffer *out, SignalConstPoin SignalFfiError *signal_cdsi_lookup_complete(SignalCPromiseFfiCdsiLookupResponse *promise, SignalConstPointerTokioAsyncContext async_runtime, SignalConstPointerCdsiLookup lookup); -SignalFfiError *signal_auth_chat_destroy(SignalMutPointerAuthChat p); - -SignalFfiError *signal_unauth_chat_destroy(SignalMutPointerUnauthChat p); - SignalFfiError *signal_http_request_destroy(SignalMutPointerHttpRequest p); SignalFfiError *signal_unauthenticated_chat_connection_destroy(SignalMutPointerUnauthenticatedChatConnection p); @@ -1963,10 +1912,6 @@ SignalFfiError *signal_chat_connection_info_ip_version(uint8_t *out, SignalConst SignalFfiError *signal_chat_connection_info_description(const char **out, SignalConstPointerChatConnectionInfo connection_info); -SignalFfiError *signal_chat_service_new_unauth(SignalMutPointerUnauthChat *out, SignalConstPointerConnectionManager connection_manager); - -SignalFfiError *signal_chat_service_new_auth(SignalMutPointerAuthChat *out, SignalConstPointerConnectionManager connection_manager, const char *username, const char *password, bool receive_stories); - SignalFfiError *signal_unauthenticated_chat_connection_connect(SignalCPromiseMutPointerUnauthenticatedChatConnection *promise, SignalConstPointerTokioAsyncContext async_runtime, SignalConstPointerConnectionManager connection_manager); SignalFfiError *signal_unauthenticated_chat_connection_init_listener(SignalConstPointerUnauthenticatedChatConnection chat, SignalConstPointerFfiChatListenerStruct listener); @@ -1987,26 +1932,6 @@ SignalFfiError *signal_authenticated_chat_connection_disconnect(SignalCPromisebo SignalFfiError *signal_authenticated_chat_connection_info(SignalMutPointerChatConnectionInfo *out, SignalConstPointerAuthenticatedChatConnection chat); -SignalFfiError *signal_chat_service_disconnect_unauth(SignalCPromisebool *promise, SignalConstPointerTokioAsyncContext async_runtime, SignalConstPointerUnauthChat chat); - -SignalFfiError *signal_chat_service_disconnect_auth(SignalCPromisebool *promise, SignalConstPointerTokioAsyncContext async_runtime, SignalConstPointerAuthChat chat); - -SignalFfiError *signal_chat_service_connect_unauth(SignalCPromiseFfiChatServiceDebugInfo *promise, SignalConstPointerTokioAsyncContext async_runtime, SignalConstPointerUnauthChat chat); - -SignalFfiError *signal_chat_service_connect_auth(SignalCPromiseFfiChatServiceDebugInfo *promise, SignalConstPointerTokioAsyncContext async_runtime, SignalConstPointerAuthChat chat); - -SignalFfiError *signal_chat_service_unauth_send(SignalCPromiseFfiChatResponse *promise, SignalConstPointerTokioAsyncContext async_runtime, SignalConstPointerUnauthChat chat, SignalConstPointerHttpRequest http_request, uint32_t timeout_millis); - -SignalFfiError *signal_chat_service_unauth_send_and_debug(SignalCPromiseFfiResponseAndDebugInfo *promise, SignalConstPointerTokioAsyncContext async_runtime, SignalConstPointerUnauthChat chat, SignalConstPointerHttpRequest http_request, uint32_t timeout_millis); - -SignalFfiError *signal_chat_service_auth_send(SignalCPromiseFfiChatResponse *promise, SignalConstPointerTokioAsyncContext async_runtime, SignalConstPointerAuthChat chat, SignalConstPointerHttpRequest http_request, uint32_t timeout_millis); - -SignalFfiError *signal_chat_service_auth_send_and_debug(SignalCPromiseFfiResponseAndDebugInfo *promise, SignalConstPointerTokioAsyncContext async_runtime, SignalConstPointerAuthChat chat, SignalConstPointerHttpRequest http_request, uint32_t timeout_millis); - -SignalFfiError *signal_chat_service_set_listener_auth(SignalConstPointerTokioAsyncContext runtime, SignalConstPointerAuthChat chat, SignalConstPointerFfiChatListenerStruct listener); - -SignalFfiError *signal_chat_service_set_listener_unauth(SignalConstPointerTokioAsyncContext runtime, SignalConstPointerUnauthChat chat, SignalConstPointerFfiChatListenerStruct listener); - SignalFfiError *signal_server_message_ack_destroy(SignalMutPointerServerMessageAck p); SignalFfiError *signal_server_message_ack_send(SignalCPromisebool *promise, SignalConstPointerTokioAsyncContext async_runtime, SignalConstPointerServerMessageAck ack); @@ -2103,7 +2028,7 @@ SignalFfiError *signal_online_backup_validator_finalize(SignalMutPointerOnlineBa SignalFfiError *signal_username_hash(uint8_t (*out)[32], const char *username); -SignalFfiError *signal_username_proof(SignalOwnedBuffer *out, const char *username, SignalBorrowedBuffer randomness); +SignalFfiError *signal_username_proof(SignalOwnedBuffer *out, const char *username, const uint8_t (*randomness)[32]); SignalFfiError *signal_username_verify(SignalBorrowedBuffer proof, SignalBorrowedBuffer hash); diff --git a/pkg/libsignalgo/version.go b/pkg/libsignalgo/version.go index 8a399dd..219f19f 100644 --- a/pkg/libsignalgo/version.go +++ b/pkg/libsignalgo/version.go @@ -2,4 +2,4 @@ package libsignalgo -const Version = "v0.65.4" +const Version = "v0.66.1" From 50b9a51c1efcaf38a263cc48957b8eefdfa1dd9c Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Wed, 12 Feb 2025 13:51:43 +0200 Subject: [PATCH 285/580] dependencies: update go --- .github/workflows/go.yml | 8 ++++---- CHANGELOG.md | 1 + go.mod | 4 ++-- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml index c2496f6..5d8ebfa 100644 --- a/.github/workflows/go.yml +++ b/.github/workflows/go.yml @@ -11,8 +11,8 @@ jobs: strategy: fail-fast: false matrix: - go-version: ["1.22", "1.23"] - name: Lint ${{ matrix.go-version == '1.23' && '(latest)' || '(old)' }} + go-version: ["1.23", "1.24"] + name: Lint ${{ matrix.go-version == '1.24' && '(latest)' || '(old)' }} steps: - uses: actions/checkout@v4 @@ -40,8 +40,8 @@ jobs: strategy: fail-fast: false matrix: - go-version: ["1.22", "1.23"] - name: Test ${{ matrix.go-version == '1.23' && '(latest)' || '(old)' }} + go-version: ["1.23", "1.24"] + name: Test ${{ matrix.go-version == '1.24' && '(latest)' || '(old)' }} steps: - uses: actions/checkout@v4 diff --git a/CHANGELOG.md b/CHANGELOG.md index a2bf687..8c90bcd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,6 @@ # v0.8.0 (unreleased) +* Bumped minimum Go version to 1.23. * Added support for history transfer. * Updated libsignal to v0.66.1. diff --git a/go.mod b/go.mod index 238c27e..50527e5 100644 --- a/go.mod +++ b/go.mod @@ -1,8 +1,8 @@ module go.mau.fi/mautrix-signal -go 1.22.0 +go 1.23.0 -toolchain go1.23.5 +toolchain go1.24.0 require ( github.com/coder/websocket v1.8.12 From 79776c13bc90cfa0f5ff402b064ce6e439533bb9 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Thu, 13 Feb 2025 14:59:44 +0200 Subject: [PATCH 286/580] signalmeow/store: fix missing columns in signalmeow_backup_chat table --- pkg/signalmeow/store/upgrades/00-latest.sql | 5 ++- .../upgrades/20-fix-backup-chat-columns.go | 36 +++++++++++++++++++ 2 files changed, 40 insertions(+), 1 deletion(-) create mode 100644 pkg/signalmeow/store/upgrades/20-fix-backup-chat-columns.go diff --git a/pkg/signalmeow/store/upgrades/00-latest.sql b/pkg/signalmeow/store/upgrades/00-latest.sql index 23c3762..670f0e0 100644 --- a/pkg/signalmeow/store/upgrades/00-latest.sql +++ b/pkg/signalmeow/store/upgrades/00-latest.sql @@ -1,4 +1,4 @@ --- v0 -> v19 (compatible with v13+): Latest revision +-- v0 -> v20 (compatible with v13+): Latest revision CREATE TABLE signalmeow_device ( aci_uuid TEXT PRIMARY KEY, @@ -136,6 +136,9 @@ CREATE TABLE signalmeow_backup_chat ( recipient_id BIGINT NOT NULL, data bytea NOT NULL, + latest_message_id BIGINT, + total_message_count INTEGER, + PRIMARY KEY (account_id, chat_id), CONSTRAINT signalmeow_backup_chat_device_fkey FOREIGN KEY (account_id) REFERENCES signalmeow_device (aci_uuid) ON DELETE CASCADE ON UPDATE CASCADE, diff --git a/pkg/signalmeow/store/upgrades/20-fix-backup-chat-columns.go b/pkg/signalmeow/store/upgrades/20-fix-backup-chat-columns.go new file mode 100644 index 0000000..d409fe6 --- /dev/null +++ b/pkg/signalmeow/store/upgrades/20-fix-backup-chat-columns.go @@ -0,0 +1,36 @@ +// mautrix-signal - A Matrix-signal puppeting bridge. +// Copyright (C) 2025 Tulir Asokan +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +package upgrades + +import ( + "context" + + "go.mau.fi/util/dbutil" +) + +func init() { + Table.Register(-1, 20, 13, "Add missing columns for backup chat table", dbutil.TxnModeOn, func(ctx context.Context, db *dbutil.Database) (err error) { + var exists bool + if exists, err = db.ColumnExists(ctx, "signalmeow_backup_chat", "latest_message_id"); err == nil && !exists { + _, err = db.Exec(ctx, ` + ALTER TABLE signalmeow_backup_chat ADD COLUMN latest_message_id BIGINT; + ALTER TABLE signalmeow_backup_chat ADD COLUMN total_message_count INTEGER; + `) + } + return + }) +} From daadb450e3af60c9ad9187e7cd018a5a47ed8035 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Thu, 13 Feb 2025 15:28:32 +0200 Subject: [PATCH 287/580] ci: disable gotestfmt It doesn't like build warnings in Go 1.24's new json format --- .github/workflows/go.yml | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml index 5d8ebfa..6bbfaef 100644 --- a/.github/workflows/go.yml +++ b/.github/workflows/go.yml @@ -52,10 +52,10 @@ jobs: go-version: ${{ matrix.go-version }} cache: true - - name: Set up gotestfmt - uses: GoTestTools/gotestfmt-action@v2 - with: - token: ${{ secrets.GITHUB_TOKEN }} + #- name: Set up gotestfmt + # uses: GoTestTools/gotestfmt-action@v2 + # with: + # token: ${{ secrets.GITHUB_TOKEN }} - name: Install libolm run: sudo apt-get install libolm-dev @@ -68,4 +68,5 @@ jobs: run: | set -euo pipefail export LIBRARY_PATH=. - go test -v -json ./... -cover | gotestfmt + #go test -v -json ./... -cover | gotestfmt + go test ./... From 8c22feeb53c1c777c31e08eb5ade803dbbf2a517 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Sun, 16 Feb 2025 17:23:04 +0200 Subject: [PATCH 288/580] dependencies: update --- go.mod | 20 ++++++++++---------- go.sum | 40 ++++++++++++++++++++-------------------- 2 files changed, 30 insertions(+), 30 deletions(-) diff --git a/go.mod b/go.mod index 50527e5..ae5a99e 100644 --- a/go.mod +++ b/go.mod @@ -13,12 +13,12 @@ require ( github.com/rs/zerolog v1.33.0 github.com/stretchr/testify v1.10.0 github.com/tidwall/gjson v1.18.0 - go.mau.fi/util v0.8.5-0.20250203220331-1c0d19ea6003 - golang.org/x/crypto v0.32.0 - golang.org/x/exp v0.0.0-20250128182459-e0ece0dbea4c - golang.org/x/net v0.34.0 - google.golang.org/protobuf v1.36.3 - maunium.net/go/mautrix v0.23.1-0.20250203222456-475c4bf39d91 + go.mau.fi/util v0.8.5 + golang.org/x/crypto v0.33.0 + golang.org/x/exp v0.0.0-20250215185904-eff6e970281f + golang.org/x/net v0.35.0 + google.golang.org/protobuf v1.36.5 + maunium.net/go/mautrix v0.23.1 ) require ( @@ -31,7 +31,7 @@ require ( github.com/mattn/go-colorable v0.1.14 // indirect github.com/mattn/go-isatty v0.0.20 // indirect github.com/mattn/go-sqlite3 v1.14.24 // indirect - github.com/petermattis/goid v0.0.0-20241211131331-93ee7e083c43 // indirect + github.com/petermattis/goid v0.0.0-20250211185408-f2b9d978cd7a // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/rogpeppe/go-internal v1.10.0 // indirect github.com/rs/xid v1.6.0 // indirect @@ -41,9 +41,9 @@ require ( github.com/tidwall/sjson v1.2.5 // indirect github.com/yuin/goldmark v1.7.8 // indirect go.mau.fi/zeroconfig v0.1.3 // indirect - golang.org/x/sync v0.10.0 // indirect - golang.org/x/sys v0.29.0 // indirect - golang.org/x/text v0.21.0 // indirect + golang.org/x/sync v0.11.0 // indirect + golang.org/x/sys v0.30.0 // indirect + golang.org/x/text v0.22.0 // indirect gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect gopkg.in/natefinch/lumberjack.v2 v2.2.1 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect diff --git a/go.sum b/go.sum index 5aaee56..8ffc192 100644 --- a/go.sum +++ b/go.sum @@ -40,8 +40,8 @@ github.com/mattn/go-pointer v0.0.1 h1:n+XhsuGeVO6MEAp7xyEukFINEa+Quek5psIR/ylA6o github.com/mattn/go-pointer v0.0.1/go.mod h1:2zXcozF6qYGgmsG+SeTZz3oAbFLdD3OWqnUbNvJZAlc= github.com/mattn/go-sqlite3 v1.14.24 h1:tpSp2G2KyMnnQu99ngJ47EIkWVmliIizyZBfPrBWDRM= github.com/mattn/go-sqlite3 v1.14.24/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y= -github.com/petermattis/goid v0.0.0-20241211131331-93ee7e083c43 h1:ah1dvbqPMN5+ocrg/ZSgZ6k8bOk+kcZQ7fnyx6UvOm4= -github.com/petermattis/goid v0.0.0-20241211131331-93ee7e083c43/go.mod h1:pxMtw7cyUw6B2bRH0ZBANSPg+AoSud1I1iyJHI69jH4= +github.com/petermattis/goid v0.0.0-20250211185408-f2b9d978cd7a h1:ckxP/kGzsxvxXo8jO6E/0QJ8MMmwI7IRj4Fys9QbAZA= +github.com/petermattis/goid v0.0.0-20250211185408-f2b9d978cd7a/go.mod h1:pxMtw7cyUw6B2bRH0ZBANSPg+AoSud1I1iyJHI69jH4= github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= @@ -70,27 +70,27 @@ github.com/tidwall/sjson v1.2.5 h1:kLy8mja+1c9jlljvWTlSazM7cKDRfJuR/bOJhcY5NcY= github.com/tidwall/sjson v1.2.5/go.mod h1:Fvgq9kS/6ociJEDnK0Fk1cpYF4FIW6ZF7LAe+6jwd28= github.com/yuin/goldmark v1.7.8 h1:iERMLn0/QJeHFhxSt3p6PeN9mGnvIKSpG9YYorDMnic= github.com/yuin/goldmark v1.7.8/go.mod h1:uzxRWxtg69N339t3louHJ7+O03ezfj6PlliRlaOzY1E= -go.mau.fi/util v0.8.5-0.20250203220331-1c0d19ea6003 h1:ye5l+QpYW5CpGVMedb3EHlmflGMQsMtw8mC4K/U8hIw= -go.mau.fi/util v0.8.5-0.20250203220331-1c0d19ea6003/go.mod h1:MOfGTs1CBuK6ERTcSL4lb5YU7/ujz09eOPVEDckuazY= +go.mau.fi/util v0.8.5 h1:PwCAAtcfK0XxZ4sdErJyfBMkTEWoQU33aB7QqDDzQRI= +go.mau.fi/util v0.8.5/go.mod h1:Ycug9mrbztlahHPEJ6H5r8Nu/xqZaWbE5vPHVWmfz6M= go.mau.fi/zeroconfig v0.1.3 h1:As9wYDKmktjmNZW5i1vn8zvJlmGKHeVxHVIBMXsm4kM= go.mau.fi/zeroconfig v0.1.3/go.mod h1:NcSJkf180JT+1IId76PcMuLTNa1CzsFFZ0nBygIQM70= -golang.org/x/crypto v0.32.0 h1:euUpcYgM8WcP71gNpTqQCn6rC2t6ULUPiOzfWaXVVfc= -golang.org/x/crypto v0.32.0/go.mod h1:ZnnJkOaASj8g0AjIduWNlq2NRxL0PlBrbKVyZ6V/Ugc= -golang.org/x/exp v0.0.0-20250128182459-e0ece0dbea4c h1:KL/ZBHXgKGVmuZBZ01Lt57yE5ws8ZPSkkihmEyq7FXc= -golang.org/x/exp v0.0.0-20250128182459-e0ece0dbea4c/go.mod h1:tujkw807nyEEAamNbDrEGzRav+ilXA7PCRAd6xsmwiU= -golang.org/x/net v0.34.0 h1:Mb7Mrk043xzHgnRM88suvJFwzVrRfHEHJEl5/71CKw0= -golang.org/x/net v0.34.0/go.mod h1:di0qlW3YNM5oh6GqDGQr92MyTozJPmybPK4Ev/Gm31k= -golang.org/x/sync v0.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ= -golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/crypto v0.33.0 h1:IOBPskki6Lysi0lo9qQvbxiQ+FvsCC/YWOecCHAixus= +golang.org/x/crypto v0.33.0/go.mod h1:bVdXmD7IV/4GdElGPozy6U7lWdRXA4qyRVGJV57uQ5M= +golang.org/x/exp v0.0.0-20250215185904-eff6e970281f h1:oFMYAjX0867ZD2jcNiLBrI9BdpmEkvPyi5YrBGXbamg= +golang.org/x/exp v0.0.0-20250215185904-eff6e970281f/go.mod h1:BHOTPb3L19zxehTsLoJXVaTktb06DFgmdW6Wb9s8jqk= +golang.org/x/net v0.35.0 h1:T5GQRQb2y08kTAByq9L4/bz8cipCdA8FbRTXewonqY8= +golang.org/x/net v0.35.0/go.mod h1:EglIi67kWsHKlRzzVMUD93VMSWGFOMSZgxFjparz1Qk= +golang.org/x/sync v0.11.0 h1:GGz8+XQP4FvTTrjZPzNKTMFtSXH80RAzG+5ghFPgK9w= +golang.org/x/sync v0.11.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.29.0 h1:TPYlXGxvx1MGTn2GiZDhnjPA9wZzZeGKHHmKhHYvgaU= -golang.org/x/sys v0.29.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo= -golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= -google.golang.org/protobuf v1.36.3 h1:82DV7MYdb8anAVi3qge1wSnMDrnKK7ebr+I0hHRN1BU= -google.golang.org/protobuf v1.36.3/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= +golang.org/x/sys v0.30.0 h1:QjkSwP/36a20jFYWkSue1YwXzLmsV5Gfq7Eiy72C1uc= +golang.org/x/sys v0.30.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/text v0.22.0 h1:bofq7m3/HAFvbF51jz3Q9wLg3jkvSPuiZu/pD1XwgtM= +golang.org/x/text v0.22.0/go.mod h1:YRoo4H8PVmsu+E3Ou7cqLVH8oXWIHVoX0jqUWALQhfY= +google.golang.org/protobuf v1.36.5 h1:tPhr+woSbjfYvY6/GPufUoYizxw1cF/yFoxJ2fmpwlM= +google.golang.org/protobuf v1.36.5/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= @@ -100,5 +100,5 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= maunium.net/go/mauflag v1.0.0 h1:YiaRc0tEI3toYtJMRIfjP+jklH45uDHtT80nUamyD4M= maunium.net/go/mauflag v1.0.0/go.mod h1:nLivPOpTpHnpzEh8jEdSL9UqO9+/KBJFmNRlwKfkPeA= -maunium.net/go/mautrix v0.23.1-0.20250203222456-475c4bf39d91 h1:jbga2dSYVTd3MgAKugiz5+mIYp+qxUOCDokUGZOEWRg= -maunium.net/go/mautrix v0.23.1-0.20250203222456-475c4bf39d91/go.mod h1:q2U2IRLSFpglDhIpSjd8TnCNVzBNrUJBD8pmYCGQiwc= +maunium.net/go/mautrix v0.23.1 h1:xZtX43YZF3WRxkdR+oMUrpiQe+jbjc+LeXLxHuXP5IM= +maunium.net/go/mautrix v0.23.1/go.mod h1:kldoZQDneV/jquIhwG1MmMw5j2A2M/MnQYRSWt863cY= From 143cd120f54bbd95fc3f01859db03b1a841c3d6c Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Sun, 16 Feb 2025 17:27:27 +0200 Subject: [PATCH 289/580] libsignal: update to v0.66.2 --- CHANGELOG.md | 2 +- pkg/libsignalgo/libsignal | 2 +- pkg/libsignalgo/version.go | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8c90bcd..eb175af 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,7 @@ * Bumped minimum Go version to 1.23. * Added support for history transfer. -* Updated libsignal to v0.66.1. +* Updated libsignal to v0.66.2. # v0.7.5 (2025-01-16) diff --git a/pkg/libsignalgo/libsignal b/pkg/libsignalgo/libsignal index c1ba7d5..525e8bc 160000 --- a/pkg/libsignalgo/libsignal +++ b/pkg/libsignalgo/libsignal @@ -1 +1 @@ -Subproject commit c1ba7d54f16ddcf9b49ddcf2bde7e7419be8ab32 +Subproject commit 525e8bce0c84576014268ab5b3982612b765f598 diff --git a/pkg/libsignalgo/version.go b/pkg/libsignalgo/version.go index 219f19f..1760c96 100644 --- a/pkg/libsignalgo/version.go +++ b/pkg/libsignalgo/version.go @@ -2,4 +2,4 @@ package libsignalgo -const Version = "v0.66.1" +const Version = "v0.66.2" From 2e44f2ca133efcce94ecbfe4c05359bcbb69736b Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Sun, 16 Feb 2025 17:30:24 +0200 Subject: [PATCH 290/580] Bump version to v0.8.0 --- CHANGELOG.md | 2 +- cmd/mautrix-signal/main.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index eb175af..5804dc1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,4 @@ -# v0.8.0 (unreleased) +# v0.8.0 (2025-02-16) * Bumped minimum Go version to 1.23. * Added support for history transfer. diff --git a/cmd/mautrix-signal/main.go b/cmd/mautrix-signal/main.go index 1cd74ce..2cbed46 100644 --- a/cmd/mautrix-signal/main.go +++ b/cmd/mautrix-signal/main.go @@ -38,7 +38,7 @@ var m = mxmain.BridgeMain{ Name: "mautrix-signal", URL: "https://github.com/mautrix/signal", Description: "A Matrix-Signal puppeting bridge.", - Version: "0.7.5", + Version: "0.8.0", Connector: &connector.SignalConnector{}, } From 79985bffa9fc291569147726d59913d331274c85 Mon Sep 17 00:00:00 2001 From: Scott Weber Date: Tue, 18 Feb 2025 10:42:12 -0500 Subject: [PATCH 291/580] login: open new WS and refresh QR code after 45s (#585) --- pkg/connector/login.go | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/pkg/connector/login.go b/pkg/connector/login.go index 8d30da9..50ba0ae 100644 --- a/pkg/connector/login.go +++ b/pkg/connector/login.go @@ -19,6 +19,7 @@ package connector import ( "context" "fmt" + "time" "github.com/google/uuid" "maunium.net/go/mautrix/bridge/status" @@ -50,6 +51,7 @@ type QRLogin struct { Main *SignalConnector cancelChan context.CancelFunc ProvChan chan signalmeow.ProvisioningResponse + newQRCount int ProvData *store.DeviceData } @@ -139,6 +141,17 @@ func (qr *QRLogin) qrWait(ctx context.Context) (*bridgev2.LoginStep, error) { Type: bridgev2.LoginDisplayTypeNothing, }, }, nil + + // Server will timeout the request after 60 seconds, but Signal Desktop opens + // a new socket and gets a new QR code after 45 seconds. We should do the same. + case <-time.After(45 * time.Second): + qr.cancelChan() + qr.newQRCount++ + if qr.newQRCount >= 6 { + return nil, fmt.Errorf("too many QR code refreshes") + } + return qr.Start(ctx) + case <-ctx.Done(): qr.cancelChan() return nil, ctx.Err() From 6e22103e1c1d3653a29f02d468f2ddadcf968c0b Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Sat, 22 Feb 2025 23:47:24 +0200 Subject: [PATCH 292/580] dependencies: update mautrix-go --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index ae5a99e..e5ba156 100644 --- a/go.mod +++ b/go.mod @@ -18,7 +18,7 @@ require ( golang.org/x/exp v0.0.0-20250215185904-eff6e970281f golang.org/x/net v0.35.0 google.golang.org/protobuf v1.36.5 - maunium.net/go/mautrix v0.23.1 + maunium.net/go/mautrix v0.23.2-0.20250224184759-0115ba0258cb ) require ( diff --git a/go.sum b/go.sum index 8ffc192..bcd6305 100644 --- a/go.sum +++ b/go.sum @@ -100,5 +100,5 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= maunium.net/go/mauflag v1.0.0 h1:YiaRc0tEI3toYtJMRIfjP+jklH45uDHtT80nUamyD4M= maunium.net/go/mauflag v1.0.0/go.mod h1:nLivPOpTpHnpzEh8jEdSL9UqO9+/KBJFmNRlwKfkPeA= -maunium.net/go/mautrix v0.23.1 h1:xZtX43YZF3WRxkdR+oMUrpiQe+jbjc+LeXLxHuXP5IM= -maunium.net/go/mautrix v0.23.1/go.mod h1:kldoZQDneV/jquIhwG1MmMw5j2A2M/MnQYRSWt863cY= +maunium.net/go/mautrix v0.23.2-0.20250224184759-0115ba0258cb h1:neXlaiDrKjZsLmNm+ufCQGuEB050TKWVi7w9Qta+lFM= +maunium.net/go/mautrix v0.23.2-0.20250224184759-0115ba0258cb/go.mod h1:kldoZQDneV/jquIhwG1MmMw5j2A2M/MnQYRSWt863cY= From 272f38297ff3ba6fef89d9756c1e15fc13bc91c7 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Tue, 25 Feb 2025 18:22:24 +0200 Subject: [PATCH 293/580] libsignal: update to v0.67.0 --- pkg/libsignalgo/libsignal | 2 +- pkg/libsignalgo/libsignal-ffi.h | 6 ++++-- pkg/libsignalgo/version.go | 2 +- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/pkg/libsignalgo/libsignal b/pkg/libsignalgo/libsignal index 525e8bc..865d879 160000 --- a/pkg/libsignalgo/libsignal +++ b/pkg/libsignalgo/libsignal @@ -1 +1 @@ -Subproject commit 525e8bce0c84576014268ab5b3982612b765f598 +Subproject commit 865d879ec91396abf3c34f78cd7416708591c6ae diff --git a/pkg/libsignalgo/libsignal-ffi.h b/pkg/libsignalgo/libsignal-ffi.h index b2627d8..860963e 100644 --- a/pkg/libsignalgo/libsignal-ffi.h +++ b/pkg/libsignalgo/libsignal-ffi.h @@ -204,7 +204,7 @@ typedef enum { SignalErrorCodeCdsiInvalidToken = 147, SignalErrorCodeConnectionFailed = 148, SignalErrorCodeChatServiceInactive = 149, - SignalErrorCodeChatServiceIntentionallyDisconnected = 150, + SignalErrorCodeRequestTimedOut = 150, SignalErrorCodeSvrDataMissing = 160, SignalErrorCodeSvrRestoreFailed = 161, SignalErrorCodeSvrRotationMachineTooManySteps = 162, @@ -1890,6 +1890,8 @@ SignalFfiError *signal_cdsi_lookup_destroy(SignalMutPointerCdsiLookup p); SignalFfiError *signal_cdsi_lookup_new(SignalCPromiseMutPointerCdsiLookup *promise, SignalConstPointerTokioAsyncContext async_runtime, SignalConstPointerConnectionManager connection_manager, const char *username, const char *password, SignalConstPointerLookupRequest request); +SignalFfiError *signal_cdsi_lookup_new_routes(SignalCPromiseMutPointerCdsiLookup *promise, SignalConstPointerTokioAsyncContext async_runtime, SignalConstPointerConnectionManager connection_manager, const char *username, const char *password, SignalConstPointerLookupRequest request); + SignalFfiError *signal_cdsi_lookup_token(SignalOwnedBuffer *out, SignalConstPointerCdsiLookup lookup); SignalFfiError *signal_cdsi_lookup_complete(SignalCPromiseFfiCdsiLookupResponse *promise, SignalConstPointerTokioAsyncContext async_runtime, SignalConstPointerCdsiLookup lookup); @@ -1934,7 +1936,7 @@ SignalFfiError *signal_authenticated_chat_connection_info(SignalMutPointerChatCo SignalFfiError *signal_server_message_ack_destroy(SignalMutPointerServerMessageAck p); -SignalFfiError *signal_server_message_ack_send(SignalCPromisebool *promise, SignalConstPointerTokioAsyncContext async_runtime, SignalConstPointerServerMessageAck ack); +SignalFfiError *signal_server_message_ack_send(SignalConstPointerServerMessageAck ack); SignalFfiError *signal_tokio_async_context_destroy(SignalMutPointerTokioAsyncContext p); diff --git a/pkg/libsignalgo/version.go b/pkg/libsignalgo/version.go index 1760c96..aa85777 100644 --- a/pkg/libsignalgo/version.go +++ b/pkg/libsignalgo/version.go @@ -2,4 +2,4 @@ package libsignalgo -const Version = "v0.66.2" +const Version = "v0.67.0" From 4713ddfcd1c421234572a00b2f271704f3787fff Mon Sep 17 00:00:00 2001 From: Nick Mills-Barrett Date: Fri, 21 Feb 2025 11:57:01 +0000 Subject: [PATCH 294/580] signalmeow: block until stop completes Currently the disconnect/stop bridge call will complete before all the loops have returned. This switches them all to use a shared cancelable context and wait group to block on stop until all loops exit. --- pkg/signalmeow/client.go | 4 +- pkg/signalmeow/keys.go | 81 ++++++++++++++++++------------------- pkg/signalmeow/receiving.go | 44 +++++++++++--------- 3 files changed, 69 insertions(+), 60 deletions(-) diff --git a/pkg/signalmeow/client.go b/pkg/signalmeow/client.go index 7ef1abb..e5e4c88 100644 --- a/pkg/signalmeow/client.go +++ b/pkg/signalmeow/client.go @@ -48,9 +48,11 @@ type Client struct { AuthedWS *web.SignalWebsocket UnauthedWS *web.SignalWebsocket - WSCancel context.CancelFunc lastConnectionStatus SignalConnectionStatus + loopCancel context.CancelFunc + loopWg sync.WaitGroup + EventHandler func(events.SignalEvent) storageAuthLock sync.Mutex diff --git a/pkg/signalmeow/keys.go b/pkg/signalmeow/keys.go index ad717ac..bc86789 100644 --- a/pkg/signalmeow/keys.go +++ b/pkg/signalmeow/keys.go @@ -599,49 +599,48 @@ func (cli *Client) CheckAndUploadNewPreKeys(ctx context.Context, pks store.PreKe return nil } -func (cli *Client) StartKeyCheckLoop(ctx context.Context) { +func (cli *Client) keyCheckLoop(ctx context.Context) { log := zerolog.Ctx(ctx).With().Str("action", "start key check loop").Logger() - go func() { - // Do the initial check in 5-10 minutes after starting the loop - window_start := 0 - window_size := 1 - for { - random_minutes_in_window := rand.Intn(window_size) + window_start - check_time := time.Duration(random_minutes_in_window) * time.Minute - log.Debug().Dur("check_time", check_time).Msg("Waiting to check for new prekeys") - select { - case <-ctx.Done(): - return - case <-time.After(check_time): - err := cli.CheckAndUploadNewPreKeys(ctx, cli.Store.ACIPreKeyStore) - if err != nil { - log.Err(err).Msg("Error checking and uploading new prekeys for ACI identity") - // Retry within half an hour - window_start = 5 - window_size = 25 - continue - } - err = cli.CheckAndUploadNewPreKeys(ctx, cli.Store.PNIPreKeyStore) - if err != nil { - if errors.Is(err, errPrekeyUpload422) { - log.Err(err).Msg("Got 422 error while uploading PNI prekeys, deleting session") - disconnectErr := cli.ClearKeysAndDisconnect(ctx) - if disconnectErr != nil { - log.Err(disconnectErr).Msg("ClearKeysAndDisconnect error") - } - return - } - log.Err(err).Msg("Error checking and uploading new prekeys for PNI identity") - // Retry within half an hour - window_start = 5 - window_size = 25 - continue - } - // After a successful check, check again in 36 to 60 hours - window_start = 36 * 60 - window_size = 24 * 60 + // Do the initial check in 5-10 minutes after starting the loop + window_start := 0 + window_size := 1 + for { + random_minutes_in_window := rand.Intn(window_size) + window_start + check_time := time.Duration(random_minutes_in_window) * time.Minute + log.Debug().Dur("check_time", check_time).Msg("Waiting to check for new prekeys") + + select { + case <-ctx.Done(): + return + case <-time.After(check_time): + err := cli.CheckAndUploadNewPreKeys(ctx, cli.Store.ACIPreKeyStore) + if err != nil { + log.Err(err).Msg("Error checking and uploading new prekeys for ACI identity") + // Retry within half an hour + window_start = 5 + window_size = 25 + continue } + err = cli.CheckAndUploadNewPreKeys(ctx, cli.Store.PNIPreKeyStore) + if err != nil { + if errors.Is(err, errPrekeyUpload422) { + log.Err(err).Msg("Got 422 error while uploading PNI prekeys, deleting session") + disconnectErr := cli.ClearKeysAndDisconnect(ctx) + if disconnectErr != nil { + log.Err(disconnectErr).Msg("ClearKeysAndDisconnect error") + } + return + } + log.Err(err).Msg("Error checking and uploading new prekeys for PNI identity") + // Retry within half an hour + window_start = 5 + window_size = 25 + continue + } + // After a successful check, check again in 36 to 60 hours + window_start = 36 * 60 + window_size = 24 * 60 } - }() + } } diff --git a/pkg/signalmeow/receiving.go b/pkg/signalmeow/receiving.go index 2eb622f..8fa4ffa 100644 --- a/pkg/signalmeow/receiving.go +++ b/pkg/signalmeow/receiving.go @@ -77,31 +77,30 @@ func (cli *Client) startWebsocketsInternal( ctx context.Context, ) ( authChan, unauthChan chan web.SignalWebsocketConnectionStatus, - cancelCtx context.Context, - cancelFunc context.CancelFunc, + loopCtx context.Context, loopCancel context.CancelFunc, err error, ) { - cancelCtx, cancelFunc = context.WithCancel(ctx) - cli.WSCancel = cancelFunc - unauthChan, err = cli.connectUnauthedWS(cancelCtx) + loopCtx, loopCancel = context.WithCancel(ctx) + unauthChan, err = cli.connectUnauthedWS(loopCtx) if err != nil { - cancelFunc() + loopCancel() return } zerolog.Ctx(ctx).Info().Msg("Unauthed websocket connecting") - authChan, err = cli.connectAuthedWS(cancelCtx, cli.incomingRequestHandler) + authChan, err = cli.connectAuthedWS(loopCtx, cli.incomingRequestHandler) if err != nil { - cancelFunc() + loopCancel() return } zerolog.Ctx(ctx).Info().Msg("Authed websocket connecting") + cli.loopCancel = loopCancel return } func (cli *Client) StartReceiveLoops(ctx context.Context) (chan SignalConnectionStatus, error) { log := zerolog.Ctx(ctx).With().Str("action", "start receive loops").Logger() - ctx = log.WithContext(ctx) - authChan, unauthChan, ctx, cancel, err := cli.startWebsocketsInternal(log.WithContext(ctx)) + + authChan, unauthChan, loopCtx, loopCancel, err := cli.startWebsocketsInternal(log.WithContext(ctx)) if err != nil { return nil, err } @@ -110,13 +109,15 @@ func (cli *Client) StartReceiveLoops(ctx context.Context) (chan SignalConnection initialConnectChan := make(chan struct{}) // Combine both websocket status channels into a single, more generic "Signal" connection status channel + cli.loopWg.Add(1) go func() { + defer cli.loopWg.Done() defer close(statusChan) - defer cancel() + defer loopCancel() var currentStatus, lastAuthStatus, lastUnauthStatus web.SignalWebsocketConnectionStatus for { select { - case <-ctx.Done(): + case <-loopCtx.Done(): log.Info().Msg("Context done, exiting websocket status loop") return case status := <-authChan: @@ -201,19 +202,21 @@ func (cli *Client) StartReceiveLoops(ctx context.Context) (chan SignalConnection }() // Send sync message once both websockets are connected + cli.loopWg.Add(1) go func() { + defer cli.loopWg.Done() for { select { - case <-ctx.Done(): + case <-loopCtx.Done(): return case <-initialConnectChan: log.Info().Msg("Both websockets connected, sending contacts sync request") // TODO hacky if cli.SyncContactsOnConnect { - cli.SendContactSyncRequest(ctx) + cli.SendContactSyncRequest(loopCtx) } if cli.Store.MasterKey == nil { - cli.SendStorageMasterKeyRequest(ctx) + cli.SendStorageMasterKeyRequest(loopCtx) } return } @@ -221,7 +224,11 @@ func (cli *Client) StartReceiveLoops(ctx context.Context) (chan SignalConnection }() // Start loop to check for and upload more prekeys - cli.StartKeyCheckLoop(ctx) + cli.loopWg.Add(1) + go func() { + defer cli.loopWg.Done() + cli.keyCheckLoop(loopCtx) + }() return statusChan, nil } @@ -233,8 +240,9 @@ func (cli *Client) StopReceiveLoops() error { }() authErr := cli.AuthedWS.Close() unauthErr := cli.UnauthedWS.Close() - if cli.WSCancel != nil { - cli.WSCancel() + if cli.loopCancel != nil { + cli.loopCancel() + cli.loopWg.Wait() } if authErr != nil { return authErr From 870f0d152e156cc5dc95abbfb807833ebac31eda Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Wed, 26 Feb 2025 16:47:51 +0200 Subject: [PATCH 295/580] signalmeow: fix propagating errors when disconnected --- pkg/connector/client.go | 1 - pkg/signalmeow/receiving.go | 2 +- pkg/signalmeow/web/signalwebsocket.go | 47 ++++++++------------------- 3 files changed, 14 insertions(+), 36 deletions(-) diff --git a/pkg/connector/client.go b/pkg/connector/client.go index 4aebc69..1bf8742 100644 --- a/pkg/connector/client.go +++ b/pkg/connector/client.go @@ -236,7 +236,6 @@ func (s *SignalClient) ConnectBackground(ctx context.Context, _ *bridgev2.Connec log.Info().Msg("Authed websocket connected") case web.SignalWebsocketConnectionEventDisconnected: log.Err(status.Err).Msg("Authed websocket disconnected") - return fmt.Errorf("authed websocket disconnected: %w", status.Err) case web.SignalWebsocketConnectionEventLoggedOut: log.Err(status.Err).Msg("Authed websocket logged out") return fmt.Errorf("authed websocket logged out: %w", status.Err) diff --git a/pkg/signalmeow/receiving.go b/pkg/signalmeow/receiving.go index 8fa4ffa..f5e2390 100644 --- a/pkg/signalmeow/receiving.go +++ b/pkg/signalmeow/receiving.go @@ -285,7 +285,7 @@ func (cli *Client) incomingRequestHandler(ctx context.Context, req *signalpb.Web if *req.Verb == http.MethodPut && *req.Path == "/api/v1/message" { return cli.incomingAPIMessageHandler(ctx, req) } else if *req.Verb == http.MethodPut && *req.Path == "/api/v1/queue/empty" { - log.Trace().Msg("Received queue empty") + log.Debug().Msg("Received queue empty notice") cli.handleEvent(&events.QueueEmpty{}) } else { log.Warn().Any("req", req).Msg("Unknown websocket request message") diff --git a/pkg/signalmeow/web/signalwebsocket.go b/pkg/signalmeow/web/signalwebsocket.go index c273c31..d837dc7 100644 --- a/pkg/signalmeow/web/signalwebsocket.go +++ b/pkg/signalmeow/web/signalwebsocket.go @@ -195,7 +195,7 @@ func (s *SignalWebsocket) connectLoop( log.Warn().Dur("backoff", backoff).Msg("Failed to connect, waiting to retry...") time.Sleep(backoff) backoff += backoffIncrement - } else if !isFirstConnect && s.basicAuth != nil { + } else if !isFirstConnect && s.basicAuth != nil && ctx.Err() == nil { time.Sleep(initialBackoff) } if ctx.Err() != nil { @@ -331,42 +331,21 @@ func (s *SignalWebsocket) connectLoop( }() // Wait for read or write or ping loop to exit (which means there was an error) - log.Info().Msg("Waiting for read or write loop to exit") - select { - case <-loopCtx.Done(): - log.Info().Msg("received loopCtx done") - if context.Cause(loopCtx) != nil { - err := context.Cause(loopCtx) - if err != nil && err != context.Canceled { - log.Err(err).Msg("loopCtx error") - errorCount++ - } + log.Debug().Msg("Finished preparing connection, waiting for loop context to finish") + <-loopCtx.Done() + ctxCauseErr := context.Cause(loopCtx) + log.Debug().AnErr("ctx_cause_err", ctxCauseErr).Msg("Read or write loop exited") + if ctxCauseErr == nil || errors.Is(ctxCauseErr, context.Canceled) { + s.statusChannel <- SignalWebsocketConnectionStatus{ + Event: SignalWebsocketConnectionEventCleanShutdown, } - if context.Cause(loopCtx) != nil && context.Cause(loopCtx) == context.Canceled { - s.statusChannel <- SignalWebsocketConnectionStatus{ - Event: SignalWebsocketConnectionEventCleanShutdown, - } - } else { - s.statusChannel <- SignalWebsocketConnectionStatus{ - Event: SignalWebsocketConnectionEventDisconnected, - Err: err, - } - } - case <-ctx.Done(): - log.Info().AnErr("ctx_err", ctx.Err()).AnErr("ctx_cause", context.Cause(ctx)).Msg("received ctx done") - if context.Cause(ctx) != nil && context.Cause(ctx) == context.Canceled { - s.statusChannel <- SignalWebsocketConnectionStatus{ - Event: SignalWebsocketConnectionEventCleanShutdown, - } - return - } else { - s.statusChannel <- SignalWebsocketConnectionStatus{ - Event: SignalWebsocketConnectionEventDisconnected, - Err: err, - } + } else { + errorCount++ + s.statusChannel <- SignalWebsocketConnectionStatus{ + Event: SignalWebsocketConnectionEventDisconnected, + Err: ctxCauseErr, } } - log.Info().Msg("Read or write loop exited") // Clean up ws.Close(websocket.StatusGoingAway, "Going away") From 9e7a24a7bab3c678e6a84ef60674869bf9a4c9a4 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Tue, 4 Mar 2025 14:49:17 +0200 Subject: [PATCH 296/580] client: don't propagate background timeouts if connection was successful --- pkg/connector/client.go | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/pkg/connector/client.go b/pkg/connector/client.go index 1bf8742..3cb4700 100644 --- a/pkg/connector/client.go +++ b/pkg/connector/client.go @@ -228,12 +228,14 @@ func (s *SignalClient) ConnectBackground(ctx context.Context, _ *bridgev2.Connec defer s.Disconnect() log := zerolog.Ctx(ctx) queueEmpty := s.queueEmptyWaiter.GetChan() + didConnect := false for { select { case status := <-ch: switch status.Event { case web.SignalWebsocketConnectionEventConnected: log.Info().Msg("Authed websocket connected") + didConnect = true case web.SignalWebsocketConnectionEventDisconnected: log.Err(status.Err).Msg("Authed websocket disconnected") case web.SignalWebsocketConnectionEventLoggedOut: @@ -247,6 +249,10 @@ func (s *SignalClient) ConnectBackground(ctx context.Context, _ *bridgev2.Connec } case <-ctx.Done(): log.Warn().Msg("Context finished before queue empty event") + if didConnect { + // Don't propagate timeout errors if the connection was successful at least once + return nil + } return ctx.Err() case <-queueEmpty: log.Info().Msg("Received queue empty event") From d7c598dbf45e9e2f9fd7c8c26216bf446f6fcfd5 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Fri, 7 Mar 2025 17:20:20 +0200 Subject: [PATCH 297/580] client: enable registering apns pushers --- pkg/connector/client.go | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/pkg/connector/client.go b/pkg/connector/client.go index 3cb4700..8c0db20 100644 --- a/pkg/connector/client.go +++ b/pkg/connector/client.go @@ -76,10 +76,14 @@ func (s *SignalClient) RegisterPushNotifications(ctx context.Context, pushType b if s.Client == nil { return bridgev2.ErrNotLoggedIn } - if pushType != bridgev2.PushTypeFCM { + switch pushType { + case bridgev2.PushTypeFCM: + return s.Client.RegisterFCM(ctx, token) + case bridgev2.PushTypeAPNs: + return s.Client.RegisterAPNs(ctx, token) + default: return fmt.Errorf("unsupported push type: %s", pushType) } - return s.Client.RegisterFCM(ctx, token) } func (s *SignalClient) LogoutRemote(ctx context.Context) { From cc42285a53bf74fb2b8e338526fd6103b68b08c5 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Mon, 10 Mar 2025 17:58:52 +0200 Subject: [PATCH 298/580] capabilities: resend to include gif info --- pkg/connector/capabilities.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/connector/capabilities.go b/pkg/connector/capabilities.go index 1be2d45..072c6fa 100644 --- a/pkg/connector/capabilities.go +++ b/pkg/connector/capabilities.go @@ -180,5 +180,5 @@ func (s *SignalConnector) GetCapabilities() *bridgev2.NetworkGeneralCapabilities } func (s *SignalConnector) GetBridgeInfoVersion() (info, capabilities int) { - return 1, 2 + return 1, 3 } From 89e2a3a5f2bc09a058415cc96aa459c76c876164 Mon Sep 17 00:00:00 2001 From: Nick Mills-Barrett Date: Tue, 11 Mar 2025 14:08:13 +0000 Subject: [PATCH 299/580] dependencies: upgrade mautrix-go --- go.mod | 4 ++-- go.sum | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/go.mod b/go.mod index e5ba156..fd62047 100644 --- a/go.mod +++ b/go.mod @@ -13,12 +13,12 @@ require ( github.com/rs/zerolog v1.33.0 github.com/stretchr/testify v1.10.0 github.com/tidwall/gjson v1.18.0 - go.mau.fi/util v0.8.5 + go.mau.fi/util v0.8.6-0.20250227184636-7ff63b0b9d95 golang.org/x/crypto v0.33.0 golang.org/x/exp v0.0.0-20250215185904-eff6e970281f golang.org/x/net v0.35.0 google.golang.org/protobuf v1.36.5 - maunium.net/go/mautrix v0.23.2-0.20250224184759-0115ba0258cb + maunium.net/go/mautrix v0.23.2-0.20250311105500-a6d948f7c2bb ) require ( diff --git a/go.sum b/go.sum index bcd6305..ef886d9 100644 --- a/go.sum +++ b/go.sum @@ -70,8 +70,8 @@ github.com/tidwall/sjson v1.2.5 h1:kLy8mja+1c9jlljvWTlSazM7cKDRfJuR/bOJhcY5NcY= github.com/tidwall/sjson v1.2.5/go.mod h1:Fvgq9kS/6ociJEDnK0Fk1cpYF4FIW6ZF7LAe+6jwd28= github.com/yuin/goldmark v1.7.8 h1:iERMLn0/QJeHFhxSt3p6PeN9mGnvIKSpG9YYorDMnic= github.com/yuin/goldmark v1.7.8/go.mod h1:uzxRWxtg69N339t3louHJ7+O03ezfj6PlliRlaOzY1E= -go.mau.fi/util v0.8.5 h1:PwCAAtcfK0XxZ4sdErJyfBMkTEWoQU33aB7QqDDzQRI= -go.mau.fi/util v0.8.5/go.mod h1:Ycug9mrbztlahHPEJ6H5r8Nu/xqZaWbE5vPHVWmfz6M= +go.mau.fi/util v0.8.6-0.20250227184636-7ff63b0b9d95 h1:5EfVWWjU2Hte9uE6B/hBgvjnVfBx/7SYDZBnsuo+EBs= +go.mau.fi/util v0.8.6-0.20250227184636-7ff63b0b9d95/go.mod h1:Ycug9mrbztlahHPEJ6H5r8Nu/xqZaWbE5vPHVWmfz6M= go.mau.fi/zeroconfig v0.1.3 h1:As9wYDKmktjmNZW5i1vn8zvJlmGKHeVxHVIBMXsm4kM= go.mau.fi/zeroconfig v0.1.3/go.mod h1:NcSJkf180JT+1IId76PcMuLTNa1CzsFFZ0nBygIQM70= golang.org/x/crypto v0.33.0 h1:IOBPskki6Lysi0lo9qQvbxiQ+FvsCC/YWOecCHAixus= @@ -100,5 +100,5 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= maunium.net/go/mauflag v1.0.0 h1:YiaRc0tEI3toYtJMRIfjP+jklH45uDHtT80nUamyD4M= maunium.net/go/mauflag v1.0.0/go.mod h1:nLivPOpTpHnpzEh8jEdSL9UqO9+/KBJFmNRlwKfkPeA= -maunium.net/go/mautrix v0.23.2-0.20250224184759-0115ba0258cb h1:neXlaiDrKjZsLmNm+ufCQGuEB050TKWVi7w9Qta+lFM= -maunium.net/go/mautrix v0.23.2-0.20250224184759-0115ba0258cb/go.mod h1:kldoZQDneV/jquIhwG1MmMw5j2A2M/MnQYRSWt863cY= +maunium.net/go/mautrix v0.23.2-0.20250311105500-a6d948f7c2bb h1:HAKsPqJiBsugs8qOy9mMmASEpmqpJ/Cbc/2Bj6wuNYQ= +maunium.net/go/mautrix v0.23.2-0.20250311105500-a6d948f7c2bb/go.mod h1:IHMaSJh7YIxMrZSDVefS+nLdr3RbeLowsCSa6ibONZ0= From 13a4881fdb550303ca1367f6ac2cda3ee803c889 Mon Sep 17 00:00:00 2001 From: Nick Mills-Barrett Date: Tue, 11 Mar 2025 14:08:25 +0000 Subject: [PATCH 300/580] backfill: don't delete all backfill messages if will paginate flag set --- pkg/connector/backfill.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/connector/backfill.go b/pkg/connector/backfill.go index c0416b1..ae6d196 100644 --- a/pkg/connector/backfill.go +++ b/pkg/connector/backfill.go @@ -172,7 +172,7 @@ func (s *SignalClient) FetchMessages(ctx context.Context, params bridgev2.FetchM CompleteCallback: func() { // When reaching the last backwards backfill batch, delete the chat from the backup store. // If backwards backfilling isn't enabled, delete immediately after the first backfill request. - if (!params.Forward && len(items) < params.Count) || !s.Main.Bridge.Config.Backfill.Queue.Enabled { + if (!params.Forward && len(items) < params.Count) || (!s.Main.Bridge.Config.Backfill.Queue.Enabled && !s.Main.Bridge.Config.Backfill.WillPaginateManually) { err := s.Client.Store.BackupStore.DeleteBackupChat(ctx, chat.Id) if err != nil { zerolog.Ctx(ctx).Err(err).Msg("Failed to delete chat from backup store") From e9ae079903c09eea88c8cf912bd0bba7b77b2b23 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Wed, 12 Mar 2025 14:21:21 +0200 Subject: [PATCH 301/580] libsignal: update to v0.67.4 --- pkg/libsignalgo/libsignal | 2 +- pkg/libsignalgo/libsignal-ffi.h | 7 +++++++ pkg/libsignalgo/version.go | 2 +- 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/pkg/libsignalgo/libsignal b/pkg/libsignalgo/libsignal index 865d879..7b293c1 160000 --- a/pkg/libsignalgo/libsignal +++ b/pkg/libsignalgo/libsignal @@ -1 +1 @@ -Subproject commit 865d879ec91396abf3c34f78cd7416708591c6ae +Subproject commit 7b293c19e0c71f204d4596e8f31f95ec993ea080 diff --git a/pkg/libsignalgo/libsignal-ffi.h b/pkg/libsignalgo/libsignal-ffi.h index 860963e..7470062 100644 --- a/pkg/libsignalgo/libsignal-ffi.h +++ b/pkg/libsignalgo/libsignal-ffi.h @@ -905,6 +905,8 @@ typedef void (*SignalReceivedIncomingMessage)(void *ctx, SignalOwnedBuffer envel typedef void (*SignalReceivedQueueEmpty)(void *ctx); +typedef void (*SignalReceivedAlerts)(void *ctx, SignalStringArray alerts); + typedef void (*SignalConnectionInterrupted)(void *ctx, SignalFfiError *error); typedef void (*SignalDestroyChatListener)(void *ctx); @@ -928,6 +930,7 @@ typedef struct { void *ctx; SignalReceivedIncomingMessage received_incoming_message; SignalReceivedQueueEmpty received_queue_empty; + SignalReceivedAlerts received_alerts; SignalConnectionInterrupted connection_interrupted; SignalDestroyChatListener destroy; } SignalFfiChatListenerStruct; @@ -1666,6 +1669,8 @@ SignalFfiError *signal_server_secret_params_get_public_params(SignalMutPointerSe SignalFfiError *signal_server_secret_params_sign_deterministic(uint8_t (*out)[SignalSIGNATURE_LEN], SignalConstPointerServerSecretParams params, const uint8_t (*randomness)[SignalRANDOMNESS_LEN], SignalBorrowedBuffer message); +SignalFfiError *signal_server_public_params_get_endorsement_public_key(SignalOwnedBuffer *out, SignalConstPointerServerPublicParams params); + SignalFfiError *signal_server_public_params_receive_auth_credential_with_pni_as_service_id(SignalOwnedBuffer *out, SignalConstPointerServerPublicParams params, const SignalServiceIdFixedWidthBinaryBytes *aci, const SignalServiceIdFixedWidthBinaryBytes *pni, uint64_t redemption_time, SignalBorrowedBuffer auth_credential_with_pni_response_bytes); SignalFfiError *signal_server_public_params_create_auth_credential_with_pni_presentation_deterministic(SignalOwnedBuffer *out, SignalConstPointerServerPublicParams server_public_params, const uint8_t (*randomness)[SignalRANDOMNESS_LEN], const unsigned char (*group_secret_params)[SignalGROUP_SECRET_PARAMS_LEN], SignalBorrowedBuffer auth_credential_with_pni_bytes); @@ -1924,6 +1929,8 @@ SignalFfiError *signal_unauthenticated_chat_connection_disconnect(SignalCPromise SignalFfiError *signal_unauthenticated_chat_connection_info(SignalMutPointerChatConnectionInfo *out, SignalConstPointerUnauthenticatedChatConnection chat); +SignalFfiError *signal_authenticated_chat_connection_preconnect(SignalCPromisebool *promise, SignalConstPointerTokioAsyncContext async_runtime, SignalConstPointerConnectionManager connection_manager); + SignalFfiError *signal_authenticated_chat_connection_connect(SignalCPromiseMutPointerAuthenticatedChatConnection *promise, SignalConstPointerTokioAsyncContext async_runtime, SignalConstPointerConnectionManager connection_manager, const char *username, const char *password, bool receive_stories); SignalFfiError *signal_authenticated_chat_connection_init_listener(SignalConstPointerAuthenticatedChatConnection chat, SignalConstPointerFfiChatListenerStruct listener); diff --git a/pkg/libsignalgo/version.go b/pkg/libsignalgo/version.go index aa85777..30d8666 100644 --- a/pkg/libsignalgo/version.go +++ b/pkg/libsignalgo/version.go @@ -2,4 +2,4 @@ package libsignalgo -const Version = "v0.67.0" +const Version = "v0.67.4" From 521f5e569de2467c0479a60ee8c4297d88416be6 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Thu, 13 Mar 2025 14:48:09 +0200 Subject: [PATCH 302/580] signalmeow/web: add logs for missing responses --- pkg/signalmeow/web/signalwebsocket.go | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/pkg/signalmeow/web/signalwebsocket.go b/pkg/signalmeow/web/signalwebsocket.go index d837dc7..eb57a11 100644 --- a/pkg/signalmeow/web/signalwebsocket.go +++ b/pkg/signalmeow/web/signalwebsocket.go @@ -162,14 +162,16 @@ func (s *SignalWebsocket) connectLoop( response, err := (*requestHandler)(ctx, request) if err != nil { - log.Err(err).Msg("Error handling request") - continue - } - if response != nil && s.sendChannel != nil { + log.Err(err).Uint64("request_id", request.GetId()).Msg("Error handling request") + } else if response != nil && s.sendChannel != nil { s.sendChannel <- SignalWebsocketSendMessage{ RequestMessage: request, ResponseMessage: response, } + } else if response == nil { + log.Warn().Uint64("request_id", request.GetId()).Msg("Request handler didn't return a response nor an error") + } else { + log.Warn().Uint64("request_id", request.GetId()).Msg("sendChannel is nil, can't send response") } } } From f09966c1484351d8fcacbb785a5d9753db4fd7c7 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Thu, 13 Mar 2025 14:49:40 +0200 Subject: [PATCH 303/580] signalmeow/web: remove redundant use of function pointer --- pkg/signalmeow/client.go | 2 +- pkg/signalmeow/web/signalwebsocket.go | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/pkg/signalmeow/client.go b/pkg/signalmeow/client.go index e5e4c88..0f03354 100644 --- a/pkg/signalmeow/client.go +++ b/pkg/signalmeow/client.go @@ -87,7 +87,7 @@ func (cli *Client) connectAuthedWS(ctx context.Context, requestHandler web.Reque Logger() ctx = log.WithContext(ctx) authedWS := web.NewSignalWebsocket(url.UserPassword(username, password)) - statusChan := authedWS.Connect(ctx, &requestHandler) + statusChan := authedWS.Connect(ctx, requestHandler) cli.AuthedWS = authedWS return statusChan, nil } diff --git a/pkg/signalmeow/web/signalwebsocket.go b/pkg/signalmeow/web/signalwebsocket.go index eb57a11..40c97b7 100644 --- a/pkg/signalmeow/web/signalwebsocket.go +++ b/pkg/signalmeow/web/signalwebsocket.go @@ -104,14 +104,14 @@ func (s *SignalWebsocket) Close() error { return nil } -func (s *SignalWebsocket) Connect(ctx context.Context, requestHandler *RequestHandlerFunc) chan SignalWebsocketConnectionStatus { +func (s *SignalWebsocket) Connect(ctx context.Context, requestHandler RequestHandlerFunc) chan SignalWebsocketConnectionStatus { go s.connectLoop(ctx, requestHandler) return s.statusChannel } func (s *SignalWebsocket) connectLoop( ctx context.Context, - requestHandler *RequestHandlerFunc, + requestHandler RequestHandlerFunc, ) { log := zerolog.Ctx(ctx).With(). Str("loop", "signal_websocket_connect_loop"). @@ -159,7 +159,7 @@ func (s *SignalWebsocket) connectLoop( } // Handle the request with the request handler function - response, err := (*requestHandler)(ctx, request) + response, err := requestHandler(ctx, request) if err != nil { log.Err(err).Uint64("request_id", request.GetId()).Msg("Error handling request") From 562ed0559371b6b9d30dca8cdf8692ff6e3060a5 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Thu, 13 Mar 2025 14:52:11 +0200 Subject: [PATCH 304/580] signalmeow: add request id to all incoming request logs --- pkg/signalmeow/receiving.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pkg/signalmeow/receiving.go b/pkg/signalmeow/receiving.go index f5e2390..d86f910 100644 --- a/pkg/signalmeow/receiving.go +++ b/pkg/signalmeow/receiving.go @@ -280,6 +280,7 @@ func (cli *Client) incomingRequestHandler(ctx context.Context, req *signalpb.Web Str("handler", "incoming request handler"). Str("verb", *req.Verb). Str("path", *req.Path). + Uint64("request_id", *req.Id). Logger() ctx = log.WithContext(ctx) if *req.Verb == http.MethodPut && *req.Path == "/api/v1/message" { @@ -296,7 +297,7 @@ func (cli *Client) incomingRequestHandler(ctx context.Context, req *signalpb.Web } func (cli *Client) incomingAPIMessageHandler(ctx context.Context, req *signalpb.WebSocketRequestMessage) (*web.SimpleResponse, error) { - log := *zerolog.Ctx(ctx) + log := zerolog.Ctx(ctx) envelope := &signalpb.Envelope{} err := proto.Unmarshal(req.Body, envelope) if err != nil { From 85cee8308eed7edfaf545611834c60ab11b62054 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Thu, 13 Mar 2025 14:54:29 +0200 Subject: [PATCH 305/580] signalmeow: remove unnecessarily big channel buffer --- pkg/signalmeow/receiving.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/signalmeow/receiving.go b/pkg/signalmeow/receiving.go index d86f910..073909b 100644 --- a/pkg/signalmeow/receiving.go +++ b/pkg/signalmeow/receiving.go @@ -104,7 +104,7 @@ func (cli *Client) StartReceiveLoops(ctx context.Context) (chan SignalConnection if err != nil { return nil, err } - statusChan := make(chan SignalConnectionStatus, 10000) + statusChan := make(chan SignalConnectionStatus, 128) initialConnectChan := make(chan struct{}) From e55601d0e09ba9949124d15dacd84b261f98bce0 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Thu, 13 Mar 2025 16:41:39 +0200 Subject: [PATCH 306/580] signalmeow/web: fix another oversized channel --- pkg/signalmeow/web/signalwebsocket.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/signalmeow/web/signalwebsocket.go b/pkg/signalmeow/web/signalwebsocket.go index 40c97b7..4af77af 100644 --- a/pkg/signalmeow/web/signalwebsocket.go +++ b/pkg/signalmeow/web/signalwebsocket.go @@ -118,7 +118,7 @@ func (s *SignalWebsocket) connectLoop( Logger() ctx, cancel := context.WithCancel(ctx) - incomingRequestChan := make(chan *signalpb.WebSocketRequestMessage, 10000) + incomingRequestChan := make(chan *signalpb.WebSocketRequestMessage, 256) defer func() { close(incomingRequestChan) close(s.statusChannel) From 074a2a9befa57775c6f5c54d4c3ce30aa0aa3126 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Thu, 13 Mar 2025 17:38:14 +0200 Subject: [PATCH 307/580] client: consume unauth websocket status in ConnectBackground --- pkg/connector/client.go | 15 ++++++++++++++- pkg/signalmeow/receiving.go | 2 +- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/pkg/connector/client.go b/pkg/connector/client.go index 8c0db20..8ffd0e0 100644 --- a/pkg/connector/client.go +++ b/pkg/connector/client.go @@ -225,7 +225,7 @@ func (s *SignalClient) Connect(ctx context.Context) { func (s *SignalClient) ConnectBackground(ctx context.Context, _ *bridgev2.ConnectBackgroundParams) error { s.queueEmptyWaiter.Clear() - ch, _, err := s.Client.StartWebsockets(ctx) + ch, unauthCh, err := s.Client.StartWebsockets(ctx) if err != nil { return err } @@ -251,6 +251,19 @@ func (s *SignalClient) ConnectBackground(ctx context.Context, _ *bridgev2.Connec case web.SignalWebsocketConnectionEventCleanShutdown: log.Info().Msg("Authed websocket clean shutdown") } + case status := <-unauthCh: + switch status.Event { + case web.SignalWebsocketConnectionEventConnected: + log.Info().Msg("Unauthed websocket connected") + case web.SignalWebsocketConnectionEventDisconnected: + log.Err(status.Err).Msg("Unauthed websocket disconnected") + case web.SignalWebsocketConnectionEventLoggedOut: + log.Err(status.Err).Msg("Unauthed websocket logged out") + case web.SignalWebsocketConnectionEventError: + log.Err(status.Err).Msg("Unauthed websocket error") + case web.SignalWebsocketConnectionEventCleanShutdown: + log.Info().Msg("Unauthed websocket clean shutdown") + } case <-ctx.Done(): log.Warn().Msg("Context finished before queue empty event") if didConnect { diff --git a/pkg/signalmeow/receiving.go b/pkg/signalmeow/receiving.go index 073909b..34fcd55 100644 --- a/pkg/signalmeow/receiving.go +++ b/pkg/signalmeow/receiving.go @@ -280,7 +280,7 @@ func (cli *Client) incomingRequestHandler(ctx context.Context, req *signalpb.Web Str("handler", "incoming request handler"). Str("verb", *req.Verb). Str("path", *req.Path). - Uint64("request_id", *req.Id). + Uint64("incoming_request_id", *req.Id). Logger() ctx = log.WithContext(ctx) if *req.Verb == http.MethodPut && *req.Path == "/api/v1/message" { From 72b0616261f3b8dff5b01864dc0d6f6a71c9e63d Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Thu, 13 Mar 2025 17:43:11 +0200 Subject: [PATCH 308/580] signalmeow/web: don't deadlock on status channel --- pkg/signalmeow/web/signalwebsocket.go | 56 +++++++++++---------------- 1 file changed, 22 insertions(+), 34 deletions(-) diff --git a/pkg/signalmeow/web/signalwebsocket.go b/pkg/signalmeow/web/signalwebsocket.go index 4af77af..ac280be 100644 --- a/pkg/signalmeow/web/signalwebsocket.go +++ b/pkg/signalmeow/web/signalwebsocket.go @@ -109,6 +109,19 @@ func (s *SignalWebsocket) Connect(ctx context.Context, requestHandler RequestHan return s.statusChannel } +func (s *SignalWebsocket) pushStatus(ctx context.Context, status SignalWebsocketConnectionEvent, err error) { + select { + case s.statusChannel <- SignalWebsocketConnectionStatus{ + Event: status, + Err: err, + }: + case <-ctx.Done(): + return + case <-time.After(5 * time.Second): + zerolog.Ctx(ctx).Error().Msg("Status channel didn't accept status") + } +} + func (s *SignalWebsocket) connectLoop( ctx context.Context, requestHandler RequestHandlerFunc, @@ -212,30 +225,18 @@ func (s *SignalWebsocket) connectLoop( // Server didn't want to open websocket if resp.StatusCode >= 500 { // We can try again if it's a 5xx - s.statusChannel <- SignalWebsocketConnectionStatus{ - Event: SignalWebsocketConnectionEventDisconnected, - Err: fmt.Errorf("5xx opening websocket: %v", resp.Status), - } + s.pushStatus(ctx, SignalWebsocketConnectionEventDisconnected, fmt.Errorf("5xx opening websocket: %v", resp.Status)) } else if resp.StatusCode == 403 { // We are logged out, so we should stop trying to reconnect - s.statusChannel <- SignalWebsocketConnectionStatus{ - Event: SignalWebsocketConnectionEventLoggedOut, - Err: fmt.Errorf("403 opening websocket, we are logged out"), - } + s.pushStatus(ctx, SignalWebsocketConnectionEventLoggedOut, fmt.Errorf("403 opening websocket, we are logged out")) return // NOT RETRYING, KILLING THE CONNECTION LOOP } else if resp.StatusCode > 0 && resp.StatusCode < 500 { // Unexpected status code - s.statusChannel <- SignalWebsocketConnectionStatus{ - Event: SignalWebsocketConnectionEventError, - Err: fmt.Errorf("bad status opening websocket: %v", resp.Status), - } + s.pushStatus(ctx, SignalWebsocketConnectionEventError, fmt.Errorf("unexpected status opening websocket: %v", resp.Status)) return // NOT RETRYING, KILLING THE CONNECTION LOOP } else { // Something is very wrong - s.statusChannel <- SignalWebsocketConnectionStatus{ - Event: SignalWebsocketConnectionEventError, - Err: fmt.Errorf("unexpected error opening websocket: %v", resp.Status), - } + s.pushStatus(ctx, SignalWebsocketConnectionEventError, fmt.Errorf("unexpected error opening websocket: %v", resp.Status)) } // Retry the connection retrying = true @@ -245,24 +246,16 @@ func (s *SignalWebsocket) connectLoop( if err != nil { // Unexpected error opening websocket if backoff < maxBackoff { - s.statusChannel <- SignalWebsocketConnectionStatus{ - Event: SignalWebsocketConnectionEventDisconnected, - Err: fmt.Errorf("hopefully transient error opening websocket: %w", err), - } + s.pushStatus(ctx, SignalWebsocketConnectionEventDisconnected, fmt.Errorf("transient error opening websocket: %w", err)) } else { - s.statusChannel <- SignalWebsocketConnectionStatus{ - Event: SignalWebsocketConnectionEventError, - Err: fmt.Errorf("continuing error opening websocket: %w", err), - } + s.pushStatus(ctx, SignalWebsocketConnectionEventError, fmt.Errorf("continuing error opening websocket: %w", err)) } retrying = true continue } // Succssfully connected - s.statusChannel <- SignalWebsocketConnectionStatus{ - Event: SignalWebsocketConnectionEventConnected, - } + s.pushStatus(ctx, SignalWebsocketConnectionEventConnected, nil) s.ws = ws retrying = false backoff = initialBackoff @@ -338,15 +331,10 @@ func (s *SignalWebsocket) connectLoop( ctxCauseErr := context.Cause(loopCtx) log.Debug().AnErr("ctx_cause_err", ctxCauseErr).Msg("Read or write loop exited") if ctxCauseErr == nil || errors.Is(ctxCauseErr, context.Canceled) { - s.statusChannel <- SignalWebsocketConnectionStatus{ - Event: SignalWebsocketConnectionEventCleanShutdown, - } + s.pushStatus(ctx, SignalWebsocketConnectionEventCleanShutdown, nil) } else { errorCount++ - s.statusChannel <- SignalWebsocketConnectionStatus{ - Event: SignalWebsocketConnectionEventDisconnected, - Err: ctxCauseErr, - } + s.pushStatus(ctx, SignalWebsocketConnectionEventError, ctxCauseErr) } // Clean up From 03d675c465b67b596fa277bff00505031ea048b7 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Sun, 16 Mar 2025 16:53:21 +0200 Subject: [PATCH 309/580] Bump version to v0.8.1 --- CHANGELOG.md | 5 +++++ cmd/mautrix-signal/main.go | 2 +- go.mod | 22 ++++++++++----------- go.sum | 40 +++++++++++++++++++------------------- 4 files changed, 37 insertions(+), 32 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5804dc1..01410df 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,8 @@ +# v0.8.1 (2025-03-16) + +* Added QR refreshing when logging in. +* Updated libsignal to v0.67.4. + # v0.8.0 (2025-02-16) * Bumped minimum Go version to 1.23. diff --git a/cmd/mautrix-signal/main.go b/cmd/mautrix-signal/main.go index 2cbed46..c97a5d2 100644 --- a/cmd/mautrix-signal/main.go +++ b/cmd/mautrix-signal/main.go @@ -38,7 +38,7 @@ var m = mxmain.BridgeMain{ Name: "mautrix-signal", URL: "https://github.com/mautrix/signal", Description: "A Matrix-Signal puppeting bridge.", - Version: "0.8.0", + Version: "0.8.1", Connector: &connector.SignalConnector{}, } diff --git a/go.mod b/go.mod index fd62047..bb606a4 100644 --- a/go.mod +++ b/go.mod @@ -2,10 +2,10 @@ module go.mau.fi/mautrix-signal go 1.23.0 -toolchain go1.24.0 +toolchain go1.24.1 require ( - github.com/coder/websocket v1.8.12 + github.com/coder/websocket v1.8.13 github.com/emersion/go-vcard v0.0.0-20241024213814-c9703dde27ff github.com/google/uuid v1.6.0 github.com/gorilla/mux v1.8.0 @@ -13,12 +13,12 @@ require ( github.com/rs/zerolog v1.33.0 github.com/stretchr/testify v1.10.0 github.com/tidwall/gjson v1.18.0 - go.mau.fi/util v0.8.6-0.20250227184636-7ff63b0b9d95 - golang.org/x/crypto v0.33.0 - golang.org/x/exp v0.0.0-20250215185904-eff6e970281f - golang.org/x/net v0.35.0 + go.mau.fi/util v0.8.6 + golang.org/x/crypto v0.36.0 + golang.org/x/exp v0.0.0-20250305212735-054e65f0b394 + golang.org/x/net v0.37.0 google.golang.org/protobuf v1.36.5 - maunium.net/go/mautrix v0.23.2-0.20250311105500-a6d948f7c2bb + maunium.net/go/mautrix v0.23.2 ) require ( @@ -31,7 +31,7 @@ require ( github.com/mattn/go-colorable v0.1.14 // indirect github.com/mattn/go-isatty v0.0.20 // indirect github.com/mattn/go-sqlite3 v1.14.24 // indirect - github.com/petermattis/goid v0.0.0-20250211185408-f2b9d978cd7a // indirect + github.com/petermattis/goid v0.0.0-20250303134427-723919f7f203 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/rogpeppe/go-internal v1.10.0 // indirect github.com/rs/xid v1.6.0 // indirect @@ -41,9 +41,9 @@ require ( github.com/tidwall/sjson v1.2.5 // indirect github.com/yuin/goldmark v1.7.8 // indirect go.mau.fi/zeroconfig v0.1.3 // indirect - golang.org/x/sync v0.11.0 // indirect - golang.org/x/sys v0.30.0 // indirect - golang.org/x/text v0.22.0 // indirect + golang.org/x/sync v0.12.0 // indirect + golang.org/x/sys v0.31.0 // indirect + golang.org/x/text v0.23.0 // indirect gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect gopkg.in/natefinch/lumberjack.v2 v2.2.1 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect diff --git a/go.sum b/go.sum index ef886d9..1926fed 100644 --- a/go.sum +++ b/go.sum @@ -2,8 +2,8 @@ filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA= filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4= github.com/DATA-DOG/go-sqlmock v1.5.2 h1:OcvFkGmslmlZibjAjaHm3L//6LiuBgolP7OputlJIzU= github.com/DATA-DOG/go-sqlmock v1.5.2/go.mod h1:88MAG/4G7SMwSE3CeA0ZKzrT5CiOU3OJ+JlNzwDqpNU= -github.com/coder/websocket v1.8.12 h1:5bUXkEPPIbewrnkU8LTCLVaxi4N4J8ahufH2vlo4NAo= -github.com/coder/websocket v1.8.12/go.mod h1:LNVeNrXQZfe5qhS9ALED3uA+l5pPqvwXg3CKoDBB2gs= +github.com/coder/websocket v1.8.13 h1:f3QZdXy7uGVz+4uCJy2nTZyM0yTBj8yANEHhqlXZ9FE= +github.com/coder/websocket v1.8.13/go.mod h1:LNVeNrXQZfe5qhS9ALED3uA+l5pPqvwXg3CKoDBB2gs= github.com/coreos/go-systemd/v22 v22.5.0 h1:RrqgGjYQKalulkV8NGVIfkXQf6YYmOyiJKk8iXXhfZs= github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= @@ -40,8 +40,8 @@ github.com/mattn/go-pointer v0.0.1 h1:n+XhsuGeVO6MEAp7xyEukFINEa+Quek5psIR/ylA6o github.com/mattn/go-pointer v0.0.1/go.mod h1:2zXcozF6qYGgmsG+SeTZz3oAbFLdD3OWqnUbNvJZAlc= github.com/mattn/go-sqlite3 v1.14.24 h1:tpSp2G2KyMnnQu99ngJ47EIkWVmliIizyZBfPrBWDRM= github.com/mattn/go-sqlite3 v1.14.24/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y= -github.com/petermattis/goid v0.0.0-20250211185408-f2b9d978cd7a h1:ckxP/kGzsxvxXo8jO6E/0QJ8MMmwI7IRj4Fys9QbAZA= -github.com/petermattis/goid v0.0.0-20250211185408-f2b9d978cd7a/go.mod h1:pxMtw7cyUw6B2bRH0ZBANSPg+AoSud1I1iyJHI69jH4= +github.com/petermattis/goid v0.0.0-20250303134427-723919f7f203 h1:E7Kmf11E4K7B5hDti2K2NqPb1nlYlGYsu02S1JNd/Bs= +github.com/petermattis/goid v0.0.0-20250303134427-723919f7f203/go.mod h1:pxMtw7cyUw6B2bRH0ZBANSPg+AoSud1I1iyJHI69jH4= github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= @@ -70,25 +70,25 @@ github.com/tidwall/sjson v1.2.5 h1:kLy8mja+1c9jlljvWTlSazM7cKDRfJuR/bOJhcY5NcY= github.com/tidwall/sjson v1.2.5/go.mod h1:Fvgq9kS/6ociJEDnK0Fk1cpYF4FIW6ZF7LAe+6jwd28= github.com/yuin/goldmark v1.7.8 h1:iERMLn0/QJeHFhxSt3p6PeN9mGnvIKSpG9YYorDMnic= github.com/yuin/goldmark v1.7.8/go.mod h1:uzxRWxtg69N339t3louHJ7+O03ezfj6PlliRlaOzY1E= -go.mau.fi/util v0.8.6-0.20250227184636-7ff63b0b9d95 h1:5EfVWWjU2Hte9uE6B/hBgvjnVfBx/7SYDZBnsuo+EBs= -go.mau.fi/util v0.8.6-0.20250227184636-7ff63b0b9d95/go.mod h1:Ycug9mrbztlahHPEJ6H5r8Nu/xqZaWbE5vPHVWmfz6M= +go.mau.fi/util v0.8.6 h1:AEK13rfgtiZJL2YsNK+W4ihhYCuukcRom8WPP/w/L54= +go.mau.fi/util v0.8.6/go.mod h1:uNB3UTXFbkpp7xL1M/WvQks90B/L4gvbLpbS0603KOE= go.mau.fi/zeroconfig v0.1.3 h1:As9wYDKmktjmNZW5i1vn8zvJlmGKHeVxHVIBMXsm4kM= go.mau.fi/zeroconfig v0.1.3/go.mod h1:NcSJkf180JT+1IId76PcMuLTNa1CzsFFZ0nBygIQM70= -golang.org/x/crypto v0.33.0 h1:IOBPskki6Lysi0lo9qQvbxiQ+FvsCC/YWOecCHAixus= -golang.org/x/crypto v0.33.0/go.mod h1:bVdXmD7IV/4GdElGPozy6U7lWdRXA4qyRVGJV57uQ5M= -golang.org/x/exp v0.0.0-20250215185904-eff6e970281f h1:oFMYAjX0867ZD2jcNiLBrI9BdpmEkvPyi5YrBGXbamg= -golang.org/x/exp v0.0.0-20250215185904-eff6e970281f/go.mod h1:BHOTPb3L19zxehTsLoJXVaTktb06DFgmdW6Wb9s8jqk= -golang.org/x/net v0.35.0 h1:T5GQRQb2y08kTAByq9L4/bz8cipCdA8FbRTXewonqY8= -golang.org/x/net v0.35.0/go.mod h1:EglIi67kWsHKlRzzVMUD93VMSWGFOMSZgxFjparz1Qk= -golang.org/x/sync v0.11.0 h1:GGz8+XQP4FvTTrjZPzNKTMFtSXH80RAzG+5ghFPgK9w= -golang.org/x/sync v0.11.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/crypto v0.36.0 h1:AnAEvhDddvBdpY+uR+MyHmuZzzNqXSe/GvuDeob5L34= +golang.org/x/crypto v0.36.0/go.mod h1:Y4J0ReaxCR1IMaabaSMugxJES1EpwhBHhv2bDHklZvc= +golang.org/x/exp v0.0.0-20250305212735-054e65f0b394 h1:nDVHiLt8aIbd/VzvPWN6kSOPE7+F/fNFDSXLVYkE/Iw= +golang.org/x/exp v0.0.0-20250305212735-054e65f0b394/go.mod h1:sIifuuw/Yco/y6yb6+bDNfyeQ/MdPUy/hKEMYQV17cM= +golang.org/x/net v0.37.0 h1:1zLorHbz+LYj7MQlSf1+2tPIIgibq2eL5xkrGk6f+2c= +golang.org/x/net v0.37.0/go.mod h1:ivrbrMbzFq5J41QOQh0siUuly180yBYtLp+CKbEaFx8= +golang.org/x/sync v0.12.0 h1:MHc5BpPuC30uJk597Ri8TV3CNZcTLu6B6z4lJy+g6Jw= +golang.org/x/sync v0.12.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.30.0 h1:QjkSwP/36a20jFYWkSue1YwXzLmsV5Gfq7Eiy72C1uc= -golang.org/x/sys v0.30.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/text v0.22.0 h1:bofq7m3/HAFvbF51jz3Q9wLg3jkvSPuiZu/pD1XwgtM= -golang.org/x/text v0.22.0/go.mod h1:YRoo4H8PVmsu+E3Ou7cqLVH8oXWIHVoX0jqUWALQhfY= +golang.org/x/sys v0.31.0 h1:ioabZlmFYtWhL+TRYpcnNlLwhyxaM9kWTDEmfnprqik= +golang.org/x/sys v0.31.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= +golang.org/x/text v0.23.0 h1:D71I7dUrlY+VX0gQShAThNGHFxZ13dGLBHQLVl1mJlY= +golang.org/x/text v0.23.0/go.mod h1:/BLNzu4aZCJ1+kcD0DNRotWKage4q2rGVAg4o22unh4= google.golang.org/protobuf v1.36.5 h1:tPhr+woSbjfYvY6/GPufUoYizxw1cF/yFoxJ2fmpwlM= google.golang.org/protobuf v1.36.5/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= @@ -100,5 +100,5 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= maunium.net/go/mauflag v1.0.0 h1:YiaRc0tEI3toYtJMRIfjP+jklH45uDHtT80nUamyD4M= maunium.net/go/mauflag v1.0.0/go.mod h1:nLivPOpTpHnpzEh8jEdSL9UqO9+/KBJFmNRlwKfkPeA= -maunium.net/go/mautrix v0.23.2-0.20250311105500-a6d948f7c2bb h1:HAKsPqJiBsugs8qOy9mMmASEpmqpJ/Cbc/2Bj6wuNYQ= -maunium.net/go/mautrix v0.23.2-0.20250311105500-a6d948f7c2bb/go.mod h1:IHMaSJh7YIxMrZSDVefS+nLdr3RbeLowsCSa6ibONZ0= +maunium.net/go/mautrix v0.23.2 h1:Bo3tPrQJwkxyL7aMmy/T+d2tqIrypZjHqeHe8fyeAOg= +maunium.net/go/mautrix v0.23.2/go.mod h1:pCYLHmo02Jauak/9VlTkbGPrBMvLXsGqTGMNOx+L2PE= From c4797ab292a04b23117e73ae70977943bf1a0513 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Thu, 20 Mar 2025 16:52:52 +0200 Subject: [PATCH 310/580] dependencies: update mautrix-go --- cmd/mautrix-signal/legacyprovision.go | 2 +- go.mod | 2 +- go.sum | 4 ++-- pkg/connector/client.go | 2 +- pkg/connector/login.go | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/cmd/mautrix-signal/legacyprovision.go b/cmd/mautrix-signal/legacyprovision.go index 177d4a5..8bad469 100644 --- a/cmd/mautrix-signal/legacyprovision.go +++ b/cmd/mautrix-signal/legacyprovision.go @@ -28,8 +28,8 @@ import ( "github.com/gorilla/mux" "github.com/rs/zerolog" "maunium.net/go/mautrix" - "maunium.net/go/mautrix/bridge/status" "maunium.net/go/mautrix/bridgev2" + "maunium.net/go/mautrix/bridgev2/status" "maunium.net/go/mautrix/id" "go.mau.fi/mautrix-signal/pkg/connector" diff --git a/go.mod b/go.mod index bb606a4..7e2044e 100644 --- a/go.mod +++ b/go.mod @@ -18,7 +18,7 @@ require ( golang.org/x/exp v0.0.0-20250305212735-054e65f0b394 golang.org/x/net v0.37.0 google.golang.org/protobuf v1.36.5 - maunium.net/go/mautrix v0.23.2 + maunium.net/go/mautrix v0.23.3-0.20250320134109-06f200da0d10 ) require ( diff --git a/go.sum b/go.sum index 1926fed..b049d15 100644 --- a/go.sum +++ b/go.sum @@ -100,5 +100,5 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= maunium.net/go/mauflag v1.0.0 h1:YiaRc0tEI3toYtJMRIfjP+jklH45uDHtT80nUamyD4M= maunium.net/go/mauflag v1.0.0/go.mod h1:nLivPOpTpHnpzEh8jEdSL9UqO9+/KBJFmNRlwKfkPeA= -maunium.net/go/mautrix v0.23.2 h1:Bo3tPrQJwkxyL7aMmy/T+d2tqIrypZjHqeHe8fyeAOg= -maunium.net/go/mautrix v0.23.2/go.mod h1:pCYLHmo02Jauak/9VlTkbGPrBMvLXsGqTGMNOx+L2PE= +maunium.net/go/mautrix v0.23.3-0.20250320134109-06f200da0d10 h1:XE2szxSvJVngk+qHqlKO2fiBZwcAp3oYq+9P5jlAm6w= +maunium.net/go/mautrix v0.23.3-0.20250320134109-06f200da0d10/go.mod h1:pCYLHmo02Jauak/9VlTkbGPrBMvLXsGqTGMNOx+L2PE= diff --git a/pkg/connector/client.go b/pkg/connector/client.go index 8ffd0e0..7a4d003 100644 --- a/pkg/connector/client.go +++ b/pkg/connector/client.go @@ -23,9 +23,9 @@ import ( "github.com/rs/zerolog" "go.mau.fi/util/exsync" - "maunium.net/go/mautrix/bridge/status" "maunium.net/go/mautrix/bridgev2" "maunium.net/go/mautrix/bridgev2/networkid" + "maunium.net/go/mautrix/bridgev2/status" "go.mau.fi/mautrix-signal/pkg/signalid" "go.mau.fi/mautrix-signal/pkg/signalmeow" diff --git a/pkg/connector/login.go b/pkg/connector/login.go index 50ba0ae..15a48c3 100644 --- a/pkg/connector/login.go +++ b/pkg/connector/login.go @@ -22,9 +22,9 @@ import ( "time" "github.com/google/uuid" - "maunium.net/go/mautrix/bridge/status" "maunium.net/go/mautrix/bridgev2" "maunium.net/go/mautrix/bridgev2/database" + "maunium.net/go/mautrix/bridgev2/status" "go.mau.fi/mautrix-signal/pkg/signalid" "go.mau.fi/mautrix-signal/pkg/signalmeow" From 833d64a25806680e247d8225fad84dbf1658b948 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Thu, 20 Mar 2025 16:53:40 +0200 Subject: [PATCH 311/580] signalmeow/profile: add nil check when fetching expiring credentials --- pkg/signalmeow/profile.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/pkg/signalmeow/profile.go b/pkg/signalmeow/profile.go index 5182c23..c21fb5f 100644 --- a/pkg/signalmeow/profile.go +++ b/pkg/signalmeow/profile.go @@ -364,6 +364,8 @@ func (cli *Client) FetchExpiringProfileKeyCredentialById(ctx context.Context, si profileKey, err := cli.ProfileKeyForSignalID(ctx, signalACI) if err != nil { return nil, fmt.Errorf("error getting profile key for ACI: %w", err) + } else if profileKey == nil { + return nil, errProfileKeyNotFound } requestContext, err := libsignalgo.CreateProfileKeyCredentialRequestContext( prodServerPublicParams, From 6d621fc2aafcdf079c16380abfcd2b58259df037 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Thu, 20 Mar 2025 17:37:53 +0200 Subject: [PATCH 312/580] signalmeow/web: fix error type on disconnects --- pkg/signalmeow/web/signalwebsocket.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/signalmeow/web/signalwebsocket.go b/pkg/signalmeow/web/signalwebsocket.go index ac280be..6e625e3 100644 --- a/pkg/signalmeow/web/signalwebsocket.go +++ b/pkg/signalmeow/web/signalwebsocket.go @@ -334,7 +334,7 @@ func (s *SignalWebsocket) connectLoop( s.pushStatus(ctx, SignalWebsocketConnectionEventCleanShutdown, nil) } else { errorCount++ - s.pushStatus(ctx, SignalWebsocketConnectionEventError, ctxCauseErr) + s.pushStatus(ctx, SignalWebsocketConnectionEventDisconnected, ctxCauseErr) } // Clean up From ebf7e9a60dc7eb124ecc21de91aa723a3094f09c Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Tue, 25 Mar 2025 12:52:13 +0200 Subject: [PATCH 313/580] signalmeow/web: fix writing to send channel during close --- pkg/signalmeow/web/signalwebsocket.go | 47 ++++++++++++++++++++------- 1 file changed, 36 insertions(+), 11 deletions(-) diff --git a/pkg/signalmeow/web/signalwebsocket.go b/pkg/signalmeow/web/signalwebsocket.go index 6e625e3..47cc2e3 100644 --- a/pkg/signalmeow/web/signalwebsocket.go +++ b/pkg/signalmeow/web/signalwebsocket.go @@ -29,6 +29,7 @@ import ( "github.com/coder/websocket" "github.com/rs/zerolog" + "go.mau.fi/util/exsync" signalpb "go.mau.fi/mautrix-signal/pkg/signalmeow/protobuf" "go.mau.fi/mautrix-signal/pkg/signalmeow/wspb" @@ -47,6 +48,8 @@ type SignalWebsocket struct { basicAuth *url.Userinfo sendChannel chan SignalWebsocketSendMessage statusChannel chan SignalWebsocketConnectionStatus + closeLock sync.RWMutex + closeEvt *exsync.Event } func NewSignalWebsocket(basicAuth *url.Userinfo) *SignalWebsocket { @@ -54,6 +57,7 @@ func NewSignalWebsocket(basicAuth *url.Userinfo) *SignalWebsocket { basicAuth: basicAuth, sendChannel: make(chan SignalWebsocketSendMessage), statusChannel: make(chan SignalWebsocketConnectionStatus), + closeEvt: exsync.NewEvent(), } } @@ -122,6 +126,22 @@ func (s *SignalWebsocket) pushStatus(ctx context.Context, status SignalWebsocket } } +func (s *SignalWebsocket) pushOutgoing(ctx context.Context, send SignalWebsocketSendMessage) error { + s.closeLock.RLock() + defer s.closeLock.RUnlock() + if s.sendChannel == nil { + return errors.New("connection is not open") + } + select { + case s.sendChannel <- send: + return nil + case <-ctx.Done(): + return ctx.Err() + case <-s.closeEvt.GetChan(): + return errors.New("connection closed before send could be queued") + } +} + func (s *SignalWebsocket) connectLoop( ctx context.Context, requestHandler RequestHandlerFunc, @@ -133,13 +153,17 @@ func (s *SignalWebsocket) connectLoop( incomingRequestChan := make(chan *signalpb.WebSocketRequestMessage, 256) defer func() { + s.closeEvt.Set() + cancel() + + s.closeLock.Lock() + defer s.closeLock.Unlock() close(incomingRequestChan) close(s.statusChannel) close(s.sendChannel) incomingRequestChan = nil s.statusChannel = nil s.sendChannel = nil - cancel() }() const initialBackoff = 2 * time.Second @@ -176,15 +200,16 @@ func (s *SignalWebsocket) connectLoop( if err != nil { log.Err(err).Uint64("request_id", request.GetId()).Msg("Error handling request") - } else if response != nil && s.sendChannel != nil { - s.sendChannel <- SignalWebsocketSendMessage{ + } else if response != nil { + err = s.pushOutgoing(ctx, SignalWebsocketSendMessage{ RequestMessage: request, ResponseMessage: response, + }) + if err != nil { + log.Err(err).Uint64("request_id", request.GetId()).Msg("Error queuing response message") } - } else if response == nil { - log.Warn().Uint64("request_id", request.GetId()).Msg("Request handler didn't return a response nor an error") } else { - log.Warn().Uint64("request_id", request.GetId()).Msg("sendChannel is nil, can't send response") + log.Warn().Uint64("request_id", request.GetId()).Msg("Request handler didn't return a response nor an error") } } } @@ -527,13 +552,13 @@ func (s *SignalWebsocket) sendRequestInternal( request.Headers = append(request.Headers, "authorization:Basic "+s.basicAuth.String()) } responseChannel := make(chan *signalpb.WebSocketResponseMessage, 1) - if s.sendChannel == nil { - return nil, errors.New("Send channel not initialized") - } - s.sendChannel <- SignalWebsocketSendMessage{ + err := s.pushOutgoing(ctx, SignalWebsocketSendMessage{ RequestMessage: request, ResponseChannel: responseChannel, RequestTime: startTime, + }) + if err != nil { + return nil, err } response := <-responseChannel @@ -544,7 +569,7 @@ func (s *SignalWebsocket) sendRequestInternal( if ctx.Err() != nil { return nil, fmt.Errorf("retried 3 times, giving up: %w", ctx.Err()) } else { - return nil, errors.New("Retried 3 times, giving up") + return nil, errors.New("retried 3 times, giving up") } } if ctx.Err() != nil { From 8aaa6f6f7628af3e3fb72e79d4e65119b80a5031 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Wed, 9 Apr 2025 15:25:04 +0300 Subject: [PATCH 314/580] signalmeow/profile: lock cache when writing --- pkg/signalmeow/profile.go | 40 +++++++++++++++++++++++++++------------ 1 file changed, 28 insertions(+), 12 deletions(-) diff --git a/pkg/signalmeow/profile.go b/pkg/signalmeow/profile.go index c21fb5f..bbd31f3 100644 --- a/pkg/signalmeow/profile.go +++ b/pkg/signalmeow/profile.go @@ -30,6 +30,7 @@ import ( "io" "net/http" "strings" + "sync" "time" "github.com/google/uuid" @@ -76,6 +77,7 @@ type ProfileCache struct { profiles map[string]*types.Profile errors map[string]*error lastFetched map[string]time.Time + lock sync.RWMutex } func (cli *Client) ProfileKeyCredentialRequest(ctx context.Context, signalACI uuid.UUID) ([]byte, error) { @@ -112,17 +114,9 @@ func (cli *Client) ProfileKeyForSignalID(ctx context.Context, signalACI uuid.UUI var errProfileKeyNotFound = errors.New("profile key not found") -func (cli *Client) RetrieveProfileByID(ctx context.Context, signalID uuid.UUID) (*types.Profile, error) { - if cli.ProfileCache == nil { - cli.ProfileCache = &ProfileCache{ - profiles: make(map[string]*types.Profile), - errors: make(map[string]*error), - lastFetched: make(map[string]time.Time), - } - } - - // Check if we have a cached profile that is less than an hour old - // or if we have a cached error that is less than an hour old +func (cli *Client) getCachedProfileByID(signalID uuid.UUID) (*types.Profile, error) { + cli.ProfileCache.lock.RLock() + defer cli.ProfileCache.lock.RUnlock() lastFetched, ok := cli.ProfileCache.lastFetched[signalID.String()] if ok && time.Since(lastFetched) < 1*time.Hour { profile, ok := cli.ProfileCache.profiles[signalID.String()] @@ -134,12 +128,32 @@ func (cli *Client) RetrieveProfileByID(ctx context.Context, signalID uuid.UUID) return nil, fmt.Errorf("%w: %w", ErrCachedError, *err) } } + return nil, nil +} + +func (cli *Client) RetrieveProfileByID(ctx context.Context, signalID uuid.UUID) (*types.Profile, error) { + if cli.ProfileCache == nil { + cli.ProfileCache = &ProfileCache{ + profiles: make(map[string]*types.Profile), + errors: make(map[string]*error), + lastFetched: make(map[string]time.Time), + } + } + + // Check if we have a cached profile that is less than an hour old + // or if we have a cached error that is less than an hour old + profile, err := cli.getCachedProfileByID(signalID) + if err != nil || profile != nil { + return profile, err + } // If we get here, we don't have a cached profile, so fetch it - profile, err := cli.fetchProfileByID(ctx, signalID) + profile, err = cli.fetchProfileByID(ctx, signalID) if err != nil { // If we get a 401 or 5xx error, we should not retry until the cache expires if errors.Is(err, ErrProfileUnauthorized) || errors.Is(err, ErrProfileInternalError) { + cli.ProfileCache.lock.Lock() + defer cli.ProfileCache.lock.Unlock() cli.ProfileCache.errors[signalID.String()] = &err cli.ProfileCache.lastFetched[signalID.String()] = time.Now() } @@ -147,6 +161,8 @@ func (cli *Client) RetrieveProfileByID(ctx context.Context, signalID uuid.UUID) } // If we get here, we have a valid profile, so cache it + cli.ProfileCache.lock.Lock() + defer cli.ProfileCache.lock.Unlock() cli.ProfileCache.profiles[signalID.String()] = profile cli.ProfileCache.lastFetched[signalID.String()] = time.Now() From be83b6133fa1556e623dc57e4cc43ac0a9fe1f3c Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Thu, 10 Apr 2025 18:30:43 +0300 Subject: [PATCH 315/580] backfill: set stream order for outgoing items (#593) --- pkg/connector/backfill.go | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/pkg/connector/backfill.go b/pkg/connector/backfill.go index ae6d196..2dde03f 100644 --- a/pkg/connector/backfill.go +++ b/pkg/connector/backfill.go @@ -107,17 +107,32 @@ func (s *SignalClient) FetchMessages(ctx context.Context, params bridgev2.FetchM } return uuid.Nil, nil } - for _, item := range items { + var prevStreamOrder int64 + findNextStreamOrder := func(i int) int64 { + for ; i < len(items); i++ { + inc, ok := items[i].DirectionalDetails.(*backuppb.ChatItem_Incoming) + if ok { + return int64(inc.Incoming.GetDateServerSent()) + } + } + return time.Now().UnixMilli() + } + for i, item := range items { var streamOrder int64 switch dt := item.DirectionalDetails.(type) { case *backuppb.ChatItem_Incoming: streamOrder = int64(dt.Incoming.GetDateServerSent()) + prevStreamOrder = streamOrder if !firstDirectionfulProcessed { firstDirectionfulProcessed = true isRead = dt.Incoming.Read } case *backuppb.ChatItem_Outgoing: - // TODO stream order? + streamOrder = int64(item.GetDateSent()) + // Ensure stream order is higher than previous incoming item, but lower than next incoming item + streamOrder = min(streamOrder, findNextStreamOrder(i+1)-1) + streamOrder = max(streamOrder, prevStreamOrder+1) + if !firstDirectionfulProcessed { firstDirectionfulProcessed = true isRead = true From 1a32ce06cc4ff087c885f3eb4f45396809a13eca Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Tue, 15 Apr 2025 15:20:37 +0300 Subject: [PATCH 316/580] libsignal: update to v0.70.0 --- pkg/libsignalgo/libsignal | 2 +- pkg/libsignalgo/libsignal-ffi.h | 2622 ++++++++++++++++--------------- pkg/libsignalgo/version.go | 2 +- 3 files changed, 1326 insertions(+), 1300 deletions(-) diff --git a/pkg/libsignalgo/libsignal b/pkg/libsignalgo/libsignal index 7b293c1..efe13e9 160000 --- a/pkg/libsignalgo/libsignal +++ b/pkg/libsignalgo/libsignal @@ -1 +1 @@ -Subproject commit 7b293c19e0c71f204d4596e8f31f95ec993ea080 +Subproject commit efe13e9b363d2c115dba61b76e5e53bbfc2874bc diff --git a/pkg/libsignalgo/libsignal-ffi.h b/pkg/libsignalgo/libsignal-ffi.h index 7470062..82f1f7f 100644 --- a/pkg/libsignalgo/libsignal-ffi.h +++ b/pkg/libsignalgo/libsignal-ffi.h @@ -29,11 +29,6 @@ SPDX-License-Identifier: AGPL-3.0-only #define SignalBackupId_LEN 16 -/** - * The encoded length of a [`FourCC`], in bytes. - */ -#define SignalFourCC_ENCODED_LEN 4 - #define SignalNUM_AUTH_CRED_ATTRIBUTES 3 #define SignalNUM_PROFILE_KEY_CRED_ATTRIBUTES 4 @@ -125,6 +120,11 @@ SPDX-License-Identifier: AGPL-3.0-only */ #define SignalSECONDS_PER_DAY 86400 +/** + * The encoded length of a [`FourCC`], in bytes. + */ +#define SignalFourCC_ENCODED_LEN 4 + typedef enum { SignalCiphertextMessageTypeWhisper = 2, SignalCiphertextMessageTypePreKey = 3, @@ -210,6 +210,8 @@ typedef enum { SignalErrorCodeSvrRotationMachineTooManySteps = 162, SignalErrorCodeAppExpired = 170, SignalErrorCodeDeviceDeregistered = 171, + SignalErrorCodeConnectionInvalidated = 172, + SignalErrorCodeConnectedElsewhere = 173, SignalErrorCodeBackupValidation = 180, } SignalErrorCode; @@ -226,6 +228,8 @@ typedef struct SignalAes256GcmSiv SignalAes256GcmSiv; typedef struct SignalAuthenticatedChatConnection SignalAuthenticatedChatConnection; +typedef struct SignalBridgedStringMap SignalBridgedStringMap; + typedef struct SignalCdsiLookup SignalCdsiLookup; typedef struct SignalCiphertextMessage SignalCiphertextMessage; @@ -329,6 +333,165 @@ typedef struct SignalUnidentifiedSenderMessageContent SignalUnidentifiedSenderMe typedef struct SignalValidatingMac SignalValidatingMac; +typedef struct { + SignalProtocolAddress *raw; +} SignalMutPointerProtocolAddress; + +typedef struct { + const SignalProtocolAddress *raw; +} SignalConstPointerProtocolAddress; + +typedef struct { + SignalAes256Ctr32 *raw; +} SignalMutPointerAes256Ctr32; + +typedef struct { + const unsigned char *base; + size_t length; +} SignalBorrowedBuffer; + +typedef struct { + unsigned char *base; + size_t length; +} SignalBorrowedMutableBuffer; + +typedef struct { + SignalAes256GcmDecryption *raw; +} SignalMutPointerAes256GcmDecryption; + +/** + * A representation of a array allocated on the Rust heap for use in C code. + */ +typedef struct { + unsigned char *base; + /** + * The number of elements in the buffer (not necessarily the number of bytes). + */ + size_t length; +} SignalOwnedBuffer; + +typedef struct { + SignalAes256GcmEncryption *raw; +} SignalMutPointerAes256GcmEncryption; + +typedef struct { + const SignalAes256GcmSiv *raw; +} SignalConstPointerAes256GcmSiv; + +typedef struct { + SignalAes256GcmSiv *raw; +} SignalMutPointerAes256GcmSiv; + +typedef struct { + SignalAuthenticatedChatConnection *raw; +} SignalMutPointerAuthenticatedChatConnection; + +typedef uint64_t SignalCancellationId; + +/** + * A C callback used to report the results of Rust futures. + * + * cbindgen will produce independent C types like `SignalCPromisei32` and + * `SignalCPromiseProtocolAddress`. + * + * This derives Copy because it behaves like a C type; nevertheless, a promise should still only be + * completed once. + */ +typedef struct { + void (*complete)(SignalFfiError *error, const SignalMutPointerAuthenticatedChatConnection *result, const void *context); + const void *context; + SignalCancellationId cancellation_id; +} SignalCPromiseMutPointerAuthenticatedChatConnection; + +typedef struct { + const SignalTokioAsyncContext *raw; +} SignalConstPointerTokioAsyncContext; + +typedef struct { + const SignalConnectionManager *raw; +} SignalConstPointerConnectionManager; + +/** + * A C callback used to report the results of Rust futures. + * + * cbindgen will produce independent C types like `SignalCPromisei32` and + * `SignalCPromiseProtocolAddress`. + * + * This derives Copy because it behaves like a C type; nevertheless, a promise should still only be + * completed once. + */ +typedef struct { + void (*complete)(SignalFfiError *error, const bool *result, const void *context); + const void *context; + SignalCancellationId cancellation_id; +} SignalCPromisebool; + +typedef struct { + const SignalAuthenticatedChatConnection *raw; +} SignalConstPointerAuthenticatedChatConnection; + +typedef SignalConnectionInfo SignalChatConnectionInfo; + +typedef struct { + SignalChatConnectionInfo *raw; +} SignalMutPointerChatConnectionInfo; + +typedef void (*SignalReceivedIncomingMessage)(void *ctx, SignalOwnedBuffer envelope, uint64_t timestamp_millis, SignalServerMessageAck *cleanup); + +typedef void (*SignalReceivedQueueEmpty)(void *ctx); + +/** + * A representation of a array allocated on the Rust heap for use in C code. + */ +typedef struct { + size_t *base; + /** + * The number of elements in the buffer (not necessarily the number of bytes). + */ + size_t length; +} SignalOwnedBufferOfusize; + +typedef struct { + SignalOwnedBuffer bytes; + SignalOwnedBufferOfusize lengths; +} SignalBytestringArray; + +typedef SignalBytestringArray SignalStringArray; + +typedef void (*SignalReceivedAlerts)(void *ctx, SignalStringArray alerts); + +typedef void (*SignalConnectionInterrupted)(void *ctx, SignalFfiError *error); + +typedef void (*SignalDestroyChatListener)(void *ctx); + +/** + * Callbacks for [`ChatListener`]. + * + * Callbacks will be serialized (i.e. two calls will not come in at the same time), but may not + * always happen on the same thread. Calls should be responded to promptly to avoid blocking later + * messages. + * + * # Safety + * + * This type contains raw pointers. Code that constructs an instance of this type must ensure + * memory safety assuming that + * - the callback function pointer fields are called with `ctx` as an argument; + * - the `destroy` function pointer field is called with `ctx` as an argument; + * - no function pointer fields are called after `destroy` is called. + */ +typedef struct { + void *ctx; + SignalReceivedIncomingMessage received_incoming_message; + SignalReceivedQueueEmpty received_queue_empty; + SignalReceivedAlerts received_alerts; + SignalConnectionInterrupted connection_interrupted; + SignalDestroyChatListener destroy; +} SignalFfiChatListenerStruct; + +typedef struct { + const SignalFfiChatListenerStruct *raw; +} SignalConstPointerFfiChatListenerStruct; + /** * A type alias to be used with [`OwnedBufferOf`], so that `OwnedBufferOf` and * `OwnedBufferOf<*const c_char>` get distinct names. @@ -346,6 +509,55 @@ typedef struct { size_t length; } SignalOwnedBufferOfCStringPtr; +typedef struct { + uint16_t status; + const char *message; + SignalOwnedBufferOfCStringPtr headers; + SignalOwnedBuffer body; +} SignalFfiChatResponse; + +/** + * A C callback used to report the results of Rust futures. + * + * cbindgen will produce independent C types like `SignalCPromisei32` and + * `SignalCPromiseProtocolAddress`. + * + * This derives Copy because it behaves like a C type; nevertheless, a promise should still only be + * completed once. + */ +typedef struct { + void (*complete)(SignalFfiError *error, const SignalFfiChatResponse *result, const void *context); + const void *context; + SignalCancellationId cancellation_id; +} SignalCPromiseFfiChatResponse; + +typedef struct { + const SignalHttpRequest *raw; +} SignalConstPointerHttpRequest; + +/** + * The fixed-width binary representation of a ServiceId. + * + * Rarely used. The variable-width format that privileges ACIs is preferred. + */ +typedef uint8_t SignalServiceIdFixedWidthBinaryBytes[17]; + +typedef struct { + SignalPrivateKey *raw; +} SignalMutPointerPrivateKey; + +typedef struct { + SignalBridgedStringMap *raw; +} SignalMutPointerBridgedStringMap; + +typedef struct { + const SignalBridgedStringMap *raw; +} SignalConstPointerBridgedStringMap; + +typedef struct { + SignalSgxClientState *raw; +} SignalMutPointerSgxClientState; + typedef struct { /** * Telephone number, as an unformatted e164. @@ -366,64 +578,93 @@ typedef struct { size_t length; } SignalOwnedBufferOfFfiCdsiLookupResponseEntry; -/** - * A representation of a array allocated on the Rust heap for use in C code. - */ typedef struct { - unsigned char *base; - /** - * The number of elements in the buffer (not necessarily the number of bytes). - */ - size_t length; -} SignalOwnedBuffer; + SignalOwnedBufferOfFfiCdsiLookupResponseEntry entries; + int32_t debug_permits_used; +} SignalFfiCdsiLookupResponse; /** - * A representation of a array allocated on the Rust heap for use in C code. + * A C callback used to report the results of Rust futures. + * + * cbindgen will produce independent C types like `SignalCPromisei32` and + * `SignalCPromiseProtocolAddress`. + * + * This derives Copy because it behaves like a C type; nevertheless, a promise should still only be + * completed once. */ typedef struct { - size_t *base; - /** - * The number of elements in the buffer (not necessarily the number of bytes). - */ - size_t length; -} SignalOwnedBufferOfusize; + void (*complete)(SignalFfiError *error, const SignalFfiCdsiLookupResponse *result, const void *context); + const void *context; + SignalCancellationId cancellation_id; +} SignalCPromiseFfiCdsiLookupResponse; typedef struct { - SignalOwnedBuffer bytes; - SignalOwnedBufferOfusize lengths; -} SignalBytestringArray; + const SignalCdsiLookup *raw; +} SignalConstPointerCdsiLookup; typedef struct { - SignalProtocolAddress *raw; -} SignalMutPointerProtocolAddress; + SignalCdsiLookup *raw; +} SignalMutPointerCdsiLookup; -typedef SignalBytestringArray SignalStringArray; +/** + * A C callback used to report the results of Rust futures. + * + * cbindgen will produce independent C types like `SignalCPromisei32` and + * `SignalCPromiseProtocolAddress`. + * + * This derives Copy because it behaves like a C type; nevertheless, a promise should still only be + * completed once. + */ +typedef struct { + void (*complete)(SignalFfiError *error, const SignalMutPointerCdsiLookup *result, const void *context); + const void *context; + SignalCancellationId cancellation_id; +} SignalCPromiseMutPointerCdsiLookup; typedef struct { - SignalPrivateKey *raw; -} SignalMutPointerPrivateKey; + const SignalLookupRequest *raw; +} SignalConstPointerLookupRequest; typedef struct { - SignalPublicKey *raw; -} SignalMutPointerPublicKey; + const SignalChatConnectionInfo *raw; +} SignalConstPointerChatConnectionInfo; typedef struct { - const unsigned char *base; - size_t length; -} SignalBorrowedBuffer; + SignalCiphertextMessage *raw; +} SignalMutPointerCiphertextMessage; typedef struct { - const SignalPublicKey *raw; -} SignalConstPointerPublicKey; + const SignalPlaintextContent *raw; +} SignalConstPointerPlaintextContent; + +typedef struct { + const SignalCiphertextMessage *raw; +} SignalConstPointerCiphertextMessage; + +typedef struct { + SignalConnectionInfo *raw; +} SignalMutPointerConnectionInfo; + +typedef struct { + SignalConnectionManager *raw; +} SignalMutPointerConnectionManager; + +typedef struct { + const SignalConnectionProxyConfig *raw; +} SignalConstPointerConnectionProxyConfig; + +typedef struct { + SignalConnectionProxyConfig *raw; +} SignalMutPointerConnectionProxyConfig; + +typedef struct { + const SignalMessage *raw; +} SignalConstPointerSignalMessage; typedef struct { SignalSessionRecord *raw; } SignalMutPointerSessionRecord; -typedef struct { - const SignalProtocolAddress *raw; -} SignalConstPointerProtocolAddress; - typedef int (*SignalLoadSession)(void *store_ctx, SignalMutPointerSessionRecord *recordp, SignalConstPointerProtocolAddress address); typedef struct { @@ -446,8 +687,16 @@ typedef int (*SignalGetIdentityKeyPair)(void *store_ctx, SignalMutPointerPrivate typedef int (*SignalGetLocalRegistrationId)(void *store_ctx, uint32_t *idp); +typedef struct { + const SignalPublicKey *raw; +} SignalConstPointerPublicKey; + typedef int (*SignalSaveIdentityKey)(void *store_ctx, SignalConstPointerProtocolAddress address, SignalConstPointerPublicKey public_key); +typedef struct { + SignalPublicKey *raw; +} SignalMutPointerPublicKey; + typedef int (*SignalGetIdentityKey)(void *store_ctx, SignalMutPointerPublicKey *public_keyp, SignalConstPointerProtocolAddress address); typedef int (*SignalIsTrustedIdentity)(void *store_ctx, SignalConstPointerProtocolAddress address, SignalConstPointerPublicKey public_key, unsigned int direction); @@ -465,6 +714,10 @@ typedef struct { const SignalIdentityKeyStore *raw; } SignalConstPointerFfiIdentityKeyStoreStruct; +typedef struct { + const SignalPreKeySignalMessage *raw; +} SignalConstPointerPreKeySignalMessage; + typedef struct { SignalPreKeyRecord *raw; } SignalMutPointerPreKeyRecord; @@ -512,44 +765,30 @@ typedef struct { const SignalSignedPreKeyStore *raw; } SignalConstPointerFfiSignedPreKeyStoreStruct; -typedef void (*SignalLogCallback)(void *ctx, SignalLogLevel level, const char *file, uint32_t line, const char *message); +typedef struct { + SignalKyberPreKeyRecord *raw; +} SignalMutPointerKyberPreKeyRecord; -typedef void (*SignalLogFlushCallback)(void *ctx); +typedef int (*SignalLoadKyberPreKey)(void *store_ctx, SignalMutPointerKyberPreKeyRecord *recordp, uint32_t id); + +typedef struct { + const SignalKyberPreKeyRecord *raw; +} SignalConstPointerKyberPreKeyRecord; + +typedef int (*SignalStoreKyberPreKey)(void *store_ctx, uint32_t id, SignalConstPointerKyberPreKeyRecord record); + +typedef int (*SignalMarkKyberPreKeyUsed)(void *store_ctx, uint32_t id); typedef struct { void *ctx; - SignalLogCallback log; - SignalLogFlushCallback flush; -} SignalFfiLogger; + SignalLoadKyberPreKey load_kyber_pre_key; + SignalStoreKyberPreKey store_kyber_pre_key; + SignalMarkKyberPreKeyUsed mark_kyber_pre_key_used; +} SignalKyberPreKeyStore; typedef struct { - SignalAes256GcmSiv *raw; -} SignalMutPointerAes256GcmSiv; - -typedef struct { - SignalAes256Ctr32 *raw; -} SignalMutPointerAes256Ctr32; - -typedef struct { - SignalAes256GcmEncryption *raw; -} SignalMutPointerAes256GcmEncryption; - -typedef struct { - SignalAes256GcmDecryption *raw; -} SignalMutPointerAes256GcmDecryption; - -typedef struct { - unsigned char *base; - size_t length; -} SignalBorrowedMutableBuffer; - -typedef struct { - const SignalAes256GcmSiv *raw; -} SignalConstPointerAes256GcmSiv; - -typedef struct { - SignalCiphertextMessage *raw; -} SignalMutPointerCiphertextMessage; + const SignalKyberPreKeyStore *raw; +} SignalConstPointerFfiKyberPreKeyStoreStruct; typedef struct { SignalDecryptionErrorMessage *raw; @@ -568,92 +807,69 @@ typedef struct { } SignalConstPointerFingerprint; typedef struct { - SignalPlaintextContent *raw; -} SignalMutPointerPlaintextContent; + SignalSenderKeyRecord *raw; +} SignalMutPointerSenderKeyRecord; + +typedef int (*SignalLoadSenderKey)(void *store_ctx, SignalMutPointerSenderKeyRecord*, SignalConstPointerProtocolAddress, const uint8_t (*distribution_id)[16]); typedef struct { - const SignalPlaintextContent *raw; -} SignalConstPointerPlaintextContent; + const SignalSenderKeyRecord *raw; +} SignalConstPointerSenderKeyRecord; + +typedef int (*SignalStoreSenderKey)(void *store_ctx, SignalConstPointerProtocolAddress, const uint8_t (*distribution_id)[16], SignalConstPointerSenderKeyRecord); typedef struct { - SignalPreKeyBundle *raw; -} SignalMutPointerPreKeyBundle; + void *ctx; + SignalLoadSenderKey load_sender_key; + SignalStoreSenderKey store_sender_key; +} SignalSenderKeyStore; typedef struct { - const SignalPreKeyBundle *raw; -} SignalConstPointerPreKeyBundle; + const SignalSenderKeyStore *raw; +} SignalConstPointerFfiSenderKeyStoreStruct; typedef struct { - SignalPreKeySignalMessage *raw; -} SignalMutPointerPreKeySignalMessage; + const SignalServerSecretParams *raw; +} SignalConstPointerServerSecretParams; typedef struct { - const SignalPreKeySignalMessage *raw; -} SignalConstPointerPreKeySignalMessage; + const SignalBorrowedBuffer *base; + size_t length; +} SignalBorrowedSliceOfBuffers; + +typedef struct { + const SignalServerPublicParams *raw; +} SignalConstPointerServerPublicParams; + +typedef struct { + SignalHsmEnclaveClient *raw; +} SignalMutPointerHsmEnclaveClient; + +typedef struct { + const SignalHsmEnclaveClient *raw; +} SignalConstPointerHsmEnclaveClient; + +typedef struct { + SignalHttpRequest *raw; +} SignalMutPointerHttpRequest; typedef struct { const SignalPrivateKey *raw; } SignalConstPointerPrivateKey; typedef struct { - SignalSenderCertificate *raw; -} SignalMutPointerSenderCertificate; + SignalIncrementalMac *raw; +} SignalMutPointerIncrementalMac; + +typedef void (*SignalLogCallback)(void *ctx, SignalLogLevel level, const char *file, uint32_t line, const char *message); + +typedef void (*SignalLogFlushCallback)(void *ctx); typedef struct { - const SignalSenderCertificate *raw; -} SignalConstPointerSenderCertificate; - -typedef struct { - SignalSenderKeyDistributionMessage *raw; -} SignalMutPointerSenderKeyDistributionMessage; - -typedef struct { - const SignalSenderKeyDistributionMessage *raw; -} SignalConstPointerSenderKeyDistributionMessage; - -typedef struct { - SignalSenderKeyMessage *raw; -} SignalMutPointerSenderKeyMessage; - -typedef struct { - const SignalSenderKeyMessage *raw; -} SignalConstPointerSenderKeyMessage; - -typedef struct { - SignalSenderKeyRecord *raw; -} SignalMutPointerSenderKeyRecord; - -typedef struct { - const SignalSenderKeyRecord *raw; -} SignalConstPointerSenderKeyRecord; - -typedef struct { - SignalServerCertificate *raw; -} SignalMutPointerServerCertificate; - -typedef struct { - const SignalServerCertificate *raw; -} SignalConstPointerServerCertificate; - -typedef struct { - SignalMessage *raw; -} SignalMutPointerSignalMessage; - -typedef struct { - const SignalMessage *raw; -} SignalConstPointerSignalMessage; - -typedef struct { - SignalKyberPreKeyRecord *raw; -} SignalMutPointerKyberPreKeyRecord; - -typedef struct { - const SignalKyberPreKeyRecord *raw; -} SignalConstPointerKyberPreKeyRecord; - -typedef struct { - SignalUnidentifiedSenderMessageContent *raw; -} SignalMutPointerUnidentifiedSenderMessageContent; + void *ctx; + SignalLogCallback log; + SignalLogFlushCallback flush; +} SignalFfiLogger; typedef SignalKeyPair SignalKyberKeyPair; @@ -671,10 +887,6 @@ typedef struct { SignalKyberPublicKey *raw; } SignalMutPointerKyberPublicKey; -typedef struct { - const SignalKyberPublicKey *raw; -} SignalConstPointerKyberPublicKey; - /** * A KEM secret key with the ability to decapsulate a shared secret. */ @@ -686,359 +898,30 @@ typedef struct { SignalKyberSecretKey *raw; } SignalMutPointerKyberSecretKey; +typedef struct { + const SignalKyberPublicKey *raw; +} SignalConstPointerKyberPublicKey; + typedef struct { const SignalKyberSecretKey *raw; } SignalConstPointerKyberSecretKey; -/** - * The fixed-width binary representation of a ServiceId. - * - * Rarely used. The variable-width format that privileges ACIs is preferred. - */ -typedef uint8_t SignalServiceIdFixedWidthBinaryBytes[17]; - -typedef struct { - const SignalUnidentifiedSenderMessageContent *raw; -} SignalConstPointerUnidentifiedSenderMessageContent; - -typedef struct { - const SignalCiphertextMessage *raw; -} SignalConstPointerCiphertextMessage; - -typedef int (*SignalLoadKyberPreKey)(void *store_ctx, SignalMutPointerKyberPreKeyRecord *recordp, uint32_t id); - -typedef int (*SignalStoreKyberPreKey)(void *store_ctx, uint32_t id, SignalConstPointerKyberPreKeyRecord record); - -typedef int (*SignalMarkKyberPreKeyUsed)(void *store_ctx, uint32_t id); - -typedef struct { - void *ctx; - SignalLoadKyberPreKey load_kyber_pre_key; - SignalStoreKyberPreKey store_kyber_pre_key; - SignalMarkKyberPreKeyUsed mark_kyber_pre_key_used; -} SignalKyberPreKeyStore; - -typedef struct { - const SignalKyberPreKeyStore *raw; -} SignalConstPointerFfiKyberPreKeyStoreStruct; - -typedef struct { - const SignalConstPointerProtocolAddress *base; - size_t length; -} SignalBorrowedSliceOfConstPointerProtocolAddress; - -typedef struct { - const SignalConstPointerSessionRecord *base; - size_t length; -} SignalBorrowedSliceOfConstPointerSessionRecord; - -typedef int (*SignalLoadSenderKey)(void *store_ctx, SignalMutPointerSenderKeyRecord*, SignalConstPointerProtocolAddress, const uint8_t (*distribution_id)[16]); - -typedef int (*SignalStoreSenderKey)(void *store_ctx, SignalConstPointerProtocolAddress, const uint8_t (*distribution_id)[16], SignalConstPointerSenderKeyRecord); - -typedef struct { - void *ctx; - SignalLoadSenderKey load_sender_key; - SignalStoreSenderKey store_sender_key; -} SignalSenderKeyStore; - -typedef struct { - const SignalSenderKeyStore *raw; -} SignalConstPointerFfiSenderKeyStoreStruct; - -typedef struct { - SignalSgxClientState *raw; -} SignalMutPointerSgxClientState; - -typedef struct { - SignalHsmEnclaveClient *raw; -} SignalMutPointerHsmEnclaveClient; - -typedef struct { - const SignalHsmEnclaveClient *raw; -} SignalConstPointerHsmEnclaveClient; - -typedef struct { - const SignalSgxClientState *raw; -} SignalConstPointerSgxClientState; - -typedef struct { - SignalServerPublicParams *raw; -} SignalMutPointerServerPublicParams; - -typedef struct { - const SignalServerPublicParams *raw; -} SignalConstPointerServerPublicParams; - -typedef struct { - SignalServerSecretParams *raw; -} SignalMutPointerServerSecretParams; - -typedef struct { - const SignalServerSecretParams *raw; -} SignalConstPointerServerSecretParams; - -typedef struct { - const SignalBorrowedBuffer *base; - size_t length; -} SignalBorrowedSliceOfBuffers; - -typedef struct { - SignalConnectionInfo *raw; -} SignalMutPointerConnectionInfo; - -typedef struct { - SignalConnectionProxyConfig *raw; -} SignalMutPointerConnectionProxyConfig; - -typedef struct { - const SignalConnectionProxyConfig *raw; -} SignalConstPointerConnectionProxyConfig; - -typedef struct { - SignalConnectionManager *raw; -} SignalMutPointerConnectionManager; - -typedef struct { - const SignalConnectionManager *raw; -} SignalConstPointerConnectionManager; - typedef struct { SignalLookupRequest *raw; } SignalMutPointerLookupRequest; -typedef struct { - const SignalLookupRequest *raw; -} SignalConstPointerLookupRequest; - -typedef struct { - SignalCdsiLookup *raw; -} SignalMutPointerCdsiLookup; - -typedef uint64_t SignalCancellationId; - -/** - * A C callback used to report the results of Rust futures. - * - * cbindgen will produce independent C types like `SignalCPromisei32` and - * `SignalCPromiseProtocolAddress`. - * - * This derives Copy because it behaves like a C type; nevertheless, a promise should still only be - * completed once. - */ -typedef struct { - void (*complete)(SignalFfiError *error, const SignalMutPointerCdsiLookup *result, const void *context); - const void *context; - SignalCancellationId cancellation_id; -} SignalCPromiseMutPointerCdsiLookup; - -typedef struct { - const SignalTokioAsyncContext *raw; -} SignalConstPointerTokioAsyncContext; - -typedef struct { - const SignalCdsiLookup *raw; -} SignalConstPointerCdsiLookup; - -typedef struct { - SignalOwnedBufferOfFfiCdsiLookupResponseEntry entries; - int32_t debug_permits_used; -} SignalFfiCdsiLookupResponse; - -/** - * A C callback used to report the results of Rust futures. - * - * cbindgen will produce independent C types like `SignalCPromisei32` and - * `SignalCPromiseProtocolAddress`. - * - * This derives Copy because it behaves like a C type; nevertheless, a promise should still only be - * completed once. - */ -typedef struct { - void (*complete)(SignalFfiError *error, const SignalFfiCdsiLookupResponse *result, const void *context); - const void *context; - SignalCancellationId cancellation_id; -} SignalCPromiseFfiCdsiLookupResponse; - -typedef struct { - SignalHttpRequest *raw; -} SignalMutPointerHttpRequest; - -typedef struct { - SignalUnauthenticatedChatConnection *raw; -} SignalMutPointerUnauthenticatedChatConnection; - -typedef struct { - SignalAuthenticatedChatConnection *raw; -} SignalMutPointerAuthenticatedChatConnection; - -typedef struct { - const SignalHttpRequest *raw; -} SignalConstPointerHttpRequest; - -typedef SignalConnectionInfo SignalChatConnectionInfo; - -typedef struct { - const SignalChatConnectionInfo *raw; -} SignalConstPointerChatConnectionInfo; - -/** - * A C callback used to report the results of Rust futures. - * - * cbindgen will produce independent C types like `SignalCPromisei32` and - * `SignalCPromiseProtocolAddress`. - * - * This derives Copy because it behaves like a C type; nevertheless, a promise should still only be - * completed once. - */ -typedef struct { - void (*complete)(SignalFfiError *error, const SignalMutPointerUnauthenticatedChatConnection *result, const void *context); - const void *context; - SignalCancellationId cancellation_id; -} SignalCPromiseMutPointerUnauthenticatedChatConnection; - -typedef struct { - const SignalUnauthenticatedChatConnection *raw; -} SignalConstPointerUnauthenticatedChatConnection; - -typedef void (*SignalReceivedIncomingMessage)(void *ctx, SignalOwnedBuffer envelope, uint64_t timestamp_millis, SignalServerMessageAck *cleanup); - -typedef void (*SignalReceivedQueueEmpty)(void *ctx); - -typedef void (*SignalReceivedAlerts)(void *ctx, SignalStringArray alerts); - -typedef void (*SignalConnectionInterrupted)(void *ctx, SignalFfiError *error); - -typedef void (*SignalDestroyChatListener)(void *ctx); - -/** - * Callbacks for [`ChatListener`]. - * - * Callbacks will be serialized (i.e. two calls will not come in at the same time), but may not - * always happen on the same thread. Calls should be responded to promptly to avoid blocking later - * messages. - * - * # Safety - * - * This type contains raw pointers. Code that constructs an instance of this type must ensure - * memory safety assuming that - * - the callback function pointer fields are called with `ctx` as an argument; - * - the `destroy` function pointer field is called with `ctx` as an argument; - * - no function pointer fields are called after `destroy` is called. - */ -typedef struct { - void *ctx; - SignalReceivedIncomingMessage received_incoming_message; - SignalReceivedQueueEmpty received_queue_empty; - SignalReceivedAlerts received_alerts; - SignalConnectionInterrupted connection_interrupted; - SignalDestroyChatListener destroy; -} SignalFfiChatListenerStruct; - -typedef struct { - const SignalFfiChatListenerStruct *raw; -} SignalConstPointerFfiChatListenerStruct; - -typedef struct { - uint16_t status; - const char *message; - SignalOwnedBufferOfCStringPtr headers; - SignalOwnedBuffer body; -} SignalFfiChatResponse; - -/** - * A C callback used to report the results of Rust futures. - * - * cbindgen will produce independent C types like `SignalCPromisei32` and - * `SignalCPromiseProtocolAddress`. - * - * This derives Copy because it behaves like a C type; nevertheless, a promise should still only be - * completed once. - */ -typedef struct { - void (*complete)(SignalFfiError *error, const SignalFfiChatResponse *result, const void *context); - const void *context; - SignalCancellationId cancellation_id; -} SignalCPromiseFfiChatResponse; - -/** - * A C callback used to report the results of Rust futures. - * - * cbindgen will produce independent C types like `SignalCPromisei32` and - * `SignalCPromiseProtocolAddress`. - * - * This derives Copy because it behaves like a C type; nevertheless, a promise should still only be - * completed once. - */ -typedef struct { - void (*complete)(SignalFfiError *error, const bool *result, const void *context); - const void *context; - SignalCancellationId cancellation_id; -} SignalCPromisebool; - -typedef struct { - SignalChatConnectionInfo *raw; -} SignalMutPointerChatConnectionInfo; - -/** - * A C callback used to report the results of Rust futures. - * - * cbindgen will produce independent C types like `SignalCPromisei32` and - * `SignalCPromiseProtocolAddress`. - * - * This derives Copy because it behaves like a C type; nevertheless, a promise should still only be - * completed once. - */ -typedef struct { - void (*complete)(SignalFfiError *error, const SignalMutPointerAuthenticatedChatConnection *result, const void *context); - const void *context; - SignalCancellationId cancellation_id; -} SignalCPromiseMutPointerAuthenticatedChatConnection; - -typedef struct { - const SignalAuthenticatedChatConnection *raw; -} SignalConstPointerAuthenticatedChatConnection; - -typedef struct { - SignalServerMessageAck *raw; -} SignalMutPointerServerMessageAck; - -typedef struct { - const SignalServerMessageAck *raw; -} SignalConstPointerServerMessageAck; - -typedef struct { - SignalTokioAsyncContext *raw; -} SignalMutPointerTokioAsyncContext; - -typedef struct { - SignalPinHash *raw; -} SignalMutPointerPinHash; - -typedef struct { - const SignalPinHash *raw; -} SignalConstPointerPinHash; - -typedef struct { - SignalIncrementalMac *raw; -} SignalMutPointerIncrementalMac; - -typedef struct { - SignalValidatingMac *raw; -} SignalMutPointerValidatingMac; - typedef struct { SignalMessageBackupKey *raw; } SignalMutPointerMessageBackupKey; -typedef struct { - SignalMessageBackupValidationOutcome *raw; -} SignalMutPointerMessageBackupValidationOutcome; - typedef struct { const SignalMessageBackupKey *raw; } SignalConstPointerMessageBackupKey; +typedef struct { + SignalMessageBackupValidationOutcome *raw; +} SignalMutPointerMessageBackupValidationOutcome; + typedef struct { const SignalMessageBackupValidationOutcome *raw; } SignalConstPointerMessageBackupValidationOutcome; @@ -1058,17 +941,146 @@ typedef struct { } SignalConstPointerFfiInputStreamStruct; typedef struct { - SignalOnlineBackupValidator *raw; -} SignalMutPointerOnlineBackupValidator; + SignalMessage *raw; +} SignalMutPointerSignalMessage; typedef struct { SignalSanitizedMetadata *raw; } SignalMutPointerSanitizedMetadata; +typedef struct { + SignalOnlineBackupValidator *raw; +} SignalMutPointerOnlineBackupValidator; + +typedef struct { + const SignalPinHash *raw; +} SignalConstPointerPinHash; + +typedef struct { + SignalPinHash *raw; +} SignalMutPointerPinHash; + +typedef struct { + SignalPlaintextContent *raw; +} SignalMutPointerPlaintextContent; + +typedef struct { + SignalPreKeyBundle *raw; +} SignalMutPointerPreKeyBundle; + +typedef struct { + const SignalPreKeyBundle *raw; +} SignalConstPointerPreKeyBundle; + +typedef struct { + SignalPreKeySignalMessage *raw; +} SignalMutPointerPreKeySignalMessage; + +typedef struct { + const SignalSenderKeyDistributionMessage *raw; +} SignalConstPointerSenderKeyDistributionMessage; + typedef struct { const SignalSanitizedMetadata *raw; } SignalConstPointerSanitizedMetadata; +typedef struct { + const SignalConstPointerProtocolAddress *base; + size_t length; +} SignalBorrowedSliceOfConstPointerProtocolAddress; + +typedef struct { + const SignalConstPointerSessionRecord *base; + size_t length; +} SignalBorrowedSliceOfConstPointerSessionRecord; + +typedef struct { + const SignalUnidentifiedSenderMessageContent *raw; +} SignalConstPointerUnidentifiedSenderMessageContent; + +typedef struct { + SignalUnidentifiedSenderMessageContent *raw; +} SignalMutPointerUnidentifiedSenderMessageContent; + +typedef struct { + SignalSenderCertificate *raw; +} SignalMutPointerSenderCertificate; + +typedef struct { + const SignalSenderCertificate *raw; +} SignalConstPointerSenderCertificate; + +typedef struct { + SignalServerCertificate *raw; +} SignalMutPointerServerCertificate; + +typedef struct { + const SignalServerCertificate *raw; +} SignalConstPointerServerCertificate; + +typedef struct { + SignalSenderKeyDistributionMessage *raw; +} SignalMutPointerSenderKeyDistributionMessage; + +typedef struct { + SignalSenderKeyMessage *raw; +} SignalMutPointerSenderKeyMessage; + +typedef struct { + const SignalSenderKeyMessage *raw; +} SignalConstPointerSenderKeyMessage; + +typedef struct { + SignalServerMessageAck *raw; +} SignalMutPointerServerMessageAck; + +typedef struct { + const SignalServerMessageAck *raw; +} SignalConstPointerServerMessageAck; + +typedef struct { + SignalServerPublicParams *raw; +} SignalMutPointerServerPublicParams; + +typedef struct { + SignalServerSecretParams *raw; +} SignalMutPointerServerSecretParams; + +typedef struct { + const SignalSgxClientState *raw; +} SignalConstPointerSgxClientState; + +typedef struct { + SignalTokioAsyncContext *raw; +} SignalMutPointerTokioAsyncContext; + +typedef struct { + SignalUnauthenticatedChatConnection *raw; +} SignalMutPointerUnauthenticatedChatConnection; + +/** + * A C callback used to report the results of Rust futures. + * + * cbindgen will produce independent C types like `SignalCPromisei32` and + * `SignalCPromiseProtocolAddress`. + * + * This derives Copy because it behaves like a C type; nevertheless, a promise should still only be + * completed once. + */ +typedef struct { + void (*complete)(SignalFfiError *error, const SignalMutPointerUnauthenticatedChatConnection *result, const void *context); + const void *context; + SignalCancellationId cancellation_id; +} SignalCPromiseMutPointerUnauthenticatedChatConnection; + +typedef struct { + const SignalUnauthenticatedChatConnection *raw; +} SignalConstPointerUnauthenticatedChatConnection; + +typedef struct { + SignalValidatingMac *raw; +} SignalMutPointerValidatingMac; + typedef SignalInputStream SignalSyncInputStream; typedef struct { @@ -1077,57 +1089,31 @@ typedef struct { typedef uint8_t SignalRandomnessBytes[SignalRANDOMNESS_LEN]; -void signal_print_ptr(const void *p); +SignalFfiError *signal_account_entropy_pool_derive_backup_key(uint8_t (*out)[SignalBACKUP_KEY_LEN], const char *account_entropy); -void signal_free_string(const char *buf); +SignalFfiError *signal_account_entropy_pool_derive_svr_key(uint8_t (*out)[SignalSVR_KEY_LEN], const char *account_entropy); -void signal_free_buffer(const unsigned char *buf, size_t buf_len); +SignalFfiError *signal_account_entropy_pool_generate(const char **out); -void signal_free_list_of_strings(SignalOwnedBufferOfCStringPtr buffer); +SignalFfiError *signal_account_entropy_pool_is_valid(bool *out, const char *account_entropy); -void signal_free_lookup_response_entry_list(SignalOwnedBufferOfFfiCdsiLookupResponseEntry buffer); +SignalFfiError *signal_address_clone(SignalMutPointerProtocolAddress *new_obj, SignalConstPointerProtocolAddress obj); -void signal_free_bytestring_array(SignalBytestringArray array); +SignalFfiError *signal_address_destroy(SignalMutPointerProtocolAddress p); -SignalFfiError *signal_error_get_message(const SignalFfiError *err, const char **out); +SignalFfiError *signal_address_get_device_id(uint32_t *out, SignalConstPointerProtocolAddress obj); -SignalFfiError *signal_error_get_address(const SignalFfiError *err, SignalMutPointerProtocolAddress *out); +SignalFfiError *signal_address_get_name(const char **out, SignalConstPointerProtocolAddress obj); -SignalFfiError *signal_error_get_uuid(const SignalFfiError *err, uint8_t (*out)[16]); - -uint32_t signal_error_get_type(const SignalFfiError *err); - -SignalFfiError *signal_error_get_retry_after_seconds(const SignalFfiError *err, uint32_t *out); - -SignalFfiError *signal_error_get_tries_remaining(const SignalFfiError *err, uint32_t *out); - -SignalFfiError *signal_error_get_unknown_fields(const SignalFfiError *err, SignalStringArray *out); - -void signal_error_free(SignalFfiError *err); - -SignalFfiError *signal_identitykeypair_deserialize(SignalMutPointerPrivateKey *private_key, SignalMutPointerPublicKey *public_key, SignalBorrowedBuffer input); - -SignalFfiError *signal_sealed_session_cipher_decrypt(SignalOwnedBuffer *out, const char **sender_e164, const char **sender_uuid, uint32_t *sender_device_id, SignalBorrowedBuffer ctext, SignalConstPointerPublicKey trust_root, uint64_t timestamp, const char *local_e164, const char *local_uuid, unsigned int local_device_id, SignalConstPointerFfiSessionStoreStruct session_store, SignalConstPointerFfiIdentityKeyStoreStruct identity_store, SignalConstPointerFfiPreKeyStoreStruct prekey_store, SignalConstPointerFfiSignedPreKeyStoreStruct signed_prekey_store); - -bool signal_init_logger(SignalLogLevel max_level, SignalFfiLogger logger); - -SignalFfiError *signal_aes256_gcm_siv_destroy(SignalMutPointerAes256GcmSiv p); +SignalFfiError *signal_address_new(SignalMutPointerProtocolAddress *out, const char *name, uint32_t device_id); SignalFfiError *signal_aes256_ctr32_destroy(SignalMutPointerAes256Ctr32 p); -SignalFfiError *signal_aes256_gcm_encryption_destroy(SignalMutPointerAes256GcmEncryption p); - -SignalFfiError *signal_aes256_gcm_decryption_destroy(SignalMutPointerAes256GcmDecryption p); - SignalFfiError *signal_aes256_ctr32_new(SignalMutPointerAes256Ctr32 *out, SignalBorrowedBuffer key, SignalBorrowedBuffer nonce, uint32_t initial_ctr); SignalFfiError *signal_aes256_ctr32_process(SignalMutPointerAes256Ctr32 ctr, SignalBorrowedMutableBuffer data, uint32_t offset, uint32_t length); -SignalFfiError *signal_aes256_gcm_encryption_new(SignalMutPointerAes256GcmEncryption *out, SignalBorrowedBuffer key, SignalBorrowedBuffer nonce, SignalBorrowedBuffer associated_data); - -SignalFfiError *signal_aes256_gcm_encryption_update(SignalMutPointerAes256GcmEncryption gcm, SignalBorrowedMutableBuffer data, uint32_t offset, uint32_t length); - -SignalFfiError *signal_aes256_gcm_encryption_compute_tag(SignalOwnedBuffer *out, SignalMutPointerAes256GcmEncryption gcm); +SignalFfiError *signal_aes256_gcm_decryption_destroy(SignalMutPointerAes256GcmDecryption p); SignalFfiError *signal_aes256_gcm_decryption_new(SignalMutPointerAes256GcmDecryption *out, SignalBorrowedBuffer key, SignalBorrowedBuffer nonce, SignalBorrowedBuffer associated_data); @@ -1135,677 +1121,47 @@ SignalFfiError *signal_aes256_gcm_decryption_update(SignalMutPointerAes256GcmDec SignalFfiError *signal_aes256_gcm_decryption_verify_tag(bool *out, SignalMutPointerAes256GcmDecryption gcm, SignalBorrowedBuffer tag); -SignalFfiError *signal_aes256_gcm_siv_new(SignalMutPointerAes256GcmSiv *out, SignalBorrowedBuffer key); +SignalFfiError *signal_aes256_gcm_encryption_compute_tag(SignalOwnedBuffer *out, SignalMutPointerAes256GcmEncryption gcm); -SignalFfiError *signal_aes256_gcm_siv_encrypt(SignalOwnedBuffer *out, SignalConstPointerAes256GcmSiv aes_gcm_siv_obj, SignalBorrowedBuffer ptext, SignalBorrowedBuffer nonce, SignalBorrowedBuffer associated_data); +SignalFfiError *signal_aes256_gcm_encryption_destroy(SignalMutPointerAes256GcmEncryption p); + +SignalFfiError *signal_aes256_gcm_encryption_new(SignalMutPointerAes256GcmEncryption *out, SignalBorrowedBuffer key, SignalBorrowedBuffer nonce, SignalBorrowedBuffer associated_data); + +SignalFfiError *signal_aes256_gcm_encryption_update(SignalMutPointerAes256GcmEncryption gcm, SignalBorrowedMutableBuffer data, uint32_t offset, uint32_t length); SignalFfiError *signal_aes256_gcm_siv_decrypt(SignalOwnedBuffer *out, SignalConstPointerAes256GcmSiv aes_gcm_siv, SignalBorrowedBuffer ctext, SignalBorrowedBuffer nonce, SignalBorrowedBuffer associated_data); -SignalFfiError *signal_ciphertext_message_destroy(SignalMutPointerCiphertextMessage p); +SignalFfiError *signal_aes256_gcm_siv_destroy(SignalMutPointerAes256GcmSiv p); -SignalFfiError *signal_decryption_error_message_destroy(SignalMutPointerDecryptionErrorMessage p); +SignalFfiError *signal_aes256_gcm_siv_encrypt(SignalOwnedBuffer *out, SignalConstPointerAes256GcmSiv aes_gcm_siv_obj, SignalBorrowedBuffer ptext, SignalBorrowedBuffer nonce, SignalBorrowedBuffer associated_data); -SignalFfiError *signal_decryption_error_message_clone(SignalMutPointerDecryptionErrorMessage *new_obj, SignalConstPointerDecryptionErrorMessage obj); - -SignalFfiError *signal_fingerprint_destroy(SignalMutPointerFingerprint p); - -SignalFfiError *signal_fingerprint_clone(SignalMutPointerFingerprint *new_obj, SignalConstPointerFingerprint obj); - -SignalFfiError *signal_plaintext_content_destroy(SignalMutPointerPlaintextContent p); - -SignalFfiError *signal_plaintext_content_clone(SignalMutPointerPlaintextContent *new_obj, SignalConstPointerPlaintextContent obj); - -SignalFfiError *signal_pre_key_bundle_destroy(SignalMutPointerPreKeyBundle p); - -SignalFfiError *signal_pre_key_bundle_clone(SignalMutPointerPreKeyBundle *new_obj, SignalConstPointerPreKeyBundle obj); - -SignalFfiError *signal_pre_key_record_destroy(SignalMutPointerPreKeyRecord p); - -SignalFfiError *signal_pre_key_record_clone(SignalMutPointerPreKeyRecord *new_obj, SignalConstPointerPreKeyRecord obj); - -SignalFfiError *signal_pre_key_signal_message_destroy(SignalMutPointerPreKeySignalMessage p); - -SignalFfiError *signal_pre_key_signal_message_clone(SignalMutPointerPreKeySignalMessage *new_obj, SignalConstPointerPreKeySignalMessage obj); - -SignalFfiError *signal_privatekey_destroy(SignalMutPointerPrivateKey p); - -SignalFfiError *signal_privatekey_clone(SignalMutPointerPrivateKey *new_obj, SignalConstPointerPrivateKey obj); - -SignalFfiError *signal_address_destroy(SignalMutPointerProtocolAddress p); - -SignalFfiError *signal_address_clone(SignalMutPointerProtocolAddress *new_obj, SignalConstPointerProtocolAddress obj); - -SignalFfiError *signal_publickey_destroy(SignalMutPointerPublicKey p); - -SignalFfiError *signal_publickey_clone(SignalMutPointerPublicKey *new_obj, SignalConstPointerPublicKey obj); - -SignalFfiError *signal_sender_certificate_destroy(SignalMutPointerSenderCertificate p); - -SignalFfiError *signal_sender_certificate_clone(SignalMutPointerSenderCertificate *new_obj, SignalConstPointerSenderCertificate obj); - -SignalFfiError *signal_sender_key_distribution_message_destroy(SignalMutPointerSenderKeyDistributionMessage p); - -SignalFfiError *signal_sender_key_distribution_message_clone(SignalMutPointerSenderKeyDistributionMessage *new_obj, SignalConstPointerSenderKeyDistributionMessage obj); - -SignalFfiError *signal_sender_key_message_destroy(SignalMutPointerSenderKeyMessage p); - -SignalFfiError *signal_sender_key_message_clone(SignalMutPointerSenderKeyMessage *new_obj, SignalConstPointerSenderKeyMessage obj); - -SignalFfiError *signal_sender_key_record_destroy(SignalMutPointerSenderKeyRecord p); - -SignalFfiError *signal_sender_key_record_clone(SignalMutPointerSenderKeyRecord *new_obj, SignalConstPointerSenderKeyRecord obj); - -SignalFfiError *signal_server_certificate_destroy(SignalMutPointerServerCertificate p); - -SignalFfiError *signal_server_certificate_clone(SignalMutPointerServerCertificate *new_obj, SignalConstPointerServerCertificate obj); - -SignalFfiError *signal_session_record_destroy(SignalMutPointerSessionRecord p); - -SignalFfiError *signal_session_record_clone(SignalMutPointerSessionRecord *new_obj, SignalConstPointerSessionRecord obj); - -SignalFfiError *signal_message_destroy(SignalMutPointerSignalMessage p); - -SignalFfiError *signal_message_clone(SignalMutPointerSignalMessage *new_obj, SignalConstPointerSignalMessage obj); - -SignalFfiError *signal_signed_pre_key_record_destroy(SignalMutPointerSignedPreKeyRecord p); - -SignalFfiError *signal_signed_pre_key_record_clone(SignalMutPointerSignedPreKeyRecord *new_obj, SignalConstPointerSignedPreKeyRecord obj); - -SignalFfiError *signal_kyber_pre_key_record_destroy(SignalMutPointerKyberPreKeyRecord p); - -SignalFfiError *signal_kyber_pre_key_record_clone(SignalMutPointerKyberPreKeyRecord *new_obj, SignalConstPointerKyberPreKeyRecord obj); - -SignalFfiError *signal_unidentified_sender_message_content_destroy(SignalMutPointerUnidentifiedSenderMessageContent p); - -SignalFfiError *signal_kyber_key_pair_destroy(SignalMutPointerKyberKeyPair p); - -SignalFfiError *signal_kyber_key_pair_clone(SignalMutPointerKyberKeyPair *new_obj, SignalConstPointerKyberKeyPair obj); - -SignalFfiError *signal_kyber_public_key_destroy(SignalMutPointerKyberPublicKey p); - -SignalFfiError *signal_kyber_public_key_clone(SignalMutPointerKyberPublicKey *new_obj, SignalConstPointerKyberPublicKey obj); - -SignalFfiError *signal_kyber_secret_key_destroy(SignalMutPointerKyberSecretKey p); - -SignalFfiError *signal_kyber_secret_key_clone(SignalMutPointerKyberSecretKey *new_obj, SignalConstPointerKyberSecretKey obj); - -SignalFfiError *signal_hkdf_derive(SignalBorrowedMutableBuffer output, SignalBorrowedBuffer ikm, SignalBorrowedBuffer label, SignalBorrowedBuffer salt); - -SignalFfiError *signal_service_id_service_id_binary(SignalOwnedBuffer *out, const SignalServiceIdFixedWidthBinaryBytes *value); - -SignalFfiError *signal_service_id_service_id_string(const char **out, const SignalServiceIdFixedWidthBinaryBytes *value); - -SignalFfiError *signal_service_id_service_id_log(const char **out, const SignalServiceIdFixedWidthBinaryBytes *value); - -SignalFfiError *signal_service_id_parse_from_service_id_binary(SignalServiceIdFixedWidthBinaryBytes *out, SignalBorrowedBuffer input); - -SignalFfiError *signal_service_id_parse_from_service_id_string(SignalServiceIdFixedWidthBinaryBytes *out, const char *input); - -SignalFfiError *signal_address_new(SignalMutPointerProtocolAddress *out, const char *name, uint32_t device_id); - -SignalFfiError *signal_publickey_deserialize(SignalMutPointerPublicKey *out, SignalBorrowedBuffer data); - -SignalFfiError *signal_publickey_serialize(SignalOwnedBuffer *out, SignalConstPointerPublicKey obj); - -SignalFfiError *signal_publickey_get_public_key_bytes(SignalOwnedBuffer *out, SignalConstPointerPublicKey obj); - -SignalFfiError *signal_address_get_device_id(uint32_t *out, SignalConstPointerProtocolAddress obj); - -SignalFfiError *signal_address_get_name(const char **out, SignalConstPointerProtocolAddress obj); - -SignalFfiError *signal_publickey_equals(bool *out, SignalConstPointerPublicKey lhs, SignalConstPointerPublicKey rhs); - -SignalFfiError *signal_publickey_compare(int32_t *out, SignalConstPointerPublicKey key1, SignalConstPointerPublicKey key2); - -SignalFfiError *signal_publickey_verify(bool *out, SignalConstPointerPublicKey key, SignalBorrowedBuffer message, SignalBorrowedBuffer signature); - -SignalFfiError *signal_privatekey_deserialize(SignalMutPointerPrivateKey *out, SignalBorrowedBuffer data); - -SignalFfiError *signal_privatekey_serialize(SignalOwnedBuffer *out, SignalConstPointerPrivateKey obj); - -SignalFfiError *signal_privatekey_generate(SignalMutPointerPrivateKey *out); - -SignalFfiError *signal_privatekey_get_public_key(SignalMutPointerPublicKey *out, SignalConstPointerPrivateKey k); - -SignalFfiError *signal_privatekey_sign(SignalOwnedBuffer *out, SignalConstPointerPrivateKey key, SignalBorrowedBuffer message); - -SignalFfiError *signal_privatekey_agree(SignalOwnedBuffer *out, SignalConstPointerPrivateKey private_key, SignalConstPointerPublicKey public_key); - -SignalFfiError *signal_kyber_public_key_serialize(SignalOwnedBuffer *out, SignalConstPointerKyberPublicKey obj); - -SignalFfiError *signal_kyber_public_key_deserialize(SignalMutPointerKyberPublicKey *out, SignalBorrowedBuffer data); - -SignalFfiError *signal_kyber_secret_key_serialize(SignalOwnedBuffer *out, SignalConstPointerKyberSecretKey obj); - -SignalFfiError *signal_kyber_secret_key_deserialize(SignalMutPointerKyberSecretKey *out, SignalBorrowedBuffer data); - -SignalFfiError *signal_kyber_public_key_equals(bool *out, SignalConstPointerKyberPublicKey lhs, SignalConstPointerKyberPublicKey rhs); - -SignalFfiError *signal_kyber_key_pair_generate(SignalMutPointerKyberKeyPair *out); - -SignalFfiError *signal_kyber_key_pair_get_public_key(SignalMutPointerKyberPublicKey *out, SignalConstPointerKyberKeyPair key_pair); - -SignalFfiError *signal_kyber_key_pair_get_secret_key(SignalMutPointerKyberSecretKey *out, SignalConstPointerKyberKeyPair key_pair); - -SignalFfiError *signal_identitykeypair_serialize(SignalOwnedBuffer *out, SignalConstPointerPublicKey public_key, SignalConstPointerPrivateKey private_key); - -SignalFfiError *signal_identitykeypair_sign_alternate_identity(SignalOwnedBuffer *out, SignalConstPointerPublicKey public_key, SignalConstPointerPrivateKey private_key, SignalConstPointerPublicKey other_identity); - -SignalFfiError *signal_identitykey_verify_alternate_identity(bool *out, SignalConstPointerPublicKey public_key, SignalConstPointerPublicKey other_identity, SignalBorrowedBuffer signature); - -SignalFfiError *signal_fingerprint_new(SignalMutPointerFingerprint *out, uint32_t iterations, uint32_t version, SignalBorrowedBuffer local_identifier, SignalConstPointerPublicKey local_key, SignalBorrowedBuffer remote_identifier, SignalConstPointerPublicKey remote_key); - -SignalFfiError *signal_fingerprint_scannable_encoding(SignalOwnedBuffer *out, SignalConstPointerFingerprint obj); - -SignalFfiError *signal_fingerprint_display_string(const char **out, SignalConstPointerFingerprint obj); - -SignalFfiError *signal_fingerprint_compare(bool *out, SignalBorrowedBuffer fprint1, SignalBorrowedBuffer fprint2); - -SignalFfiError *signal_message_deserialize(SignalMutPointerSignalMessage *out, SignalBorrowedBuffer data); - -SignalFfiError *signal_message_get_body(SignalOwnedBuffer *out, SignalConstPointerSignalMessage obj); - -SignalFfiError *signal_message_get_serialized(SignalOwnedBuffer *out, SignalConstPointerSignalMessage obj); - -SignalFfiError *signal_message_get_counter(uint32_t *out, SignalConstPointerSignalMessage obj); - -SignalFfiError *signal_message_get_message_version(uint32_t *out, SignalConstPointerSignalMessage obj); - -SignalFfiError *signal_message_new(SignalMutPointerSignalMessage *out, uint8_t message_version, SignalBorrowedBuffer mac_key, SignalConstPointerPublicKey sender_ratchet_key, uint32_t counter, uint32_t previous_counter, SignalBorrowedBuffer ciphertext, SignalConstPointerPublicKey sender_identity_key, SignalConstPointerPublicKey receiver_identity_key); - -SignalFfiError *signal_message_verify_mac(bool *out, SignalConstPointerSignalMessage msg, SignalConstPointerPublicKey sender_identity_key, SignalConstPointerPublicKey receiver_identity_key, SignalBorrowedBuffer mac_key); - -SignalFfiError *signal_message_get_sender_ratchet_key(SignalMutPointerPublicKey *out, SignalConstPointerSignalMessage m); - -SignalFfiError *signal_pre_key_signal_message_new(SignalMutPointerPreKeySignalMessage *out, uint8_t message_version, uint32_t registration_id, uint32_t pre_key_id, uint32_t signed_pre_key_id, SignalConstPointerPublicKey base_key, SignalConstPointerPublicKey identity_key, SignalConstPointerSignalMessage signal_message); - -SignalFfiError *signal_pre_key_signal_message_get_base_key(SignalMutPointerPublicKey *out, SignalConstPointerPreKeySignalMessage m); - -SignalFfiError *signal_pre_key_signal_message_get_identity_key(SignalMutPointerPublicKey *out, SignalConstPointerPreKeySignalMessage m); - -SignalFfiError *signal_pre_key_signal_message_get_signal_message(SignalMutPointerSignalMessage *out, SignalConstPointerPreKeySignalMessage m); - -SignalFfiError *signal_pre_key_signal_message_deserialize(SignalMutPointerPreKeySignalMessage *out, SignalBorrowedBuffer data); - -SignalFfiError *signal_pre_key_signal_message_serialize(SignalOwnedBuffer *out, SignalConstPointerPreKeySignalMessage obj); - -SignalFfiError *signal_pre_key_signal_message_get_registration_id(uint32_t *out, SignalConstPointerPreKeySignalMessage obj); - -SignalFfiError *signal_pre_key_signal_message_get_signed_pre_key_id(uint32_t *out, SignalConstPointerPreKeySignalMessage obj); - -SignalFfiError *signal_pre_key_signal_message_get_pre_key_id(uint32_t *out, SignalConstPointerPreKeySignalMessage obj); - -SignalFfiError *signal_pre_key_signal_message_get_version(uint32_t *out, SignalConstPointerPreKeySignalMessage obj); - -SignalFfiError *signal_sender_key_message_deserialize(SignalMutPointerSenderKeyMessage *out, SignalBorrowedBuffer data); - -SignalFfiError *signal_sender_key_message_get_cipher_text(SignalOwnedBuffer *out, SignalConstPointerSenderKeyMessage obj); - -SignalFfiError *signal_sender_key_message_serialize(SignalOwnedBuffer *out, SignalConstPointerSenderKeyMessage obj); - -SignalFfiError *signal_sender_key_message_get_distribution_id(uint8_t (*out)[16], SignalConstPointerSenderKeyMessage obj); - -SignalFfiError *signal_sender_key_message_get_chain_id(uint32_t *out, SignalConstPointerSenderKeyMessage obj); - -SignalFfiError *signal_sender_key_message_get_iteration(uint32_t *out, SignalConstPointerSenderKeyMessage obj); - -SignalFfiError *signal_sender_key_message_new(SignalMutPointerSenderKeyMessage *out, uint8_t message_version, const uint8_t (*distribution_id)[16], uint32_t chain_id, uint32_t iteration, SignalBorrowedBuffer ciphertext, SignalConstPointerPrivateKey pk); - -SignalFfiError *signal_sender_key_message_verify_signature(bool *out, SignalConstPointerSenderKeyMessage skm, SignalConstPointerPublicKey pubkey); - -SignalFfiError *signal_sender_key_distribution_message_deserialize(SignalMutPointerSenderKeyDistributionMessage *out, SignalBorrowedBuffer data); - -SignalFfiError *signal_sender_key_distribution_message_get_chain_key(SignalOwnedBuffer *out, SignalConstPointerSenderKeyDistributionMessage obj); - -SignalFfiError *signal_sender_key_distribution_message_serialize(SignalOwnedBuffer *out, SignalConstPointerSenderKeyDistributionMessage obj); - -SignalFfiError *signal_sender_key_distribution_message_get_distribution_id(uint8_t (*out)[16], SignalConstPointerSenderKeyDistributionMessage obj); - -SignalFfiError *signal_sender_key_distribution_message_get_chain_id(uint32_t *out, SignalConstPointerSenderKeyDistributionMessage obj); - -SignalFfiError *signal_sender_key_distribution_message_get_iteration(uint32_t *out, SignalConstPointerSenderKeyDistributionMessage obj); - -SignalFfiError *signal_sender_key_distribution_message_new(SignalMutPointerSenderKeyDistributionMessage *out, uint8_t message_version, const uint8_t (*distribution_id)[16], uint32_t chain_id, uint32_t iteration, SignalBorrowedBuffer chainkey, SignalConstPointerPublicKey pk); - -SignalFfiError *signal_sender_key_distribution_message_get_signature_key(SignalMutPointerPublicKey *out, SignalConstPointerSenderKeyDistributionMessage m); - -SignalFfiError *signal_decryption_error_message_deserialize(SignalMutPointerDecryptionErrorMessage *out, SignalBorrowedBuffer data); - -SignalFfiError *signal_decryption_error_message_get_timestamp(uint64_t *out, SignalConstPointerDecryptionErrorMessage obj); - -SignalFfiError *signal_decryption_error_message_get_device_id(uint32_t *out, SignalConstPointerDecryptionErrorMessage obj); - -SignalFfiError *signal_decryption_error_message_serialize(SignalOwnedBuffer *out, SignalConstPointerDecryptionErrorMessage obj); - -SignalFfiError *signal_decryption_error_message_get_ratchet_key(SignalMutPointerPublicKey *out, SignalConstPointerDecryptionErrorMessage m); - -SignalFfiError *signal_decryption_error_message_for_original_message(SignalMutPointerDecryptionErrorMessage *out, SignalBorrowedBuffer original_bytes, uint8_t original_type, uint64_t original_timestamp, uint32_t original_sender_device_id); - -SignalFfiError *signal_decryption_error_message_extract_from_serialized_content(SignalMutPointerDecryptionErrorMessage *out, SignalBorrowedBuffer bytes); - -SignalFfiError *signal_plaintext_content_deserialize(SignalMutPointerPlaintextContent *out, SignalBorrowedBuffer data); - -SignalFfiError *signal_plaintext_content_serialize(SignalOwnedBuffer *out, SignalConstPointerPlaintextContent obj); - -SignalFfiError *signal_plaintext_content_get_body(SignalOwnedBuffer *out, SignalConstPointerPlaintextContent obj); - -SignalFfiError *signal_plaintext_content_from_decryption_error_message(SignalMutPointerPlaintextContent *out, SignalConstPointerDecryptionErrorMessage m); - -SignalFfiError *signal_pre_key_bundle_new(SignalMutPointerPreKeyBundle *out, uint32_t registration_id, uint32_t device_id, uint32_t prekey_id, SignalConstPointerPublicKey prekey, uint32_t signed_prekey_id, SignalConstPointerPublicKey signed_prekey, SignalBorrowedBuffer signed_prekey_signature, SignalConstPointerPublicKey identity_key, uint32_t kyber_prekey_id, SignalConstPointerKyberPublicKey kyber_prekey, SignalBorrowedBuffer kyber_prekey_signature); - -SignalFfiError *signal_pre_key_bundle_get_identity_key(SignalMutPointerPublicKey *out, SignalConstPointerPreKeyBundle p); - -SignalFfiError *signal_pre_key_bundle_get_signed_pre_key_signature(SignalOwnedBuffer *out, SignalConstPointerPreKeyBundle obj); - -SignalFfiError *signal_pre_key_bundle_get_registration_id(uint32_t *out, SignalConstPointerPreKeyBundle obj); - -SignalFfiError *signal_pre_key_bundle_get_device_id(uint32_t *out, SignalConstPointerPreKeyBundle obj); - -SignalFfiError *signal_pre_key_bundle_get_signed_pre_key_id(uint32_t *out, SignalConstPointerPreKeyBundle obj); - -SignalFfiError *signal_pre_key_bundle_get_pre_key_id(uint32_t *out, SignalConstPointerPreKeyBundle obj); - -SignalFfiError *signal_pre_key_bundle_get_pre_key_public(SignalMutPointerPublicKey *out, SignalConstPointerPreKeyBundle obj); - -SignalFfiError *signal_pre_key_bundle_get_signed_pre_key_public(SignalMutPointerPublicKey *out, SignalConstPointerPreKeyBundle obj); - -SignalFfiError *signal_pre_key_bundle_get_kyber_pre_key_id(uint32_t *out, SignalConstPointerPreKeyBundle obj); - -SignalFfiError *signal_pre_key_bundle_get_kyber_pre_key_public(SignalMutPointerKyberPublicKey *out, SignalConstPointerPreKeyBundle bundle); - -SignalFfiError *signal_pre_key_bundle_get_kyber_pre_key_signature(SignalOwnedBuffer *out, SignalConstPointerPreKeyBundle bundle); - -SignalFfiError *signal_signed_pre_key_record_deserialize(SignalMutPointerSignedPreKeyRecord *out, SignalBorrowedBuffer data); - -SignalFfiError *signal_signed_pre_key_record_get_signature(SignalOwnedBuffer *out, SignalConstPointerSignedPreKeyRecord obj); - -SignalFfiError *signal_signed_pre_key_record_serialize(SignalOwnedBuffer *out, SignalConstPointerSignedPreKeyRecord obj); - -SignalFfiError *signal_signed_pre_key_record_get_id(uint32_t *out, SignalConstPointerSignedPreKeyRecord obj); - -SignalFfiError *signal_signed_pre_key_record_get_timestamp(uint64_t *out, SignalConstPointerSignedPreKeyRecord obj); - -SignalFfiError *signal_signed_pre_key_record_get_public_key(SignalMutPointerPublicKey *out, SignalConstPointerSignedPreKeyRecord obj); - -SignalFfiError *signal_signed_pre_key_record_get_private_key(SignalMutPointerPrivateKey *out, SignalConstPointerSignedPreKeyRecord obj); - -SignalFfiError *signal_kyber_pre_key_record_deserialize(SignalMutPointerKyberPreKeyRecord *out, SignalBorrowedBuffer data); - -SignalFfiError *signal_kyber_pre_key_record_get_signature(SignalOwnedBuffer *out, SignalConstPointerKyberPreKeyRecord obj); - -SignalFfiError *signal_kyber_pre_key_record_serialize(SignalOwnedBuffer *out, SignalConstPointerKyberPreKeyRecord obj); - -SignalFfiError *signal_kyber_pre_key_record_get_id(uint32_t *out, SignalConstPointerKyberPreKeyRecord obj); - -SignalFfiError *signal_kyber_pre_key_record_get_timestamp(uint64_t *out, SignalConstPointerKyberPreKeyRecord obj); - -SignalFfiError *signal_kyber_pre_key_record_get_public_key(SignalMutPointerKyberPublicKey *out, SignalConstPointerKyberPreKeyRecord obj); - -SignalFfiError *signal_kyber_pre_key_record_get_secret_key(SignalMutPointerKyberSecretKey *out, SignalConstPointerKyberPreKeyRecord obj); - -SignalFfiError *signal_kyber_pre_key_record_get_key_pair(SignalMutPointerKyberKeyPair *out, SignalConstPointerKyberPreKeyRecord obj); - -SignalFfiError *signal_signed_pre_key_record_new(SignalMutPointerSignedPreKeyRecord *out, uint32_t id, uint64_t timestamp, SignalConstPointerPublicKey pub_key, SignalConstPointerPrivateKey priv_key, SignalBorrowedBuffer signature); - -SignalFfiError *signal_kyber_pre_key_record_new(SignalMutPointerKyberPreKeyRecord *out, uint32_t id, uint64_t timestamp, SignalConstPointerKyberKeyPair key_pair, SignalBorrowedBuffer signature); - -SignalFfiError *signal_pre_key_record_deserialize(SignalMutPointerPreKeyRecord *out, SignalBorrowedBuffer data); - -SignalFfiError *signal_pre_key_record_serialize(SignalOwnedBuffer *out, SignalConstPointerPreKeyRecord obj); - -SignalFfiError *signal_pre_key_record_get_id(uint32_t *out, SignalConstPointerPreKeyRecord obj); - -SignalFfiError *signal_pre_key_record_get_public_key(SignalMutPointerPublicKey *out, SignalConstPointerPreKeyRecord obj); - -SignalFfiError *signal_pre_key_record_get_private_key(SignalMutPointerPrivateKey *out, SignalConstPointerPreKeyRecord obj); - -SignalFfiError *signal_pre_key_record_new(SignalMutPointerPreKeyRecord *out, uint32_t id, SignalConstPointerPublicKey pub_key, SignalConstPointerPrivateKey priv_key); - -SignalFfiError *signal_sender_key_record_deserialize(SignalMutPointerSenderKeyRecord *out, SignalBorrowedBuffer data); - -SignalFfiError *signal_sender_key_record_serialize(SignalOwnedBuffer *out, SignalConstPointerSenderKeyRecord obj); - -SignalFfiError *signal_server_certificate_deserialize(SignalMutPointerServerCertificate *out, SignalBorrowedBuffer data); - -SignalFfiError *signal_server_certificate_get_serialized(SignalOwnedBuffer *out, SignalConstPointerServerCertificate obj); - -SignalFfiError *signal_server_certificate_get_certificate(SignalOwnedBuffer *out, SignalConstPointerServerCertificate obj); - -SignalFfiError *signal_server_certificate_get_signature(SignalOwnedBuffer *out, SignalConstPointerServerCertificate obj); - -SignalFfiError *signal_server_certificate_get_key_id(uint32_t *out, SignalConstPointerServerCertificate obj); - -SignalFfiError *signal_server_certificate_get_key(SignalMutPointerPublicKey *out, SignalConstPointerServerCertificate obj); - -SignalFfiError *signal_server_certificate_new(SignalMutPointerServerCertificate *out, uint32_t key_id, SignalConstPointerPublicKey server_key, SignalConstPointerPrivateKey trust_root); - -SignalFfiError *signal_sender_certificate_deserialize(SignalMutPointerSenderCertificate *out, SignalBorrowedBuffer data); - -SignalFfiError *signal_sender_certificate_get_serialized(SignalOwnedBuffer *out, SignalConstPointerSenderCertificate obj); - -SignalFfiError *signal_sender_certificate_get_certificate(SignalOwnedBuffer *out, SignalConstPointerSenderCertificate obj); - -SignalFfiError *signal_sender_certificate_get_signature(SignalOwnedBuffer *out, SignalConstPointerSenderCertificate obj); - -SignalFfiError *signal_sender_certificate_get_sender_uuid(const char **out, SignalConstPointerSenderCertificate obj); - -SignalFfiError *signal_sender_certificate_get_sender_e164(const char **out, SignalConstPointerSenderCertificate obj); - -SignalFfiError *signal_sender_certificate_get_expiration(uint64_t *out, SignalConstPointerSenderCertificate obj); - -SignalFfiError *signal_sender_certificate_get_device_id(uint32_t *out, SignalConstPointerSenderCertificate obj); - -SignalFfiError *signal_sender_certificate_get_key(SignalMutPointerPublicKey *out, SignalConstPointerSenderCertificate obj); - -SignalFfiError *signal_sender_certificate_validate(bool *out, SignalConstPointerSenderCertificate cert, SignalConstPointerPublicKey key, uint64_t time); - -SignalFfiError *signal_sender_certificate_get_server_certificate(SignalMutPointerServerCertificate *out, SignalConstPointerSenderCertificate cert); - -SignalFfiError *signal_sender_certificate_new(SignalMutPointerSenderCertificate *out, const char *sender_uuid, const char *sender_e164, uint32_t sender_device_id, SignalConstPointerPublicKey sender_key, uint64_t expiration, SignalConstPointerServerCertificate signer_cert, SignalConstPointerPrivateKey signer_key); - -SignalFfiError *signal_unidentified_sender_message_content_deserialize(SignalMutPointerUnidentifiedSenderMessageContent *out, SignalBorrowedBuffer data); - -SignalFfiError *signal_unidentified_sender_message_content_serialize(SignalOwnedBuffer *out, SignalConstPointerUnidentifiedSenderMessageContent obj); - -SignalFfiError *signal_unidentified_sender_message_content_get_contents(SignalOwnedBuffer *out, SignalConstPointerUnidentifiedSenderMessageContent obj); - -SignalFfiError *signal_unidentified_sender_message_content_get_group_id_or_empty(SignalOwnedBuffer *out, SignalConstPointerUnidentifiedSenderMessageContent m); - -SignalFfiError *signal_unidentified_sender_message_content_get_sender_cert(SignalMutPointerSenderCertificate *out, SignalConstPointerUnidentifiedSenderMessageContent m); - -SignalFfiError *signal_unidentified_sender_message_content_get_msg_type(uint8_t *out, SignalConstPointerUnidentifiedSenderMessageContent m); - -SignalFfiError *signal_unidentified_sender_message_content_get_content_hint(uint32_t *out, SignalConstPointerUnidentifiedSenderMessageContent m); - -SignalFfiError *signal_unidentified_sender_message_content_new(SignalMutPointerUnidentifiedSenderMessageContent *out, SignalConstPointerCiphertextMessage message, SignalConstPointerSenderCertificate sender, uint32_t content_hint, SignalBorrowedBuffer group_id); - -SignalFfiError *signal_ciphertext_message_type(uint8_t *out, SignalConstPointerCiphertextMessage msg); - -SignalFfiError *signal_ciphertext_message_serialize(SignalOwnedBuffer *out, SignalConstPointerCiphertextMessage obj); - -SignalFfiError *signal_ciphertext_message_from_plaintext_content(SignalMutPointerCiphertextMessage *out, SignalConstPointerPlaintextContent m); - -SignalFfiError *signal_session_record_archive_current_state(SignalMutPointerSessionRecord session_record); - -SignalFfiError *signal_session_record_has_usable_sender_chain(bool *out, SignalConstPointerSessionRecord s, uint64_t now); - -SignalFfiError *signal_session_record_current_ratchet_key_matches(bool *out, SignalConstPointerSessionRecord s, SignalConstPointerPublicKey key); - -SignalFfiError *signal_session_record_deserialize(SignalMutPointerSessionRecord *out, SignalBorrowedBuffer data); - -SignalFfiError *signal_session_record_serialize(SignalOwnedBuffer *out, SignalConstPointerSessionRecord obj); - -SignalFfiError *signal_session_record_get_local_registration_id(uint32_t *out, SignalConstPointerSessionRecord obj); - -SignalFfiError *signal_session_record_get_remote_registration_id(uint32_t *out, SignalConstPointerSessionRecord obj); - -SignalFfiError *signal_process_prekey_bundle(SignalConstPointerPreKeyBundle bundle, SignalConstPointerProtocolAddress protocol_address, SignalConstPointerFfiSessionStoreStruct session_store, SignalConstPointerFfiIdentityKeyStoreStruct identity_key_store, uint64_t now); - -SignalFfiError *signal_encrypt_message(SignalMutPointerCiphertextMessage *out, SignalBorrowedBuffer ptext, SignalConstPointerProtocolAddress protocol_address, SignalConstPointerFfiSessionStoreStruct session_store, SignalConstPointerFfiIdentityKeyStoreStruct identity_key_store, uint64_t now); - -SignalFfiError *signal_decrypt_message(SignalOwnedBuffer *out, SignalConstPointerSignalMessage message, SignalConstPointerProtocolAddress protocol_address, SignalConstPointerFfiSessionStoreStruct session_store, SignalConstPointerFfiIdentityKeyStoreStruct identity_key_store); - -SignalFfiError *signal_decrypt_pre_key_message(SignalOwnedBuffer *out, SignalConstPointerPreKeySignalMessage message, SignalConstPointerProtocolAddress protocol_address, SignalConstPointerFfiSessionStoreStruct session_store, SignalConstPointerFfiIdentityKeyStoreStruct identity_key_store, SignalConstPointerFfiPreKeyStoreStruct prekey_store, SignalConstPointerFfiSignedPreKeyStoreStruct signed_prekey_store, SignalConstPointerFfiKyberPreKeyStoreStruct kyber_prekey_store); - -SignalFfiError *signal_sealed_session_cipher_encrypt(SignalOwnedBuffer *out, SignalConstPointerProtocolAddress destination, SignalConstPointerUnidentifiedSenderMessageContent content, SignalConstPointerFfiIdentityKeyStoreStruct identity_key_store); - -SignalFfiError *signal_sealed_sender_multi_recipient_encrypt(SignalOwnedBuffer *out, SignalBorrowedSliceOfConstPointerProtocolAddress recipients, SignalBorrowedSliceOfConstPointerSessionRecord recipient_sessions, SignalBorrowedBuffer excluded_recipients, SignalConstPointerUnidentifiedSenderMessageContent content, SignalConstPointerFfiIdentityKeyStoreStruct identity_key_store); - -SignalFfiError *signal_sealed_sender_multi_recipient_message_for_single_recipient(SignalOwnedBuffer *out, SignalBorrowedBuffer encoded_multi_recipient_message); - -SignalFfiError *signal_sealed_session_cipher_decrypt_to_usmc(SignalMutPointerUnidentifiedSenderMessageContent *out, SignalBorrowedBuffer ctext, SignalConstPointerFfiIdentityKeyStoreStruct identity_store); - -SignalFfiError *signal_sender_key_distribution_message_create(SignalMutPointerSenderKeyDistributionMessage *out, SignalConstPointerProtocolAddress sender, const uint8_t (*distribution_id)[16], SignalConstPointerFfiSenderKeyStoreStruct store); - -SignalFfiError *signal_process_sender_key_distribution_message(SignalConstPointerProtocolAddress sender, SignalConstPointerSenderKeyDistributionMessage sender_key_distribution_message, SignalConstPointerFfiSenderKeyStoreStruct store); - -SignalFfiError *signal_group_encrypt_message(SignalMutPointerCiphertextMessage *out, SignalConstPointerProtocolAddress sender, const uint8_t (*distribution_id)[16], SignalBorrowedBuffer message, SignalConstPointerFfiSenderKeyStoreStruct store); - -SignalFfiError *signal_group_decrypt_message(SignalOwnedBuffer *out, SignalConstPointerProtocolAddress sender, SignalBorrowedBuffer message, SignalConstPointerFfiSenderKeyStoreStruct store); - -SignalFfiError *signal_device_transfer_generate_private_key(SignalOwnedBuffer *out); - -SignalFfiError *signal_device_transfer_generate_private_key_with_format(SignalOwnedBuffer *out, uint8_t key_format); - -SignalFfiError *signal_device_transfer_generate_certificate(SignalOwnedBuffer *out, SignalBorrowedBuffer private_key, const char *name, uint32_t days_to_expire); - -SignalFfiError *signal_cds2_client_state_new(SignalMutPointerSgxClientState *out, SignalBorrowedBuffer mrenclave, SignalBorrowedBuffer attestation_msg, uint64_t current_timestamp); - -SignalFfiError *signal_hsm_enclave_client_destroy(SignalMutPointerHsmEnclaveClient p); - -SignalFfiError *signal_hsm_enclave_client_new(SignalMutPointerHsmEnclaveClient *out, SignalBorrowedBuffer trusted_public_key, SignalBorrowedBuffer trusted_code_hashes); - -SignalFfiError *signal_hsm_enclave_client_complete_handshake(SignalMutPointerHsmEnclaveClient cli, SignalBorrowedBuffer handshake_received); - -SignalFfiError *signal_hsm_enclave_client_established_send(SignalOwnedBuffer *out, SignalMutPointerHsmEnclaveClient cli, SignalBorrowedBuffer plaintext_to_send); - -SignalFfiError *signal_hsm_enclave_client_established_recv(SignalOwnedBuffer *out, SignalMutPointerHsmEnclaveClient cli, SignalBorrowedBuffer received_ciphertext); - -SignalFfiError *signal_hsm_enclave_client_initial_request(SignalOwnedBuffer *out, SignalConstPointerHsmEnclaveClient obj); - -SignalFfiError *signal_sgx_client_state_destroy(SignalMutPointerSgxClientState p); - -SignalFfiError *signal_sgx_client_state_initial_request(SignalOwnedBuffer *out, SignalConstPointerSgxClientState obj); - -SignalFfiError *signal_sgx_client_state_complete_handshake(SignalMutPointerSgxClientState cli, SignalBorrowedBuffer handshake_received); - -SignalFfiError *signal_sgx_client_state_established_send(SignalOwnedBuffer *out, SignalMutPointerSgxClientState cli, SignalBorrowedBuffer plaintext_to_send); - -SignalFfiError *signal_sgx_client_state_established_recv(SignalOwnedBuffer *out, SignalMutPointerSgxClientState cli, SignalBorrowedBuffer received_ciphertext); - -SignalFfiError *signal_expiring_profile_key_credential_check_valid_contents(SignalBorrowedBuffer buffer); - -SignalFfiError *signal_expiring_profile_key_credential_response_check_valid_contents(SignalBorrowedBuffer buffer); - -SignalFfiError *signal_group_master_key_check_valid_contents(SignalBorrowedBuffer buffer); - -SignalFfiError *signal_group_public_params_check_valid_contents(SignalBorrowedBuffer buffer); - -SignalFfiError *signal_group_secret_params_check_valid_contents(SignalBorrowedBuffer buffer); - -SignalFfiError *signal_profile_key_check_valid_contents(SignalBorrowedBuffer buffer); - -SignalFfiError *signal_profile_key_ciphertext_check_valid_contents(SignalBorrowedBuffer buffer); - -SignalFfiError *signal_profile_key_commitment_check_valid_contents(SignalBorrowedBuffer buffer); - -SignalFfiError *signal_profile_key_credential_request_check_valid_contents(SignalBorrowedBuffer buffer); - -SignalFfiError *signal_profile_key_credential_request_context_check_valid_contents(SignalBorrowedBuffer buffer); - -SignalFfiError *signal_receipt_credential_check_valid_contents(SignalBorrowedBuffer buffer); - -SignalFfiError *signal_receipt_credential_presentation_check_valid_contents(SignalBorrowedBuffer buffer); - -SignalFfiError *signal_receipt_credential_request_check_valid_contents(SignalBorrowedBuffer buffer); - -SignalFfiError *signal_receipt_credential_request_context_check_valid_contents(SignalBorrowedBuffer buffer); - -SignalFfiError *signal_receipt_credential_response_check_valid_contents(SignalBorrowedBuffer buffer); - -SignalFfiError *signal_uuid_ciphertext_check_valid_contents(SignalBorrowedBuffer buffer); - -SignalFfiError *signal_server_public_params_destroy(SignalMutPointerServerPublicParams p); - -SignalFfiError *signal_server_public_params_deserialize(SignalMutPointerServerPublicParams *out, SignalBorrowedBuffer buffer); - -SignalFfiError *signal_server_public_params_serialize(SignalOwnedBuffer *out, SignalConstPointerServerPublicParams handle); - -SignalFfiError *signal_server_secret_params_destroy(SignalMutPointerServerSecretParams p); - -SignalFfiError *signal_server_secret_params_deserialize(SignalMutPointerServerSecretParams *out, SignalBorrowedBuffer buffer); - -SignalFfiError *signal_server_secret_params_serialize(SignalOwnedBuffer *out, SignalConstPointerServerSecretParams handle); - -SignalFfiError *signal_profile_key_get_commitment(unsigned char (*out)[SignalPROFILE_KEY_COMMITMENT_LEN], const unsigned char (*profile_key)[SignalPROFILE_KEY_LEN], const SignalServiceIdFixedWidthBinaryBytes *user_id); - -SignalFfiError *signal_profile_key_get_profile_key_version(uint8_t (*out)[SignalPROFILE_KEY_VERSION_ENCODED_LEN], const unsigned char (*profile_key)[SignalPROFILE_KEY_LEN], const SignalServiceIdFixedWidthBinaryBytes *user_id); - -SignalFfiError *signal_profile_key_derive_access_key(uint8_t (*out)[SignalACCESS_KEY_LEN], const unsigned char (*profile_key)[SignalPROFILE_KEY_LEN]); - -SignalFfiError *signal_group_secret_params_generate_deterministic(unsigned char (*out)[SignalGROUP_SECRET_PARAMS_LEN], const uint8_t (*randomness)[SignalRANDOMNESS_LEN]); - -SignalFfiError *signal_group_secret_params_derive_from_master_key(unsigned char (*out)[SignalGROUP_SECRET_PARAMS_LEN], const unsigned char (*master_key)[SignalGROUP_MASTER_KEY_LEN]); - -SignalFfiError *signal_group_secret_params_get_master_key(unsigned char (*out)[SignalGROUP_MASTER_KEY_LEN], const unsigned char (*params)[SignalGROUP_SECRET_PARAMS_LEN]); - -SignalFfiError *signal_group_secret_params_get_public_params(unsigned char (*out)[SignalGROUP_PUBLIC_PARAMS_LEN], const unsigned char (*params)[SignalGROUP_SECRET_PARAMS_LEN]); - -SignalFfiError *signal_group_secret_params_encrypt_service_id(unsigned char (*out)[SignalUUID_CIPHERTEXT_LEN], const unsigned char (*params)[SignalGROUP_SECRET_PARAMS_LEN], const SignalServiceIdFixedWidthBinaryBytes *service_id); - -SignalFfiError *signal_group_secret_params_decrypt_service_id(SignalServiceIdFixedWidthBinaryBytes *out, const unsigned char (*params)[SignalGROUP_SECRET_PARAMS_LEN], const unsigned char (*ciphertext)[SignalUUID_CIPHERTEXT_LEN]); - -SignalFfiError *signal_group_secret_params_encrypt_profile_key(unsigned char (*out)[SignalPROFILE_KEY_CIPHERTEXT_LEN], const unsigned char (*params)[SignalGROUP_SECRET_PARAMS_LEN], const unsigned char (*profile_key)[SignalPROFILE_KEY_LEN], const SignalServiceIdFixedWidthBinaryBytes *user_id); - -SignalFfiError *signal_group_secret_params_decrypt_profile_key(unsigned char (*out)[SignalPROFILE_KEY_LEN], const unsigned char (*params)[SignalGROUP_SECRET_PARAMS_LEN], const unsigned char (*profile_key)[SignalPROFILE_KEY_CIPHERTEXT_LEN], const SignalServiceIdFixedWidthBinaryBytes *user_id); - -SignalFfiError *signal_group_secret_params_encrypt_blob_with_padding_deterministic(SignalOwnedBuffer *out, const unsigned char (*params)[SignalGROUP_SECRET_PARAMS_LEN], const uint8_t (*randomness)[SignalRANDOMNESS_LEN], SignalBorrowedBuffer plaintext, uint32_t padding_len); - -SignalFfiError *signal_group_secret_params_decrypt_blob_with_padding(SignalOwnedBuffer *out, const unsigned char (*params)[SignalGROUP_SECRET_PARAMS_LEN], SignalBorrowedBuffer ciphertext); - -SignalFfiError *signal_server_secret_params_generate_deterministic(SignalMutPointerServerSecretParams *out, const uint8_t (*randomness)[SignalRANDOMNESS_LEN]); - -SignalFfiError *signal_server_secret_params_get_public_params(SignalMutPointerServerPublicParams *out, SignalConstPointerServerSecretParams params); - -SignalFfiError *signal_server_secret_params_sign_deterministic(uint8_t (*out)[SignalSIGNATURE_LEN], SignalConstPointerServerSecretParams params, const uint8_t (*randomness)[SignalRANDOMNESS_LEN], SignalBorrowedBuffer message); - -SignalFfiError *signal_server_public_params_get_endorsement_public_key(SignalOwnedBuffer *out, SignalConstPointerServerPublicParams params); - -SignalFfiError *signal_server_public_params_receive_auth_credential_with_pni_as_service_id(SignalOwnedBuffer *out, SignalConstPointerServerPublicParams params, const SignalServiceIdFixedWidthBinaryBytes *aci, const SignalServiceIdFixedWidthBinaryBytes *pni, uint64_t redemption_time, SignalBorrowedBuffer auth_credential_with_pni_response_bytes); - -SignalFfiError *signal_server_public_params_create_auth_credential_with_pni_presentation_deterministic(SignalOwnedBuffer *out, SignalConstPointerServerPublicParams server_public_params, const uint8_t (*randomness)[SignalRANDOMNESS_LEN], const unsigned char (*group_secret_params)[SignalGROUP_SECRET_PARAMS_LEN], SignalBorrowedBuffer auth_credential_with_pni_bytes); - -SignalFfiError *signal_server_public_params_create_profile_key_credential_request_context_deterministic(unsigned char (*out)[SignalPROFILE_KEY_CREDENTIAL_REQUEST_CONTEXT_LEN], SignalConstPointerServerPublicParams server_public_params, const uint8_t (*randomness)[SignalRANDOMNESS_LEN], const SignalServiceIdFixedWidthBinaryBytes *user_id, const unsigned char (*profile_key)[SignalPROFILE_KEY_LEN]); - -SignalFfiError *signal_server_public_params_receive_expiring_profile_key_credential(unsigned char (*out)[SignalEXPIRING_PROFILE_KEY_CREDENTIAL_LEN], SignalConstPointerServerPublicParams server_public_params, const unsigned char (*request_context)[SignalPROFILE_KEY_CREDENTIAL_REQUEST_CONTEXT_LEN], const unsigned char (*response)[SignalEXPIRING_PROFILE_KEY_CREDENTIAL_RESPONSE_LEN], uint64_t current_time_in_seconds); - -SignalFfiError *signal_server_public_params_create_expiring_profile_key_credential_presentation_deterministic(SignalOwnedBuffer *out, SignalConstPointerServerPublicParams server_public_params, const uint8_t (*randomness)[SignalRANDOMNESS_LEN], const unsigned char (*group_secret_params)[SignalGROUP_SECRET_PARAMS_LEN], const unsigned char (*profile_key_credential)[SignalEXPIRING_PROFILE_KEY_CREDENTIAL_LEN]); - -SignalFfiError *signal_server_public_params_create_receipt_credential_request_context_deterministic(unsigned char (*out)[SignalRECEIPT_CREDENTIAL_REQUEST_CONTEXT_LEN], SignalConstPointerServerPublicParams server_public_params, const uint8_t (*randomness)[SignalRANDOMNESS_LEN], const uint8_t (*receipt_serial)[SignalRECEIPT_SERIAL_LEN]); - -SignalFfiError *signal_server_public_params_receive_receipt_credential(unsigned char (*out)[SignalRECEIPT_CREDENTIAL_LEN], SignalConstPointerServerPublicParams server_public_params, const unsigned char (*request_context)[SignalRECEIPT_CREDENTIAL_REQUEST_CONTEXT_LEN], const unsigned char (*response)[SignalRECEIPT_CREDENTIAL_RESPONSE_LEN]); - -SignalFfiError *signal_server_public_params_create_receipt_credential_presentation_deterministic(unsigned char (*out)[SignalRECEIPT_CREDENTIAL_PRESENTATION_LEN], SignalConstPointerServerPublicParams server_public_params, const uint8_t (*randomness)[SignalRANDOMNESS_LEN], const unsigned char (*receipt_credential)[SignalRECEIPT_CREDENTIAL_LEN]); - -SignalFfiError *signal_server_secret_params_issue_auth_credential_with_pni_zkc_deterministic(SignalOwnedBuffer *out, SignalConstPointerServerSecretParams server_secret_params, const uint8_t (*randomness)[SignalRANDOMNESS_LEN], const SignalServiceIdFixedWidthBinaryBytes *aci, const SignalServiceIdFixedWidthBinaryBytes *pni, uint64_t redemption_time); - -SignalFfiError *signal_auth_credential_with_pni_check_valid_contents(SignalBorrowedBuffer bytes); - -SignalFfiError *signal_auth_credential_with_pni_response_check_valid_contents(SignalBorrowedBuffer bytes); - -SignalFfiError *signal_server_secret_params_verify_auth_credential_presentation(SignalConstPointerServerSecretParams server_secret_params, const unsigned char (*group_public_params)[SignalGROUP_PUBLIC_PARAMS_LEN], SignalBorrowedBuffer presentation_bytes, uint64_t current_time_in_seconds); - -SignalFfiError *signal_server_secret_params_issue_expiring_profile_key_credential_deterministic(unsigned char (*out)[SignalEXPIRING_PROFILE_KEY_CREDENTIAL_RESPONSE_LEN], SignalConstPointerServerSecretParams server_secret_params, const uint8_t (*randomness)[SignalRANDOMNESS_LEN], const unsigned char (*request)[SignalPROFILE_KEY_CREDENTIAL_REQUEST_LEN], const SignalServiceIdFixedWidthBinaryBytes *user_id, const unsigned char (*commitment)[SignalPROFILE_KEY_COMMITMENT_LEN], uint64_t expiration_in_seconds); - -SignalFfiError *signal_server_secret_params_verify_profile_key_credential_presentation(SignalConstPointerServerSecretParams server_secret_params, const unsigned char (*group_public_params)[SignalGROUP_PUBLIC_PARAMS_LEN], SignalBorrowedBuffer presentation_bytes, uint64_t current_time_in_seconds); - -SignalFfiError *signal_server_secret_params_issue_receipt_credential_deterministic(unsigned char (*out)[SignalRECEIPT_CREDENTIAL_RESPONSE_LEN], SignalConstPointerServerSecretParams server_secret_params, const uint8_t (*randomness)[SignalRANDOMNESS_LEN], const unsigned char (*request)[SignalRECEIPT_CREDENTIAL_REQUEST_LEN], uint64_t receipt_expiration_time, uint64_t receipt_level); - -SignalFfiError *signal_server_secret_params_verify_receipt_credential_presentation(SignalConstPointerServerSecretParams server_secret_params, const unsigned char (*presentation)[SignalRECEIPT_CREDENTIAL_PRESENTATION_LEN]); - -SignalFfiError *signal_group_public_params_get_group_identifier(uint8_t (*out)[SignalGROUP_IDENTIFIER_LEN], const unsigned char (*group_public_params)[SignalGROUP_PUBLIC_PARAMS_LEN]); - -SignalFfiError *signal_server_public_params_verify_signature(SignalConstPointerServerPublicParams server_public_params, SignalBorrowedBuffer message, const uint8_t (*notary_signature)[SignalSIGNATURE_LEN]); +SignalFfiError *signal_aes256_gcm_siv_new(SignalMutPointerAes256GcmSiv *out, SignalBorrowedBuffer key); SignalFfiError *signal_auth_credential_presentation_check_valid_contents(SignalBorrowedBuffer presentation_bytes); -SignalFfiError *signal_auth_credential_presentation_get_uuid_ciphertext(unsigned char (*out)[SignalUUID_CIPHERTEXT_LEN], SignalBorrowedBuffer presentation_bytes); - SignalFfiError *signal_auth_credential_presentation_get_pni_ciphertext(unsigned char (*out)[SignalUUID_CIPHERTEXT_LEN], SignalBorrowedBuffer presentation_bytes); SignalFfiError *signal_auth_credential_presentation_get_redemption_time(uint64_t *out, SignalBorrowedBuffer presentation_bytes); -SignalFfiError *signal_profile_key_credential_request_context_get_request(unsigned char (*out)[SignalPROFILE_KEY_CREDENTIAL_REQUEST_LEN], const unsigned char (*context)[SignalPROFILE_KEY_CREDENTIAL_REQUEST_CONTEXT_LEN]); +SignalFfiError *signal_auth_credential_presentation_get_uuid_ciphertext(unsigned char (*out)[SignalUUID_CIPHERTEXT_LEN], SignalBorrowedBuffer presentation_bytes); -SignalFfiError *signal_expiring_profile_key_credential_get_expiration_time(uint64_t *out, const unsigned char (*credential)[SignalEXPIRING_PROFILE_KEY_CREDENTIAL_LEN]); +SignalFfiError *signal_auth_credential_with_pni_check_valid_contents(SignalBorrowedBuffer bytes); -SignalFfiError *signal_profile_key_credential_presentation_check_valid_contents(SignalBorrowedBuffer presentation_bytes); +SignalFfiError *signal_auth_credential_with_pni_response_check_valid_contents(SignalBorrowedBuffer bytes); -SignalFfiError *signal_profile_key_credential_presentation_get_uuid_ciphertext(unsigned char (*out)[SignalUUID_CIPHERTEXT_LEN], SignalBorrowedBuffer presentation_bytes); +SignalFfiError *signal_authenticated_chat_connection_connect(SignalCPromiseMutPointerAuthenticatedChatConnection *promise, SignalConstPointerTokioAsyncContext async_runtime, SignalConstPointerConnectionManager connection_manager, const char *username, const char *password, bool receive_stories); -SignalFfiError *signal_profile_key_credential_presentation_get_profile_key_ciphertext(unsigned char (*out)[SignalPROFILE_KEY_CIPHERTEXT_LEN], SignalBorrowedBuffer presentation_bytes); +SignalFfiError *signal_authenticated_chat_connection_destroy(SignalMutPointerAuthenticatedChatConnection p); -SignalFfiError *signal_receipt_credential_request_context_get_request(unsigned char (*out)[SignalRECEIPT_CREDENTIAL_REQUEST_LEN], const unsigned char (*request_context)[SignalRECEIPT_CREDENTIAL_REQUEST_CONTEXT_LEN]); +SignalFfiError *signal_authenticated_chat_connection_disconnect(SignalCPromisebool *promise, SignalConstPointerTokioAsyncContext async_runtime, SignalConstPointerAuthenticatedChatConnection chat); -SignalFfiError *signal_receipt_credential_get_receipt_expiration_time(uint64_t *out, const unsigned char (*receipt_credential)[SignalRECEIPT_CREDENTIAL_LEN]); +SignalFfiError *signal_authenticated_chat_connection_info(SignalMutPointerChatConnectionInfo *out, SignalConstPointerAuthenticatedChatConnection chat); -SignalFfiError *signal_receipt_credential_get_receipt_level(uint64_t *out, const unsigned char (*receipt_credential)[SignalRECEIPT_CREDENTIAL_LEN]); +SignalFfiError *signal_authenticated_chat_connection_init_listener(SignalConstPointerAuthenticatedChatConnection chat, SignalConstPointerFfiChatListenerStruct listener); -SignalFfiError *signal_receipt_credential_presentation_get_receipt_expiration_time(uint64_t *out, const unsigned char (*presentation)[SignalRECEIPT_CREDENTIAL_PRESENTATION_LEN]); +SignalFfiError *signal_authenticated_chat_connection_preconnect(SignalCPromisebool *promise, SignalConstPointerTokioAsyncContext async_runtime, SignalConstPointerConnectionManager connection_manager); -SignalFfiError *signal_receipt_credential_presentation_get_receipt_level(uint64_t *out, const unsigned char (*presentation)[SignalRECEIPT_CREDENTIAL_PRESENTATION_LEN]); - -SignalFfiError *signal_receipt_credential_presentation_get_receipt_serial(uint8_t (*out)[SignalRECEIPT_SERIAL_LEN], const unsigned char (*presentation)[SignalRECEIPT_CREDENTIAL_PRESENTATION_LEN]); - -SignalFfiError *signal_generic_server_secret_params_check_valid_contents(SignalBorrowedBuffer params_bytes); - -SignalFfiError *signal_generic_server_secret_params_generate_deterministic(SignalOwnedBuffer *out, const uint8_t (*randomness)[SignalRANDOMNESS_LEN]); - -SignalFfiError *signal_generic_server_secret_params_get_public_params(SignalOwnedBuffer *out, SignalBorrowedBuffer params_bytes); - -SignalFfiError *signal_generic_server_public_params_check_valid_contents(SignalBorrowedBuffer params_bytes); - -SignalFfiError *signal_call_link_secret_params_check_valid_contents(SignalBorrowedBuffer params_bytes); - -SignalFfiError *signal_call_link_secret_params_derive_from_root_key(SignalOwnedBuffer *out, SignalBorrowedBuffer root_key); - -SignalFfiError *signal_call_link_secret_params_get_public_params(SignalOwnedBuffer *out, SignalBorrowedBuffer params_bytes); - -SignalFfiError *signal_call_link_secret_params_decrypt_user_id(SignalServiceIdFixedWidthBinaryBytes *out, SignalBorrowedBuffer params_bytes, const unsigned char (*user_id)[SignalUUID_CIPHERTEXT_LEN]); - -SignalFfiError *signal_call_link_public_params_check_valid_contents(SignalBorrowedBuffer params_bytes); - -SignalFfiError *signal_create_call_link_credential_request_context_check_valid_contents(SignalBorrowedBuffer context_bytes); - -SignalFfiError *signal_create_call_link_credential_request_context_new_deterministic(SignalOwnedBuffer *out, SignalBorrowedBuffer room_id, const uint8_t (*randomness)[SignalRANDOMNESS_LEN]); - -SignalFfiError *signal_create_call_link_credential_request_context_get_request(SignalOwnedBuffer *out, SignalBorrowedBuffer context_bytes); - -SignalFfiError *signal_create_call_link_credential_request_check_valid_contents(SignalBorrowedBuffer request_bytes); - -SignalFfiError *signal_create_call_link_credential_request_issue_deterministic(SignalOwnedBuffer *out, SignalBorrowedBuffer request_bytes, const SignalServiceIdFixedWidthBinaryBytes *user_id, uint64_t timestamp, SignalBorrowedBuffer params_bytes, const uint8_t (*randomness)[SignalRANDOMNESS_LEN]); - -SignalFfiError *signal_create_call_link_credential_response_check_valid_contents(SignalBorrowedBuffer response_bytes); - -SignalFfiError *signal_create_call_link_credential_request_context_receive_response(SignalOwnedBuffer *out, SignalBorrowedBuffer context_bytes, SignalBorrowedBuffer response_bytes, const SignalServiceIdFixedWidthBinaryBytes *user_id, SignalBorrowedBuffer params_bytes); - -SignalFfiError *signal_create_call_link_credential_check_valid_contents(SignalBorrowedBuffer params_bytes); - -SignalFfiError *signal_create_call_link_credential_present_deterministic(SignalOwnedBuffer *out, SignalBorrowedBuffer credential_bytes, SignalBorrowedBuffer room_id, const SignalServiceIdFixedWidthBinaryBytes *user_id, SignalBorrowedBuffer server_params_bytes, SignalBorrowedBuffer call_link_params_bytes, const uint8_t (*randomness)[SignalRANDOMNESS_LEN]); - -SignalFfiError *signal_create_call_link_credential_presentation_check_valid_contents(SignalBorrowedBuffer presentation_bytes); - -SignalFfiError *signal_create_call_link_credential_presentation_verify(SignalBorrowedBuffer presentation_bytes, SignalBorrowedBuffer room_id, uint64_t now, SignalBorrowedBuffer server_params_bytes, SignalBorrowedBuffer call_link_params_bytes); - -SignalFfiError *signal_call_link_auth_credential_response_check_valid_contents(SignalBorrowedBuffer response_bytes); - -SignalFfiError *signal_call_link_auth_credential_response_issue_deterministic(SignalOwnedBuffer *out, const SignalServiceIdFixedWidthBinaryBytes *user_id, uint64_t redemption_time, SignalBorrowedBuffer params_bytes, const uint8_t (*randomness)[SignalRANDOMNESS_LEN]); - -SignalFfiError *signal_call_link_auth_credential_response_receive(SignalOwnedBuffer *out, SignalBorrowedBuffer response_bytes, const SignalServiceIdFixedWidthBinaryBytes *user_id, uint64_t redemption_time, SignalBorrowedBuffer params_bytes); - -SignalFfiError *signal_call_link_auth_credential_check_valid_contents(SignalBorrowedBuffer credential_bytes); - -SignalFfiError *signal_call_link_auth_credential_present_deterministic(SignalOwnedBuffer *out, SignalBorrowedBuffer credential_bytes, const SignalServiceIdFixedWidthBinaryBytes *user_id, uint64_t redemption_time, SignalBorrowedBuffer server_params_bytes, SignalBorrowedBuffer call_link_params_bytes, const uint8_t (*randomness)[SignalRANDOMNESS_LEN]); - -SignalFfiError *signal_call_link_auth_credential_presentation_check_valid_contents(SignalBorrowedBuffer presentation_bytes); - -SignalFfiError *signal_call_link_auth_credential_presentation_verify(SignalBorrowedBuffer presentation_bytes, uint64_t now, SignalBorrowedBuffer server_params_bytes, SignalBorrowedBuffer call_link_params_bytes); - -SignalFfiError *signal_call_link_auth_credential_presentation_get_user_id(unsigned char (*out)[SignalUUID_CIPHERTEXT_LEN], SignalBorrowedBuffer presentation_bytes); - -SignalFfiError *signal_backup_auth_credential_request_context_new(SignalOwnedBuffer *out, const uint8_t (*backup_key)[32], const uint8_t (*uuid)[16]); - -SignalFfiError *signal_backup_auth_credential_request_context_check_valid_contents(SignalBorrowedBuffer context_bytes); - -SignalFfiError *signal_backup_auth_credential_request_context_get_request(SignalOwnedBuffer *out, SignalBorrowedBuffer context_bytes); - -SignalFfiError *signal_backup_auth_credential_request_check_valid_contents(SignalBorrowedBuffer request_bytes); - -SignalFfiError *signal_backup_auth_credential_request_issue_deterministic(SignalOwnedBuffer *out, SignalBorrowedBuffer request_bytes, uint64_t redemption_time, uint8_t backup_level, uint8_t credential_type, SignalBorrowedBuffer params_bytes, const uint8_t (*randomness)[SignalRANDOMNESS_LEN]); - -SignalFfiError *signal_backup_auth_credential_response_check_valid_contents(SignalBorrowedBuffer response_bytes); - -SignalFfiError *signal_backup_auth_credential_request_context_receive_response(SignalOwnedBuffer *out, SignalBorrowedBuffer context_bytes, SignalBorrowedBuffer response_bytes, uint64_t expected_redemption_time, SignalBorrowedBuffer params_bytes); +SignalFfiError *signal_authenticated_chat_connection_send(SignalCPromiseFfiChatResponse *promise, SignalConstPointerTokioAsyncContext async_runtime, SignalConstPointerAuthenticatedChatConnection chat, SignalConstPointerHttpRequest http_request, uint32_t timeout_millis); SignalFfiError *signal_backup_auth_credential_check_valid_contents(SignalBorrowedBuffer params_bytes); @@ -1821,19 +1177,261 @@ SignalFfiError *signal_backup_auth_credential_presentation_check_valid_contents( SignalFfiError *signal_backup_auth_credential_presentation_verify(SignalBorrowedBuffer presentation_bytes, uint64_t now, SignalBorrowedBuffer server_params_bytes); +SignalFfiError *signal_backup_auth_credential_request_check_valid_contents(SignalBorrowedBuffer request_bytes); + +SignalFfiError *signal_backup_auth_credential_request_context_check_valid_contents(SignalBorrowedBuffer context_bytes); + +SignalFfiError *signal_backup_auth_credential_request_context_get_request(SignalOwnedBuffer *out, SignalBorrowedBuffer context_bytes); + +SignalFfiError *signal_backup_auth_credential_request_context_new(SignalOwnedBuffer *out, const uint8_t (*backup_key)[32], const uint8_t (*uuid)[16]); + +SignalFfiError *signal_backup_auth_credential_request_context_receive_response(SignalOwnedBuffer *out, SignalBorrowedBuffer context_bytes, SignalBorrowedBuffer response_bytes, uint64_t expected_redemption_time, SignalBorrowedBuffer params_bytes); + +SignalFfiError *signal_backup_auth_credential_request_issue_deterministic(SignalOwnedBuffer *out, SignalBorrowedBuffer request_bytes, uint64_t redemption_time, uint8_t backup_level, uint8_t credential_type, SignalBorrowedBuffer params_bytes, const uint8_t (*randomness)[SignalRANDOMNESS_LEN]); + +SignalFfiError *signal_backup_auth_credential_response_check_valid_contents(SignalBorrowedBuffer response_bytes); + +SignalFfiError *signal_backup_key_derive_backup_id(uint8_t (*out)[16], const uint8_t (*backup_key)[SignalBACKUP_KEY_LEN], const SignalServiceIdFixedWidthBinaryBytes *aci); + +SignalFfiError *signal_backup_key_derive_ec_key(SignalMutPointerPrivateKey *out, const uint8_t (*backup_key)[SignalBACKUP_KEY_LEN], const SignalServiceIdFixedWidthBinaryBytes *aci); + +SignalFfiError *signal_backup_key_derive_local_backup_metadata_key(uint8_t (*out)[SignalLOCAL_BACKUP_METADATA_KEY_LEN], const uint8_t (*backup_key)[SignalBACKUP_KEY_LEN]); + +SignalFfiError *signal_backup_key_derive_media_encryption_key(uint8_t (*out)[SignalMEDIA_ENCRYPTION_KEY_LEN], const uint8_t (*backup_key)[SignalBACKUP_KEY_LEN], const uint8_t (*media_id)[SignalMEDIA_ID_LEN]); + +SignalFfiError *signal_backup_key_derive_media_id(uint8_t (*out)[SignalMEDIA_ID_LEN], const uint8_t (*backup_key)[SignalBACKUP_KEY_LEN], const char *media_name); + +SignalFfiError *signal_backup_key_derive_thumbnail_transit_encryption_key(uint8_t (*out)[SignalMEDIA_ENCRYPTION_KEY_LEN], const uint8_t (*backup_key)[SignalBACKUP_KEY_LEN], const uint8_t (*media_id)[SignalMEDIA_ID_LEN]); + +SignalFfiError *signal_bridged_string_map_clone(SignalMutPointerBridgedStringMap *new_obj, SignalConstPointerBridgedStringMap obj); + +SignalFfiError *signal_bridged_string_map_destroy(SignalMutPointerBridgedStringMap p); + +SignalFfiError *signal_bridged_string_map_insert(SignalMutPointerBridgedStringMap map, const char *key, const char *value); + +SignalFfiError *signal_bridged_string_map_new(SignalMutPointerBridgedStringMap *out, uint32_t initial_capacity); + +SignalFfiError *signal_call_link_auth_credential_check_valid_contents(SignalBorrowedBuffer credential_bytes); + +SignalFfiError *signal_call_link_auth_credential_present_deterministic(SignalOwnedBuffer *out, SignalBorrowedBuffer credential_bytes, const SignalServiceIdFixedWidthBinaryBytes *user_id, uint64_t redemption_time, SignalBorrowedBuffer server_params_bytes, SignalBorrowedBuffer call_link_params_bytes, const uint8_t (*randomness)[SignalRANDOMNESS_LEN]); + +SignalFfiError *signal_call_link_auth_credential_presentation_check_valid_contents(SignalBorrowedBuffer presentation_bytes); + +SignalFfiError *signal_call_link_auth_credential_presentation_get_user_id(unsigned char (*out)[SignalUUID_CIPHERTEXT_LEN], SignalBorrowedBuffer presentation_bytes); + +SignalFfiError *signal_call_link_auth_credential_presentation_verify(SignalBorrowedBuffer presentation_bytes, uint64_t now, SignalBorrowedBuffer server_params_bytes, SignalBorrowedBuffer call_link_params_bytes); + +SignalFfiError *signal_call_link_auth_credential_response_check_valid_contents(SignalBorrowedBuffer response_bytes); + +SignalFfiError *signal_call_link_auth_credential_response_issue_deterministic(SignalOwnedBuffer *out, const SignalServiceIdFixedWidthBinaryBytes *user_id, uint64_t redemption_time, SignalBorrowedBuffer params_bytes, const uint8_t (*randomness)[SignalRANDOMNESS_LEN]); + +SignalFfiError *signal_call_link_auth_credential_response_receive(SignalOwnedBuffer *out, SignalBorrowedBuffer response_bytes, const SignalServiceIdFixedWidthBinaryBytes *user_id, uint64_t redemption_time, SignalBorrowedBuffer params_bytes); + +SignalFfiError *signal_call_link_public_params_check_valid_contents(SignalBorrowedBuffer params_bytes); + +SignalFfiError *signal_call_link_secret_params_check_valid_contents(SignalBorrowedBuffer params_bytes); + +SignalFfiError *signal_call_link_secret_params_decrypt_user_id(SignalServiceIdFixedWidthBinaryBytes *out, SignalBorrowedBuffer params_bytes, const unsigned char (*user_id)[SignalUUID_CIPHERTEXT_LEN]); + +SignalFfiError *signal_call_link_secret_params_derive_from_root_key(SignalOwnedBuffer *out, SignalBorrowedBuffer root_key); + +SignalFfiError *signal_call_link_secret_params_encrypt_user_id(unsigned char (*out)[SignalUUID_CIPHERTEXT_LEN], SignalBorrowedBuffer params_bytes, const SignalServiceIdFixedWidthBinaryBytes *user_id); + +SignalFfiError *signal_call_link_secret_params_get_public_params(SignalOwnedBuffer *out, SignalBorrowedBuffer params_bytes); + +SignalFfiError *signal_cds2_client_state_new(SignalMutPointerSgxClientState *out, SignalBorrowedBuffer mrenclave, SignalBorrowedBuffer attestation_msg, uint64_t current_timestamp); + +SignalFfiError *signal_cdsi_lookup_complete(SignalCPromiseFfiCdsiLookupResponse *promise, SignalConstPointerTokioAsyncContext async_runtime, SignalConstPointerCdsiLookup lookup); + +SignalFfiError *signal_cdsi_lookup_destroy(SignalMutPointerCdsiLookup p); + +SignalFfiError *signal_cdsi_lookup_new(SignalCPromiseMutPointerCdsiLookup *promise, SignalConstPointerTokioAsyncContext async_runtime, SignalConstPointerConnectionManager connection_manager, const char *username, const char *password, SignalConstPointerLookupRequest request); + +SignalFfiError *signal_cdsi_lookup_token(SignalOwnedBuffer *out, SignalConstPointerCdsiLookup lookup); + +SignalFfiError *signal_chat_connection_info_description(const char **out, SignalConstPointerChatConnectionInfo connection_info); + +SignalFfiError *signal_chat_connection_info_ip_version(uint8_t *out, SignalConstPointerChatConnectionInfo connection_info); + +SignalFfiError *signal_chat_connection_info_local_port(uint16_t *out, SignalConstPointerChatConnectionInfo connection_info); + +SignalFfiError *signal_ciphertext_message_destroy(SignalMutPointerCiphertextMessage p); + +SignalFfiError *signal_ciphertext_message_from_plaintext_content(SignalMutPointerCiphertextMessage *out, SignalConstPointerPlaintextContent m); + +SignalFfiError *signal_ciphertext_message_serialize(SignalOwnedBuffer *out, SignalConstPointerCiphertextMessage obj); + +SignalFfiError *signal_ciphertext_message_type(uint8_t *out, SignalConstPointerCiphertextMessage msg); + +SignalFfiError *signal_connection_info_destroy(SignalMutPointerConnectionInfo p); + +SignalFfiError *signal_connection_manager_clear_proxy(SignalConstPointerConnectionManager connection_manager); + +SignalFfiError *signal_connection_manager_destroy(SignalMutPointerConnectionManager p); + +SignalFfiError *signal_connection_manager_new(SignalMutPointerConnectionManager *out, uint8_t environment, const char *user_agent, SignalMutPointerBridgedStringMap remote_config); + +SignalFfiError *signal_connection_manager_on_network_change(SignalConstPointerConnectionManager connection_manager); + +SignalFfiError *signal_connection_manager_set_censorship_circumvention_enabled(SignalConstPointerConnectionManager connection_manager, bool enabled); + +SignalFfiError *signal_connection_manager_set_invalid_proxy(SignalConstPointerConnectionManager connection_manager); + +SignalFfiError *signal_connection_manager_set_proxy(SignalConstPointerConnectionManager connection_manager, SignalConstPointerConnectionProxyConfig proxy); + +SignalFfiError *signal_connection_manager_set_remote_config(SignalConstPointerConnectionManager connection_manager, SignalMutPointerBridgedStringMap remote_config); + +SignalFfiError *signal_connection_proxy_config_clone(SignalMutPointerConnectionProxyConfig *new_obj, SignalConstPointerConnectionProxyConfig obj); + +SignalFfiError *signal_connection_proxy_config_destroy(SignalMutPointerConnectionProxyConfig p); + +SignalFfiError *signal_connection_proxy_config_new(SignalMutPointerConnectionProxyConfig *out, const char *scheme, const char *host, int32_t port, const char *username, const char *password); + +SignalFfiError *signal_create_call_link_credential_check_valid_contents(SignalBorrowedBuffer params_bytes); + +SignalFfiError *signal_create_call_link_credential_present_deterministic(SignalOwnedBuffer *out, SignalBorrowedBuffer credential_bytes, SignalBorrowedBuffer room_id, const SignalServiceIdFixedWidthBinaryBytes *user_id, SignalBorrowedBuffer server_params_bytes, SignalBorrowedBuffer call_link_params_bytes, const uint8_t (*randomness)[SignalRANDOMNESS_LEN]); + +SignalFfiError *signal_create_call_link_credential_presentation_check_valid_contents(SignalBorrowedBuffer presentation_bytes); + +SignalFfiError *signal_create_call_link_credential_presentation_verify(SignalBorrowedBuffer presentation_bytes, SignalBorrowedBuffer room_id, uint64_t now, SignalBorrowedBuffer server_params_bytes, SignalBorrowedBuffer call_link_params_bytes); + +SignalFfiError *signal_create_call_link_credential_request_check_valid_contents(SignalBorrowedBuffer request_bytes); + +SignalFfiError *signal_create_call_link_credential_request_context_check_valid_contents(SignalBorrowedBuffer context_bytes); + +SignalFfiError *signal_create_call_link_credential_request_context_get_request(SignalOwnedBuffer *out, SignalBorrowedBuffer context_bytes); + +SignalFfiError *signal_create_call_link_credential_request_context_new_deterministic(SignalOwnedBuffer *out, SignalBorrowedBuffer room_id, const uint8_t (*randomness)[SignalRANDOMNESS_LEN]); + +SignalFfiError *signal_create_call_link_credential_request_context_receive_response(SignalOwnedBuffer *out, SignalBorrowedBuffer context_bytes, SignalBorrowedBuffer response_bytes, const SignalServiceIdFixedWidthBinaryBytes *user_id, SignalBorrowedBuffer params_bytes); + +SignalFfiError *signal_create_call_link_credential_request_issue_deterministic(SignalOwnedBuffer *out, SignalBorrowedBuffer request_bytes, const SignalServiceIdFixedWidthBinaryBytes *user_id, uint64_t timestamp, SignalBorrowedBuffer params_bytes, const uint8_t (*randomness)[SignalRANDOMNESS_LEN]); + +SignalFfiError *signal_create_call_link_credential_response_check_valid_contents(SignalBorrowedBuffer response_bytes); + +SignalFfiError *signal_create_otp(const char **out, const char *username, SignalBorrowedBuffer secret); + +SignalFfiError *signal_create_otp_from_base64(const char **out, const char *username, const char *secret); + +SignalFfiError *signal_decrypt_message(SignalOwnedBuffer *out, SignalConstPointerSignalMessage message, SignalConstPointerProtocolAddress protocol_address, SignalConstPointerFfiSessionStoreStruct session_store, SignalConstPointerFfiIdentityKeyStoreStruct identity_key_store); + +SignalFfiError *signal_decrypt_pre_key_message(SignalOwnedBuffer *out, SignalConstPointerPreKeySignalMessage message, SignalConstPointerProtocolAddress protocol_address, SignalConstPointerFfiSessionStoreStruct session_store, SignalConstPointerFfiIdentityKeyStoreStruct identity_key_store, SignalConstPointerFfiPreKeyStoreStruct prekey_store, SignalConstPointerFfiSignedPreKeyStoreStruct signed_prekey_store, SignalConstPointerFfiKyberPreKeyStoreStruct kyber_prekey_store); + +SignalFfiError *signal_decryption_error_message_clone(SignalMutPointerDecryptionErrorMessage *new_obj, SignalConstPointerDecryptionErrorMessage obj); + +SignalFfiError *signal_decryption_error_message_deserialize(SignalMutPointerDecryptionErrorMessage *out, SignalBorrowedBuffer data); + +SignalFfiError *signal_decryption_error_message_destroy(SignalMutPointerDecryptionErrorMessage p); + +SignalFfiError *signal_decryption_error_message_extract_from_serialized_content(SignalMutPointerDecryptionErrorMessage *out, SignalBorrowedBuffer bytes); + +SignalFfiError *signal_decryption_error_message_for_original_message(SignalMutPointerDecryptionErrorMessage *out, SignalBorrowedBuffer original_bytes, uint8_t original_type, uint64_t original_timestamp, uint32_t original_sender_device_id); + +SignalFfiError *signal_decryption_error_message_get_device_id(uint32_t *out, SignalConstPointerDecryptionErrorMessage obj); + +SignalFfiError *signal_decryption_error_message_get_ratchet_key(SignalMutPointerPublicKey *out, SignalConstPointerDecryptionErrorMessage m); + +SignalFfiError *signal_decryption_error_message_get_timestamp(uint64_t *out, SignalConstPointerDecryptionErrorMessage obj); + +SignalFfiError *signal_decryption_error_message_serialize(SignalOwnedBuffer *out, SignalConstPointerDecryptionErrorMessage obj); + +SignalFfiError *signal_device_transfer_generate_certificate(SignalOwnedBuffer *out, SignalBorrowedBuffer private_key, const char *name, uint32_t days_to_expire); + +SignalFfiError *signal_device_transfer_generate_private_key(SignalOwnedBuffer *out); + +SignalFfiError *signal_device_transfer_generate_private_key_with_format(SignalOwnedBuffer *out, uint8_t key_format); + +SignalFfiError *signal_encrypt_message(SignalMutPointerCiphertextMessage *out, SignalBorrowedBuffer ptext, SignalConstPointerProtocolAddress protocol_address, SignalConstPointerFfiSessionStoreStruct session_store, SignalConstPointerFfiIdentityKeyStoreStruct identity_key_store, uint64_t now); + +void signal_error_free(SignalFfiError *err); + +SignalFfiError *signal_error_get_address(const SignalFfiError *err, SignalMutPointerProtocolAddress *out); + +SignalFfiError *signal_error_get_message(const SignalFfiError *err, const char **out); + +SignalFfiError *signal_error_get_retry_after_seconds(const SignalFfiError *err, uint32_t *out); + +SignalFfiError *signal_error_get_tries_remaining(const SignalFfiError *err, uint32_t *out); + +uint32_t signal_error_get_type(const SignalFfiError *err); + +SignalFfiError *signal_error_get_unknown_fields(const SignalFfiError *err, SignalStringArray *out); + +SignalFfiError *signal_error_get_uuid(const SignalFfiError *err, uint8_t (*out)[16]); + +SignalFfiError *signal_expiring_profile_key_credential_check_valid_contents(SignalBorrowedBuffer buffer); + +SignalFfiError *signal_expiring_profile_key_credential_get_expiration_time(uint64_t *out, const unsigned char (*credential)[SignalEXPIRING_PROFILE_KEY_CREDENTIAL_LEN]); + +SignalFfiError *signal_expiring_profile_key_credential_response_check_valid_contents(SignalBorrowedBuffer buffer); + +SignalFfiError *signal_fingerprint_clone(SignalMutPointerFingerprint *new_obj, SignalConstPointerFingerprint obj); + +SignalFfiError *signal_fingerprint_compare(bool *out, SignalBorrowedBuffer fprint1, SignalBorrowedBuffer fprint2); + +SignalFfiError *signal_fingerprint_destroy(SignalMutPointerFingerprint p); + +SignalFfiError *signal_fingerprint_display_string(const char **out, SignalConstPointerFingerprint obj); + +SignalFfiError *signal_fingerprint_new(SignalMutPointerFingerprint *out, uint32_t iterations, uint32_t version, SignalBorrowedBuffer local_identifier, SignalConstPointerPublicKey local_key, SignalBorrowedBuffer remote_identifier, SignalConstPointerPublicKey remote_key); + +SignalFfiError *signal_fingerprint_scannable_encoding(SignalOwnedBuffer *out, SignalConstPointerFingerprint obj); + +void signal_free_buffer(const unsigned char *buf, size_t buf_len); + +void signal_free_bytestring_array(SignalBytestringArray array); + +void signal_free_list_of_strings(SignalOwnedBufferOfCStringPtr buffer); + +void signal_free_lookup_response_entry_list(SignalOwnedBufferOfFfiCdsiLookupResponseEntry buffer); + +void signal_free_string(const char *buf); + +SignalFfiError *signal_generic_server_public_params_check_valid_contents(SignalBorrowedBuffer params_bytes); + +SignalFfiError *signal_generic_server_secret_params_check_valid_contents(SignalBorrowedBuffer params_bytes); + +SignalFfiError *signal_generic_server_secret_params_generate_deterministic(SignalOwnedBuffer *out, const uint8_t (*randomness)[SignalRANDOMNESS_LEN]); + +SignalFfiError *signal_generic_server_secret_params_get_public_params(SignalOwnedBuffer *out, SignalBorrowedBuffer params_bytes); + +SignalFfiError *signal_group_decrypt_message(SignalOwnedBuffer *out, SignalConstPointerProtocolAddress sender, SignalBorrowedBuffer message, SignalConstPointerFfiSenderKeyStoreStruct store); + +SignalFfiError *signal_group_encrypt_message(SignalMutPointerCiphertextMessage *out, SignalConstPointerProtocolAddress sender, const uint8_t (*distribution_id)[16], SignalBorrowedBuffer message, SignalConstPointerFfiSenderKeyStoreStruct store); + +SignalFfiError *signal_group_master_key_check_valid_contents(SignalBorrowedBuffer buffer); + +SignalFfiError *signal_group_public_params_check_valid_contents(SignalBorrowedBuffer buffer); + +SignalFfiError *signal_group_public_params_get_group_identifier(uint8_t (*out)[SignalGROUP_IDENTIFIER_LEN], const unsigned char (*group_public_params)[SignalGROUP_PUBLIC_PARAMS_LEN]); + +SignalFfiError *signal_group_secret_params_check_valid_contents(SignalBorrowedBuffer buffer); + +SignalFfiError *signal_group_secret_params_decrypt_blob_with_padding(SignalOwnedBuffer *out, const unsigned char (*params)[SignalGROUP_SECRET_PARAMS_LEN], SignalBorrowedBuffer ciphertext); + +SignalFfiError *signal_group_secret_params_decrypt_profile_key(unsigned char (*out)[SignalPROFILE_KEY_LEN], const unsigned char (*params)[SignalGROUP_SECRET_PARAMS_LEN], const unsigned char (*profile_key)[SignalPROFILE_KEY_CIPHERTEXT_LEN], const SignalServiceIdFixedWidthBinaryBytes *user_id); + +SignalFfiError *signal_group_secret_params_decrypt_service_id(SignalServiceIdFixedWidthBinaryBytes *out, const unsigned char (*params)[SignalGROUP_SECRET_PARAMS_LEN], const unsigned char (*ciphertext)[SignalUUID_CIPHERTEXT_LEN]); + +SignalFfiError *signal_group_secret_params_derive_from_master_key(unsigned char (*out)[SignalGROUP_SECRET_PARAMS_LEN], const unsigned char (*master_key)[SignalGROUP_MASTER_KEY_LEN]); + +SignalFfiError *signal_group_secret_params_encrypt_blob_with_padding_deterministic(SignalOwnedBuffer *out, const unsigned char (*params)[SignalGROUP_SECRET_PARAMS_LEN], const uint8_t (*randomness)[SignalRANDOMNESS_LEN], SignalBorrowedBuffer plaintext, uint32_t padding_len); + +SignalFfiError *signal_group_secret_params_encrypt_profile_key(unsigned char (*out)[SignalPROFILE_KEY_CIPHERTEXT_LEN], const unsigned char (*params)[SignalGROUP_SECRET_PARAMS_LEN], const unsigned char (*profile_key)[SignalPROFILE_KEY_LEN], const SignalServiceIdFixedWidthBinaryBytes *user_id); + +SignalFfiError *signal_group_secret_params_encrypt_service_id(unsigned char (*out)[SignalUUID_CIPHERTEXT_LEN], const unsigned char (*params)[SignalGROUP_SECRET_PARAMS_LEN], const SignalServiceIdFixedWidthBinaryBytes *service_id); + +SignalFfiError *signal_group_secret_params_generate_deterministic(unsigned char (*out)[SignalGROUP_SECRET_PARAMS_LEN], const uint8_t (*randomness)[SignalRANDOMNESS_LEN]); + +SignalFfiError *signal_group_secret_params_get_master_key(unsigned char (*out)[SignalGROUP_MASTER_KEY_LEN], const unsigned char (*params)[SignalGROUP_SECRET_PARAMS_LEN]); + +SignalFfiError *signal_group_secret_params_get_public_params(unsigned char (*out)[SignalGROUP_PUBLIC_PARAMS_LEN], const unsigned char (*params)[SignalGROUP_SECRET_PARAMS_LEN]); + SignalFfiError *signal_group_send_derived_key_pair_check_valid_contents(SignalBorrowedBuffer bytes); SignalFfiError *signal_group_send_derived_key_pair_for_expiration(SignalOwnedBuffer *out, uint64_t expiration, SignalConstPointerServerSecretParams server_params); -SignalFfiError *signal_group_send_endorsements_response_check_valid_contents(SignalBorrowedBuffer bytes); - -SignalFfiError *signal_group_send_endorsements_response_issue_deterministic(SignalOwnedBuffer *out, SignalBorrowedBuffer concatenated_group_member_ciphertexts, SignalBorrowedBuffer key_pair, const uint8_t (*randomness)[SignalRANDOMNESS_LEN]); - -SignalFfiError *signal_group_send_endorsements_response_get_expiration(uint64_t *out, SignalBorrowedBuffer response_bytes); - -SignalFfiError *signal_group_send_endorsements_response_receive_and_combine_with_service_ids(SignalBytestringArray *out, SignalBorrowedBuffer response_bytes, SignalBorrowedBuffer group_members, const SignalServiceIdFixedWidthBinaryBytes *local_user, uint64_t now, const unsigned char (*group_params)[SignalGROUP_SECRET_PARAMS_LEN], SignalConstPointerServerPublicParams server_params); - -SignalFfiError *signal_group_send_endorsements_response_receive_and_combine_with_ciphertexts(SignalBytestringArray *out, SignalBorrowedBuffer response_bytes, SignalBorrowedBuffer concatenated_group_member_ciphertexts, SignalBorrowedBuffer local_user_ciphertext, uint64_t now, SignalConstPointerServerPublicParams server_params); +SignalFfiError *signal_group_send_endorsement_call_link_params_to_token(SignalOwnedBuffer *out, SignalBorrowedBuffer endorsement, SignalBorrowedBuffer call_link_secret_params_serialized); SignalFfiError *signal_group_send_endorsement_check_valid_contents(SignalBorrowedBuffer bytes); @@ -1843,9 +1441,15 @@ SignalFfiError *signal_group_send_endorsement_remove(SignalOwnedBuffer *out, Sig SignalFfiError *signal_group_send_endorsement_to_token(SignalOwnedBuffer *out, SignalBorrowedBuffer endorsement, const unsigned char (*group_params)[SignalGROUP_SECRET_PARAMS_LEN]); -SignalFfiError *signal_group_send_token_check_valid_contents(SignalBorrowedBuffer bytes); +SignalFfiError *signal_group_send_endorsements_response_check_valid_contents(SignalBorrowedBuffer bytes); -SignalFfiError *signal_group_send_token_to_full_token(SignalOwnedBuffer *out, SignalBorrowedBuffer token, uint64_t expiration); +SignalFfiError *signal_group_send_endorsements_response_get_expiration(uint64_t *out, SignalBorrowedBuffer response_bytes); + +SignalFfiError *signal_group_send_endorsements_response_issue_deterministic(SignalOwnedBuffer *out, SignalBorrowedBuffer concatenated_group_member_ciphertexts, SignalBorrowedBuffer key_pair, const uint8_t (*randomness)[SignalRANDOMNESS_LEN]); + +SignalFfiError *signal_group_send_endorsements_response_receive_and_combine_with_ciphertexts(SignalBytestringArray *out, SignalBorrowedBuffer response_bytes, SignalBorrowedBuffer concatenated_group_member_ciphertexts, SignalBorrowedBuffer local_user_ciphertext, uint64_t now, SignalConstPointerServerPublicParams server_params); + +SignalFfiError *signal_group_send_endorsements_response_receive_and_combine_with_service_ids(SignalBytestringArray *out, SignalBorrowedBuffer response_bytes, SignalBorrowedBuffer group_members, const SignalServiceIdFixedWidthBinaryBytes *local_user, uint64_t now, const unsigned char (*group_params)[SignalGROUP_SECRET_PARAMS_LEN], SignalConstPointerServerPublicParams server_params); SignalFfiError *signal_group_send_full_token_check_valid_contents(SignalBorrowedBuffer bytes); @@ -1853,111 +1457,173 @@ SignalFfiError *signal_group_send_full_token_get_expiration(uint64_t *out, Signa SignalFfiError *signal_group_send_full_token_verify(SignalBorrowedBuffer token, SignalBorrowedBuffer user_ids, uint64_t now, SignalBorrowedBuffer key_pair); -SignalFfiError *signal_connection_info_destroy(SignalMutPointerConnectionInfo p); +SignalFfiError *signal_group_send_token_check_valid_contents(SignalBorrowedBuffer bytes); -SignalFfiError *signal_connection_proxy_config_destroy(SignalMutPointerConnectionProxyConfig p); +SignalFfiError *signal_group_send_token_to_full_token(SignalOwnedBuffer *out, SignalBorrowedBuffer token, uint64_t expiration); -SignalFfiError *signal_connection_proxy_config_clone(SignalMutPointerConnectionProxyConfig *new_obj, SignalConstPointerConnectionProxyConfig obj); +SignalFfiError *signal_hex_encode(char *output, size_t output_len, const uint8_t *input, size_t input_len); -SignalFfiError *signal_connection_proxy_config_new(SignalMutPointerConnectionProxyConfig *out, const char *scheme, const char *host, int32_t port, const char *username, const char *password); +SignalFfiError *signal_hkdf_derive(SignalBorrowedMutableBuffer output, SignalBorrowedBuffer ikm, SignalBorrowedBuffer label, SignalBorrowedBuffer salt); -SignalFfiError *signal_connection_manager_destroy(SignalMutPointerConnectionManager p); +SignalFfiError *signal_hsm_enclave_client_complete_handshake(SignalMutPointerHsmEnclaveClient cli, SignalBorrowedBuffer handshake_received); -SignalFfiError *signal_connection_manager_new(SignalMutPointerConnectionManager *out, uint8_t environment, const char *user_agent); +SignalFfiError *signal_hsm_enclave_client_destroy(SignalMutPointerHsmEnclaveClient p); -SignalFfiError *signal_connection_manager_set_proxy(SignalConstPointerConnectionManager connection_manager, SignalConstPointerConnectionProxyConfig proxy); +SignalFfiError *signal_hsm_enclave_client_established_recv(SignalOwnedBuffer *out, SignalMutPointerHsmEnclaveClient cli, SignalBorrowedBuffer received_ciphertext); -SignalFfiError *signal_connection_manager_set_invalid_proxy(SignalConstPointerConnectionManager connection_manager); +SignalFfiError *signal_hsm_enclave_client_established_send(SignalOwnedBuffer *out, SignalMutPointerHsmEnclaveClient cli, SignalBorrowedBuffer plaintext_to_send); -SignalFfiError *signal_connection_manager_clear_proxy(SignalConstPointerConnectionManager connection_manager); +SignalFfiError *signal_hsm_enclave_client_initial_request(SignalOwnedBuffer *out, SignalConstPointerHsmEnclaveClient obj); -SignalFfiError *signal_connection_manager_set_censorship_circumvention_enabled(SignalConstPointerConnectionManager connection_manager, bool enabled); +SignalFfiError *signal_hsm_enclave_client_new(SignalMutPointerHsmEnclaveClient *out, SignalBorrowedBuffer trusted_public_key, SignalBorrowedBuffer trusted_code_hashes); -SignalFfiError *signal_connection_manager_on_network_change(SignalConstPointerConnectionManager connection_manager); - -SignalFfiError *signal_create_otp(const char **out, const char *username, SignalBorrowedBuffer secret); - -SignalFfiError *signal_create_otp_from_base64(const char **out, const char *username, const char *secret); - -SignalFfiError *signal_lookup_request_destroy(SignalMutPointerLookupRequest p); - -SignalFfiError *signal_lookup_request_new(SignalMutPointerLookupRequest *out); - -SignalFfiError *signal_lookup_request_add_e164(SignalConstPointerLookupRequest request, const char *e164); - -SignalFfiError *signal_lookup_request_add_previous_e164(SignalConstPointerLookupRequest request, const char *e164); - -SignalFfiError *signal_lookup_request_set_token(SignalConstPointerLookupRequest request, SignalBorrowedBuffer token); - -SignalFfiError *signal_lookup_request_add_aci_and_access_key(SignalConstPointerLookupRequest request, const SignalServiceIdFixedWidthBinaryBytes *aci, SignalBorrowedBuffer access_key); - -SignalFfiError *signal_cdsi_lookup_destroy(SignalMutPointerCdsiLookup p); - -SignalFfiError *signal_cdsi_lookup_new(SignalCPromiseMutPointerCdsiLookup *promise, SignalConstPointerTokioAsyncContext async_runtime, SignalConstPointerConnectionManager connection_manager, const char *username, const char *password, SignalConstPointerLookupRequest request); - -SignalFfiError *signal_cdsi_lookup_new_routes(SignalCPromiseMutPointerCdsiLookup *promise, SignalConstPointerTokioAsyncContext async_runtime, SignalConstPointerConnectionManager connection_manager, const char *username, const char *password, SignalConstPointerLookupRequest request); - -SignalFfiError *signal_cdsi_lookup_token(SignalOwnedBuffer *out, SignalConstPointerCdsiLookup lookup); - -SignalFfiError *signal_cdsi_lookup_complete(SignalCPromiseFfiCdsiLookupResponse *promise, SignalConstPointerTokioAsyncContext async_runtime, SignalConstPointerCdsiLookup lookup); +SignalFfiError *signal_http_request_add_header(SignalConstPointerHttpRequest request, const char *name, const char *value); SignalFfiError *signal_http_request_destroy(SignalMutPointerHttpRequest p); -SignalFfiError *signal_unauthenticated_chat_connection_destroy(SignalMutPointerUnauthenticatedChatConnection p); - -SignalFfiError *signal_authenticated_chat_connection_destroy(SignalMutPointerAuthenticatedChatConnection p); - SignalFfiError *signal_http_request_new_with_body(SignalMutPointerHttpRequest *out, const char *method, const char *path, SignalBorrowedBuffer body_as_slice); SignalFfiError *signal_http_request_new_without_body(SignalMutPointerHttpRequest *out, const char *method, const char *path); -SignalFfiError *signal_http_request_add_header(SignalConstPointerHttpRequest request, const char *name, const char *value); +SignalFfiError *signal_identitykey_verify_alternate_identity(bool *out, SignalConstPointerPublicKey public_key, SignalConstPointerPublicKey other_identity, SignalBorrowedBuffer signature); -SignalFfiError *signal_chat_connection_info_local_port(uint16_t *out, SignalConstPointerChatConnectionInfo connection_info); +SignalFfiError *signal_identitykeypair_deserialize(SignalMutPointerPrivateKey *private_key, SignalMutPointerPublicKey *public_key, SignalBorrowedBuffer input); -SignalFfiError *signal_chat_connection_info_ip_version(uint8_t *out, SignalConstPointerChatConnectionInfo connection_info); +SignalFfiError *signal_identitykeypair_serialize(SignalOwnedBuffer *out, SignalConstPointerPublicKey public_key, SignalConstPointerPrivateKey private_key); -SignalFfiError *signal_chat_connection_info_description(const char **out, SignalConstPointerChatConnectionInfo connection_info); +SignalFfiError *signal_identitykeypair_sign_alternate_identity(SignalOwnedBuffer *out, SignalConstPointerPublicKey public_key, SignalConstPointerPrivateKey private_key, SignalConstPointerPublicKey other_identity); -SignalFfiError *signal_unauthenticated_chat_connection_connect(SignalCPromiseMutPointerUnauthenticatedChatConnection *promise, SignalConstPointerTokioAsyncContext async_runtime, SignalConstPointerConnectionManager connection_manager); +SignalFfiError *signal_incremental_mac_calculate_chunk_size(uint32_t *out, uint32_t data_size); -SignalFfiError *signal_unauthenticated_chat_connection_init_listener(SignalConstPointerUnauthenticatedChatConnection chat, SignalConstPointerFfiChatListenerStruct listener); +SignalFfiError *signal_incremental_mac_destroy(SignalMutPointerIncrementalMac p); -SignalFfiError *signal_unauthenticated_chat_connection_send(SignalCPromiseFfiChatResponse *promise, SignalConstPointerTokioAsyncContext async_runtime, SignalConstPointerUnauthenticatedChatConnection chat, SignalConstPointerHttpRequest http_request, uint32_t timeout_millis); +SignalFfiError *signal_incremental_mac_finalize(SignalOwnedBuffer *out, SignalMutPointerIncrementalMac mac); -SignalFfiError *signal_unauthenticated_chat_connection_disconnect(SignalCPromisebool *promise, SignalConstPointerTokioAsyncContext async_runtime, SignalConstPointerUnauthenticatedChatConnection chat); +SignalFfiError *signal_incremental_mac_initialize(SignalMutPointerIncrementalMac *out, SignalBorrowedBuffer key, uint32_t chunk_size); -SignalFfiError *signal_unauthenticated_chat_connection_info(SignalMutPointerChatConnectionInfo *out, SignalConstPointerUnauthenticatedChatConnection chat); +SignalFfiError *signal_incremental_mac_update(SignalOwnedBuffer *out, SignalMutPointerIncrementalMac mac, SignalBorrowedBuffer bytes, uint32_t offset, uint32_t length); -SignalFfiError *signal_authenticated_chat_connection_preconnect(SignalCPromisebool *promise, SignalConstPointerTokioAsyncContext async_runtime, SignalConstPointerConnectionManager connection_manager); +bool signal_init_logger(SignalLogLevel max_level, SignalFfiLogger logger); -SignalFfiError *signal_authenticated_chat_connection_connect(SignalCPromiseMutPointerAuthenticatedChatConnection *promise, SignalConstPointerTokioAsyncContext async_runtime, SignalConstPointerConnectionManager connection_manager, const char *username, const char *password, bool receive_stories); +SignalFfiError *signal_kyber_key_pair_clone(SignalMutPointerKyberKeyPair *new_obj, SignalConstPointerKyberKeyPair obj); -SignalFfiError *signal_authenticated_chat_connection_init_listener(SignalConstPointerAuthenticatedChatConnection chat, SignalConstPointerFfiChatListenerStruct listener); +SignalFfiError *signal_kyber_key_pair_destroy(SignalMutPointerKyberKeyPair p); -SignalFfiError *signal_authenticated_chat_connection_send(SignalCPromiseFfiChatResponse *promise, SignalConstPointerTokioAsyncContext async_runtime, SignalConstPointerAuthenticatedChatConnection chat, SignalConstPointerHttpRequest http_request, uint32_t timeout_millis); +SignalFfiError *signal_kyber_key_pair_generate(SignalMutPointerKyberKeyPair *out); -SignalFfiError *signal_authenticated_chat_connection_disconnect(SignalCPromisebool *promise, SignalConstPointerTokioAsyncContext async_runtime, SignalConstPointerAuthenticatedChatConnection chat); +SignalFfiError *signal_kyber_key_pair_get_public_key(SignalMutPointerKyberPublicKey *out, SignalConstPointerKyberKeyPair key_pair); -SignalFfiError *signal_authenticated_chat_connection_info(SignalMutPointerChatConnectionInfo *out, SignalConstPointerAuthenticatedChatConnection chat); +SignalFfiError *signal_kyber_key_pair_get_secret_key(SignalMutPointerKyberSecretKey *out, SignalConstPointerKyberKeyPair key_pair); -SignalFfiError *signal_server_message_ack_destroy(SignalMutPointerServerMessageAck p); +SignalFfiError *signal_kyber_pre_key_record_clone(SignalMutPointerKyberPreKeyRecord *new_obj, SignalConstPointerKyberPreKeyRecord obj); -SignalFfiError *signal_server_message_ack_send(SignalConstPointerServerMessageAck ack); +SignalFfiError *signal_kyber_pre_key_record_deserialize(SignalMutPointerKyberPreKeyRecord *out, SignalBorrowedBuffer data); -SignalFfiError *signal_tokio_async_context_destroy(SignalMutPointerTokioAsyncContext p); +SignalFfiError *signal_kyber_pre_key_record_destroy(SignalMutPointerKyberPreKeyRecord p); -SignalFfiError *signal_tokio_async_context_new(SignalMutPointerTokioAsyncContext *out); +SignalFfiError *signal_kyber_pre_key_record_get_id(uint32_t *out, SignalConstPointerKyberPreKeyRecord obj); -SignalFfiError *signal_tokio_async_context_cancel(SignalConstPointerTokioAsyncContext context, uint64_t raw_cancellation_id); +SignalFfiError *signal_kyber_pre_key_record_get_key_pair(SignalMutPointerKyberKeyPair *out, SignalConstPointerKyberPreKeyRecord obj); -SignalFfiError *signal_pin_hash_destroy(SignalMutPointerPinHash p); +SignalFfiError *signal_kyber_pre_key_record_get_public_key(SignalMutPointerKyberPublicKey *out, SignalConstPointerKyberPreKeyRecord obj); + +SignalFfiError *signal_kyber_pre_key_record_get_secret_key(SignalMutPointerKyberSecretKey *out, SignalConstPointerKyberPreKeyRecord obj); + +SignalFfiError *signal_kyber_pre_key_record_get_signature(SignalOwnedBuffer *out, SignalConstPointerKyberPreKeyRecord obj); + +SignalFfiError *signal_kyber_pre_key_record_get_timestamp(uint64_t *out, SignalConstPointerKyberPreKeyRecord obj); + +SignalFfiError *signal_kyber_pre_key_record_new(SignalMutPointerKyberPreKeyRecord *out, uint32_t id, uint64_t timestamp, SignalConstPointerKyberKeyPair key_pair, SignalBorrowedBuffer signature); + +SignalFfiError *signal_kyber_pre_key_record_serialize(SignalOwnedBuffer *out, SignalConstPointerKyberPreKeyRecord obj); + +SignalFfiError *signal_kyber_public_key_clone(SignalMutPointerKyberPublicKey *new_obj, SignalConstPointerKyberPublicKey obj); + +SignalFfiError *signal_kyber_public_key_deserialize(SignalMutPointerKyberPublicKey *out, SignalBorrowedBuffer data); + +SignalFfiError *signal_kyber_public_key_destroy(SignalMutPointerKyberPublicKey p); + +SignalFfiError *signal_kyber_public_key_equals(bool *out, SignalConstPointerKyberPublicKey lhs, SignalConstPointerKyberPublicKey rhs); + +SignalFfiError *signal_kyber_public_key_serialize(SignalOwnedBuffer *out, SignalConstPointerKyberPublicKey obj); + +SignalFfiError *signal_kyber_secret_key_clone(SignalMutPointerKyberSecretKey *new_obj, SignalConstPointerKyberSecretKey obj); + +SignalFfiError *signal_kyber_secret_key_deserialize(SignalMutPointerKyberSecretKey *out, SignalBorrowedBuffer data); + +SignalFfiError *signal_kyber_secret_key_destroy(SignalMutPointerKyberSecretKey p); + +SignalFfiError *signal_kyber_secret_key_serialize(SignalOwnedBuffer *out, SignalConstPointerKyberSecretKey obj); + +SignalFfiError *signal_lookup_request_add_aci_and_access_key(SignalConstPointerLookupRequest request, const SignalServiceIdFixedWidthBinaryBytes *aci, SignalBorrowedBuffer access_key); + +SignalFfiError *signal_lookup_request_add_e164(SignalConstPointerLookupRequest request, const char *e164); + +SignalFfiError *signal_lookup_request_add_previous_e164(SignalConstPointerLookupRequest request, const char *e164); + +SignalFfiError *signal_lookup_request_destroy(SignalMutPointerLookupRequest p); + +SignalFfiError *signal_lookup_request_new(SignalMutPointerLookupRequest *out); + +SignalFfiError *signal_lookup_request_set_token(SignalConstPointerLookupRequest request, SignalBorrowedBuffer token); + +SignalFfiError *signal_message_backup_key_destroy(SignalMutPointerMessageBackupKey p); + +SignalFfiError *signal_message_backup_key_from_account_entropy_pool(SignalMutPointerMessageBackupKey *out, const char *account_entropy, const SignalServiceIdFixedWidthBinaryBytes *aci); + +SignalFfiError *signal_message_backup_key_from_backup_key_and_backup_id(SignalMutPointerMessageBackupKey *out, const uint8_t (*backup_key)[32], const uint8_t (*backup_id)[16]); + +SignalFfiError *signal_message_backup_key_get_aes_key(uint8_t (*out)[32], SignalConstPointerMessageBackupKey key); + +SignalFfiError *signal_message_backup_key_get_hmac_key(uint8_t (*out)[32], SignalConstPointerMessageBackupKey key); + +SignalFfiError *signal_message_backup_validation_outcome_destroy(SignalMutPointerMessageBackupValidationOutcome p); + +SignalFfiError *signal_message_backup_validation_outcome_get_error_message(const char **out, SignalConstPointerMessageBackupValidationOutcome outcome); + +SignalFfiError *signal_message_backup_validation_outcome_get_unknown_fields(SignalStringArray *out, SignalConstPointerMessageBackupValidationOutcome outcome); + +SignalFfiError *signal_message_backup_validator_validate(SignalMutPointerMessageBackupValidationOutcome *out, SignalConstPointerMessageBackupKey key, SignalConstPointerFfiInputStreamStruct first_stream, SignalConstPointerFfiInputStreamStruct second_stream, uint64_t len, uint8_t purpose); + +SignalFfiError *signal_message_clone(SignalMutPointerSignalMessage *new_obj, SignalConstPointerSignalMessage obj); + +SignalFfiError *signal_message_deserialize(SignalMutPointerSignalMessage *out, SignalBorrowedBuffer data); + +SignalFfiError *signal_message_destroy(SignalMutPointerSignalMessage p); + +SignalFfiError *signal_message_get_body(SignalOwnedBuffer *out, SignalConstPointerSignalMessage obj); + +SignalFfiError *signal_message_get_counter(uint32_t *out, SignalConstPointerSignalMessage obj); + +SignalFfiError *signal_message_get_message_version(uint32_t *out, SignalConstPointerSignalMessage obj); + +SignalFfiError *signal_message_get_sender_ratchet_key(SignalMutPointerPublicKey *out, SignalConstPointerSignalMessage m); + +SignalFfiError *signal_message_get_serialized(SignalOwnedBuffer *out, SignalConstPointerSignalMessage obj); + +SignalFfiError *signal_message_new(SignalMutPointerSignalMessage *out, uint8_t message_version, SignalBorrowedBuffer mac_key, SignalConstPointerPublicKey sender_ratchet_key, uint32_t counter, uint32_t previous_counter, SignalBorrowedBuffer ciphertext, SignalConstPointerPublicKey sender_identity_key, SignalConstPointerPublicKey receiver_identity_key); + +SignalFfiError *signal_message_verify_mac(bool *out, SignalConstPointerSignalMessage msg, SignalConstPointerPublicKey sender_identity_key, SignalConstPointerPublicKey receiver_identity_key, SignalBorrowedBuffer mac_key); + +#if defined(SIGNAL_MEDIA_SUPPORTED) +SignalFfiError *signal_mp4_sanitizer_sanitize(SignalMutPointerSanitizedMetadata *out, SignalConstPointerFfiInputStreamStruct input, uint64_t len); +#endif + +SignalFfiError *signal_online_backup_validator_add_frame(SignalMutPointerOnlineBackupValidator backup, SignalBorrowedBuffer frame); + +SignalFfiError *signal_online_backup_validator_destroy(SignalMutPointerOnlineBackupValidator p); + +SignalFfiError *signal_online_backup_validator_finalize(SignalMutPointerOnlineBackupValidator backup); + +SignalFfiError *signal_online_backup_validator_new(SignalMutPointerOnlineBackupValidator *out, SignalBorrowedBuffer backup_info_frame, uint8_t purpose); + +SignalFfiError *signal_pin_hash_access_key(uint8_t (*out)[32], SignalConstPointerPinHash ph); SignalFfiError *signal_pin_hash_clone(SignalMutPointerPinHash *new_obj, SignalConstPointerPinHash obj); -SignalFfiError *signal_pin_hash_encryption_key(uint8_t (*out)[32], SignalConstPointerPinHash ph); +SignalFfiError *signal_pin_hash_destroy(SignalMutPointerPinHash p); -SignalFfiError *signal_pin_hash_access_key(uint8_t (*out)[32], SignalConstPointerPinHash ph); +SignalFfiError *signal_pin_hash_encryption_key(uint8_t (*out)[32], SignalConstPointerPinHash ph); SignalFfiError *signal_pin_hash_from_salt(SignalMutPointerPinHash *out, SignalBorrowedBuffer pin, const uint8_t (*salt)[32]); @@ -1967,110 +1633,180 @@ SignalFfiError *signal_pin_local_hash(const char **out, SignalBorrowedBuffer pin SignalFfiError *signal_pin_verify_local_hash(bool *out, const char *encoded_hash, SignalBorrowedBuffer pin); -SignalFfiError *signal_account_entropy_pool_generate(const char **out); +SignalFfiError *signal_plaintext_content_clone(SignalMutPointerPlaintextContent *new_obj, SignalConstPointerPlaintextContent obj); -SignalFfiError *signal_account_entropy_pool_is_valid(bool *out, const char *account_entropy); +SignalFfiError *signal_plaintext_content_deserialize(SignalMutPointerPlaintextContent *out, SignalBorrowedBuffer data); -SignalFfiError *signal_account_entropy_pool_derive_svr_key(uint8_t (*out)[SignalSVR_KEY_LEN], const char *account_entropy); +SignalFfiError *signal_plaintext_content_destroy(SignalMutPointerPlaintextContent p); -SignalFfiError *signal_account_entropy_pool_derive_backup_key(uint8_t (*out)[SignalBACKUP_KEY_LEN], const char *account_entropy); +SignalFfiError *signal_plaintext_content_from_decryption_error_message(SignalMutPointerPlaintextContent *out, SignalConstPointerDecryptionErrorMessage m); -SignalFfiError *signal_backup_key_derive_backup_id(uint8_t (*out)[16], const uint8_t (*backup_key)[SignalBACKUP_KEY_LEN], const SignalServiceIdFixedWidthBinaryBytes *aci); +SignalFfiError *signal_plaintext_content_get_body(SignalOwnedBuffer *out, SignalConstPointerPlaintextContent obj); -SignalFfiError *signal_backup_key_derive_ec_key(SignalMutPointerPrivateKey *out, const uint8_t (*backup_key)[SignalBACKUP_KEY_LEN], const SignalServiceIdFixedWidthBinaryBytes *aci); +SignalFfiError *signal_plaintext_content_serialize(SignalOwnedBuffer *out, SignalConstPointerPlaintextContent obj); -SignalFfiError *signal_backup_key_derive_local_backup_metadata_key(uint8_t (*out)[SignalLOCAL_BACKUP_METADATA_KEY_LEN], const uint8_t (*backup_key)[SignalBACKUP_KEY_LEN]); +SignalFfiError *signal_pre_key_bundle_clone(SignalMutPointerPreKeyBundle *new_obj, SignalConstPointerPreKeyBundle obj); -SignalFfiError *signal_backup_key_derive_media_id(uint8_t (*out)[SignalMEDIA_ID_LEN], const uint8_t (*backup_key)[SignalBACKUP_KEY_LEN], const char *media_name); +SignalFfiError *signal_pre_key_bundle_destroy(SignalMutPointerPreKeyBundle p); -SignalFfiError *signal_backup_key_derive_media_encryption_key(uint8_t (*out)[SignalMEDIA_ENCRYPTION_KEY_LEN], const uint8_t (*backup_key)[SignalBACKUP_KEY_LEN], const uint8_t (*media_id)[SignalMEDIA_ID_LEN]); +SignalFfiError *signal_pre_key_bundle_get_device_id(uint32_t *out, SignalConstPointerPreKeyBundle obj); -SignalFfiError *signal_backup_key_derive_thumbnail_transit_encryption_key(uint8_t (*out)[SignalMEDIA_ENCRYPTION_KEY_LEN], const uint8_t (*backup_key)[SignalBACKUP_KEY_LEN], const uint8_t (*media_id)[SignalMEDIA_ID_LEN]); +SignalFfiError *signal_pre_key_bundle_get_identity_key(SignalMutPointerPublicKey *out, SignalConstPointerPreKeyBundle p); -SignalFfiError *signal_svr2_client_new(SignalMutPointerSgxClientState *out, SignalBorrowedBuffer mrenclave, SignalBorrowedBuffer attestation_msg, uint64_t current_timestamp); +SignalFfiError *signal_pre_key_bundle_get_kyber_pre_key_id(uint32_t *out, SignalConstPointerPreKeyBundle obj); -SignalFfiError *signal_incremental_mac_destroy(SignalMutPointerIncrementalMac p); +SignalFfiError *signal_pre_key_bundle_get_kyber_pre_key_public(SignalMutPointerKyberPublicKey *out, SignalConstPointerPreKeyBundle bundle); -SignalFfiError *signal_incremental_mac_calculate_chunk_size(uint32_t *out, uint32_t data_size); +SignalFfiError *signal_pre_key_bundle_get_kyber_pre_key_signature(SignalOwnedBuffer *out, SignalConstPointerPreKeyBundle bundle); -SignalFfiError *signal_incremental_mac_initialize(SignalMutPointerIncrementalMac *out, SignalBorrowedBuffer key, uint32_t chunk_size); +SignalFfiError *signal_pre_key_bundle_get_pre_key_id(uint32_t *out, SignalConstPointerPreKeyBundle obj); -SignalFfiError *signal_incremental_mac_update(SignalOwnedBuffer *out, SignalMutPointerIncrementalMac mac, SignalBorrowedBuffer bytes, uint32_t offset, uint32_t length); +SignalFfiError *signal_pre_key_bundle_get_pre_key_public(SignalMutPointerPublicKey *out, SignalConstPointerPreKeyBundle obj); -SignalFfiError *signal_incremental_mac_finalize(SignalOwnedBuffer *out, SignalMutPointerIncrementalMac mac); +SignalFfiError *signal_pre_key_bundle_get_registration_id(uint32_t *out, SignalConstPointerPreKeyBundle obj); -SignalFfiError *signal_validating_mac_destroy(SignalMutPointerValidatingMac p); +SignalFfiError *signal_pre_key_bundle_get_signed_pre_key_id(uint32_t *out, SignalConstPointerPreKeyBundle obj); -SignalFfiError *signal_validating_mac_initialize(SignalMutPointerValidatingMac *out, SignalBorrowedBuffer key, uint32_t chunk_size, SignalBorrowedBuffer digests); +SignalFfiError *signal_pre_key_bundle_get_signed_pre_key_public(SignalMutPointerPublicKey *out, SignalConstPointerPreKeyBundle obj); -SignalFfiError *signal_validating_mac_update(int32_t *out, SignalMutPointerValidatingMac mac, SignalBorrowedBuffer bytes, uint32_t offset, uint32_t length); +SignalFfiError *signal_pre_key_bundle_get_signed_pre_key_signature(SignalOwnedBuffer *out, SignalConstPointerPreKeyBundle obj); -SignalFfiError *signal_validating_mac_finalize(int32_t *out, SignalMutPointerValidatingMac mac); +SignalFfiError *signal_pre_key_bundle_new(SignalMutPointerPreKeyBundle *out, uint32_t registration_id, uint32_t device_id, uint32_t prekey_id, SignalConstPointerPublicKey prekey, uint32_t signed_prekey_id, SignalConstPointerPublicKey signed_prekey, SignalBorrowedBuffer signed_prekey_signature, SignalConstPointerPublicKey identity_key, uint32_t kyber_prekey_id, SignalConstPointerKyberPublicKey kyber_prekey, SignalBorrowedBuffer kyber_prekey_signature); -SignalFfiError *signal_message_backup_key_destroy(SignalMutPointerMessageBackupKey p); +SignalFfiError *signal_pre_key_record_clone(SignalMutPointerPreKeyRecord *new_obj, SignalConstPointerPreKeyRecord obj); -SignalFfiError *signal_message_backup_validation_outcome_destroy(SignalMutPointerMessageBackupValidationOutcome p); +SignalFfiError *signal_pre_key_record_deserialize(SignalMutPointerPreKeyRecord *out, SignalBorrowedBuffer data); -SignalFfiError *signal_message_backup_key_from_master_key(SignalMutPointerMessageBackupKey *out, const uint8_t (*master_key)[32], const SignalServiceIdFixedWidthBinaryBytes *aci); +SignalFfiError *signal_pre_key_record_destroy(SignalMutPointerPreKeyRecord p); -SignalFfiError *signal_message_backup_key_from_account_entropy_pool(SignalMutPointerMessageBackupKey *out, const char *account_entropy, const SignalServiceIdFixedWidthBinaryBytes *aci); +SignalFfiError *signal_pre_key_record_get_id(uint32_t *out, SignalConstPointerPreKeyRecord obj); -SignalFfiError *signal_message_backup_key_from_backup_key_and_backup_id(SignalMutPointerMessageBackupKey *out, const uint8_t (*backup_key)[32], const uint8_t (*backup_id)[16]); +SignalFfiError *signal_pre_key_record_get_private_key(SignalMutPointerPrivateKey *out, SignalConstPointerPreKeyRecord obj); -SignalFfiError *signal_message_backup_key_get_hmac_key(uint8_t (*out)[32], SignalConstPointerMessageBackupKey key); +SignalFfiError *signal_pre_key_record_get_public_key(SignalMutPointerPublicKey *out, SignalConstPointerPreKeyRecord obj); -SignalFfiError *signal_message_backup_key_get_aes_key(uint8_t (*out)[32], SignalConstPointerMessageBackupKey key); +SignalFfiError *signal_pre_key_record_new(SignalMutPointerPreKeyRecord *out, uint32_t id, SignalConstPointerPublicKey pub_key, SignalConstPointerPrivateKey priv_key); -SignalFfiError *signal_message_backup_validation_outcome_get_error_message(const char **out, SignalConstPointerMessageBackupValidationOutcome outcome); +SignalFfiError *signal_pre_key_record_serialize(SignalOwnedBuffer *out, SignalConstPointerPreKeyRecord obj); -SignalFfiError *signal_message_backup_validation_outcome_get_unknown_fields(SignalStringArray *out, SignalConstPointerMessageBackupValidationOutcome outcome); +SignalFfiError *signal_pre_key_signal_message_clone(SignalMutPointerPreKeySignalMessage *new_obj, SignalConstPointerPreKeySignalMessage obj); -SignalFfiError *signal_message_backup_validator_validate(SignalMutPointerMessageBackupValidationOutcome *out, SignalConstPointerMessageBackupKey key, SignalConstPointerFfiInputStreamStruct first_stream, SignalConstPointerFfiInputStreamStruct second_stream, uint64_t len, uint8_t purpose); +SignalFfiError *signal_pre_key_signal_message_deserialize(SignalMutPointerPreKeySignalMessage *out, SignalBorrowedBuffer data); -SignalFfiError *signal_online_backup_validator_destroy(SignalMutPointerOnlineBackupValidator p); +SignalFfiError *signal_pre_key_signal_message_destroy(SignalMutPointerPreKeySignalMessage p); -SignalFfiError *signal_online_backup_validator_new(SignalMutPointerOnlineBackupValidator *out, SignalBorrowedBuffer backup_info_frame, uint8_t purpose); +SignalFfiError *signal_pre_key_signal_message_get_base_key(SignalMutPointerPublicKey *out, SignalConstPointerPreKeySignalMessage m); -SignalFfiError *signal_online_backup_validator_add_frame(SignalMutPointerOnlineBackupValidator backup, SignalBorrowedBuffer frame); +SignalFfiError *signal_pre_key_signal_message_get_identity_key(SignalMutPointerPublicKey *out, SignalConstPointerPreKeySignalMessage m); -SignalFfiError *signal_online_backup_validator_finalize(SignalMutPointerOnlineBackupValidator backup); +SignalFfiError *signal_pre_key_signal_message_get_pre_key_id(uint32_t *out, SignalConstPointerPreKeySignalMessage obj); -SignalFfiError *signal_username_hash(uint8_t (*out)[32], const char *username); +SignalFfiError *signal_pre_key_signal_message_get_registration_id(uint32_t *out, SignalConstPointerPreKeySignalMessage obj); -SignalFfiError *signal_username_proof(SignalOwnedBuffer *out, const char *username, const uint8_t (*randomness)[32]); +SignalFfiError *signal_pre_key_signal_message_get_signal_message(SignalMutPointerSignalMessage *out, SignalConstPointerPreKeySignalMessage m); -SignalFfiError *signal_username_verify(SignalBorrowedBuffer proof, SignalBorrowedBuffer hash); +SignalFfiError *signal_pre_key_signal_message_get_signed_pre_key_id(uint32_t *out, SignalConstPointerPreKeySignalMessage obj); -SignalFfiError *signal_username_candidates_from(SignalStringArray *out, const char *nickname, uint32_t min_len, uint32_t max_len); +SignalFfiError *signal_pre_key_signal_message_get_version(uint32_t *out, SignalConstPointerPreKeySignalMessage obj); -SignalFfiError *signal_username_hash_from_parts(uint8_t (*out)[32], const char *nickname, const char *discriminator, uint32_t min_len, uint32_t max_len); +SignalFfiError *signal_pre_key_signal_message_new(SignalMutPointerPreKeySignalMessage *out, uint8_t message_version, uint32_t registration_id, uint32_t pre_key_id, uint32_t signed_pre_key_id, SignalConstPointerPublicKey base_key, SignalConstPointerPublicKey identity_key, SignalConstPointerSignalMessage signal_message); -SignalFfiError *signal_username_link_create(SignalOwnedBuffer *out, const char *username, SignalBorrowedBuffer entropy); +SignalFfiError *signal_pre_key_signal_message_serialize(SignalOwnedBuffer *out, SignalConstPointerPreKeySignalMessage obj); -SignalFfiError *signal_username_link_decrypt_username(const char **out, SignalBorrowedBuffer entropy, SignalBorrowedBuffer encrypted_username); +void signal_print_ptr(const void *p); -#if defined(SIGNAL_MEDIA_SUPPORTED) -SignalFfiError *signal_sanitized_metadata_destroy(SignalMutPointerSanitizedMetadata p); -#endif +SignalFfiError *signal_privatekey_agree(SignalOwnedBuffer *out, SignalConstPointerPrivateKey private_key, SignalConstPointerPublicKey public_key); + +SignalFfiError *signal_privatekey_clone(SignalMutPointerPrivateKey *new_obj, SignalConstPointerPrivateKey obj); + +SignalFfiError *signal_privatekey_deserialize(SignalMutPointerPrivateKey *out, SignalBorrowedBuffer data); + +SignalFfiError *signal_privatekey_destroy(SignalMutPointerPrivateKey p); + +SignalFfiError *signal_privatekey_generate(SignalMutPointerPrivateKey *out); + +SignalFfiError *signal_privatekey_get_public_key(SignalMutPointerPublicKey *out, SignalConstPointerPrivateKey k); + +SignalFfiError *signal_privatekey_serialize(SignalOwnedBuffer *out, SignalConstPointerPrivateKey obj); + +SignalFfiError *signal_privatekey_sign(SignalOwnedBuffer *out, SignalConstPointerPrivateKey key, SignalBorrowedBuffer message); + +SignalFfiError *signal_process_prekey_bundle(SignalConstPointerPreKeyBundle bundle, SignalConstPointerProtocolAddress protocol_address, SignalConstPointerFfiSessionStoreStruct session_store, SignalConstPointerFfiIdentityKeyStoreStruct identity_key_store, uint64_t now); + +SignalFfiError *signal_process_sender_key_distribution_message(SignalConstPointerProtocolAddress sender, SignalConstPointerSenderKeyDistributionMessage sender_key_distribution_message, SignalConstPointerFfiSenderKeyStoreStruct store); + +SignalFfiError *signal_profile_key_check_valid_contents(SignalBorrowedBuffer buffer); + +SignalFfiError *signal_profile_key_ciphertext_check_valid_contents(SignalBorrowedBuffer buffer); + +SignalFfiError *signal_profile_key_commitment_check_valid_contents(SignalBorrowedBuffer buffer); + +SignalFfiError *signal_profile_key_credential_presentation_check_valid_contents(SignalBorrowedBuffer presentation_bytes); + +SignalFfiError *signal_profile_key_credential_presentation_get_profile_key_ciphertext(unsigned char (*out)[SignalPROFILE_KEY_CIPHERTEXT_LEN], SignalBorrowedBuffer presentation_bytes); + +SignalFfiError *signal_profile_key_credential_presentation_get_uuid_ciphertext(unsigned char (*out)[SignalUUID_CIPHERTEXT_LEN], SignalBorrowedBuffer presentation_bytes); + +SignalFfiError *signal_profile_key_credential_request_check_valid_contents(SignalBorrowedBuffer buffer); + +SignalFfiError *signal_profile_key_credential_request_context_check_valid_contents(SignalBorrowedBuffer buffer); + +SignalFfiError *signal_profile_key_credential_request_context_get_request(unsigned char (*out)[SignalPROFILE_KEY_CREDENTIAL_REQUEST_LEN], const unsigned char (*context)[SignalPROFILE_KEY_CREDENTIAL_REQUEST_CONTEXT_LEN]); + +SignalFfiError *signal_profile_key_derive_access_key(uint8_t (*out)[SignalACCESS_KEY_LEN], const unsigned char (*profile_key)[SignalPROFILE_KEY_LEN]); + +SignalFfiError *signal_profile_key_get_commitment(unsigned char (*out)[SignalPROFILE_KEY_COMMITMENT_LEN], const unsigned char (*profile_key)[SignalPROFILE_KEY_LEN], const SignalServiceIdFixedWidthBinaryBytes *user_id); + +SignalFfiError *signal_profile_key_get_profile_key_version(uint8_t (*out)[SignalPROFILE_KEY_VERSION_ENCODED_LEN], const unsigned char (*profile_key)[SignalPROFILE_KEY_LEN], const SignalServiceIdFixedWidthBinaryBytes *user_id); + +SignalFfiError *signal_publickey_clone(SignalMutPointerPublicKey *new_obj, SignalConstPointerPublicKey obj); + +SignalFfiError *signal_publickey_compare(int32_t *out, SignalConstPointerPublicKey key1, SignalConstPointerPublicKey key2); + +SignalFfiError *signal_publickey_deserialize(SignalMutPointerPublicKey *out, SignalBorrowedBuffer data); + +SignalFfiError *signal_publickey_destroy(SignalMutPointerPublicKey p); + +SignalFfiError *signal_publickey_equals(bool *out, SignalConstPointerPublicKey lhs, SignalConstPointerPublicKey rhs); + +SignalFfiError *signal_publickey_get_public_key_bytes(SignalOwnedBuffer *out, SignalConstPointerPublicKey obj); + +SignalFfiError *signal_publickey_serialize(SignalOwnedBuffer *out, SignalConstPointerPublicKey obj); + +SignalFfiError *signal_publickey_verify(bool *out, SignalConstPointerPublicKey key, SignalBorrowedBuffer message, SignalBorrowedBuffer signature); + +SignalFfiError *signal_receipt_credential_check_valid_contents(SignalBorrowedBuffer buffer); + +SignalFfiError *signal_receipt_credential_get_receipt_expiration_time(uint64_t *out, const unsigned char (*receipt_credential)[SignalRECEIPT_CREDENTIAL_LEN]); + +SignalFfiError *signal_receipt_credential_get_receipt_level(uint64_t *out, const unsigned char (*receipt_credential)[SignalRECEIPT_CREDENTIAL_LEN]); + +SignalFfiError *signal_receipt_credential_presentation_check_valid_contents(SignalBorrowedBuffer buffer); + +SignalFfiError *signal_receipt_credential_presentation_get_receipt_expiration_time(uint64_t *out, const unsigned char (*presentation)[SignalRECEIPT_CREDENTIAL_PRESENTATION_LEN]); + +SignalFfiError *signal_receipt_credential_presentation_get_receipt_level(uint64_t *out, const unsigned char (*presentation)[SignalRECEIPT_CREDENTIAL_PRESENTATION_LEN]); + +SignalFfiError *signal_receipt_credential_presentation_get_receipt_serial(uint8_t (*out)[SignalRECEIPT_SERIAL_LEN], const unsigned char (*presentation)[SignalRECEIPT_CREDENTIAL_PRESENTATION_LEN]); + +SignalFfiError *signal_receipt_credential_request_check_valid_contents(SignalBorrowedBuffer buffer); + +SignalFfiError *signal_receipt_credential_request_context_check_valid_contents(SignalBorrowedBuffer buffer); + +SignalFfiError *signal_receipt_credential_request_context_get_request(unsigned char (*out)[SignalRECEIPT_CREDENTIAL_REQUEST_LEN], const unsigned char (*request_context)[SignalRECEIPT_CREDENTIAL_REQUEST_CONTEXT_LEN]); + +SignalFfiError *signal_receipt_credential_response_check_valid_contents(SignalBorrowedBuffer buffer); #if defined(SIGNAL_MEDIA_SUPPORTED) SignalFfiError *signal_sanitized_metadata_clone(SignalMutPointerSanitizedMetadata *new_obj, SignalConstPointerSanitizedMetadata obj); #endif #if defined(SIGNAL_MEDIA_SUPPORTED) -SignalFfiError *signal_signal_media_check_available(void); +SignalFfiError *signal_sanitized_metadata_destroy(SignalMutPointerSanitizedMetadata p); #endif #if defined(SIGNAL_MEDIA_SUPPORTED) -SignalFfiError *signal_mp4_sanitizer_sanitize(SignalMutPointerSanitizedMetadata *out, SignalConstPointerFfiInputStreamStruct input, uint64_t len); -#endif - -#if defined(SIGNAL_MEDIA_SUPPORTED) -SignalFfiError *signal_webp_sanitizer_sanitize(SignalConstPointerFfiSyncInputStreamStruct input); -#endif - -#if defined(SIGNAL_MEDIA_SUPPORTED) -SignalFfiError *signal_sanitized_metadata_get_metadata(SignalOwnedBuffer *out, SignalConstPointerSanitizedMetadata sanitized); +SignalFfiError *signal_sanitized_metadata_get_data_len(uint64_t *out, SignalConstPointerSanitizedMetadata sanitized); #endif #if defined(SIGNAL_MEDIA_SUPPORTED) @@ -2078,7 +1814,297 @@ SignalFfiError *signal_sanitized_metadata_get_data_offset(uint64_t *out, SignalC #endif #if defined(SIGNAL_MEDIA_SUPPORTED) -SignalFfiError *signal_sanitized_metadata_get_data_len(uint64_t *out, SignalConstPointerSanitizedMetadata sanitized); +SignalFfiError *signal_sanitized_metadata_get_metadata(SignalOwnedBuffer *out, SignalConstPointerSanitizedMetadata sanitized); +#endif + +SignalFfiError *signal_sealed_sender_multi_recipient_encrypt(SignalOwnedBuffer *out, SignalBorrowedSliceOfConstPointerProtocolAddress recipients, SignalBorrowedSliceOfConstPointerSessionRecord recipient_sessions, SignalBorrowedBuffer excluded_recipients, SignalConstPointerUnidentifiedSenderMessageContent content, SignalConstPointerFfiIdentityKeyStoreStruct identity_key_store); + +SignalFfiError *signal_sealed_sender_multi_recipient_message_for_single_recipient(SignalOwnedBuffer *out, SignalBorrowedBuffer encoded_multi_recipient_message); + +SignalFfiError *signal_sealed_session_cipher_decrypt(SignalOwnedBuffer *out, const char **sender_e164, const char **sender_uuid, uint32_t *sender_device_id, SignalBorrowedBuffer ctext, SignalConstPointerPublicKey trust_root, uint64_t timestamp, const char *local_e164, const char *local_uuid, unsigned int local_device_id, SignalConstPointerFfiSessionStoreStruct session_store, SignalConstPointerFfiIdentityKeyStoreStruct identity_store, SignalConstPointerFfiPreKeyStoreStruct prekey_store, SignalConstPointerFfiSignedPreKeyStoreStruct signed_prekey_store); + +SignalFfiError *signal_sealed_session_cipher_decrypt_to_usmc(SignalMutPointerUnidentifiedSenderMessageContent *out, SignalBorrowedBuffer ctext, SignalConstPointerFfiIdentityKeyStoreStruct identity_store); + +SignalFfiError *signal_sealed_session_cipher_encrypt(SignalOwnedBuffer *out, SignalConstPointerProtocolAddress destination, SignalConstPointerUnidentifiedSenderMessageContent content, SignalConstPointerFfiIdentityKeyStoreStruct identity_key_store); + +SignalFfiError *signal_sender_certificate_clone(SignalMutPointerSenderCertificate *new_obj, SignalConstPointerSenderCertificate obj); + +SignalFfiError *signal_sender_certificate_deserialize(SignalMutPointerSenderCertificate *out, SignalBorrowedBuffer data); + +SignalFfiError *signal_sender_certificate_destroy(SignalMutPointerSenderCertificate p); + +SignalFfiError *signal_sender_certificate_get_certificate(SignalOwnedBuffer *out, SignalConstPointerSenderCertificate obj); + +SignalFfiError *signal_sender_certificate_get_device_id(uint32_t *out, SignalConstPointerSenderCertificate obj); + +SignalFfiError *signal_sender_certificate_get_expiration(uint64_t *out, SignalConstPointerSenderCertificate obj); + +SignalFfiError *signal_sender_certificate_get_key(SignalMutPointerPublicKey *out, SignalConstPointerSenderCertificate obj); + +SignalFfiError *signal_sender_certificate_get_sender_e164(const char **out, SignalConstPointerSenderCertificate obj); + +SignalFfiError *signal_sender_certificate_get_sender_uuid(const char **out, SignalConstPointerSenderCertificate obj); + +SignalFfiError *signal_sender_certificate_get_serialized(SignalOwnedBuffer *out, SignalConstPointerSenderCertificate obj); + +SignalFfiError *signal_sender_certificate_get_server_certificate(SignalMutPointerServerCertificate *out, SignalConstPointerSenderCertificate cert); + +SignalFfiError *signal_sender_certificate_get_signature(SignalOwnedBuffer *out, SignalConstPointerSenderCertificate obj); + +SignalFfiError *signal_sender_certificate_new(SignalMutPointerSenderCertificate *out, const char *sender_uuid, const char *sender_e164, uint32_t sender_device_id, SignalConstPointerPublicKey sender_key, uint64_t expiration, SignalConstPointerServerCertificate signer_cert, SignalConstPointerPrivateKey signer_key); + +SignalFfiError *signal_sender_certificate_validate(bool *out, SignalConstPointerSenderCertificate cert, SignalConstPointerPublicKey key, uint64_t time); + +SignalFfiError *signal_sender_key_distribution_message_clone(SignalMutPointerSenderKeyDistributionMessage *new_obj, SignalConstPointerSenderKeyDistributionMessage obj); + +SignalFfiError *signal_sender_key_distribution_message_create(SignalMutPointerSenderKeyDistributionMessage *out, SignalConstPointerProtocolAddress sender, const uint8_t (*distribution_id)[16], SignalConstPointerFfiSenderKeyStoreStruct store); + +SignalFfiError *signal_sender_key_distribution_message_deserialize(SignalMutPointerSenderKeyDistributionMessage *out, SignalBorrowedBuffer data); + +SignalFfiError *signal_sender_key_distribution_message_destroy(SignalMutPointerSenderKeyDistributionMessage p); + +SignalFfiError *signal_sender_key_distribution_message_get_chain_id(uint32_t *out, SignalConstPointerSenderKeyDistributionMessage obj); + +SignalFfiError *signal_sender_key_distribution_message_get_chain_key(SignalOwnedBuffer *out, SignalConstPointerSenderKeyDistributionMessage obj); + +SignalFfiError *signal_sender_key_distribution_message_get_distribution_id(uint8_t (*out)[16], SignalConstPointerSenderKeyDistributionMessage obj); + +SignalFfiError *signal_sender_key_distribution_message_get_iteration(uint32_t *out, SignalConstPointerSenderKeyDistributionMessage obj); + +SignalFfiError *signal_sender_key_distribution_message_get_signature_key(SignalMutPointerPublicKey *out, SignalConstPointerSenderKeyDistributionMessage m); + +SignalFfiError *signal_sender_key_distribution_message_new(SignalMutPointerSenderKeyDistributionMessage *out, uint8_t message_version, const uint8_t (*distribution_id)[16], uint32_t chain_id, uint32_t iteration, SignalBorrowedBuffer chainkey, SignalConstPointerPublicKey pk); + +SignalFfiError *signal_sender_key_distribution_message_serialize(SignalOwnedBuffer *out, SignalConstPointerSenderKeyDistributionMessage obj); + +SignalFfiError *signal_sender_key_message_clone(SignalMutPointerSenderKeyMessage *new_obj, SignalConstPointerSenderKeyMessage obj); + +SignalFfiError *signal_sender_key_message_deserialize(SignalMutPointerSenderKeyMessage *out, SignalBorrowedBuffer data); + +SignalFfiError *signal_sender_key_message_destroy(SignalMutPointerSenderKeyMessage p); + +SignalFfiError *signal_sender_key_message_get_chain_id(uint32_t *out, SignalConstPointerSenderKeyMessage obj); + +SignalFfiError *signal_sender_key_message_get_cipher_text(SignalOwnedBuffer *out, SignalConstPointerSenderKeyMessage obj); + +SignalFfiError *signal_sender_key_message_get_distribution_id(uint8_t (*out)[16], SignalConstPointerSenderKeyMessage obj); + +SignalFfiError *signal_sender_key_message_get_iteration(uint32_t *out, SignalConstPointerSenderKeyMessage obj); + +SignalFfiError *signal_sender_key_message_new(SignalMutPointerSenderKeyMessage *out, uint8_t message_version, const uint8_t (*distribution_id)[16], uint32_t chain_id, uint32_t iteration, SignalBorrowedBuffer ciphertext, SignalConstPointerPrivateKey pk); + +SignalFfiError *signal_sender_key_message_serialize(SignalOwnedBuffer *out, SignalConstPointerSenderKeyMessage obj); + +SignalFfiError *signal_sender_key_message_verify_signature(bool *out, SignalConstPointerSenderKeyMessage skm, SignalConstPointerPublicKey pubkey); + +SignalFfiError *signal_sender_key_record_clone(SignalMutPointerSenderKeyRecord *new_obj, SignalConstPointerSenderKeyRecord obj); + +SignalFfiError *signal_sender_key_record_deserialize(SignalMutPointerSenderKeyRecord *out, SignalBorrowedBuffer data); + +SignalFfiError *signal_sender_key_record_destroy(SignalMutPointerSenderKeyRecord p); + +SignalFfiError *signal_sender_key_record_serialize(SignalOwnedBuffer *out, SignalConstPointerSenderKeyRecord obj); + +SignalFfiError *signal_server_certificate_clone(SignalMutPointerServerCertificate *new_obj, SignalConstPointerServerCertificate obj); + +SignalFfiError *signal_server_certificate_deserialize(SignalMutPointerServerCertificate *out, SignalBorrowedBuffer data); + +SignalFfiError *signal_server_certificate_destroy(SignalMutPointerServerCertificate p); + +SignalFfiError *signal_server_certificate_get_certificate(SignalOwnedBuffer *out, SignalConstPointerServerCertificate obj); + +SignalFfiError *signal_server_certificate_get_key(SignalMutPointerPublicKey *out, SignalConstPointerServerCertificate obj); + +SignalFfiError *signal_server_certificate_get_key_id(uint32_t *out, SignalConstPointerServerCertificate obj); + +SignalFfiError *signal_server_certificate_get_serialized(SignalOwnedBuffer *out, SignalConstPointerServerCertificate obj); + +SignalFfiError *signal_server_certificate_get_signature(SignalOwnedBuffer *out, SignalConstPointerServerCertificate obj); + +SignalFfiError *signal_server_certificate_new(SignalMutPointerServerCertificate *out, uint32_t key_id, SignalConstPointerPublicKey server_key, SignalConstPointerPrivateKey trust_root); + +SignalFfiError *signal_server_message_ack_destroy(SignalMutPointerServerMessageAck p); + +SignalFfiError *signal_server_message_ack_send(SignalConstPointerServerMessageAck ack); + +SignalFfiError *signal_server_public_params_create_auth_credential_with_pni_presentation_deterministic(SignalOwnedBuffer *out, SignalConstPointerServerPublicParams server_public_params, const uint8_t (*randomness)[SignalRANDOMNESS_LEN], const unsigned char (*group_secret_params)[SignalGROUP_SECRET_PARAMS_LEN], SignalBorrowedBuffer auth_credential_with_pni_bytes); + +SignalFfiError *signal_server_public_params_create_expiring_profile_key_credential_presentation_deterministic(SignalOwnedBuffer *out, SignalConstPointerServerPublicParams server_public_params, const uint8_t (*randomness)[SignalRANDOMNESS_LEN], const unsigned char (*group_secret_params)[SignalGROUP_SECRET_PARAMS_LEN], const unsigned char (*profile_key_credential)[SignalEXPIRING_PROFILE_KEY_CREDENTIAL_LEN]); + +SignalFfiError *signal_server_public_params_create_profile_key_credential_request_context_deterministic(unsigned char (*out)[SignalPROFILE_KEY_CREDENTIAL_REQUEST_CONTEXT_LEN], SignalConstPointerServerPublicParams server_public_params, const uint8_t (*randomness)[SignalRANDOMNESS_LEN], const SignalServiceIdFixedWidthBinaryBytes *user_id, const unsigned char (*profile_key)[SignalPROFILE_KEY_LEN]); + +SignalFfiError *signal_server_public_params_create_receipt_credential_presentation_deterministic(unsigned char (*out)[SignalRECEIPT_CREDENTIAL_PRESENTATION_LEN], SignalConstPointerServerPublicParams server_public_params, const uint8_t (*randomness)[SignalRANDOMNESS_LEN], const unsigned char (*receipt_credential)[SignalRECEIPT_CREDENTIAL_LEN]); + +SignalFfiError *signal_server_public_params_create_receipt_credential_request_context_deterministic(unsigned char (*out)[SignalRECEIPT_CREDENTIAL_REQUEST_CONTEXT_LEN], SignalConstPointerServerPublicParams server_public_params, const uint8_t (*randomness)[SignalRANDOMNESS_LEN], const uint8_t (*receipt_serial)[SignalRECEIPT_SERIAL_LEN]); + +SignalFfiError *signal_server_public_params_deserialize(SignalMutPointerServerPublicParams *out, SignalBorrowedBuffer buffer); + +SignalFfiError *signal_server_public_params_destroy(SignalMutPointerServerPublicParams p); + +SignalFfiError *signal_server_public_params_get_endorsement_public_key(SignalOwnedBuffer *out, SignalConstPointerServerPublicParams params); + +SignalFfiError *signal_server_public_params_receive_auth_credential_with_pni_as_service_id(SignalOwnedBuffer *out, SignalConstPointerServerPublicParams params, const SignalServiceIdFixedWidthBinaryBytes *aci, const SignalServiceIdFixedWidthBinaryBytes *pni, uint64_t redemption_time, SignalBorrowedBuffer auth_credential_with_pni_response_bytes); + +SignalFfiError *signal_server_public_params_receive_expiring_profile_key_credential(unsigned char (*out)[SignalEXPIRING_PROFILE_KEY_CREDENTIAL_LEN], SignalConstPointerServerPublicParams server_public_params, const unsigned char (*request_context)[SignalPROFILE_KEY_CREDENTIAL_REQUEST_CONTEXT_LEN], const unsigned char (*response)[SignalEXPIRING_PROFILE_KEY_CREDENTIAL_RESPONSE_LEN], uint64_t current_time_in_seconds); + +SignalFfiError *signal_server_public_params_receive_receipt_credential(unsigned char (*out)[SignalRECEIPT_CREDENTIAL_LEN], SignalConstPointerServerPublicParams server_public_params, const unsigned char (*request_context)[SignalRECEIPT_CREDENTIAL_REQUEST_CONTEXT_LEN], const unsigned char (*response)[SignalRECEIPT_CREDENTIAL_RESPONSE_LEN]); + +SignalFfiError *signal_server_public_params_serialize(SignalOwnedBuffer *out, SignalConstPointerServerPublicParams handle); + +SignalFfiError *signal_server_public_params_verify_signature(SignalConstPointerServerPublicParams server_public_params, SignalBorrowedBuffer message, const uint8_t (*notary_signature)[SignalSIGNATURE_LEN]); + +SignalFfiError *signal_server_secret_params_deserialize(SignalMutPointerServerSecretParams *out, SignalBorrowedBuffer buffer); + +SignalFfiError *signal_server_secret_params_destroy(SignalMutPointerServerSecretParams p); + +SignalFfiError *signal_server_secret_params_generate_deterministic(SignalMutPointerServerSecretParams *out, const uint8_t (*randomness)[SignalRANDOMNESS_LEN]); + +SignalFfiError *signal_server_secret_params_get_public_params(SignalMutPointerServerPublicParams *out, SignalConstPointerServerSecretParams params); + +SignalFfiError *signal_server_secret_params_issue_auth_credential_with_pni_zkc_deterministic(SignalOwnedBuffer *out, SignalConstPointerServerSecretParams server_secret_params, const uint8_t (*randomness)[SignalRANDOMNESS_LEN], const SignalServiceIdFixedWidthBinaryBytes *aci, const SignalServiceIdFixedWidthBinaryBytes *pni, uint64_t redemption_time); + +SignalFfiError *signal_server_secret_params_issue_expiring_profile_key_credential_deterministic(unsigned char (*out)[SignalEXPIRING_PROFILE_KEY_CREDENTIAL_RESPONSE_LEN], SignalConstPointerServerSecretParams server_secret_params, const uint8_t (*randomness)[SignalRANDOMNESS_LEN], const unsigned char (*request)[SignalPROFILE_KEY_CREDENTIAL_REQUEST_LEN], const SignalServiceIdFixedWidthBinaryBytes *user_id, const unsigned char (*commitment)[SignalPROFILE_KEY_COMMITMENT_LEN], uint64_t expiration_in_seconds); + +SignalFfiError *signal_server_secret_params_issue_receipt_credential_deterministic(unsigned char (*out)[SignalRECEIPT_CREDENTIAL_RESPONSE_LEN], SignalConstPointerServerSecretParams server_secret_params, const uint8_t (*randomness)[SignalRANDOMNESS_LEN], const unsigned char (*request)[SignalRECEIPT_CREDENTIAL_REQUEST_LEN], uint64_t receipt_expiration_time, uint64_t receipt_level); + +SignalFfiError *signal_server_secret_params_serialize(SignalOwnedBuffer *out, SignalConstPointerServerSecretParams handle); + +SignalFfiError *signal_server_secret_params_sign_deterministic(uint8_t (*out)[SignalSIGNATURE_LEN], SignalConstPointerServerSecretParams params, const uint8_t (*randomness)[SignalRANDOMNESS_LEN], SignalBorrowedBuffer message); + +SignalFfiError *signal_server_secret_params_verify_auth_credential_presentation(SignalConstPointerServerSecretParams server_secret_params, const unsigned char (*group_public_params)[SignalGROUP_PUBLIC_PARAMS_LEN], SignalBorrowedBuffer presentation_bytes, uint64_t current_time_in_seconds); + +SignalFfiError *signal_server_secret_params_verify_profile_key_credential_presentation(SignalConstPointerServerSecretParams server_secret_params, const unsigned char (*group_public_params)[SignalGROUP_PUBLIC_PARAMS_LEN], SignalBorrowedBuffer presentation_bytes, uint64_t current_time_in_seconds); + +SignalFfiError *signal_server_secret_params_verify_receipt_credential_presentation(SignalConstPointerServerSecretParams server_secret_params, const unsigned char (*presentation)[SignalRECEIPT_CREDENTIAL_PRESENTATION_LEN]); + +SignalFfiError *signal_service_id_parse_from_service_id_binary(SignalServiceIdFixedWidthBinaryBytes *out, SignalBorrowedBuffer input); + +SignalFfiError *signal_service_id_parse_from_service_id_string(SignalServiceIdFixedWidthBinaryBytes *out, const char *input); + +SignalFfiError *signal_service_id_service_id_binary(SignalOwnedBuffer *out, const SignalServiceIdFixedWidthBinaryBytes *value); + +SignalFfiError *signal_service_id_service_id_log(const char **out, const SignalServiceIdFixedWidthBinaryBytes *value); + +SignalFfiError *signal_service_id_service_id_string(const char **out, const SignalServiceIdFixedWidthBinaryBytes *value); + +SignalFfiError *signal_session_record_archive_current_state(SignalMutPointerSessionRecord session_record); + +SignalFfiError *signal_session_record_clone(SignalMutPointerSessionRecord *new_obj, SignalConstPointerSessionRecord obj); + +SignalFfiError *signal_session_record_current_ratchet_key_matches(bool *out, SignalConstPointerSessionRecord s, SignalConstPointerPublicKey key); + +SignalFfiError *signal_session_record_deserialize(SignalMutPointerSessionRecord *out, SignalBorrowedBuffer data); + +SignalFfiError *signal_session_record_destroy(SignalMutPointerSessionRecord p); + +SignalFfiError *signal_session_record_get_local_registration_id(uint32_t *out, SignalConstPointerSessionRecord obj); + +SignalFfiError *signal_session_record_get_remote_registration_id(uint32_t *out, SignalConstPointerSessionRecord obj); + +SignalFfiError *signal_session_record_has_usable_sender_chain(bool *out, SignalConstPointerSessionRecord s, uint64_t now); + +SignalFfiError *signal_session_record_serialize(SignalOwnedBuffer *out, SignalConstPointerSessionRecord obj); + +SignalFfiError *signal_sgx_client_state_complete_handshake(SignalMutPointerSgxClientState cli, SignalBorrowedBuffer handshake_received); + +SignalFfiError *signal_sgx_client_state_destroy(SignalMutPointerSgxClientState p); + +SignalFfiError *signal_sgx_client_state_established_recv(SignalOwnedBuffer *out, SignalMutPointerSgxClientState cli, SignalBorrowedBuffer received_ciphertext); + +SignalFfiError *signal_sgx_client_state_established_send(SignalOwnedBuffer *out, SignalMutPointerSgxClientState cli, SignalBorrowedBuffer plaintext_to_send); + +SignalFfiError *signal_sgx_client_state_initial_request(SignalOwnedBuffer *out, SignalConstPointerSgxClientState obj); + +#if defined(SIGNAL_MEDIA_SUPPORTED) +SignalFfiError *signal_signal_media_check_available(void); +#endif + +SignalFfiError *signal_signed_pre_key_record_clone(SignalMutPointerSignedPreKeyRecord *new_obj, SignalConstPointerSignedPreKeyRecord obj); + +SignalFfiError *signal_signed_pre_key_record_deserialize(SignalMutPointerSignedPreKeyRecord *out, SignalBorrowedBuffer data); + +SignalFfiError *signal_signed_pre_key_record_destroy(SignalMutPointerSignedPreKeyRecord p); + +SignalFfiError *signal_signed_pre_key_record_get_id(uint32_t *out, SignalConstPointerSignedPreKeyRecord obj); + +SignalFfiError *signal_signed_pre_key_record_get_private_key(SignalMutPointerPrivateKey *out, SignalConstPointerSignedPreKeyRecord obj); + +SignalFfiError *signal_signed_pre_key_record_get_public_key(SignalMutPointerPublicKey *out, SignalConstPointerSignedPreKeyRecord obj); + +SignalFfiError *signal_signed_pre_key_record_get_signature(SignalOwnedBuffer *out, SignalConstPointerSignedPreKeyRecord obj); + +SignalFfiError *signal_signed_pre_key_record_get_timestamp(uint64_t *out, SignalConstPointerSignedPreKeyRecord obj); + +SignalFfiError *signal_signed_pre_key_record_new(SignalMutPointerSignedPreKeyRecord *out, uint32_t id, uint64_t timestamp, SignalConstPointerPublicKey pub_key, SignalConstPointerPrivateKey priv_key, SignalBorrowedBuffer signature); + +SignalFfiError *signal_signed_pre_key_record_serialize(SignalOwnedBuffer *out, SignalConstPointerSignedPreKeyRecord obj); + +SignalFfiError *signal_svr2_client_new(SignalMutPointerSgxClientState *out, SignalBorrowedBuffer mrenclave, SignalBorrowedBuffer attestation_msg, uint64_t current_timestamp); + +SignalFfiError *signal_tokio_async_context_cancel(SignalConstPointerTokioAsyncContext context, uint64_t raw_cancellation_id); + +SignalFfiError *signal_tokio_async_context_destroy(SignalMutPointerTokioAsyncContext p); + +SignalFfiError *signal_tokio_async_context_new(SignalMutPointerTokioAsyncContext *out); + +SignalFfiError *signal_unauthenticated_chat_connection_connect(SignalCPromiseMutPointerUnauthenticatedChatConnection *promise, SignalConstPointerTokioAsyncContext async_runtime, SignalConstPointerConnectionManager connection_manager); + +SignalFfiError *signal_unauthenticated_chat_connection_destroy(SignalMutPointerUnauthenticatedChatConnection p); + +SignalFfiError *signal_unauthenticated_chat_connection_disconnect(SignalCPromisebool *promise, SignalConstPointerTokioAsyncContext async_runtime, SignalConstPointerUnauthenticatedChatConnection chat); + +SignalFfiError *signal_unauthenticated_chat_connection_info(SignalMutPointerChatConnectionInfo *out, SignalConstPointerUnauthenticatedChatConnection chat); + +SignalFfiError *signal_unauthenticated_chat_connection_init_listener(SignalConstPointerUnauthenticatedChatConnection chat, SignalConstPointerFfiChatListenerStruct listener); + +SignalFfiError *signal_unauthenticated_chat_connection_send(SignalCPromiseFfiChatResponse *promise, SignalConstPointerTokioAsyncContext async_runtime, SignalConstPointerUnauthenticatedChatConnection chat, SignalConstPointerHttpRequest http_request, uint32_t timeout_millis); + +SignalFfiError *signal_unidentified_sender_message_content_deserialize(SignalMutPointerUnidentifiedSenderMessageContent *out, SignalBorrowedBuffer data); + +SignalFfiError *signal_unidentified_sender_message_content_destroy(SignalMutPointerUnidentifiedSenderMessageContent p); + +SignalFfiError *signal_unidentified_sender_message_content_get_content_hint(uint32_t *out, SignalConstPointerUnidentifiedSenderMessageContent m); + +SignalFfiError *signal_unidentified_sender_message_content_get_contents(SignalOwnedBuffer *out, SignalConstPointerUnidentifiedSenderMessageContent obj); + +SignalFfiError *signal_unidentified_sender_message_content_get_group_id_or_empty(SignalOwnedBuffer *out, SignalConstPointerUnidentifiedSenderMessageContent m); + +SignalFfiError *signal_unidentified_sender_message_content_get_msg_type(uint8_t *out, SignalConstPointerUnidentifiedSenderMessageContent m); + +SignalFfiError *signal_unidentified_sender_message_content_get_sender_cert(SignalMutPointerSenderCertificate *out, SignalConstPointerUnidentifiedSenderMessageContent m); + +SignalFfiError *signal_unidentified_sender_message_content_new(SignalMutPointerUnidentifiedSenderMessageContent *out, SignalConstPointerCiphertextMessage message, SignalConstPointerSenderCertificate sender, uint32_t content_hint, SignalBorrowedBuffer group_id); + +SignalFfiError *signal_unidentified_sender_message_content_new_from_content_and_type(SignalMutPointerUnidentifiedSenderMessageContent *out, SignalBorrowedBuffer message_content, uint8_t message_type, SignalConstPointerSenderCertificate sender, uint32_t content_hint, SignalBorrowedBuffer group_id); + +SignalFfiError *signal_unidentified_sender_message_content_serialize(SignalOwnedBuffer *out, SignalConstPointerUnidentifiedSenderMessageContent obj); + +SignalFfiError *signal_username_candidates_from(SignalStringArray *out, const char *nickname, uint32_t min_len, uint32_t max_len); + +SignalFfiError *signal_username_hash(uint8_t (*out)[32], const char *username); + +SignalFfiError *signal_username_hash_from_parts(uint8_t (*out)[32], const char *nickname, const char *discriminator, uint32_t min_len, uint32_t max_len); + +SignalFfiError *signal_username_link_create(SignalOwnedBuffer *out, const char *username, SignalBorrowedBuffer entropy); + +SignalFfiError *signal_username_link_decrypt_username(const char **out, SignalBorrowedBuffer entropy, SignalBorrowedBuffer encrypted_username); + +SignalFfiError *signal_username_proof(SignalOwnedBuffer *out, const char *username, const uint8_t (*randomness)[32]); + +SignalFfiError *signal_username_verify(SignalBorrowedBuffer proof, SignalBorrowedBuffer hash); + +SignalFfiError *signal_uuid_ciphertext_check_valid_contents(SignalBorrowedBuffer buffer); + +SignalFfiError *signal_validating_mac_destroy(SignalMutPointerValidatingMac p); + +SignalFfiError *signal_validating_mac_finalize(int32_t *out, SignalMutPointerValidatingMac mac); + +SignalFfiError *signal_validating_mac_initialize(SignalMutPointerValidatingMac *out, SignalBorrowedBuffer key, uint32_t chunk_size, SignalBorrowedBuffer digests); + +SignalFfiError *signal_validating_mac_update(int32_t *out, SignalMutPointerValidatingMac mac, SignalBorrowedBuffer bytes, uint32_t offset, uint32_t length); + +#if defined(SIGNAL_MEDIA_SUPPORTED) +SignalFfiError *signal_webp_sanitizer_sanitize(SignalConstPointerFfiSyncInputStreamStruct input); #endif #endif /* SIGNAL_FFI_H_ */ diff --git a/pkg/libsignalgo/version.go b/pkg/libsignalgo/version.go index 30d8666..631a0a2 100644 --- a/pkg/libsignalgo/version.go +++ b/pkg/libsignalgo/version.go @@ -2,4 +2,4 @@ package libsignalgo -const Version = "v0.67.4" +const Version = "v0.70.0" From e9dbb9640157abb9c5a0eb243a9ff0f339ed5259 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Tue, 15 Apr 2025 15:22:31 +0300 Subject: [PATCH 317/580] signalmeow: update protobufs --- pkg/msgconv/from-signal-backup.go | 20 +- pkg/msgconv/from-signal.go | 4 +- pkg/signalmeow/contact.go | 9 +- pkg/signalmeow/protobuf/SignalService.pb.go | 3696 +++++++++-------- pkg/signalmeow/protobuf/SignalService.pb.raw | Bin 19370 -> 19700 bytes pkg/signalmeow/protobuf/SignalService.proto | 1093 ++--- pkg/signalmeow/protobuf/StorageService.pb.go | 635 ++- pkg/signalmeow/protobuf/StorageService.pb.raw | Bin 6238 -> 7611 bytes pkg/signalmeow/protobuf/StorageService.proto | 66 +- pkg/signalmeow/protobuf/backuppb/Backup.pb.go | 939 +++-- .../protobuf/backuppb/Backup.pb.raw | Bin 31259 -> 31810 bytes pkg/signalmeow/protobuf/backuppb/Backup.proto | 35 +- pkg/signalmeow/protobuf/update-protos.sh | 4 +- pkg/signalmeow/receiving.go | 8 +- pkg/signalmeow/sending.go | 22 +- 15 files changed, 3652 insertions(+), 2879 deletions(-) diff --git a/pkg/msgconv/from-signal-backup.go b/pkg/msgconv/from-signal-backup.go index ccb4e50..d5532cd 100644 --- a/pkg/msgconv/from-signal-backup.go +++ b/pkg/msgconv/from-signal-backup.go @@ -189,16 +189,16 @@ func backupToSignalAttachment( atts map[uuid.UUID]*backuppb.FilePointer_BackupLocator, ) *signalpb.AttachmentPointer { sig := &signalpb.AttachmentPointer{ - ContentType: fp.ContentType, - IncrementalMac: fp.IncrementalMac, - IncrementalMacChunkSize: fp.IncrementalMacChunkSize, - FileName: fp.FileName, - Flags: ptr.NonZero(uint32(backupToSignalAttachmentFlag(flag))), - Width: fp.Width, - Height: fp.Height, - Caption: nil, // is this field deprecated or something? - BlurHash: fp.BlurHash, - Uuid: clientUUID[:], + //IncrementalMacChunkSize: fp.IncrementalMacChunkSize, + ContentType: fp.ContentType, + IncrementalMac: fp.IncrementalMac, + FileName: fp.FileName, + Flags: ptr.NonZero(uint32(backupToSignalAttachmentFlag(flag))), + Width: fp.Width, + Height: fp.Height, + Caption: nil, // is this field deprecated or something? + BlurHash: fp.BlurHash, + ClientUuid: clientUUID[:], } switch loc := fp.Locator.(type) { case *backuppb.FilePointer_AttachmentLocator_: diff --git a/pkg/msgconv/from-signal.go b/pkg/msgconv/from-signal.go index 7ee29b7..fb80394 100644 --- a/pkg/msgconv/from-signal.go +++ b/pkg/msgconv/from-signal.go @@ -465,10 +465,10 @@ func (mc *MessageConverter) downloadSignalLongText(ctx context.Context, att *sig func (mc *MessageConverter) downloadAttachment(ctx context.Context, att *signalpb.AttachmentPointer, attMap AttachmentMap) ([]byte, error) { if att.AttachmentIdentifier == nil { - if len(att.GetUuid()) != 16 { + if len(att.GetClientUuid()) != 16 { return nil, fmt.Errorf("no attachment identifier found") } - target, ok := attMap[uuid.UUID(att.GetUuid())] + target, ok := attMap[uuid.UUID(att.GetClientUuid())] if !ok { return nil, fmt.Errorf("no attachment identifier and attachment not found in map") } else if target == nil { diff --git a/pkg/signalmeow/contact.go b/pkg/signalmeow/contact.go index fdea194..9e7eec2 100644 --- a/pkg/signalmeow/contact.go +++ b/pkg/signalmeow/contact.go @@ -30,7 +30,6 @@ import ( "github.com/rs/zerolog" "google.golang.org/protobuf/proto" - "go.mau.fi/mautrix-signal/pkg/libsignalgo" signalpb "go.mau.fi/mautrix-signal/pkg/signalmeow/protobuf" "go.mau.fi/mautrix-signal/pkg/signalmeow/types" ) @@ -49,10 +48,10 @@ func (cli *Client) StoreContactDetailsAsContact(ctx context.Context, contactDeta recipient.E164 = contactDetails.GetNumber() } recipient.ContactName = contactDetails.GetName() - if profileKeyString := contactDetails.GetProfileKey(); profileKeyString != nil { - profileKey := libsignalgo.ProfileKey(profileKeyString) - recipient.Profile.Key = profileKey - } + //if profileKeyString := contactDetails.GetProfileKey(); profileKeyString != nil { + // profileKey := libsignalgo.ProfileKey(profileKeyString) + // recipient.Profile.Key = profileKey + //} if avatar != nil && *avatar != nil && len(*avatar) > 0 { rawHash := sha256.Sum256(*avatar) avatarHash := hex.EncodeToString(rawHash[:]) diff --git a/pkg/signalmeow/protobuf/SignalService.pb.go b/pkg/signalmeow/protobuf/SignalService.pb.go index aed9592..2e8d5b0 100644 --- a/pkg/signalmeow/protobuf/SignalService.pb.go +++ b/pkg/signalmeow/protobuf/SignalService.pb.go @@ -1,7 +1,6 @@ -//* -// Copyright (C) 2014-2016 Open Whisper Systems // -// Licensed according to the LICENSE file in this repository. +// Copyright 2020-2022 Signal Messenger, LLC +// SPDX-License-Identifier: AGPL-3.0-only // Code generated by protoc-gen-go. DO NOT EDIT. // versions: @@ -30,13 +29,13 @@ const ( type Envelope_Type int32 const ( - Envelope_UNKNOWN Envelope_Type = 0 - Envelope_CIPHERTEXT Envelope_Type = 1 - Envelope_KEY_EXCHANGE Envelope_Type = 2 - Envelope_PREKEY_BUNDLE Envelope_Type = 3 - Envelope_RECEIPT Envelope_Type = 5 - Envelope_UNIDENTIFIED_SENDER Envelope_Type = 6 - Envelope_PLAINTEXT_CONTENT Envelope_Type = 8 + Envelope_UNKNOWN Envelope_Type = 0 + Envelope_CIPHERTEXT Envelope_Type = 1 // content => (version byte | SignalMessage{Content}) + Envelope_PREKEY_BUNDLE Envelope_Type = 3 // content => (version byte | PreKeySignalMessage{Content}) + Envelope_SERVER_DELIVERY_RECEIPT Envelope_Type = 5 // legacyMessage => [] AND content => [] + Envelope_UNIDENTIFIED_SENDER Envelope_Type = 6 // legacyMessage => [] AND content => ((version byte | UnidentifiedSenderMessage) OR (version byte | Multi-Recipient Sealed Sender Format)) + Envelope_SENDERKEY_MESSAGE Envelope_Type = 7 // legacyMessage => [] AND content => (version byte | SenderKeyMessage) + Envelope_PLAINTEXT_CONTENT Envelope_Type = 8 // legacyMessage => [] AND content => (marker byte | Content) ) // Enum value maps for Envelope_Type. @@ -44,20 +43,20 @@ var ( Envelope_Type_name = map[int32]string{ 0: "UNKNOWN", 1: "CIPHERTEXT", - 2: "KEY_EXCHANGE", 3: "PREKEY_BUNDLE", - 5: "RECEIPT", + 5: "SERVER_DELIVERY_RECEIPT", 6: "UNIDENTIFIED_SENDER", + 7: "SENDERKEY_MESSAGE", 8: "PLAINTEXT_CONTENT", } Envelope_Type_value = map[string]int32{ - "UNKNOWN": 0, - "CIPHERTEXT": 1, - "KEY_EXCHANGE": 2, - "PREKEY_BUNDLE": 3, - "RECEIPT": 5, - "UNIDENTIFIED_SENDER": 6, - "PLAINTEXT_CONTENT": 8, + "UNKNOWN": 0, + "CIPHERTEXT": 1, + "PREKEY_BUNDLE": 3, + "SERVER_DELIVERY_RECEIPT": 5, + "UNIDENTIFIED_SENDER": 6, + "SENDERKEY_MESSAGE": 7, + "PLAINTEXT_CONTENT": 8, } ) @@ -275,80 +274,13 @@ func (CallMessage_Opaque_Urgency) EnumDescriptor() ([]byte, []int) { return file_SignalService_proto_rawDescGZIP(), []int{2, 5, 0} } -type BodyRange_Style int32 - -const ( - BodyRange_NONE BodyRange_Style = 0 - BodyRange_BOLD BodyRange_Style = 1 - BodyRange_ITALIC BodyRange_Style = 2 - BodyRange_SPOILER BodyRange_Style = 3 - BodyRange_STRIKETHROUGH BodyRange_Style = 4 - BodyRange_MONOSPACE BodyRange_Style = 5 -) - -// Enum value maps for BodyRange_Style. -var ( - BodyRange_Style_name = map[int32]string{ - 0: "NONE", - 1: "BOLD", - 2: "ITALIC", - 3: "SPOILER", - 4: "STRIKETHROUGH", - 5: "MONOSPACE", - } - BodyRange_Style_value = map[string]int32{ - "NONE": 0, - "BOLD": 1, - "ITALIC": 2, - "SPOILER": 3, - "STRIKETHROUGH": 4, - "MONOSPACE": 5, - } -) - -func (x BodyRange_Style) Enum() *BodyRange_Style { - p := new(BodyRange_Style) - *p = x - return p -} - -func (x BodyRange_Style) String() string { - return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) -} - -func (BodyRange_Style) Descriptor() protoreflect.EnumDescriptor { - return file_SignalService_proto_enumTypes[4].Descriptor() -} - -func (BodyRange_Style) Type() protoreflect.EnumType { - return &file_SignalService_proto_enumTypes[4] -} - -func (x BodyRange_Style) Number() protoreflect.EnumNumber { - return protoreflect.EnumNumber(x) -} - -// Deprecated: Do not use. -func (x *BodyRange_Style) UnmarshalJSON(b []byte) error { - num, err := protoimpl.X.UnmarshalJSONEnum(x.Descriptor(), b) - if err != nil { - return err - } - *x = BodyRange_Style(num) - return nil -} - -// Deprecated: Use BodyRange_Style.Descriptor instead. -func (BodyRange_Style) EnumDescriptor() ([]byte, []int) { - return file_SignalService_proto_rawDescGZIP(), []int{3, 0} -} - type DataMessage_Flags int32 const ( DataMessage_END_SESSION DataMessage_Flags = 1 DataMessage_EXPIRATION_TIMER_UPDATE DataMessage_Flags = 2 DataMessage_PROFILE_KEY_UPDATE DataMessage_Flags = 4 + DataMessage_FORWARD DataMessage_Flags = 8 ) // Enum value maps for DataMessage_Flags. @@ -357,11 +289,13 @@ var ( 1: "END_SESSION", 2: "EXPIRATION_TIMER_UPDATE", 4: "PROFILE_KEY_UPDATE", + 8: "FORWARD", } DataMessage_Flags_value = map[string]int32{ "END_SESSION": 1, "EXPIRATION_TIMER_UPDATE": 2, "PROFILE_KEY_UPDATE": 4, + "FORWARD": 8, } ) @@ -376,11 +310,11 @@ func (x DataMessage_Flags) String() string { } func (DataMessage_Flags) Descriptor() protoreflect.EnumDescriptor { - return file_SignalService_proto_enumTypes[5].Descriptor() + return file_SignalService_proto_enumTypes[4].Descriptor() } func (DataMessage_Flags) Type() protoreflect.EnumType { - return &file_SignalService_proto_enumTypes[5] + return &file_SignalService_proto_enumTypes[4] } func (x DataMessage_Flags) Number() protoreflect.EnumNumber { @@ -399,7 +333,7 @@ func (x *DataMessage_Flags) UnmarshalJSON(b []byte) error { // Deprecated: Use DataMessage_Flags.Descriptor instead. func (DataMessage_Flags) EnumDescriptor() ([]byte, []int) { - return file_SignalService_proto_rawDescGZIP(), []int{4, 0} + return file_SignalService_proto_rawDescGZIP(), []int{3, 0} } type DataMessage_ProtocolVersion int32 @@ -453,11 +387,11 @@ func (x DataMessage_ProtocolVersion) String() string { } func (DataMessage_ProtocolVersion) Descriptor() protoreflect.EnumDescriptor { - return file_SignalService_proto_enumTypes[6].Descriptor() + return file_SignalService_proto_enumTypes[5].Descriptor() } func (DataMessage_ProtocolVersion) Type() protoreflect.EnumType { - return &file_SignalService_proto_enumTypes[6] + return &file_SignalService_proto_enumTypes[5] } func (x DataMessage_ProtocolVersion) Number() protoreflect.EnumNumber { @@ -476,7 +410,63 @@ func (x *DataMessage_ProtocolVersion) UnmarshalJSON(b []byte) error { // Deprecated: Use DataMessage_ProtocolVersion.Descriptor instead. func (DataMessage_ProtocolVersion) EnumDescriptor() ([]byte, []int) { - return file_SignalService_proto_rawDescGZIP(), []int{4, 1} + return file_SignalService_proto_rawDescGZIP(), []int{3, 1} +} + +type DataMessage_Payment_Activation_Type int32 + +const ( + DataMessage_Payment_Activation_REQUEST DataMessage_Payment_Activation_Type = 0 + DataMessage_Payment_Activation_ACTIVATED DataMessage_Payment_Activation_Type = 1 +) + +// Enum value maps for DataMessage_Payment_Activation_Type. +var ( + DataMessage_Payment_Activation_Type_name = map[int32]string{ + 0: "REQUEST", + 1: "ACTIVATED", + } + DataMessage_Payment_Activation_Type_value = map[string]int32{ + "REQUEST": 0, + "ACTIVATED": 1, + } +) + +func (x DataMessage_Payment_Activation_Type) Enum() *DataMessage_Payment_Activation_Type { + p := new(DataMessage_Payment_Activation_Type) + *p = x + return p +} + +func (x DataMessage_Payment_Activation_Type) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (DataMessage_Payment_Activation_Type) Descriptor() protoreflect.EnumDescriptor { + return file_SignalService_proto_enumTypes[6].Descriptor() +} + +func (DataMessage_Payment_Activation_Type) Type() protoreflect.EnumType { + return &file_SignalService_proto_enumTypes[6] +} + +func (x DataMessage_Payment_Activation_Type) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Do not use. +func (x *DataMessage_Payment_Activation_Type) UnmarshalJSON(b []byte) error { + num, err := protoimpl.X.UnmarshalJSONEnum(x.Descriptor(), b) + if err != nil { + return err + } + *x = DataMessage_Payment_Activation_Type(num) + return nil +} + +// Deprecated: Use DataMessage_Payment_Activation_Type.Descriptor instead. +func (DataMessage_Payment_Activation_Type) EnumDescriptor() ([]byte, []int) { + return file_SignalService_proto_rawDescGZIP(), []int{3, 0, 2, 0} } type DataMessage_Quote_Type int32 @@ -532,7 +522,7 @@ func (x *DataMessage_Quote_Type) UnmarshalJSON(b []byte) error { // Deprecated: Use DataMessage_Quote_Type.Descriptor instead. func (DataMessage_Quote_Type) EnumDescriptor() ([]byte, []int) { - return file_SignalService_proto_rawDescGZIP(), []int{4, 0, 0} + return file_SignalService_proto_rawDescGZIP(), []int{3, 1, 0} } type DataMessage_Contact_Phone_Type int32 @@ -594,7 +584,7 @@ func (x *DataMessage_Contact_Phone_Type) UnmarshalJSON(b []byte) error { // Deprecated: Use DataMessage_Contact_Phone_Type.Descriptor instead. func (DataMessage_Contact_Phone_Type) EnumDescriptor() ([]byte, []int) { - return file_SignalService_proto_rawDescGZIP(), []int{4, 1, 1, 0} + return file_SignalService_proto_rawDescGZIP(), []int{3, 2, 1, 0} } type DataMessage_Contact_Email_Type int32 @@ -656,7 +646,7 @@ func (x *DataMessage_Contact_Email_Type) UnmarshalJSON(b []byte) error { // Deprecated: Use DataMessage_Contact_Email_Type.Descriptor instead. func (DataMessage_Contact_Email_Type) EnumDescriptor() ([]byte, []int) { - return file_SignalService_proto_rawDescGZIP(), []int{4, 1, 2, 0} + return file_SignalService_proto_rawDescGZIP(), []int{3, 2, 2, 0} } type DataMessage_Contact_PostalAddress_Type int32 @@ -715,63 +705,7 @@ func (x *DataMessage_Contact_PostalAddress_Type) UnmarshalJSON(b []byte) error { // Deprecated: Use DataMessage_Contact_PostalAddress_Type.Descriptor instead. func (DataMessage_Contact_PostalAddress_Type) EnumDescriptor() ([]byte, []int) { - return file_SignalService_proto_rawDescGZIP(), []int{4, 1, 3, 0} -} - -type DataMessage_Payment_Activation_Type int32 - -const ( - DataMessage_Payment_Activation_REQUEST DataMessage_Payment_Activation_Type = 0 - DataMessage_Payment_Activation_ACTIVATED DataMessage_Payment_Activation_Type = 1 -) - -// Enum value maps for DataMessage_Payment_Activation_Type. -var ( - DataMessage_Payment_Activation_Type_name = map[int32]string{ - 0: "REQUEST", - 1: "ACTIVATED", - } - DataMessage_Payment_Activation_Type_value = map[string]int32{ - "REQUEST": 0, - "ACTIVATED": 1, - } -) - -func (x DataMessage_Payment_Activation_Type) Enum() *DataMessage_Payment_Activation_Type { - p := new(DataMessage_Payment_Activation_Type) - *p = x - return p -} - -func (x DataMessage_Payment_Activation_Type) String() string { - return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) -} - -func (DataMessage_Payment_Activation_Type) Descriptor() protoreflect.EnumDescriptor { - return file_SignalService_proto_enumTypes[11].Descriptor() -} - -func (DataMessage_Payment_Activation_Type) Type() protoreflect.EnumType { - return &file_SignalService_proto_enumTypes[11] -} - -func (x DataMessage_Payment_Activation_Type) Number() protoreflect.EnumNumber { - return protoreflect.EnumNumber(x) -} - -// Deprecated: Do not use. -func (x *DataMessage_Payment_Activation_Type) UnmarshalJSON(b []byte) error { - num, err := protoimpl.X.UnmarshalJSONEnum(x.Descriptor(), b) - if err != nil { - return err - } - *x = DataMessage_Payment_Activation_Type(num) - return nil -} - -// Deprecated: Use DataMessage_Payment_Activation_Type.Descriptor instead. -func (DataMessage_Payment_Activation_Type) EnumDescriptor() ([]byte, []int) { - return file_SignalService_proto_rawDescGZIP(), []int{4, 7, 2, 0} + return file_SignalService_proto_rawDescGZIP(), []int{3, 2, 3, 0} } type ReceiptMessage_Type int32 @@ -807,11 +741,11 @@ func (x ReceiptMessage_Type) String() string { } func (ReceiptMessage_Type) Descriptor() protoreflect.EnumDescriptor { - return file_SignalService_proto_enumTypes[12].Descriptor() + return file_SignalService_proto_enumTypes[11].Descriptor() } func (ReceiptMessage_Type) Type() protoreflect.EnumType { - return &file_SignalService_proto_enumTypes[12] + return &file_SignalService_proto_enumTypes[11] } func (x ReceiptMessage_Type) Number() protoreflect.EnumNumber { @@ -830,7 +764,7 @@ func (x *ReceiptMessage_Type) UnmarshalJSON(b []byte) error { // Deprecated: Use ReceiptMessage_Type.Descriptor instead. func (ReceiptMessage_Type) EnumDescriptor() ([]byte, []int) { - return file_SignalService_proto_rawDescGZIP(), []int{6, 0} + return file_SignalService_proto_rawDescGZIP(), []int{5, 0} } type TypingMessage_Action int32 @@ -863,11 +797,11 @@ func (x TypingMessage_Action) String() string { } func (TypingMessage_Action) Descriptor() protoreflect.EnumDescriptor { - return file_SignalService_proto_enumTypes[13].Descriptor() + return file_SignalService_proto_enumTypes[12].Descriptor() } func (TypingMessage_Action) Type() protoreflect.EnumType { - return &file_SignalService_proto_enumTypes[13] + return &file_SignalService_proto_enumTypes[12] } func (x TypingMessage_Action) Number() protoreflect.EnumNumber { @@ -886,7 +820,7 @@ func (x *TypingMessage_Action) UnmarshalJSON(b []byte) error { // Deprecated: Use TypingMessage_Action.Descriptor instead. func (TypingMessage_Action) EnumDescriptor() ([]byte, []int) { - return file_SignalService_proto_rawDescGZIP(), []int{7, 0} + return file_SignalService_proto_rawDescGZIP(), []int{6, 0} } type TextAttachment_Style int32 @@ -931,11 +865,11 @@ func (x TextAttachment_Style) String() string { } func (TextAttachment_Style) Descriptor() protoreflect.EnumDescriptor { - return file_SignalService_proto_enumTypes[14].Descriptor() + return file_SignalService_proto_enumTypes[13].Descriptor() } func (TextAttachment_Style) Type() protoreflect.EnumType { - return &file_SignalService_proto_enumTypes[14] + return &file_SignalService_proto_enumTypes[13] } func (x TextAttachment_Style) Number() protoreflect.EnumNumber { @@ -954,7 +888,7 @@ func (x *TextAttachment_Style) UnmarshalJSON(b []byte) error { // Deprecated: Use TextAttachment_Style.Descriptor instead. func (TextAttachment_Style) EnumDescriptor() ([]byte, []int) { - return file_SignalService_proto_rawDescGZIP(), []int{10, 0} + return file_SignalService_proto_rawDescGZIP(), []int{9, 0} } type Verified_State int32 @@ -990,11 +924,11 @@ func (x Verified_State) String() string { } func (Verified_State) Descriptor() protoreflect.EnumDescriptor { - return file_SignalService_proto_enumTypes[15].Descriptor() + return file_SignalService_proto_enumTypes[14].Descriptor() } func (Verified_State) Type() protoreflect.EnumType { - return &file_SignalService_proto_enumTypes[15] + return &file_SignalService_proto_enumTypes[14] } func (x Verified_State) Number() protoreflect.EnumNumber { @@ -1013,19 +947,17 @@ func (x *Verified_State) UnmarshalJSON(b []byte) error { // Deprecated: Use Verified_State.Descriptor instead. func (Verified_State) EnumDescriptor() ([]byte, []int) { - return file_SignalService_proto_rawDescGZIP(), []int{11, 0} + return file_SignalService_proto_rawDescGZIP(), []int{10, 0} } type SyncMessage_Request_Type int32 const ( - SyncMessage_Request_UNKNOWN SyncMessage_Request_Type = 0 - SyncMessage_Request_CONTACTS SyncMessage_Request_Type = 1 - // GROUPS = 2; + SyncMessage_Request_UNKNOWN SyncMessage_Request_Type = 0 + SyncMessage_Request_CONTACTS SyncMessage_Request_Type = 1 SyncMessage_Request_BLOCKED SyncMessage_Request_Type = 3 SyncMessage_Request_CONFIGURATION SyncMessage_Request_Type = 4 SyncMessage_Request_KEYS SyncMessage_Request_Type = 5 - SyncMessage_Request_PNI_IDENTITY SyncMessage_Request_Type = 6 ) // Enum value maps for SyncMessage_Request_Type. @@ -1036,7 +968,6 @@ var ( 3: "BLOCKED", 4: "CONFIGURATION", 5: "KEYS", - 6: "PNI_IDENTITY", } SyncMessage_Request_Type_value = map[string]int32{ "UNKNOWN": 0, @@ -1044,7 +975,6 @@ var ( "BLOCKED": 3, "CONFIGURATION": 4, "KEYS": 5, - "PNI_IDENTITY": 6, } ) @@ -1059,11 +989,11 @@ func (x SyncMessage_Request_Type) String() string { } func (SyncMessage_Request_Type) Descriptor() protoreflect.EnumDescriptor { - return file_SignalService_proto_enumTypes[16].Descriptor() + return file_SignalService_proto_enumTypes[15].Descriptor() } func (SyncMessage_Request_Type) Type() protoreflect.EnumType { - return &file_SignalService_proto_enumTypes[16] + return &file_SignalService_proto_enumTypes[15] } func (x SyncMessage_Request_Type) Number() protoreflect.EnumNumber { @@ -1082,7 +1012,7 @@ func (x *SyncMessage_Request_Type) UnmarshalJSON(b []byte) error { // Deprecated: Use SyncMessage_Request_Type.Descriptor instead. func (SyncMessage_Request_Type) EnumDescriptor() ([]byte, []int) { - return file_SignalService_proto_rawDescGZIP(), []int{12, 3, 0} + return file_SignalService_proto_rawDescGZIP(), []int{11, 3, 0} } type SyncMessage_StickerPackOperation_Type int32 @@ -1115,11 +1045,11 @@ func (x SyncMessage_StickerPackOperation_Type) String() string { } func (SyncMessage_StickerPackOperation_Type) Descriptor() protoreflect.EnumDescriptor { - return file_SignalService_proto_enumTypes[17].Descriptor() + return file_SignalService_proto_enumTypes[16].Descriptor() } func (SyncMessage_StickerPackOperation_Type) Type() protoreflect.EnumType { - return &file_SignalService_proto_enumTypes[17] + return &file_SignalService_proto_enumTypes[16] } func (x SyncMessage_StickerPackOperation_Type) Number() protoreflect.EnumNumber { @@ -1138,7 +1068,7 @@ func (x *SyncMessage_StickerPackOperation_Type) UnmarshalJSON(b []byte) error { // Deprecated: Use SyncMessage_StickerPackOperation_Type.Descriptor instead. func (SyncMessage_StickerPackOperation_Type) EnumDescriptor() ([]byte, []int) { - return file_SignalService_proto_rawDescGZIP(), []int{12, 7, 0} + return file_SignalService_proto_rawDescGZIP(), []int{11, 7, 0} } type SyncMessage_FetchLatest_Type int32 @@ -1177,11 +1107,11 @@ func (x SyncMessage_FetchLatest_Type) String() string { } func (SyncMessage_FetchLatest_Type) Descriptor() protoreflect.EnumDescriptor { - return file_SignalService_proto_enumTypes[18].Descriptor() + return file_SignalService_proto_enumTypes[17].Descriptor() } func (SyncMessage_FetchLatest_Type) Type() protoreflect.EnumType { - return &file_SignalService_proto_enumTypes[18] + return &file_SignalService_proto_enumTypes[17] } func (x SyncMessage_FetchLatest_Type) Number() protoreflect.EnumNumber { @@ -1200,7 +1130,7 @@ func (x *SyncMessage_FetchLatest_Type) UnmarshalJSON(b []byte) error { // Deprecated: Use SyncMessage_FetchLatest_Type.Descriptor instead. func (SyncMessage_FetchLatest_Type) EnumDescriptor() ([]byte, []int) { - return file_SignalService_proto_rawDescGZIP(), []int{12, 9, 0} + return file_SignalService_proto_rawDescGZIP(), []int{11, 9, 0} } type SyncMessage_MessageRequestResponse_Type int32 @@ -1248,11 +1178,11 @@ func (x SyncMessage_MessageRequestResponse_Type) String() string { } func (SyncMessage_MessageRequestResponse_Type) Descriptor() protoreflect.EnumDescriptor { - return file_SignalService_proto_enumTypes[19].Descriptor() + return file_SignalService_proto_enumTypes[18].Descriptor() } func (SyncMessage_MessageRequestResponse_Type) Type() protoreflect.EnumType { - return &file_SignalService_proto_enumTypes[19] + return &file_SignalService_proto_enumTypes[18] } func (x SyncMessage_MessageRequestResponse_Type) Number() protoreflect.EnumNumber { @@ -1271,7 +1201,7 @@ func (x *SyncMessage_MessageRequestResponse_Type) UnmarshalJSON(b []byte) error // Deprecated: Use SyncMessage_MessageRequestResponse_Type.Descriptor instead. func (SyncMessage_MessageRequestResponse_Type) EnumDescriptor() ([]byte, []int) { - return file_SignalService_proto_rawDescGZIP(), []int{12, 11, 0} + return file_SignalService_proto_rawDescGZIP(), []int{11, 12, 0} } type SyncMessage_CallEvent_Type int32 @@ -1313,11 +1243,11 @@ func (x SyncMessage_CallEvent_Type) String() string { } func (SyncMessage_CallEvent_Type) Descriptor() protoreflect.EnumDescriptor { - return file_SignalService_proto_enumTypes[20].Descriptor() + return file_SignalService_proto_enumTypes[19].Descriptor() } func (SyncMessage_CallEvent_Type) Type() protoreflect.EnumType { - return &file_SignalService_proto_enumTypes[20] + return &file_SignalService_proto_enumTypes[19] } func (x SyncMessage_CallEvent_Type) Number() protoreflect.EnumNumber { @@ -1336,7 +1266,7 @@ func (x *SyncMessage_CallEvent_Type) UnmarshalJSON(b []byte) error { // Deprecated: Use SyncMessage_CallEvent_Type.Descriptor instead. func (SyncMessage_CallEvent_Type) EnumDescriptor() ([]byte, []int) { - return file_SignalService_proto_rawDescGZIP(), []int{12, 14, 0} + return file_SignalService_proto_rawDescGZIP(), []int{11, 15, 0} } type SyncMessage_CallEvent_Direction int32 @@ -1372,11 +1302,11 @@ func (x SyncMessage_CallEvent_Direction) String() string { } func (SyncMessage_CallEvent_Direction) Descriptor() protoreflect.EnumDescriptor { - return file_SignalService_proto_enumTypes[21].Descriptor() + return file_SignalService_proto_enumTypes[20].Descriptor() } func (SyncMessage_CallEvent_Direction) Type() protoreflect.EnumType { - return &file_SignalService_proto_enumTypes[21] + return &file_SignalService_proto_enumTypes[20] } func (x SyncMessage_CallEvent_Direction) Number() protoreflect.EnumNumber { @@ -1395,34 +1325,34 @@ func (x *SyncMessage_CallEvent_Direction) UnmarshalJSON(b []byte) error { // Deprecated: Use SyncMessage_CallEvent_Direction.Descriptor instead. func (SyncMessage_CallEvent_Direction) EnumDescriptor() ([]byte, []int) { - return file_SignalService_proto_rawDescGZIP(), []int{12, 14, 1} + return file_SignalService_proto_rawDescGZIP(), []int{11, 15, 1} } type SyncMessage_CallEvent_Event int32 const ( - SyncMessage_CallEvent_UNKNOWN_ACTION SyncMessage_CallEvent_Event = 0 - SyncMessage_CallEvent_ACCEPTED SyncMessage_CallEvent_Event = 1 - SyncMessage_CallEvent_NOT_ACCEPTED SyncMessage_CallEvent_Event = 2 - SyncMessage_CallEvent_DELETE SyncMessage_CallEvent_Event = 3 - SyncMessage_CallEvent_OBSERVED SyncMessage_CallEvent_Event = 4 + SyncMessage_CallEvent_UNKNOWN_EVENT SyncMessage_CallEvent_Event = 0 + SyncMessage_CallEvent_ACCEPTED SyncMessage_CallEvent_Event = 1 + SyncMessage_CallEvent_NOT_ACCEPTED SyncMessage_CallEvent_Event = 2 + SyncMessage_CallEvent_DELETE SyncMessage_CallEvent_Event = 3 + SyncMessage_CallEvent_OBSERVED SyncMessage_CallEvent_Event = 4 ) // Enum value maps for SyncMessage_CallEvent_Event. var ( SyncMessage_CallEvent_Event_name = map[int32]string{ - 0: "UNKNOWN_ACTION", + 0: "UNKNOWN_EVENT", 1: "ACCEPTED", 2: "NOT_ACCEPTED", 3: "DELETE", 4: "OBSERVED", } SyncMessage_CallEvent_Event_value = map[string]int32{ - "UNKNOWN_ACTION": 0, - "ACCEPTED": 1, - "NOT_ACCEPTED": 2, - "DELETE": 3, - "OBSERVED": 4, + "UNKNOWN_EVENT": 0, + "ACCEPTED": 1, + "NOT_ACCEPTED": 2, + "DELETE": 3, + "OBSERVED": 4, } ) @@ -1437,11 +1367,11 @@ func (x SyncMessage_CallEvent_Event) String() string { } func (SyncMessage_CallEvent_Event) Descriptor() protoreflect.EnumDescriptor { - return file_SignalService_proto_enumTypes[22].Descriptor() + return file_SignalService_proto_enumTypes[21].Descriptor() } func (SyncMessage_CallEvent_Event) Type() protoreflect.EnumType { - return &file_SignalService_proto_enumTypes[22] + return &file_SignalService_proto_enumTypes[21] } func (x SyncMessage_CallEvent_Event) Number() protoreflect.EnumNumber { @@ -1460,7 +1390,7 @@ func (x *SyncMessage_CallEvent_Event) UnmarshalJSON(b []byte) error { // Deprecated: Use SyncMessage_CallEvent_Event.Descriptor instead. func (SyncMessage_CallEvent_Event) EnumDescriptor() ([]byte, []int) { - return file_SignalService_proto_rawDescGZIP(), []int{12, 14, 2} + return file_SignalService_proto_rawDescGZIP(), []int{11, 15, 2} } type SyncMessage_CallLinkUpdate_Type int32 @@ -1490,11 +1420,11 @@ func (x SyncMessage_CallLinkUpdate_Type) String() string { } func (SyncMessage_CallLinkUpdate_Type) Descriptor() protoreflect.EnumDescriptor { - return file_SignalService_proto_enumTypes[23].Descriptor() + return file_SignalService_proto_enumTypes[22].Descriptor() } func (SyncMessage_CallLinkUpdate_Type) Type() protoreflect.EnumType { - return &file_SignalService_proto_enumTypes[23] + return &file_SignalService_proto_enumTypes[22] } func (x SyncMessage_CallLinkUpdate_Type) Number() protoreflect.EnumNumber { @@ -1513,7 +1443,7 @@ func (x *SyncMessage_CallLinkUpdate_Type) UnmarshalJSON(b []byte) error { // Deprecated: Use SyncMessage_CallLinkUpdate_Type.Descriptor instead. func (SyncMessage_CallLinkUpdate_Type) EnumDescriptor() ([]byte, []int) { - return file_SignalService_proto_rawDescGZIP(), []int{12, 15, 0} + return file_SignalService_proto_rawDescGZIP(), []int{11, 16, 0} } type SyncMessage_CallLogEvent_Type int32 @@ -1522,6 +1452,7 @@ const ( SyncMessage_CallLogEvent_CLEAR SyncMessage_CallLogEvent_Type = 0 SyncMessage_CallLogEvent_MARKED_AS_READ SyncMessage_CallLogEvent_Type = 1 SyncMessage_CallLogEvent_MARKED_AS_READ_IN_CONVERSATION SyncMessage_CallLogEvent_Type = 2 + SyncMessage_CallLogEvent_CLEAR_IN_CONVERSATION SyncMessage_CallLogEvent_Type = 3 ) // Enum value maps for SyncMessage_CallLogEvent_Type. @@ -1530,11 +1461,13 @@ var ( 0: "CLEAR", 1: "MARKED_AS_READ", 2: "MARKED_AS_READ_IN_CONVERSATION", + 3: "CLEAR_IN_CONVERSATION", } SyncMessage_CallLogEvent_Type_value = map[string]int32{ "CLEAR": 0, "MARKED_AS_READ": 1, "MARKED_AS_READ_IN_CONVERSATION": 2, + "CLEAR_IN_CONVERSATION": 3, } ) @@ -1549,11 +1482,11 @@ func (x SyncMessage_CallLogEvent_Type) String() string { } func (SyncMessage_CallLogEvent_Type) Descriptor() protoreflect.EnumDescriptor { - return file_SignalService_proto_enumTypes[24].Descriptor() + return file_SignalService_proto_enumTypes[23].Descriptor() } func (SyncMessage_CallLogEvent_Type) Type() protoreflect.EnumType { - return &file_SignalService_proto_enumTypes[24] + return &file_SignalService_proto_enumTypes[23] } func (x SyncMessage_CallLogEvent_Type) Number() protoreflect.EnumNumber { @@ -1572,7 +1505,116 @@ func (x *SyncMessage_CallLogEvent_Type) UnmarshalJSON(b []byte) error { // Deprecated: Use SyncMessage_CallLogEvent_Type.Descriptor instead. func (SyncMessage_CallLogEvent_Type) EnumDescriptor() ([]byte, []int) { - return file_SignalService_proto_rawDescGZIP(), []int{12, 16, 0} + return file_SignalService_proto_rawDescGZIP(), []int{11, 17, 0} +} + +type SyncMessage_AttachmentBackfillResponse_Error int32 + +const ( + SyncMessage_AttachmentBackfillResponse_MESSAGE_NOT_FOUND SyncMessage_AttachmentBackfillResponse_Error = 0 +) + +// Enum value maps for SyncMessage_AttachmentBackfillResponse_Error. +var ( + SyncMessage_AttachmentBackfillResponse_Error_name = map[int32]string{ + 0: "MESSAGE_NOT_FOUND", + } + SyncMessage_AttachmentBackfillResponse_Error_value = map[string]int32{ + "MESSAGE_NOT_FOUND": 0, + } +) + +func (x SyncMessage_AttachmentBackfillResponse_Error) Enum() *SyncMessage_AttachmentBackfillResponse_Error { + p := new(SyncMessage_AttachmentBackfillResponse_Error) + *p = x + return p +} + +func (x SyncMessage_AttachmentBackfillResponse_Error) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (SyncMessage_AttachmentBackfillResponse_Error) Descriptor() protoreflect.EnumDescriptor { + return file_SignalService_proto_enumTypes[24].Descriptor() +} + +func (SyncMessage_AttachmentBackfillResponse_Error) Type() protoreflect.EnumType { + return &file_SignalService_proto_enumTypes[24] +} + +func (x SyncMessage_AttachmentBackfillResponse_Error) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Do not use. +func (x *SyncMessage_AttachmentBackfillResponse_Error) UnmarshalJSON(b []byte) error { + num, err := protoimpl.X.UnmarshalJSONEnum(x.Descriptor(), b) + if err != nil { + return err + } + *x = SyncMessage_AttachmentBackfillResponse_Error(num) + return nil +} + +// Deprecated: Use SyncMessage_AttachmentBackfillResponse_Error.Descriptor instead. +func (SyncMessage_AttachmentBackfillResponse_Error) EnumDescriptor() ([]byte, []int) { + return file_SignalService_proto_rawDescGZIP(), []int{11, 21, 0} +} + +type SyncMessage_AttachmentBackfillResponse_AttachmentData_Status int32 + +const ( + SyncMessage_AttachmentBackfillResponse_AttachmentData_PENDING SyncMessage_AttachmentBackfillResponse_AttachmentData_Status = 0 + SyncMessage_AttachmentBackfillResponse_AttachmentData_TERMINAL_ERROR SyncMessage_AttachmentBackfillResponse_AttachmentData_Status = 1 +) + +// Enum value maps for SyncMessage_AttachmentBackfillResponse_AttachmentData_Status. +var ( + SyncMessage_AttachmentBackfillResponse_AttachmentData_Status_name = map[int32]string{ + 0: "PENDING", + 1: "TERMINAL_ERROR", + } + SyncMessage_AttachmentBackfillResponse_AttachmentData_Status_value = map[string]int32{ + "PENDING": 0, + "TERMINAL_ERROR": 1, + } +) + +func (x SyncMessage_AttachmentBackfillResponse_AttachmentData_Status) Enum() *SyncMessage_AttachmentBackfillResponse_AttachmentData_Status { + p := new(SyncMessage_AttachmentBackfillResponse_AttachmentData_Status) + *p = x + return p +} + +func (x SyncMessage_AttachmentBackfillResponse_AttachmentData_Status) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (SyncMessage_AttachmentBackfillResponse_AttachmentData_Status) Descriptor() protoreflect.EnumDescriptor { + return file_SignalService_proto_enumTypes[25].Descriptor() +} + +func (SyncMessage_AttachmentBackfillResponse_AttachmentData_Status) Type() protoreflect.EnumType { + return &file_SignalService_proto_enumTypes[25] +} + +func (x SyncMessage_AttachmentBackfillResponse_AttachmentData_Status) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Do not use. +func (x *SyncMessage_AttachmentBackfillResponse_AttachmentData_Status) UnmarshalJSON(b []byte) error { + num, err := protoimpl.X.UnmarshalJSONEnum(x.Descriptor(), b) + if err != nil { + return err + } + *x = SyncMessage_AttachmentBackfillResponse_AttachmentData_Status(num) + return nil +} + +// Deprecated: Use SyncMessage_AttachmentBackfillResponse_AttachmentData_Status.Descriptor instead. +func (SyncMessage_AttachmentBackfillResponse_AttachmentData_Status) EnumDescriptor() ([]byte, []int) { + return file_SignalService_proto_rawDescGZIP(), []int{11, 21, 0, 0} } type AttachmentPointer_Flags int32 @@ -1580,7 +1622,7 @@ type AttachmentPointer_Flags int32 const ( AttachmentPointer_VOICE_MESSAGE AttachmentPointer_Flags = 1 AttachmentPointer_BORDERLESS AttachmentPointer_Flags = 2 - AttachmentPointer_GIF AttachmentPointer_Flags = 4 + AttachmentPointer_GIF AttachmentPointer_Flags = 8 ) // Enum value maps for AttachmentPointer_Flags. @@ -1588,12 +1630,12 @@ var ( AttachmentPointer_Flags_name = map[int32]string{ 1: "VOICE_MESSAGE", 2: "BORDERLESS", - 4: "GIF", + 8: "GIF", } AttachmentPointer_Flags_value = map[string]int32{ "VOICE_MESSAGE": 1, "BORDERLESS": 2, - "GIF": 4, + "GIF": 8, } ) @@ -1608,11 +1650,11 @@ func (x AttachmentPointer_Flags) String() string { } func (AttachmentPointer_Flags) Descriptor() protoreflect.EnumDescriptor { - return file_SignalService_proto_enumTypes[25].Descriptor() + return file_SignalService_proto_enumTypes[26].Descriptor() } func (AttachmentPointer_Flags) Type() protoreflect.EnumType { - return &file_SignalService_proto_enumTypes[25] + return &file_SignalService_proto_enumTypes[26] } func (x AttachmentPointer_Flags) Number() protoreflect.EnumNumber { @@ -1631,72 +1673,75 @@ func (x *AttachmentPointer_Flags) UnmarshalJSON(b []byte) error { // Deprecated: Use AttachmentPointer_Flags.Descriptor instead. func (AttachmentPointer_Flags) EnumDescriptor() ([]byte, []int) { - return file_SignalService_proto_rawDescGZIP(), []int{13, 0} + return file_SignalService_proto_rawDescGZIP(), []int{12, 0} } -type GroupContext_Type int32 +type BodyRange_Style int32 const ( - GroupContext_UNKNOWN GroupContext_Type = 0 - GroupContext_UPDATE GroupContext_Type = 1 - GroupContext_DELIVER GroupContext_Type = 2 - GroupContext_QUIT GroupContext_Type = 3 - GroupContext_REQUEST_INFO GroupContext_Type = 4 + BodyRange_NONE BodyRange_Style = 0 + BodyRange_BOLD BodyRange_Style = 1 + BodyRange_ITALIC BodyRange_Style = 2 + BodyRange_SPOILER BodyRange_Style = 3 + BodyRange_STRIKETHROUGH BodyRange_Style = 4 + BodyRange_MONOSPACE BodyRange_Style = 5 ) -// Enum value maps for GroupContext_Type. +// Enum value maps for BodyRange_Style. var ( - GroupContext_Type_name = map[int32]string{ - 0: "UNKNOWN", - 1: "UPDATE", - 2: "DELIVER", - 3: "QUIT", - 4: "REQUEST_INFO", + BodyRange_Style_name = map[int32]string{ + 0: "NONE", + 1: "BOLD", + 2: "ITALIC", + 3: "SPOILER", + 4: "STRIKETHROUGH", + 5: "MONOSPACE", } - GroupContext_Type_value = map[string]int32{ - "UNKNOWN": 0, - "UPDATE": 1, - "DELIVER": 2, - "QUIT": 3, - "REQUEST_INFO": 4, + BodyRange_Style_value = map[string]int32{ + "NONE": 0, + "BOLD": 1, + "ITALIC": 2, + "SPOILER": 3, + "STRIKETHROUGH": 4, + "MONOSPACE": 5, } ) -func (x GroupContext_Type) Enum() *GroupContext_Type { - p := new(GroupContext_Type) +func (x BodyRange_Style) Enum() *BodyRange_Style { + p := new(BodyRange_Style) *p = x return p } -func (x GroupContext_Type) String() string { +func (x BodyRange_Style) String() string { return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) } -func (GroupContext_Type) Descriptor() protoreflect.EnumDescriptor { - return file_SignalService_proto_enumTypes[26].Descriptor() +func (BodyRange_Style) Descriptor() protoreflect.EnumDescriptor { + return file_SignalService_proto_enumTypes[27].Descriptor() } -func (GroupContext_Type) Type() protoreflect.EnumType { - return &file_SignalService_proto_enumTypes[26] +func (BodyRange_Style) Type() protoreflect.EnumType { + return &file_SignalService_proto_enumTypes[27] } -func (x GroupContext_Type) Number() protoreflect.EnumNumber { +func (x BodyRange_Style) Number() protoreflect.EnumNumber { return protoreflect.EnumNumber(x) } // Deprecated: Do not use. -func (x *GroupContext_Type) UnmarshalJSON(b []byte) error { +func (x *BodyRange_Style) UnmarshalJSON(b []byte) error { num, err := protoimpl.X.UnmarshalJSONEnum(x.Descriptor(), b) if err != nil { return err } - *x = GroupContext_Type(num) + *x = BodyRange_Style(num) return nil } -// Deprecated: Use GroupContext_Type.Descriptor instead. -func (GroupContext_Type) EnumDescriptor() ([]byte, []int) { - return file_SignalService_proto_rawDescGZIP(), []int{14, 0} +// Deprecated: Use BodyRange_Style.Descriptor instead. +func (BodyRange_Style) EnumDescriptor() ([]byte, []int) { + return file_SignalService_proto_rawDescGZIP(), []int{19, 0} } type Envelope struct { @@ -1709,9 +1754,11 @@ type Envelope struct { Content []byte `protobuf:"bytes,8,opt,name=content" json:"content,omitempty"` // Contains an encrypted Content ServerGuid *string `protobuf:"bytes,9,opt,name=serverGuid" json:"serverGuid,omitempty"` ServerTimestamp *uint64 `protobuf:"varint,10,opt,name=serverTimestamp" json:"serverTimestamp,omitempty"` - Urgent *bool `protobuf:"varint,14,opt,name=urgent,def=1" json:"urgent,omitempty"` - Story *bool `protobuf:"varint,16,opt,name=story" json:"story,omitempty"` - ReportingToken []byte `protobuf:"bytes,17,opt,name=reportingToken" json:"reportingToken,omitempty"` + Ephemeral *bool `protobuf:"varint,12,opt,name=ephemeral" json:"ephemeral,omitempty"` // indicates that the message should not be persisted if the recipient is offline + Urgent *bool `protobuf:"varint,14,opt,name=urgent,def=1" json:"urgent,omitempty"` // indicates that the content is considered timely by the sender; defaults to true so senders have to opt-out to say something isn't time critical + UpdatedPni *string `protobuf:"bytes,15,opt,name=updatedPni" json:"updatedPni,omitempty"` // for number-change synchronization messages, provides the new server-assigned phone number identifier associated with the changed number + Story *bool `protobuf:"varint,16,opt,name=story" json:"story,omitempty"` // indicates that the content is a story. + ReportSpamToken []byte `protobuf:"bytes,17,opt,name=report_spam_token,json=reportSpamToken" json:"report_spam_token,omitempty"` // token sent when reporting spam unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } @@ -1807,6 +1854,13 @@ func (x *Envelope) GetServerTimestamp() uint64 { return 0 } +func (x *Envelope) GetEphemeral() bool { + if x != nil && x.Ephemeral != nil { + return *x.Ephemeral + } + return false +} + func (x *Envelope) GetUrgent() bool { if x != nil && x.Urgent != nil { return *x.Urgent @@ -1814,6 +1868,13 @@ func (x *Envelope) GetUrgent() bool { return Default_Envelope_Urgent } +func (x *Envelope) GetUpdatedPni() string { + if x != nil && x.UpdatedPni != nil { + return *x.UpdatedPni + } + return "" +} + func (x *Envelope) GetStory() bool { if x != nil && x.Story != nil { return *x.Story @@ -1821,9 +1882,9 @@ func (x *Envelope) GetStory() bool { return false } -func (x *Envelope) GetReportingToken() []byte { +func (x *Envelope) GetReportSpamToken() []byte { if x != nil { - return x.ReportingToken + return x.ReportSpamToken } return nil } @@ -2044,104 +2105,6 @@ func (x *CallMessage) GetOpaque() *CallMessage_Opaque { return nil } -type BodyRange struct { - state protoimpl.MessageState `protogen:"open.v1"` - Start *uint32 `protobuf:"varint,1,opt,name=start" json:"start,omitempty"` - Length *uint32 `protobuf:"varint,2,opt,name=length" json:"length,omitempty"` - // Types that are valid to be assigned to AssociatedValue: - // - // *BodyRange_MentionAci - // *BodyRange_Style_ - AssociatedValue isBodyRange_AssociatedValue `protobuf_oneof:"associatedValue"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache -} - -func (x *BodyRange) Reset() { - *x = BodyRange{} - mi := &file_SignalService_proto_msgTypes[3] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) -} - -func (x *BodyRange) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*BodyRange) ProtoMessage() {} - -func (x *BodyRange) ProtoReflect() protoreflect.Message { - mi := &file_SignalService_proto_msgTypes[3] - if x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use BodyRange.ProtoReflect.Descriptor instead. -func (*BodyRange) Descriptor() ([]byte, []int) { - return file_SignalService_proto_rawDescGZIP(), []int{3} -} - -func (x *BodyRange) GetStart() uint32 { - if x != nil && x.Start != nil { - return *x.Start - } - return 0 -} - -func (x *BodyRange) GetLength() uint32 { - if x != nil && x.Length != nil { - return *x.Length - } - return 0 -} - -func (x *BodyRange) GetAssociatedValue() isBodyRange_AssociatedValue { - if x != nil { - return x.AssociatedValue - } - return nil -} - -func (x *BodyRange) GetMentionAci() string { - if x != nil { - if x, ok := x.AssociatedValue.(*BodyRange_MentionAci); ok { - return x.MentionAci - } - } - return "" -} - -func (x *BodyRange) GetStyle() BodyRange_Style { - if x != nil { - if x, ok := x.AssociatedValue.(*BodyRange_Style_); ok { - return x.Style - } - } - return BodyRange_NONE -} - -type isBodyRange_AssociatedValue interface { - isBodyRange_AssociatedValue() -} - -type BodyRange_MentionAci struct { - MentionAci string `protobuf:"bytes,3,opt,name=mentionAci,oneof"` -} - -type BodyRange_Style_ struct { - Style BodyRange_Style `protobuf:"varint,4,opt,name=style,enum=signalservice.BodyRange_Style,oneof"` -} - -func (*BodyRange_MentionAci) isBodyRange_AssociatedValue() {} - -func (*BodyRange_Style_) isBodyRange_AssociatedValue() {} - type DataMessage struct { state protoimpl.MessageState `protogen:"open.v1"` Body *string `protobuf:"bytes,1,opt,name=body" json:"body,omitempty"` @@ -2164,14 +2127,14 @@ type DataMessage struct { GroupCallUpdate *DataMessage_GroupCallUpdate `protobuf:"bytes,19,opt,name=groupCallUpdate" json:"groupCallUpdate,omitempty"` Payment *DataMessage_Payment `protobuf:"bytes,20,opt,name=payment" json:"payment,omitempty"` StoryContext *DataMessage_StoryContext `protobuf:"bytes,21,opt,name=storyContext" json:"storyContext,omitempty"` - GiftBadge *DataMessage_GiftBadge `protobuf:"bytes,22,opt,name=giftBadge" json:"giftBadge,omitempty"` + GiftBadge *DataMessage_GiftBadge `protobuf:"bytes,22,opt,name=giftBadge" json:"giftBadge,omitempty"` // NEXT ID: 24 unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } func (x *DataMessage) Reset() { *x = DataMessage{} - mi := &file_SignalService_proto_msgTypes[4] + mi := &file_SignalService_proto_msgTypes[3] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2183,7 +2146,7 @@ func (x *DataMessage) String() string { func (*DataMessage) ProtoMessage() {} func (x *DataMessage) ProtoReflect() protoreflect.Message { - mi := &file_SignalService_proto_msgTypes[4] + mi := &file_SignalService_proto_msgTypes[3] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2196,7 +2159,7 @@ func (x *DataMessage) ProtoReflect() protoreflect.Message { // Deprecated: Use DataMessage.ProtoReflect.Descriptor instead. func (*DataMessage) Descriptor() ([]byte, []int) { - return file_SignalService_proto_rawDescGZIP(), []int{4} + return file_SignalService_proto_rawDescGZIP(), []int{3} } func (x *DataMessage) GetBody() string { @@ -2355,7 +2318,7 @@ type NullMessage struct { func (x *NullMessage) Reset() { *x = NullMessage{} - mi := &file_SignalService_proto_msgTypes[5] + mi := &file_SignalService_proto_msgTypes[4] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2367,7 +2330,7 @@ func (x *NullMessage) String() string { func (*NullMessage) ProtoMessage() {} func (x *NullMessage) ProtoReflect() protoreflect.Message { - mi := &file_SignalService_proto_msgTypes[5] + mi := &file_SignalService_proto_msgTypes[4] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2380,7 +2343,7 @@ func (x *NullMessage) ProtoReflect() protoreflect.Message { // Deprecated: Use NullMessage.ProtoReflect.Descriptor instead. func (*NullMessage) Descriptor() ([]byte, []int) { - return file_SignalService_proto_rawDescGZIP(), []int{5} + return file_SignalService_proto_rawDescGZIP(), []int{4} } func (x *NullMessage) GetPadding() []byte { @@ -2400,7 +2363,7 @@ type ReceiptMessage struct { func (x *ReceiptMessage) Reset() { *x = ReceiptMessage{} - mi := &file_SignalService_proto_msgTypes[6] + mi := &file_SignalService_proto_msgTypes[5] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2412,7 +2375,7 @@ func (x *ReceiptMessage) String() string { func (*ReceiptMessage) ProtoMessage() {} func (x *ReceiptMessage) ProtoReflect() protoreflect.Message { - mi := &file_SignalService_proto_msgTypes[6] + mi := &file_SignalService_proto_msgTypes[5] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2425,7 +2388,7 @@ func (x *ReceiptMessage) ProtoReflect() protoreflect.Message { // Deprecated: Use ReceiptMessage.ProtoReflect.Descriptor instead. func (*ReceiptMessage) Descriptor() ([]byte, []int) { - return file_SignalService_proto_rawDescGZIP(), []int{6} + return file_SignalService_proto_rawDescGZIP(), []int{5} } func (x *ReceiptMessage) GetType() ReceiptMessage_Type { @@ -2453,7 +2416,7 @@ type TypingMessage struct { func (x *TypingMessage) Reset() { *x = TypingMessage{} - mi := &file_SignalService_proto_msgTypes[7] + mi := &file_SignalService_proto_msgTypes[6] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2465,7 +2428,7 @@ func (x *TypingMessage) String() string { func (*TypingMessage) ProtoMessage() {} func (x *TypingMessage) ProtoReflect() protoreflect.Message { - mi := &file_SignalService_proto_msgTypes[7] + mi := &file_SignalService_proto_msgTypes[6] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2478,7 +2441,7 @@ func (x *TypingMessage) ProtoReflect() protoreflect.Message { // Deprecated: Use TypingMessage.ProtoReflect.Descriptor instead. func (*TypingMessage) Descriptor() ([]byte, []int) { - return file_SignalService_proto_rawDescGZIP(), []int{7} + return file_SignalService_proto_rawDescGZIP(), []int{6} } func (x *TypingMessage) GetTimestamp() uint64 { @@ -2519,7 +2482,7 @@ type StoryMessage struct { func (x *StoryMessage) Reset() { *x = StoryMessage{} - mi := &file_SignalService_proto_msgTypes[8] + mi := &file_SignalService_proto_msgTypes[7] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2531,7 +2494,7 @@ func (x *StoryMessage) String() string { func (*StoryMessage) ProtoMessage() {} func (x *StoryMessage) ProtoReflect() protoreflect.Message { - mi := &file_SignalService_proto_msgTypes[8] + mi := &file_SignalService_proto_msgTypes[7] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2544,7 +2507,7 @@ func (x *StoryMessage) ProtoReflect() protoreflect.Message { // Deprecated: Use StoryMessage.ProtoReflect.Descriptor instead. func (*StoryMessage) Descriptor() ([]byte, []int) { - return file_SignalService_proto_rawDescGZIP(), []int{8} + return file_SignalService_proto_rawDescGZIP(), []int{7} } func (x *StoryMessage) GetProfileKey() []byte { @@ -2629,7 +2592,7 @@ type Preview struct { func (x *Preview) Reset() { *x = Preview{} - mi := &file_SignalService_proto_msgTypes[9] + mi := &file_SignalService_proto_msgTypes[8] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2641,7 +2604,7 @@ func (x *Preview) String() string { func (*Preview) ProtoMessage() {} func (x *Preview) ProtoReflect() protoreflect.Message { - mi := &file_SignalService_proto_msgTypes[9] + mi := &file_SignalService_proto_msgTypes[8] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2654,7 +2617,7 @@ func (x *Preview) ProtoReflect() protoreflect.Message { // Deprecated: Use Preview.ProtoReflect.Descriptor instead. func (*Preview) Descriptor() ([]byte, []int) { - return file_SignalService_proto_rawDescGZIP(), []int{9} + return file_SignalService_proto_rawDescGZIP(), []int{8} } func (x *Preview) GetUrl() string { @@ -2710,7 +2673,7 @@ type TextAttachment struct { func (x *TextAttachment) Reset() { *x = TextAttachment{} - mi := &file_SignalService_proto_msgTypes[10] + mi := &file_SignalService_proto_msgTypes[9] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2722,7 +2685,7 @@ func (x *TextAttachment) String() string { func (*TextAttachment) ProtoMessage() {} func (x *TextAttachment) ProtoReflect() protoreflect.Message { - mi := &file_SignalService_proto_msgTypes[10] + mi := &file_SignalService_proto_msgTypes[9] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2735,7 +2698,7 @@ func (x *TextAttachment) ProtoReflect() protoreflect.Message { // Deprecated: Use TextAttachment.ProtoReflect.Descriptor instead. func (*TextAttachment) Descriptor() ([]byte, []int) { - return file_SignalService_proto_rawDescGZIP(), []int{10} + return file_SignalService_proto_rawDescGZIP(), []int{9} } func (x *TextAttachment) GetText() string { @@ -2826,7 +2789,7 @@ type Verified struct { func (x *Verified) Reset() { *x = Verified{} - mi := &file_SignalService_proto_msgTypes[11] + mi := &file_SignalService_proto_msgTypes[10] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2838,7 +2801,7 @@ func (x *Verified) String() string { func (*Verified) ProtoMessage() {} func (x *Verified) ProtoReflect() protoreflect.Message { - mi := &file_SignalService_proto_msgTypes[11] + mi := &file_SignalService_proto_msgTypes[10] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2851,7 +2814,7 @@ func (x *Verified) ProtoReflect() protoreflect.Message { // Deprecated: Use Verified.ProtoReflect.Descriptor instead. func (*Verified) Descriptor() ([]byte, []int) { - return file_SignalService_proto_rawDescGZIP(), []int{11} + return file_SignalService_proto_rawDescGZIP(), []int{10} } func (x *Verified) GetDestinationAci() string { @@ -2883,35 +2846,37 @@ func (x *Verified) GetNullMessage() []byte { } type SyncMessage struct { - state protoimpl.MessageState `protogen:"open.v1"` - Sent *SyncMessage_Sent `protobuf:"bytes,1,opt,name=sent" json:"sent,omitempty"` - Contacts *SyncMessage_Contacts `protobuf:"bytes,2,opt,name=contacts" json:"contacts,omitempty"` - Request *SyncMessage_Request `protobuf:"bytes,4,opt,name=request" json:"request,omitempty"` - Read []*SyncMessage_Read `protobuf:"bytes,5,rep,name=read" json:"read,omitempty"` - Blocked *SyncMessage_Blocked `protobuf:"bytes,6,opt,name=blocked" json:"blocked,omitempty"` - Verified *Verified `protobuf:"bytes,7,opt,name=verified" json:"verified,omitempty"` - Configuration *SyncMessage_Configuration `protobuf:"bytes,9,opt,name=configuration" json:"configuration,omitempty"` - Padding []byte `protobuf:"bytes,8,opt,name=padding" json:"padding,omitempty"` - StickerPackOperation []*SyncMessage_StickerPackOperation `protobuf:"bytes,10,rep,name=stickerPackOperation" json:"stickerPackOperation,omitempty"` - ViewOnceOpen *SyncMessage_ViewOnceOpen `protobuf:"bytes,11,opt,name=viewOnceOpen" json:"viewOnceOpen,omitempty"` - FetchLatest *SyncMessage_FetchLatest `protobuf:"bytes,12,opt,name=fetchLatest" json:"fetchLatest,omitempty"` - Keys *SyncMessage_Keys `protobuf:"bytes,13,opt,name=keys" json:"keys,omitempty"` - MessageRequestResponse *SyncMessage_MessageRequestResponse `protobuf:"bytes,14,opt,name=messageRequestResponse" json:"messageRequestResponse,omitempty"` - OutgoingPayment *SyncMessage_OutgoingPayment `protobuf:"bytes,15,opt,name=outgoingPayment" json:"outgoingPayment,omitempty"` - Viewed []*SyncMessage_Viewed `protobuf:"bytes,16,rep,name=viewed" json:"viewed,omitempty"` - PniChangeNumber *SyncMessage_PniChangeNumber `protobuf:"bytes,18,opt,name=pniChangeNumber" json:"pniChangeNumber,omitempty"` - CallEvent *SyncMessage_CallEvent `protobuf:"bytes,19,opt,name=callEvent" json:"callEvent,omitempty"` - CallLinkUpdate *SyncMessage_CallLinkUpdate `protobuf:"bytes,20,opt,name=callLinkUpdate" json:"callLinkUpdate,omitempty"` - CallLogEvent *SyncMessage_CallLogEvent `protobuf:"bytes,21,opt,name=callLogEvent" json:"callLogEvent,omitempty"` - DeleteForMe *SyncMessage_DeleteForMe `protobuf:"bytes,22,opt,name=deleteForMe" json:"deleteForMe,omitempty"` - DeviceNameChange *SyncMessage_DeviceNameChange `protobuf:"bytes,23,opt,name=deviceNameChange" json:"deviceNameChange,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` + Sent *SyncMessage_Sent `protobuf:"bytes,1,opt,name=sent" json:"sent,omitempty"` + Contacts *SyncMessage_Contacts `protobuf:"bytes,2,opt,name=contacts" json:"contacts,omitempty"` + Request *SyncMessage_Request `protobuf:"bytes,4,opt,name=request" json:"request,omitempty"` + Read []*SyncMessage_Read `protobuf:"bytes,5,rep,name=read" json:"read,omitempty"` + Blocked *SyncMessage_Blocked `protobuf:"bytes,6,opt,name=blocked" json:"blocked,omitempty"` + Verified *Verified `protobuf:"bytes,7,opt,name=verified" json:"verified,omitempty"` + Configuration *SyncMessage_Configuration `protobuf:"bytes,9,opt,name=configuration" json:"configuration,omitempty"` + Padding []byte `protobuf:"bytes,8,opt,name=padding" json:"padding,omitempty"` + StickerPackOperation []*SyncMessage_StickerPackOperation `protobuf:"bytes,10,rep,name=stickerPackOperation" json:"stickerPackOperation,omitempty"` + ViewOnceOpen *SyncMessage_ViewOnceOpen `protobuf:"bytes,11,opt,name=viewOnceOpen" json:"viewOnceOpen,omitempty"` + FetchLatest *SyncMessage_FetchLatest `protobuf:"bytes,12,opt,name=fetchLatest" json:"fetchLatest,omitempty"` + Keys *SyncMessage_Keys `protobuf:"bytes,13,opt,name=keys" json:"keys,omitempty"` + MessageRequestResponse *SyncMessage_MessageRequestResponse `protobuf:"bytes,14,opt,name=messageRequestResponse" json:"messageRequestResponse,omitempty"` + OutgoingPayment *SyncMessage_OutgoingPayment `protobuf:"bytes,15,opt,name=outgoingPayment" json:"outgoingPayment,omitempty"` + Viewed []*SyncMessage_Viewed `protobuf:"bytes,16,rep,name=viewed" json:"viewed,omitempty"` + PniChangeNumber *SyncMessage_PniChangeNumber `protobuf:"bytes,18,opt,name=pniChangeNumber" json:"pniChangeNumber,omitempty"` + CallEvent *SyncMessage_CallEvent `protobuf:"bytes,19,opt,name=callEvent" json:"callEvent,omitempty"` + CallLinkUpdate *SyncMessage_CallLinkUpdate `protobuf:"bytes,20,opt,name=callLinkUpdate" json:"callLinkUpdate,omitempty"` + CallLogEvent *SyncMessage_CallLogEvent `protobuf:"bytes,21,opt,name=callLogEvent" json:"callLogEvent,omitempty"` + DeleteForMe *SyncMessage_DeleteForMe `protobuf:"bytes,22,opt,name=deleteForMe" json:"deleteForMe,omitempty"` + DeviceNameChange *SyncMessage_DeviceNameChange `protobuf:"bytes,23,opt,name=deviceNameChange" json:"deviceNameChange,omitempty"` + AttachmentBackfillRequest *SyncMessage_AttachmentBackfillRequest `protobuf:"bytes,24,opt,name=attachmentBackfillRequest" json:"attachmentBackfillRequest,omitempty"` + AttachmentBackfillResponse *SyncMessage_AttachmentBackfillResponse `protobuf:"bytes,25,opt,name=attachmentBackfillResponse" json:"attachmentBackfillResponse,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } func (x *SyncMessage) Reset() { *x = SyncMessage{} - mi := &file_SignalService_proto_msgTypes[12] + mi := &file_SignalService_proto_msgTypes[11] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2923,7 +2888,7 @@ func (x *SyncMessage) String() string { func (*SyncMessage) ProtoMessage() {} func (x *SyncMessage) ProtoReflect() protoreflect.Message { - mi := &file_SignalService_proto_msgTypes[12] + mi := &file_SignalService_proto_msgTypes[11] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2936,7 +2901,7 @@ func (x *SyncMessage) ProtoReflect() protoreflect.Message { // Deprecated: Use SyncMessage.ProtoReflect.Descriptor instead. func (*SyncMessage) Descriptor() ([]byte, []int) { - return file_SignalService_proto_rawDescGZIP(), []int{12} + return file_SignalService_proto_rawDescGZIP(), []int{11} } func (x *SyncMessage) GetSent() *SyncMessage_Sent { @@ -3086,36 +3051,52 @@ func (x *SyncMessage) GetDeviceNameChange() *SyncMessage_DeviceNameChange { return nil } +func (x *SyncMessage) GetAttachmentBackfillRequest() *SyncMessage_AttachmentBackfillRequest { + if x != nil { + return x.AttachmentBackfillRequest + } + return nil +} + +func (x *SyncMessage) GetAttachmentBackfillResponse() *SyncMessage_AttachmentBackfillResponse { + if x != nil { + return x.AttachmentBackfillResponse + } + return nil +} + type AttachmentPointer struct { state protoimpl.MessageState `protogen:"open.v1"` // Types that are valid to be assigned to AttachmentIdentifier: // // *AttachmentPointer_CdnId // *AttachmentPointer_CdnKey - AttachmentIdentifier isAttachmentPointer_AttachmentIdentifier `protobuf_oneof:"attachment_identifier"` - ContentType *string `protobuf:"bytes,2,opt,name=contentType" json:"contentType,omitempty"` - Key []byte `protobuf:"bytes,3,opt,name=key" json:"key,omitempty"` - Size *uint32 `protobuf:"varint,4,opt,name=size" json:"size,omitempty"` - Thumbnail []byte `protobuf:"bytes,5,opt,name=thumbnail" json:"thumbnail,omitempty"` - Digest []byte `protobuf:"bytes,6,opt,name=digest" json:"digest,omitempty"` - IncrementalMac []byte `protobuf:"bytes,19,opt,name=incrementalMac" json:"incrementalMac,omitempty"` - IncrementalMacChunkSize *uint32 `protobuf:"varint,17,opt,name=incrementalMacChunkSize" json:"incrementalMacChunkSize,omitempty"` - FileName *string `protobuf:"bytes,7,opt,name=fileName" json:"fileName,omitempty"` - Flags *uint32 `protobuf:"varint,8,opt,name=flags" json:"flags,omitempty"` - Width *uint32 `protobuf:"varint,9,opt,name=width" json:"width,omitempty"` - Height *uint32 `protobuf:"varint,10,opt,name=height" json:"height,omitempty"` - Caption *string `protobuf:"bytes,11,opt,name=caption" json:"caption,omitempty"` - BlurHash *string `protobuf:"bytes,12,opt,name=blurHash" json:"blurHash,omitempty"` - UploadTimestamp *uint64 `protobuf:"varint,13,opt,name=uploadTimestamp" json:"uploadTimestamp,omitempty"` - CdnNumber *uint32 `protobuf:"varint,14,opt,name=cdnNumber" json:"cdnNumber,omitempty"` - Uuid []byte `protobuf:"bytes,20,opt,name=uuid" json:"uuid,omitempty"` // Next ID: 21 - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache + AttachmentIdentifier isAttachmentPointer_AttachmentIdentifier `protobuf_oneof:"attachment_identifier"` + // Cross-client identifier for this attachment among all attachments on the + // owning message. + ClientUuid []byte `protobuf:"bytes,20,opt,name=clientUuid" json:"clientUuid,omitempty"` + ContentType *string `protobuf:"bytes,2,opt,name=contentType" json:"contentType,omitempty"` + Key []byte `protobuf:"bytes,3,opt,name=key" json:"key,omitempty"` + Size *uint32 `protobuf:"varint,4,opt,name=size" json:"size,omitempty"` + Thumbnail []byte `protobuf:"bytes,5,opt,name=thumbnail" json:"thumbnail,omitempty"` + Digest []byte `protobuf:"bytes,6,opt,name=digest" json:"digest,omitempty"` + IncrementalMac []byte `protobuf:"bytes,19,opt,name=incrementalMac" json:"incrementalMac,omitempty"` + ChunkSize *uint32 `protobuf:"varint,17,opt,name=chunkSize" json:"chunkSize,omitempty"` + FileName *string `protobuf:"bytes,7,opt,name=fileName" json:"fileName,omitempty"` + Flags *uint32 `protobuf:"varint,8,opt,name=flags" json:"flags,omitempty"` + Width *uint32 `protobuf:"varint,9,opt,name=width" json:"width,omitempty"` + Height *uint32 `protobuf:"varint,10,opt,name=height" json:"height,omitempty"` + Caption *string `protobuf:"bytes,11,opt,name=caption" json:"caption,omitempty"` + BlurHash *string `protobuf:"bytes,12,opt,name=blurHash" json:"blurHash,omitempty"` + UploadTimestamp *uint64 `protobuf:"varint,13,opt,name=uploadTimestamp" json:"uploadTimestamp,omitempty"` + CdnNumber *uint32 `protobuf:"varint,14,opt,name=cdnNumber" json:"cdnNumber,omitempty"` // Next ID: 21 + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } func (x *AttachmentPointer) Reset() { *x = AttachmentPointer{} - mi := &file_SignalService_proto_msgTypes[13] + mi := &file_SignalService_proto_msgTypes[12] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3127,7 +3108,7 @@ func (x *AttachmentPointer) String() string { func (*AttachmentPointer) ProtoMessage() {} func (x *AttachmentPointer) ProtoReflect() protoreflect.Message { - mi := &file_SignalService_proto_msgTypes[13] + mi := &file_SignalService_proto_msgTypes[12] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3140,7 +3121,7 @@ func (x *AttachmentPointer) ProtoReflect() protoreflect.Message { // Deprecated: Use AttachmentPointer.ProtoReflect.Descriptor instead. func (*AttachmentPointer) Descriptor() ([]byte, []int) { - return file_SignalService_proto_rawDescGZIP(), []int{13} + return file_SignalService_proto_rawDescGZIP(), []int{12} } func (x *AttachmentPointer) GetAttachmentIdentifier() isAttachmentPointer_AttachmentIdentifier { @@ -3168,6 +3149,13 @@ func (x *AttachmentPointer) GetCdnKey() string { return "" } +func (x *AttachmentPointer) GetClientUuid() []byte { + if x != nil { + return x.ClientUuid + } + return nil +} + func (x *AttachmentPointer) GetContentType() string { if x != nil && x.ContentType != nil { return *x.ContentType @@ -3210,9 +3198,9 @@ func (x *AttachmentPointer) GetIncrementalMac() []byte { return nil } -func (x *AttachmentPointer) GetIncrementalMacChunkSize() uint32 { - if x != nil && x.IncrementalMacChunkSize != nil { - return *x.IncrementalMacChunkSize +func (x *AttachmentPointer) GetChunkSize() uint32 { + if x != nil && x.ChunkSize != nil { + return *x.ChunkSize } return 0 } @@ -3273,13 +3261,6 @@ func (x *AttachmentPointer) GetCdnNumber() uint32 { return 0 } -func (x *AttachmentPointer) GetUuid() []byte { - if x != nil { - return x.Uuid - } - return nil -} - type isAttachmentPointer_AttachmentIdentifier interface { isAttachmentPointer_AttachmentIdentifier() } @@ -3296,90 +3277,6 @@ func (*AttachmentPointer_CdnId) isAttachmentPointer_AttachmentIdentifier() {} func (*AttachmentPointer_CdnKey) isAttachmentPointer_AttachmentIdentifier() {} -type GroupContext struct { - state protoimpl.MessageState `protogen:"open.v1"` - Id []byte `protobuf:"bytes,1,opt,name=id" json:"id,omitempty"` - Type *GroupContext_Type `protobuf:"varint,2,opt,name=type,enum=signalservice.GroupContext_Type" json:"type,omitempty"` - Name *string `protobuf:"bytes,3,opt,name=name" json:"name,omitempty"` - MembersE164 []string `protobuf:"bytes,4,rep,name=membersE164" json:"membersE164,omitempty"` - Members []*GroupContext_Member `protobuf:"bytes,6,rep,name=members" json:"members,omitempty"` - Avatar *AttachmentPointer `protobuf:"bytes,5,opt,name=avatar" json:"avatar,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache -} - -func (x *GroupContext) Reset() { - *x = GroupContext{} - mi := &file_SignalService_proto_msgTypes[14] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) -} - -func (x *GroupContext) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*GroupContext) ProtoMessage() {} - -func (x *GroupContext) ProtoReflect() protoreflect.Message { - mi := &file_SignalService_proto_msgTypes[14] - if x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use GroupContext.ProtoReflect.Descriptor instead. -func (*GroupContext) Descriptor() ([]byte, []int) { - return file_SignalService_proto_rawDescGZIP(), []int{14} -} - -func (x *GroupContext) GetId() []byte { - if x != nil { - return x.Id - } - return nil -} - -func (x *GroupContext) GetType() GroupContext_Type { - if x != nil && x.Type != nil { - return *x.Type - } - return GroupContext_UNKNOWN -} - -func (x *GroupContext) GetName() string { - if x != nil && x.Name != nil { - return *x.Name - } - return "" -} - -func (x *GroupContext) GetMembersE164() []string { - if x != nil { - return x.MembersE164 - } - return nil -} - -func (x *GroupContext) GetMembers() []*GroupContext_Member { - if x != nil { - return x.Members - } - return nil -} - -func (x *GroupContext) GetAvatar() *AttachmentPointer { - if x != nil { - return x.Avatar - } - return nil -} - type GroupContextV2 struct { state protoimpl.MessageState `protogen:"open.v1"` MasterKey []byte `protobuf:"bytes,1,opt,name=masterKey" json:"masterKey,omitempty"` @@ -3391,7 +3288,7 @@ type GroupContextV2 struct { func (x *GroupContextV2) Reset() { *x = GroupContextV2{} - mi := &file_SignalService_proto_msgTypes[15] + mi := &file_SignalService_proto_msgTypes[13] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3403,7 +3300,7 @@ func (x *GroupContextV2) String() string { func (*GroupContextV2) ProtoMessage() {} func (x *GroupContextV2) ProtoReflect() protoreflect.Message { - mi := &file_SignalService_proto_msgTypes[15] + mi := &file_SignalService_proto_msgTypes[13] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3416,7 +3313,7 @@ func (x *GroupContextV2) ProtoReflect() protoreflect.Message { // Deprecated: Use GroupContextV2.ProtoReflect.Descriptor instead. func (*GroupContextV2) Descriptor() ([]byte, []int) { - return file_SignalService_proto_rawDescGZIP(), []int{15} + return file_SignalService_proto_rawDescGZIP(), []int{13} } func (x *GroupContextV2) GetMasterKey() []byte { @@ -3446,20 +3343,16 @@ type ContactDetails struct { Aci *string `protobuf:"bytes,9,opt,name=aci" json:"aci,omitempty"` Name *string `protobuf:"bytes,2,opt,name=name" json:"name,omitempty"` Avatar *ContactDetails_Avatar `protobuf:"bytes,3,opt,name=avatar" json:"avatar,omitempty"` - Color *string `protobuf:"bytes,4,opt,name=color" json:"color,omitempty"` - Verified *Verified `protobuf:"bytes,5,opt,name=verified" json:"verified,omitempty"` - ProfileKey []byte `protobuf:"bytes,6,opt,name=profileKey" json:"profileKey,omitempty"` ExpireTimer *uint32 `protobuf:"varint,8,opt,name=expireTimer" json:"expireTimer,omitempty"` ExpireTimerVersion *uint32 `protobuf:"varint,12,opt,name=expireTimerVersion" json:"expireTimerVersion,omitempty"` InboxPosition *uint32 `protobuf:"varint,10,opt,name=inboxPosition" json:"inboxPosition,omitempty"` - Archived *bool `protobuf:"varint,11,opt,name=archived" json:"archived,omitempty"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } func (x *ContactDetails) Reset() { *x = ContactDetails{} - mi := &file_SignalService_proto_msgTypes[16] + mi := &file_SignalService_proto_msgTypes[14] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3471,7 +3364,7 @@ func (x *ContactDetails) String() string { func (*ContactDetails) ProtoMessage() {} func (x *ContactDetails) ProtoReflect() protoreflect.Message { - mi := &file_SignalService_proto_msgTypes[16] + mi := &file_SignalService_proto_msgTypes[14] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3484,7 +3377,7 @@ func (x *ContactDetails) ProtoReflect() protoreflect.Message { // Deprecated: Use ContactDetails.ProtoReflect.Descriptor instead. func (*ContactDetails) Descriptor() ([]byte, []int) { - return file_SignalService_proto_rawDescGZIP(), []int{16} + return file_SignalService_proto_rawDescGZIP(), []int{14} } func (x *ContactDetails) GetNumber() string { @@ -3515,27 +3408,6 @@ func (x *ContactDetails) GetAvatar() *ContactDetails_Avatar { return nil } -func (x *ContactDetails) GetColor() string { - if x != nil && x.Color != nil { - return *x.Color - } - return "" -} - -func (x *ContactDetails) GetVerified() *Verified { - if x != nil { - return x.Verified - } - return nil -} - -func (x *ContactDetails) GetProfileKey() []byte { - if x != nil { - return x.ProfileKey - } - return nil -} - func (x *ContactDetails) GetExpireTimer() uint32 { if x != nil && x.ExpireTimer != nil { return *x.ExpireTimer @@ -3557,147 +3429,11 @@ func (x *ContactDetails) GetInboxPosition() uint32 { return 0 } -func (x *ContactDetails) GetArchived() bool { - if x != nil && x.Archived != nil { - return *x.Archived - } - return false -} - -type GroupDetails struct { - state protoimpl.MessageState `protogen:"open.v1"` - Id []byte `protobuf:"bytes,1,opt,name=id" json:"id,omitempty"` - Name *string `protobuf:"bytes,2,opt,name=name" json:"name,omitempty"` - MembersE164 []string `protobuf:"bytes,3,rep,name=membersE164" json:"membersE164,omitempty"` - Members []*GroupDetails_Member `protobuf:"bytes,9,rep,name=members" json:"members,omitempty"` - Avatar *GroupDetails_Avatar `protobuf:"bytes,4,opt,name=avatar" json:"avatar,omitempty"` - Active *bool `protobuf:"varint,5,opt,name=active,def=1" json:"active,omitempty"` - ExpireTimer *uint32 `protobuf:"varint,6,opt,name=expireTimer" json:"expireTimer,omitempty"` - Color *string `protobuf:"bytes,7,opt,name=color" json:"color,omitempty"` - Blocked *bool `protobuf:"varint,8,opt,name=blocked" json:"blocked,omitempty"` - InboxPosition *uint32 `protobuf:"varint,10,opt,name=inboxPosition" json:"inboxPosition,omitempty"` - Archived *bool `protobuf:"varint,11,opt,name=archived" json:"archived,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache -} - -// Default values for GroupDetails fields. -const ( - Default_GroupDetails_Active = bool(true) -) - -func (x *GroupDetails) Reset() { - *x = GroupDetails{} - mi := &file_SignalService_proto_msgTypes[17] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) -} - -func (x *GroupDetails) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*GroupDetails) ProtoMessage() {} - -func (x *GroupDetails) ProtoReflect() protoreflect.Message { - mi := &file_SignalService_proto_msgTypes[17] - if x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use GroupDetails.ProtoReflect.Descriptor instead. -func (*GroupDetails) Descriptor() ([]byte, []int) { - return file_SignalService_proto_rawDescGZIP(), []int{17} -} - -func (x *GroupDetails) GetId() []byte { - if x != nil { - return x.Id - } - return nil -} - -func (x *GroupDetails) GetName() string { - if x != nil && x.Name != nil { - return *x.Name - } - return "" -} - -func (x *GroupDetails) GetMembersE164() []string { - if x != nil { - return x.MembersE164 - } - return nil -} - -func (x *GroupDetails) GetMembers() []*GroupDetails_Member { - if x != nil { - return x.Members - } - return nil -} - -func (x *GroupDetails) GetAvatar() *GroupDetails_Avatar { - if x != nil { - return x.Avatar - } - return nil -} - -func (x *GroupDetails) GetActive() bool { - if x != nil && x.Active != nil { - return *x.Active - } - return Default_GroupDetails_Active -} - -func (x *GroupDetails) GetExpireTimer() uint32 { - if x != nil && x.ExpireTimer != nil { - return *x.ExpireTimer - } - return 0 -} - -func (x *GroupDetails) GetColor() string { - if x != nil && x.Color != nil { - return *x.Color - } - return "" -} - -func (x *GroupDetails) GetBlocked() bool { - if x != nil && x.Blocked != nil { - return *x.Blocked - } - return false -} - -func (x *GroupDetails) GetInboxPosition() uint32 { - if x != nil && x.InboxPosition != nil { - return *x.InboxPosition - } - return 0 -} - -func (x *GroupDetails) GetArchived() bool { - if x != nil && x.Archived != nil { - return *x.Archived - } - return false -} - type PaymentAddress struct { state protoimpl.MessageState `protogen:"open.v1"` // Types that are valid to be assigned to Address: // - // *PaymentAddress_MobileCoinAddress_ + // *PaymentAddress_MobileCoin_ Address isPaymentAddress_Address `protobuf_oneof:"Address"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache @@ -3705,7 +3441,7 @@ type PaymentAddress struct { func (x *PaymentAddress) Reset() { *x = PaymentAddress{} - mi := &file_SignalService_proto_msgTypes[18] + mi := &file_SignalService_proto_msgTypes[15] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3717,7 +3453,7 @@ func (x *PaymentAddress) String() string { func (*PaymentAddress) ProtoMessage() {} func (x *PaymentAddress) ProtoReflect() protoreflect.Message { - mi := &file_SignalService_proto_msgTypes[18] + mi := &file_SignalService_proto_msgTypes[15] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3730,7 +3466,7 @@ func (x *PaymentAddress) ProtoReflect() protoreflect.Message { // Deprecated: Use PaymentAddress.ProtoReflect.Descriptor instead. func (*PaymentAddress) Descriptor() ([]byte, []int) { - return file_SignalService_proto_rawDescGZIP(), []int{18} + return file_SignalService_proto_rawDescGZIP(), []int{15} } func (x *PaymentAddress) GetAddress() isPaymentAddress_Address { @@ -3740,10 +3476,10 @@ func (x *PaymentAddress) GetAddress() isPaymentAddress_Address { return nil } -func (x *PaymentAddress) GetMobileCoinAddress() *PaymentAddress_MobileCoinAddress { +func (x *PaymentAddress) GetMobileCoin() *PaymentAddress_MobileCoin { if x != nil { - if x, ok := x.Address.(*PaymentAddress_MobileCoinAddress_); ok { - return x.MobileCoinAddress + if x, ok := x.Address.(*PaymentAddress_MobileCoin_); ok { + return x.MobileCoin } } return nil @@ -3753,15 +3489,15 @@ type isPaymentAddress_Address interface { isPaymentAddress_Address() } -type PaymentAddress_MobileCoinAddress_ struct { - MobileCoinAddress *PaymentAddress_MobileCoinAddress `protobuf:"bytes,1,opt,name=mobileCoinAddress,oneof"` +type PaymentAddress_MobileCoin_ struct { + MobileCoin *PaymentAddress_MobileCoin `protobuf:"bytes,1,opt,name=mobileCoin,oneof"` } -func (*PaymentAddress_MobileCoinAddress_) isPaymentAddress_Address() {} +func (*PaymentAddress_MobileCoin_) isPaymentAddress_Address() {} type DecryptionErrorMessage struct { state protoimpl.MessageState `protogen:"open.v1"` - RatchetKey []byte `protobuf:"bytes,1,opt,name=ratchetKey" json:"ratchetKey,omitempty"` + RatchetKey []byte `protobuf:"bytes,1,opt,name=ratchetKey" json:"ratchetKey,omitempty"` // set to the public ratchet key from the SignalMessage if a 1-1 payload fails to decrypt Timestamp *uint64 `protobuf:"varint,2,opt,name=timestamp" json:"timestamp,omitempty"` DeviceId *uint32 `protobuf:"varint,3,opt,name=deviceId" json:"deviceId,omitempty"` unknownFields protoimpl.UnknownFields @@ -3770,7 +3506,7 @@ type DecryptionErrorMessage struct { func (x *DecryptionErrorMessage) Reset() { *x = DecryptionErrorMessage{} - mi := &file_SignalService_proto_msgTypes[19] + mi := &file_SignalService_proto_msgTypes[16] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3782,7 +3518,7 @@ func (x *DecryptionErrorMessage) String() string { func (*DecryptionErrorMessage) ProtoMessage() {} func (x *DecryptionErrorMessage) ProtoReflect() protoreflect.Message { - mi := &file_SignalService_proto_msgTypes[19] + mi := &file_SignalService_proto_msgTypes[16] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3795,7 +3531,7 @@ func (x *DecryptionErrorMessage) ProtoReflect() protoreflect.Message { // Deprecated: Use DecryptionErrorMessage.ProtoReflect.Descriptor instead. func (*DecryptionErrorMessage) Descriptor() ([]byte, []int) { - return file_SignalService_proto_rawDescGZIP(), []int{19} + return file_SignalService_proto_rawDescGZIP(), []int{16} } func (x *DecryptionErrorMessage) GetRatchetKey() []byte { @@ -3820,16 +3556,17 @@ func (x *DecryptionErrorMessage) GetDeviceId() uint32 { } type PniSignatureMessage struct { - state protoimpl.MessageState `protogen:"open.v1"` - Pni []byte `protobuf:"bytes,1,opt,name=pni" json:"pni,omitempty"` - Signature []byte `protobuf:"bytes,2,opt,name=signature" json:"signature,omitempty"` + state protoimpl.MessageState `protogen:"open.v1"` + Pni []byte `protobuf:"bytes,1,opt,name=pni" json:"pni,omitempty"` + // Signature *by* the PNI identity key *of* the ACI identity key + Signature []byte `protobuf:"bytes,2,opt,name=signature" json:"signature,omitempty"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } func (x *PniSignatureMessage) Reset() { *x = PniSignatureMessage{} - mi := &file_SignalService_proto_msgTypes[20] + mi := &file_SignalService_proto_msgTypes[17] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3841,7 +3578,7 @@ func (x *PniSignatureMessage) String() string { func (*PniSignatureMessage) ProtoMessage() {} func (x *PniSignatureMessage) ProtoReflect() protoreflect.Message { - mi := &file_SignalService_proto_msgTypes[20] + mi := &file_SignalService_proto_msgTypes[17] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3854,7 +3591,7 @@ func (x *PniSignatureMessage) ProtoReflect() protoreflect.Message { // Deprecated: Use PniSignatureMessage.ProtoReflect.Descriptor instead. func (*PniSignatureMessage) Descriptor() ([]byte, []int) { - return file_SignalService_proto_rawDescGZIP(), []int{20} + return file_SignalService_proto_rawDescGZIP(), []int{17} } func (x *PniSignatureMessage) GetPni() []byte { @@ -3881,7 +3618,7 @@ type EditMessage struct { func (x *EditMessage) Reset() { *x = EditMessage{} - mi := &file_SignalService_proto_msgTypes[21] + mi := &file_SignalService_proto_msgTypes[18] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3893,7 +3630,7 @@ func (x *EditMessage) String() string { func (*EditMessage) ProtoMessage() {} func (x *EditMessage) ProtoReflect() protoreflect.Message { - mi := &file_SignalService_proto_msgTypes[21] + mi := &file_SignalService_proto_msgTypes[18] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3906,7 +3643,7 @@ func (x *EditMessage) ProtoReflect() protoreflect.Message { // Deprecated: Use EditMessage.ProtoReflect.Descriptor instead. func (*EditMessage) Descriptor() ([]byte, []int) { - return file_SignalService_proto_rawDescGZIP(), []int{21} + return file_SignalService_proto_rawDescGZIP(), []int{18} } func (x *EditMessage) GetTargetSentTimestamp() uint64 { @@ -3923,6 +3660,292 @@ func (x *EditMessage) GetDataMessage() *DataMessage { return nil } +type BodyRange struct { + state protoimpl.MessageState `protogen:"open.v1"` + Start *uint32 `protobuf:"varint,1,opt,name=start" json:"start,omitempty"` // Starting index in UTF-16 code units/raw string representation + Length *uint32 `protobuf:"varint,2,opt,name=length" json:"length,omitempty"` // Length of range in UTF-16 code units/raw string representation + // Types that are valid to be assigned to AssociatedValue: + // + // *BodyRange_MentionAci + // *BodyRange_Style_ + AssociatedValue isBodyRange_AssociatedValue `protobuf_oneof:"associatedValue"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *BodyRange) Reset() { + *x = BodyRange{} + mi := &file_SignalService_proto_msgTypes[19] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *BodyRange) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*BodyRange) ProtoMessage() {} + +func (x *BodyRange) ProtoReflect() protoreflect.Message { + mi := &file_SignalService_proto_msgTypes[19] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use BodyRange.ProtoReflect.Descriptor instead. +func (*BodyRange) Descriptor() ([]byte, []int) { + return file_SignalService_proto_rawDescGZIP(), []int{19} +} + +func (x *BodyRange) GetStart() uint32 { + if x != nil && x.Start != nil { + return *x.Start + } + return 0 +} + +func (x *BodyRange) GetLength() uint32 { + if x != nil && x.Length != nil { + return *x.Length + } + return 0 +} + +func (x *BodyRange) GetAssociatedValue() isBodyRange_AssociatedValue { + if x != nil { + return x.AssociatedValue + } + return nil +} + +func (x *BodyRange) GetMentionAci() string { + if x != nil { + if x, ok := x.AssociatedValue.(*BodyRange_MentionAci); ok { + return x.MentionAci + } + } + return "" +} + +func (x *BodyRange) GetStyle() BodyRange_Style { + if x != nil { + if x, ok := x.AssociatedValue.(*BodyRange_Style_); ok { + return x.Style + } + } + return BodyRange_NONE +} + +type isBodyRange_AssociatedValue interface { + isBodyRange_AssociatedValue() +} + +type BodyRange_MentionAci struct { + MentionAci string `protobuf:"bytes,3,opt,name=mentionAci,oneof"` +} + +type BodyRange_Style_ struct { + Style BodyRange_Style `protobuf:"varint,4,opt,name=style,enum=signalservice.BodyRange_Style,oneof"` +} + +func (*BodyRange_MentionAci) isBodyRange_AssociatedValue() {} + +func (*BodyRange_Style_) isBodyRange_AssociatedValue() {} + +type AddressableMessage struct { + state protoimpl.MessageState `protogen:"open.v1"` + // Types that are valid to be assigned to Author: + // + // *AddressableMessage_AuthorServiceId + // *AddressableMessage_AuthorE164 + Author isAddressableMessage_Author `protobuf_oneof:"author"` + SentTimestamp *uint64 `protobuf:"varint,3,opt,name=sentTimestamp" json:"sentTimestamp,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *AddressableMessage) Reset() { + *x = AddressableMessage{} + mi := &file_SignalService_proto_msgTypes[20] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *AddressableMessage) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*AddressableMessage) ProtoMessage() {} + +func (x *AddressableMessage) ProtoReflect() protoreflect.Message { + mi := &file_SignalService_proto_msgTypes[20] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use AddressableMessage.ProtoReflect.Descriptor instead. +func (*AddressableMessage) Descriptor() ([]byte, []int) { + return file_SignalService_proto_rawDescGZIP(), []int{20} +} + +func (x *AddressableMessage) GetAuthor() isAddressableMessage_Author { + if x != nil { + return x.Author + } + return nil +} + +func (x *AddressableMessage) GetAuthorServiceId() string { + if x != nil { + if x, ok := x.Author.(*AddressableMessage_AuthorServiceId); ok { + return x.AuthorServiceId + } + } + return "" +} + +func (x *AddressableMessage) GetAuthorE164() string { + if x != nil { + if x, ok := x.Author.(*AddressableMessage_AuthorE164); ok { + return x.AuthorE164 + } + } + return "" +} + +func (x *AddressableMessage) GetSentTimestamp() uint64 { + if x != nil && x.SentTimestamp != nil { + return *x.SentTimestamp + } + return 0 +} + +type isAddressableMessage_Author interface { + isAddressableMessage_Author() +} + +type AddressableMessage_AuthorServiceId struct { + AuthorServiceId string `protobuf:"bytes,1,opt,name=authorServiceId,oneof"` +} + +type AddressableMessage_AuthorE164 struct { + AuthorE164 string `protobuf:"bytes,2,opt,name=authorE164,oneof"` +} + +func (*AddressableMessage_AuthorServiceId) isAddressableMessage_Author() {} + +func (*AddressableMessage_AuthorE164) isAddressableMessage_Author() {} + +type ConversationIdentifier struct { + state protoimpl.MessageState `protogen:"open.v1"` + // Types that are valid to be assigned to Identifier: + // + // *ConversationIdentifier_ThreadServiceId + // *ConversationIdentifier_ThreadGroupId + // *ConversationIdentifier_ThreadE164 + Identifier isConversationIdentifier_Identifier `protobuf_oneof:"identifier"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ConversationIdentifier) Reset() { + *x = ConversationIdentifier{} + mi := &file_SignalService_proto_msgTypes[21] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ConversationIdentifier) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ConversationIdentifier) ProtoMessage() {} + +func (x *ConversationIdentifier) ProtoReflect() protoreflect.Message { + mi := &file_SignalService_proto_msgTypes[21] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ConversationIdentifier.ProtoReflect.Descriptor instead. +func (*ConversationIdentifier) Descriptor() ([]byte, []int) { + return file_SignalService_proto_rawDescGZIP(), []int{21} +} + +func (x *ConversationIdentifier) GetIdentifier() isConversationIdentifier_Identifier { + if x != nil { + return x.Identifier + } + return nil +} + +func (x *ConversationIdentifier) GetThreadServiceId() string { + if x != nil { + if x, ok := x.Identifier.(*ConversationIdentifier_ThreadServiceId); ok { + return x.ThreadServiceId + } + } + return "" +} + +func (x *ConversationIdentifier) GetThreadGroupId() []byte { + if x != nil { + if x, ok := x.Identifier.(*ConversationIdentifier_ThreadGroupId); ok { + return x.ThreadGroupId + } + } + return nil +} + +func (x *ConversationIdentifier) GetThreadE164() string { + if x != nil { + if x, ok := x.Identifier.(*ConversationIdentifier_ThreadE164); ok { + return x.ThreadE164 + } + } + return "" +} + +type isConversationIdentifier_Identifier interface { + isConversationIdentifier_Identifier() +} + +type ConversationIdentifier_ThreadServiceId struct { + ThreadServiceId string `protobuf:"bytes,1,opt,name=threadServiceId,oneof"` +} + +type ConversationIdentifier_ThreadGroupId struct { + ThreadGroupId []byte `protobuf:"bytes,2,opt,name=threadGroupId,oneof"` +} + +type ConversationIdentifier_ThreadE164 struct { + ThreadE164 string `protobuf:"bytes,3,opt,name=threadE164,oneof"` +} + +func (*ConversationIdentifier_ThreadServiceId) isConversationIdentifier_Identifier() {} + +func (*ConversationIdentifier_ThreadGroupId) isConversationIdentifier_Identifier() {} + +func (*ConversationIdentifier_ThreadE164) isConversationIdentifier_Identifier() {} + type CallMessage_Offer struct { state protoimpl.MessageState `protogen:"open.v1"` Id *uint64 `protobuf:"varint,1,opt,name=id" json:"id,omitempty"` @@ -4194,7 +4217,7 @@ func (x *CallMessage_Hangup) GetDeviceId() uint32 { type CallMessage_Opaque struct { state protoimpl.MessageState `protogen:"open.v1"` Data []byte `protobuf:"bytes,1,opt,name=data" json:"data,omitempty"` - Urgency *CallMessage_Opaque_Urgency `protobuf:"varint,2,opt,name=urgency,enum=signalservice.CallMessage_Opaque_Urgency" json:"urgency,omitempty"` + Urgency *CallMessage_Opaque_Urgency `protobuf:"varint,2,opt,name=urgency,enum=signalservice.CallMessage_Opaque_Urgency" json:"urgency,omitempty"` // If missing, treat as DROPPABLE. unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } @@ -4243,6 +4266,88 @@ func (x *CallMessage_Opaque) GetUrgency() CallMessage_Opaque_Urgency { return CallMessage_Opaque_DROPPABLE } +type DataMessage_Payment struct { + state protoimpl.MessageState `protogen:"open.v1"` + // Types that are valid to be assigned to Item: + // + // *DataMessage_Payment_Notification_ + // *DataMessage_Payment_Activation_ + Item isDataMessage_Payment_Item `protobuf_oneof:"Item"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *DataMessage_Payment) Reset() { + *x = DataMessage_Payment{} + mi := &file_SignalService_proto_msgTypes[28] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *DataMessage_Payment) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*DataMessage_Payment) ProtoMessage() {} + +func (x *DataMessage_Payment) ProtoReflect() protoreflect.Message { + mi := &file_SignalService_proto_msgTypes[28] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use DataMessage_Payment.ProtoReflect.Descriptor instead. +func (*DataMessage_Payment) Descriptor() ([]byte, []int) { + return file_SignalService_proto_rawDescGZIP(), []int{3, 0} +} + +func (x *DataMessage_Payment) GetItem() isDataMessage_Payment_Item { + if x != nil { + return x.Item + } + return nil +} + +func (x *DataMessage_Payment) GetNotification() *DataMessage_Payment_Notification { + if x != nil { + if x, ok := x.Item.(*DataMessage_Payment_Notification_); ok { + return x.Notification + } + } + return nil +} + +func (x *DataMessage_Payment) GetActivation() *DataMessage_Payment_Activation { + if x != nil { + if x, ok := x.Item.(*DataMessage_Payment_Activation_); ok { + return x.Activation + } + } + return nil +} + +type isDataMessage_Payment_Item interface { + isDataMessage_Payment_Item() +} + +type DataMessage_Payment_Notification_ struct { + Notification *DataMessage_Payment_Notification `protobuf:"bytes,1,opt,name=notification,oneof"` +} + +type DataMessage_Payment_Activation_ struct { + Activation *DataMessage_Payment_Activation `protobuf:"bytes,2,opt,name=activation,oneof"` +} + +func (*DataMessage_Payment_Notification_) isDataMessage_Payment_Item() {} + +func (*DataMessage_Payment_Activation_) isDataMessage_Payment_Item() {} + type DataMessage_Quote struct { state protoimpl.MessageState `protogen:"open.v1"` Id *uint64 `protobuf:"varint,1,opt,name=id" json:"id,omitempty"` @@ -4257,7 +4362,7 @@ type DataMessage_Quote struct { func (x *DataMessage_Quote) Reset() { *x = DataMessage_Quote{} - mi := &file_SignalService_proto_msgTypes[28] + mi := &file_SignalService_proto_msgTypes[29] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4269,7 +4374,7 @@ func (x *DataMessage_Quote) String() string { func (*DataMessage_Quote) ProtoMessage() {} func (x *DataMessage_Quote) ProtoReflect() protoreflect.Message { - mi := &file_SignalService_proto_msgTypes[28] + mi := &file_SignalService_proto_msgTypes[29] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4282,7 +4387,7 @@ func (x *DataMessage_Quote) ProtoReflect() protoreflect.Message { // Deprecated: Use DataMessage_Quote.ProtoReflect.Descriptor instead. func (*DataMessage_Quote) Descriptor() ([]byte, []int) { - return file_SignalService_proto_rawDescGZIP(), []int{4, 0} + return file_SignalService_proto_rawDescGZIP(), []int{3, 1} } func (x *DataMessage_Quote) GetId() uint64 { @@ -4341,7 +4446,7 @@ type DataMessage_Contact struct { func (x *DataMessage_Contact) Reset() { *x = DataMessage_Contact{} - mi := &file_SignalService_proto_msgTypes[29] + mi := &file_SignalService_proto_msgTypes[30] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4353,7 +4458,7 @@ func (x *DataMessage_Contact) String() string { func (*DataMessage_Contact) ProtoMessage() {} func (x *DataMessage_Contact) ProtoReflect() protoreflect.Message { - mi := &file_SignalService_proto_msgTypes[29] + mi := &file_SignalService_proto_msgTypes[30] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4366,7 +4471,7 @@ func (x *DataMessage_Contact) ProtoReflect() protoreflect.Message { // Deprecated: Use DataMessage_Contact.ProtoReflect.Descriptor instead. func (*DataMessage_Contact) Descriptor() ([]byte, []int) { - return file_SignalService_proto_rawDescGZIP(), []int{4, 1} + return file_SignalService_proto_rawDescGZIP(), []int{3, 2} } func (x *DataMessage_Contact) GetName() *DataMessage_Contact_Name { @@ -4424,7 +4529,7 @@ type DataMessage_Sticker struct { func (x *DataMessage_Sticker) Reset() { *x = DataMessage_Sticker{} - mi := &file_SignalService_proto_msgTypes[30] + mi := &file_SignalService_proto_msgTypes[31] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4436,7 +4541,7 @@ func (x *DataMessage_Sticker) String() string { func (*DataMessage_Sticker) ProtoMessage() {} func (x *DataMessage_Sticker) ProtoReflect() protoreflect.Message { - mi := &file_SignalService_proto_msgTypes[30] + mi := &file_SignalService_proto_msgTypes[31] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4449,7 +4554,7 @@ func (x *DataMessage_Sticker) ProtoReflect() protoreflect.Message { // Deprecated: Use DataMessage_Sticker.ProtoReflect.Descriptor instead. func (*DataMessage_Sticker) Descriptor() ([]byte, []int) { - return file_SignalService_proto_rawDescGZIP(), []int{4, 2} + return file_SignalService_proto_rawDescGZIP(), []int{3, 3} } func (x *DataMessage_Sticker) GetPackId() []byte { @@ -4499,7 +4604,7 @@ type DataMessage_Reaction struct { func (x *DataMessage_Reaction) Reset() { *x = DataMessage_Reaction{} - mi := &file_SignalService_proto_msgTypes[31] + mi := &file_SignalService_proto_msgTypes[32] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4511,7 +4616,7 @@ func (x *DataMessage_Reaction) String() string { func (*DataMessage_Reaction) ProtoMessage() {} func (x *DataMessage_Reaction) ProtoReflect() protoreflect.Message { - mi := &file_SignalService_proto_msgTypes[31] + mi := &file_SignalService_proto_msgTypes[32] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4524,7 +4629,7 @@ func (x *DataMessage_Reaction) ProtoReflect() protoreflect.Message { // Deprecated: Use DataMessage_Reaction.ProtoReflect.Descriptor instead. func (*DataMessage_Reaction) Descriptor() ([]byte, []int) { - return file_SignalService_proto_rawDescGZIP(), []int{4, 3} + return file_SignalService_proto_rawDescGZIP(), []int{3, 4} } func (x *DataMessage_Reaction) GetEmoji() string { @@ -4564,7 +4669,7 @@ type DataMessage_Delete struct { func (x *DataMessage_Delete) Reset() { *x = DataMessage_Delete{} - mi := &file_SignalService_proto_msgTypes[32] + mi := &file_SignalService_proto_msgTypes[33] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4576,7 +4681,7 @@ func (x *DataMessage_Delete) String() string { func (*DataMessage_Delete) ProtoMessage() {} func (x *DataMessage_Delete) ProtoReflect() protoreflect.Message { - mi := &file_SignalService_proto_msgTypes[32] + mi := &file_SignalService_proto_msgTypes[33] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4589,7 +4694,7 @@ func (x *DataMessage_Delete) ProtoReflect() protoreflect.Message { // Deprecated: Use DataMessage_Delete.ProtoReflect.Descriptor instead. func (*DataMessage_Delete) Descriptor() ([]byte, []int) { - return file_SignalService_proto_rawDescGZIP(), []int{4, 4} + return file_SignalService_proto_rawDescGZIP(), []int{3, 5} } func (x *DataMessage_Delete) GetTargetSentTimestamp() uint64 { @@ -4608,7 +4713,7 @@ type DataMessage_GroupCallUpdate struct { func (x *DataMessage_GroupCallUpdate) Reset() { *x = DataMessage_GroupCallUpdate{} - mi := &file_SignalService_proto_msgTypes[33] + mi := &file_SignalService_proto_msgTypes[34] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4620,7 +4725,7 @@ func (x *DataMessage_GroupCallUpdate) String() string { func (*DataMessage_GroupCallUpdate) ProtoMessage() {} func (x *DataMessage_GroupCallUpdate) ProtoReflect() protoreflect.Message { - mi := &file_SignalService_proto_msgTypes[33] + mi := &file_SignalService_proto_msgTypes[34] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4633,7 +4738,7 @@ func (x *DataMessage_GroupCallUpdate) ProtoReflect() protoreflect.Message { // Deprecated: Use DataMessage_GroupCallUpdate.ProtoReflect.Descriptor instead. func (*DataMessage_GroupCallUpdate) Descriptor() ([]byte, []int) { - return file_SignalService_proto_rawDescGZIP(), []int{4, 5} + return file_SignalService_proto_rawDescGZIP(), []int{3, 6} } func (x *DataMessage_GroupCallUpdate) GetEraId() string { @@ -4653,7 +4758,7 @@ type DataMessage_StoryContext struct { func (x *DataMessage_StoryContext) Reset() { *x = DataMessage_StoryContext{} - mi := &file_SignalService_proto_msgTypes[34] + mi := &file_SignalService_proto_msgTypes[35] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4665,7 +4770,7 @@ func (x *DataMessage_StoryContext) String() string { func (*DataMessage_StoryContext) ProtoMessage() {} func (x *DataMessage_StoryContext) ProtoReflect() protoreflect.Message { - mi := &file_SignalService_proto_msgTypes[34] + mi := &file_SignalService_proto_msgTypes[35] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4678,7 +4783,7 @@ func (x *DataMessage_StoryContext) ProtoReflect() protoreflect.Message { // Deprecated: Use DataMessage_StoryContext.ProtoReflect.Descriptor instead. func (*DataMessage_StoryContext) Descriptor() ([]byte, []int) { - return file_SignalService_proto_rawDescGZIP(), []int{4, 6} + return file_SignalService_proto_rawDescGZIP(), []int{3, 7} } func (x *DataMessage_StoryContext) GetAuthorAci() string { @@ -4695,88 +4800,6 @@ func (x *DataMessage_StoryContext) GetSentTimestamp() uint64 { return 0 } -type DataMessage_Payment struct { - state protoimpl.MessageState `protogen:"open.v1"` - // Types that are valid to be assigned to Item: - // - // *DataMessage_Payment_Notification_ - // *DataMessage_Payment_Activation_ - Item isDataMessage_Payment_Item `protobuf_oneof:"Item"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache -} - -func (x *DataMessage_Payment) Reset() { - *x = DataMessage_Payment{} - mi := &file_SignalService_proto_msgTypes[35] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) -} - -func (x *DataMessage_Payment) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*DataMessage_Payment) ProtoMessage() {} - -func (x *DataMessage_Payment) ProtoReflect() protoreflect.Message { - mi := &file_SignalService_proto_msgTypes[35] - if x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use DataMessage_Payment.ProtoReflect.Descriptor instead. -func (*DataMessage_Payment) Descriptor() ([]byte, []int) { - return file_SignalService_proto_rawDescGZIP(), []int{4, 7} -} - -func (x *DataMessage_Payment) GetItem() isDataMessage_Payment_Item { - if x != nil { - return x.Item - } - return nil -} - -func (x *DataMessage_Payment) GetNotification() *DataMessage_Payment_Notification { - if x != nil { - if x, ok := x.Item.(*DataMessage_Payment_Notification_); ok { - return x.Notification - } - } - return nil -} - -func (x *DataMessage_Payment) GetActivation() *DataMessage_Payment_Activation { - if x != nil { - if x, ok := x.Item.(*DataMessage_Payment_Activation_); ok { - return x.Activation - } - } - return nil -} - -type isDataMessage_Payment_Item interface { - isDataMessage_Payment_Item() -} - -type DataMessage_Payment_Notification_ struct { - Notification *DataMessage_Payment_Notification `protobuf:"bytes,1,opt,name=notification,oneof"` -} - -type DataMessage_Payment_Activation_ struct { - Activation *DataMessage_Payment_Activation `protobuf:"bytes,2,opt,name=activation,oneof"` -} - -func (*DataMessage_Payment_Notification_) isDataMessage_Payment_Item() {} - -func (*DataMessage_Payment_Activation_) isDataMessage_Payment_Item() {} - type DataMessage_GiftBadge struct { state protoimpl.MessageState `protogen:"open.v1"` ReceiptCredentialPresentation []byte `protobuf:"bytes,1,opt,name=receiptCredentialPresentation" json:"receiptCredentialPresentation,omitempty"` @@ -4811,7 +4834,7 @@ func (x *DataMessage_GiftBadge) ProtoReflect() protoreflect.Message { // Deprecated: Use DataMessage_GiftBadge.ProtoReflect.Descriptor instead. func (*DataMessage_GiftBadge) Descriptor() ([]byte, []int) { - return file_SignalService_proto_rawDescGZIP(), []int{4, 8} + return file_SignalService_proto_rawDescGZIP(), []int{3, 8} } func (x *DataMessage_GiftBadge) GetReceiptCredentialPresentation() []byte { @@ -4821,6 +4844,280 @@ func (x *DataMessage_GiftBadge) GetReceiptCredentialPresentation() []byte { return nil } +type DataMessage_Payment_Amount struct { + state protoimpl.MessageState `protogen:"open.v1"` + // Types that are valid to be assigned to Amount: + // + // *DataMessage_Payment_Amount_MobileCoin_ + Amount isDataMessage_Payment_Amount_Amount `protobuf_oneof:"Amount"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *DataMessage_Payment_Amount) Reset() { + *x = DataMessage_Payment_Amount{} + mi := &file_SignalService_proto_msgTypes[37] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *DataMessage_Payment_Amount) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*DataMessage_Payment_Amount) ProtoMessage() {} + +func (x *DataMessage_Payment_Amount) ProtoReflect() protoreflect.Message { + mi := &file_SignalService_proto_msgTypes[37] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use DataMessage_Payment_Amount.ProtoReflect.Descriptor instead. +func (*DataMessage_Payment_Amount) Descriptor() ([]byte, []int) { + return file_SignalService_proto_rawDescGZIP(), []int{3, 0, 0} +} + +func (x *DataMessage_Payment_Amount) GetAmount() isDataMessage_Payment_Amount_Amount { + if x != nil { + return x.Amount + } + return nil +} + +func (x *DataMessage_Payment_Amount) GetMobileCoin() *DataMessage_Payment_Amount_MobileCoin { + if x != nil { + if x, ok := x.Amount.(*DataMessage_Payment_Amount_MobileCoin_); ok { + return x.MobileCoin + } + } + return nil +} + +type isDataMessage_Payment_Amount_Amount interface { + isDataMessage_Payment_Amount_Amount() +} + +type DataMessage_Payment_Amount_MobileCoin_ struct { + MobileCoin *DataMessage_Payment_Amount_MobileCoin `protobuf:"bytes,1,opt,name=mobileCoin,oneof"` +} + +func (*DataMessage_Payment_Amount_MobileCoin_) isDataMessage_Payment_Amount_Amount() {} + +type DataMessage_Payment_Notification struct { + state protoimpl.MessageState `protogen:"open.v1"` + // Types that are valid to be assigned to Transaction: + // + // *DataMessage_Payment_Notification_MobileCoin_ + Transaction isDataMessage_Payment_Notification_Transaction `protobuf_oneof:"Transaction"` + // Optional, Refers to the PaymentRequest message, if any. + Note *string `protobuf:"bytes,2,opt,name=note" json:"note,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *DataMessage_Payment_Notification) Reset() { + *x = DataMessage_Payment_Notification{} + mi := &file_SignalService_proto_msgTypes[38] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *DataMessage_Payment_Notification) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*DataMessage_Payment_Notification) ProtoMessage() {} + +func (x *DataMessage_Payment_Notification) ProtoReflect() protoreflect.Message { + mi := &file_SignalService_proto_msgTypes[38] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use DataMessage_Payment_Notification.ProtoReflect.Descriptor instead. +func (*DataMessage_Payment_Notification) Descriptor() ([]byte, []int) { + return file_SignalService_proto_rawDescGZIP(), []int{3, 0, 1} +} + +func (x *DataMessage_Payment_Notification) GetTransaction() isDataMessage_Payment_Notification_Transaction { + if x != nil { + return x.Transaction + } + return nil +} + +func (x *DataMessage_Payment_Notification) GetMobileCoin() *DataMessage_Payment_Notification_MobileCoin { + if x != nil { + if x, ok := x.Transaction.(*DataMessage_Payment_Notification_MobileCoin_); ok { + return x.MobileCoin + } + } + return nil +} + +func (x *DataMessage_Payment_Notification) GetNote() string { + if x != nil && x.Note != nil { + return *x.Note + } + return "" +} + +type isDataMessage_Payment_Notification_Transaction interface { + isDataMessage_Payment_Notification_Transaction() +} + +type DataMessage_Payment_Notification_MobileCoin_ struct { + MobileCoin *DataMessage_Payment_Notification_MobileCoin `protobuf:"bytes,1,opt,name=mobileCoin,oneof"` +} + +func (*DataMessage_Payment_Notification_MobileCoin_) isDataMessage_Payment_Notification_Transaction() { +} + +type DataMessage_Payment_Activation struct { + state protoimpl.MessageState `protogen:"open.v1"` + Type *DataMessage_Payment_Activation_Type `protobuf:"varint,1,opt,name=type,enum=signalservice.DataMessage_Payment_Activation_Type" json:"type,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *DataMessage_Payment_Activation) Reset() { + *x = DataMessage_Payment_Activation{} + mi := &file_SignalService_proto_msgTypes[39] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *DataMessage_Payment_Activation) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*DataMessage_Payment_Activation) ProtoMessage() {} + +func (x *DataMessage_Payment_Activation) ProtoReflect() protoreflect.Message { + mi := &file_SignalService_proto_msgTypes[39] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use DataMessage_Payment_Activation.ProtoReflect.Descriptor instead. +func (*DataMessage_Payment_Activation) Descriptor() ([]byte, []int) { + return file_SignalService_proto_rawDescGZIP(), []int{3, 0, 2} +} + +func (x *DataMessage_Payment_Activation) GetType() DataMessage_Payment_Activation_Type { + if x != nil && x.Type != nil { + return *x.Type + } + return DataMessage_Payment_Activation_REQUEST +} + +type DataMessage_Payment_Amount_MobileCoin struct { + state protoimpl.MessageState `protogen:"open.v1"` + PicoMob *uint64 `protobuf:"varint,1,opt,name=picoMob" json:"picoMob,omitempty"` // 1,000,000,000,000 picoMob per Mob + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *DataMessage_Payment_Amount_MobileCoin) Reset() { + *x = DataMessage_Payment_Amount_MobileCoin{} + mi := &file_SignalService_proto_msgTypes[40] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *DataMessage_Payment_Amount_MobileCoin) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*DataMessage_Payment_Amount_MobileCoin) ProtoMessage() {} + +func (x *DataMessage_Payment_Amount_MobileCoin) ProtoReflect() protoreflect.Message { + mi := &file_SignalService_proto_msgTypes[40] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use DataMessage_Payment_Amount_MobileCoin.ProtoReflect.Descriptor instead. +func (*DataMessage_Payment_Amount_MobileCoin) Descriptor() ([]byte, []int) { + return file_SignalService_proto_rawDescGZIP(), []int{3, 0, 0, 0} +} + +func (x *DataMessage_Payment_Amount_MobileCoin) GetPicoMob() uint64 { + if x != nil && x.PicoMob != nil { + return *x.PicoMob + } + return 0 +} + +type DataMessage_Payment_Notification_MobileCoin struct { + state protoimpl.MessageState `protogen:"open.v1"` + Receipt []byte `protobuf:"bytes,1,opt,name=receipt" json:"receipt,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *DataMessage_Payment_Notification_MobileCoin) Reset() { + *x = DataMessage_Payment_Notification_MobileCoin{} + mi := &file_SignalService_proto_msgTypes[41] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *DataMessage_Payment_Notification_MobileCoin) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*DataMessage_Payment_Notification_MobileCoin) ProtoMessage() {} + +func (x *DataMessage_Payment_Notification_MobileCoin) ProtoReflect() protoreflect.Message { + mi := &file_SignalService_proto_msgTypes[41] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use DataMessage_Payment_Notification_MobileCoin.ProtoReflect.Descriptor instead. +func (*DataMessage_Payment_Notification_MobileCoin) Descriptor() ([]byte, []int) { + return file_SignalService_proto_rawDescGZIP(), []int{3, 0, 1, 0} +} + +func (x *DataMessage_Payment_Notification_MobileCoin) GetReceipt() []byte { + if x != nil { + return x.Receipt + } + return nil +} + type DataMessage_Quote_QuotedAttachment struct { state protoimpl.MessageState `protogen:"open.v1"` ContentType *string `protobuf:"bytes,1,opt,name=contentType" json:"contentType,omitempty"` @@ -4832,7 +5129,7 @@ type DataMessage_Quote_QuotedAttachment struct { func (x *DataMessage_Quote_QuotedAttachment) Reset() { *x = DataMessage_Quote_QuotedAttachment{} - mi := &file_SignalService_proto_msgTypes[37] + mi := &file_SignalService_proto_msgTypes[42] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4844,7 +5141,7 @@ func (x *DataMessage_Quote_QuotedAttachment) String() string { func (*DataMessage_Quote_QuotedAttachment) ProtoMessage() {} func (x *DataMessage_Quote_QuotedAttachment) ProtoReflect() protoreflect.Message { - mi := &file_SignalService_proto_msgTypes[37] + mi := &file_SignalService_proto_msgTypes[42] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4857,7 +5154,7 @@ func (x *DataMessage_Quote_QuotedAttachment) ProtoReflect() protoreflect.Message // Deprecated: Use DataMessage_Quote_QuotedAttachment.ProtoReflect.Descriptor instead. func (*DataMessage_Quote_QuotedAttachment) Descriptor() ([]byte, []int) { - return file_SignalService_proto_rawDescGZIP(), []int{4, 0, 0} + return file_SignalService_proto_rawDescGZIP(), []int{3, 1, 0} } func (x *DataMessage_Quote_QuotedAttachment) GetContentType() string { @@ -4895,7 +5192,7 @@ type DataMessage_Contact_Name struct { func (x *DataMessage_Contact_Name) Reset() { *x = DataMessage_Contact_Name{} - mi := &file_SignalService_proto_msgTypes[38] + mi := &file_SignalService_proto_msgTypes[43] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4907,7 +5204,7 @@ func (x *DataMessage_Contact_Name) String() string { func (*DataMessage_Contact_Name) ProtoMessage() {} func (x *DataMessage_Contact_Name) ProtoReflect() protoreflect.Message { - mi := &file_SignalService_proto_msgTypes[38] + mi := &file_SignalService_proto_msgTypes[43] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4920,7 +5217,7 @@ func (x *DataMessage_Contact_Name) ProtoReflect() protoreflect.Message { // Deprecated: Use DataMessage_Contact_Name.ProtoReflect.Descriptor instead. func (*DataMessage_Contact_Name) Descriptor() ([]byte, []int) { - return file_SignalService_proto_rawDescGZIP(), []int{4, 1, 0} + return file_SignalService_proto_rawDescGZIP(), []int{3, 2, 0} } func (x *DataMessage_Contact_Name) GetGivenName() string { @@ -4976,7 +5273,7 @@ type DataMessage_Contact_Phone struct { func (x *DataMessage_Contact_Phone) Reset() { *x = DataMessage_Contact_Phone{} - mi := &file_SignalService_proto_msgTypes[39] + mi := &file_SignalService_proto_msgTypes[44] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4988,7 +5285,7 @@ func (x *DataMessage_Contact_Phone) String() string { func (*DataMessage_Contact_Phone) ProtoMessage() {} func (x *DataMessage_Contact_Phone) ProtoReflect() protoreflect.Message { - mi := &file_SignalService_proto_msgTypes[39] + mi := &file_SignalService_proto_msgTypes[44] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5001,7 +5298,7 @@ func (x *DataMessage_Contact_Phone) ProtoReflect() protoreflect.Message { // Deprecated: Use DataMessage_Contact_Phone.ProtoReflect.Descriptor instead. func (*DataMessage_Contact_Phone) Descriptor() ([]byte, []int) { - return file_SignalService_proto_rawDescGZIP(), []int{4, 1, 1} + return file_SignalService_proto_rawDescGZIP(), []int{3, 2, 1} } func (x *DataMessage_Contact_Phone) GetValue() string { @@ -5036,7 +5333,7 @@ type DataMessage_Contact_Email struct { func (x *DataMessage_Contact_Email) Reset() { *x = DataMessage_Contact_Email{} - mi := &file_SignalService_proto_msgTypes[40] + mi := &file_SignalService_proto_msgTypes[45] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5048,7 +5345,7 @@ func (x *DataMessage_Contact_Email) String() string { func (*DataMessage_Contact_Email) ProtoMessage() {} func (x *DataMessage_Contact_Email) ProtoReflect() protoreflect.Message { - mi := &file_SignalService_proto_msgTypes[40] + mi := &file_SignalService_proto_msgTypes[45] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5061,7 +5358,7 @@ func (x *DataMessage_Contact_Email) ProtoReflect() protoreflect.Message { // Deprecated: Use DataMessage_Contact_Email.ProtoReflect.Descriptor instead. func (*DataMessage_Contact_Email) Descriptor() ([]byte, []int) { - return file_SignalService_proto_rawDescGZIP(), []int{4, 1, 2} + return file_SignalService_proto_rawDescGZIP(), []int{3, 2, 2} } func (x *DataMessage_Contact_Email) GetValue() string { @@ -5102,7 +5399,7 @@ type DataMessage_Contact_PostalAddress struct { func (x *DataMessage_Contact_PostalAddress) Reset() { *x = DataMessage_Contact_PostalAddress{} - mi := &file_SignalService_proto_msgTypes[41] + mi := &file_SignalService_proto_msgTypes[46] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5114,7 +5411,7 @@ func (x *DataMessage_Contact_PostalAddress) String() string { func (*DataMessage_Contact_PostalAddress) ProtoMessage() {} func (x *DataMessage_Contact_PostalAddress) ProtoReflect() protoreflect.Message { - mi := &file_SignalService_proto_msgTypes[41] + mi := &file_SignalService_proto_msgTypes[46] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5127,7 +5424,7 @@ func (x *DataMessage_Contact_PostalAddress) ProtoReflect() protoreflect.Message // Deprecated: Use DataMessage_Contact_PostalAddress.ProtoReflect.Descriptor instead. func (*DataMessage_Contact_PostalAddress) Descriptor() ([]byte, []int) { - return file_SignalService_proto_rawDescGZIP(), []int{4, 1, 3} + return file_SignalService_proto_rawDescGZIP(), []int{3, 2, 3} } func (x *DataMessage_Contact_PostalAddress) GetType() DataMessage_Contact_PostalAddress_Type { @@ -5203,7 +5500,7 @@ type DataMessage_Contact_Avatar struct { func (x *DataMessage_Contact_Avatar) Reset() { *x = DataMessage_Contact_Avatar{} - mi := &file_SignalService_proto_msgTypes[42] + mi := &file_SignalService_proto_msgTypes[47] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5215,7 +5512,7 @@ func (x *DataMessage_Contact_Avatar) String() string { func (*DataMessage_Contact_Avatar) ProtoMessage() {} func (x *DataMessage_Contact_Avatar) ProtoReflect() protoreflect.Message { - mi := &file_SignalService_proto_msgTypes[42] + mi := &file_SignalService_proto_msgTypes[47] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5228,7 +5525,7 @@ func (x *DataMessage_Contact_Avatar) ProtoReflect() protoreflect.Message { // Deprecated: Use DataMessage_Contact_Avatar.ProtoReflect.Descriptor instead. func (*DataMessage_Contact_Avatar) Descriptor() ([]byte, []int) { - return file_SignalService_proto_rawDescGZIP(), []int{4, 1, 4} + return file_SignalService_proto_rawDescGZIP(), []int{3, 2, 4} } func (x *DataMessage_Contact_Avatar) GetAvatar() *AttachmentPointer { @@ -5245,279 +5542,6 @@ func (x *DataMessage_Contact_Avatar) GetIsProfile() bool { return false } -type DataMessage_Payment_Amount struct { - state protoimpl.MessageState `protogen:"open.v1"` - // Types that are valid to be assigned to Amount: - // - // *DataMessage_Payment_Amount_MobileCoin_ - Amount isDataMessage_Payment_Amount_Amount `protobuf_oneof:"Amount"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache -} - -func (x *DataMessage_Payment_Amount) Reset() { - *x = DataMessage_Payment_Amount{} - mi := &file_SignalService_proto_msgTypes[43] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) -} - -func (x *DataMessage_Payment_Amount) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*DataMessage_Payment_Amount) ProtoMessage() {} - -func (x *DataMessage_Payment_Amount) ProtoReflect() protoreflect.Message { - mi := &file_SignalService_proto_msgTypes[43] - if x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use DataMessage_Payment_Amount.ProtoReflect.Descriptor instead. -func (*DataMessage_Payment_Amount) Descriptor() ([]byte, []int) { - return file_SignalService_proto_rawDescGZIP(), []int{4, 7, 0} -} - -func (x *DataMessage_Payment_Amount) GetAmount() isDataMessage_Payment_Amount_Amount { - if x != nil { - return x.Amount - } - return nil -} - -func (x *DataMessage_Payment_Amount) GetMobileCoin() *DataMessage_Payment_Amount_MobileCoin { - if x != nil { - if x, ok := x.Amount.(*DataMessage_Payment_Amount_MobileCoin_); ok { - return x.MobileCoin - } - } - return nil -} - -type isDataMessage_Payment_Amount_Amount interface { - isDataMessage_Payment_Amount_Amount() -} - -type DataMessage_Payment_Amount_MobileCoin_ struct { - MobileCoin *DataMessage_Payment_Amount_MobileCoin `protobuf:"bytes,1,opt,name=mobileCoin,oneof"` -} - -func (*DataMessage_Payment_Amount_MobileCoin_) isDataMessage_Payment_Amount_Amount() {} - -type DataMessage_Payment_Notification struct { - state protoimpl.MessageState `protogen:"open.v1"` - // Types that are valid to be assigned to Transaction: - // - // *DataMessage_Payment_Notification_MobileCoin_ - Transaction isDataMessage_Payment_Notification_Transaction `protobuf_oneof:"Transaction"` - Note *string `protobuf:"bytes,2,opt,name=note" json:"note,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache -} - -func (x *DataMessage_Payment_Notification) Reset() { - *x = DataMessage_Payment_Notification{} - mi := &file_SignalService_proto_msgTypes[44] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) -} - -func (x *DataMessage_Payment_Notification) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*DataMessage_Payment_Notification) ProtoMessage() {} - -func (x *DataMessage_Payment_Notification) ProtoReflect() protoreflect.Message { - mi := &file_SignalService_proto_msgTypes[44] - if x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use DataMessage_Payment_Notification.ProtoReflect.Descriptor instead. -func (*DataMessage_Payment_Notification) Descriptor() ([]byte, []int) { - return file_SignalService_proto_rawDescGZIP(), []int{4, 7, 1} -} - -func (x *DataMessage_Payment_Notification) GetTransaction() isDataMessage_Payment_Notification_Transaction { - if x != nil { - return x.Transaction - } - return nil -} - -func (x *DataMessage_Payment_Notification) GetMobileCoin() *DataMessage_Payment_Notification_MobileCoin { - if x != nil { - if x, ok := x.Transaction.(*DataMessage_Payment_Notification_MobileCoin_); ok { - return x.MobileCoin - } - } - return nil -} - -func (x *DataMessage_Payment_Notification) GetNote() string { - if x != nil && x.Note != nil { - return *x.Note - } - return "" -} - -type isDataMessage_Payment_Notification_Transaction interface { - isDataMessage_Payment_Notification_Transaction() -} - -type DataMessage_Payment_Notification_MobileCoin_ struct { - MobileCoin *DataMessage_Payment_Notification_MobileCoin `protobuf:"bytes,1,opt,name=mobileCoin,oneof"` -} - -func (*DataMessage_Payment_Notification_MobileCoin_) isDataMessage_Payment_Notification_Transaction() { -} - -type DataMessage_Payment_Activation struct { - state protoimpl.MessageState `protogen:"open.v1"` - Type *DataMessage_Payment_Activation_Type `protobuf:"varint,1,opt,name=type,enum=signalservice.DataMessage_Payment_Activation_Type" json:"type,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache -} - -func (x *DataMessage_Payment_Activation) Reset() { - *x = DataMessage_Payment_Activation{} - mi := &file_SignalService_proto_msgTypes[45] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) -} - -func (x *DataMessage_Payment_Activation) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*DataMessage_Payment_Activation) ProtoMessage() {} - -func (x *DataMessage_Payment_Activation) ProtoReflect() protoreflect.Message { - mi := &file_SignalService_proto_msgTypes[45] - if x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use DataMessage_Payment_Activation.ProtoReflect.Descriptor instead. -func (*DataMessage_Payment_Activation) Descriptor() ([]byte, []int) { - return file_SignalService_proto_rawDescGZIP(), []int{4, 7, 2} -} - -func (x *DataMessage_Payment_Activation) GetType() DataMessage_Payment_Activation_Type { - if x != nil && x.Type != nil { - return *x.Type - } - return DataMessage_Payment_Activation_REQUEST -} - -type DataMessage_Payment_Amount_MobileCoin struct { - state protoimpl.MessageState `protogen:"open.v1"` - PicoMob *uint64 `protobuf:"varint,1,opt,name=picoMob" json:"picoMob,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache -} - -func (x *DataMessage_Payment_Amount_MobileCoin) Reset() { - *x = DataMessage_Payment_Amount_MobileCoin{} - mi := &file_SignalService_proto_msgTypes[46] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) -} - -func (x *DataMessage_Payment_Amount_MobileCoin) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*DataMessage_Payment_Amount_MobileCoin) ProtoMessage() {} - -func (x *DataMessage_Payment_Amount_MobileCoin) ProtoReflect() protoreflect.Message { - mi := &file_SignalService_proto_msgTypes[46] - if x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use DataMessage_Payment_Amount_MobileCoin.ProtoReflect.Descriptor instead. -func (*DataMessage_Payment_Amount_MobileCoin) Descriptor() ([]byte, []int) { - return file_SignalService_proto_rawDescGZIP(), []int{4, 7, 0, 0} -} - -func (x *DataMessage_Payment_Amount_MobileCoin) GetPicoMob() uint64 { - if x != nil && x.PicoMob != nil { - return *x.PicoMob - } - return 0 -} - -type DataMessage_Payment_Notification_MobileCoin struct { - state protoimpl.MessageState `protogen:"open.v1"` - Receipt []byte `protobuf:"bytes,1,opt,name=receipt" json:"receipt,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache -} - -func (x *DataMessage_Payment_Notification_MobileCoin) Reset() { - *x = DataMessage_Payment_Notification_MobileCoin{} - mi := &file_SignalService_proto_msgTypes[47] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) -} - -func (x *DataMessage_Payment_Notification_MobileCoin) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*DataMessage_Payment_Notification_MobileCoin) ProtoMessage() {} - -func (x *DataMessage_Payment_Notification_MobileCoin) ProtoReflect() protoreflect.Message { - mi := &file_SignalService_proto_msgTypes[47] - if x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use DataMessage_Payment_Notification_MobileCoin.ProtoReflect.Descriptor instead. -func (*DataMessage_Payment_Notification_MobileCoin) Descriptor() ([]byte, []int) { - return file_SignalService_proto_rawDescGZIP(), []int{4, 7, 1, 0} -} - -func (x *DataMessage_Payment_Notification_MobileCoin) GetReceipt() []byte { - if x != nil { - return x.Receipt - } - return nil -} - type TextAttachment_Gradient struct { state protoimpl.MessageState `protogen:"open.v1"` StartColor *uint32 `protobuf:"varint,1,opt,name=startColor" json:"startColor,omitempty"` // deprecated: this field will be removed in a future release. @@ -5556,7 +5580,7 @@ func (x *TextAttachment_Gradient) ProtoReflect() protoreflect.Message { // Deprecated: Use TextAttachment_Gradient.ProtoReflect.Descriptor instead. func (*TextAttachment_Gradient) Descriptor() ([]byte, []int) { - return file_SignalService_proto_rawDescGZIP(), []int{10, 0} + return file_SignalService_proto_rawDescGZIP(), []int{9, 0} } func (x *TextAttachment_Gradient) GetStartColor() uint32 { @@ -5642,7 +5666,7 @@ func (x *SyncMessage_Sent) ProtoReflect() protoreflect.Message { // Deprecated: Use SyncMessage_Sent.ProtoReflect.Descriptor instead. func (*SyncMessage_Sent) Descriptor() ([]byte, []int) { - return file_SignalService_proto_rawDescGZIP(), []int{12, 0} + return file_SignalService_proto_rawDescGZIP(), []int{11, 0} } func (x *SyncMessage_Sent) GetDestinationE164() string { @@ -5755,7 +5779,7 @@ func (x *SyncMessage_Contacts) ProtoReflect() protoreflect.Message { // Deprecated: Use SyncMessage_Contacts.ProtoReflect.Descriptor instead. func (*SyncMessage_Contacts) Descriptor() ([]byte, []int) { - return file_SignalService_proto_rawDescGZIP(), []int{12, 1} + return file_SignalService_proto_rawDescGZIP(), []int{11, 1} } func (x *SyncMessage_Contacts) GetBlob() *AttachmentPointer { @@ -5808,7 +5832,7 @@ func (x *SyncMessage_Blocked) ProtoReflect() protoreflect.Message { // Deprecated: Use SyncMessage_Blocked.ProtoReflect.Descriptor instead. func (*SyncMessage_Blocked) Descriptor() ([]byte, []int) { - return file_SignalService_proto_rawDescGZIP(), []int{12, 2} + return file_SignalService_proto_rawDescGZIP(), []int{11, 2} } func (x *SyncMessage_Blocked) GetNumbers() []string { @@ -5866,7 +5890,7 @@ func (x *SyncMessage_Request) ProtoReflect() protoreflect.Message { // Deprecated: Use SyncMessage_Request.ProtoReflect.Descriptor instead. func (*SyncMessage_Request) Descriptor() ([]byte, []int) { - return file_SignalService_proto_rawDescGZIP(), []int{12, 3} + return file_SignalService_proto_rawDescGZIP(), []int{11, 3} } func (x *SyncMessage_Request) GetType() SyncMessage_Request_Type { @@ -5911,7 +5935,7 @@ func (x *SyncMessage_Read) ProtoReflect() protoreflect.Message { // Deprecated: Use SyncMessage_Read.ProtoReflect.Descriptor instead. func (*SyncMessage_Read) Descriptor() ([]byte, []int) { - return file_SignalService_proto_rawDescGZIP(), []int{12, 4} + return file_SignalService_proto_rawDescGZIP(), []int{11, 4} } func (x *SyncMessage_Read) GetSenderAci() string { @@ -5963,7 +5987,7 @@ func (x *SyncMessage_Viewed) ProtoReflect() protoreflect.Message { // Deprecated: Use SyncMessage_Viewed.ProtoReflect.Descriptor instead. func (*SyncMessage_Viewed) Descriptor() ([]byte, []int) { - return file_SignalService_proto_rawDescGZIP(), []int{12, 5} + return file_SignalService_proto_rawDescGZIP(), []int{11, 5} } func (x *SyncMessage_Viewed) GetSenderAci() string { @@ -6018,7 +6042,7 @@ func (x *SyncMessage_Configuration) ProtoReflect() protoreflect.Message { // Deprecated: Use SyncMessage_Configuration.ProtoReflect.Descriptor instead. func (*SyncMessage_Configuration) Descriptor() ([]byte, []int) { - return file_SignalService_proto_rawDescGZIP(), []int{12, 6} + return file_SignalService_proto_rawDescGZIP(), []int{11, 6} } func (x *SyncMessage_Configuration) GetReadReceipts() bool { @@ -6092,7 +6116,7 @@ func (x *SyncMessage_StickerPackOperation) ProtoReflect() protoreflect.Message { // Deprecated: Use SyncMessage_StickerPackOperation.ProtoReflect.Descriptor instead. func (*SyncMessage_StickerPackOperation) Descriptor() ([]byte, []int) { - return file_SignalService_proto_rawDescGZIP(), []int{12, 7} + return file_SignalService_proto_rawDescGZIP(), []int{11, 7} } func (x *SyncMessage_StickerPackOperation) GetPackId() []byte { @@ -6151,7 +6175,7 @@ func (x *SyncMessage_ViewOnceOpen) ProtoReflect() protoreflect.Message { // Deprecated: Use SyncMessage_ViewOnceOpen.ProtoReflect.Descriptor instead. func (*SyncMessage_ViewOnceOpen) Descriptor() ([]byte, []int) { - return file_SignalService_proto_rawDescGZIP(), []int{12, 8} + return file_SignalService_proto_rawDescGZIP(), []int{11, 8} } func (x *SyncMessage_ViewOnceOpen) GetSenderAci() string { @@ -6202,7 +6226,7 @@ func (x *SyncMessage_FetchLatest) ProtoReflect() protoreflect.Message { // Deprecated: Use SyncMessage_FetchLatest.ProtoReflect.Descriptor instead. func (*SyncMessage_FetchLatest) Descriptor() ([]byte, []int) { - return file_SignalService_proto_rawDescGZIP(), []int{12, 9} + return file_SignalService_proto_rawDescGZIP(), []int{11, 9} } func (x *SyncMessage_FetchLatest) GetType() SyncMessage_FetchLatest_Type { @@ -6213,13 +6237,10 @@ func (x *SyncMessage_FetchLatest) GetType() SyncMessage_FetchLatest_Type { } type SyncMessage_Keys struct { - state protoimpl.MessageState `protogen:"open.v1"` - // @deprecated - StorageService []byte `protobuf:"bytes,1,opt,name=storageService" json:"storageService,omitempty"` - // @deprecated - Master []byte `protobuf:"bytes,2,opt,name=master" json:"master,omitempty"` - AccountEntropyPool *string `protobuf:"bytes,3,opt,name=accountEntropyPool" json:"accountEntropyPool,omitempty"` - MediaRootBackupKey []byte `protobuf:"bytes,4,opt,name=mediaRootBackupKey" json:"mediaRootBackupKey,omitempty"` + state protoimpl.MessageState `protogen:"open.v1"` + Master []byte `protobuf:"bytes,2,opt,name=master" json:"master,omitempty"` // deprecated: this field will be removed in a future release. + AccountEntropyPool *string `protobuf:"bytes,3,opt,name=accountEntropyPool" json:"accountEntropyPool,omitempty"` + MediaRootBackupKey []byte `protobuf:"bytes,4,opt,name=mediaRootBackupKey" json:"mediaRootBackupKey,omitempty"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } @@ -6251,14 +6272,7 @@ func (x *SyncMessage_Keys) ProtoReflect() protoreflect.Message { // Deprecated: Use SyncMessage_Keys.ProtoReflect.Descriptor instead. func (*SyncMessage_Keys) Descriptor() ([]byte, []int) { - return file_SignalService_proto_rawDescGZIP(), []int{12, 10} -} - -func (x *SyncMessage_Keys) GetStorageService() []byte { - if x != nil { - return x.StorageService - } - return nil + return file_SignalService_proto_rawDescGZIP(), []int{11, 10} } func (x *SyncMessage_Keys) GetMaster() []byte { @@ -6282,6 +6296,58 @@ func (x *SyncMessage_Keys) GetMediaRootBackupKey() []byte { return nil } +type SyncMessage_PniIdentity struct { + state protoimpl.MessageState `protogen:"open.v1"` + PublicKey []byte `protobuf:"bytes,1,opt,name=publicKey" json:"publicKey,omitempty"` + PrivateKey []byte `protobuf:"bytes,2,opt,name=privateKey" json:"privateKey,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *SyncMessage_PniIdentity) Reset() { + *x = SyncMessage_PniIdentity{} + mi := &file_SignalService_proto_msgTypes[60] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *SyncMessage_PniIdentity) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SyncMessage_PniIdentity) ProtoMessage() {} + +func (x *SyncMessage_PniIdentity) ProtoReflect() protoreflect.Message { + mi := &file_SignalService_proto_msgTypes[60] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use SyncMessage_PniIdentity.ProtoReflect.Descriptor instead. +func (*SyncMessage_PniIdentity) Descriptor() ([]byte, []int) { + return file_SignalService_proto_rawDescGZIP(), []int{11, 11} +} + +func (x *SyncMessage_PniIdentity) GetPublicKey() []byte { + if x != nil { + return x.PublicKey + } + return nil +} + +func (x *SyncMessage_PniIdentity) GetPrivateKey() []byte { + if x != nil { + return x.PrivateKey + } + return nil +} + type SyncMessage_MessageRequestResponse struct { state protoimpl.MessageState `protogen:"open.v1"` ThreadAci *string `protobuf:"bytes,2,opt,name=threadAci" json:"threadAci,omitempty"` @@ -6293,7 +6359,7 @@ type SyncMessage_MessageRequestResponse struct { func (x *SyncMessage_MessageRequestResponse) Reset() { *x = SyncMessage_MessageRequestResponse{} - mi := &file_SignalService_proto_msgTypes[60] + mi := &file_SignalService_proto_msgTypes[61] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6305,7 +6371,7 @@ func (x *SyncMessage_MessageRequestResponse) String() string { func (*SyncMessage_MessageRequestResponse) ProtoMessage() {} func (x *SyncMessage_MessageRequestResponse) ProtoReflect() protoreflect.Message { - mi := &file_SignalService_proto_msgTypes[60] + mi := &file_SignalService_proto_msgTypes[61] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6318,7 +6384,7 @@ func (x *SyncMessage_MessageRequestResponse) ProtoReflect() protoreflect.Message // Deprecated: Use SyncMessage_MessageRequestResponse.ProtoReflect.Descriptor instead. func (*SyncMessage_MessageRequestResponse) Descriptor() ([]byte, []int) { - return file_SignalService_proto_rawDescGZIP(), []int{12, 11} + return file_SignalService_proto_rawDescGZIP(), []int{11, 12} } func (x *SyncMessage_MessageRequestResponse) GetThreadAci() string { @@ -6346,17 +6412,17 @@ type SyncMessage_OutgoingPayment struct { state protoimpl.MessageState `protogen:"open.v1"` RecipientServiceId *string `protobuf:"bytes,1,opt,name=recipientServiceId" json:"recipientServiceId,omitempty"` Note *string `protobuf:"bytes,2,opt,name=note" json:"note,omitempty"` - // Types that are valid to be assigned to PaymentDetail: + // Types that are valid to be assigned to AttachmentIdentifier: // // *SyncMessage_OutgoingPayment_MobileCoin_ - PaymentDetail isSyncMessage_OutgoingPayment_PaymentDetail `protobuf_oneof:"paymentDetail"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache + AttachmentIdentifier isSyncMessage_OutgoingPayment_AttachmentIdentifier `protobuf_oneof:"attachment_identifier"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } func (x *SyncMessage_OutgoingPayment) Reset() { *x = SyncMessage_OutgoingPayment{} - mi := &file_SignalService_proto_msgTypes[61] + mi := &file_SignalService_proto_msgTypes[62] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6368,7 +6434,7 @@ func (x *SyncMessage_OutgoingPayment) String() string { func (*SyncMessage_OutgoingPayment) ProtoMessage() {} func (x *SyncMessage_OutgoingPayment) ProtoReflect() protoreflect.Message { - mi := &file_SignalService_proto_msgTypes[61] + mi := &file_SignalService_proto_msgTypes[62] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6381,7 +6447,7 @@ func (x *SyncMessage_OutgoingPayment) ProtoReflect() protoreflect.Message { // Deprecated: Use SyncMessage_OutgoingPayment.ProtoReflect.Descriptor instead. func (*SyncMessage_OutgoingPayment) Descriptor() ([]byte, []int) { - return file_SignalService_proto_rawDescGZIP(), []int{12, 12} + return file_SignalService_proto_rawDescGZIP(), []int{11, 13} } func (x *SyncMessage_OutgoingPayment) GetRecipientServiceId() string { @@ -6398,31 +6464,32 @@ func (x *SyncMessage_OutgoingPayment) GetNote() string { return "" } -func (x *SyncMessage_OutgoingPayment) GetPaymentDetail() isSyncMessage_OutgoingPayment_PaymentDetail { +func (x *SyncMessage_OutgoingPayment) GetAttachmentIdentifier() isSyncMessage_OutgoingPayment_AttachmentIdentifier { if x != nil { - return x.PaymentDetail + return x.AttachmentIdentifier } return nil } func (x *SyncMessage_OutgoingPayment) GetMobileCoin() *SyncMessage_OutgoingPayment_MobileCoin { if x != nil { - if x, ok := x.PaymentDetail.(*SyncMessage_OutgoingPayment_MobileCoin_); ok { + if x, ok := x.AttachmentIdentifier.(*SyncMessage_OutgoingPayment_MobileCoin_); ok { return x.MobileCoin } } return nil } -type isSyncMessage_OutgoingPayment_PaymentDetail interface { - isSyncMessage_OutgoingPayment_PaymentDetail() +type isSyncMessage_OutgoingPayment_AttachmentIdentifier interface { + isSyncMessage_OutgoingPayment_AttachmentIdentifier() } type SyncMessage_OutgoingPayment_MobileCoin_ struct { MobileCoin *SyncMessage_OutgoingPayment_MobileCoin `protobuf:"bytes,3,opt,name=mobileCoin,oneof"` } -func (*SyncMessage_OutgoingPayment_MobileCoin_) isSyncMessage_OutgoingPayment_PaymentDetail() {} +func (*SyncMessage_OutgoingPayment_MobileCoin_) isSyncMessage_OutgoingPayment_AttachmentIdentifier() { +} type SyncMessage_PniChangeNumber struct { state protoimpl.MessageState `protogen:"open.v1"` @@ -6437,7 +6504,7 @@ type SyncMessage_PniChangeNumber struct { func (x *SyncMessage_PniChangeNumber) Reset() { *x = SyncMessage_PniChangeNumber{} - mi := &file_SignalService_proto_msgTypes[62] + mi := &file_SignalService_proto_msgTypes[63] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6449,7 +6516,7 @@ func (x *SyncMessage_PniChangeNumber) String() string { func (*SyncMessage_PniChangeNumber) ProtoMessage() {} func (x *SyncMessage_PniChangeNumber) ProtoReflect() protoreflect.Message { - mi := &file_SignalService_proto_msgTypes[62] + mi := &file_SignalService_proto_msgTypes[63] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6462,7 +6529,7 @@ func (x *SyncMessage_PniChangeNumber) ProtoReflect() protoreflect.Message { // Deprecated: Use SyncMessage_PniChangeNumber.ProtoReflect.Descriptor instead. func (*SyncMessage_PniChangeNumber) Descriptor() ([]byte, []int) { - return file_SignalService_proto_rawDescGZIP(), []int{12, 13} + return file_SignalService_proto_rawDescGZIP(), []int{11, 14} } func (x *SyncMessage_PniChangeNumber) GetIdentityKeyPair() []byte { @@ -6501,20 +6568,25 @@ func (x *SyncMessage_PniChangeNumber) GetNewE164() string { } type SyncMessage_CallEvent struct { - state protoimpl.MessageState `protogen:"open.v1"` - ConversationId []byte `protobuf:"bytes,1,opt,name=conversationId" json:"conversationId,omitempty"` - Id *uint64 `protobuf:"varint,2,opt,name=id" json:"id,omitempty"` - Timestamp *uint64 `protobuf:"varint,3,opt,name=timestamp" json:"timestamp,omitempty"` - Type *SyncMessage_CallEvent_Type `protobuf:"varint,4,opt,name=type,enum=signalservice.SyncMessage_CallEvent_Type" json:"type,omitempty"` - Direction *SyncMessage_CallEvent_Direction `protobuf:"varint,5,opt,name=direction,enum=signalservice.SyncMessage_CallEvent_Direction" json:"direction,omitempty"` - Event *SyncMessage_CallEvent_Event `protobuf:"varint,6,opt,name=event,enum=signalservice.SyncMessage_CallEvent_Event" json:"event,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` + // Data identifying a conversation. The service ID for 1:1, the group ID for + // group, or the room ID for an ad-hoc call. See also + // `CallLogEvent/conversationId`. + ConversationId []byte `protobuf:"bytes,1,opt,name=conversationId" json:"conversationId,omitempty"` + // An identifier for a call. Generated directly for 1:1, or derived from + // the era ID for group and ad-hoc calls. See also `CallLogEvent/callId`. + CallId *uint64 `protobuf:"varint,2,opt,name=callId" json:"callId,omitempty"` + Timestamp *uint64 `protobuf:"varint,3,opt,name=timestamp" json:"timestamp,omitempty"` + Type *SyncMessage_CallEvent_Type `protobuf:"varint,4,opt,name=type,enum=signalservice.SyncMessage_CallEvent_Type" json:"type,omitempty"` + Direction *SyncMessage_CallEvent_Direction `protobuf:"varint,5,opt,name=direction,enum=signalservice.SyncMessage_CallEvent_Direction" json:"direction,omitempty"` + Event *SyncMessage_CallEvent_Event `protobuf:"varint,6,opt,name=event,enum=signalservice.SyncMessage_CallEvent_Event" json:"event,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } func (x *SyncMessage_CallEvent) Reset() { *x = SyncMessage_CallEvent{} - mi := &file_SignalService_proto_msgTypes[63] + mi := &file_SignalService_proto_msgTypes[64] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6526,7 +6598,7 @@ func (x *SyncMessage_CallEvent) String() string { func (*SyncMessage_CallEvent) ProtoMessage() {} func (x *SyncMessage_CallEvent) ProtoReflect() protoreflect.Message { - mi := &file_SignalService_proto_msgTypes[63] + mi := &file_SignalService_proto_msgTypes[64] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6539,7 +6611,7 @@ func (x *SyncMessage_CallEvent) ProtoReflect() protoreflect.Message { // Deprecated: Use SyncMessage_CallEvent.ProtoReflect.Descriptor instead. func (*SyncMessage_CallEvent) Descriptor() ([]byte, []int) { - return file_SignalService_proto_rawDescGZIP(), []int{12, 14} + return file_SignalService_proto_rawDescGZIP(), []int{11, 15} } func (x *SyncMessage_CallEvent) GetConversationId() []byte { @@ -6549,9 +6621,9 @@ func (x *SyncMessage_CallEvent) GetConversationId() []byte { return nil } -func (x *SyncMessage_CallEvent) GetId() uint64 { - if x != nil && x.Id != nil { - return *x.Id +func (x *SyncMessage_CallEvent) GetCallId() uint64 { + if x != nil && x.CallId != nil { + return *x.CallId } return 0 } @@ -6581,21 +6653,21 @@ func (x *SyncMessage_CallEvent) GetEvent() SyncMessage_CallEvent_Event { if x != nil && x.Event != nil { return *x.Event } - return SyncMessage_CallEvent_UNKNOWN_ACTION + return SyncMessage_CallEvent_UNKNOWN_EVENT } type SyncMessage_CallLinkUpdate struct { state protoimpl.MessageState `protogen:"open.v1"` RootKey []byte `protobuf:"bytes,1,opt,name=rootKey" json:"rootKey,omitempty"` - AdminPassKey []byte `protobuf:"bytes,2,opt,name=adminPassKey" json:"adminPassKey,omitempty"` - Type *SyncMessage_CallLinkUpdate_Type `protobuf:"varint,3,opt,name=type,enum=signalservice.SyncMessage_CallLinkUpdate_Type" json:"type,omitempty"` + AdminPasskey []byte `protobuf:"bytes,2,opt,name=adminPasskey" json:"adminPasskey,omitempty"` + Type *SyncMessage_CallLinkUpdate_Type `protobuf:"varint,3,opt,name=type,enum=signalservice.SyncMessage_CallLinkUpdate_Type" json:"type,omitempty"` // defaults to UPDATE unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } func (x *SyncMessage_CallLinkUpdate) Reset() { *x = SyncMessage_CallLinkUpdate{} - mi := &file_SignalService_proto_msgTypes[64] + mi := &file_SignalService_proto_msgTypes[65] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6607,7 +6679,7 @@ func (x *SyncMessage_CallLinkUpdate) String() string { func (*SyncMessage_CallLinkUpdate) ProtoMessage() {} func (x *SyncMessage_CallLinkUpdate) ProtoReflect() protoreflect.Message { - mi := &file_SignalService_proto_msgTypes[64] + mi := &file_SignalService_proto_msgTypes[65] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6620,7 +6692,7 @@ func (x *SyncMessage_CallLinkUpdate) ProtoReflect() protoreflect.Message { // Deprecated: Use SyncMessage_CallLinkUpdate.ProtoReflect.Descriptor instead. func (*SyncMessage_CallLinkUpdate) Descriptor() ([]byte, []int) { - return file_SignalService_proto_rawDescGZIP(), []int{12, 15} + return file_SignalService_proto_rawDescGZIP(), []int{11, 16} } func (x *SyncMessage_CallLinkUpdate) GetRootKey() []byte { @@ -6630,9 +6702,9 @@ func (x *SyncMessage_CallLinkUpdate) GetRootKey() []byte { return nil } -func (x *SyncMessage_CallLinkUpdate) GetAdminPassKey() []byte { +func (x *SyncMessage_CallLinkUpdate) GetAdminPasskey() []byte { if x != nil { - return x.AdminPassKey + return x.AdminPasskey } return nil } @@ -6661,7 +6733,7 @@ type SyncMessage_CallLogEvent struct { func (x *SyncMessage_CallLogEvent) Reset() { *x = SyncMessage_CallLogEvent{} - mi := &file_SignalService_proto_msgTypes[65] + mi := &file_SignalService_proto_msgTypes[66] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6673,7 +6745,7 @@ func (x *SyncMessage_CallLogEvent) String() string { func (*SyncMessage_CallLogEvent) ProtoMessage() {} func (x *SyncMessage_CallLogEvent) ProtoReflect() protoreflect.Message { - mi := &file_SignalService_proto_msgTypes[65] + mi := &file_SignalService_proto_msgTypes[66] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6686,7 +6758,7 @@ func (x *SyncMessage_CallLogEvent) ProtoReflect() protoreflect.Message { // Deprecated: Use SyncMessage_CallLogEvent.ProtoReflect.Descriptor instead. func (*SyncMessage_CallLogEvent) Descriptor() ([]byte, []int) { - return file_SignalService_proto_rawDescGZIP(), []int{12, 16} + return file_SignalService_proto_rawDescGZIP(), []int{11, 17} } func (x *SyncMessage_CallLogEvent) GetType() SyncMessage_CallLogEvent_Type { @@ -6729,7 +6801,7 @@ type SyncMessage_DeleteForMe struct { func (x *SyncMessage_DeleteForMe) Reset() { *x = SyncMessage_DeleteForMe{} - mi := &file_SignalService_proto_msgTypes[66] + mi := &file_SignalService_proto_msgTypes[67] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6741,7 +6813,7 @@ func (x *SyncMessage_DeleteForMe) String() string { func (*SyncMessage_DeleteForMe) ProtoMessage() {} func (x *SyncMessage_DeleteForMe) ProtoReflect() protoreflect.Message { - mi := &file_SignalService_proto_msgTypes[66] + mi := &file_SignalService_proto_msgTypes[67] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6754,7 +6826,7 @@ func (x *SyncMessage_DeleteForMe) ProtoReflect() protoreflect.Message { // Deprecated: Use SyncMessage_DeleteForMe.ProtoReflect.Descriptor instead. func (*SyncMessage_DeleteForMe) Descriptor() ([]byte, []int) { - return file_SignalService_proto_rawDescGZIP(), []int{12, 17} + return file_SignalService_proto_rawDescGZIP(), []int{11, 18} } func (x *SyncMessage_DeleteForMe) GetMessageDeletes() []*SyncMessage_DeleteForMe_MessageDeletes { @@ -6794,7 +6866,7 @@ type SyncMessage_DeviceNameChange struct { func (x *SyncMessage_DeviceNameChange) Reset() { *x = SyncMessage_DeviceNameChange{} - mi := &file_SignalService_proto_msgTypes[67] + mi := &file_SignalService_proto_msgTypes[68] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6806,7 +6878,7 @@ func (x *SyncMessage_DeviceNameChange) String() string { func (*SyncMessage_DeviceNameChange) ProtoMessage() {} func (x *SyncMessage_DeviceNameChange) ProtoReflect() protoreflect.Message { - mi := &file_SignalService_proto_msgTypes[67] + mi := &file_SignalService_proto_msgTypes[68] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6819,7 +6891,7 @@ func (x *SyncMessage_DeviceNameChange) ProtoReflect() protoreflect.Message { // Deprecated: Use SyncMessage_DeviceNameChange.ProtoReflect.Descriptor instead. func (*SyncMessage_DeviceNameChange) Descriptor() ([]byte, []int) { - return file_SignalService_proto_rawDescGZIP(), []int{12, 18} + return file_SignalService_proto_rawDescGZIP(), []int{11, 19} } func (x *SyncMessage_DeviceNameChange) GetDeviceId() uint32 { @@ -6829,18 +6901,170 @@ func (x *SyncMessage_DeviceNameChange) GetDeviceId() uint32 { return 0 } +type SyncMessage_AttachmentBackfillRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + TargetMessage *AddressableMessage `protobuf:"bytes,1,opt,name=targetMessage" json:"targetMessage,omitempty"` + TargetConversation *ConversationIdentifier `protobuf:"bytes,2,opt,name=targetConversation" json:"targetConversation,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *SyncMessage_AttachmentBackfillRequest) Reset() { + *x = SyncMessage_AttachmentBackfillRequest{} + mi := &file_SignalService_proto_msgTypes[69] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *SyncMessage_AttachmentBackfillRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SyncMessage_AttachmentBackfillRequest) ProtoMessage() {} + +func (x *SyncMessage_AttachmentBackfillRequest) ProtoReflect() protoreflect.Message { + mi := &file_SignalService_proto_msgTypes[69] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use SyncMessage_AttachmentBackfillRequest.ProtoReflect.Descriptor instead. +func (*SyncMessage_AttachmentBackfillRequest) Descriptor() ([]byte, []int) { + return file_SignalService_proto_rawDescGZIP(), []int{11, 20} +} + +func (x *SyncMessage_AttachmentBackfillRequest) GetTargetMessage() *AddressableMessage { + if x != nil { + return x.TargetMessage + } + return nil +} + +func (x *SyncMessage_AttachmentBackfillRequest) GetTargetConversation() *ConversationIdentifier { + if x != nil { + return x.TargetConversation + } + return nil +} + +type SyncMessage_AttachmentBackfillResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + TargetMessage *AddressableMessage `protobuf:"bytes,1,opt,name=targetMessage" json:"targetMessage,omitempty"` + TargetConversation *ConversationIdentifier `protobuf:"bytes,2,opt,name=targetConversation" json:"targetConversation,omitempty"` + // Types that are valid to be assigned to Data: + // + // *SyncMessage_AttachmentBackfillResponse_Attachments + // *SyncMessage_AttachmentBackfillResponse_Error_ + Data isSyncMessage_AttachmentBackfillResponse_Data `protobuf_oneof:"data"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *SyncMessage_AttachmentBackfillResponse) Reset() { + *x = SyncMessage_AttachmentBackfillResponse{} + mi := &file_SignalService_proto_msgTypes[70] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *SyncMessage_AttachmentBackfillResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SyncMessage_AttachmentBackfillResponse) ProtoMessage() {} + +func (x *SyncMessage_AttachmentBackfillResponse) ProtoReflect() protoreflect.Message { + mi := &file_SignalService_proto_msgTypes[70] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use SyncMessage_AttachmentBackfillResponse.ProtoReflect.Descriptor instead. +func (*SyncMessage_AttachmentBackfillResponse) Descriptor() ([]byte, []int) { + return file_SignalService_proto_rawDescGZIP(), []int{11, 21} +} + +func (x *SyncMessage_AttachmentBackfillResponse) GetTargetMessage() *AddressableMessage { + if x != nil { + return x.TargetMessage + } + return nil +} + +func (x *SyncMessage_AttachmentBackfillResponse) GetTargetConversation() *ConversationIdentifier { + if x != nil { + return x.TargetConversation + } + return nil +} + +func (x *SyncMessage_AttachmentBackfillResponse) GetData() isSyncMessage_AttachmentBackfillResponse_Data { + if x != nil { + return x.Data + } + return nil +} + +func (x *SyncMessage_AttachmentBackfillResponse) GetAttachments() *SyncMessage_AttachmentBackfillResponse_AttachmentDataList { + if x != nil { + if x, ok := x.Data.(*SyncMessage_AttachmentBackfillResponse_Attachments); ok { + return x.Attachments + } + } + return nil +} + +func (x *SyncMessage_AttachmentBackfillResponse) GetError() SyncMessage_AttachmentBackfillResponse_Error { + if x != nil { + if x, ok := x.Data.(*SyncMessage_AttachmentBackfillResponse_Error_); ok { + return x.Error + } + } + return SyncMessage_AttachmentBackfillResponse_MESSAGE_NOT_FOUND +} + +type isSyncMessage_AttachmentBackfillResponse_Data interface { + isSyncMessage_AttachmentBackfillResponse_Data() +} + +type SyncMessage_AttachmentBackfillResponse_Attachments struct { + Attachments *SyncMessage_AttachmentBackfillResponse_AttachmentDataList `protobuf:"bytes,3,opt,name=attachments,oneof"` +} + +type SyncMessage_AttachmentBackfillResponse_Error_ struct { + Error SyncMessage_AttachmentBackfillResponse_Error `protobuf:"varint,4,opt,name=error,enum=signalservice.SyncMessage_AttachmentBackfillResponse_Error,oneof"` +} + +func (*SyncMessage_AttachmentBackfillResponse_Attachments) isSyncMessage_AttachmentBackfillResponse_Data() { +} + +func (*SyncMessage_AttachmentBackfillResponse_Error_) isSyncMessage_AttachmentBackfillResponse_Data() { +} + type SyncMessage_Sent_UnidentifiedDeliveryStatus struct { - state protoimpl.MessageState `protogen:"open.v1"` - DestinationServiceId *string `protobuf:"bytes,3,opt,name=destinationServiceId" json:"destinationServiceId,omitempty"` - Unidentified *bool `protobuf:"varint,2,opt,name=unidentified" json:"unidentified,omitempty"` - DestinationIdentityKey []byte `protobuf:"bytes,5,opt,name=destinationIdentityKey" json:"destinationIdentityKey,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` + DestinationServiceId *string `protobuf:"bytes,3,opt,name=destinationServiceId" json:"destinationServiceId,omitempty"` + Unidentified *bool `protobuf:"varint,2,opt,name=unidentified" json:"unidentified,omitempty"` + DestinationPniIdentityKey []byte `protobuf:"bytes,5,opt,name=destinationPniIdentityKey" json:"destinationPniIdentityKey,omitempty"` // Only set for PNI destinations + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } func (x *SyncMessage_Sent_UnidentifiedDeliveryStatus) Reset() { *x = SyncMessage_Sent_UnidentifiedDeliveryStatus{} - mi := &file_SignalService_proto_msgTypes[68] + mi := &file_SignalService_proto_msgTypes[71] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6852,7 +7076,7 @@ func (x *SyncMessage_Sent_UnidentifiedDeliveryStatus) String() string { func (*SyncMessage_Sent_UnidentifiedDeliveryStatus) ProtoMessage() {} func (x *SyncMessage_Sent_UnidentifiedDeliveryStatus) ProtoReflect() protoreflect.Message { - mi := &file_SignalService_proto_msgTypes[68] + mi := &file_SignalService_proto_msgTypes[71] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6865,7 +7089,7 @@ func (x *SyncMessage_Sent_UnidentifiedDeliveryStatus) ProtoReflect() protoreflec // Deprecated: Use SyncMessage_Sent_UnidentifiedDeliveryStatus.ProtoReflect.Descriptor instead. func (*SyncMessage_Sent_UnidentifiedDeliveryStatus) Descriptor() ([]byte, []int) { - return file_SignalService_proto_rawDescGZIP(), []int{12, 0, 0} + return file_SignalService_proto_rawDescGZIP(), []int{11, 0, 0} } func (x *SyncMessage_Sent_UnidentifiedDeliveryStatus) GetDestinationServiceId() string { @@ -6882,9 +7106,9 @@ func (x *SyncMessage_Sent_UnidentifiedDeliveryStatus) GetUnidentified() bool { return false } -func (x *SyncMessage_Sent_UnidentifiedDeliveryStatus) GetDestinationIdentityKey() []byte { +func (x *SyncMessage_Sent_UnidentifiedDeliveryStatus) GetDestinationPniIdentityKey() []byte { if x != nil { - return x.DestinationIdentityKey + return x.DestinationPniIdentityKey } return nil } @@ -6900,7 +7124,7 @@ type SyncMessage_Sent_StoryMessageRecipient struct { func (x *SyncMessage_Sent_StoryMessageRecipient) Reset() { *x = SyncMessage_Sent_StoryMessageRecipient{} - mi := &file_SignalService_proto_msgTypes[69] + mi := &file_SignalService_proto_msgTypes[72] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6912,7 +7136,7 @@ func (x *SyncMessage_Sent_StoryMessageRecipient) String() string { func (*SyncMessage_Sent_StoryMessageRecipient) ProtoMessage() {} func (x *SyncMessage_Sent_StoryMessageRecipient) ProtoReflect() protoreflect.Message { - mi := &file_SignalService_proto_msgTypes[69] + mi := &file_SignalService_proto_msgTypes[72] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6925,7 +7149,7 @@ func (x *SyncMessage_Sent_StoryMessageRecipient) ProtoReflect() protoreflect.Mes // Deprecated: Use SyncMessage_Sent_StoryMessageRecipient.ProtoReflect.Descriptor instead. func (*SyncMessage_Sent_StoryMessageRecipient) Descriptor() ([]byte, []int) { - return file_SignalService_proto_rawDescGZIP(), []int{12, 0, 1} + return file_SignalService_proto_rawDescGZIP(), []int{11, 0, 1} } func (x *SyncMessage_Sent_StoryMessageRecipient) GetDestinationServiceId() string { @@ -6950,25 +7174,22 @@ func (x *SyncMessage_Sent_StoryMessageRecipient) GetIsAllowedToReply() bool { } type SyncMessage_OutgoingPayment_MobileCoin struct { - state protoimpl.MessageState `protogen:"open.v1"` - RecipientAddress []byte `protobuf:"bytes,1,opt,name=recipientAddress" json:"recipientAddress,omitempty"` - // @required - AmountPicoMob *uint64 `protobuf:"varint,2,opt,name=amountPicoMob" json:"amountPicoMob,omitempty"` - // @required - FeePicoMob *uint64 `protobuf:"varint,3,opt,name=feePicoMob" json:"feePicoMob,omitempty"` - Receipt []byte `protobuf:"bytes,4,opt,name=receipt" json:"receipt,omitempty"` - LedgerBlockTimestamp *uint64 `protobuf:"varint,5,opt,name=ledgerBlockTimestamp" json:"ledgerBlockTimestamp,omitempty"` - // @required - LedgerBlockIndex *uint64 `protobuf:"varint,6,opt,name=ledgerBlockIndex" json:"ledgerBlockIndex,omitempty"` - SpentKeyImages [][]byte `protobuf:"bytes,7,rep,name=spentKeyImages" json:"spentKeyImages,omitempty"` - OutputPublicKeys [][]byte `protobuf:"bytes,8,rep,name=outputPublicKeys" json:"outputPublicKeys,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` + RecipientAddress []byte `protobuf:"bytes,1,opt,name=recipientAddress" json:"recipientAddress,omitempty"` + AmountPicoMob *uint64 `protobuf:"varint,2,opt,name=amountPicoMob" json:"amountPicoMob,omitempty"` + FeePicoMob *uint64 `protobuf:"varint,3,opt,name=feePicoMob" json:"feePicoMob,omitempty"` + Receipt []byte `protobuf:"bytes,4,opt,name=receipt" json:"receipt,omitempty"` + LedgerBlockTimestamp *uint64 `protobuf:"varint,5,opt,name=ledgerBlockTimestamp" json:"ledgerBlockTimestamp,omitempty"` + LedgerBlockIndex *uint64 `protobuf:"varint,6,opt,name=ledgerBlockIndex" json:"ledgerBlockIndex,omitempty"` + SpentKeyImages [][]byte `protobuf:"bytes,7,rep,name=spentKeyImages" json:"spentKeyImages,omitempty"` + OutputPublicKeys [][]byte `protobuf:"bytes,8,rep,name=outputPublicKeys" json:"outputPublicKeys,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } func (x *SyncMessage_OutgoingPayment_MobileCoin) Reset() { *x = SyncMessage_OutgoingPayment_MobileCoin{} - mi := &file_SignalService_proto_msgTypes[70] + mi := &file_SignalService_proto_msgTypes[73] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6980,7 +7201,7 @@ func (x *SyncMessage_OutgoingPayment_MobileCoin) String() string { func (*SyncMessage_OutgoingPayment_MobileCoin) ProtoMessage() {} func (x *SyncMessage_OutgoingPayment_MobileCoin) ProtoReflect() protoreflect.Message { - mi := &file_SignalService_proto_msgTypes[70] + mi := &file_SignalService_proto_msgTypes[73] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6993,7 +7214,7 @@ func (x *SyncMessage_OutgoingPayment_MobileCoin) ProtoReflect() protoreflect.Mes // Deprecated: Use SyncMessage_OutgoingPayment_MobileCoin.ProtoReflect.Descriptor instead. func (*SyncMessage_OutgoingPayment_MobileCoin) Descriptor() ([]byte, []int) { - return file_SignalService_proto_rawDescGZIP(), []int{12, 12, 0} + return file_SignalService_proto_rawDescGZIP(), []int{11, 13, 0} } func (x *SyncMessage_OutgoingPayment_MobileCoin) GetRecipientAddress() []byte { @@ -7052,210 +7273,17 @@ func (x *SyncMessage_OutgoingPayment_MobileCoin) GetOutputPublicKeys() [][]byte return nil } -type SyncMessage_DeleteForMe_ConversationIdentifier struct { - state protoimpl.MessageState `protogen:"open.v1"` - // Types that are valid to be assigned to Identifier: - // - // *SyncMessage_DeleteForMe_ConversationIdentifier_ThreadServiceId - // *SyncMessage_DeleteForMe_ConversationIdentifier_ThreadGroupId - // *SyncMessage_DeleteForMe_ConversationIdentifier_ThreadE164 - Identifier isSyncMessage_DeleteForMe_ConversationIdentifier_Identifier `protobuf_oneof:"identifier"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache -} - -func (x *SyncMessage_DeleteForMe_ConversationIdentifier) Reset() { - *x = SyncMessage_DeleteForMe_ConversationIdentifier{} - mi := &file_SignalService_proto_msgTypes[71] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) -} - -func (x *SyncMessage_DeleteForMe_ConversationIdentifier) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*SyncMessage_DeleteForMe_ConversationIdentifier) ProtoMessage() {} - -func (x *SyncMessage_DeleteForMe_ConversationIdentifier) ProtoReflect() protoreflect.Message { - mi := &file_SignalService_proto_msgTypes[71] - if x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use SyncMessage_DeleteForMe_ConversationIdentifier.ProtoReflect.Descriptor instead. -func (*SyncMessage_DeleteForMe_ConversationIdentifier) Descriptor() ([]byte, []int) { - return file_SignalService_proto_rawDescGZIP(), []int{12, 17, 0} -} - -func (x *SyncMessage_DeleteForMe_ConversationIdentifier) GetIdentifier() isSyncMessage_DeleteForMe_ConversationIdentifier_Identifier { - if x != nil { - return x.Identifier - } - return nil -} - -func (x *SyncMessage_DeleteForMe_ConversationIdentifier) GetThreadServiceId() string { - if x != nil { - if x, ok := x.Identifier.(*SyncMessage_DeleteForMe_ConversationIdentifier_ThreadServiceId); ok { - return x.ThreadServiceId - } - } - return "" -} - -func (x *SyncMessage_DeleteForMe_ConversationIdentifier) GetThreadGroupId() []byte { - if x != nil { - if x, ok := x.Identifier.(*SyncMessage_DeleteForMe_ConversationIdentifier_ThreadGroupId); ok { - return x.ThreadGroupId - } - } - return nil -} - -func (x *SyncMessage_DeleteForMe_ConversationIdentifier) GetThreadE164() string { - if x != nil { - if x, ok := x.Identifier.(*SyncMessage_DeleteForMe_ConversationIdentifier_ThreadE164); ok { - return x.ThreadE164 - } - } - return "" -} - -type isSyncMessage_DeleteForMe_ConversationIdentifier_Identifier interface { - isSyncMessage_DeleteForMe_ConversationIdentifier_Identifier() -} - -type SyncMessage_DeleteForMe_ConversationIdentifier_ThreadServiceId struct { - ThreadServiceId string `protobuf:"bytes,1,opt,name=threadServiceId,oneof"` -} - -type SyncMessage_DeleteForMe_ConversationIdentifier_ThreadGroupId struct { - ThreadGroupId []byte `protobuf:"bytes,2,opt,name=threadGroupId,oneof"` -} - -type SyncMessage_DeleteForMe_ConversationIdentifier_ThreadE164 struct { - ThreadE164 string `protobuf:"bytes,3,opt,name=threadE164,oneof"` -} - -func (*SyncMessage_DeleteForMe_ConversationIdentifier_ThreadServiceId) isSyncMessage_DeleteForMe_ConversationIdentifier_Identifier() { -} - -func (*SyncMessage_DeleteForMe_ConversationIdentifier_ThreadGroupId) isSyncMessage_DeleteForMe_ConversationIdentifier_Identifier() { -} - -func (*SyncMessage_DeleteForMe_ConversationIdentifier_ThreadE164) isSyncMessage_DeleteForMe_ConversationIdentifier_Identifier() { -} - -type SyncMessage_DeleteForMe_AddressableMessage struct { - state protoimpl.MessageState `protogen:"open.v1"` - // Types that are valid to be assigned to Author: - // - // *SyncMessage_DeleteForMe_AddressableMessage_AuthorServiceId - // *SyncMessage_DeleteForMe_AddressableMessage_AuthorE164 - Author isSyncMessage_DeleteForMe_AddressableMessage_Author `protobuf_oneof:"author"` - SentTimestamp *uint64 `protobuf:"varint,3,opt,name=sentTimestamp" json:"sentTimestamp,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache -} - -func (x *SyncMessage_DeleteForMe_AddressableMessage) Reset() { - *x = SyncMessage_DeleteForMe_AddressableMessage{} - mi := &file_SignalService_proto_msgTypes[72] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) -} - -func (x *SyncMessage_DeleteForMe_AddressableMessage) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*SyncMessage_DeleteForMe_AddressableMessage) ProtoMessage() {} - -func (x *SyncMessage_DeleteForMe_AddressableMessage) ProtoReflect() protoreflect.Message { - mi := &file_SignalService_proto_msgTypes[72] - if x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use SyncMessage_DeleteForMe_AddressableMessage.ProtoReflect.Descriptor instead. -func (*SyncMessage_DeleteForMe_AddressableMessage) Descriptor() ([]byte, []int) { - return file_SignalService_proto_rawDescGZIP(), []int{12, 17, 1} -} - -func (x *SyncMessage_DeleteForMe_AddressableMessage) GetAuthor() isSyncMessage_DeleteForMe_AddressableMessage_Author { - if x != nil { - return x.Author - } - return nil -} - -func (x *SyncMessage_DeleteForMe_AddressableMessage) GetAuthorServiceId() string { - if x != nil { - if x, ok := x.Author.(*SyncMessage_DeleteForMe_AddressableMessage_AuthorServiceId); ok { - return x.AuthorServiceId - } - } - return "" -} - -func (x *SyncMessage_DeleteForMe_AddressableMessage) GetAuthorE164() string { - if x != nil { - if x, ok := x.Author.(*SyncMessage_DeleteForMe_AddressableMessage_AuthorE164); ok { - return x.AuthorE164 - } - } - return "" -} - -func (x *SyncMessage_DeleteForMe_AddressableMessage) GetSentTimestamp() uint64 { - if x != nil && x.SentTimestamp != nil { - return *x.SentTimestamp - } - return 0 -} - -type isSyncMessage_DeleteForMe_AddressableMessage_Author interface { - isSyncMessage_DeleteForMe_AddressableMessage_Author() -} - -type SyncMessage_DeleteForMe_AddressableMessage_AuthorServiceId struct { - AuthorServiceId string `protobuf:"bytes,1,opt,name=authorServiceId,oneof"` -} - -type SyncMessage_DeleteForMe_AddressableMessage_AuthorE164 struct { - AuthorE164 string `protobuf:"bytes,2,opt,name=authorE164,oneof"` -} - -func (*SyncMessage_DeleteForMe_AddressableMessage_AuthorServiceId) isSyncMessage_DeleteForMe_AddressableMessage_Author() { -} - -func (*SyncMessage_DeleteForMe_AddressableMessage_AuthorE164) isSyncMessage_DeleteForMe_AddressableMessage_Author() { -} - type SyncMessage_DeleteForMe_MessageDeletes struct { - state protoimpl.MessageState `protogen:"open.v1"` - Conversation *SyncMessage_DeleteForMe_ConversationIdentifier `protobuf:"bytes,1,opt,name=conversation" json:"conversation,omitempty"` - Messages []*SyncMessage_DeleteForMe_AddressableMessage `protobuf:"bytes,2,rep,name=messages" json:"messages,omitempty"` + state protoimpl.MessageState `protogen:"open.v1"` + Conversation *ConversationIdentifier `protobuf:"bytes,1,opt,name=conversation" json:"conversation,omitempty"` + Messages []*AddressableMessage `protobuf:"bytes,2,rep,name=messages" json:"messages,omitempty"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } func (x *SyncMessage_DeleteForMe_MessageDeletes) Reset() { *x = SyncMessage_DeleteForMe_MessageDeletes{} - mi := &file_SignalService_proto_msgTypes[73] + mi := &file_SignalService_proto_msgTypes[74] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7267,7 +7295,7 @@ func (x *SyncMessage_DeleteForMe_MessageDeletes) String() string { func (*SyncMessage_DeleteForMe_MessageDeletes) ProtoMessage() {} func (x *SyncMessage_DeleteForMe_MessageDeletes) ProtoReflect() protoreflect.Message { - mi := &file_SignalService_proto_msgTypes[73] + mi := &file_SignalService_proto_msgTypes[74] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7280,17 +7308,17 @@ func (x *SyncMessage_DeleteForMe_MessageDeletes) ProtoReflect() protoreflect.Mes // Deprecated: Use SyncMessage_DeleteForMe_MessageDeletes.ProtoReflect.Descriptor instead. func (*SyncMessage_DeleteForMe_MessageDeletes) Descriptor() ([]byte, []int) { - return file_SignalService_proto_rawDescGZIP(), []int{12, 17, 2} + return file_SignalService_proto_rawDescGZIP(), []int{11, 18, 0} } -func (x *SyncMessage_DeleteForMe_MessageDeletes) GetConversation() *SyncMessage_DeleteForMe_ConversationIdentifier { +func (x *SyncMessage_DeleteForMe_MessageDeletes) GetConversation() *ConversationIdentifier { if x != nil { return x.Conversation } return nil } -func (x *SyncMessage_DeleteForMe_MessageDeletes) GetMessages() []*SyncMessage_DeleteForMe_AddressableMessage { +func (x *SyncMessage_DeleteForMe_MessageDeletes) GetMessages() []*AddressableMessage { if x != nil { return x.Messages } @@ -7298,19 +7326,22 @@ func (x *SyncMessage_DeleteForMe_MessageDeletes) GetMessages() []*SyncMessage_De } type SyncMessage_DeleteForMe_AttachmentDelete struct { - state protoimpl.MessageState `protogen:"open.v1"` - Conversation *SyncMessage_DeleteForMe_ConversationIdentifier `protobuf:"bytes,1,opt,name=conversation" json:"conversation,omitempty"` - TargetMessage *SyncMessage_DeleteForMe_AddressableMessage `protobuf:"bytes,2,opt,name=targetMessage" json:"targetMessage,omitempty"` - Uuid []byte `protobuf:"bytes,3,opt,name=uuid" json:"uuid,omitempty"` // The `uuid` from the `Attachment`. - FallbackDigest []byte `protobuf:"bytes,4,opt,name=fallbackDigest" json:"fallbackDigest,omitempty"` - FallbackPlaintextHash []byte `protobuf:"bytes,5,opt,name=fallbackPlaintextHash" json:"fallbackPlaintextHash,omitempty"` + state protoimpl.MessageState `protogen:"open.v1"` + Conversation *ConversationIdentifier `protobuf:"bytes,1,opt,name=conversation" json:"conversation,omitempty"` + TargetMessage *AddressableMessage `protobuf:"bytes,2,opt,name=targetMessage" json:"targetMessage,omitempty"` + // The `clientUuid` from `AttachmentPointer`. + ClientUuid []byte `protobuf:"bytes,3,opt,name=clientUuid" json:"clientUuid,omitempty"` + // SHA256 hash of the (encrypted, padded, etc.) attachment blob on the CDN. + FallbackDigest []byte `protobuf:"bytes,4,opt,name=fallbackDigest" json:"fallbackDigest,omitempty"` + // SHA256 hash of the plaintext content of the attachment. + FallbackPlaintextHash []byte `protobuf:"bytes,5,opt,name=fallbackPlaintextHash" json:"fallbackPlaintextHash,omitempty"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } func (x *SyncMessage_DeleteForMe_AttachmentDelete) Reset() { *x = SyncMessage_DeleteForMe_AttachmentDelete{} - mi := &file_SignalService_proto_msgTypes[74] + mi := &file_SignalService_proto_msgTypes[75] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7322,7 +7353,7 @@ func (x *SyncMessage_DeleteForMe_AttachmentDelete) String() string { func (*SyncMessage_DeleteForMe_AttachmentDelete) ProtoMessage() {} func (x *SyncMessage_DeleteForMe_AttachmentDelete) ProtoReflect() protoreflect.Message { - mi := &file_SignalService_proto_msgTypes[74] + mi := &file_SignalService_proto_msgTypes[75] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7335,26 +7366,26 @@ func (x *SyncMessage_DeleteForMe_AttachmentDelete) ProtoReflect() protoreflect.M // Deprecated: Use SyncMessage_DeleteForMe_AttachmentDelete.ProtoReflect.Descriptor instead. func (*SyncMessage_DeleteForMe_AttachmentDelete) Descriptor() ([]byte, []int) { - return file_SignalService_proto_rawDescGZIP(), []int{12, 17, 3} + return file_SignalService_proto_rawDescGZIP(), []int{11, 18, 1} } -func (x *SyncMessage_DeleteForMe_AttachmentDelete) GetConversation() *SyncMessage_DeleteForMe_ConversationIdentifier { +func (x *SyncMessage_DeleteForMe_AttachmentDelete) GetConversation() *ConversationIdentifier { if x != nil { return x.Conversation } return nil } -func (x *SyncMessage_DeleteForMe_AttachmentDelete) GetTargetMessage() *SyncMessage_DeleteForMe_AddressableMessage { +func (x *SyncMessage_DeleteForMe_AttachmentDelete) GetTargetMessage() *AddressableMessage { if x != nil { return x.TargetMessage } return nil } -func (x *SyncMessage_DeleteForMe_AttachmentDelete) GetUuid() []byte { +func (x *SyncMessage_DeleteForMe_AttachmentDelete) GetClientUuid() []byte { if x != nil { - return x.Uuid + return x.ClientUuid } return nil } @@ -7374,18 +7405,18 @@ func (x *SyncMessage_DeleteForMe_AttachmentDelete) GetFallbackPlaintextHash() [] } type SyncMessage_DeleteForMe_ConversationDelete struct { - state protoimpl.MessageState `protogen:"open.v1"` - Conversation *SyncMessage_DeleteForMe_ConversationIdentifier `protobuf:"bytes,1,opt,name=conversation" json:"conversation,omitempty"` - MostRecentMessages []*SyncMessage_DeleteForMe_AddressableMessage `protobuf:"bytes,2,rep,name=mostRecentMessages" json:"mostRecentMessages,omitempty"` - MostRecentNonExpiringMessages []*SyncMessage_DeleteForMe_AddressableMessage `protobuf:"bytes,4,rep,name=mostRecentNonExpiringMessages" json:"mostRecentNonExpiringMessages,omitempty"` - IsFullDelete *bool `protobuf:"varint,3,opt,name=isFullDelete" json:"isFullDelete,omitempty"` + state protoimpl.MessageState `protogen:"open.v1"` + Conversation *ConversationIdentifier `protobuf:"bytes,1,opt,name=conversation" json:"conversation,omitempty"` + MostRecentMessages []*AddressableMessage `protobuf:"bytes,2,rep,name=mostRecentMessages" json:"mostRecentMessages,omitempty"` + IsFullDelete *bool `protobuf:"varint,3,opt,name=isFullDelete" json:"isFullDelete,omitempty"` + MostRecentNonExpiringMessages []*AddressableMessage `protobuf:"bytes,4,rep,name=mostRecentNonExpiringMessages" json:"mostRecentNonExpiringMessages,omitempty"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } func (x *SyncMessage_DeleteForMe_ConversationDelete) Reset() { *x = SyncMessage_DeleteForMe_ConversationDelete{} - mi := &file_SignalService_proto_msgTypes[75] + mi := &file_SignalService_proto_msgTypes[76] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7397,7 +7428,7 @@ func (x *SyncMessage_DeleteForMe_ConversationDelete) String() string { func (*SyncMessage_DeleteForMe_ConversationDelete) ProtoMessage() {} func (x *SyncMessage_DeleteForMe_ConversationDelete) ProtoReflect() protoreflect.Message { - mi := &file_SignalService_proto_msgTypes[75] + mi := &file_SignalService_proto_msgTypes[76] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7410,30 +7441,23 @@ func (x *SyncMessage_DeleteForMe_ConversationDelete) ProtoReflect() protoreflect // Deprecated: Use SyncMessage_DeleteForMe_ConversationDelete.ProtoReflect.Descriptor instead. func (*SyncMessage_DeleteForMe_ConversationDelete) Descriptor() ([]byte, []int) { - return file_SignalService_proto_rawDescGZIP(), []int{12, 17, 4} + return file_SignalService_proto_rawDescGZIP(), []int{11, 18, 2} } -func (x *SyncMessage_DeleteForMe_ConversationDelete) GetConversation() *SyncMessage_DeleteForMe_ConversationIdentifier { +func (x *SyncMessage_DeleteForMe_ConversationDelete) GetConversation() *ConversationIdentifier { if x != nil { return x.Conversation } return nil } -func (x *SyncMessage_DeleteForMe_ConversationDelete) GetMostRecentMessages() []*SyncMessage_DeleteForMe_AddressableMessage { +func (x *SyncMessage_DeleteForMe_ConversationDelete) GetMostRecentMessages() []*AddressableMessage { if x != nil { return x.MostRecentMessages } return nil } -func (x *SyncMessage_DeleteForMe_ConversationDelete) GetMostRecentNonExpiringMessages() []*SyncMessage_DeleteForMe_AddressableMessage { - if x != nil { - return x.MostRecentNonExpiringMessages - } - return nil -} - func (x *SyncMessage_DeleteForMe_ConversationDelete) GetIsFullDelete() bool { if x != nil && x.IsFullDelete != nil { return *x.IsFullDelete @@ -7441,16 +7465,23 @@ func (x *SyncMessage_DeleteForMe_ConversationDelete) GetIsFullDelete() bool { return false } +func (x *SyncMessage_DeleteForMe_ConversationDelete) GetMostRecentNonExpiringMessages() []*AddressableMessage { + if x != nil { + return x.MostRecentNonExpiringMessages + } + return nil +} + type SyncMessage_DeleteForMe_LocalOnlyConversationDelete struct { - state protoimpl.MessageState `protogen:"open.v1"` - Conversation *SyncMessage_DeleteForMe_ConversationIdentifier `protobuf:"bytes,1,opt,name=conversation" json:"conversation,omitempty"` + state protoimpl.MessageState `protogen:"open.v1"` + Conversation *ConversationIdentifier `protobuf:"bytes,1,opt,name=conversation" json:"conversation,omitempty"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } func (x *SyncMessage_DeleteForMe_LocalOnlyConversationDelete) Reset() { *x = SyncMessage_DeleteForMe_LocalOnlyConversationDelete{} - mi := &file_SignalService_proto_msgTypes[76] + mi := &file_SignalService_proto_msgTypes[77] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7462,7 +7493,7 @@ func (x *SyncMessage_DeleteForMe_LocalOnlyConversationDelete) String() string { func (*SyncMessage_DeleteForMe_LocalOnlyConversationDelete) ProtoMessage() {} func (x *SyncMessage_DeleteForMe_LocalOnlyConversationDelete) ProtoReflect() protoreflect.Message { - mi := &file_SignalService_proto_msgTypes[76] + mi := &file_SignalService_proto_msgTypes[77] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7475,38 +7506,42 @@ func (x *SyncMessage_DeleteForMe_LocalOnlyConversationDelete) ProtoReflect() pro // Deprecated: Use SyncMessage_DeleteForMe_LocalOnlyConversationDelete.ProtoReflect.Descriptor instead. func (*SyncMessage_DeleteForMe_LocalOnlyConversationDelete) Descriptor() ([]byte, []int) { - return file_SignalService_proto_rawDescGZIP(), []int{12, 17, 5} + return file_SignalService_proto_rawDescGZIP(), []int{11, 18, 3} } -func (x *SyncMessage_DeleteForMe_LocalOnlyConversationDelete) GetConversation() *SyncMessage_DeleteForMe_ConversationIdentifier { +func (x *SyncMessage_DeleteForMe_LocalOnlyConversationDelete) GetConversation() *ConversationIdentifier { if x != nil { return x.Conversation } return nil } -type GroupContext_Member struct { - state protoimpl.MessageState `protogen:"open.v1"` - E164 *string `protobuf:"bytes,2,opt,name=e164" json:"e164,omitempty"` +type SyncMessage_AttachmentBackfillResponse_AttachmentData struct { + state protoimpl.MessageState `protogen:"open.v1"` + // Types that are valid to be assigned to Data: + // + // *SyncMessage_AttachmentBackfillResponse_AttachmentData_Attachment + // *SyncMessage_AttachmentBackfillResponse_AttachmentData_Status_ + Data isSyncMessage_AttachmentBackfillResponse_AttachmentData_Data `protobuf_oneof:"data"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } -func (x *GroupContext_Member) Reset() { - *x = GroupContext_Member{} - mi := &file_SignalService_proto_msgTypes[77] +func (x *SyncMessage_AttachmentBackfillResponse_AttachmentData) Reset() { + *x = SyncMessage_AttachmentBackfillResponse_AttachmentData{} + mi := &file_SignalService_proto_msgTypes[78] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } -func (x *GroupContext_Member) String() string { +func (x *SyncMessage_AttachmentBackfillResponse_AttachmentData) String() string { return protoimpl.X.MessageStringOf(x) } -func (*GroupContext_Member) ProtoMessage() {} +func (*SyncMessage_AttachmentBackfillResponse_AttachmentData) ProtoMessage() {} -func (x *GroupContext_Member) ProtoReflect() protoreflect.Message { - mi := &file_SignalService_proto_msgTypes[77] +func (x *SyncMessage_AttachmentBackfillResponse_AttachmentData) ProtoReflect() protoreflect.Message { + mi := &file_SignalService_proto_msgTypes[78] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7517,16 +7552,104 @@ func (x *GroupContext_Member) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use GroupContext_Member.ProtoReflect.Descriptor instead. -func (*GroupContext_Member) Descriptor() ([]byte, []int) { - return file_SignalService_proto_rawDescGZIP(), []int{14, 0} +// Deprecated: Use SyncMessage_AttachmentBackfillResponse_AttachmentData.ProtoReflect.Descriptor instead. +func (*SyncMessage_AttachmentBackfillResponse_AttachmentData) Descriptor() ([]byte, []int) { + return file_SignalService_proto_rawDescGZIP(), []int{11, 21, 0} } -func (x *GroupContext_Member) GetE164() string { - if x != nil && x.E164 != nil { - return *x.E164 +func (x *SyncMessage_AttachmentBackfillResponse_AttachmentData) GetData() isSyncMessage_AttachmentBackfillResponse_AttachmentData_Data { + if x != nil { + return x.Data } - return "" + return nil +} + +func (x *SyncMessage_AttachmentBackfillResponse_AttachmentData) GetAttachment() *AttachmentPointer { + if x != nil { + if x, ok := x.Data.(*SyncMessage_AttachmentBackfillResponse_AttachmentData_Attachment); ok { + return x.Attachment + } + } + return nil +} + +func (x *SyncMessage_AttachmentBackfillResponse_AttachmentData) GetStatus() SyncMessage_AttachmentBackfillResponse_AttachmentData_Status { + if x != nil { + if x, ok := x.Data.(*SyncMessage_AttachmentBackfillResponse_AttachmentData_Status_); ok { + return x.Status + } + } + return SyncMessage_AttachmentBackfillResponse_AttachmentData_PENDING +} + +type isSyncMessage_AttachmentBackfillResponse_AttachmentData_Data interface { + isSyncMessage_AttachmentBackfillResponse_AttachmentData_Data() +} + +type SyncMessage_AttachmentBackfillResponse_AttachmentData_Attachment struct { + Attachment *AttachmentPointer `protobuf:"bytes,1,opt,name=attachment,oneof"` +} + +type SyncMessage_AttachmentBackfillResponse_AttachmentData_Status_ struct { + Status SyncMessage_AttachmentBackfillResponse_AttachmentData_Status `protobuf:"varint,2,opt,name=status,enum=signalservice.SyncMessage_AttachmentBackfillResponse_AttachmentData_Status,oneof"` +} + +func (*SyncMessage_AttachmentBackfillResponse_AttachmentData_Attachment) isSyncMessage_AttachmentBackfillResponse_AttachmentData_Data() { +} + +func (*SyncMessage_AttachmentBackfillResponse_AttachmentData_Status_) isSyncMessage_AttachmentBackfillResponse_AttachmentData_Data() { +} + +type SyncMessage_AttachmentBackfillResponse_AttachmentDataList struct { + state protoimpl.MessageState `protogen:"open.v1"` + Attachments []*SyncMessage_AttachmentBackfillResponse_AttachmentData `protobuf:"bytes,1,rep,name=attachments" json:"attachments,omitempty"` + LongText *SyncMessage_AttachmentBackfillResponse_AttachmentData `protobuf:"bytes,2,opt,name=longText" json:"longText,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *SyncMessage_AttachmentBackfillResponse_AttachmentDataList) Reset() { + *x = SyncMessage_AttachmentBackfillResponse_AttachmentDataList{} + mi := &file_SignalService_proto_msgTypes[79] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *SyncMessage_AttachmentBackfillResponse_AttachmentDataList) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SyncMessage_AttachmentBackfillResponse_AttachmentDataList) ProtoMessage() {} + +func (x *SyncMessage_AttachmentBackfillResponse_AttachmentDataList) ProtoReflect() protoreflect.Message { + mi := &file_SignalService_proto_msgTypes[79] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use SyncMessage_AttachmentBackfillResponse_AttachmentDataList.ProtoReflect.Descriptor instead. +func (*SyncMessage_AttachmentBackfillResponse_AttachmentDataList) Descriptor() ([]byte, []int) { + return file_SignalService_proto_rawDescGZIP(), []int{11, 21, 1} +} + +func (x *SyncMessage_AttachmentBackfillResponse_AttachmentDataList) GetAttachments() []*SyncMessage_AttachmentBackfillResponse_AttachmentData { + if x != nil { + return x.Attachments + } + return nil +} + +func (x *SyncMessage_AttachmentBackfillResponse_AttachmentDataList) GetLongText() *SyncMessage_AttachmentBackfillResponse_AttachmentData { + if x != nil { + return x.LongText + } + return nil } type ContactDetails_Avatar struct { @@ -7539,7 +7662,7 @@ type ContactDetails_Avatar struct { func (x *ContactDetails_Avatar) Reset() { *x = ContactDetails_Avatar{} - mi := &file_SignalService_proto_msgTypes[78] + mi := &file_SignalService_proto_msgTypes[80] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7551,7 +7674,7 @@ func (x *ContactDetails_Avatar) String() string { func (*ContactDetails_Avatar) ProtoMessage() {} func (x *ContactDetails_Avatar) ProtoReflect() protoreflect.Message { - mi := &file_SignalService_proto_msgTypes[78] + mi := &file_SignalService_proto_msgTypes[80] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7564,7 +7687,7 @@ func (x *ContactDetails_Avatar) ProtoReflect() protoreflect.Message { // Deprecated: Use ContactDetails_Avatar.ProtoReflect.Descriptor instead. func (*ContactDetails_Avatar) Descriptor() ([]byte, []int) { - return file_SignalService_proto_rawDescGZIP(), []int{16, 0} + return file_SignalService_proto_rawDescGZIP(), []int{14, 0} } func (x *ContactDetails_Avatar) GetContentType() string { @@ -7581,124 +7704,28 @@ func (x *ContactDetails_Avatar) GetLength() uint32 { return 0 } -type GroupDetails_Avatar struct { +type PaymentAddress_MobileCoin struct { state protoimpl.MessageState `protogen:"open.v1"` - ContentType *string `protobuf:"bytes,1,opt,name=contentType" json:"contentType,omitempty"` - Length *uint32 `protobuf:"varint,2,opt,name=length" json:"length,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache -} - -func (x *GroupDetails_Avatar) Reset() { - *x = GroupDetails_Avatar{} - mi := &file_SignalService_proto_msgTypes[79] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) -} - -func (x *GroupDetails_Avatar) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*GroupDetails_Avatar) ProtoMessage() {} - -func (x *GroupDetails_Avatar) ProtoReflect() protoreflect.Message { - mi := &file_SignalService_proto_msgTypes[79] - if x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use GroupDetails_Avatar.ProtoReflect.Descriptor instead. -func (*GroupDetails_Avatar) Descriptor() ([]byte, []int) { - return file_SignalService_proto_rawDescGZIP(), []int{17, 0} -} - -func (x *GroupDetails_Avatar) GetContentType() string { - if x != nil && x.ContentType != nil { - return *x.ContentType - } - return "" -} - -func (x *GroupDetails_Avatar) GetLength() uint32 { - if x != nil && x.Length != nil { - return *x.Length - } - return 0 -} - -type GroupDetails_Member struct { - state protoimpl.MessageState `protogen:"open.v1"` - E164 *string `protobuf:"bytes,2,opt,name=e164" json:"e164,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache -} - -func (x *GroupDetails_Member) Reset() { - *x = GroupDetails_Member{} - mi := &file_SignalService_proto_msgTypes[80] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) -} - -func (x *GroupDetails_Member) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*GroupDetails_Member) ProtoMessage() {} - -func (x *GroupDetails_Member) ProtoReflect() protoreflect.Message { - mi := &file_SignalService_proto_msgTypes[80] - if x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use GroupDetails_Member.ProtoReflect.Descriptor instead. -func (*GroupDetails_Member) Descriptor() ([]byte, []int) { - return file_SignalService_proto_rawDescGZIP(), []int{17, 1} -} - -func (x *GroupDetails_Member) GetE164() string { - if x != nil && x.E164 != nil { - return *x.E164 - } - return "" -} - -type PaymentAddress_MobileCoinAddress struct { - state protoimpl.MessageState `protogen:"open.v1"` - Address []byte `protobuf:"bytes,1,opt,name=address" json:"address,omitempty"` + PublicAddress []byte `protobuf:"bytes,1,opt,name=publicAddress" json:"publicAddress,omitempty"` Signature []byte `protobuf:"bytes,2,opt,name=signature" json:"signature,omitempty"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } -func (x *PaymentAddress_MobileCoinAddress) Reset() { - *x = PaymentAddress_MobileCoinAddress{} +func (x *PaymentAddress_MobileCoin) Reset() { + *x = PaymentAddress_MobileCoin{} mi := &file_SignalService_proto_msgTypes[81] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } -func (x *PaymentAddress_MobileCoinAddress) String() string { +func (x *PaymentAddress_MobileCoin) String() string { return protoimpl.X.MessageStringOf(x) } -func (*PaymentAddress_MobileCoinAddress) ProtoMessage() {} +func (*PaymentAddress_MobileCoin) ProtoMessage() {} -func (x *PaymentAddress_MobileCoinAddress) ProtoReflect() protoreflect.Message { +func (x *PaymentAddress_MobileCoin) ProtoReflect() protoreflect.Message { mi := &file_SignalService_proto_msgTypes[81] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -7710,19 +7737,19 @@ func (x *PaymentAddress_MobileCoinAddress) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use PaymentAddress_MobileCoinAddress.ProtoReflect.Descriptor instead. -func (*PaymentAddress_MobileCoinAddress) Descriptor() ([]byte, []int) { - return file_SignalService_proto_rawDescGZIP(), []int{18, 0} +// Deprecated: Use PaymentAddress_MobileCoin.ProtoReflect.Descriptor instead. +func (*PaymentAddress_MobileCoin) Descriptor() ([]byte, []int) { + return file_SignalService_proto_rawDescGZIP(), []int{15, 0} } -func (x *PaymentAddress_MobileCoinAddress) GetAddress() []byte { +func (x *PaymentAddress_MobileCoin) GetPublicAddress() []byte { if x != nil { - return x.Address + return x.PublicAddress } return nil } -func (x *PaymentAddress_MobileCoinAddress) GetSignature() []byte { +func (x *PaymentAddress_MobileCoin) GetSignature() []byte { if x != nil { return x.Signature } @@ -7746,245 +7773,252 @@ func file_SignalService_proto_rawDescGZIP() []byte { return file_SignalService_proto_rawDescData } -var file_SignalService_proto_enumTypes = make([]protoimpl.EnumInfo, 27) +var file_SignalService_proto_enumTypes = make([]protoimpl.EnumInfo, 28) var file_SignalService_proto_msgTypes = make([]protoimpl.MessageInfo, 82) var file_SignalService_proto_goTypes = []any{ - (Envelope_Type)(0), // 0: signalservice.Envelope.Type - (CallMessage_Offer_Type)(0), // 1: signalservice.CallMessage.Offer.Type - (CallMessage_Hangup_Type)(0), // 2: signalservice.CallMessage.Hangup.Type - (CallMessage_Opaque_Urgency)(0), // 3: signalservice.CallMessage.Opaque.Urgency - (BodyRange_Style)(0), // 4: signalservice.BodyRange.Style - (DataMessage_Flags)(0), // 5: signalservice.DataMessage.Flags - (DataMessage_ProtocolVersion)(0), // 6: signalservice.DataMessage.ProtocolVersion - (DataMessage_Quote_Type)(0), // 7: signalservice.DataMessage.Quote.Type - (DataMessage_Contact_Phone_Type)(0), // 8: signalservice.DataMessage.Contact.Phone.Type - (DataMessage_Contact_Email_Type)(0), // 9: signalservice.DataMessage.Contact.Email.Type - (DataMessage_Contact_PostalAddress_Type)(0), // 10: signalservice.DataMessage.Contact.PostalAddress.Type - (DataMessage_Payment_Activation_Type)(0), // 11: signalservice.DataMessage.Payment.Activation.Type - (ReceiptMessage_Type)(0), // 12: signalservice.ReceiptMessage.Type - (TypingMessage_Action)(0), // 13: signalservice.TypingMessage.Action - (TextAttachment_Style)(0), // 14: signalservice.TextAttachment.Style - (Verified_State)(0), // 15: signalservice.Verified.State - (SyncMessage_Request_Type)(0), // 16: signalservice.SyncMessage.Request.Type - (SyncMessage_StickerPackOperation_Type)(0), // 17: signalservice.SyncMessage.StickerPackOperation.Type - (SyncMessage_FetchLatest_Type)(0), // 18: signalservice.SyncMessage.FetchLatest.Type - (SyncMessage_MessageRequestResponse_Type)(0), // 19: signalservice.SyncMessage.MessageRequestResponse.Type - (SyncMessage_CallEvent_Type)(0), // 20: signalservice.SyncMessage.CallEvent.Type - (SyncMessage_CallEvent_Direction)(0), // 21: signalservice.SyncMessage.CallEvent.Direction - (SyncMessage_CallEvent_Event)(0), // 22: signalservice.SyncMessage.CallEvent.Event - (SyncMessage_CallLinkUpdate_Type)(0), // 23: signalservice.SyncMessage.CallLinkUpdate.Type - (SyncMessage_CallLogEvent_Type)(0), // 24: signalservice.SyncMessage.CallLogEvent.Type - (AttachmentPointer_Flags)(0), // 25: signalservice.AttachmentPointer.Flags - (GroupContext_Type)(0), // 26: signalservice.GroupContext.Type - (*Envelope)(nil), // 27: signalservice.Envelope - (*Content)(nil), // 28: signalservice.Content - (*CallMessage)(nil), // 29: signalservice.CallMessage - (*BodyRange)(nil), // 30: signalservice.BodyRange - (*DataMessage)(nil), // 31: signalservice.DataMessage - (*NullMessage)(nil), // 32: signalservice.NullMessage - (*ReceiptMessage)(nil), // 33: signalservice.ReceiptMessage - (*TypingMessage)(nil), // 34: signalservice.TypingMessage - (*StoryMessage)(nil), // 35: signalservice.StoryMessage - (*Preview)(nil), // 36: signalservice.Preview - (*TextAttachment)(nil), // 37: signalservice.TextAttachment - (*Verified)(nil), // 38: signalservice.Verified - (*SyncMessage)(nil), // 39: signalservice.SyncMessage - (*AttachmentPointer)(nil), // 40: signalservice.AttachmentPointer - (*GroupContext)(nil), // 41: signalservice.GroupContext - (*GroupContextV2)(nil), // 42: signalservice.GroupContextV2 - (*ContactDetails)(nil), // 43: signalservice.ContactDetails - (*GroupDetails)(nil), // 44: signalservice.GroupDetails - (*PaymentAddress)(nil), // 45: signalservice.PaymentAddress - (*DecryptionErrorMessage)(nil), // 46: signalservice.DecryptionErrorMessage - (*PniSignatureMessage)(nil), // 47: signalservice.PniSignatureMessage - (*EditMessage)(nil), // 48: signalservice.EditMessage - (*CallMessage_Offer)(nil), // 49: signalservice.CallMessage.Offer - (*CallMessage_Answer)(nil), // 50: signalservice.CallMessage.Answer - (*CallMessage_IceUpdate)(nil), // 51: signalservice.CallMessage.IceUpdate - (*CallMessage_Busy)(nil), // 52: signalservice.CallMessage.Busy - (*CallMessage_Hangup)(nil), // 53: signalservice.CallMessage.Hangup - (*CallMessage_Opaque)(nil), // 54: signalservice.CallMessage.Opaque - (*DataMessage_Quote)(nil), // 55: signalservice.DataMessage.Quote - (*DataMessage_Contact)(nil), // 56: signalservice.DataMessage.Contact - (*DataMessage_Sticker)(nil), // 57: signalservice.DataMessage.Sticker - (*DataMessage_Reaction)(nil), // 58: signalservice.DataMessage.Reaction - (*DataMessage_Delete)(nil), // 59: signalservice.DataMessage.Delete - (*DataMessage_GroupCallUpdate)(nil), // 60: signalservice.DataMessage.GroupCallUpdate - (*DataMessage_StoryContext)(nil), // 61: signalservice.DataMessage.StoryContext - (*DataMessage_Payment)(nil), // 62: signalservice.DataMessage.Payment - (*DataMessage_GiftBadge)(nil), // 63: signalservice.DataMessage.GiftBadge - (*DataMessage_Quote_QuotedAttachment)(nil), // 64: signalservice.DataMessage.Quote.QuotedAttachment - (*DataMessage_Contact_Name)(nil), // 65: signalservice.DataMessage.Contact.Name - (*DataMessage_Contact_Phone)(nil), // 66: signalservice.DataMessage.Contact.Phone - (*DataMessage_Contact_Email)(nil), // 67: signalservice.DataMessage.Contact.Email - (*DataMessage_Contact_PostalAddress)(nil), // 68: signalservice.DataMessage.Contact.PostalAddress - (*DataMessage_Contact_Avatar)(nil), // 69: signalservice.DataMessage.Contact.Avatar - (*DataMessage_Payment_Amount)(nil), // 70: signalservice.DataMessage.Payment.Amount - (*DataMessage_Payment_Notification)(nil), // 71: signalservice.DataMessage.Payment.Notification - (*DataMessage_Payment_Activation)(nil), // 72: signalservice.DataMessage.Payment.Activation - (*DataMessage_Payment_Amount_MobileCoin)(nil), // 73: signalservice.DataMessage.Payment.Amount.MobileCoin - (*DataMessage_Payment_Notification_MobileCoin)(nil), // 74: signalservice.DataMessage.Payment.Notification.MobileCoin - (*TextAttachment_Gradient)(nil), // 75: signalservice.TextAttachment.Gradient - (*SyncMessage_Sent)(nil), // 76: signalservice.SyncMessage.Sent - (*SyncMessage_Contacts)(nil), // 77: signalservice.SyncMessage.Contacts - (*SyncMessage_Blocked)(nil), // 78: signalservice.SyncMessage.Blocked - (*SyncMessage_Request)(nil), // 79: signalservice.SyncMessage.Request - (*SyncMessage_Read)(nil), // 80: signalservice.SyncMessage.Read - (*SyncMessage_Viewed)(nil), // 81: signalservice.SyncMessage.Viewed - (*SyncMessage_Configuration)(nil), // 82: signalservice.SyncMessage.Configuration - (*SyncMessage_StickerPackOperation)(nil), // 83: signalservice.SyncMessage.StickerPackOperation - (*SyncMessage_ViewOnceOpen)(nil), // 84: signalservice.SyncMessage.ViewOnceOpen - (*SyncMessage_FetchLatest)(nil), // 85: signalservice.SyncMessage.FetchLatest - (*SyncMessage_Keys)(nil), // 86: signalservice.SyncMessage.Keys - (*SyncMessage_MessageRequestResponse)(nil), // 87: signalservice.SyncMessage.MessageRequestResponse - (*SyncMessage_OutgoingPayment)(nil), // 88: signalservice.SyncMessage.OutgoingPayment - (*SyncMessage_PniChangeNumber)(nil), // 89: signalservice.SyncMessage.PniChangeNumber - (*SyncMessage_CallEvent)(nil), // 90: signalservice.SyncMessage.CallEvent - (*SyncMessage_CallLinkUpdate)(nil), // 91: signalservice.SyncMessage.CallLinkUpdate - (*SyncMessage_CallLogEvent)(nil), // 92: signalservice.SyncMessage.CallLogEvent - (*SyncMessage_DeleteForMe)(nil), // 93: signalservice.SyncMessage.DeleteForMe - (*SyncMessage_DeviceNameChange)(nil), // 94: signalservice.SyncMessage.DeviceNameChange - (*SyncMessage_Sent_UnidentifiedDeliveryStatus)(nil), // 95: signalservice.SyncMessage.Sent.UnidentifiedDeliveryStatus - (*SyncMessage_Sent_StoryMessageRecipient)(nil), // 96: signalservice.SyncMessage.Sent.StoryMessageRecipient - (*SyncMessage_OutgoingPayment_MobileCoin)(nil), // 97: signalservice.SyncMessage.OutgoingPayment.MobileCoin - (*SyncMessage_DeleteForMe_ConversationIdentifier)(nil), // 98: signalservice.SyncMessage.DeleteForMe.ConversationIdentifier - (*SyncMessage_DeleteForMe_AddressableMessage)(nil), // 99: signalservice.SyncMessage.DeleteForMe.AddressableMessage - (*SyncMessage_DeleteForMe_MessageDeletes)(nil), // 100: signalservice.SyncMessage.DeleteForMe.MessageDeletes - (*SyncMessage_DeleteForMe_AttachmentDelete)(nil), // 101: signalservice.SyncMessage.DeleteForMe.AttachmentDelete - (*SyncMessage_DeleteForMe_ConversationDelete)(nil), // 102: signalservice.SyncMessage.DeleteForMe.ConversationDelete - (*SyncMessage_DeleteForMe_LocalOnlyConversationDelete)(nil), // 103: signalservice.SyncMessage.DeleteForMe.LocalOnlyConversationDelete - (*GroupContext_Member)(nil), // 104: signalservice.GroupContext.Member - (*ContactDetails_Avatar)(nil), // 105: signalservice.ContactDetails.Avatar - (*GroupDetails_Avatar)(nil), // 106: signalservice.GroupDetails.Avatar - (*GroupDetails_Member)(nil), // 107: signalservice.GroupDetails.Member - (*PaymentAddress_MobileCoinAddress)(nil), // 108: signalservice.PaymentAddress.MobileCoinAddress + (Envelope_Type)(0), // 0: signalservice.Envelope.Type + (CallMessage_Offer_Type)(0), // 1: signalservice.CallMessage.Offer.Type + (CallMessage_Hangup_Type)(0), // 2: signalservice.CallMessage.Hangup.Type + (CallMessage_Opaque_Urgency)(0), // 3: signalservice.CallMessage.Opaque.Urgency + (DataMessage_Flags)(0), // 4: signalservice.DataMessage.Flags + (DataMessage_ProtocolVersion)(0), // 5: signalservice.DataMessage.ProtocolVersion + (DataMessage_Payment_Activation_Type)(0), // 6: signalservice.DataMessage.Payment.Activation.Type + (DataMessage_Quote_Type)(0), // 7: signalservice.DataMessage.Quote.Type + (DataMessage_Contact_Phone_Type)(0), // 8: signalservice.DataMessage.Contact.Phone.Type + (DataMessage_Contact_Email_Type)(0), // 9: signalservice.DataMessage.Contact.Email.Type + (DataMessage_Contact_PostalAddress_Type)(0), // 10: signalservice.DataMessage.Contact.PostalAddress.Type + (ReceiptMessage_Type)(0), // 11: signalservice.ReceiptMessage.Type + (TypingMessage_Action)(0), // 12: signalservice.TypingMessage.Action + (TextAttachment_Style)(0), // 13: signalservice.TextAttachment.Style + (Verified_State)(0), // 14: signalservice.Verified.State + (SyncMessage_Request_Type)(0), // 15: signalservice.SyncMessage.Request.Type + (SyncMessage_StickerPackOperation_Type)(0), // 16: signalservice.SyncMessage.StickerPackOperation.Type + (SyncMessage_FetchLatest_Type)(0), // 17: signalservice.SyncMessage.FetchLatest.Type + (SyncMessage_MessageRequestResponse_Type)(0), // 18: signalservice.SyncMessage.MessageRequestResponse.Type + (SyncMessage_CallEvent_Type)(0), // 19: signalservice.SyncMessage.CallEvent.Type + (SyncMessage_CallEvent_Direction)(0), // 20: signalservice.SyncMessage.CallEvent.Direction + (SyncMessage_CallEvent_Event)(0), // 21: signalservice.SyncMessage.CallEvent.Event + (SyncMessage_CallLinkUpdate_Type)(0), // 22: signalservice.SyncMessage.CallLinkUpdate.Type + (SyncMessage_CallLogEvent_Type)(0), // 23: signalservice.SyncMessage.CallLogEvent.Type + (SyncMessage_AttachmentBackfillResponse_Error)(0), // 24: signalservice.SyncMessage.AttachmentBackfillResponse.Error + (SyncMessage_AttachmentBackfillResponse_AttachmentData_Status)(0), // 25: signalservice.SyncMessage.AttachmentBackfillResponse.AttachmentData.Status + (AttachmentPointer_Flags)(0), // 26: signalservice.AttachmentPointer.Flags + (BodyRange_Style)(0), // 27: signalservice.BodyRange.Style + (*Envelope)(nil), // 28: signalservice.Envelope + (*Content)(nil), // 29: signalservice.Content + (*CallMessage)(nil), // 30: signalservice.CallMessage + (*DataMessage)(nil), // 31: signalservice.DataMessage + (*NullMessage)(nil), // 32: signalservice.NullMessage + (*ReceiptMessage)(nil), // 33: signalservice.ReceiptMessage + (*TypingMessage)(nil), // 34: signalservice.TypingMessage + (*StoryMessage)(nil), // 35: signalservice.StoryMessage + (*Preview)(nil), // 36: signalservice.Preview + (*TextAttachment)(nil), // 37: signalservice.TextAttachment + (*Verified)(nil), // 38: signalservice.Verified + (*SyncMessage)(nil), // 39: signalservice.SyncMessage + (*AttachmentPointer)(nil), // 40: signalservice.AttachmentPointer + (*GroupContextV2)(nil), // 41: signalservice.GroupContextV2 + (*ContactDetails)(nil), // 42: signalservice.ContactDetails + (*PaymentAddress)(nil), // 43: signalservice.PaymentAddress + (*DecryptionErrorMessage)(nil), // 44: signalservice.DecryptionErrorMessage + (*PniSignatureMessage)(nil), // 45: signalservice.PniSignatureMessage + (*EditMessage)(nil), // 46: signalservice.EditMessage + (*BodyRange)(nil), // 47: signalservice.BodyRange + (*AddressableMessage)(nil), // 48: signalservice.AddressableMessage + (*ConversationIdentifier)(nil), // 49: signalservice.ConversationIdentifier + (*CallMessage_Offer)(nil), // 50: signalservice.CallMessage.Offer + (*CallMessage_Answer)(nil), // 51: signalservice.CallMessage.Answer + (*CallMessage_IceUpdate)(nil), // 52: signalservice.CallMessage.IceUpdate + (*CallMessage_Busy)(nil), // 53: signalservice.CallMessage.Busy + (*CallMessage_Hangup)(nil), // 54: signalservice.CallMessage.Hangup + (*CallMessage_Opaque)(nil), // 55: signalservice.CallMessage.Opaque + (*DataMessage_Payment)(nil), // 56: signalservice.DataMessage.Payment + (*DataMessage_Quote)(nil), // 57: signalservice.DataMessage.Quote + (*DataMessage_Contact)(nil), // 58: signalservice.DataMessage.Contact + (*DataMessage_Sticker)(nil), // 59: signalservice.DataMessage.Sticker + (*DataMessage_Reaction)(nil), // 60: signalservice.DataMessage.Reaction + (*DataMessage_Delete)(nil), // 61: signalservice.DataMessage.Delete + (*DataMessage_GroupCallUpdate)(nil), // 62: signalservice.DataMessage.GroupCallUpdate + (*DataMessage_StoryContext)(nil), // 63: signalservice.DataMessage.StoryContext + (*DataMessage_GiftBadge)(nil), // 64: signalservice.DataMessage.GiftBadge + (*DataMessage_Payment_Amount)(nil), // 65: signalservice.DataMessage.Payment.Amount + (*DataMessage_Payment_Notification)(nil), // 66: signalservice.DataMessage.Payment.Notification + (*DataMessage_Payment_Activation)(nil), // 67: signalservice.DataMessage.Payment.Activation + (*DataMessage_Payment_Amount_MobileCoin)(nil), // 68: signalservice.DataMessage.Payment.Amount.MobileCoin + (*DataMessage_Payment_Notification_MobileCoin)(nil), // 69: signalservice.DataMessage.Payment.Notification.MobileCoin + (*DataMessage_Quote_QuotedAttachment)(nil), // 70: signalservice.DataMessage.Quote.QuotedAttachment + (*DataMessage_Contact_Name)(nil), // 71: signalservice.DataMessage.Contact.Name + (*DataMessage_Contact_Phone)(nil), // 72: signalservice.DataMessage.Contact.Phone + (*DataMessage_Contact_Email)(nil), // 73: signalservice.DataMessage.Contact.Email + (*DataMessage_Contact_PostalAddress)(nil), // 74: signalservice.DataMessage.Contact.PostalAddress + (*DataMessage_Contact_Avatar)(nil), // 75: signalservice.DataMessage.Contact.Avatar + (*TextAttachment_Gradient)(nil), // 76: signalservice.TextAttachment.Gradient + (*SyncMessage_Sent)(nil), // 77: signalservice.SyncMessage.Sent + (*SyncMessage_Contacts)(nil), // 78: signalservice.SyncMessage.Contacts + (*SyncMessage_Blocked)(nil), // 79: signalservice.SyncMessage.Blocked + (*SyncMessage_Request)(nil), // 80: signalservice.SyncMessage.Request + (*SyncMessage_Read)(nil), // 81: signalservice.SyncMessage.Read + (*SyncMessage_Viewed)(nil), // 82: signalservice.SyncMessage.Viewed + (*SyncMessage_Configuration)(nil), // 83: signalservice.SyncMessage.Configuration + (*SyncMessage_StickerPackOperation)(nil), // 84: signalservice.SyncMessage.StickerPackOperation + (*SyncMessage_ViewOnceOpen)(nil), // 85: signalservice.SyncMessage.ViewOnceOpen + (*SyncMessage_FetchLatest)(nil), // 86: signalservice.SyncMessage.FetchLatest + (*SyncMessage_Keys)(nil), // 87: signalservice.SyncMessage.Keys + (*SyncMessage_PniIdentity)(nil), // 88: signalservice.SyncMessage.PniIdentity + (*SyncMessage_MessageRequestResponse)(nil), // 89: signalservice.SyncMessage.MessageRequestResponse + (*SyncMessage_OutgoingPayment)(nil), // 90: signalservice.SyncMessage.OutgoingPayment + (*SyncMessage_PniChangeNumber)(nil), // 91: signalservice.SyncMessage.PniChangeNumber + (*SyncMessage_CallEvent)(nil), // 92: signalservice.SyncMessage.CallEvent + (*SyncMessage_CallLinkUpdate)(nil), // 93: signalservice.SyncMessage.CallLinkUpdate + (*SyncMessage_CallLogEvent)(nil), // 94: signalservice.SyncMessage.CallLogEvent + (*SyncMessage_DeleteForMe)(nil), // 95: signalservice.SyncMessage.DeleteForMe + (*SyncMessage_DeviceNameChange)(nil), // 96: signalservice.SyncMessage.DeviceNameChange + (*SyncMessage_AttachmentBackfillRequest)(nil), // 97: signalservice.SyncMessage.AttachmentBackfillRequest + (*SyncMessage_AttachmentBackfillResponse)(nil), // 98: signalservice.SyncMessage.AttachmentBackfillResponse + (*SyncMessage_Sent_UnidentifiedDeliveryStatus)(nil), // 99: signalservice.SyncMessage.Sent.UnidentifiedDeliveryStatus + (*SyncMessage_Sent_StoryMessageRecipient)(nil), // 100: signalservice.SyncMessage.Sent.StoryMessageRecipient + (*SyncMessage_OutgoingPayment_MobileCoin)(nil), // 101: signalservice.SyncMessage.OutgoingPayment.MobileCoin + (*SyncMessage_DeleteForMe_MessageDeletes)(nil), // 102: signalservice.SyncMessage.DeleteForMe.MessageDeletes + (*SyncMessage_DeleteForMe_AttachmentDelete)(nil), // 103: signalservice.SyncMessage.DeleteForMe.AttachmentDelete + (*SyncMessage_DeleteForMe_ConversationDelete)(nil), // 104: signalservice.SyncMessage.DeleteForMe.ConversationDelete + (*SyncMessage_DeleteForMe_LocalOnlyConversationDelete)(nil), // 105: signalservice.SyncMessage.DeleteForMe.LocalOnlyConversationDelete + (*SyncMessage_AttachmentBackfillResponse_AttachmentData)(nil), // 106: signalservice.SyncMessage.AttachmentBackfillResponse.AttachmentData + (*SyncMessage_AttachmentBackfillResponse_AttachmentDataList)(nil), // 107: signalservice.SyncMessage.AttachmentBackfillResponse.AttachmentDataList + (*ContactDetails_Avatar)(nil), // 108: signalservice.ContactDetails.Avatar + (*PaymentAddress_MobileCoin)(nil), // 109: signalservice.PaymentAddress.MobileCoin } var file_SignalService_proto_depIdxs = []int32{ 0, // 0: signalservice.Envelope.type:type_name -> signalservice.Envelope.Type 31, // 1: signalservice.Content.dataMessage:type_name -> signalservice.DataMessage 39, // 2: signalservice.Content.syncMessage:type_name -> signalservice.SyncMessage - 29, // 3: signalservice.Content.callMessage:type_name -> signalservice.CallMessage + 30, // 3: signalservice.Content.callMessage:type_name -> signalservice.CallMessage 32, // 4: signalservice.Content.nullMessage:type_name -> signalservice.NullMessage 33, // 5: signalservice.Content.receiptMessage:type_name -> signalservice.ReceiptMessage 34, // 6: signalservice.Content.typingMessage:type_name -> signalservice.TypingMessage 35, // 7: signalservice.Content.storyMessage:type_name -> signalservice.StoryMessage - 47, // 8: signalservice.Content.pniSignatureMessage:type_name -> signalservice.PniSignatureMessage - 48, // 9: signalservice.Content.editMessage:type_name -> signalservice.EditMessage - 49, // 10: signalservice.CallMessage.offer:type_name -> signalservice.CallMessage.Offer - 50, // 11: signalservice.CallMessage.answer:type_name -> signalservice.CallMessage.Answer - 51, // 12: signalservice.CallMessage.iceUpdate:type_name -> signalservice.CallMessage.IceUpdate - 52, // 13: signalservice.CallMessage.busy:type_name -> signalservice.CallMessage.Busy - 53, // 14: signalservice.CallMessage.hangup:type_name -> signalservice.CallMessage.Hangup - 54, // 15: signalservice.CallMessage.opaque:type_name -> signalservice.CallMessage.Opaque - 4, // 16: signalservice.BodyRange.style:type_name -> signalservice.BodyRange.Style - 40, // 17: signalservice.DataMessage.attachments:type_name -> signalservice.AttachmentPointer - 42, // 18: signalservice.DataMessage.groupV2:type_name -> signalservice.GroupContextV2 - 55, // 19: signalservice.DataMessage.quote:type_name -> signalservice.DataMessage.Quote - 56, // 20: signalservice.DataMessage.contact:type_name -> signalservice.DataMessage.Contact - 36, // 21: signalservice.DataMessage.preview:type_name -> signalservice.Preview - 57, // 22: signalservice.DataMessage.sticker:type_name -> signalservice.DataMessage.Sticker - 58, // 23: signalservice.DataMessage.reaction:type_name -> signalservice.DataMessage.Reaction - 59, // 24: signalservice.DataMessage.delete:type_name -> signalservice.DataMessage.Delete - 30, // 25: signalservice.DataMessage.bodyRanges:type_name -> signalservice.BodyRange - 60, // 26: signalservice.DataMessage.groupCallUpdate:type_name -> signalservice.DataMessage.GroupCallUpdate - 62, // 27: signalservice.DataMessage.payment:type_name -> signalservice.DataMessage.Payment - 61, // 28: signalservice.DataMessage.storyContext:type_name -> signalservice.DataMessage.StoryContext - 63, // 29: signalservice.DataMessage.giftBadge:type_name -> signalservice.DataMessage.GiftBadge - 12, // 30: signalservice.ReceiptMessage.type:type_name -> signalservice.ReceiptMessage.Type - 13, // 31: signalservice.TypingMessage.action:type_name -> signalservice.TypingMessage.Action - 42, // 32: signalservice.StoryMessage.group:type_name -> signalservice.GroupContextV2 - 40, // 33: signalservice.StoryMessage.fileAttachment:type_name -> signalservice.AttachmentPointer - 37, // 34: signalservice.StoryMessage.textAttachment:type_name -> signalservice.TextAttachment - 30, // 35: signalservice.StoryMessage.bodyRanges:type_name -> signalservice.BodyRange - 40, // 36: signalservice.Preview.image:type_name -> signalservice.AttachmentPointer - 14, // 37: signalservice.TextAttachment.textStyle:type_name -> signalservice.TextAttachment.Style - 36, // 38: signalservice.TextAttachment.preview:type_name -> signalservice.Preview - 75, // 39: signalservice.TextAttachment.gradient:type_name -> signalservice.TextAttachment.Gradient - 15, // 40: signalservice.Verified.state:type_name -> signalservice.Verified.State - 76, // 41: signalservice.SyncMessage.sent:type_name -> signalservice.SyncMessage.Sent - 77, // 42: signalservice.SyncMessage.contacts:type_name -> signalservice.SyncMessage.Contacts - 79, // 43: signalservice.SyncMessage.request:type_name -> signalservice.SyncMessage.Request - 80, // 44: signalservice.SyncMessage.read:type_name -> signalservice.SyncMessage.Read - 78, // 45: signalservice.SyncMessage.blocked:type_name -> signalservice.SyncMessage.Blocked - 38, // 46: signalservice.SyncMessage.verified:type_name -> signalservice.Verified - 82, // 47: signalservice.SyncMessage.configuration:type_name -> signalservice.SyncMessage.Configuration - 83, // 48: signalservice.SyncMessage.stickerPackOperation:type_name -> signalservice.SyncMessage.StickerPackOperation - 84, // 49: signalservice.SyncMessage.viewOnceOpen:type_name -> signalservice.SyncMessage.ViewOnceOpen - 85, // 50: signalservice.SyncMessage.fetchLatest:type_name -> signalservice.SyncMessage.FetchLatest - 86, // 51: signalservice.SyncMessage.keys:type_name -> signalservice.SyncMessage.Keys - 87, // 52: signalservice.SyncMessage.messageRequestResponse:type_name -> signalservice.SyncMessage.MessageRequestResponse - 88, // 53: signalservice.SyncMessage.outgoingPayment:type_name -> signalservice.SyncMessage.OutgoingPayment - 81, // 54: signalservice.SyncMessage.viewed:type_name -> signalservice.SyncMessage.Viewed - 89, // 55: signalservice.SyncMessage.pniChangeNumber:type_name -> signalservice.SyncMessage.PniChangeNumber - 90, // 56: signalservice.SyncMessage.callEvent:type_name -> signalservice.SyncMessage.CallEvent - 91, // 57: signalservice.SyncMessage.callLinkUpdate:type_name -> signalservice.SyncMessage.CallLinkUpdate - 92, // 58: signalservice.SyncMessage.callLogEvent:type_name -> signalservice.SyncMessage.CallLogEvent - 93, // 59: signalservice.SyncMessage.deleteForMe:type_name -> signalservice.SyncMessage.DeleteForMe - 94, // 60: signalservice.SyncMessage.deviceNameChange:type_name -> signalservice.SyncMessage.DeviceNameChange - 26, // 61: signalservice.GroupContext.type:type_name -> signalservice.GroupContext.Type - 104, // 62: signalservice.GroupContext.members:type_name -> signalservice.GroupContext.Member - 40, // 63: signalservice.GroupContext.avatar:type_name -> signalservice.AttachmentPointer - 105, // 64: signalservice.ContactDetails.avatar:type_name -> signalservice.ContactDetails.Avatar - 38, // 65: signalservice.ContactDetails.verified:type_name -> signalservice.Verified - 107, // 66: signalservice.GroupDetails.members:type_name -> signalservice.GroupDetails.Member - 106, // 67: signalservice.GroupDetails.avatar:type_name -> signalservice.GroupDetails.Avatar - 108, // 68: signalservice.PaymentAddress.mobileCoinAddress:type_name -> signalservice.PaymentAddress.MobileCoinAddress - 31, // 69: signalservice.EditMessage.dataMessage:type_name -> signalservice.DataMessage - 1, // 70: signalservice.CallMessage.Offer.type:type_name -> signalservice.CallMessage.Offer.Type - 2, // 71: signalservice.CallMessage.Hangup.type:type_name -> signalservice.CallMessage.Hangup.Type - 3, // 72: signalservice.CallMessage.Opaque.urgency:type_name -> signalservice.CallMessage.Opaque.Urgency - 64, // 73: signalservice.DataMessage.Quote.attachments:type_name -> signalservice.DataMessage.Quote.QuotedAttachment - 30, // 74: signalservice.DataMessage.Quote.bodyRanges:type_name -> signalservice.BodyRange - 7, // 75: signalservice.DataMessage.Quote.type:type_name -> signalservice.DataMessage.Quote.Type - 65, // 76: signalservice.DataMessage.Contact.name:type_name -> signalservice.DataMessage.Contact.Name - 66, // 77: signalservice.DataMessage.Contact.number:type_name -> signalservice.DataMessage.Contact.Phone - 67, // 78: signalservice.DataMessage.Contact.email:type_name -> signalservice.DataMessage.Contact.Email - 68, // 79: signalservice.DataMessage.Contact.address:type_name -> signalservice.DataMessage.Contact.PostalAddress - 69, // 80: signalservice.DataMessage.Contact.avatar:type_name -> signalservice.DataMessage.Contact.Avatar - 40, // 81: signalservice.DataMessage.Sticker.data:type_name -> signalservice.AttachmentPointer - 71, // 82: signalservice.DataMessage.Payment.notification:type_name -> signalservice.DataMessage.Payment.Notification - 72, // 83: signalservice.DataMessage.Payment.activation:type_name -> signalservice.DataMessage.Payment.Activation - 40, // 84: signalservice.DataMessage.Quote.QuotedAttachment.thumbnail:type_name -> signalservice.AttachmentPointer - 8, // 85: signalservice.DataMessage.Contact.Phone.type:type_name -> signalservice.DataMessage.Contact.Phone.Type - 9, // 86: signalservice.DataMessage.Contact.Email.type:type_name -> signalservice.DataMessage.Contact.Email.Type - 10, // 87: signalservice.DataMessage.Contact.PostalAddress.type:type_name -> signalservice.DataMessage.Contact.PostalAddress.Type - 40, // 88: signalservice.DataMessage.Contact.Avatar.avatar:type_name -> signalservice.AttachmentPointer - 73, // 89: signalservice.DataMessage.Payment.Amount.mobileCoin:type_name -> signalservice.DataMessage.Payment.Amount.MobileCoin - 74, // 90: signalservice.DataMessage.Payment.Notification.mobileCoin:type_name -> signalservice.DataMessage.Payment.Notification.MobileCoin - 11, // 91: signalservice.DataMessage.Payment.Activation.type:type_name -> signalservice.DataMessage.Payment.Activation.Type - 31, // 92: signalservice.SyncMessage.Sent.message:type_name -> signalservice.DataMessage - 95, // 93: signalservice.SyncMessage.Sent.unidentifiedStatus:type_name -> signalservice.SyncMessage.Sent.UnidentifiedDeliveryStatus - 35, // 94: signalservice.SyncMessage.Sent.storyMessage:type_name -> signalservice.StoryMessage - 96, // 95: signalservice.SyncMessage.Sent.storyMessageRecipients:type_name -> signalservice.SyncMessage.Sent.StoryMessageRecipient - 48, // 96: signalservice.SyncMessage.Sent.editMessage:type_name -> signalservice.EditMessage - 40, // 97: signalservice.SyncMessage.Contacts.blob:type_name -> signalservice.AttachmentPointer - 16, // 98: signalservice.SyncMessage.Request.type:type_name -> signalservice.SyncMessage.Request.Type - 17, // 99: signalservice.SyncMessage.StickerPackOperation.type:type_name -> signalservice.SyncMessage.StickerPackOperation.Type - 18, // 100: signalservice.SyncMessage.FetchLatest.type:type_name -> signalservice.SyncMessage.FetchLatest.Type - 19, // 101: signalservice.SyncMessage.MessageRequestResponse.type:type_name -> signalservice.SyncMessage.MessageRequestResponse.Type - 97, // 102: signalservice.SyncMessage.OutgoingPayment.mobileCoin:type_name -> signalservice.SyncMessage.OutgoingPayment.MobileCoin - 20, // 103: signalservice.SyncMessage.CallEvent.type:type_name -> signalservice.SyncMessage.CallEvent.Type - 21, // 104: signalservice.SyncMessage.CallEvent.direction:type_name -> signalservice.SyncMessage.CallEvent.Direction - 22, // 105: signalservice.SyncMessage.CallEvent.event:type_name -> signalservice.SyncMessage.CallEvent.Event - 23, // 106: signalservice.SyncMessage.CallLinkUpdate.type:type_name -> signalservice.SyncMessage.CallLinkUpdate.Type - 24, // 107: signalservice.SyncMessage.CallLogEvent.type:type_name -> signalservice.SyncMessage.CallLogEvent.Type - 100, // 108: signalservice.SyncMessage.DeleteForMe.messageDeletes:type_name -> signalservice.SyncMessage.DeleteForMe.MessageDeletes - 102, // 109: signalservice.SyncMessage.DeleteForMe.conversationDeletes:type_name -> signalservice.SyncMessage.DeleteForMe.ConversationDelete - 103, // 110: signalservice.SyncMessage.DeleteForMe.localOnlyConversationDeletes:type_name -> signalservice.SyncMessage.DeleteForMe.LocalOnlyConversationDelete - 101, // 111: signalservice.SyncMessage.DeleteForMe.attachmentDeletes:type_name -> signalservice.SyncMessage.DeleteForMe.AttachmentDelete - 98, // 112: signalservice.SyncMessage.DeleteForMe.MessageDeletes.conversation:type_name -> signalservice.SyncMessage.DeleteForMe.ConversationIdentifier - 99, // 113: signalservice.SyncMessage.DeleteForMe.MessageDeletes.messages:type_name -> signalservice.SyncMessage.DeleteForMe.AddressableMessage - 98, // 114: signalservice.SyncMessage.DeleteForMe.AttachmentDelete.conversation:type_name -> signalservice.SyncMessage.DeleteForMe.ConversationIdentifier - 99, // 115: signalservice.SyncMessage.DeleteForMe.AttachmentDelete.targetMessage:type_name -> signalservice.SyncMessage.DeleteForMe.AddressableMessage - 98, // 116: signalservice.SyncMessage.DeleteForMe.ConversationDelete.conversation:type_name -> signalservice.SyncMessage.DeleteForMe.ConversationIdentifier - 99, // 117: signalservice.SyncMessage.DeleteForMe.ConversationDelete.mostRecentMessages:type_name -> signalservice.SyncMessage.DeleteForMe.AddressableMessage - 99, // 118: signalservice.SyncMessage.DeleteForMe.ConversationDelete.mostRecentNonExpiringMessages:type_name -> signalservice.SyncMessage.DeleteForMe.AddressableMessage - 98, // 119: signalservice.SyncMessage.DeleteForMe.LocalOnlyConversationDelete.conversation:type_name -> signalservice.SyncMessage.DeleteForMe.ConversationIdentifier - 120, // [120:120] is the sub-list for method output_type - 120, // [120:120] is the sub-list for method input_type - 120, // [120:120] is the sub-list for extension type_name - 120, // [120:120] is the sub-list for extension extendee - 0, // [0:120] is the sub-list for field type_name + 45, // 8: signalservice.Content.pniSignatureMessage:type_name -> signalservice.PniSignatureMessage + 46, // 9: signalservice.Content.editMessage:type_name -> signalservice.EditMessage + 50, // 10: signalservice.CallMessage.offer:type_name -> signalservice.CallMessage.Offer + 51, // 11: signalservice.CallMessage.answer:type_name -> signalservice.CallMessage.Answer + 52, // 12: signalservice.CallMessage.iceUpdate:type_name -> signalservice.CallMessage.IceUpdate + 53, // 13: signalservice.CallMessage.busy:type_name -> signalservice.CallMessage.Busy + 54, // 14: signalservice.CallMessage.hangup:type_name -> signalservice.CallMessage.Hangup + 55, // 15: signalservice.CallMessage.opaque:type_name -> signalservice.CallMessage.Opaque + 40, // 16: signalservice.DataMessage.attachments:type_name -> signalservice.AttachmentPointer + 41, // 17: signalservice.DataMessage.groupV2:type_name -> signalservice.GroupContextV2 + 57, // 18: signalservice.DataMessage.quote:type_name -> signalservice.DataMessage.Quote + 58, // 19: signalservice.DataMessage.contact:type_name -> signalservice.DataMessage.Contact + 36, // 20: signalservice.DataMessage.preview:type_name -> signalservice.Preview + 59, // 21: signalservice.DataMessage.sticker:type_name -> signalservice.DataMessage.Sticker + 60, // 22: signalservice.DataMessage.reaction:type_name -> signalservice.DataMessage.Reaction + 61, // 23: signalservice.DataMessage.delete:type_name -> signalservice.DataMessage.Delete + 47, // 24: signalservice.DataMessage.bodyRanges:type_name -> signalservice.BodyRange + 62, // 25: signalservice.DataMessage.groupCallUpdate:type_name -> signalservice.DataMessage.GroupCallUpdate + 56, // 26: signalservice.DataMessage.payment:type_name -> signalservice.DataMessage.Payment + 63, // 27: signalservice.DataMessage.storyContext:type_name -> signalservice.DataMessage.StoryContext + 64, // 28: signalservice.DataMessage.giftBadge:type_name -> signalservice.DataMessage.GiftBadge + 11, // 29: signalservice.ReceiptMessage.type:type_name -> signalservice.ReceiptMessage.Type + 12, // 30: signalservice.TypingMessage.action:type_name -> signalservice.TypingMessage.Action + 41, // 31: signalservice.StoryMessage.group:type_name -> signalservice.GroupContextV2 + 40, // 32: signalservice.StoryMessage.fileAttachment:type_name -> signalservice.AttachmentPointer + 37, // 33: signalservice.StoryMessage.textAttachment:type_name -> signalservice.TextAttachment + 47, // 34: signalservice.StoryMessage.bodyRanges:type_name -> signalservice.BodyRange + 40, // 35: signalservice.Preview.image:type_name -> signalservice.AttachmentPointer + 13, // 36: signalservice.TextAttachment.textStyle:type_name -> signalservice.TextAttachment.Style + 36, // 37: signalservice.TextAttachment.preview:type_name -> signalservice.Preview + 76, // 38: signalservice.TextAttachment.gradient:type_name -> signalservice.TextAttachment.Gradient + 14, // 39: signalservice.Verified.state:type_name -> signalservice.Verified.State + 77, // 40: signalservice.SyncMessage.sent:type_name -> signalservice.SyncMessage.Sent + 78, // 41: signalservice.SyncMessage.contacts:type_name -> signalservice.SyncMessage.Contacts + 80, // 42: signalservice.SyncMessage.request:type_name -> signalservice.SyncMessage.Request + 81, // 43: signalservice.SyncMessage.read:type_name -> signalservice.SyncMessage.Read + 79, // 44: signalservice.SyncMessage.blocked:type_name -> signalservice.SyncMessage.Blocked + 38, // 45: signalservice.SyncMessage.verified:type_name -> signalservice.Verified + 83, // 46: signalservice.SyncMessage.configuration:type_name -> signalservice.SyncMessage.Configuration + 84, // 47: signalservice.SyncMessage.stickerPackOperation:type_name -> signalservice.SyncMessage.StickerPackOperation + 85, // 48: signalservice.SyncMessage.viewOnceOpen:type_name -> signalservice.SyncMessage.ViewOnceOpen + 86, // 49: signalservice.SyncMessage.fetchLatest:type_name -> signalservice.SyncMessage.FetchLatest + 87, // 50: signalservice.SyncMessage.keys:type_name -> signalservice.SyncMessage.Keys + 89, // 51: signalservice.SyncMessage.messageRequestResponse:type_name -> signalservice.SyncMessage.MessageRequestResponse + 90, // 52: signalservice.SyncMessage.outgoingPayment:type_name -> signalservice.SyncMessage.OutgoingPayment + 82, // 53: signalservice.SyncMessage.viewed:type_name -> signalservice.SyncMessage.Viewed + 91, // 54: signalservice.SyncMessage.pniChangeNumber:type_name -> signalservice.SyncMessage.PniChangeNumber + 92, // 55: signalservice.SyncMessage.callEvent:type_name -> signalservice.SyncMessage.CallEvent + 93, // 56: signalservice.SyncMessage.callLinkUpdate:type_name -> signalservice.SyncMessage.CallLinkUpdate + 94, // 57: signalservice.SyncMessage.callLogEvent:type_name -> signalservice.SyncMessage.CallLogEvent + 95, // 58: signalservice.SyncMessage.deleteForMe:type_name -> signalservice.SyncMessage.DeleteForMe + 96, // 59: signalservice.SyncMessage.deviceNameChange:type_name -> signalservice.SyncMessage.DeviceNameChange + 97, // 60: signalservice.SyncMessage.attachmentBackfillRequest:type_name -> signalservice.SyncMessage.AttachmentBackfillRequest + 98, // 61: signalservice.SyncMessage.attachmentBackfillResponse:type_name -> signalservice.SyncMessage.AttachmentBackfillResponse + 108, // 62: signalservice.ContactDetails.avatar:type_name -> signalservice.ContactDetails.Avatar + 109, // 63: signalservice.PaymentAddress.mobileCoin:type_name -> signalservice.PaymentAddress.MobileCoin + 31, // 64: signalservice.EditMessage.dataMessage:type_name -> signalservice.DataMessage + 27, // 65: signalservice.BodyRange.style:type_name -> signalservice.BodyRange.Style + 1, // 66: signalservice.CallMessage.Offer.type:type_name -> signalservice.CallMessage.Offer.Type + 2, // 67: signalservice.CallMessage.Hangup.type:type_name -> signalservice.CallMessage.Hangup.Type + 3, // 68: signalservice.CallMessage.Opaque.urgency:type_name -> signalservice.CallMessage.Opaque.Urgency + 66, // 69: signalservice.DataMessage.Payment.notification:type_name -> signalservice.DataMessage.Payment.Notification + 67, // 70: signalservice.DataMessage.Payment.activation:type_name -> signalservice.DataMessage.Payment.Activation + 70, // 71: signalservice.DataMessage.Quote.attachments:type_name -> signalservice.DataMessage.Quote.QuotedAttachment + 47, // 72: signalservice.DataMessage.Quote.bodyRanges:type_name -> signalservice.BodyRange + 7, // 73: signalservice.DataMessage.Quote.type:type_name -> signalservice.DataMessage.Quote.Type + 71, // 74: signalservice.DataMessage.Contact.name:type_name -> signalservice.DataMessage.Contact.Name + 72, // 75: signalservice.DataMessage.Contact.number:type_name -> signalservice.DataMessage.Contact.Phone + 73, // 76: signalservice.DataMessage.Contact.email:type_name -> signalservice.DataMessage.Contact.Email + 74, // 77: signalservice.DataMessage.Contact.address:type_name -> signalservice.DataMessage.Contact.PostalAddress + 75, // 78: signalservice.DataMessage.Contact.avatar:type_name -> signalservice.DataMessage.Contact.Avatar + 40, // 79: signalservice.DataMessage.Sticker.data:type_name -> signalservice.AttachmentPointer + 68, // 80: signalservice.DataMessage.Payment.Amount.mobileCoin:type_name -> signalservice.DataMessage.Payment.Amount.MobileCoin + 69, // 81: signalservice.DataMessage.Payment.Notification.mobileCoin:type_name -> signalservice.DataMessage.Payment.Notification.MobileCoin + 6, // 82: signalservice.DataMessage.Payment.Activation.type:type_name -> signalservice.DataMessage.Payment.Activation.Type + 40, // 83: signalservice.DataMessage.Quote.QuotedAttachment.thumbnail:type_name -> signalservice.AttachmentPointer + 8, // 84: signalservice.DataMessage.Contact.Phone.type:type_name -> signalservice.DataMessage.Contact.Phone.Type + 9, // 85: signalservice.DataMessage.Contact.Email.type:type_name -> signalservice.DataMessage.Contact.Email.Type + 10, // 86: signalservice.DataMessage.Contact.PostalAddress.type:type_name -> signalservice.DataMessage.Contact.PostalAddress.Type + 40, // 87: signalservice.DataMessage.Contact.Avatar.avatar:type_name -> signalservice.AttachmentPointer + 31, // 88: signalservice.SyncMessage.Sent.message:type_name -> signalservice.DataMessage + 99, // 89: signalservice.SyncMessage.Sent.unidentifiedStatus:type_name -> signalservice.SyncMessage.Sent.UnidentifiedDeliveryStatus + 35, // 90: signalservice.SyncMessage.Sent.storyMessage:type_name -> signalservice.StoryMessage + 100, // 91: signalservice.SyncMessage.Sent.storyMessageRecipients:type_name -> signalservice.SyncMessage.Sent.StoryMessageRecipient + 46, // 92: signalservice.SyncMessage.Sent.editMessage:type_name -> signalservice.EditMessage + 40, // 93: signalservice.SyncMessage.Contacts.blob:type_name -> signalservice.AttachmentPointer + 15, // 94: signalservice.SyncMessage.Request.type:type_name -> signalservice.SyncMessage.Request.Type + 16, // 95: signalservice.SyncMessage.StickerPackOperation.type:type_name -> signalservice.SyncMessage.StickerPackOperation.Type + 17, // 96: signalservice.SyncMessage.FetchLatest.type:type_name -> signalservice.SyncMessage.FetchLatest.Type + 18, // 97: signalservice.SyncMessage.MessageRequestResponse.type:type_name -> signalservice.SyncMessage.MessageRequestResponse.Type + 101, // 98: signalservice.SyncMessage.OutgoingPayment.mobileCoin:type_name -> signalservice.SyncMessage.OutgoingPayment.MobileCoin + 19, // 99: signalservice.SyncMessage.CallEvent.type:type_name -> signalservice.SyncMessage.CallEvent.Type + 20, // 100: signalservice.SyncMessage.CallEvent.direction:type_name -> signalservice.SyncMessage.CallEvent.Direction + 21, // 101: signalservice.SyncMessage.CallEvent.event:type_name -> signalservice.SyncMessage.CallEvent.Event + 22, // 102: signalservice.SyncMessage.CallLinkUpdate.type:type_name -> signalservice.SyncMessage.CallLinkUpdate.Type + 23, // 103: signalservice.SyncMessage.CallLogEvent.type:type_name -> signalservice.SyncMessage.CallLogEvent.Type + 102, // 104: signalservice.SyncMessage.DeleteForMe.messageDeletes:type_name -> signalservice.SyncMessage.DeleteForMe.MessageDeletes + 104, // 105: signalservice.SyncMessage.DeleteForMe.conversationDeletes:type_name -> signalservice.SyncMessage.DeleteForMe.ConversationDelete + 105, // 106: signalservice.SyncMessage.DeleteForMe.localOnlyConversationDeletes:type_name -> signalservice.SyncMessage.DeleteForMe.LocalOnlyConversationDelete + 103, // 107: signalservice.SyncMessage.DeleteForMe.attachmentDeletes:type_name -> signalservice.SyncMessage.DeleteForMe.AttachmentDelete + 48, // 108: signalservice.SyncMessage.AttachmentBackfillRequest.targetMessage:type_name -> signalservice.AddressableMessage + 49, // 109: signalservice.SyncMessage.AttachmentBackfillRequest.targetConversation:type_name -> signalservice.ConversationIdentifier + 48, // 110: signalservice.SyncMessage.AttachmentBackfillResponse.targetMessage:type_name -> signalservice.AddressableMessage + 49, // 111: signalservice.SyncMessage.AttachmentBackfillResponse.targetConversation:type_name -> signalservice.ConversationIdentifier + 107, // 112: signalservice.SyncMessage.AttachmentBackfillResponse.attachments:type_name -> signalservice.SyncMessage.AttachmentBackfillResponse.AttachmentDataList + 24, // 113: signalservice.SyncMessage.AttachmentBackfillResponse.error:type_name -> signalservice.SyncMessage.AttachmentBackfillResponse.Error + 49, // 114: signalservice.SyncMessage.DeleteForMe.MessageDeletes.conversation:type_name -> signalservice.ConversationIdentifier + 48, // 115: signalservice.SyncMessage.DeleteForMe.MessageDeletes.messages:type_name -> signalservice.AddressableMessage + 49, // 116: signalservice.SyncMessage.DeleteForMe.AttachmentDelete.conversation:type_name -> signalservice.ConversationIdentifier + 48, // 117: signalservice.SyncMessage.DeleteForMe.AttachmentDelete.targetMessage:type_name -> signalservice.AddressableMessage + 49, // 118: signalservice.SyncMessage.DeleteForMe.ConversationDelete.conversation:type_name -> signalservice.ConversationIdentifier + 48, // 119: signalservice.SyncMessage.DeleteForMe.ConversationDelete.mostRecentMessages:type_name -> signalservice.AddressableMessage + 48, // 120: signalservice.SyncMessage.DeleteForMe.ConversationDelete.mostRecentNonExpiringMessages:type_name -> signalservice.AddressableMessage + 49, // 121: signalservice.SyncMessage.DeleteForMe.LocalOnlyConversationDelete.conversation:type_name -> signalservice.ConversationIdentifier + 40, // 122: signalservice.SyncMessage.AttachmentBackfillResponse.AttachmentData.attachment:type_name -> signalservice.AttachmentPointer + 25, // 123: signalservice.SyncMessage.AttachmentBackfillResponse.AttachmentData.status:type_name -> signalservice.SyncMessage.AttachmentBackfillResponse.AttachmentData.Status + 106, // 124: signalservice.SyncMessage.AttachmentBackfillResponse.AttachmentDataList.attachments:type_name -> signalservice.SyncMessage.AttachmentBackfillResponse.AttachmentData + 106, // 125: signalservice.SyncMessage.AttachmentBackfillResponse.AttachmentDataList.longText:type_name -> signalservice.SyncMessage.AttachmentBackfillResponse.AttachmentData + 126, // [126:126] is the sub-list for method output_type + 126, // [126:126] is the sub-list for method input_type + 126, // [126:126] is the sub-list for extension type_name + 126, // [126:126] is the sub-list for extension extendee + 0, // [0:126] is the sub-list for field type_name } func init() { file_SignalService_proto_init() } @@ -7992,53 +8026,61 @@ func file_SignalService_proto_init() { if File_SignalService_proto != nil { return } - file_SignalService_proto_msgTypes[3].OneofWrappers = []any{ - (*BodyRange_MentionAci)(nil), - (*BodyRange_Style_)(nil), - } - file_SignalService_proto_msgTypes[8].OneofWrappers = []any{ + file_SignalService_proto_msgTypes[7].OneofWrappers = []any{ (*StoryMessage_FileAttachment)(nil), (*StoryMessage_TextAttachment)(nil), } - file_SignalService_proto_msgTypes[10].OneofWrappers = []any{ + file_SignalService_proto_msgTypes[9].OneofWrappers = []any{ (*TextAttachment_Gradient_)(nil), (*TextAttachment_Color)(nil), } - file_SignalService_proto_msgTypes[13].OneofWrappers = []any{ + file_SignalService_proto_msgTypes[12].OneofWrappers = []any{ (*AttachmentPointer_CdnId)(nil), (*AttachmentPointer_CdnKey)(nil), } - file_SignalService_proto_msgTypes[18].OneofWrappers = []any{ - (*PaymentAddress_MobileCoinAddress_)(nil), + file_SignalService_proto_msgTypes[15].OneofWrappers = []any{ + (*PaymentAddress_MobileCoin_)(nil), } - file_SignalService_proto_msgTypes[35].OneofWrappers = []any{ + file_SignalService_proto_msgTypes[19].OneofWrappers = []any{ + (*BodyRange_MentionAci)(nil), + (*BodyRange_Style_)(nil), + } + file_SignalService_proto_msgTypes[20].OneofWrappers = []any{ + (*AddressableMessage_AuthorServiceId)(nil), + (*AddressableMessage_AuthorE164)(nil), + } + file_SignalService_proto_msgTypes[21].OneofWrappers = []any{ + (*ConversationIdentifier_ThreadServiceId)(nil), + (*ConversationIdentifier_ThreadGroupId)(nil), + (*ConversationIdentifier_ThreadE164)(nil), + } + file_SignalService_proto_msgTypes[28].OneofWrappers = []any{ (*DataMessage_Payment_Notification_)(nil), (*DataMessage_Payment_Activation_)(nil), } - file_SignalService_proto_msgTypes[43].OneofWrappers = []any{ + file_SignalService_proto_msgTypes[37].OneofWrappers = []any{ (*DataMessage_Payment_Amount_MobileCoin_)(nil), } - file_SignalService_proto_msgTypes[44].OneofWrappers = []any{ + file_SignalService_proto_msgTypes[38].OneofWrappers = []any{ (*DataMessage_Payment_Notification_MobileCoin_)(nil), } - file_SignalService_proto_msgTypes[61].OneofWrappers = []any{ + file_SignalService_proto_msgTypes[62].OneofWrappers = []any{ (*SyncMessage_OutgoingPayment_MobileCoin_)(nil), } - file_SignalService_proto_msgTypes[71].OneofWrappers = []any{ - (*SyncMessage_DeleteForMe_ConversationIdentifier_ThreadServiceId)(nil), - (*SyncMessage_DeleteForMe_ConversationIdentifier_ThreadGroupId)(nil), - (*SyncMessage_DeleteForMe_ConversationIdentifier_ThreadE164)(nil), + file_SignalService_proto_msgTypes[70].OneofWrappers = []any{ + (*SyncMessage_AttachmentBackfillResponse_Attachments)(nil), + (*SyncMessage_AttachmentBackfillResponse_Error_)(nil), } - file_SignalService_proto_msgTypes[72].OneofWrappers = []any{ - (*SyncMessage_DeleteForMe_AddressableMessage_AuthorServiceId)(nil), - (*SyncMessage_DeleteForMe_AddressableMessage_AuthorE164)(nil), + file_SignalService_proto_msgTypes[78].OneofWrappers = []any{ + (*SyncMessage_AttachmentBackfillResponse_AttachmentData_Attachment)(nil), + (*SyncMessage_AttachmentBackfillResponse_AttachmentData_Status_)(nil), } type x struct{} out := protoimpl.TypeBuilder{ File: protoimpl.DescBuilder{ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_SignalService_proto_rawDesc, - NumEnums: 27, + NumEnums: 28, NumMessages: 82, NumExtensions: 0, NumServices: 0, diff --git a/pkg/signalmeow/protobuf/SignalService.pb.raw b/pkg/signalmeow/protobuf/SignalService.pb.raw index ef74a34b022885779472ea55468cec2136898678..befb7053450b2a5831204736297be0cfa084b7e8 100644 GIT binary patch delta 2426 zcmcIm+i%-c7~gU3CvE2*md!~^Te7z6x-Jskwd&S2O}sQs<77^{t{@b=#A{8R%WS8t z2s9yqCLy6Aoel(IzyoN21QYVpKms8RA@L7@GyzYH7c^-S5(05MwzE1Z9UBk494p`D z_g&8Kd|%#w1^oOfcxiyT;`(S;40QR#+LBln6+vd&`oNHvw*`0+^cH&{tk+6{CYG`l ziP=g_e0-AxZG$dVt17DuZF*Zj&@k* CF+3TjO#7qsfKSYbMeMH|1>Qsjs{Z-~Pm z;xE9!U?*(P@@$G-C``?9@mZF3pf0#0$MPpxz7S_;ljOTlz=#^0$gy0UL&Dqo0Y$d}90-mue4(bRC8VauM1O-H!|i%(DiU8WX1;1~T%C^+?T z<}#%ZZGFIpzX|2QBY31M-H!awb3DV(NBKDI)mOWo@KCp7`VZl6T?0sgK|#}m;!;_x zXj4LQ`HUpXym+=Qsv5(P8vUdD@v{S6C!=?>;_nWC>M*n!x>~DNRFMhx0sQA!@8Qj$ zEffA<+(W2go8CjS|KDf)Rd{dBhh`M0RUdsd-weXm>n=+ zH?JU>^_-DJ1xF6t0PkUV@WA%%&|MT{IaxAsoV@i*Pak{%1oP0vu8>N0-%ut2R*`1`|GK?z?ROZK2348&&HC|^i&1``Qy zbJ2V59I;~DcL+0B0#RtcBKt+29|YHpX50 z?s-RSRb0@7SxMEVxA4tCCeN%++opw*3MWW-DvG0)p5|A=X;i~y0G=}bTyFyYjlw_TXf)B=I!m^-%n~wP@P+7=0NDk_rFvyKCp{&a{~6kOUlA9kZsLX5evh%! zowO6L#RlS0|x*A delta 1910 zcma)6U2GIp6z0xMyUX35&R%MF7%Ev7yFjoFEl{DQlx26iUAEnp>8?s5X{NiEc4U9* z?CeTO47>;if0JWkc#sH*O(1EA86Sv7pDT&J7+*B{M2zu?2NR<&dgrI4lqh|f%=x+Z zobS8eIe%P7cRoTN^l+=fXM0iz-a_4@ow%)G){P}ejG?`L)ip>0hYh+|H%z@YU#Op_ zH7UZvL3M*S{xo#YdEc8Hx(A=^Zz+Sgt4tfLan020wQQNzOx;|{(Iu(Pf$$$u z)&mkb_7%i7`8H_JuRv$-*XUFDzIPm*h3>wbNEpuPe0DaQR`P{x;f(cK-xPmf8DW9l z-mp2dnbhX#3^iJMiAu=j>~Sxw_Fu4IfFSgqwS4d&BzEA?qPA3JeWt0Y=@t0u@K5L# zTpv6f4r5L)OB}mKP&wUtFnA5gMck&eSTZ3vT+HY4Q!nLblc_>>Di2qWw07A*?E^tI zsFkaFZCYzIn2(&qg1NLvB_2+{&;zNX2e`iwG>_gzS?C$c^75^)_0G_J1RWDMkPH`d zAMTg$BOIQjjRr%MrWI<^2GMY^RIjzD(Qw#x5C#TD;O3qLj0}fhWmLkXi2YUP7=(uV zA$elkpl8#DyvkuQX_{JT!3AtzyO~?JlUW=xHDjKdUP}(jz`#+b_K6d_MS_K9lhMUH z=!GWS8=337%43pR*Rcy^GZi_a!yCtUK-chI8v}fKypy|xVPteCCkYT4?sdG(gzt_& z$IF)yoE_a6eL6w;@FUSjL=yiKQt1rbNiX*w!BM?dGN?_AR+-dFsfA|k{EU8)I>Q%I zH->>KzjiVixUf4t*o*?mjUDm{aeKCSxH6VF@Q}m7j8ShcGAc}Z!6dG*TzxW$kwcz3 zY~_RpVsHcR$oCbPUQ|alc9EJ^W$Iz^t*Y}+VmMHx)j6gGrGM~{B*b_YTJIvqu+Pho z+Tm{C8Cb!=?!HOqkh&HkM{v8=(%9QdZE*S7#3j`;|$yvE0| zV7F;+7jGEEEd=BC;&eJ$P()-0(#k~kMMY(6$&ZE8#cY9XBR0yaa=NI@6lSyeu_;lA zS8&*&2tFS>$Nj)Vcjn!FY&n+dmAb*e*@az$9K?P$0s1+emYtmv7>L5RyP|M+cK~_= zF}R(1y_?9`uNkEUy~UCO?6hBfWJ7E`Lw%w@{u}Q-i#zy@C!S@Eb`Q7x1RH7R|BrT9 z2}BbPDzCy5ZK?{17 z8d5t$98%Z2$RjR&>$#M$Z>~}=oo6ihV?mpyH5>lUB%VfNdSX)|`GzgBX?MjY%VmS@ zCbmr?)%u)Xp{crF^PF%q9EC5&w=14KzD0d9NzUQO (version byte | SignalMessage{Content}) + reserved 2; + reserved "KEY_EXCHANGE"; + PREKEY_BUNDLE = 3; // content => (version byte | PreKeySignalMessage{Content}) + SERVER_DELIVERY_RECEIPT = 5; // legacyMessage => [] AND content => [] + UNIDENTIFIED_SENDER = 6; // legacyMessage => [] AND content => ((version byte | UnidentifiedSenderMessage) OR (version byte | Multi-Recipient Sealed Sender Format)) + SENDERKEY_MESSAGE = 7; // legacyMessage => [] AND content => (version byte | SenderKeyMessage) + PLAINTEXT_CONTENT = 8; // legacyMessage => [] AND content => (marker byte | Content) } - optional Type type = 1; - reserved /*sourceE164*/ 2; - optional string sourceServiceId = 11; - optional uint32 sourceDevice = 7; + optional Type type = 1; + reserved 2; // formerly optional string sourceE164 = 2; + optional string sourceServiceId = 11; + optional uint32 sourceDevice = 7; optional string destinationServiceId = 13; - reserved /*relay*/ 3; - optional uint64 timestamp = 5; - reserved /*legacyMessage*/ 6; - optional bytes content = 8; // Contains an encrypted Content - optional string serverGuid = 9; - optional uint64 serverTimestamp = 10; - optional bool urgent = 14 [default = true]; - reserved /*updatedPni*/ 15; // Not used presently, may be used in the future - optional bool story = 16; - optional bytes reportingToken = 17; - reserved 18; // internal server use - // NEXT ID: 19 + reserved 3; // formerly optional string relay = 3; + optional uint64 timestamp = 5; + reserved 6; // formerly optional bytes legacyMessage = 6; // Contains an encrypted DataMessage; this field could have been set historically for type 1 or 3 messages; no longer in use + optional bytes content = 8; // Contains an encrypted Content + optional string serverGuid = 9; + optional uint64 serverTimestamp = 10; + optional bool ephemeral = 12; // indicates that the message should not be persisted if the recipient is offline + optional bool urgent = 14 [default = true]; // indicates that the content is considered timely by the sender; defaults to true so senders have to opt-out to say something isn't time critical + optional string updatedPni = 15; // for number-change synchronization messages, provides the new server-assigned phone number identifier associated with the changed number + optional bool story = 16; // indicates that the content is a story. + optional bytes report_spam_token = 17; // token sent when reporting spam + reserved 18; // internal server use + // next: 19 } message Content { - optional DataMessage dataMessage = 1; - optional SyncMessage syncMessage = 2; - optional CallMessage callMessage = 3; - optional NullMessage nullMessage = 4; - optional ReceiptMessage receiptMessage = 5; - optional TypingMessage typingMessage = 6; - optional bytes senderKeyDistributionMessage = 7; - optional bytes decryptionErrorMessage = 8; - optional StoryMessage storyMessage = 9; - optional PniSignatureMessage pniSignatureMessage = 10; - optional EditMessage editMessage = 11; + optional DataMessage dataMessage = 1; + optional SyncMessage syncMessage = 2; + optional CallMessage callMessage = 3; + optional NullMessage nullMessage = 4; + optional ReceiptMessage receiptMessage = 5; + optional TypingMessage typingMessage = 6; + optional bytes /* SenderKeyDistributionMessage */ senderKeyDistributionMessage = 7; + optional bytes /* DecryptionErrorMessage */ decryptionErrorMessage = 8; + optional StoryMessage storyMessage = 9; + optional PniSignatureMessage pniSignatureMessage = 10; + optional EditMessage editMessage = 11; } message CallMessage { message Offer { enum Type { - OFFER_AUDIO_CALL = 0; - OFFER_VIDEO_CALL = 1; - reserved /* OFFER_NEED_PERMISSION */ 2; // removed + OFFER_AUDIO_CALL = 0; + OFFER_VIDEO_CALL = 1; + reserved /* OFFER_NEED_PERMISSION */ 2; // removed } - - optional uint64 id = 1; - reserved /* sdp */ 2; - optional Type type = 3; - optional bytes opaque = 4; + optional uint64 id = 1; + reserved /* sdp */ 2; + optional Type type = 3; + optional bytes opaque = 4; } message Answer { - optional uint64 id = 1; - reserved /* sdp */ 2; - optional bytes opaque = 3; + optional uint64 id = 1; + reserved /* sdp */ 2; + optional bytes opaque = 3; } message IceUpdate { - optional uint64 id = 1; - reserved /* mid */ 2; - reserved /* line */ 3; - reserved /* sdp */ 4; - optional bytes opaque = 5; + optional uint64 id = 1; + reserved /* mid */ 2; + reserved /* line */ 3; + reserved /* sdp */ 4; + optional bytes opaque = 5; } message Busy { @@ -89,188 +90,50 @@ message CallMessage { message Hangup { enum Type { - HANGUP_NORMAL = 0; - HANGUP_ACCEPTED = 1; - HANGUP_DECLINED = 2; - HANGUP_BUSY = 3; + HANGUP_NORMAL = 0; + HANGUP_ACCEPTED = 1; + HANGUP_DECLINED = 2; + HANGUP_BUSY = 3; HANGUP_NEED_PERMISSION = 4; } - - optional uint64 id = 1; - optional Type type = 2; + optional uint64 id = 1; + optional Type type = 2; optional uint32 deviceId = 3; } message Opaque { enum Urgency { - DROPPABLE = 0; + DROPPABLE = 0; HANDLE_IMMEDIATELY = 1; } - - optional bytes data = 1; - optional Urgency urgency = 2; + optional bytes data = 1; + optional Urgency urgency = 2; // If missing, treat as DROPPABLE. } - optional Offer offer = 1; - optional Answer answer = 2; - repeated IceUpdate iceUpdate = 3; - reserved /* legacyHangup */ 4; - optional Busy busy = 5; - reserved /* profileKey */ 6; - optional Hangup hangup = 7; - reserved /* multiRing */ 8; - optional uint32 destinationDeviceId = 9; - optional Opaque opaque = 10; -} - -message BodyRange { - enum Style { - NONE = 0; - BOLD = 1; - ITALIC = 2; - SPOILER = 3; - STRIKETHROUGH = 4; - MONOSPACE = 5; - } - - optional uint32 start = 1; - optional uint32 length = 2; - - oneof associatedValue { - string mentionAci = 3; - Style style = 4; - } + optional Offer offer = 1; + optional Answer answer = 2; + repeated IceUpdate iceUpdate = 3; + reserved /* legacyHangup */ 4; + optional Busy busy = 5; + reserved /* profileKey */ 6; + optional Hangup hangup = 7; + reserved /* multiRing */ 8; + optional uint32 destinationDeviceId = 9; + optional Opaque opaque = 10; } message DataMessage { enum Flags { - END_SESSION = 1; + END_SESSION = 1; EXPIRATION_TIMER_UPDATE = 2; - PROFILE_KEY_UPDATE = 4; - } - - message Quote { - enum Type { - NORMAL = 0; - GIFT_BADGE = 1; - } - - message QuotedAttachment { - optional string contentType = 1; - optional string fileName = 2; - optional AttachmentPointer thumbnail = 3; - } - - optional uint64 id = 1; - reserved /*authorE164*/ 2; - optional string authorAci = 5; - optional string text = 3; - repeated QuotedAttachment attachments = 4; - repeated BodyRange bodyRanges = 6; - optional Type type = 7; - } - - message Contact { - message Name { - optional string givenName = 1; - optional string familyName = 2; - optional string prefix = 3; - optional string suffix = 4; - optional string middleName = 5; - reserved /*displayName*/ 6; - optional string nickname = 7; - } - - message Phone { - enum Type { - HOME = 1; - MOBILE = 2; - WORK = 3; - CUSTOM = 4; - } - - optional string value = 1; - optional Type type = 2; - optional string label = 3; - } - - message Email { - enum Type { - HOME = 1; - MOBILE = 2; - WORK = 3; - CUSTOM = 4; - } - - optional string value = 1; - optional Type type = 2; - optional string label = 3; - } - - message PostalAddress { - enum Type { - HOME = 1; - WORK = 2; - CUSTOM = 3; - } - - optional Type type = 1; - optional string label = 2; - optional string street = 3; - optional string pobox = 4; - optional string neighborhood = 5; - optional string city = 6; - optional string region = 7; - optional string postcode = 8; - optional string country = 9; - } - - message Avatar { - optional AttachmentPointer avatar = 1; - optional bool isProfile = 2; - } - - optional Name name = 1; - repeated Phone number = 3; - repeated Email email = 4; - repeated PostalAddress address = 5; - optional Avatar avatar = 6; - optional string organization = 7; - } - - message Sticker { - optional bytes packId = 1; - optional bytes packKey = 2; - optional uint32 stickerId = 3; - optional AttachmentPointer data = 4; - optional string emoji = 5; - } - - message Reaction { - optional string emoji = 1; - optional bool remove = 2; - reserved /*targetAuthorE164*/ 3; - optional string targetAuthorAci = 4; - optional uint64 targetSentTimestamp = 5; - } - - message Delete { - optional uint64 targetSentTimestamp = 1; - } - - message GroupCallUpdate { - optional string eraId = 1; - } - - message StoryContext { - optional string authorAci = 1; - optional uint64 sentTimestamp = 2; + PROFILE_KEY_UPDATE = 4; + FORWARD = 8; } message Payment { message Amount { message MobileCoin { - optional uint64 picoMob = 1; + optional uint64 picoMob = 1; // 1,000,000,000,000 picoMob per Mob } oneof Amount { @@ -287,13 +150,14 @@ message DataMessage { MobileCoin mobileCoin = 1; } + // Optional, Refers to the PaymentRequest message, if any. optional string note = 2; reserved /*requestId*/ 1003; } message Activation { enum Type { - REQUEST = 0; + REQUEST = 0; ACTIVATED = 1; } @@ -302,53 +166,172 @@ message DataMessage { oneof Item { Notification notification = 1; - Activation activation = 2; + Activation activation = 2; } - reserved /*request*/ 1002; + reserved /*request*/ 1002; reserved /*cancellation*/ 1003; } + message Quote { + enum Type { + NORMAL = 0; + GIFT_BADGE = 1; + } + + message QuotedAttachment { + optional string contentType = 1; + optional string fileName = 2; + optional AttachmentPointer thumbnail = 3; + } + + optional uint64 id = 1; + reserved /*authorE164*/ 2; + optional string authorAci = 5; + optional string text = 3; + repeated QuotedAttachment attachments = 4; + repeated BodyRange bodyRanges = 6; + optional Type type = 7; + } + + message Contact { + message Name { + optional string givenName = 1; + optional string familyName = 2; + optional string prefix = 3; + optional string suffix = 4; + optional string middleName = 5; + reserved /*displayName*/ 6; + optional string nickname = 7; + } + + message Phone { + enum Type { + HOME = 1; + MOBILE = 2; + WORK = 3; + CUSTOM = 4; + } + + optional string value = 1; + optional Type type = 2; + optional string label = 3; + } + + message Email { + enum Type { + HOME = 1; + MOBILE = 2; + WORK = 3; + CUSTOM = 4; + } + + optional string value = 1; + optional Type type = 2; + optional string label = 3; + } + + message PostalAddress { + enum Type { + HOME = 1; + WORK = 2; + CUSTOM = 3; + } + + optional Type type = 1; + optional string label = 2; + optional string street = 3; + optional string pobox = 4; + optional string neighborhood = 5; + optional string city = 6; + optional string region = 7; + optional string postcode = 8; + optional string country = 9; + } + + message Avatar { + optional AttachmentPointer avatar = 1; + optional bool isProfile = 2; + } + + optional Name name = 1; + repeated Phone number = 3; + repeated Email email = 4; + repeated PostalAddress address = 5; + optional Avatar avatar = 6; + optional string organization = 7; + } + + message Sticker { + optional bytes packId = 1; + optional bytes packKey = 2; + optional uint32 stickerId = 3; + optional AttachmentPointer data = 4; + optional string emoji = 5; + } + + message Reaction { + optional string emoji = 1; + optional bool remove = 2; + reserved /* targetAuthorE164 */ 3; + optional string targetAuthorAci = 4; + optional uint64 targetSentTimestamp = 5; + } + + message Delete { + optional uint64 targetSentTimestamp = 1; + } + + message GroupCallUpdate { + optional string eraId = 1; + } + + message StoryContext { + optional string authorAci = 1; + optional uint64 sentTimestamp = 2; + } + + enum ProtocolVersion { + option allow_alias = true; + + INITIAL = 0; + MESSAGE_TIMERS = 1; + VIEW_ONCE = 2; + VIEW_ONCE_VIDEO = 3; + REACTIONS = 4; + CDN_SELECTOR_ATTACHMENTS = 5; + MENTIONS = 6; + PAYMENTS = 7; + CURRENT = 7; + } + message GiftBadge { optional bytes receiptCredentialPresentation = 1; } - enum ProtocolVersion { - option allow_alias = true; - - INITIAL = 0; - MESSAGE_TIMERS = 1; - VIEW_ONCE = 2; - VIEW_ONCE_VIDEO = 3; - REACTIONS = 4; - CDN_SELECTOR_ATTACHMENTS = 5; - MENTIONS = 6; - PAYMENTS = 7; - CURRENT = 7; - } - - optional string body = 1; - repeated AttachmentPointer attachments = 2; - reserved /*groupV1*/ 3; - optional GroupContextV2 groupV2 = 15; - optional uint32 flags = 4; - optional uint32 expireTimer = 5; - optional uint32 expireTimerVersion = 23; - optional bytes profileKey = 6; - optional uint64 timestamp = 7; - optional Quote quote = 8; - repeated Contact contact = 9; - repeated Preview preview = 10; - optional Sticker sticker = 11; - optional uint32 requiredProtocolVersion = 12; - optional bool isViewOnce = 14; - optional Reaction reaction = 16; - optional Delete delete = 17; - repeated BodyRange bodyRanges = 18; - optional GroupCallUpdate groupCallUpdate = 19; - optional Payment payment = 20; - optional StoryContext storyContext = 21; - optional GiftBadge giftBadge = 22; + optional string body = 1; + repeated AttachmentPointer attachments = 2; + reserved /*groupV1*/ 3; + optional GroupContextV2 groupV2 = 15; + optional uint32 flags = 4; + optional uint32 expireTimer = 5; + optional uint32 expireTimerVersion = 23; + optional bytes profileKey = 6; + optional uint64 timestamp = 7; + optional Quote quote = 8; + repeated Contact contact = 9; + repeated Preview preview = 10; + optional Sticker sticker = 11; + optional uint32 requiredProtocolVersion = 12; + optional bool isViewOnce = 14; + optional Reaction reaction = 16; + optional Delete delete = 17; + repeated BodyRange bodyRanges = 18; + optional GroupCallUpdate groupCallUpdate = 19; + optional Payment payment = 20; + optional StoryContext storyContext = 21; + optional GiftBadge giftBadge = 22; + // NEXT ID: 24 } message NullMessage { @@ -358,185 +341,186 @@ message NullMessage { message ReceiptMessage { enum Type { DELIVERY = 0; - READ = 1; - VIEWED = 2; + READ = 1; + VIEWED = 2; } - optional Type type = 1; + optional Type type = 1; repeated uint64 timestamp = 2; } message TypingMessage { - enum Action { - STARTED = 0; - STOPPED = 1; - } + enum Action { + STARTED = 0; + STOPPED = 1; + } - optional uint64 timestamp = 1; - optional Action action = 2; - optional bytes groupId = 3; + optional uint64 timestamp = 1; + optional Action action = 2; + optional bytes groupId = 3; } message StoryMessage { - optional bytes profileKey = 1; - optional GroupContextV2 group = 2; + optional bytes profileKey = 1; + optional GroupContextV2 group = 2; oneof attachment { AttachmentPointer fileAttachment = 3; - TextAttachment textAttachment = 4; + TextAttachment textAttachment = 4; } - optional bool allowsReplies = 5; - repeated BodyRange bodyRanges = 6; + optional bool allowsReplies = 5; + repeated BodyRange bodyRanges = 6; } message Preview { - optional string url = 1; - optional string title = 2; - optional AttachmentPointer image = 3; - optional string description = 4; - optional uint64 date = 5; + optional string url = 1; + optional string title = 2; + optional AttachmentPointer image = 3; + optional string description = 4; + optional uint64 date = 5; } message TextAttachment { enum Style { - DEFAULT = 0; - REGULAR = 1; - BOLD = 2; - SERIF = 3; - SCRIPT = 4; + DEFAULT = 0; + REGULAR = 1; + BOLD = 2; + SERIF = 3; + SCRIPT = 4; CONDENSED = 5; } message Gradient { optional uint32 startColor = 1; // deprecated: this field will be removed in a future release. - optional uint32 endColor = 2; // deprecated: this field will be removed in a future release. - optional uint32 angle = 3; // degrees - repeated uint32 colors = 4; - repeated float positions = 5; // percent from 0 to 1 + optional uint32 endColor = 2; // deprecated: this field will be removed in a future release. + optional uint32 angle = 3; // degrees + repeated uint32 colors = 4; + repeated float positions = 5; // percent from 0 to 1 } - optional string text = 1; - optional Style textStyle = 2; - optional uint32 textForegroundColor = 3; // integer representation of hex color - optional uint32 textBackgroundColor = 4; - optional Preview preview = 5; + optional string text = 1; + optional Style textStyle = 2; + optional uint32 textForegroundColor = 3; // integer representation of hex color + optional uint32 textBackgroundColor = 4; + optional Preview preview = 5; oneof background { Gradient gradient = 6; - uint32 color = 7; + uint32 color = 7; } } message Verified { enum State { - DEFAULT = 0; - VERIFIED = 1; + DEFAULT = 0; + VERIFIED = 1; UNVERIFIED = 2; } - reserved /*destinationE164*/ 1; - optional string destinationAci = 5; - optional bytes identityKey = 2; - optional State state = 3; - optional bytes nullMessage = 4; + reserved /*destinationE164*/ 1; + optional string destinationAci = 5; + optional bytes identityKey = 2; + optional State state = 3; + optional bytes nullMessage = 4; } message SyncMessage { message Sent { message UnidentifiedDeliveryStatus { - reserved /*destinationE164*/ 1; - optional string destinationServiceId = 3; - optional bool unidentified = 2; - reserved /*destinationPni*/ 4; - optional bytes destinationIdentityKey = 5; + reserved /*destinationE164*/ 1; + optional string destinationServiceId = 3; + optional bool unidentified = 2; + reserved /*destinationPni */ 4; + optional bytes destinationPniIdentityKey = 5; // Only set for PNI destinations } message StoryMessageRecipient { optional string destinationServiceId = 1; - repeated string distributionListIds = 2; - optional bool isAllowedToReply = 3; + repeated string distributionListIds = 2; + optional bool isAllowedToReply = 3; + reserved /*destinationPni */ 4; } - optional string destinationE164 = 1; - optional string destinationServiceId = 7; - optional uint64 timestamp = 2; - optional DataMessage message = 3; - optional uint64 expirationStartTimestamp = 4; - repeated UnidentifiedDeliveryStatus unidentifiedStatus = 5; - optional bool isRecipientUpdate = 6 [default = false]; - optional StoryMessage storyMessage = 8; - repeated StoryMessageRecipient storyMessageRecipients = 9; - optional EditMessage editMessage = 10; - reserved /*destinationPni*/ 11; - // NEXT ID: 12 + optional string destinationE164 = 1; + optional string destinationServiceId = 7; + optional uint64 timestamp = 2; + optional DataMessage message = 3; + optional uint64 expirationStartTimestamp = 4; + repeated UnidentifiedDeliveryStatus unidentifiedStatus = 5; + optional bool isRecipientUpdate = 6 [default = false]; + optional StoryMessage storyMessage = 8; + repeated StoryMessageRecipient storyMessageRecipients = 9; + optional EditMessage editMessage = 10; + reserved /*destinationPni */ 11; + // Next ID: 12 } message Contacts { - optional AttachmentPointer blob = 1; - optional bool complete = 2 [default = false]; + optional AttachmentPointer blob = 1; + optional bool complete = 2 [default = false]; } message Blocked { - repeated string numbers = 1; - repeated string acis = 3; - repeated bytes groupIds = 2; + repeated string numbers = 1; + repeated string acis = 3; + repeated bytes groupIds = 2; } message Request { enum Type { - UNKNOWN = 0; - CONTACTS = 1; -// GROUPS = 2; - BLOCKED = 3; + UNKNOWN = 0; + CONTACTS = 1; + reserved /*GROUPS*/ 2; + BLOCKED = 3; CONFIGURATION = 4; - KEYS = 5; - PNI_IDENTITY = 6; + KEYS = 5; + reserved /*PNI_IDENTITY*/ 6; } optional Type type = 1; } message Read { - reserved /*senderE164*/ 1; - optional string senderAci = 3; - optional uint64 timestamp = 2; + reserved /*senderE164*/ 1; + optional string senderAci = 3; + optional uint64 timestamp = 2; } message Viewed { - reserved /*senderE164*/ 1; - optional string senderAci = 3; - optional uint64 timestamp = 2; + reserved /*senderE164*/ 1; + optional string senderAci = 3; + optional uint64 timestamp = 2; } message Configuration { - optional bool readReceipts = 1; - optional bool unidentifiedDeliveryIndicators = 2; - optional bool typingIndicators = 3; - reserved /* linkPreviews */ 4; - optional uint32 provisioningVersion = 5; - optional bool linkPreviews = 6; + optional bool readReceipts = 1; + optional bool unidentifiedDeliveryIndicators = 2; + optional bool typingIndicators = 3; + reserved /* linkPreviews */ 4; + optional uint32 provisioningVersion = 5; + optional bool linkPreviews = 6; } message StickerPackOperation { enum Type { INSTALL = 0; - REMOVE = 1; + REMOVE = 1; } - optional bytes packId = 1; + optional bytes packId = 1; optional bytes packKey = 2; - optional Type type = 3; + optional Type type = 3; } message ViewOnceOpen { - reserved /*senderE164*/ 1; - optional string senderAci = 3; - optional uint64 timestamp = 2; + reserved /*senderE164*/ 1; + optional string senderAci = 3; + optional uint64 timestamp = 2; } message FetchLatest { enum Type { - UNKNOWN = 0; - LOCAL_PROFILE = 1; - STORAGE_MANIFEST = 2; + UNKNOWN = 0; + LOCAL_PROFILE = 1; + STORAGE_MANIFEST = 2; SUBSCRIPTION_STATUS = 3; } @@ -544,91 +528,95 @@ message SyncMessage { } message Keys { - // @deprecated - optional bytes storageService = 1; - // @deprecated - optional bytes master = 2; + reserved /* storageService */ 1; + optional bytes master = 2; // deprecated: this field will be removed in a future release. optional string accountEntropyPool = 3; optional bytes mediaRootBackupKey = 4; } + message PniIdentity { + optional bytes publicKey = 1; + optional bytes privateKey = 2; + } + message MessageRequestResponse { enum Type { - UNKNOWN = 0; - ACCEPT = 1; - DELETE = 2; - BLOCK = 3; + UNKNOWN = 0; + ACCEPT = 1; + DELETE = 2; + BLOCK = 3; BLOCK_AND_DELETE = 4; - SPAM = 5; - BLOCK_AND_SPAM = 6; + SPAM = 5; + BLOCK_AND_SPAM = 6; } - reserved /*threadE164*/ 1; - optional string threadAci = 2; - optional bytes groupId = 3; - optional Type type = 4; + reserved /*threadE164*/ 1; + optional string threadAci = 2; + optional bytes groupId = 3; + optional Type type = 4; } message OutgoingPayment { message MobileCoin { - optional bytes recipientAddress = 1; - // @required - optional uint64 amountPicoMob = 2; - // @required - optional uint64 feePicoMob = 3; - optional bytes receipt = 4; + optional bytes recipientAddress = 1; + optional uint64 amountPicoMob = 2; + optional uint64 feePicoMob = 3; + optional bytes receipt = 4; optional uint64 ledgerBlockTimestamp = 5; - // @required - optional uint64 ledgerBlockIndex = 6; - repeated bytes spentKeyImages = 7; - repeated bytes outputPublicKeys = 8; + optional uint64 ledgerBlockIndex = 6; + repeated bytes spentKeyImages = 7; + repeated bytes outputPublicKeys = 8; } optional string recipientServiceId = 1; - optional string note = 2; - - oneof paymentDetail { + optional string note = 2; + oneof attachment_identifier { MobileCoin mobileCoin = 3; } } message PniChangeNumber { - optional bytes identityKeyPair = 1; // Serialized libsignal-client IdentityKeyPair - optional bytes signedPreKey = 2; // Serialized libsignal-client SignedPreKeyRecord - optional bytes lastResortKyberPreKey = 5; // Serialized libsignal-client KyberPreKeyRecord - optional uint32 registrationId = 3; - optional string newE164 = 4; // The e164 we have changed our number to + optional bytes identityKeyPair = 1; // Serialized libsignal-client IdentityKeyPair + optional bytes signedPreKey = 2; // Serialized libsignal-client SignedPreKeyRecord + optional bytes lastResortKyberPreKey = 5; // Serialized libsignal-client KyberPreKeyRecord + optional uint32 registrationId = 3; + optional string newE164 = 4; // The e164 we have changed our number to // Next ID: 6 } message CallEvent { enum Type { UNKNOWN_TYPE = 0; - AUDIO_CALL = 1; - VIDEO_CALL = 2; - GROUP_CALL = 3; - AD_HOC_CALL = 4; + AUDIO_CALL = 1; + VIDEO_CALL = 2; + GROUP_CALL = 3; + AD_HOC_CALL = 4; } enum Direction { UNKNOWN_DIRECTION = 0; - INCOMING = 1; - OUTGOING = 2; + INCOMING = 1; + OUTGOING = 2; } enum Event { - UNKNOWN_ACTION = 0; - ACCEPTED = 1; - NOT_ACCEPTED = 2; - DELETE = 3; - OBSERVED = 4; + UNKNOWN_EVENT = 0; + ACCEPTED = 1; + NOT_ACCEPTED = 2; + DELETE = 3; + OBSERVED = 4; } - optional bytes conversationId = 1; - optional uint64 id = 2; - optional uint64 timestamp = 3; - optional Type type = 4; - optional Direction direction = 5; - optional Event event = 6; + /* Data identifying a conversation. The service ID for 1:1, the group ID for + * group, or the room ID for an ad-hoc call. See also + * `CallLogEvent/conversationId`. */ + optional bytes conversationId = 1; + /* An identifier for a call. Generated directly for 1:1, or derived from + * the era ID for group and ad-hoc calls. See also `CallLogEvent/callId`. */ + optional uint64 callId = 2; + optional uint64 timestamp = 3; + optional Type type = 4; + optional Direction direction = 5; + optional Event event = 6; } message CallLinkUpdate { @@ -637,46 +625,31 @@ message SyncMessage { reserved 1; // was DELETE, superseded by storage service } - optional bytes rootKey = 1; - optional bytes adminPassKey = 2; - optional Type type = 3; + optional bytes rootKey = 1; + optional bytes adminPasskey = 2; + optional Type type = 3; // defaults to UPDATE } message CallLogEvent { enum Type { - CLEAR = 0; - MARKED_AS_READ = 1; + CLEAR = 0; + MARKED_AS_READ = 1; MARKED_AS_READ_IN_CONVERSATION = 2; + CLEAR_IN_CONVERSATION = 3; } - optional Type type = 1; - optional uint64 timestamp = 2; + optional Type type = 1; + optional uint64 timestamp = 2; /* Data identifying a conversation. The service ID for 1:1, the group ID for * group, or the room ID for an ad-hoc call. See also * `CallEvent/conversationId`. */ optional bytes conversationId = 3; /* An identifier for a call. Generated directly for 1:1, or derived from * the era ID for group and ad-hoc calls. See also `CallEvent/callId`. */ - optional uint64 callId = 4; + optional uint64 callId = 4; } message DeleteForMe { - message ConversationIdentifier { - oneof identifier { - string threadServiceId = 1; - bytes threadGroupId = 2; - string threadE164 = 3; - } - } - - message AddressableMessage { - oneof author { - string authorServiceId = 1; - string authorE164 = 2; - } - optional uint64 sentTimestamp = 3; - } - message MessageDeletes { optional ConversationIdentifier conversation = 1; repeated AddressableMessage messages = 2; @@ -685,16 +658,19 @@ message SyncMessage { message AttachmentDelete { optional ConversationIdentifier conversation = 1; optional AddressableMessage targetMessage = 2; - optional bytes uuid = 3; // The `uuid` from the `Attachment`. + // The `clientUuid` from `AttachmentPointer`. + optional bytes clientUuid = 3; + // SHA256 hash of the (encrypted, padded, etc.) attachment blob on the CDN. optional bytes fallbackDigest = 4; + // SHA256 hash of the plaintext content of the attachment. optional bytes fallbackPlaintextHash = 5; } message ConversationDelete { optional ConversationIdentifier conversation = 1; repeated AddressableMessage mostRecentMessages = 2; - repeated AddressableMessage mostRecentNonExpiringMessages = 4; optional bool isFullDelete = 3; + repeated AddressableMessage mostRecentNonExpiringMessages = 4; } message LocalOnlyConversationDelete { @@ -708,163 +684,194 @@ message SyncMessage { } message DeviceNameChange { - reserved /*name*/ 1; + reserved /*name*/ 1; optional uint32 deviceId = 2; } - optional Sent sent = 1; - optional Contacts contacts = 2; - reserved /*groups*/ 3; - optional Request request = 4; - repeated Read read = 5; - optional Blocked blocked = 6; - optional Verified verified = 7; - optional Configuration configuration = 9; - optional bytes padding = 8; - repeated StickerPackOperation stickerPackOperation = 10; - optional ViewOnceOpen viewOnceOpen = 11; - optional FetchLatest fetchLatest = 12; - optional Keys keys = 13; + message AttachmentBackfillRequest { + optional AddressableMessage targetMessage = 1; + optional ConversationIdentifier targetConversation = 2; + } + + message AttachmentBackfillResponse { + message AttachmentData { + enum Status { + PENDING = 0; + TERMINAL_ERROR = 1; + } + + oneof data { + AttachmentPointer attachment = 1; + Status status = 2; + } + } + + enum Error { + MESSAGE_NOT_FOUND = 0; + } + + message AttachmentDataList { + repeated AttachmentData attachments = 1; + optional AttachmentData longText = 2; + } + + optional AddressableMessage targetMessage = 1; + optional ConversationIdentifier targetConversation = 2; + + oneof data { + AttachmentDataList attachments = 3; + Error error = 4; + } + } + + optional Sent sent = 1; + optional Contacts contacts = 2; + reserved /*groups*/ 3; + optional Request request = 4; + repeated Read read = 5; + optional Blocked blocked = 6; + optional Verified verified = 7; + optional Configuration configuration = 9; + optional bytes padding = 8; + repeated StickerPackOperation stickerPackOperation = 10; + optional ViewOnceOpen viewOnceOpen = 11; + optional FetchLatest fetchLatest = 12; + optional Keys keys = 13; optional MessageRequestResponse messageRequestResponse = 14; - optional OutgoingPayment outgoingPayment = 15; - repeated Viewed viewed = 16; - reserved /*pniIdentity*/ 17; - optional PniChangeNumber pniChangeNumber = 18; - optional CallEvent callEvent = 19; - optional CallLinkUpdate callLinkUpdate = 20; - optional CallLogEvent callLogEvent = 21; - optional DeleteForMe deleteForMe = 22; - optional DeviceNameChange deviceNameChange = 23; + optional OutgoingPayment outgoingPayment = 15; + repeated Viewed viewed = 16; + reserved /*pniIdentity*/ 17; + optional PniChangeNumber pniChangeNumber = 18; + optional CallEvent callEvent = 19; + optional CallLinkUpdate callLinkUpdate = 20; + optional CallLogEvent callLogEvent = 21; + optional DeleteForMe deleteForMe = 22; + optional DeviceNameChange deviceNameChange = 23; + optional AttachmentBackfillRequest attachmentBackfillRequest = 24; + optional AttachmentBackfillResponse attachmentBackfillResponse = 25; } message AttachmentPointer { enum Flags { VOICE_MESSAGE = 1; - BORDERLESS = 2; - reserved 3; - GIF = 4; + BORDERLESS = 2; + reserved 4; + GIF = 8; } oneof attachment_identifier { - fixed64 cdnId = 1; - string cdnKey = 15; + fixed64 cdnId = 1; + string cdnKey = 15; } - optional string contentType = 2; - optional bytes key = 3; - optional uint32 size = 4; - optional bytes thumbnail = 5; - optional bytes digest = 6; - reserved 16; - reserved 18; - optional bytes incrementalMac = 19; - optional uint32 incrementalMacChunkSize = 17; - optional string fileName = 7; - optional uint32 flags = 8; - optional uint32 width = 9; - optional uint32 height = 10; - optional string caption = 11; - optional string blurHash = 12; - optional uint64 uploadTimestamp = 13; - optional uint32 cdnNumber = 14; - optional bytes uuid = 20; + // Cross-client identifier for this attachment among all attachments on the + // owning message. + optional bytes clientUuid = 20; + optional string contentType = 2; + optional bytes key = 3; + optional uint32 size = 4; + optional bytes thumbnail = 5; + optional bytes digest = 6; + reserved /* incrementalMac with implicit chunk sizing */ 16; + reserved /* incrementalMac for all attachment types */ 18; + optional bytes incrementalMac = 19; + optional uint32 chunkSize = 17; + optional string fileName = 7; + optional uint32 flags = 8; + optional uint32 width = 9; + optional uint32 height = 10; + optional string caption = 11; + optional string blurHash = 12; + optional uint64 uploadTimestamp = 13; + optional uint32 cdnNumber = 14; // Next ID: 21 } -message GroupContext { - enum Type { - UNKNOWN = 0; - UPDATE = 1; - DELIVER = 2; - QUIT = 3; - REQUEST_INFO = 4; - } - - message Member { - reserved /* uuid */ 1; // removed - optional string e164 = 2; - } - - optional bytes id = 1; - optional Type type = 2; - optional string name = 3; - repeated string membersE164 = 4; - repeated Member members = 6; - optional AttachmentPointer avatar = 5; -} - message GroupContextV2 { - optional bytes masterKey = 1; - optional uint32 revision = 2; - optional bytes groupChange = 3; + optional bytes masterKey = 1; + optional uint32 revision = 2; + optional bytes groupChange = 3; } message ContactDetails { message Avatar { optional string contentType = 1; - optional uint32 length = 2; + optional uint32 length = 2; } - optional string number = 1; - optional string aci = 9; - optional string name = 2; - optional Avatar avatar = 3; - optional string color = 4; - optional Verified verified = 5; - optional bytes profileKey = 6; - reserved /*blocked*/ 7; - optional uint32 expireTimer = 8; - optional uint32 expireTimerVersion = 12; - optional uint32 inboxPosition = 10; - optional bool archived = 11; -} - -message GroupDetails { - message Avatar { - optional string contentType = 1; - optional uint32 length = 2; - } - - message Member { - reserved /* uuid */ 1; // removed - optional string e164 = 2; - } - - optional bytes id = 1; - optional string name = 2; - repeated string membersE164 = 3; - repeated Member members = 9; - optional Avatar avatar = 4; - optional bool active = 5 [default = true]; - optional uint32 expireTimer = 6; - optional string color = 7; - optional bool blocked = 8; - optional uint32 inboxPosition = 10; - optional bool archived = 11; + optional string number = 1; + optional string aci = 9; + optional string name = 2; + optional Avatar avatar = 3; + reserved /* color */ 4; + reserved /* verified */ 5; + reserved /* profileKey */ 6; + reserved /* blocked */ 7; + optional uint32 expireTimer = 8; + optional uint32 expireTimerVersion = 12; + optional uint32 inboxPosition = 10; + reserved /* archived */ 11; + // NEXT ID: 13 } message PaymentAddress { - oneof Address { - MobileCoinAddress mobileCoinAddress = 1; + message MobileCoin { + optional bytes publicAddress = 1; + optional bytes signature = 2; } - message MobileCoinAddress { - optional bytes address = 1; - optional bytes signature = 2; + oneof Address { + MobileCoin mobileCoin = 1; } } message DecryptionErrorMessage { - optional bytes ratchetKey = 1; - optional uint64 timestamp = 2; - optional uint32 deviceId = 3; + optional bytes ratchetKey = 1; // set to the public ratchet key from the SignalMessage if a 1-1 payload fails to decrypt + optional uint64 timestamp = 2; + optional uint32 deviceId = 3; } message PniSignatureMessage { - optional bytes pni = 1; + optional bytes pni = 1; + // Signature *by* the PNI identity key *of* the ACI identity key optional bytes signature = 2; } message EditMessage { - optional uint64 targetSentTimestamp = 1; - optional DataMessage dataMessage = 2; + optional uint64 targetSentTimestamp = 1; + optional DataMessage dataMessage = 2; +} + +message BodyRange { + enum Style { + NONE = 0; + BOLD = 1; + ITALIC = 2; + SPOILER = 3; + STRIKETHROUGH = 4; + MONOSPACE = 5; + } + + optional uint32 start = 1; // Starting index in UTF-16 code units/raw string representation + optional uint32 length = 2; // Length of range in UTF-16 code units/raw string representation + + oneof associatedValue { + string mentionAci = 3; + Style style = 4; + } +} + +message AddressableMessage { + oneof author { + string authorServiceId = 1; + string authorE164 = 2; + } + optional uint64 sentTimestamp = 3; +} + +message ConversationIdentifier { + oneof identifier { + string threadServiceId = 1; + bytes threadGroupId = 2; + string threadE164 = 3; + } } diff --git a/pkg/signalmeow/protobuf/StorageService.pb.go b/pkg/signalmeow/protobuf/StorageService.pb.go index a371ea9..3aad8ab 100644 --- a/pkg/signalmeow/protobuf/StorageService.pb.go +++ b/pkg/signalmeow/protobuf/StorageService.pb.go @@ -76,6 +76,91 @@ func (OptionalBool) EnumDescriptor() ([]byte, []int) { return file_StorageService_proto_rawDescGZIP(), []int{0} } +// If unset - computed as the value of the first byte of SHA-256(msg=CONTACT_ID) +// modulo the count of colors. Once set the avatar color for a recipient is +// never recomputed or changed. +// +// `CONTACT_ID` is the first available identifier from the list: +// - ServiceIdToBinary(ACI) +// - E164 +// - ServiceIdToBinary(PNI) +// - Group Id +type AvatarColor int32 + +const ( + AvatarColor_A100 AvatarColor = 0 + AvatarColor_A110 AvatarColor = 1 + AvatarColor_A120 AvatarColor = 2 + AvatarColor_A130 AvatarColor = 3 + AvatarColor_A140 AvatarColor = 4 + AvatarColor_A150 AvatarColor = 5 + AvatarColor_A160 AvatarColor = 6 + AvatarColor_A170 AvatarColor = 7 + AvatarColor_A180 AvatarColor = 8 + AvatarColor_A190 AvatarColor = 9 + AvatarColor_A200 AvatarColor = 10 + AvatarColor_A210 AvatarColor = 11 +) + +// Enum value maps for AvatarColor. +var ( + AvatarColor_name = map[int32]string{ + 0: "A100", + 1: "A110", + 2: "A120", + 3: "A130", + 4: "A140", + 5: "A150", + 6: "A160", + 7: "A170", + 8: "A180", + 9: "A190", + 10: "A200", + 11: "A210", + } + AvatarColor_value = map[string]int32{ + "A100": 0, + "A110": 1, + "A120": 2, + "A130": 3, + "A140": 4, + "A150": 5, + "A160": 6, + "A170": 7, + "A180": 8, + "A190": 9, + "A200": 10, + "A210": 11, + } +) + +func (x AvatarColor) Enum() *AvatarColor { + p := new(AvatarColor) + *p = x + return p +} + +func (x AvatarColor) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (AvatarColor) Descriptor() protoreflect.EnumDescriptor { + return file_StorageService_proto_enumTypes[1].Descriptor() +} + +func (AvatarColor) Type() protoreflect.EnumType { + return &file_StorageService_proto_enumTypes[1] +} + +func (x AvatarColor) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use AvatarColor.Descriptor instead. +func (AvatarColor) EnumDescriptor() ([]byte, []int) { + return file_StorageService_proto_rawDescGZIP(), []int{1} +} + type ManifestRecord_Identifier_Type int32 const ( @@ -86,6 +171,7 @@ const ( ManifestRecord_Identifier_ACCOUNT ManifestRecord_Identifier_Type = 4 ManifestRecord_Identifier_STORY_DISTRIBUTION_LIST ManifestRecord_Identifier_Type = 5 ManifestRecord_Identifier_CALL_LINK ManifestRecord_Identifier_Type = 7 + ManifestRecord_Identifier_CHAT_FOLDER ManifestRecord_Identifier_Type = 8 ) // Enum value maps for ManifestRecord_Identifier_Type. @@ -98,6 +184,7 @@ var ( 4: "ACCOUNT", 5: "STORY_DISTRIBUTION_LIST", 7: "CALL_LINK", + 8: "CHAT_FOLDER", } ManifestRecord_Identifier_Type_value = map[string]int32{ "UNKNOWN": 0, @@ -107,6 +194,7 @@ var ( "ACCOUNT": 4, "STORY_DISTRIBUTION_LIST": 5, "CALL_LINK": 7, + "CHAT_FOLDER": 8, } ) @@ -121,11 +209,11 @@ func (x ManifestRecord_Identifier_Type) String() string { } func (ManifestRecord_Identifier_Type) Descriptor() protoreflect.EnumDescriptor { - return file_StorageService_proto_enumTypes[1].Descriptor() + return file_StorageService_proto_enumTypes[2].Descriptor() } func (ManifestRecord_Identifier_Type) Type() protoreflect.EnumType { - return &file_StorageService_proto_enumTypes[1] + return &file_StorageService_proto_enumTypes[2] } func (x ManifestRecord_Identifier_Type) Number() protoreflect.EnumNumber { @@ -170,11 +258,11 @@ func (x ContactRecord_IdentityState) String() string { } func (ContactRecord_IdentityState) Descriptor() protoreflect.EnumDescriptor { - return file_StorageService_proto_enumTypes[2].Descriptor() + return file_StorageService_proto_enumTypes[3].Descriptor() } func (ContactRecord_IdentityState) Type() protoreflect.EnumType { - return &file_StorageService_proto_enumTypes[2] + return &file_StorageService_proto_enumTypes[3] } func (x ContactRecord_IdentityState) Number() protoreflect.EnumNumber { @@ -219,11 +307,11 @@ func (x GroupV2Record_StorySendMode) String() string { } func (GroupV2Record_StorySendMode) Descriptor() protoreflect.EnumDescriptor { - return file_StorageService_proto_enumTypes[3].Descriptor() + return file_StorageService_proto_enumTypes[4].Descriptor() } func (GroupV2Record_StorySendMode) Type() protoreflect.EnumType { - return &file_StorageService_proto_enumTypes[3] + return &file_StorageService_proto_enumTypes[4] } func (x GroupV2Record_StorySendMode) Number() protoreflect.EnumNumber { @@ -268,11 +356,11 @@ func (x AccountRecord_PhoneNumberSharingMode) String() string { } func (AccountRecord_PhoneNumberSharingMode) Descriptor() protoreflect.EnumDescriptor { - return file_StorageService_proto_enumTypes[4].Descriptor() + return file_StorageService_proto_enumTypes[5].Descriptor() } func (AccountRecord_PhoneNumberSharingMode) Type() protoreflect.EnumType { - return &file_StorageService_proto_enumTypes[4] + return &file_StorageService_proto_enumTypes[5] } func (x AccountRecord_PhoneNumberSharingMode) Number() protoreflect.EnumNumber { @@ -335,11 +423,11 @@ func (x AccountRecord_UsernameLink_Color) String() string { } func (AccountRecord_UsernameLink_Color) Descriptor() protoreflect.EnumDescriptor { - return file_StorageService_proto_enumTypes[5].Descriptor() + return file_StorageService_proto_enumTypes[6].Descriptor() } func (AccountRecord_UsernameLink_Color) Type() protoreflect.EnumType { - return &file_StorageService_proto_enumTypes[5] + return &file_StorageService_proto_enumTypes[6] } func (x AccountRecord_UsernameLink_Color) Number() protoreflect.EnumNumber { @@ -351,6 +439,56 @@ func (AccountRecord_UsernameLink_Color) EnumDescriptor() ([]byte, []int) { return file_StorageService_proto_rawDescGZIP(), []int{11, 1, 0} } +// Represents the default "All chats" folder record vs all other custom folders +type ChatFolderRecord_FolderType int32 + +const ( + ChatFolderRecord_UNKNOWN ChatFolderRecord_FolderType = 0 + ChatFolderRecord_ALL ChatFolderRecord_FolderType = 1 + ChatFolderRecord_CUSTOM ChatFolderRecord_FolderType = 2 +) + +// Enum value maps for ChatFolderRecord_FolderType. +var ( + ChatFolderRecord_FolderType_name = map[int32]string{ + 0: "UNKNOWN", + 1: "ALL", + 2: "CUSTOM", + } + ChatFolderRecord_FolderType_value = map[string]int32{ + "UNKNOWN": 0, + "ALL": 1, + "CUSTOM": 2, + } +) + +func (x ChatFolderRecord_FolderType) Enum() *ChatFolderRecord_FolderType { + p := new(ChatFolderRecord_FolderType) + *p = x + return p +} + +func (x ChatFolderRecord_FolderType) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (ChatFolderRecord_FolderType) Descriptor() protoreflect.EnumDescriptor { + return file_StorageService_proto_enumTypes[7].Descriptor() +} + +func (ChatFolderRecord_FolderType) Type() protoreflect.EnumType { + return &file_StorageService_proto_enumTypes[7] +} + +func (x ChatFolderRecord_FolderType) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use ChatFolderRecord_FolderType.Descriptor instead. +func (ChatFolderRecord_FolderType) EnumDescriptor() ([]byte, []int) { + return file_StorageService_proto_rawDescGZIP(), []int{14, 0} +} + type StorageManifest struct { state protoimpl.MessageState `protogen:"open.v1"` Version uint64 `protobuf:"varint,1,opt,name=version,proto3" json:"version,omitempty"` @@ -689,6 +827,7 @@ type StorageRecord struct { // *StorageRecord_Account // *StorageRecord_StoryDistributionList // *StorageRecord_CallLink + // *StorageRecord_ChatFolder Record isStorageRecord_Record `protobuf_oneof:"record"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache @@ -785,6 +924,15 @@ func (x *StorageRecord) GetCallLink() *CallLinkRecord { return nil } +func (x *StorageRecord) GetChatFolder() *ChatFolderRecord { + if x != nil { + if x, ok := x.Record.(*StorageRecord_ChatFolder); ok { + return x.ChatFolder + } + } + return nil +} + type isStorageRecord_Record interface { isStorageRecord_Record() } @@ -813,6 +961,10 @@ type StorageRecord_CallLink struct { CallLink *CallLinkRecord `protobuf:"bytes,7,opt,name=callLink,proto3,oneof"` } +type StorageRecord_ChatFolder struct { + ChatFolder *ChatFolderRecord `protobuf:"bytes,8,opt,name=chatFolder,proto3,oneof"` +} + func (*StorageRecord_Contact) isStorageRecord_Record() {} func (*StorageRecord_GroupV1) isStorageRecord_Record() {} @@ -825,6 +977,8 @@ func (*StorageRecord_StoryDistributionList) isStorageRecord_Record() {} func (*StorageRecord_CallLink) isStorageRecord_Record() {} +func (*StorageRecord_ChatFolder) isStorageRecord_Record() {} + type ContactRecord struct { state protoimpl.MessageState `protogen:"open.v1"` Aci string `protobuf:"bytes,1,opt,name=aci,proto3" json:"aci,omitempty"` @@ -849,7 +1003,8 @@ type ContactRecord struct { Hidden bool `protobuf:"varint,20,opt,name=hidden,proto3" json:"hidden,omitempty"` PniSignatureVerified bool `protobuf:"varint,21,opt,name=pniSignatureVerified,proto3" json:"pniSignatureVerified,omitempty"` Nickname *ContactRecord_Name `protobuf:"bytes,22,opt,name=nickname,proto3" json:"nickname,omitempty"` - Note string `protobuf:"bytes,23,opt,name=note,proto3" json:"note,omitempty"` // NEXT ID: 24 + Note string `protobuf:"bytes,23,opt,name=note,proto3" json:"note,omitempty"` + AvatarColor *AvatarColor `protobuf:"varint,24,opt,name=avatarColor,proto3,enum=signalservice.AvatarColor,oneof" json:"avatarColor,omitempty"` // Next ID: 25 unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } @@ -1045,6 +1200,13 @@ func (x *ContactRecord) GetNote() string { return "" } +func (x *ContactRecord) GetAvatarColor() AvatarColor { + if x != nil && x.AvatarColor != nil { + return *x.AvatarColor + } + return AvatarColor_A100 +} + type GroupV1Record struct { state protoimpl.MessageState `protogen:"open.v1"` Id []byte `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` @@ -1140,6 +1302,7 @@ type GroupV2Record struct { DontNotifyForMentionsIfMuted bool `protobuf:"varint,7,opt,name=dontNotifyForMentionsIfMuted,proto3" json:"dontNotifyForMentionsIfMuted,omitempty"` HideStory bool `protobuf:"varint,8,opt,name=hideStory,proto3" json:"hideStory,omitempty"` StorySendMode GroupV2Record_StorySendMode `protobuf:"varint,10,opt,name=storySendMode,proto3,enum=signalservice.GroupV2Record_StorySendMode" json:"storySendMode,omitempty"` + AvatarColor *AvatarColor `protobuf:"varint,11,opt,name=avatarColor,proto3,enum=signalservice.AvatarColor,oneof" json:"avatarColor,omitempty"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } @@ -1237,6 +1400,13 @@ func (x *GroupV2Record) GetStorySendMode() GroupV2Record_StorySendMode { return GroupV2Record_DEFAULT } +func (x *GroupV2Record) GetAvatarColor() AvatarColor { + if x != nil && x.AvatarColor != nil { + return *x.AvatarColor + } + return AvatarColor_A100 +} + type Payments struct { state protoimpl.MessageState `protogen:"open.v1"` Enabled bool `protobuf:"varint,1,opt,name=enabled,proto3" json:"enabled,omitempty"` @@ -1326,6 +1496,7 @@ type AccountRecord struct { HasBackup *bool `protobuf:"varint,39,opt,name=hasBackup,proto3,oneof" json:"hasBackup,omitempty"` // Set to true after backups are enabled and one is uploaded. BackupTier *uint64 `protobuf:"varint,40,opt,name=backupTier,proto3,oneof" json:"backupTier,omitempty"` // See zkgroup for integer particular values BackupSubscriberData *AccountRecord_IAPSubscriberData `protobuf:"bytes,41,opt,name=backupSubscriberData,proto3" json:"backupSubscriberData,omitempty"` + AvatarColor *AvatarColor `protobuf:"varint,42,opt,name=avatarColor,proto3,enum=signalservice.AvatarColor,oneof" json:"avatarColor,omitempty"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } @@ -1605,6 +1776,13 @@ func (x *AccountRecord) GetBackupSubscriberData() *AccountRecord_IAPSubscriberDa return nil } +func (x *AccountRecord) GetAvatarColor() AvatarColor { + if x != nil && x.AvatarColor != nil { + return *x.AvatarColor + } + return AvatarColor_A100 +} + type StoryDistributionListRecord struct { state protoimpl.MessageState `protogen:"open.v1"` Identifier []byte `protobuf:"bytes,1,opt,name=identifier,proto3" json:"identifier,omitempty"` @@ -1749,6 +1927,130 @@ func (x *CallLinkRecord) GetDeletedAtTimestampMs() uint64 { return 0 } +type ChatFolderRecord struct { + state protoimpl.MessageState `protogen:"open.v1"` + Identifier []byte `protobuf:"bytes,1,opt,name=identifier,proto3" json:"identifier,omitempty"` + Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` + Position uint32 `protobuf:"varint,3,opt,name=position,proto3" json:"position,omitempty"` + ShowOnlyUnread bool `protobuf:"varint,4,opt,name=showOnlyUnread,proto3" json:"showOnlyUnread,omitempty"` + ShowMutedChats bool `protobuf:"varint,5,opt,name=showMutedChats,proto3" json:"showMutedChats,omitempty"` + IncludeAllIndividualChats bool `protobuf:"varint,6,opt,name=includeAllIndividualChats,proto3" json:"includeAllIndividualChats,omitempty"` // Folder includes all 1:1 chats, unless excluded + IncludeAllGroupChats bool `protobuf:"varint,7,opt,name=includeAllGroupChats,proto3" json:"includeAllGroupChats,omitempty"` // Folder includes all group chats, unless excluded + FolderType ChatFolderRecord_FolderType `protobuf:"varint,8,opt,name=folderType,proto3,enum=signalservice.ChatFolderRecord_FolderType" json:"folderType,omitempty"` + IncludedRecipients []*ChatFolderRecord_Recipient `protobuf:"bytes,9,rep,name=includedRecipients,proto3" json:"includedRecipients,omitempty"` + ExcludedRecipients []*ChatFolderRecord_Recipient `protobuf:"bytes,10,rep,name=excludedRecipients,proto3" json:"excludedRecipients,omitempty"` + DeletedAtTimestampMs uint64 `protobuf:"varint,11,opt,name=deletedAtTimestampMs,proto3" json:"deletedAtTimestampMs,omitempty"` // When non-zero, `position` should be set to -1 and includedRecipients should be empty + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ChatFolderRecord) Reset() { + *x = ChatFolderRecord{} + mi := &file_StorageService_proto_msgTypes[14] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ChatFolderRecord) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ChatFolderRecord) ProtoMessage() {} + +func (x *ChatFolderRecord) ProtoReflect() protoreflect.Message { + mi := &file_StorageService_proto_msgTypes[14] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ChatFolderRecord.ProtoReflect.Descriptor instead. +func (*ChatFolderRecord) Descriptor() ([]byte, []int) { + return file_StorageService_proto_rawDescGZIP(), []int{14} +} + +func (x *ChatFolderRecord) GetIdentifier() []byte { + if x != nil { + return x.Identifier + } + return nil +} + +func (x *ChatFolderRecord) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *ChatFolderRecord) GetPosition() uint32 { + if x != nil { + return x.Position + } + return 0 +} + +func (x *ChatFolderRecord) GetShowOnlyUnread() bool { + if x != nil { + return x.ShowOnlyUnread + } + return false +} + +func (x *ChatFolderRecord) GetShowMutedChats() bool { + if x != nil { + return x.ShowMutedChats + } + return false +} + +func (x *ChatFolderRecord) GetIncludeAllIndividualChats() bool { + if x != nil { + return x.IncludeAllIndividualChats + } + return false +} + +func (x *ChatFolderRecord) GetIncludeAllGroupChats() bool { + if x != nil { + return x.IncludeAllGroupChats + } + return false +} + +func (x *ChatFolderRecord) GetFolderType() ChatFolderRecord_FolderType { + if x != nil { + return x.FolderType + } + return ChatFolderRecord_UNKNOWN +} + +func (x *ChatFolderRecord) GetIncludedRecipients() []*ChatFolderRecord_Recipient { + if x != nil { + return x.IncludedRecipients + } + return nil +} + +func (x *ChatFolderRecord) GetExcludedRecipients() []*ChatFolderRecord_Recipient { + if x != nil { + return x.ExcludedRecipients + } + return nil +} + +func (x *ChatFolderRecord) GetDeletedAtTimestampMs() uint64 { + if x != nil { + return x.DeletedAtTimestampMs + } + return 0 +} + type ManifestRecord_Identifier struct { state protoimpl.MessageState `protogen:"open.v1"` Raw []byte `protobuf:"bytes,1,opt,name=raw,proto3" json:"raw,omitempty"` @@ -1759,7 +2061,7 @@ type ManifestRecord_Identifier struct { func (x *ManifestRecord_Identifier) Reset() { *x = ManifestRecord_Identifier{} - mi := &file_StorageService_proto_msgTypes[14] + mi := &file_StorageService_proto_msgTypes[15] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1771,7 +2073,7 @@ func (x *ManifestRecord_Identifier) String() string { func (*ManifestRecord_Identifier) ProtoMessage() {} func (x *ManifestRecord_Identifier) ProtoReflect() protoreflect.Message { - mi := &file_StorageService_proto_msgTypes[14] + mi := &file_StorageService_proto_msgTypes[15] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1811,7 +2113,7 @@ type ContactRecord_Name struct { func (x *ContactRecord_Name) Reset() { *x = ContactRecord_Name{} - mi := &file_StorageService_proto_msgTypes[15] + mi := &file_StorageService_proto_msgTypes[16] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1823,7 +2125,7 @@ func (x *ContactRecord_Name) String() string { func (*ContactRecord_Name) ProtoMessage() {} func (x *ContactRecord_Name) ProtoReflect() protoreflect.Message { - mi := &file_StorageService_proto_msgTypes[15] + mi := &file_StorageService_proto_msgTypes[16] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1867,7 +2169,7 @@ type AccountRecord_PinnedConversation struct { func (x *AccountRecord_PinnedConversation) Reset() { *x = AccountRecord_PinnedConversation{} - mi := &file_StorageService_proto_msgTypes[16] + mi := &file_StorageService_proto_msgTypes[17] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1879,7 +2181,7 @@ func (x *AccountRecord_PinnedConversation) String() string { func (*AccountRecord_PinnedConversation) ProtoMessage() {} func (x *AccountRecord_PinnedConversation) ProtoReflect() protoreflect.Message { - mi := &file_StorageService_proto_msgTypes[16] + mi := &file_StorageService_proto_msgTypes[17] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1964,7 +2266,7 @@ type AccountRecord_UsernameLink struct { func (x *AccountRecord_UsernameLink) Reset() { *x = AccountRecord_UsernameLink{} - mi := &file_StorageService_proto_msgTypes[17] + mi := &file_StorageService_proto_msgTypes[18] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1976,7 +2278,7 @@ func (x *AccountRecord_UsernameLink) String() string { func (*AccountRecord_UsernameLink) ProtoMessage() {} func (x *AccountRecord_UsernameLink) ProtoReflect() protoreflect.Message { - mi := &file_StorageService_proto_msgTypes[17] + mi := &file_StorageService_proto_msgTypes[18] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2027,7 +2329,7 @@ type AccountRecord_IAPSubscriberData struct { func (x *AccountRecord_IAPSubscriberData) Reset() { *x = AccountRecord_IAPSubscriberData{} - mi := &file_StorageService_proto_msgTypes[18] + mi := &file_StorageService_proto_msgTypes[19] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2039,7 +2341,7 @@ func (x *AccountRecord_IAPSubscriberData) String() string { func (*AccountRecord_IAPSubscriberData) ProtoMessage() {} func (x *AccountRecord_IAPSubscriberData) ProtoReflect() protoreflect.Message { - mi := &file_StorageService_proto_msgTypes[18] + mi := &file_StorageService_proto_msgTypes[19] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2117,7 +2419,7 @@ type AccountRecord_PinnedConversation_Contact struct { func (x *AccountRecord_PinnedConversation_Contact) Reset() { *x = AccountRecord_PinnedConversation_Contact{} - mi := &file_StorageService_proto_msgTypes[19] + mi := &file_StorageService_proto_msgTypes[20] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2129,7 +2431,7 @@ func (x *AccountRecord_PinnedConversation_Contact) String() string { func (*AccountRecord_PinnedConversation_Contact) ProtoMessage() {} func (x *AccountRecord_PinnedConversation_Contact) ProtoReflect() protoreflect.Message { - mi := &file_StorageService_proto_msgTypes[19] + mi := &file_StorageService_proto_msgTypes[20] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2159,6 +2461,156 @@ func (x *AccountRecord_PinnedConversation_Contact) GetE164() string { return "" } +type ChatFolderRecord_Recipient struct { + state protoimpl.MessageState `protogen:"open.v1"` + // Types that are valid to be assigned to Identifier: + // + // *ChatFolderRecord_Recipient_Contact_ + // *ChatFolderRecord_Recipient_LegacyGroupId + // *ChatFolderRecord_Recipient_GroupMasterKey + Identifier isChatFolderRecord_Recipient_Identifier `protobuf_oneof:"identifier"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ChatFolderRecord_Recipient) Reset() { + *x = ChatFolderRecord_Recipient{} + mi := &file_StorageService_proto_msgTypes[21] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ChatFolderRecord_Recipient) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ChatFolderRecord_Recipient) ProtoMessage() {} + +func (x *ChatFolderRecord_Recipient) ProtoReflect() protoreflect.Message { + mi := &file_StorageService_proto_msgTypes[21] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ChatFolderRecord_Recipient.ProtoReflect.Descriptor instead. +func (*ChatFolderRecord_Recipient) Descriptor() ([]byte, []int) { + return file_StorageService_proto_rawDescGZIP(), []int{14, 0} +} + +func (x *ChatFolderRecord_Recipient) GetIdentifier() isChatFolderRecord_Recipient_Identifier { + if x != nil { + return x.Identifier + } + return nil +} + +func (x *ChatFolderRecord_Recipient) GetContact() *ChatFolderRecord_Recipient_Contact { + if x != nil { + if x, ok := x.Identifier.(*ChatFolderRecord_Recipient_Contact_); ok { + return x.Contact + } + } + return nil +} + +func (x *ChatFolderRecord_Recipient) GetLegacyGroupId() []byte { + if x != nil { + if x, ok := x.Identifier.(*ChatFolderRecord_Recipient_LegacyGroupId); ok { + return x.LegacyGroupId + } + } + return nil +} + +func (x *ChatFolderRecord_Recipient) GetGroupMasterKey() []byte { + if x != nil { + if x, ok := x.Identifier.(*ChatFolderRecord_Recipient_GroupMasterKey); ok { + return x.GroupMasterKey + } + } + return nil +} + +type isChatFolderRecord_Recipient_Identifier interface { + isChatFolderRecord_Recipient_Identifier() +} + +type ChatFolderRecord_Recipient_Contact_ struct { + Contact *ChatFolderRecord_Recipient_Contact `protobuf:"bytes,1,opt,name=contact,proto3,oneof"` +} + +type ChatFolderRecord_Recipient_LegacyGroupId struct { + LegacyGroupId []byte `protobuf:"bytes,2,opt,name=legacyGroupId,proto3,oneof"` +} + +type ChatFolderRecord_Recipient_GroupMasterKey struct { + GroupMasterKey []byte `protobuf:"bytes,3,opt,name=groupMasterKey,proto3,oneof"` +} + +func (*ChatFolderRecord_Recipient_Contact_) isChatFolderRecord_Recipient_Identifier() {} + +func (*ChatFolderRecord_Recipient_LegacyGroupId) isChatFolderRecord_Recipient_Identifier() {} + +func (*ChatFolderRecord_Recipient_GroupMasterKey) isChatFolderRecord_Recipient_Identifier() {} + +type ChatFolderRecord_Recipient_Contact struct { + state protoimpl.MessageState `protogen:"open.v1"` + ServiceId string `protobuf:"bytes,1,opt,name=serviceId,proto3" json:"serviceId,omitempty"` + E164 string `protobuf:"bytes,2,opt,name=e164,proto3" json:"e164,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ChatFolderRecord_Recipient_Contact) Reset() { + *x = ChatFolderRecord_Recipient_Contact{} + mi := &file_StorageService_proto_msgTypes[22] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ChatFolderRecord_Recipient_Contact) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ChatFolderRecord_Recipient_Contact) ProtoMessage() {} + +func (x *ChatFolderRecord_Recipient_Contact) ProtoReflect() protoreflect.Message { + mi := &file_StorageService_proto_msgTypes[22] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ChatFolderRecord_Recipient_Contact.ProtoReflect.Descriptor instead. +func (*ChatFolderRecord_Recipient_Contact) Descriptor() ([]byte, []int) { + return file_StorageService_proto_rawDescGZIP(), []int{14, 0, 0} +} + +func (x *ChatFolderRecord_Recipient_Contact) GetServiceId() string { + if x != nil { + return x.ServiceId + } + return "" +} + +func (x *ChatFolderRecord_Recipient_Contact) GetE164() string { + if x != nil { + return x.E164 + } + return "" +} + var File_StorageService_proto protoreflect.FileDescriptor //go:embed StorageService.pb.raw @@ -2176,64 +2628,77 @@ func file_StorageService_proto_rawDescGZIP() []byte { return file_StorageService_proto_rawDescData } -var file_StorageService_proto_enumTypes = make([]protoimpl.EnumInfo, 6) -var file_StorageService_proto_msgTypes = make([]protoimpl.MessageInfo, 20) +var file_StorageService_proto_enumTypes = make([]protoimpl.EnumInfo, 8) +var file_StorageService_proto_msgTypes = make([]protoimpl.MessageInfo, 23) var file_StorageService_proto_goTypes = []any{ (OptionalBool)(0), // 0: signalservice.OptionalBool - (ManifestRecord_Identifier_Type)(0), // 1: signalservice.ManifestRecord.Identifier.Type - (ContactRecord_IdentityState)(0), // 2: signalservice.ContactRecord.IdentityState - (GroupV2Record_StorySendMode)(0), // 3: signalservice.GroupV2Record.StorySendMode - (AccountRecord_PhoneNumberSharingMode)(0), // 4: signalservice.AccountRecord.PhoneNumberSharingMode - (AccountRecord_UsernameLink_Color)(0), // 5: signalservice.AccountRecord.UsernameLink.Color - (*StorageManifest)(nil), // 6: signalservice.StorageManifest - (*StorageItem)(nil), // 7: signalservice.StorageItem - (*StorageItems)(nil), // 8: signalservice.StorageItems - (*ReadOperation)(nil), // 9: signalservice.ReadOperation - (*WriteOperation)(nil), // 10: signalservice.WriteOperation - (*ManifestRecord)(nil), // 11: signalservice.ManifestRecord - (*StorageRecord)(nil), // 12: signalservice.StorageRecord - (*ContactRecord)(nil), // 13: signalservice.ContactRecord - (*GroupV1Record)(nil), // 14: signalservice.GroupV1Record - (*GroupV2Record)(nil), // 15: signalservice.GroupV2Record - (*Payments)(nil), // 16: signalservice.Payments - (*AccountRecord)(nil), // 17: signalservice.AccountRecord - (*StoryDistributionListRecord)(nil), // 18: signalservice.StoryDistributionListRecord - (*CallLinkRecord)(nil), // 19: signalservice.CallLinkRecord - (*ManifestRecord_Identifier)(nil), // 20: signalservice.ManifestRecord.Identifier - (*ContactRecord_Name)(nil), // 21: signalservice.ContactRecord.Name - (*AccountRecord_PinnedConversation)(nil), // 22: signalservice.AccountRecord.PinnedConversation - (*AccountRecord_UsernameLink)(nil), // 23: signalservice.AccountRecord.UsernameLink - (*AccountRecord_IAPSubscriberData)(nil), // 24: signalservice.AccountRecord.IAPSubscriberData - (*AccountRecord_PinnedConversation_Contact)(nil), // 25: signalservice.AccountRecord.PinnedConversation.Contact + (AvatarColor)(0), // 1: signalservice.AvatarColor + (ManifestRecord_Identifier_Type)(0), // 2: signalservice.ManifestRecord.Identifier.Type + (ContactRecord_IdentityState)(0), // 3: signalservice.ContactRecord.IdentityState + (GroupV2Record_StorySendMode)(0), // 4: signalservice.GroupV2Record.StorySendMode + (AccountRecord_PhoneNumberSharingMode)(0), // 5: signalservice.AccountRecord.PhoneNumberSharingMode + (AccountRecord_UsernameLink_Color)(0), // 6: signalservice.AccountRecord.UsernameLink.Color + (ChatFolderRecord_FolderType)(0), // 7: signalservice.ChatFolderRecord.FolderType + (*StorageManifest)(nil), // 8: signalservice.StorageManifest + (*StorageItem)(nil), // 9: signalservice.StorageItem + (*StorageItems)(nil), // 10: signalservice.StorageItems + (*ReadOperation)(nil), // 11: signalservice.ReadOperation + (*WriteOperation)(nil), // 12: signalservice.WriteOperation + (*ManifestRecord)(nil), // 13: signalservice.ManifestRecord + (*StorageRecord)(nil), // 14: signalservice.StorageRecord + (*ContactRecord)(nil), // 15: signalservice.ContactRecord + (*GroupV1Record)(nil), // 16: signalservice.GroupV1Record + (*GroupV2Record)(nil), // 17: signalservice.GroupV2Record + (*Payments)(nil), // 18: signalservice.Payments + (*AccountRecord)(nil), // 19: signalservice.AccountRecord + (*StoryDistributionListRecord)(nil), // 20: signalservice.StoryDistributionListRecord + (*CallLinkRecord)(nil), // 21: signalservice.CallLinkRecord + (*ChatFolderRecord)(nil), // 22: signalservice.ChatFolderRecord + (*ManifestRecord_Identifier)(nil), // 23: signalservice.ManifestRecord.Identifier + (*ContactRecord_Name)(nil), // 24: signalservice.ContactRecord.Name + (*AccountRecord_PinnedConversation)(nil), // 25: signalservice.AccountRecord.PinnedConversation + (*AccountRecord_UsernameLink)(nil), // 26: signalservice.AccountRecord.UsernameLink + (*AccountRecord_IAPSubscriberData)(nil), // 27: signalservice.AccountRecord.IAPSubscriberData + (*AccountRecord_PinnedConversation_Contact)(nil), // 28: signalservice.AccountRecord.PinnedConversation.Contact + (*ChatFolderRecord_Recipient)(nil), // 29: signalservice.ChatFolderRecord.Recipient + (*ChatFolderRecord_Recipient_Contact)(nil), // 30: signalservice.ChatFolderRecord.Recipient.Contact } var file_StorageService_proto_depIdxs = []int32{ - 7, // 0: signalservice.StorageItems.items:type_name -> signalservice.StorageItem - 6, // 1: signalservice.WriteOperation.manifest:type_name -> signalservice.StorageManifest - 7, // 2: signalservice.WriteOperation.insertItem:type_name -> signalservice.StorageItem - 20, // 3: signalservice.ManifestRecord.identifiers:type_name -> signalservice.ManifestRecord.Identifier - 13, // 4: signalservice.StorageRecord.contact:type_name -> signalservice.ContactRecord - 14, // 5: signalservice.StorageRecord.groupV1:type_name -> signalservice.GroupV1Record - 15, // 6: signalservice.StorageRecord.groupV2:type_name -> signalservice.GroupV2Record - 17, // 7: signalservice.StorageRecord.account:type_name -> signalservice.AccountRecord - 18, // 8: signalservice.StorageRecord.storyDistributionList:type_name -> signalservice.StoryDistributionListRecord - 19, // 9: signalservice.StorageRecord.callLink:type_name -> signalservice.CallLinkRecord - 2, // 10: signalservice.ContactRecord.identityState:type_name -> signalservice.ContactRecord.IdentityState - 21, // 11: signalservice.ContactRecord.nickname:type_name -> signalservice.ContactRecord.Name - 3, // 12: signalservice.GroupV2Record.storySendMode:type_name -> signalservice.GroupV2Record.StorySendMode - 4, // 13: signalservice.AccountRecord.phoneNumberSharingMode:type_name -> signalservice.AccountRecord.PhoneNumberSharingMode - 22, // 14: signalservice.AccountRecord.pinnedConversations:type_name -> signalservice.AccountRecord.PinnedConversation - 16, // 15: signalservice.AccountRecord.payments:type_name -> signalservice.Payments - 0, // 16: signalservice.AccountRecord.storyViewReceiptsEnabled:type_name -> signalservice.OptionalBool - 23, // 17: signalservice.AccountRecord.usernameLink:type_name -> signalservice.AccountRecord.UsernameLink - 24, // 18: signalservice.AccountRecord.backupSubscriberData:type_name -> signalservice.AccountRecord.IAPSubscriberData - 1, // 19: signalservice.ManifestRecord.Identifier.type:type_name -> signalservice.ManifestRecord.Identifier.Type - 25, // 20: signalservice.AccountRecord.PinnedConversation.contact:type_name -> signalservice.AccountRecord.PinnedConversation.Contact - 5, // 21: signalservice.AccountRecord.UsernameLink.color:type_name -> signalservice.AccountRecord.UsernameLink.Color - 22, // [22:22] is the sub-list for method output_type - 22, // [22:22] is the sub-list for method input_type - 22, // [22:22] is the sub-list for extension type_name - 22, // [22:22] is the sub-list for extension extendee - 0, // [0:22] is the sub-list for field type_name + 9, // 0: signalservice.StorageItems.items:type_name -> signalservice.StorageItem + 8, // 1: signalservice.WriteOperation.manifest:type_name -> signalservice.StorageManifest + 9, // 2: signalservice.WriteOperation.insertItem:type_name -> signalservice.StorageItem + 23, // 3: signalservice.ManifestRecord.identifiers:type_name -> signalservice.ManifestRecord.Identifier + 15, // 4: signalservice.StorageRecord.contact:type_name -> signalservice.ContactRecord + 16, // 5: signalservice.StorageRecord.groupV1:type_name -> signalservice.GroupV1Record + 17, // 6: signalservice.StorageRecord.groupV2:type_name -> signalservice.GroupV2Record + 19, // 7: signalservice.StorageRecord.account:type_name -> signalservice.AccountRecord + 20, // 8: signalservice.StorageRecord.storyDistributionList:type_name -> signalservice.StoryDistributionListRecord + 21, // 9: signalservice.StorageRecord.callLink:type_name -> signalservice.CallLinkRecord + 22, // 10: signalservice.StorageRecord.chatFolder:type_name -> signalservice.ChatFolderRecord + 3, // 11: signalservice.ContactRecord.identityState:type_name -> signalservice.ContactRecord.IdentityState + 24, // 12: signalservice.ContactRecord.nickname:type_name -> signalservice.ContactRecord.Name + 1, // 13: signalservice.ContactRecord.avatarColor:type_name -> signalservice.AvatarColor + 4, // 14: signalservice.GroupV2Record.storySendMode:type_name -> signalservice.GroupV2Record.StorySendMode + 1, // 15: signalservice.GroupV2Record.avatarColor:type_name -> signalservice.AvatarColor + 5, // 16: signalservice.AccountRecord.phoneNumberSharingMode:type_name -> signalservice.AccountRecord.PhoneNumberSharingMode + 25, // 17: signalservice.AccountRecord.pinnedConversations:type_name -> signalservice.AccountRecord.PinnedConversation + 18, // 18: signalservice.AccountRecord.payments:type_name -> signalservice.Payments + 0, // 19: signalservice.AccountRecord.storyViewReceiptsEnabled:type_name -> signalservice.OptionalBool + 26, // 20: signalservice.AccountRecord.usernameLink:type_name -> signalservice.AccountRecord.UsernameLink + 27, // 21: signalservice.AccountRecord.backupSubscriberData:type_name -> signalservice.AccountRecord.IAPSubscriberData + 1, // 22: signalservice.AccountRecord.avatarColor:type_name -> signalservice.AvatarColor + 7, // 23: signalservice.ChatFolderRecord.folderType:type_name -> signalservice.ChatFolderRecord.FolderType + 29, // 24: signalservice.ChatFolderRecord.includedRecipients:type_name -> signalservice.ChatFolderRecord.Recipient + 29, // 25: signalservice.ChatFolderRecord.excludedRecipients:type_name -> signalservice.ChatFolderRecord.Recipient + 2, // 26: signalservice.ManifestRecord.Identifier.type:type_name -> signalservice.ManifestRecord.Identifier.Type + 28, // 27: signalservice.AccountRecord.PinnedConversation.contact:type_name -> signalservice.AccountRecord.PinnedConversation.Contact + 6, // 28: signalservice.AccountRecord.UsernameLink.color:type_name -> signalservice.AccountRecord.UsernameLink.Color + 30, // 29: signalservice.ChatFolderRecord.Recipient.contact:type_name -> signalservice.ChatFolderRecord.Recipient.Contact + 30, // [30:30] is the sub-list for method output_type + 30, // [30:30] is the sub-list for method input_type + 30, // [30:30] is the sub-list for extension type_name + 30, // [30:30] is the sub-list for extension extendee + 0, // [0:30] is the sub-list for field type_name } func init() { file_StorageService_proto_init() } @@ -2248,24 +2713,32 @@ func file_StorageService_proto_init() { (*StorageRecord_Account)(nil), (*StorageRecord_StoryDistributionList)(nil), (*StorageRecord_CallLink)(nil), + (*StorageRecord_ChatFolder)(nil), } + file_StorageService_proto_msgTypes[7].OneofWrappers = []any{} + file_StorageService_proto_msgTypes[9].OneofWrappers = []any{} file_StorageService_proto_msgTypes[11].OneofWrappers = []any{} - file_StorageService_proto_msgTypes[16].OneofWrappers = []any{ + file_StorageService_proto_msgTypes[17].OneofWrappers = []any{ (*AccountRecord_PinnedConversation_Contact_)(nil), (*AccountRecord_PinnedConversation_LegacyGroupId)(nil), (*AccountRecord_PinnedConversation_GroupMasterKey)(nil), } - file_StorageService_proto_msgTypes[18].OneofWrappers = []any{ + file_StorageService_proto_msgTypes[19].OneofWrappers = []any{ (*AccountRecord_IAPSubscriberData_PurchaseToken)(nil), (*AccountRecord_IAPSubscriberData_OriginalTransactionId)(nil), } + file_StorageService_proto_msgTypes[21].OneofWrappers = []any{ + (*ChatFolderRecord_Recipient_Contact_)(nil), + (*ChatFolderRecord_Recipient_LegacyGroupId)(nil), + (*ChatFolderRecord_Recipient_GroupMasterKey)(nil), + } type x struct{} out := protoimpl.TypeBuilder{ File: protoimpl.DescBuilder{ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_StorageService_proto_rawDesc, - NumEnums: 6, - NumMessages: 20, + NumEnums: 8, + NumMessages: 23, NumExtensions: 0, NumServices: 0, }, diff --git a/pkg/signalmeow/protobuf/StorageService.pb.raw b/pkg/signalmeow/protobuf/StorageService.pb.raw index 9c6689d9adaa8592bc569b23dfe69630c4881315..1e4142f2f966d232fa2d25f4dc748e115b3520bd 100644 GIT binary patch delta 1236 zcmbW0zi-n(9L0Nf5<6eh^mKvN%|aCk)OLuj1`4GtX`n5oZIEdNOqH=sYss=BCn_C+#(4?ZB zE!CZE&v5H@u_S zU&izwGlbqn+EaNVj`VEOzB+n)mH^9&+^^ z|54R*_cp!2HY_#8CuF_n^!MCavte5ud|ge)bMYy;2IG!rx=qV2yY5ZTa(11T)im75 zlL^k%$6G&OVHt zSt%SN$acSmtbt_uUc)dOD&j+mHuKk;uqXL*NMHx~NhGqPyg`d4fcWl+0@CLCt@Y~N zbv#5Q5X-Bp7!iO>W%JHPbqx#b+t_St`Y8e>@oy3tQso&+xhGUJl$%1OQ7lC20>xsa sE>fI|)Fq13k(#AA6RFD-OOd)lu^g#6inF28cm|Mc2d(iCg{kV|FG9n1!~g&Q delta 101 zcmV-r0Gj{1JKiv`(g6XHlhXmZ0oId_0%HMllk);|0wSWbc>|dN4MGSC26AO%Z*pWJ z$_KMz1y}=<{RncCe+kh7&I7Yj3XcJkBn&x|Z45^Nq_edQZwIqy6cPioi5I5 signal.backup.AccountData - 33, // 1: signal.backup.Frame.recipient:type_name -> signal.backup.Recipient - 38, // 2: signal.backup.Frame.chat:type_name -> signal.backup.Chat - 43, // 3: signal.backup.Frame.chatItem:type_name -> signal.backup.ChatItem - 106, // 4: signal.backup.Frame.stickerPack:type_name -> signal.backup.StickerPack - 40, // 5: signal.backup.Frame.adHocCall:type_name -> signal.backup.AdHocCall - 108, // 6: signal.backup.Frame.notificationProfile:type_name -> signal.backup.NotificationProfile - 109, // 7: signal.backup.Frame.chatFolder:type_name -> signal.backup.ChatFolder - 110, // 8: signal.backup.AccountData.usernameLink:type_name -> signal.backup.AccountData.UsernameLink - 112, // 9: signal.backup.AccountData.donationSubscriberData:type_name -> signal.backup.AccountData.SubscriberData - 111, // 10: signal.backup.AccountData.accountSettings:type_name -> signal.backup.AccountData.AccountSettings - 113, // 11: signal.backup.AccountData.backupsSubscriberData:type_name -> signal.backup.AccountData.IAPSubscriberData - 34, // 12: signal.backup.Recipient.contact:type_name -> signal.backup.Contact - 35, // 13: signal.backup.Recipient.group:type_name -> signal.backup.Group - 41, // 14: signal.backup.Recipient.distributionList:type_name -> signal.backup.DistributionListItem - 36, // 15: signal.backup.Recipient.self:type_name -> signal.backup.Self - 37, // 16: signal.backup.Recipient.releaseNotes:type_name -> signal.backup.ReleaseNotes - 39, // 17: signal.backup.Recipient.callLink:type_name -> signal.backup.CallLink - 4, // 18: signal.backup.Contact.visibility:type_name -> signal.backup.Contact.Visibility - 114, // 19: signal.backup.Contact.registered:type_name -> signal.backup.Contact.Registered - 115, // 20: signal.backup.Contact.notRegistered:type_name -> signal.backup.Contact.NotRegistered - 3, // 21: signal.backup.Contact.identityState:type_name -> signal.backup.Contact.IdentityState - 116, // 22: signal.backup.Contact.nickname:type_name -> signal.backup.Contact.Name - 5, // 23: signal.backup.Group.storySendMode:type_name -> signal.backup.Group.StorySendMode - 117, // 24: signal.backup.Group.snapshot:type_name -> signal.backup.Group.GroupSnapshot - 107, // 25: signal.backup.Chat.style:type_name -> signal.backup.ChatStyle - 8, // 26: signal.backup.CallLink.restrictions:type_name -> signal.backup.CallLink.Restrictions - 9, // 27: signal.backup.AdHocCall.state:type_name -> signal.backup.AdHocCall.State - 42, // 28: signal.backup.DistributionListItem.distributionList:type_name -> signal.backup.DistributionList - 10, // 29: signal.backup.DistributionList.privacyMode:type_name -> signal.backup.DistributionList.PrivacyMode - 43, // 30: signal.backup.ChatItem.revisions:type_name -> signal.backup.ChatItem - 124, // 31: signal.backup.ChatItem.incoming:type_name -> signal.backup.ChatItem.IncomingMessageDetails - 125, // 32: signal.backup.ChatItem.outgoing:type_name -> signal.backup.ChatItem.OutgoingMessageDetails - 126, // 33: signal.backup.ChatItem.directionless:type_name -> signal.backup.ChatItem.DirectionlessMessageDetails - 46, // 34: signal.backup.ChatItem.standardMessage:type_name -> signal.backup.StandardMessage - 47, // 35: signal.backup.ChatItem.contactMessage:type_name -> signal.backup.ContactMessage - 53, // 36: signal.backup.ChatItem.stickerMessage:type_name -> signal.backup.StickerMessage - 54, // 37: signal.backup.ChatItem.remoteDeletedMessage:type_name -> signal.backup.RemoteDeletedMessage - 62, // 38: signal.backup.ChatItem.updateMessage:type_name -> signal.backup.ChatUpdateMessage - 49, // 39: signal.backup.ChatItem.paymentNotification:type_name -> signal.backup.PaymentNotification - 50, // 40: signal.backup.ChatItem.giftBadge:type_name -> signal.backup.GiftBadge - 51, // 41: signal.backup.ChatItem.viewOnceMessage:type_name -> signal.backup.ViewOnceMessage - 48, // 42: signal.backup.ChatItem.directStoryReplyMessage:type_name -> signal.backup.DirectStoryReplyMessage - 127, // 43: signal.backup.SendStatus.pending:type_name -> signal.backup.SendStatus.Pending - 128, // 44: signal.backup.SendStatus.sent:type_name -> signal.backup.SendStatus.Sent - 129, // 45: signal.backup.SendStatus.delivered:type_name -> signal.backup.SendStatus.Delivered - 130, // 46: signal.backup.SendStatus.read:type_name -> signal.backup.SendStatus.Read - 131, // 47: signal.backup.SendStatus.viewed:type_name -> signal.backup.SendStatus.Viewed - 132, // 48: signal.backup.SendStatus.skipped:type_name -> signal.backup.SendStatus.Skipped - 133, // 49: signal.backup.SendStatus.failed:type_name -> signal.backup.SendStatus.Failed - 60, // 50: signal.backup.Text.bodyRanges:type_name -> signal.backup.BodyRange - 59, // 51: signal.backup.StandardMessage.quote:type_name -> signal.backup.Quote - 45, // 52: signal.backup.StandardMessage.text:type_name -> signal.backup.Text - 57, // 53: signal.backup.StandardMessage.attachments:type_name -> signal.backup.MessageAttachment - 56, // 54: signal.backup.StandardMessage.linkPreview:type_name -> signal.backup.LinkPreview - 58, // 55: signal.backup.StandardMessage.longText:type_name -> signal.backup.FilePointer - 61, // 56: signal.backup.StandardMessage.reactions:type_name -> signal.backup.Reaction - 52, // 57: signal.backup.ContactMessage.contact:type_name -> signal.backup.ContactAttachment - 61, // 58: signal.backup.ContactMessage.reactions:type_name -> signal.backup.Reaction - 134, // 59: signal.backup.DirectStoryReplyMessage.textReply:type_name -> signal.backup.DirectStoryReplyMessage.TextReply - 61, // 60: signal.backup.DirectStoryReplyMessage.reactions:type_name -> signal.backup.Reaction - 135, // 61: signal.backup.PaymentNotification.transactionDetails:type_name -> signal.backup.PaymentNotification.TransactionDetails - 14, // 62: signal.backup.GiftBadge.state:type_name -> signal.backup.GiftBadge.State - 57, // 63: signal.backup.ViewOnceMessage.attachment:type_name -> signal.backup.MessageAttachment - 61, // 64: signal.backup.ViewOnceMessage.reactions:type_name -> signal.backup.Reaction - 139, // 65: signal.backup.ContactAttachment.name:type_name -> signal.backup.ContactAttachment.Name - 140, // 66: signal.backup.ContactAttachment.number:type_name -> signal.backup.ContactAttachment.Phone - 141, // 67: signal.backup.ContactAttachment.email:type_name -> signal.backup.ContactAttachment.Email - 142, // 68: signal.backup.ContactAttachment.address:type_name -> signal.backup.ContactAttachment.PostalAddress - 58, // 69: signal.backup.ContactAttachment.avatar:type_name -> signal.backup.FilePointer - 55, // 70: signal.backup.StickerMessage.sticker:type_name -> signal.backup.Sticker - 61, // 71: signal.backup.StickerMessage.reactions:type_name -> signal.backup.Reaction - 58, // 72: signal.backup.Sticker.data:type_name -> signal.backup.FilePointer - 58, // 73: signal.backup.LinkPreview.image:type_name -> signal.backup.FilePointer - 58, // 74: signal.backup.MessageAttachment.pointer:type_name -> signal.backup.FilePointer - 18, // 75: signal.backup.MessageAttachment.flag:type_name -> signal.backup.MessageAttachment.Flag - 143, // 76: signal.backup.FilePointer.backupLocator:type_name -> signal.backup.FilePointer.BackupLocator - 144, // 77: signal.backup.FilePointer.attachmentLocator:type_name -> signal.backup.FilePointer.AttachmentLocator - 145, // 78: signal.backup.FilePointer.invalidAttachmentLocator:type_name -> signal.backup.FilePointer.InvalidAttachmentLocator - 45, // 79: signal.backup.Quote.text:type_name -> signal.backup.Text - 146, // 80: signal.backup.Quote.attachments:type_name -> signal.backup.Quote.QuotedAttachment - 19, // 81: signal.backup.Quote.type:type_name -> signal.backup.Quote.Type - 20, // 82: signal.backup.BodyRange.style:type_name -> signal.backup.BodyRange.Style - 65, // 83: signal.backup.ChatUpdateMessage.simpleUpdate:type_name -> signal.backup.SimpleChatUpdate - 71, // 84: signal.backup.ChatUpdateMessage.groupChange:type_name -> signal.backup.GroupChangeChatUpdate - 66, // 85: signal.backup.ChatUpdateMessage.expirationTimerChange:type_name -> signal.backup.ExpirationTimerChatUpdate - 67, // 86: signal.backup.ChatUpdateMessage.profileChange:type_name -> signal.backup.ProfileChangeChatUpdate - 69, // 87: signal.backup.ChatUpdateMessage.threadMerge:type_name -> signal.backup.ThreadMergeChatUpdate - 70, // 88: signal.backup.ChatUpdateMessage.sessionSwitchover:type_name -> signal.backup.SessionSwitchoverChatUpdate - 63, // 89: signal.backup.ChatUpdateMessage.individualCall:type_name -> signal.backup.IndividualCall - 64, // 90: signal.backup.ChatUpdateMessage.groupCall:type_name -> signal.backup.GroupCall - 68, // 91: signal.backup.ChatUpdateMessage.learnedProfileChange:type_name -> signal.backup.LearnedProfileChatUpdate - 21, // 92: signal.backup.IndividualCall.type:type_name -> signal.backup.IndividualCall.Type - 22, // 93: signal.backup.IndividualCall.direction:type_name -> signal.backup.IndividualCall.Direction - 23, // 94: signal.backup.IndividualCall.state:type_name -> signal.backup.IndividualCall.State - 24, // 95: signal.backup.GroupCall.state:type_name -> signal.backup.GroupCall.State - 25, // 96: signal.backup.SimpleChatUpdate.type:type_name -> signal.backup.SimpleChatUpdate.Type - 147, // 97: signal.backup.GroupChangeChatUpdate.updates:type_name -> signal.backup.GroupChangeChatUpdate.Update - 0, // 98: signal.backup.GroupMembershipAccessLevelChangeUpdate.accessLevel:type_name -> signal.backup.GroupV2AccessLevel - 0, // 99: signal.backup.GroupAttributesAccessLevelChangeUpdate.accessLevel:type_name -> signal.backup.GroupV2AccessLevel - 148, // 100: signal.backup.GroupInvitationRevokedUpdate.invitees:type_name -> signal.backup.GroupInvitationRevokedUpdate.Invitee - 26, // 101: signal.backup.ChatStyle.wallpaperPreset:type_name -> signal.backup.ChatStyle.WallpaperPreset - 58, // 102: signal.backup.ChatStyle.wallpaperPhoto:type_name -> signal.backup.FilePointer - 151, // 103: signal.backup.ChatStyle.autoBubbleColor:type_name -> signal.backup.ChatStyle.AutomaticBubbleColor - 27, // 104: signal.backup.ChatStyle.bubbleColorPreset:type_name -> signal.backup.ChatStyle.BubbleColorPreset - 28, // 105: signal.backup.NotificationProfile.scheduleDaysEnabled:type_name -> signal.backup.NotificationProfile.DayOfWeek - 29, // 106: signal.backup.ChatFolder.folderType:type_name -> signal.backup.ChatFolder.FolderType - 2, // 107: signal.backup.AccountData.UsernameLink.color:type_name -> signal.backup.AccountData.UsernameLink.Color - 1, // 108: signal.backup.AccountData.AccountSettings.phoneNumberSharingMode:type_name -> signal.backup.AccountData.PhoneNumberSharingMode - 107, // 109: signal.backup.AccountData.AccountSettings.defaultChatStyle:type_name -> signal.backup.ChatStyle - 150, // 110: signal.backup.AccountData.AccountSettings.customChatColors:type_name -> signal.backup.ChatStyle.CustomChatColor - 118, // 111: signal.backup.Group.GroupSnapshot.title:type_name -> signal.backup.Group.GroupAttributeBlob - 118, // 112: signal.backup.Group.GroupSnapshot.description:type_name -> signal.backup.Group.GroupAttributeBlob - 118, // 113: signal.backup.Group.GroupSnapshot.disappearingMessagesTimer:type_name -> signal.backup.Group.GroupAttributeBlob - 123, // 114: signal.backup.Group.GroupSnapshot.accessControl:type_name -> signal.backup.Group.AccessControl - 119, // 115: signal.backup.Group.GroupSnapshot.members:type_name -> signal.backup.Group.Member - 120, // 116: signal.backup.Group.GroupSnapshot.membersPendingProfileKey:type_name -> signal.backup.Group.MemberPendingProfileKey - 121, // 117: signal.backup.Group.GroupSnapshot.membersPendingAdminApproval:type_name -> signal.backup.Group.MemberPendingAdminApproval - 122, // 118: signal.backup.Group.GroupSnapshot.members_banned:type_name -> signal.backup.Group.MemberBanned - 6, // 119: signal.backup.Group.Member.role:type_name -> signal.backup.Group.Member.Role - 119, // 120: signal.backup.Group.MemberPendingProfileKey.member:type_name -> signal.backup.Group.Member - 7, // 121: signal.backup.Group.AccessControl.attributes:type_name -> signal.backup.Group.AccessControl.AccessRequired - 7, // 122: signal.backup.Group.AccessControl.members:type_name -> signal.backup.Group.AccessControl.AccessRequired - 7, // 123: signal.backup.Group.AccessControl.addFromInviteLink:type_name -> signal.backup.Group.AccessControl.AccessRequired - 44, // 124: signal.backup.ChatItem.OutgoingMessageDetails.sendStatus:type_name -> signal.backup.SendStatus - 11, // 125: signal.backup.SendStatus.Failed.reason:type_name -> signal.backup.SendStatus.Failed.FailureReason - 45, // 126: signal.backup.DirectStoryReplyMessage.TextReply.text:type_name -> signal.backup.Text - 58, // 127: signal.backup.DirectStoryReplyMessage.TextReply.longText:type_name -> signal.backup.FilePointer - 138, // 128: signal.backup.PaymentNotification.TransactionDetails.transaction:type_name -> signal.backup.PaymentNotification.TransactionDetails.Transaction - 137, // 129: signal.backup.PaymentNotification.TransactionDetails.failedTransaction:type_name -> signal.backup.PaymentNotification.TransactionDetails.FailedTransaction - 12, // 130: signal.backup.PaymentNotification.TransactionDetails.FailedTransaction.reason:type_name -> signal.backup.PaymentNotification.TransactionDetails.FailedTransaction.FailureReason - 13, // 131: signal.backup.PaymentNotification.TransactionDetails.Transaction.status:type_name -> signal.backup.PaymentNotification.TransactionDetails.Transaction.Status - 136, // 132: signal.backup.PaymentNotification.TransactionDetails.Transaction.mobileCoinIdentification:type_name -> signal.backup.PaymentNotification.TransactionDetails.MobileCoinTxoIdentification - 15, // 133: signal.backup.ContactAttachment.Phone.type:type_name -> signal.backup.ContactAttachment.Phone.Type - 16, // 134: signal.backup.ContactAttachment.Email.type:type_name -> signal.backup.ContactAttachment.Email.Type - 17, // 135: signal.backup.ContactAttachment.PostalAddress.type:type_name -> signal.backup.ContactAttachment.PostalAddress.Type - 57, // 136: signal.backup.Quote.QuotedAttachment.thumbnail:type_name -> signal.backup.MessageAttachment - 72, // 137: signal.backup.GroupChangeChatUpdate.Update.genericGroupUpdate:type_name -> signal.backup.GenericGroupUpdate - 73, // 138: signal.backup.GroupChangeChatUpdate.Update.groupCreationUpdate:type_name -> signal.backup.GroupCreationUpdate - 74, // 139: signal.backup.GroupChangeChatUpdate.Update.groupNameUpdate:type_name -> signal.backup.GroupNameUpdate - 75, // 140: signal.backup.GroupChangeChatUpdate.Update.groupAvatarUpdate:type_name -> signal.backup.GroupAvatarUpdate - 76, // 141: signal.backup.GroupChangeChatUpdate.Update.groupDescriptionUpdate:type_name -> signal.backup.GroupDescriptionUpdate - 77, // 142: signal.backup.GroupChangeChatUpdate.Update.groupMembershipAccessLevelChangeUpdate:type_name -> signal.backup.GroupMembershipAccessLevelChangeUpdate - 78, // 143: signal.backup.GroupChangeChatUpdate.Update.groupAttributesAccessLevelChangeUpdate:type_name -> signal.backup.GroupAttributesAccessLevelChangeUpdate - 79, // 144: signal.backup.GroupChangeChatUpdate.Update.groupAnnouncementOnlyChangeUpdate:type_name -> signal.backup.GroupAnnouncementOnlyChangeUpdate - 80, // 145: signal.backup.GroupChangeChatUpdate.Update.groupAdminStatusUpdate:type_name -> signal.backup.GroupAdminStatusUpdate - 81, // 146: signal.backup.GroupChangeChatUpdate.Update.groupMemberLeftUpdate:type_name -> signal.backup.GroupMemberLeftUpdate - 82, // 147: signal.backup.GroupChangeChatUpdate.Update.groupMemberRemovedUpdate:type_name -> signal.backup.GroupMemberRemovedUpdate - 83, // 148: signal.backup.GroupChangeChatUpdate.Update.selfInvitedToGroupUpdate:type_name -> signal.backup.SelfInvitedToGroupUpdate - 84, // 149: signal.backup.GroupChangeChatUpdate.Update.selfInvitedOtherUserToGroupUpdate:type_name -> signal.backup.SelfInvitedOtherUserToGroupUpdate - 85, // 150: signal.backup.GroupChangeChatUpdate.Update.groupUnknownInviteeUpdate:type_name -> signal.backup.GroupUnknownInviteeUpdate - 86, // 151: signal.backup.GroupChangeChatUpdate.Update.groupInvitationAcceptedUpdate:type_name -> signal.backup.GroupInvitationAcceptedUpdate - 87, // 152: signal.backup.GroupChangeChatUpdate.Update.groupInvitationDeclinedUpdate:type_name -> signal.backup.GroupInvitationDeclinedUpdate - 88, // 153: signal.backup.GroupChangeChatUpdate.Update.groupMemberJoinedUpdate:type_name -> signal.backup.GroupMemberJoinedUpdate - 89, // 154: signal.backup.GroupChangeChatUpdate.Update.groupMemberAddedUpdate:type_name -> signal.backup.GroupMemberAddedUpdate - 90, // 155: signal.backup.GroupChangeChatUpdate.Update.groupSelfInvitationRevokedUpdate:type_name -> signal.backup.GroupSelfInvitationRevokedUpdate - 91, // 156: signal.backup.GroupChangeChatUpdate.Update.groupInvitationRevokedUpdate:type_name -> signal.backup.GroupInvitationRevokedUpdate - 92, // 157: signal.backup.GroupChangeChatUpdate.Update.groupJoinRequestUpdate:type_name -> signal.backup.GroupJoinRequestUpdate - 93, // 158: signal.backup.GroupChangeChatUpdate.Update.groupJoinRequestApprovalUpdate:type_name -> signal.backup.GroupJoinRequestApprovalUpdate - 94, // 159: signal.backup.GroupChangeChatUpdate.Update.groupJoinRequestCanceledUpdate:type_name -> signal.backup.GroupJoinRequestCanceledUpdate - 96, // 160: signal.backup.GroupChangeChatUpdate.Update.groupInviteLinkResetUpdate:type_name -> signal.backup.GroupInviteLinkResetUpdate - 97, // 161: signal.backup.GroupChangeChatUpdate.Update.groupInviteLinkEnabledUpdate:type_name -> signal.backup.GroupInviteLinkEnabledUpdate - 98, // 162: signal.backup.GroupChangeChatUpdate.Update.groupInviteLinkAdminApprovalUpdate:type_name -> signal.backup.GroupInviteLinkAdminApprovalUpdate - 99, // 163: signal.backup.GroupChangeChatUpdate.Update.groupInviteLinkDisabledUpdate:type_name -> signal.backup.GroupInviteLinkDisabledUpdate - 100, // 164: signal.backup.GroupChangeChatUpdate.Update.groupMemberJoinedByLinkUpdate:type_name -> signal.backup.GroupMemberJoinedByLinkUpdate - 101, // 165: signal.backup.GroupChangeChatUpdate.Update.groupV2MigrationUpdate:type_name -> signal.backup.GroupV2MigrationUpdate - 102, // 166: signal.backup.GroupChangeChatUpdate.Update.groupV2MigrationSelfInvitedUpdate:type_name -> signal.backup.GroupV2MigrationSelfInvitedUpdate - 103, // 167: signal.backup.GroupChangeChatUpdate.Update.groupV2MigrationInvitedMembersUpdate:type_name -> signal.backup.GroupV2MigrationInvitedMembersUpdate - 104, // 168: signal.backup.GroupChangeChatUpdate.Update.groupV2MigrationDroppedMembersUpdate:type_name -> signal.backup.GroupV2MigrationDroppedMembersUpdate - 95, // 169: signal.backup.GroupChangeChatUpdate.Update.groupSequenceOfRequestsAndCancelsUpdate:type_name -> signal.backup.GroupSequenceOfRequestsAndCancelsUpdate - 105, // 170: signal.backup.GroupChangeChatUpdate.Update.groupExpirationTimerUpdate:type_name -> signal.backup.GroupExpirationTimerUpdate - 149, // 171: signal.backup.ChatStyle.CustomChatColor.gradient:type_name -> signal.backup.ChatStyle.Gradient - 172, // [172:172] is the sub-list for method output_type - 172, // [172:172] is the sub-list for method input_type - 172, // [172:172] is the sub-list for extension type_name - 172, // [172:172] is the sub-list for extension extendee - 0, // [0:172] is the sub-list for field type_name + 33, // 0: signal.backup.Frame.account:type_name -> signal.backup.AccountData + 34, // 1: signal.backup.Frame.recipient:type_name -> signal.backup.Recipient + 39, // 2: signal.backup.Frame.chat:type_name -> signal.backup.Chat + 44, // 3: signal.backup.Frame.chatItem:type_name -> signal.backup.ChatItem + 107, // 4: signal.backup.Frame.stickerPack:type_name -> signal.backup.StickerPack + 41, // 5: signal.backup.Frame.adHocCall:type_name -> signal.backup.AdHocCall + 109, // 6: signal.backup.Frame.notificationProfile:type_name -> signal.backup.NotificationProfile + 110, // 7: signal.backup.Frame.chatFolder:type_name -> signal.backup.ChatFolder + 111, // 8: signal.backup.AccountData.usernameLink:type_name -> signal.backup.AccountData.UsernameLink + 113, // 9: signal.backup.AccountData.donationSubscriberData:type_name -> signal.backup.AccountData.SubscriberData + 112, // 10: signal.backup.AccountData.accountSettings:type_name -> signal.backup.AccountData.AccountSettings + 114, // 11: signal.backup.AccountData.backupsSubscriberData:type_name -> signal.backup.AccountData.IAPSubscriberData + 35, // 12: signal.backup.Recipient.contact:type_name -> signal.backup.Contact + 36, // 13: signal.backup.Recipient.group:type_name -> signal.backup.Group + 42, // 14: signal.backup.Recipient.distributionList:type_name -> signal.backup.DistributionListItem + 37, // 15: signal.backup.Recipient.self:type_name -> signal.backup.Self + 38, // 16: signal.backup.Recipient.releaseNotes:type_name -> signal.backup.ReleaseNotes + 40, // 17: signal.backup.Recipient.callLink:type_name -> signal.backup.CallLink + 5, // 18: signal.backup.Contact.visibility:type_name -> signal.backup.Contact.Visibility + 115, // 19: signal.backup.Contact.registered:type_name -> signal.backup.Contact.Registered + 116, // 20: signal.backup.Contact.notRegistered:type_name -> signal.backup.Contact.NotRegistered + 4, // 21: signal.backup.Contact.identityState:type_name -> signal.backup.Contact.IdentityState + 117, // 22: signal.backup.Contact.nickname:type_name -> signal.backup.Contact.Name + 0, // 23: signal.backup.Contact.avatarColor:type_name -> signal.backup.AvatarColor + 6, // 24: signal.backup.Group.storySendMode:type_name -> signal.backup.Group.StorySendMode + 118, // 25: signal.backup.Group.snapshot:type_name -> signal.backup.Group.GroupSnapshot + 0, // 26: signal.backup.Group.avatarColor:type_name -> signal.backup.AvatarColor + 0, // 27: signal.backup.Self.avatarColor:type_name -> signal.backup.AvatarColor + 108, // 28: signal.backup.Chat.style:type_name -> signal.backup.ChatStyle + 9, // 29: signal.backup.CallLink.restrictions:type_name -> signal.backup.CallLink.Restrictions + 10, // 30: signal.backup.AdHocCall.state:type_name -> signal.backup.AdHocCall.State + 43, // 31: signal.backup.DistributionListItem.distributionList:type_name -> signal.backup.DistributionList + 11, // 32: signal.backup.DistributionList.privacyMode:type_name -> signal.backup.DistributionList.PrivacyMode + 44, // 33: signal.backup.ChatItem.revisions:type_name -> signal.backup.ChatItem + 125, // 34: signal.backup.ChatItem.incoming:type_name -> signal.backup.ChatItem.IncomingMessageDetails + 126, // 35: signal.backup.ChatItem.outgoing:type_name -> signal.backup.ChatItem.OutgoingMessageDetails + 127, // 36: signal.backup.ChatItem.directionless:type_name -> signal.backup.ChatItem.DirectionlessMessageDetails + 47, // 37: signal.backup.ChatItem.standardMessage:type_name -> signal.backup.StandardMessage + 48, // 38: signal.backup.ChatItem.contactMessage:type_name -> signal.backup.ContactMessage + 54, // 39: signal.backup.ChatItem.stickerMessage:type_name -> signal.backup.StickerMessage + 55, // 40: signal.backup.ChatItem.remoteDeletedMessage:type_name -> signal.backup.RemoteDeletedMessage + 63, // 41: signal.backup.ChatItem.updateMessage:type_name -> signal.backup.ChatUpdateMessage + 50, // 42: signal.backup.ChatItem.paymentNotification:type_name -> signal.backup.PaymentNotification + 51, // 43: signal.backup.ChatItem.giftBadge:type_name -> signal.backup.GiftBadge + 52, // 44: signal.backup.ChatItem.viewOnceMessage:type_name -> signal.backup.ViewOnceMessage + 49, // 45: signal.backup.ChatItem.directStoryReplyMessage:type_name -> signal.backup.DirectStoryReplyMessage + 128, // 46: signal.backup.SendStatus.pending:type_name -> signal.backup.SendStatus.Pending + 129, // 47: signal.backup.SendStatus.sent:type_name -> signal.backup.SendStatus.Sent + 130, // 48: signal.backup.SendStatus.delivered:type_name -> signal.backup.SendStatus.Delivered + 131, // 49: signal.backup.SendStatus.read:type_name -> signal.backup.SendStatus.Read + 132, // 50: signal.backup.SendStatus.viewed:type_name -> signal.backup.SendStatus.Viewed + 133, // 51: signal.backup.SendStatus.skipped:type_name -> signal.backup.SendStatus.Skipped + 134, // 52: signal.backup.SendStatus.failed:type_name -> signal.backup.SendStatus.Failed + 61, // 53: signal.backup.Text.bodyRanges:type_name -> signal.backup.BodyRange + 60, // 54: signal.backup.StandardMessage.quote:type_name -> signal.backup.Quote + 46, // 55: signal.backup.StandardMessage.text:type_name -> signal.backup.Text + 58, // 56: signal.backup.StandardMessage.attachments:type_name -> signal.backup.MessageAttachment + 57, // 57: signal.backup.StandardMessage.linkPreview:type_name -> signal.backup.LinkPreview + 59, // 58: signal.backup.StandardMessage.longText:type_name -> signal.backup.FilePointer + 62, // 59: signal.backup.StandardMessage.reactions:type_name -> signal.backup.Reaction + 53, // 60: signal.backup.ContactMessage.contact:type_name -> signal.backup.ContactAttachment + 62, // 61: signal.backup.ContactMessage.reactions:type_name -> signal.backup.Reaction + 135, // 62: signal.backup.DirectStoryReplyMessage.textReply:type_name -> signal.backup.DirectStoryReplyMessage.TextReply + 62, // 63: signal.backup.DirectStoryReplyMessage.reactions:type_name -> signal.backup.Reaction + 136, // 64: signal.backup.PaymentNotification.transactionDetails:type_name -> signal.backup.PaymentNotification.TransactionDetails + 15, // 65: signal.backup.GiftBadge.state:type_name -> signal.backup.GiftBadge.State + 58, // 66: signal.backup.ViewOnceMessage.attachment:type_name -> signal.backup.MessageAttachment + 62, // 67: signal.backup.ViewOnceMessage.reactions:type_name -> signal.backup.Reaction + 140, // 68: signal.backup.ContactAttachment.name:type_name -> signal.backup.ContactAttachment.Name + 141, // 69: signal.backup.ContactAttachment.number:type_name -> signal.backup.ContactAttachment.Phone + 142, // 70: signal.backup.ContactAttachment.email:type_name -> signal.backup.ContactAttachment.Email + 143, // 71: signal.backup.ContactAttachment.address:type_name -> signal.backup.ContactAttachment.PostalAddress + 59, // 72: signal.backup.ContactAttachment.avatar:type_name -> signal.backup.FilePointer + 56, // 73: signal.backup.StickerMessage.sticker:type_name -> signal.backup.Sticker + 62, // 74: signal.backup.StickerMessage.reactions:type_name -> signal.backup.Reaction + 59, // 75: signal.backup.Sticker.data:type_name -> signal.backup.FilePointer + 59, // 76: signal.backup.LinkPreview.image:type_name -> signal.backup.FilePointer + 59, // 77: signal.backup.MessageAttachment.pointer:type_name -> signal.backup.FilePointer + 19, // 78: signal.backup.MessageAttachment.flag:type_name -> signal.backup.MessageAttachment.Flag + 144, // 79: signal.backup.FilePointer.backupLocator:type_name -> signal.backup.FilePointer.BackupLocator + 145, // 80: signal.backup.FilePointer.attachmentLocator:type_name -> signal.backup.FilePointer.AttachmentLocator + 146, // 81: signal.backup.FilePointer.invalidAttachmentLocator:type_name -> signal.backup.FilePointer.InvalidAttachmentLocator + 46, // 82: signal.backup.Quote.text:type_name -> signal.backup.Text + 147, // 83: signal.backup.Quote.attachments:type_name -> signal.backup.Quote.QuotedAttachment + 20, // 84: signal.backup.Quote.type:type_name -> signal.backup.Quote.Type + 21, // 85: signal.backup.BodyRange.style:type_name -> signal.backup.BodyRange.Style + 66, // 86: signal.backup.ChatUpdateMessage.simpleUpdate:type_name -> signal.backup.SimpleChatUpdate + 72, // 87: signal.backup.ChatUpdateMessage.groupChange:type_name -> signal.backup.GroupChangeChatUpdate + 67, // 88: signal.backup.ChatUpdateMessage.expirationTimerChange:type_name -> signal.backup.ExpirationTimerChatUpdate + 68, // 89: signal.backup.ChatUpdateMessage.profileChange:type_name -> signal.backup.ProfileChangeChatUpdate + 70, // 90: signal.backup.ChatUpdateMessage.threadMerge:type_name -> signal.backup.ThreadMergeChatUpdate + 71, // 91: signal.backup.ChatUpdateMessage.sessionSwitchover:type_name -> signal.backup.SessionSwitchoverChatUpdate + 64, // 92: signal.backup.ChatUpdateMessage.individualCall:type_name -> signal.backup.IndividualCall + 65, // 93: signal.backup.ChatUpdateMessage.groupCall:type_name -> signal.backup.GroupCall + 69, // 94: signal.backup.ChatUpdateMessage.learnedProfileChange:type_name -> signal.backup.LearnedProfileChatUpdate + 22, // 95: signal.backup.IndividualCall.type:type_name -> signal.backup.IndividualCall.Type + 23, // 96: signal.backup.IndividualCall.direction:type_name -> signal.backup.IndividualCall.Direction + 24, // 97: signal.backup.IndividualCall.state:type_name -> signal.backup.IndividualCall.State + 25, // 98: signal.backup.GroupCall.state:type_name -> signal.backup.GroupCall.State + 26, // 99: signal.backup.SimpleChatUpdate.type:type_name -> signal.backup.SimpleChatUpdate.Type + 148, // 100: signal.backup.GroupChangeChatUpdate.updates:type_name -> signal.backup.GroupChangeChatUpdate.Update + 1, // 101: signal.backup.GroupMembershipAccessLevelChangeUpdate.accessLevel:type_name -> signal.backup.GroupV2AccessLevel + 1, // 102: signal.backup.GroupAttributesAccessLevelChangeUpdate.accessLevel:type_name -> signal.backup.GroupV2AccessLevel + 149, // 103: signal.backup.GroupInvitationRevokedUpdate.invitees:type_name -> signal.backup.GroupInvitationRevokedUpdate.Invitee + 27, // 104: signal.backup.ChatStyle.wallpaperPreset:type_name -> signal.backup.ChatStyle.WallpaperPreset + 59, // 105: signal.backup.ChatStyle.wallpaperPhoto:type_name -> signal.backup.FilePointer + 152, // 106: signal.backup.ChatStyle.autoBubbleColor:type_name -> signal.backup.ChatStyle.AutomaticBubbleColor + 28, // 107: signal.backup.ChatStyle.bubbleColorPreset:type_name -> signal.backup.ChatStyle.BubbleColorPreset + 29, // 108: signal.backup.NotificationProfile.scheduleDaysEnabled:type_name -> signal.backup.NotificationProfile.DayOfWeek + 30, // 109: signal.backup.ChatFolder.folderType:type_name -> signal.backup.ChatFolder.FolderType + 3, // 110: signal.backup.AccountData.UsernameLink.color:type_name -> signal.backup.AccountData.UsernameLink.Color + 2, // 111: signal.backup.AccountData.AccountSettings.phoneNumberSharingMode:type_name -> signal.backup.AccountData.PhoneNumberSharingMode + 108, // 112: signal.backup.AccountData.AccountSettings.defaultChatStyle:type_name -> signal.backup.ChatStyle + 151, // 113: signal.backup.AccountData.AccountSettings.customChatColors:type_name -> signal.backup.ChatStyle.CustomChatColor + 119, // 114: signal.backup.Group.GroupSnapshot.title:type_name -> signal.backup.Group.GroupAttributeBlob + 119, // 115: signal.backup.Group.GroupSnapshot.description:type_name -> signal.backup.Group.GroupAttributeBlob + 119, // 116: signal.backup.Group.GroupSnapshot.disappearingMessagesTimer:type_name -> signal.backup.Group.GroupAttributeBlob + 124, // 117: signal.backup.Group.GroupSnapshot.accessControl:type_name -> signal.backup.Group.AccessControl + 120, // 118: signal.backup.Group.GroupSnapshot.members:type_name -> signal.backup.Group.Member + 121, // 119: signal.backup.Group.GroupSnapshot.membersPendingProfileKey:type_name -> signal.backup.Group.MemberPendingProfileKey + 122, // 120: signal.backup.Group.GroupSnapshot.membersPendingAdminApproval:type_name -> signal.backup.Group.MemberPendingAdminApproval + 123, // 121: signal.backup.Group.GroupSnapshot.members_banned:type_name -> signal.backup.Group.MemberBanned + 7, // 122: signal.backup.Group.Member.role:type_name -> signal.backup.Group.Member.Role + 120, // 123: signal.backup.Group.MemberPendingProfileKey.member:type_name -> signal.backup.Group.Member + 8, // 124: signal.backup.Group.AccessControl.attributes:type_name -> signal.backup.Group.AccessControl.AccessRequired + 8, // 125: signal.backup.Group.AccessControl.members:type_name -> signal.backup.Group.AccessControl.AccessRequired + 8, // 126: signal.backup.Group.AccessControl.addFromInviteLink:type_name -> signal.backup.Group.AccessControl.AccessRequired + 45, // 127: signal.backup.ChatItem.OutgoingMessageDetails.sendStatus:type_name -> signal.backup.SendStatus + 12, // 128: signal.backup.SendStatus.Failed.reason:type_name -> signal.backup.SendStatus.Failed.FailureReason + 46, // 129: signal.backup.DirectStoryReplyMessage.TextReply.text:type_name -> signal.backup.Text + 59, // 130: signal.backup.DirectStoryReplyMessage.TextReply.longText:type_name -> signal.backup.FilePointer + 139, // 131: signal.backup.PaymentNotification.TransactionDetails.transaction:type_name -> signal.backup.PaymentNotification.TransactionDetails.Transaction + 138, // 132: signal.backup.PaymentNotification.TransactionDetails.failedTransaction:type_name -> signal.backup.PaymentNotification.TransactionDetails.FailedTransaction + 13, // 133: signal.backup.PaymentNotification.TransactionDetails.FailedTransaction.reason:type_name -> signal.backup.PaymentNotification.TransactionDetails.FailedTransaction.FailureReason + 14, // 134: signal.backup.PaymentNotification.TransactionDetails.Transaction.status:type_name -> signal.backup.PaymentNotification.TransactionDetails.Transaction.Status + 137, // 135: signal.backup.PaymentNotification.TransactionDetails.Transaction.mobileCoinIdentification:type_name -> signal.backup.PaymentNotification.TransactionDetails.MobileCoinTxoIdentification + 16, // 136: signal.backup.ContactAttachment.Phone.type:type_name -> signal.backup.ContactAttachment.Phone.Type + 17, // 137: signal.backup.ContactAttachment.Email.type:type_name -> signal.backup.ContactAttachment.Email.Type + 18, // 138: signal.backup.ContactAttachment.PostalAddress.type:type_name -> signal.backup.ContactAttachment.PostalAddress.Type + 58, // 139: signal.backup.Quote.QuotedAttachment.thumbnail:type_name -> signal.backup.MessageAttachment + 73, // 140: signal.backup.GroupChangeChatUpdate.Update.genericGroupUpdate:type_name -> signal.backup.GenericGroupUpdate + 74, // 141: signal.backup.GroupChangeChatUpdate.Update.groupCreationUpdate:type_name -> signal.backup.GroupCreationUpdate + 75, // 142: signal.backup.GroupChangeChatUpdate.Update.groupNameUpdate:type_name -> signal.backup.GroupNameUpdate + 76, // 143: signal.backup.GroupChangeChatUpdate.Update.groupAvatarUpdate:type_name -> signal.backup.GroupAvatarUpdate + 77, // 144: signal.backup.GroupChangeChatUpdate.Update.groupDescriptionUpdate:type_name -> signal.backup.GroupDescriptionUpdate + 78, // 145: signal.backup.GroupChangeChatUpdate.Update.groupMembershipAccessLevelChangeUpdate:type_name -> signal.backup.GroupMembershipAccessLevelChangeUpdate + 79, // 146: signal.backup.GroupChangeChatUpdate.Update.groupAttributesAccessLevelChangeUpdate:type_name -> signal.backup.GroupAttributesAccessLevelChangeUpdate + 80, // 147: signal.backup.GroupChangeChatUpdate.Update.groupAnnouncementOnlyChangeUpdate:type_name -> signal.backup.GroupAnnouncementOnlyChangeUpdate + 81, // 148: signal.backup.GroupChangeChatUpdate.Update.groupAdminStatusUpdate:type_name -> signal.backup.GroupAdminStatusUpdate + 82, // 149: signal.backup.GroupChangeChatUpdate.Update.groupMemberLeftUpdate:type_name -> signal.backup.GroupMemberLeftUpdate + 83, // 150: signal.backup.GroupChangeChatUpdate.Update.groupMemberRemovedUpdate:type_name -> signal.backup.GroupMemberRemovedUpdate + 84, // 151: signal.backup.GroupChangeChatUpdate.Update.selfInvitedToGroupUpdate:type_name -> signal.backup.SelfInvitedToGroupUpdate + 85, // 152: signal.backup.GroupChangeChatUpdate.Update.selfInvitedOtherUserToGroupUpdate:type_name -> signal.backup.SelfInvitedOtherUserToGroupUpdate + 86, // 153: signal.backup.GroupChangeChatUpdate.Update.groupUnknownInviteeUpdate:type_name -> signal.backup.GroupUnknownInviteeUpdate + 87, // 154: signal.backup.GroupChangeChatUpdate.Update.groupInvitationAcceptedUpdate:type_name -> signal.backup.GroupInvitationAcceptedUpdate + 88, // 155: signal.backup.GroupChangeChatUpdate.Update.groupInvitationDeclinedUpdate:type_name -> signal.backup.GroupInvitationDeclinedUpdate + 89, // 156: signal.backup.GroupChangeChatUpdate.Update.groupMemberJoinedUpdate:type_name -> signal.backup.GroupMemberJoinedUpdate + 90, // 157: signal.backup.GroupChangeChatUpdate.Update.groupMemberAddedUpdate:type_name -> signal.backup.GroupMemberAddedUpdate + 91, // 158: signal.backup.GroupChangeChatUpdate.Update.groupSelfInvitationRevokedUpdate:type_name -> signal.backup.GroupSelfInvitationRevokedUpdate + 92, // 159: signal.backup.GroupChangeChatUpdate.Update.groupInvitationRevokedUpdate:type_name -> signal.backup.GroupInvitationRevokedUpdate + 93, // 160: signal.backup.GroupChangeChatUpdate.Update.groupJoinRequestUpdate:type_name -> signal.backup.GroupJoinRequestUpdate + 94, // 161: signal.backup.GroupChangeChatUpdate.Update.groupJoinRequestApprovalUpdate:type_name -> signal.backup.GroupJoinRequestApprovalUpdate + 95, // 162: signal.backup.GroupChangeChatUpdate.Update.groupJoinRequestCanceledUpdate:type_name -> signal.backup.GroupJoinRequestCanceledUpdate + 97, // 163: signal.backup.GroupChangeChatUpdate.Update.groupInviteLinkResetUpdate:type_name -> signal.backup.GroupInviteLinkResetUpdate + 98, // 164: signal.backup.GroupChangeChatUpdate.Update.groupInviteLinkEnabledUpdate:type_name -> signal.backup.GroupInviteLinkEnabledUpdate + 99, // 165: signal.backup.GroupChangeChatUpdate.Update.groupInviteLinkAdminApprovalUpdate:type_name -> signal.backup.GroupInviteLinkAdminApprovalUpdate + 100, // 166: signal.backup.GroupChangeChatUpdate.Update.groupInviteLinkDisabledUpdate:type_name -> signal.backup.GroupInviteLinkDisabledUpdate + 101, // 167: signal.backup.GroupChangeChatUpdate.Update.groupMemberJoinedByLinkUpdate:type_name -> signal.backup.GroupMemberJoinedByLinkUpdate + 102, // 168: signal.backup.GroupChangeChatUpdate.Update.groupV2MigrationUpdate:type_name -> signal.backup.GroupV2MigrationUpdate + 103, // 169: signal.backup.GroupChangeChatUpdate.Update.groupV2MigrationSelfInvitedUpdate:type_name -> signal.backup.GroupV2MigrationSelfInvitedUpdate + 104, // 170: signal.backup.GroupChangeChatUpdate.Update.groupV2MigrationInvitedMembersUpdate:type_name -> signal.backup.GroupV2MigrationInvitedMembersUpdate + 105, // 171: signal.backup.GroupChangeChatUpdate.Update.groupV2MigrationDroppedMembersUpdate:type_name -> signal.backup.GroupV2MigrationDroppedMembersUpdate + 96, // 172: signal.backup.GroupChangeChatUpdate.Update.groupSequenceOfRequestsAndCancelsUpdate:type_name -> signal.backup.GroupSequenceOfRequestsAndCancelsUpdate + 106, // 173: signal.backup.GroupChangeChatUpdate.Update.groupExpirationTimerUpdate:type_name -> signal.backup.GroupExpirationTimerUpdate + 150, // 174: signal.backup.ChatStyle.CustomChatColor.gradient:type_name -> signal.backup.ChatStyle.Gradient + 175, // [175:175] is the sub-list for method output_type + 175, // [175:175] is the sub-list for method input_type + 175, // [175:175] is the sub-list for extension type_name + 175, // [175:175] is the sub-list for extension extendee + 0, // [0:175] is the sub-list for field type_name } func init() { file_backuppb_Backup_proto_init() } @@ -11408,6 +11561,8 @@ func file_backuppb_Backup_proto_init() { (*Contact_Registered_)(nil), (*Contact_NotRegistered_)(nil), } + file_backuppb_Backup_proto_msgTypes[5].OneofWrappers = []any{} + file_backuppb_Backup_proto_msgTypes[6].OneofWrappers = []any{} file_backuppb_Backup_proto_msgTypes[8].OneofWrappers = []any{} file_backuppb_Backup_proto_msgTypes[9].OneofWrappers = []any{} file_backuppb_Backup_proto_msgTypes[11].OneofWrappers = []any{ @@ -11571,7 +11726,7 @@ func file_backuppb_Backup_proto_init() { File: protoimpl.DescBuilder{ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_backuppb_Backup_proto_rawDesc, - NumEnums: 30, + NumEnums: 31, NumMessages: 122, NumExtensions: 0, NumServices: 0, diff --git a/pkg/signalmeow/protobuf/backuppb/Backup.pb.raw b/pkg/signalmeow/protobuf/backuppb/Backup.pb.raw index 7a030359a9583e852063511073a9fec4c60b91d5..c72802f548667437a91409072bf911376e63bc75 100644 GIT binary patch delta 654 zcmbRJh4Ii2#tk2t7(Z_Q#3aikAtc7dR$NvTkeMgJt-z?k83g5R=4U<1!E~By^EKWN zO!YzQnA#U-h^?wMt&d47qxsS-k9<>83ViZj#m5_9yD5|gt_3-lZj zDm*xYkTrBLGHyO5(8Vb1#K*-Gk7SZkztHAjAx=hTAv7D<3EIGbVMC1YX7+jv8zQ+_ zf>U$S&@Esj-2x1wfu0FU%}GrxPW8(#Ni9~o%*?e}Te>@j@xtcqr0kH7`0ok+i0v!UgCk4d_0{RHE?hWt)v!4-)0Rtku5wkoK2?4W+ j6tf2iA_fWsQ)O&sv!)!MTmitdMtP9|ljnLdlc0N|vA7;a diff --git a/pkg/signalmeow/protobuf/backuppb/Backup.proto b/pkg/signalmeow/protobuf/backuppb/Backup.proto index 42f3e8d..9fe2079 100644 --- a/pkg/signalmeow/protobuf/backuppb/Backup.proto +++ b/pkg/signalmeow/protobuf/backuppb/Backup.proto @@ -117,6 +117,7 @@ message AccountData { reserved /*backupsSubscriberData*/ 8; // A deprecated format AccountSettings accountSettings = 9; IAPSubscriberData backupsSubscriberData = 10; + string svrPin = 11; } message Recipient { @@ -132,6 +133,30 @@ message Recipient { } } +// If unset - computed as the value of the first byte of SHA-256(msg=CONTACT_ID) +// modulo the count of colors. Once set the avatar color for a recipient is +// never recomputed or changed. +// +// `CONTACT_ID` is the first available identifier from the list: +// - ServiceIdToBinary(ACI) +// - E164 +// - ServiceIdToBinary(PNI) +// - Group Id +enum AvatarColor { + A100 = 0; + A110 = 1; + A120 = 2; + A130 = 3; + A140 = 4; + A150 = 5; + A160 = 6; + A170 = 7; + A180 = 8; + A190 = 9; + A200 = 10; + A210 = 11; +} + message Contact { enum IdentityState { DEFAULT = 0; // A valid value -- indicates unset by the user @@ -177,6 +202,10 @@ message Contact { IdentityState identityState = 15; Name nickname = 16; // absent iff both `given` and `family` are empty string note = 17; + string systemGivenName = 18; + string systemFamilyName = 19; + string systemNickname = 20; + optional AvatarColor avatarColor = 21; } message Group { @@ -192,6 +221,7 @@ message Group { StorySendMode storySendMode = 4; GroupSnapshot snapshot = 5; bool blocked = 6; + optional AvatarColor avatarColor = 7; // These are simply plaintext copies of the groups proto from Groups.proto. // They should be kept completely in-sync with Groups.proto. @@ -271,7 +301,9 @@ message Group { } } -message Self {} +message Self { + optional AvatarColor avatarColor = 1; +} message ReleaseNotes {} @@ -1279,4 +1311,5 @@ message ChatFolder { FolderType folderType = 6; repeated uint64 includedRecipientIds = 7; // generated recipient id of groups, contacts, and/or note to self repeated uint64 excludedRecipientIds = 8; // generated recipient id of groups, contacts, and/or note to self + bytes id = 9; // should be 16 bytes } diff --git a/pkg/signalmeow/protobuf/update-protos.sh b/pkg/signalmeow/protobuf/update-protos.sh index 1699017..1dd2e40 100755 --- a/pkg/signalmeow/protobuf/update-protos.sh +++ b/pkg/signalmeow/protobuf/update-protos.sh @@ -1,8 +1,8 @@ #!/bin/bash set -euo pipefail -ANDROID_GIT_REVISION=${1:-aa9c87ee67364a28977a2a5ba3bb7f5e715e19a0} -DESKTOP_GIT_REVISION=${1:-3f0536f5a58b6a20949690afd76093f41931843c} +ANDROID_GIT_REVISION=${1:-68058264729cb237bd8523df404d9455cb3f622f} +DESKTOP_GIT_REVISION=${1:-c861161f22e553ecb81982bc2c7b7d495ee42fcc} update_proto() { case "$1" in diff --git a/pkg/signalmeow/receiving.go b/pkg/signalmeow/receiving.go index 34fcd55..6ea9885 100644 --- a/pkg/signalmeow/receiving.go +++ b/pkg/signalmeow/receiving.go @@ -431,11 +431,11 @@ func (cli *Client) decryptEnvelope( Content: &content, } - case signalpb.Envelope_RECEIPT: - return DecryptionResult{Err: fmt.Errorf("receipt envelopes are not yet supported")} + case signalpb.Envelope_SERVER_DELIVERY_RECEIPT: + return DecryptionResult{Err: fmt.Errorf("server delivery receipt envelopes are not yet supported")} - case signalpb.Envelope_KEY_EXCHANGE: - return DecryptionResult{Err: fmt.Errorf("key exchange envelopes are not yet supported")} + case signalpb.Envelope_SENDERKEY_MESSAGE: + return DecryptionResult{Err: fmt.Errorf("senderkey message envelopes are not yet supported")} case signalpb.Envelope_UNKNOWN: return DecryptionResult{Err: fmt.Errorf("unknown envelope type")} diff --git a/pkg/signalmeow/sending.go b/pkg/signalmeow/sending.go index 555cbc2..7687da8 100644 --- a/pkg/signalmeow/sending.go +++ b/pkg/signalmeow/sending.go @@ -305,10 +305,10 @@ func (cli *Client) buildSSMessageToSend(ctx context.Context, recipientAddress *l } type SuccessfulSendResult struct { - Recipient libsignalgo.ServiceID - RecipientE164 *string - Unidentified bool - DestinationIdentityKey *libsignalgo.IdentityKey + Recipient libsignalgo.ServiceID + RecipientE164 *string + Unidentified bool + DestinationPNIIdentityKey *libsignalgo.IdentityKey } type FailedSendResult struct { Recipient libsignalgo.ServiceID @@ -386,9 +386,9 @@ func syncMessageFromSoloDataMessage(dataMessage *signalpb.DataMessage, result Su ExpirationStartTimestamp: ptr.Ptr(uint64(time.Now().UnixMilli())), UnidentifiedStatus: []*signalpb.SyncMessage_Sent_UnidentifiedDeliveryStatus{ { - DestinationServiceId: proto.String(result.Recipient.String()), - Unidentified: &result.Unidentified, - DestinationIdentityKey: result.DestinationIdentityKey.TrySerialize(), + DestinationServiceId: proto.String(result.Recipient.String()), + Unidentified: &result.Unidentified, + DestinationPniIdentityKey: result.DestinationPNIIdentityKey.TrySerialize(), }, }, }, @@ -407,9 +407,9 @@ func syncMessageFromSoloEditMessage(editMessage *signalpb.EditMessage, result Su ExpirationStartTimestamp: ptr.Ptr(uint64(time.Now().UnixMilli())), UnidentifiedStatus: []*signalpb.SyncMessage_Sent_UnidentifiedDeliveryStatus{ { - DestinationServiceId: proto.String(result.Recipient.String()), - Unidentified: &result.Unidentified, - DestinationIdentityKey: result.DestinationIdentityKey.TrySerialize(), + DestinationServiceId: proto.String(result.Recipient.String()), + Unidentified: &result.Unidentified, + DestinationPniIdentityKey: result.DestinationPNIIdentityKey.TrySerialize(), }, }, }, @@ -791,7 +791,7 @@ func (cli *Client) SendMessage(ctx context.Context, recipientID libsignalgo.Serv }, } if recipientID.Type == libsignalgo.ServiceIDTypePNI { - result.DestinationIdentityKey, err = cli.Store.IdentityKeyStore.GetIdentityKey(ctx, recipientID) + result.DestinationPNIIdentityKey, err = cli.Store.IdentityKeyStore.GetIdentityKey(ctx, recipientID) if err != nil { zerolog.Ctx(ctx).Err(err).Msg("Failed to add PNI destination identity key to sync message") } From e1cbbc9b9a29e5d85af681291a3484cd58c9f2c3 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Wed, 16 Apr 2025 12:55:13 +0300 Subject: [PATCH 318/580] Bump version to v0.8.2 --- CHANGELOG.md | 5 ++++ cmd/mautrix-signal/main.go | 2 +- go.mod | 26 ++++++++++---------- go.sum | 49 +++++++++++++++++++------------------- 4 files changed, 43 insertions(+), 39 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 01410df..722ed55 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,8 @@ +# v0.8.2 (2025-04-16) + +* Updated libsignal to v0.70.0 +* Fixed panics in some cases when the bridge was under heavy load. + # v0.8.1 (2025-03-16) * Added QR refreshing when logging in. diff --git a/cmd/mautrix-signal/main.go b/cmd/mautrix-signal/main.go index c97a5d2..c1689d6 100644 --- a/cmd/mautrix-signal/main.go +++ b/cmd/mautrix-signal/main.go @@ -38,7 +38,7 @@ var m = mxmain.BridgeMain{ Name: "mautrix-signal", URL: "https://github.com/mautrix/signal", Description: "A Matrix-Signal puppeting bridge.", - Version: "0.8.1", + Version: "0.8.2", Connector: &connector.SignalConnector{}, } diff --git a/go.mod b/go.mod index 7e2044e..28e17e8 100644 --- a/go.mod +++ b/go.mod @@ -2,7 +2,7 @@ module go.mau.fi/mautrix-signal go 1.23.0 -toolchain go1.24.1 +toolchain go1.24.2 require ( github.com/coder/websocket v1.8.13 @@ -10,15 +10,15 @@ require ( github.com/google/uuid v1.6.0 github.com/gorilla/mux v1.8.0 github.com/mattn/go-pointer v0.0.1 - github.com/rs/zerolog v1.33.0 + github.com/rs/zerolog v1.34.0 github.com/stretchr/testify v1.10.0 github.com/tidwall/gjson v1.18.0 go.mau.fi/util v0.8.6 - golang.org/x/crypto v0.36.0 - golang.org/x/exp v0.0.0-20250305212735-054e65f0b394 - golang.org/x/net v0.37.0 - google.golang.org/protobuf v1.36.5 - maunium.net/go/mautrix v0.23.3-0.20250320134109-06f200da0d10 + golang.org/x/crypto v0.37.0 + golang.org/x/exp v0.0.0-20250408133849-7e4ce0ab07d0 + golang.org/x/net v0.39.0 + google.golang.org/protobuf v1.36.6 + maunium.net/go/mautrix v0.23.3 ) require ( @@ -30,8 +30,8 @@ require ( github.com/lib/pq v1.10.9 // indirect github.com/mattn/go-colorable v0.1.14 // indirect github.com/mattn/go-isatty v0.0.20 // indirect - github.com/mattn/go-sqlite3 v1.14.24 // indirect - github.com/petermattis/goid v0.0.0-20250303134427-723919f7f203 // indirect + github.com/mattn/go-sqlite3 v1.14.27 // indirect + github.com/petermattis/goid v0.0.0-20250319124200-ccd6737f222a // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/rogpeppe/go-internal v1.10.0 // indirect github.com/rs/xid v1.6.0 // indirect @@ -39,11 +39,11 @@ require ( github.com/tidwall/match v1.1.1 // indirect github.com/tidwall/pretty v1.2.1 // indirect github.com/tidwall/sjson v1.2.5 // indirect - github.com/yuin/goldmark v1.7.8 // indirect + github.com/yuin/goldmark v1.7.10 // indirect go.mau.fi/zeroconfig v0.1.3 // indirect - golang.org/x/sync v0.12.0 // indirect - golang.org/x/sys v0.31.0 // indirect - golang.org/x/text v0.23.0 // indirect + golang.org/x/sync v0.13.0 // indirect + golang.org/x/sys v0.32.0 // indirect + golang.org/x/text v0.24.0 // indirect gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect gopkg.in/natefinch/lumberjack.v2 v2.2.1 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect diff --git a/go.sum b/go.sum index b049d15..fc57e3c 100644 --- a/go.sum +++ b/go.sum @@ -38,10 +38,10 @@ github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWE github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mattn/go-pointer v0.0.1 h1:n+XhsuGeVO6MEAp7xyEukFINEa+Quek5psIR/ylA6o0= github.com/mattn/go-pointer v0.0.1/go.mod h1:2zXcozF6qYGgmsG+SeTZz3oAbFLdD3OWqnUbNvJZAlc= -github.com/mattn/go-sqlite3 v1.14.24 h1:tpSp2G2KyMnnQu99ngJ47EIkWVmliIizyZBfPrBWDRM= -github.com/mattn/go-sqlite3 v1.14.24/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y= -github.com/petermattis/goid v0.0.0-20250303134427-723919f7f203 h1:E7Kmf11E4K7B5hDti2K2NqPb1nlYlGYsu02S1JNd/Bs= -github.com/petermattis/goid v0.0.0-20250303134427-723919f7f203/go.mod h1:pxMtw7cyUw6B2bRH0ZBANSPg+AoSud1I1iyJHI69jH4= +github.com/mattn/go-sqlite3 v1.14.27 h1:drZCnuvf37yPfs95E5jd9s3XhdVWLal+6BOK6qrv6IU= +github.com/mattn/go-sqlite3 v1.14.27/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y= +github.com/petermattis/goid v0.0.0-20250319124200-ccd6737f222a h1:S+AGcmAESQ0pXCUNnRH7V+bOUIgkSX5qVt2cNKCrm0Q= +github.com/petermattis/goid v0.0.0-20250319124200-ccd6737f222a/go.mod h1:pxMtw7cyUw6B2bRH0ZBANSPg+AoSud1I1iyJHI69jH4= github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= @@ -49,11 +49,10 @@ github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZN github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog= -github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= github.com/rs/xid v1.6.0 h1:fV591PaemRlL6JfRxGDEPl69wICngIQ3shQtzfy2gxU= github.com/rs/xid v1.6.0/go.mod h1:7XoLgs4eV+QndskICGsho+ADou8ySMSjJKDIan90Nz0= -github.com/rs/zerolog v1.33.0 h1:1cU2KZkvPxNyfgEmhHAz/1A9Bz+llsdYzklWFzgp0r8= -github.com/rs/zerolog v1.33.0/go.mod h1:/7mN4D5sKwJLZQ2b/znpjC3/GQWY/xaDXUM0kKWRHss= +github.com/rs/zerolog v1.34.0 h1:k43nTLIwcTVQAncfCw4KZ2VY6ukYoZaBPNOE8txlOeY= +github.com/rs/zerolog v1.34.0/go.mod h1:bJsvje4Z08ROH4Nhs5iH600c3IkWhwp44iRc54W6wYQ= github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e h1:MRM5ITcdelLK2j1vwZ3Je0FKVCfqOLp5zO6trqMLYs0= github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e/go.mod h1:XV66xRDqSt+GTGFMVlhk3ULuV0y9ZmzeVGR4mloJI3M= github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= @@ -68,29 +67,29 @@ github.com/tidwall/pretty v1.2.1 h1:qjsOFOWWQl+N3RsoF5/ssm1pHmJJwhjlSbZ51I6wMl4= github.com/tidwall/pretty v1.2.1/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU= github.com/tidwall/sjson v1.2.5 h1:kLy8mja+1c9jlljvWTlSazM7cKDRfJuR/bOJhcY5NcY= github.com/tidwall/sjson v1.2.5/go.mod h1:Fvgq9kS/6ociJEDnK0Fk1cpYF4FIW6ZF7LAe+6jwd28= -github.com/yuin/goldmark v1.7.8 h1:iERMLn0/QJeHFhxSt3p6PeN9mGnvIKSpG9YYorDMnic= -github.com/yuin/goldmark v1.7.8/go.mod h1:uzxRWxtg69N339t3louHJ7+O03ezfj6PlliRlaOzY1E= +github.com/yuin/goldmark v1.7.10 h1:S+LrtBjRmqMac2UdtB6yyCEJm+UILZ2fefI4p7o0QpI= +github.com/yuin/goldmark v1.7.10/go.mod h1:ip/1k0VRfGynBgxOz0yCqHrbZXhcjxyuS66Brc7iBKg= go.mau.fi/util v0.8.6 h1:AEK13rfgtiZJL2YsNK+W4ihhYCuukcRom8WPP/w/L54= go.mau.fi/util v0.8.6/go.mod h1:uNB3UTXFbkpp7xL1M/WvQks90B/L4gvbLpbS0603KOE= go.mau.fi/zeroconfig v0.1.3 h1:As9wYDKmktjmNZW5i1vn8zvJlmGKHeVxHVIBMXsm4kM= go.mau.fi/zeroconfig v0.1.3/go.mod h1:NcSJkf180JT+1IId76PcMuLTNa1CzsFFZ0nBygIQM70= -golang.org/x/crypto v0.36.0 h1:AnAEvhDddvBdpY+uR+MyHmuZzzNqXSe/GvuDeob5L34= -golang.org/x/crypto v0.36.0/go.mod h1:Y4J0ReaxCR1IMaabaSMugxJES1EpwhBHhv2bDHklZvc= -golang.org/x/exp v0.0.0-20250305212735-054e65f0b394 h1:nDVHiLt8aIbd/VzvPWN6kSOPE7+F/fNFDSXLVYkE/Iw= -golang.org/x/exp v0.0.0-20250305212735-054e65f0b394/go.mod h1:sIifuuw/Yco/y6yb6+bDNfyeQ/MdPUy/hKEMYQV17cM= -golang.org/x/net v0.37.0 h1:1zLorHbz+LYj7MQlSf1+2tPIIgibq2eL5xkrGk6f+2c= -golang.org/x/net v0.37.0/go.mod h1:ivrbrMbzFq5J41QOQh0siUuly180yBYtLp+CKbEaFx8= -golang.org/x/sync v0.12.0 h1:MHc5BpPuC30uJk597Ri8TV3CNZcTLu6B6z4lJy+g6Jw= -golang.org/x/sync v0.12.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= +golang.org/x/crypto v0.37.0 h1:kJNSjF/Xp7kU0iB2Z+9viTPMW4EqqsrywMXLJOOsXSE= +golang.org/x/crypto v0.37.0/go.mod h1:vg+k43peMZ0pUMhYmVAWysMK35e6ioLh3wB8ZCAfbVc= +golang.org/x/exp v0.0.0-20250408133849-7e4ce0ab07d0 h1:R84qjqJb5nVJMxqWYb3np9L5ZsaDtB+a39EqjV0JSUM= +golang.org/x/exp v0.0.0-20250408133849-7e4ce0ab07d0/go.mod h1:S9Xr4PYopiDyqSyp5NjCrhFrqg6A5zA2E/iPHPhqnS8= +golang.org/x/net v0.39.0 h1:ZCu7HMWDxpXpaiKdhzIfaltL9Lp31x/3fCP11bc6/fY= +golang.org/x/net v0.39.0/go.mod h1:X7NRbYVEA+ewNkCNyJ513WmMdQ3BineSwVtN2zD/d+E= +golang.org/x/sync v0.13.0 h1:AauUjRAJ9OSnvULf/ARrrVywoJDy0YS2AwQ98I37610= +golang.org/x/sync v0.13.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.31.0 h1:ioabZlmFYtWhL+TRYpcnNlLwhyxaM9kWTDEmfnprqik= -golang.org/x/sys v0.31.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= -golang.org/x/text v0.23.0 h1:D71I7dUrlY+VX0gQShAThNGHFxZ13dGLBHQLVl1mJlY= -golang.org/x/text v0.23.0/go.mod h1:/BLNzu4aZCJ1+kcD0DNRotWKage4q2rGVAg4o22unh4= -google.golang.org/protobuf v1.36.5 h1:tPhr+woSbjfYvY6/GPufUoYizxw1cF/yFoxJ2fmpwlM= -google.golang.org/protobuf v1.36.5/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= +golang.org/x/sys v0.32.0 h1:s77OFDvIQeibCmezSnk/q6iAfkdiQaJi4VzroCFrN20= +golang.org/x/sys v0.32.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= +golang.org/x/text v0.24.0 h1:dd5Bzh4yt5KYA8f9CJHCP4FB4D51c2c6JvN37xJJkJ0= +golang.org/x/text v0.24.0/go.mod h1:L8rBsPeo2pSS+xqN0d5u2ikmjtmoJbDBT1b7nHvFCdU= +google.golang.org/protobuf v1.36.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY= +google.golang.org/protobuf v1.36.6/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= @@ -100,5 +99,5 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= maunium.net/go/mauflag v1.0.0 h1:YiaRc0tEI3toYtJMRIfjP+jklH45uDHtT80nUamyD4M= maunium.net/go/mauflag v1.0.0/go.mod h1:nLivPOpTpHnpzEh8jEdSL9UqO9+/KBJFmNRlwKfkPeA= -maunium.net/go/mautrix v0.23.3-0.20250320134109-06f200da0d10 h1:XE2szxSvJVngk+qHqlKO2fiBZwcAp3oYq+9P5jlAm6w= -maunium.net/go/mautrix v0.23.3-0.20250320134109-06f200da0d10/go.mod h1:pCYLHmo02Jauak/9VlTkbGPrBMvLXsGqTGMNOx+L2PE= +maunium.net/go/mautrix v0.23.3 h1:U+fzdcLhFKLUm5gf2+Q0hEUqWkwDMRfvE+paUH9ogSk= +maunium.net/go/mautrix v0.23.3/go.mod h1:LX+3evXVKSvh/b43BVC3rkvN2qV7b0bkIV4fY7Snn/4= From 6e62a6835fd27767e4c26497e38ea1064a706778 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Thu, 24 Apr 2025 19:16:23 +0300 Subject: [PATCH 319/580] signalmeow/protobuf: rebuild without embed-raw --- .../protobuf/ContactDiscovery.pb.go | 30 +- .../protobuf/ContactDiscovery.pb.raw | 15 - pkg/signalmeow/protobuf/DeviceName.pb.go | 24 +- pkg/signalmeow/protobuf/DeviceName.pb.raw | 9 - pkg/signalmeow/protobuf/Groups.pb.go | 213 +++- pkg/signalmeow/protobuf/Groups.pb.raw | Bin 7339 -> 0 bytes pkg/signalmeow/protobuf/Provisioning.pb.go | 47 +- pkg/signalmeow/protobuf/Provisioning.pb.raw | Bin 957 -> 0 bytes pkg/signalmeow/protobuf/SignalService.pb.go | 668 +++++++++- pkg/signalmeow/protobuf/SignalService.pb.raw | Bin 19700 -> 0 bytes .../protobuf/StickerResources.pb.go | 27 +- .../protobuf/StickerResources.pb.raw | 12 - pkg/signalmeow/protobuf/StorageService.pb.go | 278 ++++- pkg/signalmeow/protobuf/StorageService.pb.raw | Bin 7611 -> 0 bytes .../protobuf/UnidentifiedDelivery.pb.go | 58 +- .../protobuf/UnidentifiedDelivery.pb.raw | Bin 1172 -> 0 bytes .../protobuf/WebSocketResources.pb.go | 38 +- .../protobuf/WebSocketResources.pb.raw | Bin 645 -> 0 bytes pkg/signalmeow/protobuf/backuppb/Backup.pb.go | 1083 ++++++++++++++++- pkg/signalmeow/protobuf/build-protos.sh | 2 - 20 files changed, 2376 insertions(+), 128 deletions(-) delete mode 100644 pkg/signalmeow/protobuf/ContactDiscovery.pb.raw delete mode 100644 pkg/signalmeow/protobuf/DeviceName.pb.raw delete mode 100644 pkg/signalmeow/protobuf/Groups.pb.raw delete mode 100644 pkg/signalmeow/protobuf/Provisioning.pb.raw delete mode 100644 pkg/signalmeow/protobuf/SignalService.pb.raw delete mode 100644 pkg/signalmeow/protobuf/StickerResources.pb.raw delete mode 100644 pkg/signalmeow/protobuf/StorageService.pb.raw delete mode 100644 pkg/signalmeow/protobuf/UnidentifiedDelivery.pb.raw delete mode 100644 pkg/signalmeow/protobuf/WebSocketResources.pb.raw diff --git a/pkg/signalmeow/protobuf/ContactDiscovery.pb.go b/pkg/signalmeow/protobuf/ContactDiscovery.pb.go index 020c413..97ac6b4 100644 --- a/pkg/signalmeow/protobuf/ContactDiscovery.pb.go +++ b/pkg/signalmeow/protobuf/ContactDiscovery.pb.go @@ -1,6 +1,6 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.36.1 +// protoc-gen-go v1.36.6 // protoc v3.21.12 // source: ContactDiscovery.proto @@ -14,10 +14,9 @@ import ( protoimpl "google.golang.org/protobuf/runtime/protoimpl" reflect "reflect" sync "sync" + unsafe "unsafe" ) -import _ "embed" - const ( // Verify that this generated code is sufficiently up-to-date. _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) @@ -206,17 +205,31 @@ func (x *CDSClientResponse) GetToken() []byte { var File_ContactDiscovery_proto protoreflect.FileDescriptor -//go:embed ContactDiscovery.pb.raw -var file_ContactDiscovery_proto_rawDesc []byte +const file_ContactDiscovery_proto_rawDesc = "" + + "\n" + + "\x16ContactDiscovery.proto\x12\rsignalservice\"\x9e\x02\n" + + "\x10CDSClientRequest\x12\"\n" + + "\raci_uak_pairs\x18\x01 \x01(\fR\vaciUakPairs\x12\x1d\n" + + "\n" + + "prev_e164s\x18\x02 \x01(\fR\tprevE164s\x12\x1b\n" + + "\tnew_e164s\x18\x03 \x01(\fR\bnewE164s\x12#\n" + + "\rdiscard_e164s\x18\x04 \x01(\fR\fdiscardE164s\x12\x19\n" + + "\bhas_more\x18\x05 \x01(\bR\ahasMore\x12\x14\n" + + "\x05token\x18\x06 \x01(\fR\x05token\x12\x1b\n" + + "\ttoken_ack\x18\a \x01(\bR\btokenAck\x127\n" + + "\x18return_acis_without_uaks\x18\b \x01(\bR\x15returnAcisWithoutUaks\"Z\n" + + "\x11CDSClientResponse\x12/\n" + + "\x14e164_pni_aci_triples\x18\x01 \x01(\fR\x11e164PniAciTriples\x12\x14\n" + + "\x05token\x18\x03 \x01(\fR\x05token" var ( file_ContactDiscovery_proto_rawDescOnce sync.Once - file_ContactDiscovery_proto_rawDescData = file_ContactDiscovery_proto_rawDesc + file_ContactDiscovery_proto_rawDescData []byte ) func file_ContactDiscovery_proto_rawDescGZIP() []byte { file_ContactDiscovery_proto_rawDescOnce.Do(func() { - file_ContactDiscovery_proto_rawDescData = protoimpl.X.CompressGZIP(file_ContactDiscovery_proto_rawDescData) + file_ContactDiscovery_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_ContactDiscovery_proto_rawDesc), len(file_ContactDiscovery_proto_rawDesc))) }) return file_ContactDiscovery_proto_rawDescData } @@ -243,7 +256,7 @@ func file_ContactDiscovery_proto_init() { out := protoimpl.TypeBuilder{ File: protoimpl.DescBuilder{ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: file_ContactDiscovery_proto_rawDesc, + RawDescriptor: unsafe.Slice(unsafe.StringData(file_ContactDiscovery_proto_rawDesc), len(file_ContactDiscovery_proto_rawDesc)), NumEnums: 0, NumMessages: 2, NumExtensions: 0, @@ -254,7 +267,6 @@ func file_ContactDiscovery_proto_init() { MessageInfos: file_ContactDiscovery_proto_msgTypes, }.Build() File_ContactDiscovery_proto = out.File - file_ContactDiscovery_proto_rawDesc = nil file_ContactDiscovery_proto_goTypes = nil file_ContactDiscovery_proto_depIdxs = nil } diff --git a/pkg/signalmeow/protobuf/ContactDiscovery.pb.raw b/pkg/signalmeow/protobuf/ContactDiscovery.pb.raw deleted file mode 100644 index c98f8c4..0000000 --- a/pkg/signalmeow/protobuf/ContactDiscovery.pb.raw +++ /dev/null @@ -1,15 +0,0 @@ - -ContactDiscovery.proto signalservice"ž -CDSClientRequest" - aci_uak_pairs ( R aciUakPairs - -prev_e164s ( R prevE164s - new_e164s ( RnewE164s# - discard_e164s ( R discardE164s -has_more (RhasMore -token ( Rtoken - token_ack (RtokenAck7 -return_acis_without_uaks (RreturnAcisWithoutUaks"Z -CDSClientResponse/ -e164_pni_aci_triples ( Re164PniAciTriples -token ( Rtoken \ No newline at end of file diff --git a/pkg/signalmeow/protobuf/DeviceName.pb.go b/pkg/signalmeow/protobuf/DeviceName.pb.go index dbc3df8..e83e374 100644 --- a/pkg/signalmeow/protobuf/DeviceName.pb.go +++ b/pkg/signalmeow/protobuf/DeviceName.pb.go @@ -1,6 +1,6 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.36.1 +// protoc-gen-go v1.36.6 // protoc v3.21.12 // source: DeviceName.proto @@ -14,10 +14,9 @@ import ( protoimpl "google.golang.org/protobuf/runtime/protoimpl" reflect "reflect" sync "sync" + unsafe "unsafe" ) -import _ "embed" - const ( // Verify that this generated code is sufficiently up-to-date. _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) @@ -87,17 +86,25 @@ func (x *DeviceName) GetCiphertext() []byte { var File_DeviceName_proto protoreflect.FileDescriptor -//go:embed DeviceName.pb.raw -var file_DeviceName_proto_rawDesc []byte +const file_DeviceName_proto_rawDesc = "" + + "\n" + + "\x10DeviceName.proto\x12\rsignalservice\"x\n" + + "\n" + + "DeviceName\x12(\n" + + "\x0fephemeralPublic\x18\x01 \x01(\fR\x0fephemeralPublic\x12 \n" + + "\vsyntheticIv\x18\x02 \x01(\fR\vsyntheticIv\x12\x1e\n" + + "\n" + + "ciphertext\x18\x03 \x01(\fR\n" + + "ciphertext" var ( file_DeviceName_proto_rawDescOnce sync.Once - file_DeviceName_proto_rawDescData = file_DeviceName_proto_rawDesc + file_DeviceName_proto_rawDescData []byte ) func file_DeviceName_proto_rawDescGZIP() []byte { file_DeviceName_proto_rawDescOnce.Do(func() { - file_DeviceName_proto_rawDescData = protoimpl.X.CompressGZIP(file_DeviceName_proto_rawDescData) + file_DeviceName_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_DeviceName_proto_rawDesc), len(file_DeviceName_proto_rawDesc))) }) return file_DeviceName_proto_rawDescData } @@ -123,7 +130,7 @@ func file_DeviceName_proto_init() { out := protoimpl.TypeBuilder{ File: protoimpl.DescBuilder{ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: file_DeviceName_proto_rawDesc, + RawDescriptor: unsafe.Slice(unsafe.StringData(file_DeviceName_proto_rawDesc), len(file_DeviceName_proto_rawDesc)), NumEnums: 0, NumMessages: 1, NumExtensions: 0, @@ -134,7 +141,6 @@ func file_DeviceName_proto_init() { MessageInfos: file_DeviceName_proto_msgTypes, }.Build() File_DeviceName_proto = out.File - file_DeviceName_proto_rawDesc = nil file_DeviceName_proto_goTypes = nil file_DeviceName_proto_depIdxs = nil } diff --git a/pkg/signalmeow/protobuf/DeviceName.pb.raw b/pkg/signalmeow/protobuf/DeviceName.pb.raw deleted file mode 100644 index b8aca07..0000000 --- a/pkg/signalmeow/protobuf/DeviceName.pb.raw +++ /dev/null @@ -1,9 +0,0 @@ - -DeviceName.proto signalservice"x - -DeviceName( -ephemeralPublic ( RephemeralPublic - syntheticIv ( R syntheticIv - -ciphertext ( R -ciphertext \ No newline at end of file diff --git a/pkg/signalmeow/protobuf/Groups.pb.go b/pkg/signalmeow/protobuf/Groups.pb.go index 212d5a3..7178760 100644 --- a/pkg/signalmeow/protobuf/Groups.pb.go +++ b/pkg/signalmeow/protobuf/Groups.pb.go @@ -5,7 +5,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.36.1 +// protoc-gen-go v1.36.6 // protoc v3.21.12 // source: Groups.proto @@ -16,10 +16,9 @@ import ( protoimpl "google.golang.org/protobuf/runtime/protoimpl" reflect "reflect" sync "sync" + unsafe "unsafe" ) -import _ "embed" - const ( // Verify that this generated code is sufficiently up-to-date. _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) @@ -2609,17 +2608,214 @@ func (x *GroupInviteLink_GroupInviteLinkContentsV1) GetInviteLinkPassword() []by var File_Groups_proto protoreflect.FileDescriptor -//go:embed Groups.pb.raw -var file_Groups_proto_rawDesc []byte +const file_Groups_proto_rawDesc = "" + + "\n" + + "\fGroups.proto\"\xc4\x01\n" + + "\x16AvatarUploadAttributes\x12\x10\n" + + "\x03key\x18\x01 \x01(\tR\x03key\x12\x1e\n" + + "\n" + + "credential\x18\x02 \x01(\tR\n" + + "credential\x12\x10\n" + + "\x03acl\x18\x03 \x01(\tR\x03acl\x12\x1c\n" + + "\talgorithm\x18\x04 \x01(\tR\talgorithm\x12\x12\n" + + "\x04date\x18\x05 \x01(\tR\x04date\x12\x16\n" + + "\x06policy\x18\x06 \x01(\tR\x06policy\x12\x1c\n" + + "\tsignature\x18\a \x01(\tR\tsignature\"\xe7\x01\n" + + "\x06Member\x12\x16\n" + + "\x06userId\x18\x01 \x01(\fR\x06userId\x12 \n" + + "\x04role\x18\x02 \x01(\x0e2\f.Member.RoleR\x04role\x12\x1e\n" + + "\n" + + "profileKey\x18\x03 \x01(\fR\n" + + "profileKey\x12\"\n" + + "\fpresentation\x18\x04 \x01(\fR\fpresentation\x12*\n" + + "\x10joinedAtRevision\x18\x05 \x01(\rR\x10joinedAtRevision\"3\n" + + "\x04Role\x12\v\n" + + "\aUNKNOWN\x10\x00\x12\v\n" + + "\aDEFAULT\x10\x01\x12\x11\n" + + "\rADMINISTRATOR\x10\x02\"t\n" + + "\rPendingMember\x12\x1f\n" + + "\x06member\x18\x01 \x01(\v2\a.MemberR\x06member\x12$\n" + + "\raddedByUserId\x18\x02 \x01(\fR\raddedByUserId\x12\x1c\n" + + "\ttimestamp\x18\x03 \x01(\x04R\ttimestamp\"\x8c\x01\n" + + "\x10RequestingMember\x12\x16\n" + + "\x06userId\x18\x01 \x01(\fR\x06userId\x12\x1e\n" + + "\n" + + "profileKey\x18\x02 \x01(\fR\n" + + "profileKey\x12\"\n" + + "\fpresentation\x18\x03 \x01(\fR\fpresentation\x12\x1c\n" + + "\ttimestamp\x18\x04 \x01(\x04R\ttimestamp\"D\n" + + "\fBannedMember\x12\x16\n" + + "\x06userId\x18\x01 \x01(\fR\x06userId\x12\x1c\n" + + "\ttimestamp\x18\x02 \x01(\x04R\ttimestamp\"\xae\x02\n" + + "\rAccessControl\x12=\n" + + "\n" + + "attributes\x18\x01 \x01(\x0e2\x1d.AccessControl.AccessRequiredR\n" + + "attributes\x127\n" + + "\amembers\x18\x02 \x01(\x0e2\x1d.AccessControl.AccessRequiredR\amembers\x12K\n" + + "\x11addFromInviteLink\x18\x03 \x01(\x0e2\x1d.AccessControl.AccessRequiredR\x11addFromInviteLink\"X\n" + + "\x0eAccessRequired\x12\v\n" + + "\aUNKNOWN\x10\x00\x12\a\n" + + "\x03ANY\x10\x01\x12\n" + + "\n" + + "\x06MEMBER\x10\x02\x12\x11\n" + + "\rADMINISTRATOR\x10\x03\x12\x11\n" + + "\rUNSATISFIABLE\x10\x04\"\xb4\x04\n" + + "\x05Group\x12\x1c\n" + + "\tpublicKey\x18\x01 \x01(\fR\tpublicKey\x12\x14\n" + + "\x05title\x18\x02 \x01(\fR\x05title\x12\x16\n" + + "\x06avatar\x18\x03 \x01(\tR\x06avatar\x12<\n" + + "\x19disappearingMessagesTimer\x18\x04 \x01(\fR\x19disappearingMessagesTimer\x124\n" + + "\raccessControl\x18\x05 \x01(\v2\x0e.AccessControlR\raccessControl\x12\x1a\n" + + "\brevision\x18\x06 \x01(\rR\brevision\x12!\n" + + "\amembers\x18\a \x03(\v2\a.MemberR\amembers\x126\n" + + "\x0ependingMembers\x18\b \x03(\v2\x0e.PendingMemberR\x0ependingMembers\x12?\n" + + "\x11requestingMembers\x18\t \x03(\v2\x11.RequestingMemberR\x11requestingMembers\x12.\n" + + "\x12inviteLinkPassword\x18\n" + + " \x01(\fR\x12inviteLinkPassword\x12 \n" + + "\vdescription\x18\v \x01(\fR\vdescription\x12,\n" + + "\x11announcementsOnly\x18\f \x01(\bR\x11announcementsOnly\x123\n" + + "\rbannedMembers\x18\r \x03(\v2\r.BannedMemberR\rbannedMembers\"\xe6!\n" + + "\vGroupChange\x12\x18\n" + + "\aactions\x18\x01 \x01(\fR\aactions\x12(\n" + + "\x0fserverSignature\x18\x02 \x01(\fR\x0fserverSignature\x12 \n" + + "\vchangeEpoch\x18\x03 \x01(\rR\vchangeEpoch\x1a\xf0 \n" + + "\aActions\x12(\n" + + "\x0fsourceServiceId\x18\x01 \x01(\fR\x0fsourceServiceId\x12\x18\n" + + "\agroupId\x18\x19 \x01(\fR\agroupId\x12\x1a\n" + + "\brevision\x18\x02 \x01(\rR\brevision\x12D\n" + + "\n" + + "addMembers\x18\x03 \x03(\v2$.GroupChange.Actions.AddMemberActionR\n" + + "addMembers\x12M\n" + + "\rdeleteMembers\x18\x04 \x03(\v2'.GroupChange.Actions.DeleteMemberActionR\rdeleteMembers\x12Y\n" + + "\x11modifyMemberRoles\x18\x05 \x03(\v2+.GroupChange.Actions.ModifyMemberRoleActionR\x11modifyMemberRoles\x12k\n" + + "\x17modifyMemberProfileKeys\x18\x06 \x03(\v21.GroupChange.Actions.ModifyMemberProfileKeyActionR\x17modifyMemberProfileKeys\x12Y\n" + + "\x11addPendingMembers\x18\a \x03(\v2+.GroupChange.Actions.AddPendingMemberActionR\x11addPendingMembers\x12b\n" + + "\x14deletePendingMembers\x18\b \x03(\v2..GroupChange.Actions.DeletePendingMemberActionR\x14deletePendingMembers\x12e\n" + + "\x15promotePendingMembers\x18\t \x03(\v2/.GroupChange.Actions.PromotePendingMemberActionR\x15promotePendingMembers\x12H\n" + + "\vmodifyTitle\x18\n" + + " \x01(\v2&.GroupChange.Actions.ModifyTitleActionR\vmodifyTitle\x12K\n" + + "\fmodifyAvatar\x18\v \x01(\v2'.GroupChange.Actions.ModifyAvatarActionR\fmodifyAvatar\x12\x84\x01\n" + + "\x1fmodifyDisappearingMessagesTimer\x18\f \x01(\v2:.GroupChange.Actions.ModifyDisappearingMessagesTimerActionR\x1fmodifyDisappearingMessagesTimer\x12p\n" + + "\x16modifyAttributesAccess\x18\r \x01(\v28.GroupChange.Actions.ModifyAttributesAccessControlActionR\x16modifyAttributesAccess\x12e\n" + + "\x12modifyMemberAccess\x18\x0e \x01(\v25.GroupChange.Actions.ModifyMembersAccessControlActionR\x12modifyMemberAccess\x12\x85\x01\n" + + "\x1dmodifyAddFromInviteLinkAccess\x18\x0f \x01(\v2?.GroupChange.Actions.ModifyAddFromInviteLinkAccessControlActionR\x1dmodifyAddFromInviteLinkAccess\x12b\n" + + "\x14addRequestingMembers\x18\x10 \x03(\v2..GroupChange.Actions.AddRequestingMemberActionR\x14addRequestingMembers\x12k\n" + + "\x17deleteRequestingMembers\x18\x11 \x03(\v21.GroupChange.Actions.DeleteRequestingMemberActionR\x17deleteRequestingMembers\x12n\n" + + "\x18promoteRequestingMembers\x18\x12 \x03(\v22.GroupChange.Actions.PromoteRequestingMemberActionR\x18promoteRequestingMembers\x12o\n" + + "\x18modifyInviteLinkPassword\x18\x13 \x01(\v23.GroupChange.Actions.ModifyInviteLinkPasswordActionR\x18modifyInviteLinkPassword\x12Z\n" + + "\x11modifyDescription\x18\x14 \x01(\v2,.GroupChange.Actions.ModifyDescriptionActionR\x11modifyDescription\x12l\n" + + "\x17modifyAnnouncementsOnly\x18\x15 \x01(\v22.GroupChange.Actions.ModifyAnnouncementsOnlyActionR\x17modifyAnnouncementsOnly\x12V\n" + + "\x10addBannedMembers\x18\x16 \x03(\v2*.GroupChange.Actions.AddBannedMemberActionR\x10addBannedMembers\x12_\n" + + "\x13deleteBannedMembers\x18\x17 \x03(\v2-.GroupChange.Actions.DeleteBannedMemberActionR\x13deleteBannedMembers\x12\x81\x01\n" + + "\x1bpromotePendingPniAciMembers\x18\x18 \x03(\v2?.GroupChange.Actions.PromotePendingPniAciMemberProfileKeyActionR\x1bpromotePendingPniAciMembers\x1a`\n" + + "\x0fAddMemberAction\x12\x1d\n" + + "\x05added\x18\x01 \x01(\v2\a.MemberR\x05added\x12.\n" + + "\x12joinFromInviteLink\x18\x02 \x01(\bR\x12joinFromInviteLink\x1a:\n" + + "\x12DeleteMemberAction\x12$\n" + + "\rdeletedUserId\x18\x01 \x01(\fR\rdeletedUserId\x1aR\n" + + "\x16ModifyMemberRoleAction\x12\x16\n" + + "\x06userId\x18\x01 \x01(\fR\x06userId\x12 \n" + + "\x04role\x18\x02 \x01(\x0e2\f.Member.RoleR\x04role\x1a|\n" + + "\x1cModifyMemberProfileKeyAction\x12\"\n" + + "\fpresentation\x18\x01 \x01(\fR\fpresentation\x12\x17\n" + + "\auser_id\x18\x02 \x01(\fR\x06userId\x12\x1f\n" + + "\vprofile_key\x18\x03 \x01(\fR\n" + + "profileKey\x1a>\n" + + "\x16AddPendingMemberAction\x12$\n" + + "\x05added\x18\x01 \x01(\v2\x0e.PendingMemberR\x05added\x1aA\n" + + "\x19DeletePendingMemberAction\x12$\n" + + "\rdeletedUserId\x18\x01 \x01(\fR\rdeletedUserId\x1az\n" + + "\x1aPromotePendingMemberAction\x12\"\n" + + "\fpresentation\x18\x01 \x01(\fR\fpresentation\x12\x17\n" + + "\auser_id\x18\x02 \x01(\fR\x06userId\x12\x1f\n" + + "\vprofile_key\x18\x03 \x01(\fR\n" + + "profileKey\x1a\x9a\x01\n" + + "*PromotePendingPniAciMemberProfileKeyAction\x12\"\n" + + "\fpresentation\x18\x01 \x01(\fR\fpresentation\x12\x16\n" + + "\x06userId\x18\x02 \x01(\fR\x06userId\x12\x10\n" + + "\x03pni\x18\x03 \x01(\fR\x03pni\x12\x1e\n" + + "\n" + + "profileKey\x18\x04 \x01(\fR\n" + + "profileKey\x1aD\n" + + "\x19AddRequestingMemberAction\x12'\n" + + "\x05added\x18\x01 \x01(\v2\x11.RequestingMemberR\x05added\x1aD\n" + + "\x1cDeleteRequestingMemberAction\x12$\n" + + "\rdeletedUserId\x18\x01 \x01(\fR\rdeletedUserId\x1aY\n" + + "\x1dPromoteRequestingMemberAction\x12\x16\n" + + "\x06userId\x18\x01 \x01(\fR\x06userId\x12 \n" + + "\x04role\x18\x02 \x01(\x0e2\f.Member.RoleR\x04role\x1a<\n" + + "\x15AddBannedMemberAction\x12#\n" + + "\x05added\x18\x01 \x01(\v2\r.BannedMemberR\x05added\x1a@\n" + + "\x18DeleteBannedMemberAction\x12$\n" + + "\rdeletedUserId\x18\x01 \x01(\fR\rdeletedUserId\x1a)\n" + + "\x11ModifyTitleAction\x12\x14\n" + + "\x05title\x18\x01 \x01(\fR\x05title\x1a;\n" + + "\x17ModifyDescriptionAction\x12 \n" + + "\vdescription\x18\x01 \x01(\fR\vdescription\x1a,\n" + + "\x12ModifyAvatarAction\x12\x16\n" + + "\x06avatar\x18\x01 \x01(\tR\x06avatar\x1a=\n" + + "%ModifyDisappearingMessagesTimerAction\x12\x14\n" + + "\x05timer\x18\x01 \x01(\fR\x05timer\x1ap\n" + + "#ModifyAttributesAccessControlAction\x12I\n" + + "\x10attributesAccess\x18\x01 \x01(\x0e2\x1d.AccessControl.AccessRequiredR\x10attributesAccess\x1ag\n" + + " ModifyMembersAccessControlAction\x12C\n" + + "\rmembersAccess\x18\x01 \x01(\x0e2\x1d.AccessControl.AccessRequiredR\rmembersAccess\x1a\x85\x01\n" + + "*ModifyAddFromInviteLinkAccessControlAction\x12W\n" + + "\x17addFromInviteLinkAccess\x18\x01 \x01(\x0e2\x1d.AccessControl.AccessRequiredR\x17addFromInviteLinkAccess\x1aP\n" + + "\x1eModifyInviteLinkPasswordAction\x12.\n" + + "\x12inviteLinkPassword\x18\x01 \x01(\fR\x12inviteLinkPassword\x1aM\n" + + "\x1dModifyAnnouncementsOnlyAction\x12,\n" + + "\x11announcementsOnly\x18\x01 \x01(\bR\x11announcementsOnly\"s\n" + + "\rGroupResponse\x12\x1c\n" + + "\x05group\x18\x01 \x01(\v2\x06.GroupR\x05group\x12D\n" + + "\x1dgroupSendEndorsementsResponse\x18\x02 \x01(\fR\x1dgroupSendEndorsementsResponse\"\x84\x02\n" + + "\fGroupChanges\x12B\n" + + "\fgroupChanges\x18\x01 \x03(\v2\x1e.GroupChanges.GroupChangeStateR\fgroupChanges\x12D\n" + + "\x1dgroupSendEndorsementsResponse\x18\x02 \x01(\fR\x1dgroupSendEndorsementsResponse\x1aj\n" + + "\x10GroupChangeState\x12.\n" + + "\vgroupChange\x18\x01 \x01(\v2\f.GroupChangeR\vgroupChange\x12&\n" + + "\n" + + "groupState\x18\x02 \x01(\v2\x06.GroupR\n" + + "groupState\"\x8b\x01\n" + + "\x13GroupChangeResponse\x12.\n" + + "\vgroupChange\x18\x01 \x01(\v2\f.GroupChangeR\vgroupChange\x12D\n" + + "\x1dgroupSendEndorsementsResponse\x18\x02 \x01(\fR\x1dgroupSendEndorsementsResponse\"\xbb\x01\n" + + "\x12GroupAttributeBlob\x12\x16\n" + + "\x05title\x18\x01 \x01(\tH\x00R\x05title\x12\x18\n" + + "\x06avatar\x18\x02 \x01(\fH\x00R\x06avatar\x12D\n" + + "\x1cdisappearingMessagesDuration\x18\x03 \x01(\rH\x00R\x1cdisappearingMessagesDuration\x12\"\n" + + "\vdescription\x18\x04 \x01(\tH\x00R\vdescriptionB\t\n" + + "\acontent\"\xe0\x01\n" + + "\x0fGroupInviteLink\x12L\n" + + "\n" + + "v1Contents\x18\x01 \x01(\v2*.GroupInviteLink.GroupInviteLinkContentsV1H\x00R\n" + + "v1Contents\x1as\n" + + "\x19GroupInviteLinkContentsV1\x12&\n" + + "\x0egroupMasterKey\x18\x01 \x01(\fR\x0egroupMasterKey\x12.\n" + + "\x12inviteLinkPassword\x18\x02 \x01(\fR\x12inviteLinkPasswordB\n" + + "\n" + + "\bcontents\"\xbc\x02\n" + + "\rGroupJoinInfo\x12\x1c\n" + + "\tpublicKey\x18\x01 \x01(\fR\tpublicKey\x12\x14\n" + + "\x05title\x18\x02 \x01(\fR\x05title\x12\x16\n" + + "\x06avatar\x18\x03 \x01(\tR\x06avatar\x12 \n" + + "\vmemberCount\x18\x04 \x01(\rR\vmemberCount\x12K\n" + + "\x11addFromInviteLink\x18\x05 \x01(\x0e2\x1d.AccessControl.AccessRequiredR\x11addFromInviteLink\x12\x1a\n" + + "\brevision\x18\x06 \x01(\rR\brevision\x122\n" + + "\x14pendingAdminApproval\x18\a \x01(\bR\x14pendingAdminApproval\x12 \n" + + "\vdescription\x18\b \x01(\fR\vdescription\"/\n" + + "\x17GroupExternalCredential\x12\x14\n" + + "\x05token\x18\x01 \x01(\tR\x05tokenB+\n" + + "'org.signal.storageservice.protos.groupsP\x01b\x06proto3" var ( file_Groups_proto_rawDescOnce sync.Once - file_Groups_proto_rawDescData = file_Groups_proto_rawDesc + file_Groups_proto_rawDescData []byte ) func file_Groups_proto_rawDescGZIP() []byte { file_Groups_proto_rawDescOnce.Do(func() { - file_Groups_proto_rawDescData = protoimpl.X.CompressGZIP(file_Groups_proto_rawDescData) + file_Groups_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_Groups_proto_rawDesc), len(file_Groups_proto_rawDesc))) }) return file_Groups_proto_rawDescData } @@ -2744,7 +2940,7 @@ func file_Groups_proto_init() { out := protoimpl.TypeBuilder{ File: protoimpl.DescBuilder{ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: file_Groups_proto_rawDesc, + RawDescriptor: unsafe.Slice(unsafe.StringData(file_Groups_proto_rawDesc), len(file_Groups_proto_rawDesc)), NumEnums: 2, NumMessages: 40, NumExtensions: 0, @@ -2756,7 +2952,6 @@ func file_Groups_proto_init() { MessageInfos: file_Groups_proto_msgTypes, }.Build() File_Groups_proto = out.File - file_Groups_proto_rawDesc = nil file_Groups_proto_goTypes = nil file_Groups_proto_depIdxs = nil } diff --git a/pkg/signalmeow/protobuf/Groups.pb.raw b/pkg/signalmeow/protobuf/Groups.pb.raw deleted file mode 100644 index dceda274eece491e05fbb427b8eb4b191fdc755d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7339 zcmb_hOLH5?5jMmJ$Ob@yBZ*vYM2UtSOOX}01m#tZ9S0z&n2|`amZTl|A}@gvv=*?7 z>@1lul}oCeQ}PS)BXY_uIr@kAG<`+(3yKryWlRw#QfKJT2JWK+=?_5(G z#){a|(|l|vqO zgRrOVy#tE_Wx2Aq)F^7pJiW}`g^J(p@^0(mg#01{SN7~h>E9$6aFO_fp|XA68!y!U zT7as@e|v`eW6je%ZTpe5&GI98+V-P$9GN)QaoSLB`5}7wl9*dkK2XulFkUQ7CeK2{S=B63Zb*?65f=WJ%Ke0(c?H8?1kq+ z!k-4=YZZh`)lc%(egi9X;`EGmf)!z|dGH*Q3$SE%_glM|Rg;M}CznnRj+)1NN00ZK zt*5)y`Px6`VL^2dnJvS!Q!Gr!Ag3WFq z{Na%Mu}Ur>{2mv_n2oWnvFQZtN0{Aa3{|z28Y_0xFxyQc=E72(mZ$796>s#--X2G> zxIK5zsHjoAegZ2)vj~N=q$pSFR&9D2D)tGi#hEG+&az@%t7q%Wo1|rRV8JLu4t*hh z7sXu%Q~+{zu<4b$Ty)}Ks5(|j5t>Wv0j6FUMrUD%53sX|XJP-sDI?vIH@U$cLFLpa zJmFN-;VX5s96g(+_TAf1QfagE$`5;-IZ*UF@;pMPPWs92!78?>a~>a!T0OOo?6Neh zqonN)qs}XpQ5DZza{sdp#U`mya-*}j!;esU(BY%YVO7}6@@zeMKO)7Za#s3jrHnk3 znKEtc8(rOu1Rh3a&AWBOX3R!qaJ`w5(E_%QbV0CvsC0RsC!D&Pz~q;L?&b<=8 z&CQ;}+92u%FE2=(ylMnihZOmKuE_liwH7-mg}sIiQ}p5J))aVaO9c-vRWRn!YNkn) zcA%52!V)+EOt%AlY*D9nOh{p;aDzN<(Wlj1&ozP^Z!u^Exw06Cn>bYrqJ&#KY2AO2 zs|39>!J)O}OJkoxi9&L$Ir`H?^D-4|2U%K`UVe;XQe#2_rvvjy$!YcYB zZBlYbVOy|({^az4HpX9Cl{2V(;@T}kJ$RP9oE`T=VB{7{3BF3nxn2D#rB{T#=z6eD zNkP1Fh9RT=|7X7YN4RCm%(`phnNJ6^pQjs8lpw>4psNfYqYQVTgb|hge<8t>2@t{k z1>!Ba^9jDwEw^Xi613?yVUxURO%vKFS99tgz_qi-3QQK|c(dmJtpN9J<+D=vO0gKj z5cF0^0Ut!8hGC#XAb(~69*HVg0FT>-O^i)`>t=WD@Z`MLbcEV)iy|~d(A9$U9JaKd zridAvO%Y1Xz7*$jKZ2WR=46v%@7N}0UUk~MUxGvC9WB9&SHEmGUiWRycv5C=1@xvX$ zJ6c(0!nDRkwug6BhTv*A(*&E_gKg4CN+A(GGJf2Cw-UA>f z$x|wijQwcr)c#U{>xQz_hySy_Hxrb97J#YKj2@4zesqexM+2iWg_b{kD}_d#5j3i< zFx*JNQM^p@z|r7FOwjl4x1jY$5a%?@pnr9*+bN3@Vf#wGYZC}81j{##NhUQk??qoFlSb$R67j; zIn~|*Ske}X+P@I{S10&2jWa zs4nv8H4jyeEMtbtkJkHeH;Q|8^^aY@E|Msg7(b!0^jD;)tDuX+!s#NOF^L}i7t^s? A+yDRo diff --git a/pkg/signalmeow/protobuf/Provisioning.pb.go b/pkg/signalmeow/protobuf/Provisioning.pb.go index 97c5adc..e2fbf7c 100644 --- a/pkg/signalmeow/protobuf/Provisioning.pb.go +++ b/pkg/signalmeow/protobuf/Provisioning.pb.go @@ -5,7 +5,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.36.1 +// protoc-gen-go v1.36.6 // protoc v3.21.12 // source: Provisioning.proto @@ -16,10 +16,9 @@ import ( protoimpl "google.golang.org/protobuf/runtime/protoimpl" reflect "reflect" sync "sync" + unsafe "unsafe" ) -import _ "embed" - const ( // Verify that this generated code is sufficiently up-to-date. _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) @@ -348,17 +347,48 @@ func (x *ProvisionMessage) GetMediaRootBackupKey() []byte { var File_Provisioning_proto protoreflect.FileDescriptor -//go:embed Provisioning.pb.raw -var file_Provisioning_proto_rawDesc []byte +const file_Provisioning_proto_rawDesc = "" + + "\n" + + "\x12Provisioning.proto\x12\rsignalservice\"/\n" + + "\x13ProvisioningAddress\x12\x18\n" + + "\aaddress\x18\x01 \x01(\tR\aaddress\"E\n" + + "\x11ProvisionEnvelope\x12\x1c\n" + + "\tpublicKey\x18\x01 \x01(\fR\tpublicKey\x12\x12\n" + + "\x04body\x18\x02 \x01(\fR\x04body\"\x90\x05\n" + + "\x10ProvisionMessage\x122\n" + + "\x14aciIdentityKeyPublic\x18\x01 \x01(\fR\x14aciIdentityKeyPublic\x124\n" + + "\x15aciIdentityKeyPrivate\x18\x02 \x01(\fR\x15aciIdentityKeyPrivate\x122\n" + + "\x14pniIdentityKeyPublic\x18\v \x01(\fR\x14pniIdentityKeyPublic\x124\n" + + "\x15pniIdentityKeyPrivate\x18\f \x01(\fR\x15pniIdentityKeyPrivate\x12\x10\n" + + "\x03aci\x18\b \x01(\tR\x03aci\x12\x10\n" + + "\x03pni\x18\n" + + " \x01(\tR\x03pni\x12\x16\n" + + "\x06number\x18\x03 \x01(\tR\x06number\x12*\n" + + "\x10provisioningCode\x18\x04 \x01(\tR\x10provisioningCode\x12\x1c\n" + + "\tuserAgent\x18\x05 \x01(\tR\tuserAgent\x12\x1e\n" + + "\n" + + "profileKey\x18\x06 \x01(\fR\n" + + "profileKey\x12\"\n" + + "\freadReceipts\x18\a \x01(\bR\freadReceipts\x120\n" + + "\x13provisioningVersion\x18\t \x01(\rR\x13provisioningVersion\x12\x1c\n" + + "\tmasterKey\x18\r \x01(\fR\tmasterKey\x12.\n" + + "\x12ephemeralBackupKey\x18\x0e \x01(\fR\x12ephemeralBackupKey\x12.\n" + + "\x12accountEntropyPool\x18\x0f \x01(\tR\x12accountEntropyPool\x12.\n" + + "\x12mediaRootBackupKey\x18\x10 \x01(\fR\x12mediaRootBackupKey*G\n" + + "\x13ProvisioningVersion\x12\v\n" + + "\aINITIAL\x10\x00\x12\x12\n" + + "\x0eTABLET_SUPPORT\x10\x01\x12\v\n" + + "\aCURRENT\x10\x01\x1a\x02\x10\x01BD\n" + + ".org.whispersystems.signalservice.internal.pushB\x12ProvisioningProtos" var ( file_Provisioning_proto_rawDescOnce sync.Once - file_Provisioning_proto_rawDescData = file_Provisioning_proto_rawDesc + file_Provisioning_proto_rawDescData []byte ) func file_Provisioning_proto_rawDescGZIP() []byte { file_Provisioning_proto_rawDescOnce.Do(func() { - file_Provisioning_proto_rawDescData = protoimpl.X.CompressGZIP(file_Provisioning_proto_rawDescData) + file_Provisioning_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_Provisioning_proto_rawDesc), len(file_Provisioning_proto_rawDesc))) }) return file_Provisioning_proto_rawDescData } @@ -388,7 +418,7 @@ func file_Provisioning_proto_init() { out := protoimpl.TypeBuilder{ File: protoimpl.DescBuilder{ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: file_Provisioning_proto_rawDesc, + RawDescriptor: unsafe.Slice(unsafe.StringData(file_Provisioning_proto_rawDesc), len(file_Provisioning_proto_rawDesc)), NumEnums: 1, NumMessages: 3, NumExtensions: 0, @@ -400,7 +430,6 @@ func file_Provisioning_proto_init() { MessageInfos: file_Provisioning_proto_msgTypes, }.Build() File_Provisioning_proto = out.File - file_Provisioning_proto_rawDesc = nil file_Provisioning_proto_goTypes = nil file_Provisioning_proto_depIdxs = nil } diff --git a/pkg/signalmeow/protobuf/Provisioning.pb.raw b/pkg/signalmeow/protobuf/Provisioning.pb.raw deleted file mode 100644 index 874538c7f1185b2aa7736feabcfdb3e4125f025d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 957 zcmZuw+iuf95GB2(**eAD0$L%2P@Yg93_|^Zq*y4T6l+O&MH_oaR<*sWT|3Bs!6!4j zF}bvUn?2{unemK=(8Q>fv{IF_TtwQaO3|T}i&Eqk%u1#(`amvsMdK_pU@c{&FV-RJ zz3aUn@c++IOfEJFak+wAX`pY&K-cqJreC4)2?5^%l#-*l${KcnP67Av=9V8JnQyU^bCn+Dw3Py% z)J@Wm9Aba$)KAfc4nZGA)(D356*(#EVh)BKda!-bD-z<;HXFQA8L%U-c!IkX)VS2~ z0*A+ry=V*2w}hb6Z<&MJ&!bT%E|hR^U\n" + + "\tthumbnail\x18\x03 \x01(\v2 .signalservice.AttachmentPointerR\tthumbnail\"\"\n" + + "\x04Type\x12\n" + + "\n" + + "\x06NORMAL\x10\x00\x12\x0e\n" + + "\n" + + "GIFT_BADGE\x10\x01J\x04\b\x02\x10\x03\x1a\xbf\n" + + "\n" + + "\aContact\x12;\n" + + "\x04name\x18\x01 \x01(\v2'.signalservice.DataMessage.Contact.NameR\x04name\x12@\n" + + "\x06number\x18\x03 \x03(\v2(.signalservice.DataMessage.Contact.PhoneR\x06number\x12>\n" + + "\x05email\x18\x04 \x03(\v2(.signalservice.DataMessage.Contact.EmailR\x05email\x12J\n" + + "\aaddress\x18\x05 \x03(\v20.signalservice.DataMessage.Contact.PostalAddressR\aaddress\x12A\n" + + "\x06avatar\x18\x06 \x01(\v2).signalservice.DataMessage.Contact.AvatarR\x06avatar\x12\"\n" + + "\forganization\x18\a \x01(\tR\forganization\x1a\xb6\x01\n" + + "\x04Name\x12\x1c\n" + + "\tgivenName\x18\x01 \x01(\tR\tgivenName\x12\x1e\n" + + "\n" + + "familyName\x18\x02 \x01(\tR\n" + + "familyName\x12\x16\n" + + "\x06prefix\x18\x03 \x01(\tR\x06prefix\x12\x16\n" + + "\x06suffix\x18\x04 \x01(\tR\x06suffix\x12\x1e\n" + + "\n" + + "middleName\x18\x05 \x01(\tR\n" + + "middleName\x12\x1a\n" + + "\bnickname\x18\a \x01(\tR\bnicknameJ\x04\b\x06\x10\a\x1a\xaa\x01\n" + + "\x05Phone\x12\x14\n" + + "\x05value\x18\x01 \x01(\tR\x05value\x12A\n" + + "\x04type\x18\x02 \x01(\x0e2-.signalservice.DataMessage.Contact.Phone.TypeR\x04type\x12\x14\n" + + "\x05label\x18\x03 \x01(\tR\x05label\"2\n" + + "\x04Type\x12\b\n" + + "\x04HOME\x10\x01\x12\n" + + "\n" + + "\x06MOBILE\x10\x02\x12\b\n" + + "\x04WORK\x10\x03\x12\n" + + "\n" + + "\x06CUSTOM\x10\x04\x1a\xaa\x01\n" + + "\x05Email\x12\x14\n" + + "\x05value\x18\x01 \x01(\tR\x05value\x12A\n" + + "\x04type\x18\x02 \x01(\x0e2-.signalservice.DataMessage.Contact.Email.TypeR\x04type\x12\x14\n" + + "\x05label\x18\x03 \x01(\tR\x05label\"2\n" + + "\x04Type\x12\b\n" + + "\x04HOME\x10\x01\x12\n" + + "\n" + + "\x06MOBILE\x10\x02\x12\b\n" + + "\x04WORK\x10\x03\x12\n" + + "\n" + + "\x06CUSTOM\x10\x04\x1a\xcc\x02\n" + + "\rPostalAddress\x12I\n" + + "\x04type\x18\x01 \x01(\x0e25.signalservice.DataMessage.Contact.PostalAddress.TypeR\x04type\x12\x14\n" + + "\x05label\x18\x02 \x01(\tR\x05label\x12\x16\n" + + "\x06street\x18\x03 \x01(\tR\x06street\x12\x14\n" + + "\x05pobox\x18\x04 \x01(\tR\x05pobox\x12\"\n" + + "\fneighborhood\x18\x05 \x01(\tR\fneighborhood\x12\x12\n" + + "\x04city\x18\x06 \x01(\tR\x04city\x12\x16\n" + + "\x06region\x18\a \x01(\tR\x06region\x12\x1a\n" + + "\bpostcode\x18\b \x01(\tR\bpostcode\x12\x18\n" + + "\acountry\x18\t \x01(\tR\acountry\"&\n" + + "\x04Type\x12\b\n" + + "\x04HOME\x10\x01\x12\b\n" + + "\x04WORK\x10\x02\x12\n" + + "\n" + + "\x06CUSTOM\x10\x03\x1a`\n" + + "\x06Avatar\x128\n" + + "\x06avatar\x18\x01 \x01(\v2 .signalservice.AttachmentPointerR\x06avatar\x12\x1c\n" + + "\tisProfile\x18\x02 \x01(\bR\tisProfile\x1a\xa5\x01\n" + + "\aSticker\x12\x16\n" + + "\x06packId\x18\x01 \x01(\fR\x06packId\x12\x18\n" + + "\apackKey\x18\x02 \x01(\fR\apackKey\x12\x1c\n" + + "\tstickerId\x18\x03 \x01(\rR\tstickerId\x124\n" + + "\x04data\x18\x04 \x01(\v2 .signalservice.AttachmentPointerR\x04data\x12\x14\n" + + "\x05emoji\x18\x05 \x01(\tR\x05emoji\x1a\x9a\x01\n" + + "\bReaction\x12\x14\n" + + "\x05emoji\x18\x01 \x01(\tR\x05emoji\x12\x16\n" + + "\x06remove\x18\x02 \x01(\bR\x06remove\x12(\n" + + "\x0ftargetAuthorAci\x18\x04 \x01(\tR\x0ftargetAuthorAci\x120\n" + + "\x13targetSentTimestamp\x18\x05 \x01(\x04R\x13targetSentTimestampJ\x04\b\x03\x10\x04\x1a:\n" + + "\x06Delete\x120\n" + + "\x13targetSentTimestamp\x18\x01 \x01(\x04R\x13targetSentTimestamp\x1a'\n" + + "\x0fGroupCallUpdate\x12\x14\n" + + "\x05eraId\x18\x01 \x01(\tR\x05eraId\x1aR\n" + + "\fStoryContext\x12\x1c\n" + + "\tauthorAci\x18\x01 \x01(\tR\tauthorAci\x12$\n" + + "\rsentTimestamp\x18\x02 \x01(\x04R\rsentTimestamp\x1aQ\n" + + "\tGiftBadge\x12D\n" + + "\x1dreceiptCredentialPresentation\x18\x01 \x01(\fR\x1dreceiptCredentialPresentation\"Z\n" + + "\x05Flags\x12\x0f\n" + + "\vEND_SESSION\x10\x01\x12\x1b\n" + + "\x17EXPIRATION_TIMER_UPDATE\x10\x02\x12\x16\n" + + "\x12PROFILE_KEY_UPDATE\x10\x04\x12\v\n" + + "\aFORWARD\x10\b\"\xb0\x01\n" + + "\x0fProtocolVersion\x12\v\n" + + "\aINITIAL\x10\x00\x12\x12\n" + + "\x0eMESSAGE_TIMERS\x10\x01\x12\r\n" + + "\tVIEW_ONCE\x10\x02\x12\x13\n" + + "\x0fVIEW_ONCE_VIDEO\x10\x03\x12\r\n" + + "\tREACTIONS\x10\x04\x12\x1c\n" + + "\x18CDN_SELECTOR_ATTACHMENTS\x10\x05\x12\f\n" + + "\bMENTIONS\x10\x06\x12\f\n" + + "\bPAYMENTS\x10\a\x12\v\n" + + "\aCURRENT\x10\a\x1a\x02\x10\x01J\x04\b\x03\x10\x04\"'\n" + + "\vNullMessage\x12\x18\n" + + "\apadding\x18\x01 \x01(\fR\apadding\"\x92\x01\n" + + "\x0eReceiptMessage\x126\n" + + "\x04type\x18\x01 \x01(\x0e2\".signalservice.ReceiptMessage.TypeR\x04type\x12\x1c\n" + + "\ttimestamp\x18\x02 \x03(\x04R\ttimestamp\"*\n" + + "\x04Type\x12\f\n" + + "\bDELIVERY\x10\x00\x12\b\n" + + "\x04READ\x10\x01\x12\n" + + "\n" + + "\x06VIEWED\x10\x02\"\xa8\x01\n" + + "\rTypingMessage\x12\x1c\n" + + "\ttimestamp\x18\x01 \x01(\x04R\ttimestamp\x12;\n" + + "\x06action\x18\x02 \x01(\x0e2#.signalservice.TypingMessage.ActionR\x06action\x12\x18\n" + + "\agroupId\x18\x03 \x01(\fR\agroupId\"\"\n" + + "\x06Action\x12\v\n" + + "\aSTARTED\x10\x00\x12\v\n" + + "\aSTOPPED\x10\x01\"\xe6\x02\n" + + "\fStoryMessage\x12\x1e\n" + + "\n" + + "profileKey\x18\x01 \x01(\fR\n" + + "profileKey\x123\n" + + "\x05group\x18\x02 \x01(\v2\x1d.signalservice.GroupContextV2R\x05group\x12J\n" + + "\x0efileAttachment\x18\x03 \x01(\v2 .signalservice.AttachmentPointerH\x00R\x0efileAttachment\x12G\n" + + "\x0etextAttachment\x18\x04 \x01(\v2\x1d.signalservice.TextAttachmentH\x00R\x0etextAttachment\x12$\n" + + "\rallowsReplies\x18\x05 \x01(\bR\rallowsReplies\x128\n" + + "\n" + + "bodyRanges\x18\x06 \x03(\v2\x18.signalservice.BodyRangeR\n" + + "bodyRangesB\f\n" + + "\n" + + "attachment\"\x9f\x01\n" + + "\aPreview\x12\x10\n" + + "\x03url\x18\x01 \x01(\tR\x03url\x12\x14\n" + + "\x05title\x18\x02 \x01(\tR\x05title\x126\n" + + "\x05image\x18\x03 \x01(\v2 .signalservice.AttachmentPointerR\x05image\x12 \n" + + "\vdescription\x18\x04 \x01(\tR\vdescription\x12\x12\n" + + "\x04date\x18\x05 \x01(\x04R\x04date\"\xd1\x04\n" + + "\x0eTextAttachment\x12\x12\n" + + "\x04text\x18\x01 \x01(\tR\x04text\x12A\n" + + "\ttextStyle\x18\x02 \x01(\x0e2#.signalservice.TextAttachment.StyleR\ttextStyle\x120\n" + + "\x13textForegroundColor\x18\x03 \x01(\rR\x13textForegroundColor\x120\n" + + "\x13textBackgroundColor\x18\x04 \x01(\rR\x13textBackgroundColor\x120\n" + + "\apreview\x18\x05 \x01(\v2\x16.signalservice.PreviewR\apreview\x12D\n" + + "\bgradient\x18\x06 \x01(\v2&.signalservice.TextAttachment.GradientH\x00R\bgradient\x12\x16\n" + + "\x05color\x18\a \x01(\rH\x00R\x05color\x1a\x92\x01\n" + + "\bGradient\x12\x1e\n" + + "\n" + + "startColor\x18\x01 \x01(\rR\n" + + "startColor\x12\x1a\n" + + "\bendColor\x18\x02 \x01(\rR\bendColor\x12\x14\n" + + "\x05angle\x18\x03 \x01(\rR\x05angle\x12\x16\n" + + "\x06colors\x18\x04 \x03(\rR\x06colors\x12\x1c\n" + + "\tpositions\x18\x05 \x03(\x02R\tpositions\"Q\n" + + "\x05Style\x12\v\n" + + "\aDEFAULT\x10\x00\x12\v\n" + + "\aREGULAR\x10\x01\x12\b\n" + + "\x04BOLD\x10\x02\x12\t\n" + + "\x05SERIF\x10\x03\x12\n" + + "\n" + + "\x06SCRIPT\x10\x04\x12\r\n" + + "\tCONDENSED\x10\x05B\f\n" + + "\n" + + "background\"\xe5\x01\n" + + "\bVerified\x12&\n" + + "\x0edestinationAci\x18\x05 \x01(\tR\x0edestinationAci\x12 \n" + + "\videntityKey\x18\x02 \x01(\fR\videntityKey\x123\n" + + "\x05state\x18\x03 \x01(\x0e2\x1d.signalservice.Verified.StateR\x05state\x12 \n" + + "\vnullMessage\x18\x04 \x01(\fR\vnullMessage\"2\n" + + "\x05State\x12\v\n" + + "\aDEFAULT\x10\x00\x12\f\n" + + "\bVERIFIED\x10\x01\x12\x0e\n" + + "\n" + + "UNVERIFIED\x10\x02J\x04\b\x01\x10\x02\"\xf1C\n" + + "\vSyncMessage\x123\n" + + "\x04sent\x18\x01 \x01(\v2\x1f.signalservice.SyncMessage.SentR\x04sent\x12?\n" + + "\bcontacts\x18\x02 \x01(\v2#.signalservice.SyncMessage.ContactsR\bcontacts\x12<\n" + + "\arequest\x18\x04 \x01(\v2\".signalservice.SyncMessage.RequestR\arequest\x123\n" + + "\x04read\x18\x05 \x03(\v2\x1f.signalservice.SyncMessage.ReadR\x04read\x12<\n" + + "\ablocked\x18\x06 \x01(\v2\".signalservice.SyncMessage.BlockedR\ablocked\x123\n" + + "\bverified\x18\a \x01(\v2\x17.signalservice.VerifiedR\bverified\x12N\n" + + "\rconfiguration\x18\t \x01(\v2(.signalservice.SyncMessage.ConfigurationR\rconfiguration\x12\x18\n" + + "\apadding\x18\b \x01(\fR\apadding\x12c\n" + + "\x14stickerPackOperation\x18\n" + + " \x03(\v2/.signalservice.SyncMessage.StickerPackOperationR\x14stickerPackOperation\x12K\n" + + "\fviewOnceOpen\x18\v \x01(\v2'.signalservice.SyncMessage.ViewOnceOpenR\fviewOnceOpen\x12H\n" + + "\vfetchLatest\x18\f \x01(\v2&.signalservice.SyncMessage.FetchLatestR\vfetchLatest\x123\n" + + "\x04keys\x18\r \x01(\v2\x1f.signalservice.SyncMessage.KeysR\x04keys\x12i\n" + + "\x16messageRequestResponse\x18\x0e \x01(\v21.signalservice.SyncMessage.MessageRequestResponseR\x16messageRequestResponse\x12T\n" + + "\x0foutgoingPayment\x18\x0f \x01(\v2*.signalservice.SyncMessage.OutgoingPaymentR\x0foutgoingPayment\x129\n" + + "\x06viewed\x18\x10 \x03(\v2!.signalservice.SyncMessage.ViewedR\x06viewed\x12T\n" + + "\x0fpniChangeNumber\x18\x12 \x01(\v2*.signalservice.SyncMessage.PniChangeNumberR\x0fpniChangeNumber\x12B\n" + + "\tcallEvent\x18\x13 \x01(\v2$.signalservice.SyncMessage.CallEventR\tcallEvent\x12Q\n" + + "\x0ecallLinkUpdate\x18\x14 \x01(\v2).signalservice.SyncMessage.CallLinkUpdateR\x0ecallLinkUpdate\x12K\n" + + "\fcallLogEvent\x18\x15 \x01(\v2'.signalservice.SyncMessage.CallLogEventR\fcallLogEvent\x12H\n" + + "\vdeleteForMe\x18\x16 \x01(\v2&.signalservice.SyncMessage.DeleteForMeR\vdeleteForMe\x12W\n" + + "\x10deviceNameChange\x18\x17 \x01(\v2+.signalservice.SyncMessage.DeviceNameChangeR\x10deviceNameChange\x12r\n" + + "\x19attachmentBackfillRequest\x18\x18 \x01(\v24.signalservice.SyncMessage.AttachmentBackfillRequestR\x19attachmentBackfillRequest\x12u\n" + + "\x1aattachmentBackfillResponse\x18\x19 \x01(\v25.signalservice.SyncMessage.AttachmentBackfillResponseR\x1aattachmentBackfillResponse\x1a\xfc\a\n" + + "\x04Sent\x12(\n" + + "\x0fdestinationE164\x18\x01 \x01(\tR\x0fdestinationE164\x122\n" + + "\x14destinationServiceId\x18\a \x01(\tR\x14destinationServiceId\x12\x1c\n" + + "\ttimestamp\x18\x02 \x01(\x04R\ttimestamp\x124\n" + + "\amessage\x18\x03 \x01(\v2\x1a.signalservice.DataMessageR\amessage\x12:\n" + + "\x18expirationStartTimestamp\x18\x04 \x01(\x04R\x18expirationStartTimestamp\x12j\n" + + "\x12unidentifiedStatus\x18\x05 \x03(\v2:.signalservice.SyncMessage.Sent.UnidentifiedDeliveryStatusR\x12unidentifiedStatus\x123\n" + + "\x11isRecipientUpdate\x18\x06 \x01(\b:\x05falseR\x11isRecipientUpdate\x12?\n" + + "\fstoryMessage\x18\b \x01(\v2\x1b.signalservice.StoryMessageR\fstoryMessage\x12m\n" + + "\x16storyMessageRecipients\x18\t \x03(\v25.signalservice.SyncMessage.Sent.StoryMessageRecipientR\x16storyMessageRecipients\x12<\n" + + "\veditMessage\x18\n" + + " \x01(\v2\x1a.signalservice.EditMessageR\veditMessage\x1a\xbe\x01\n" + + "\x1aUnidentifiedDeliveryStatus\x122\n" + + "\x14destinationServiceId\x18\x03 \x01(\tR\x14destinationServiceId\x12\"\n" + + "\funidentified\x18\x02 \x01(\bR\funidentified\x12<\n" + + "\x19destinationPniIdentityKey\x18\x05 \x01(\fR\x19destinationPniIdentityKeyJ\x04\b\x01\x10\x02J\x04\b\x04\x10\x05\x1a\xaf\x01\n" + + "\x15StoryMessageRecipient\x122\n" + + "\x14destinationServiceId\x18\x01 \x01(\tR\x14destinationServiceId\x120\n" + + "\x13distributionListIds\x18\x02 \x03(\tR\x13distributionListIds\x12*\n" + + "\x10isAllowedToReply\x18\x03 \x01(\bR\x10isAllowedToReplyJ\x04\b\x04\x10\x05J\x04\b\v\x10\f\x1ac\n" + + "\bContacts\x124\n" + + "\x04blob\x18\x01 \x01(\v2 .signalservice.AttachmentPointerR\x04blob\x12!\n" + + "\bcomplete\x18\x02 \x01(\b:\x05falseR\bcomplete\x1aS\n" + + "\aBlocked\x12\x18\n" + + "\anumbers\x18\x01 \x03(\tR\anumbers\x12\x12\n" + + "\x04acis\x18\x03 \x03(\tR\x04acis\x12\x1a\n" + + "\bgroupIds\x18\x02 \x03(\fR\bgroupIds\x1a\x9f\x01\n" + + "\aRequest\x12;\n" + + "\x04type\x18\x01 \x01(\x0e2'.signalservice.SyncMessage.Request.TypeR\x04type\"W\n" + + "\x04Type\x12\v\n" + + "\aUNKNOWN\x10\x00\x12\f\n" + + "\bCONTACTS\x10\x01\x12\v\n" + + "\aBLOCKED\x10\x03\x12\x11\n" + + "\rCONFIGURATION\x10\x04\x12\b\n" + + "\x04KEYS\x10\x05\"\x04\b\x02\x10\x02\"\x04\b\x06\x10\x06\x1aH\n" + + "\x04Read\x12\x1c\n" + + "\tsenderAci\x18\x03 \x01(\tR\tsenderAci\x12\x1c\n" + + "\ttimestamp\x18\x02 \x01(\x04R\ttimestampJ\x04\b\x01\x10\x02\x1aJ\n" + + "\x06Viewed\x12\x1c\n" + + "\tsenderAci\x18\x03 \x01(\tR\tsenderAci\x12\x1c\n" + + "\ttimestamp\x18\x02 \x01(\x04R\ttimestampJ\x04\b\x01\x10\x02\x1a\x83\x02\n" + + "\rConfiguration\x12\"\n" + + "\freadReceipts\x18\x01 \x01(\bR\freadReceipts\x12F\n" + + "\x1eunidentifiedDeliveryIndicators\x18\x02 \x01(\bR\x1eunidentifiedDeliveryIndicators\x12*\n" + + "\x10typingIndicators\x18\x03 \x01(\bR\x10typingIndicators\x120\n" + + "\x13provisioningVersion\x18\x05 \x01(\rR\x13provisioningVersion\x12\"\n" + + "\flinkPreviews\x18\x06 \x01(\bR\flinkPreviewsJ\x04\b\x04\x10\x05\x1a\xb3\x01\n" + + "\x14StickerPackOperation\x12\x16\n" + + "\x06packId\x18\x01 \x01(\fR\x06packId\x12\x18\n" + + "\apackKey\x18\x02 \x01(\fR\apackKey\x12H\n" + + "\x04type\x18\x03 \x01(\x0e24.signalservice.SyncMessage.StickerPackOperation.TypeR\x04type\"\x1f\n" + + "\x04Type\x12\v\n" + + "\aINSTALL\x10\x00\x12\n" + + "\n" + + "\x06REMOVE\x10\x01\x1aP\n" + + "\fViewOnceOpen\x12\x1c\n" + + "\tsenderAci\x18\x03 \x01(\tR\tsenderAci\x12\x1c\n" + + "\ttimestamp\x18\x02 \x01(\x04R\ttimestampJ\x04\b\x01\x10\x02\x1a\xa5\x01\n" + + "\vFetchLatest\x12?\n" + + "\x04type\x18\x01 \x01(\x0e2+.signalservice.SyncMessage.FetchLatest.TypeR\x04type\"U\n" + + "\x04Type\x12\v\n" + + "\aUNKNOWN\x10\x00\x12\x11\n" + + "\rLOCAL_PROFILE\x10\x01\x12\x14\n" + + "\x10STORAGE_MANIFEST\x10\x02\x12\x17\n" + + "\x13SUBSCRIPTION_STATUS\x10\x03\x1a\x84\x01\n" + + "\x04Keys\x12\x16\n" + + "\x06master\x18\x02 \x01(\fR\x06master\x12.\n" + + "\x12accountEntropyPool\x18\x03 \x01(\tR\x12accountEntropyPool\x12.\n" + + "\x12mediaRootBackupKey\x18\x04 \x01(\fR\x12mediaRootBackupKeyJ\x04\b\x01\x10\x02\x1aK\n" + + "\vPniIdentity\x12\x1c\n" + + "\tpublicKey\x18\x01 \x01(\fR\tpublicKey\x12\x1e\n" + + "\n" + + "privateKey\x18\x02 \x01(\fR\n" + + "privateKey\x1a\x8e\x02\n" + + "\x16MessageRequestResponse\x12\x1c\n" + + "\tthreadAci\x18\x02 \x01(\tR\tthreadAci\x12\x18\n" + + "\agroupId\x18\x03 \x01(\fR\agroupId\x12J\n" + + "\x04type\x18\x04 \x01(\x0e26.signalservice.SyncMessage.MessageRequestResponse.TypeR\x04type\"j\n" + + "\x04Type\x12\v\n" + + "\aUNKNOWN\x10\x00\x12\n" + + "\n" + + "\x06ACCEPT\x10\x01\x12\n" + + "\n" + + "\x06DELETE\x10\x02\x12\t\n" + + "\x05BLOCK\x10\x03\x12\x14\n" + + "\x10BLOCK_AND_DELETE\x10\x04\x12\b\n" + + "\x04SPAM\x10\x05\x12\x12\n" + + "\x0eBLOCK_AND_SPAM\x10\x06J\x04\b\x01\x10\x02\x1a\x96\x04\n" + + "\x0fOutgoingPayment\x12.\n" + + "\x12recipientServiceId\x18\x01 \x01(\tR\x12recipientServiceId\x12\x12\n" + + "\x04note\x18\x02 \x01(\tR\x04note\x12W\n" + + "\n" + + "mobileCoin\x18\x03 \x01(\v25.signalservice.SyncMessage.OutgoingPayment.MobileCoinH\x00R\n" + + "mobileCoin\x1a\xcc\x02\n" + + "\n" + + "MobileCoin\x12*\n" + + "\x10recipientAddress\x18\x01 \x01(\fR\x10recipientAddress\x12$\n" + + "\ramountPicoMob\x18\x02 \x01(\x04R\ramountPicoMob\x12\x1e\n" + + "\n" + + "feePicoMob\x18\x03 \x01(\x04R\n" + + "feePicoMob\x12\x18\n" + + "\areceipt\x18\x04 \x01(\fR\areceipt\x122\n" + + "\x14ledgerBlockTimestamp\x18\x05 \x01(\x04R\x14ledgerBlockTimestamp\x12*\n" + + "\x10ledgerBlockIndex\x18\x06 \x01(\x04R\x10ledgerBlockIndex\x12&\n" + + "\x0espentKeyImages\x18\a \x03(\fR\x0espentKeyImages\x12*\n" + + "\x10outputPublicKeys\x18\b \x03(\fR\x10outputPublicKeysB\x17\n" + + "\x15attachment_identifier\x1a\xd7\x01\n" + + "\x0fPniChangeNumber\x12(\n" + + "\x0fidentityKeyPair\x18\x01 \x01(\fR\x0fidentityKeyPair\x12\"\n" + + "\fsignedPreKey\x18\x02 \x01(\fR\fsignedPreKey\x124\n" + + "\x15lastResortKyberPreKey\x18\x05 \x01(\fR\x15lastResortKyberPreKey\x12&\n" + + "\x0eregistrationId\x18\x03 \x01(\rR\x0eregistrationId\x12\x18\n" + + "\anewE164\x18\x04 \x01(\tR\anewE164\x1a\xa9\x04\n" + + "\tCallEvent\x12&\n" + + "\x0econversationId\x18\x01 \x01(\fR\x0econversationId\x12\x16\n" + + "\x06callId\x18\x02 \x01(\x04R\x06callId\x12\x1c\n" + + "\ttimestamp\x18\x03 \x01(\x04R\ttimestamp\x12=\n" + + "\x04type\x18\x04 \x01(\x0e2).signalservice.SyncMessage.CallEvent.TypeR\x04type\x12L\n" + + "\tdirection\x18\x05 \x01(\x0e2..signalservice.SyncMessage.CallEvent.DirectionR\tdirection\x12@\n" + + "\x05event\x18\x06 \x01(\x0e2*.signalservice.SyncMessage.CallEvent.EventR\x05event\"Y\n" + + "\x04Type\x12\x10\n" + + "\fUNKNOWN_TYPE\x10\x00\x12\x0e\n" + + "\n" + + "AUDIO_CALL\x10\x01\x12\x0e\n" + + "\n" + + "VIDEO_CALL\x10\x02\x12\x0e\n" + + "\n" + + "GROUP_CALL\x10\x03\x12\x0f\n" + + "\vAD_HOC_CALL\x10\x04\">\n" + + "\tDirection\x12\x15\n" + + "\x11UNKNOWN_DIRECTION\x10\x00\x12\f\n" + + "\bINCOMING\x10\x01\x12\f\n" + + "\bOUTGOING\x10\x02\"T\n" + + "\x05Event\x12\x11\n" + + "\rUNKNOWN_EVENT\x10\x00\x12\f\n" + + "\bACCEPTED\x10\x01\x12\x10\n" + + "\fNOT_ACCEPTED\x10\x02\x12\n" + + "\n" + + "\x06DELETE\x10\x03\x12\f\n" + + "\bOBSERVED\x10\x04\x1a\xac\x01\n" + + "\x0eCallLinkUpdate\x12\x18\n" + + "\arootKey\x18\x01 \x01(\fR\arootKey\x12\"\n" + + "\fadminPasskey\x18\x02 \x01(\fR\fadminPasskey\x12B\n" + + "\x04type\x18\x03 \x01(\x0e2..signalservice.SyncMessage.CallLinkUpdate.TypeR\x04type\"\x18\n" + + "\x04Type\x12\n" + + "\n" + + "\x06UPDATE\x10\x00\"\x04\b\x01\x10\x01\x1a\x94\x02\n" + + "\fCallLogEvent\x12@\n" + + "\x04type\x18\x01 \x01(\x0e2,.signalservice.SyncMessage.CallLogEvent.TypeR\x04type\x12\x1c\n" + + "\ttimestamp\x18\x02 \x01(\x04R\ttimestamp\x12&\n" + + "\x0econversationId\x18\x03 \x01(\fR\x0econversationId\x12\x16\n" + + "\x06callId\x18\x04 \x01(\x04R\x06callId\"d\n" + + "\x04Type\x12\t\n" + + "\x05CLEAR\x10\x00\x12\x12\n" + + "\x0eMARKED_AS_READ\x10\x01\x12\"\n" + + "\x1eMARKED_AS_READ_IN_CONVERSATION\x10\x02\x12\x19\n" + + "\x15CLEAR_IN_CONVERSATION\x10\x03\x1a\xb9\n" + + "\n" + + "\vDeleteForMe\x12]\n" + + "\x0emessageDeletes\x18\x01 \x03(\v25.signalservice.SyncMessage.DeleteForMe.MessageDeletesR\x0emessageDeletes\x12k\n" + + "\x13conversationDeletes\x18\x02 \x03(\v29.signalservice.SyncMessage.DeleteForMe.ConversationDeleteR\x13conversationDeletes\x12\x86\x01\n" + + "\x1clocalOnlyConversationDeletes\x18\x03 \x03(\v2B.signalservice.SyncMessage.DeleteForMe.LocalOnlyConversationDeleteR\x1clocalOnlyConversationDeletes\x12e\n" + + "\x11attachmentDeletes\x18\x04 \x03(\v27.signalservice.SyncMessage.DeleteForMe.AttachmentDeleteR\x11attachmentDeletes\x1a\x9a\x01\n" + + "\x0eMessageDeletes\x12I\n" + + "\fconversation\x18\x01 \x01(\v2%.signalservice.ConversationIdentifierR\fconversation\x12=\n" + + "\bmessages\x18\x02 \x03(\v2!.signalservice.AddressableMessageR\bmessages\x1a\xa4\x02\n" + + "\x10AttachmentDelete\x12I\n" + + "\fconversation\x18\x01 \x01(\v2%.signalservice.ConversationIdentifierR\fconversation\x12G\n" + + "\rtargetMessage\x18\x02 \x01(\v2!.signalservice.AddressableMessageR\rtargetMessage\x12\x1e\n" + + "\n" + + "clientUuid\x18\x03 \x01(\fR\n" + + "clientUuid\x12&\n" + + "\x0efallbackDigest\x18\x04 \x01(\fR\x0efallbackDigest\x124\n" + + "\x15fallbackPlaintextHash\x18\x05 \x01(\fR\x15fallbackPlaintextHash\x1a\xbf\x02\n" + + "\x12ConversationDelete\x12I\n" + + "\fconversation\x18\x01 \x01(\v2%.signalservice.ConversationIdentifierR\fconversation\x12Q\n" + + "\x12mostRecentMessages\x18\x02 \x03(\v2!.signalservice.AddressableMessageR\x12mostRecentMessages\x12\"\n" + + "\fisFullDelete\x18\x03 \x01(\bR\fisFullDelete\x12g\n" + + "\x1dmostRecentNonExpiringMessages\x18\x04 \x03(\v2!.signalservice.AddressableMessageR\x1dmostRecentNonExpiringMessages\x1ah\n" + + "\x1bLocalOnlyConversationDelete\x12I\n" + + "\fconversation\x18\x01 \x01(\v2%.signalservice.ConversationIdentifierR\fconversation\x1a4\n" + + "\x10DeviceNameChange\x12\x1a\n" + + "\bdeviceId\x18\x02 \x01(\rR\bdeviceIdJ\x04\b\x01\x10\x02\x1a\xbb\x01\n" + + "\x19AttachmentBackfillRequest\x12G\n" + + "\rtargetMessage\x18\x01 \x01(\v2!.signalservice.AddressableMessageR\rtargetMessage\x12U\n" + + "\x12targetConversation\x18\x02 \x01(\v2%.signalservice.ConversationIdentifierR\x12targetConversation\x1a\xf9\x06\n" + + "\x1aAttachmentBackfillResponse\x12G\n" + + "\rtargetMessage\x18\x01 \x01(\v2!.signalservice.AddressableMessageR\rtargetMessage\x12U\n" + + "\x12targetConversation\x18\x02 \x01(\v2%.signalservice.ConversationIdentifierR\x12targetConversation\x12l\n" + + "\vattachments\x18\x03 \x01(\v2H.signalservice.SyncMessage.AttachmentBackfillResponse.AttachmentDataListH\x00R\vattachments\x12S\n" + + "\x05error\x18\x04 \x01(\x0e2;.signalservice.SyncMessage.AttachmentBackfillResponse.ErrorH\x00R\x05error\x1a\xee\x01\n" + + "\x0eAttachmentData\x12B\n" + + "\n" + + "attachment\x18\x01 \x01(\v2 .signalservice.AttachmentPointerH\x00R\n" + + "attachment\x12e\n" + + "\x06status\x18\x02 \x01(\x0e2K.signalservice.SyncMessage.AttachmentBackfillResponse.AttachmentData.StatusH\x00R\x06status\")\n" + + "\x06Status\x12\v\n" + + "\aPENDING\x10\x00\x12\x12\n" + + "\x0eTERMINAL_ERROR\x10\x01B\x06\n" + + "\x04data\x1a\xde\x01\n" + + "\x12AttachmentDataList\x12f\n" + + "\vattachments\x18\x01 \x03(\v2D.signalservice.SyncMessage.AttachmentBackfillResponse.AttachmentDataR\vattachments\x12`\n" + + "\blongText\x18\x02 \x01(\v2D.signalservice.SyncMessage.AttachmentBackfillResponse.AttachmentDataR\blongText\"\x1e\n" + + "\x05Error\x12\x15\n" + + "\x11MESSAGE_NOT_FOUND\x10\x00B\x06\n" + + "\x04dataJ\x04\b\x03\x10\x04J\x04\b\x11\x10\x12\"\xe7\x04\n" + + "\x11AttachmentPointer\x12\x16\n" + + "\x05cdnId\x18\x01 \x01(\x06H\x00R\x05cdnId\x12\x18\n" + + "\x06cdnKey\x18\x0f \x01(\tH\x00R\x06cdnKey\x12\x1e\n" + + "\n" + + "clientUuid\x18\x14 \x01(\fR\n" + + "clientUuid\x12 \n" + + "\vcontentType\x18\x02 \x01(\tR\vcontentType\x12\x10\n" + + "\x03key\x18\x03 \x01(\fR\x03key\x12\x12\n" + + "\x04size\x18\x04 \x01(\rR\x04size\x12\x1c\n" + + "\tthumbnail\x18\x05 \x01(\fR\tthumbnail\x12\x16\n" + + "\x06digest\x18\x06 \x01(\fR\x06digest\x12&\n" + + "\x0eincrementalMac\x18\x13 \x01(\fR\x0eincrementalMac\x12\x1c\n" + + "\tchunkSize\x18\x11 \x01(\rR\tchunkSize\x12\x1a\n" + + "\bfileName\x18\a \x01(\tR\bfileName\x12\x14\n" + + "\x05flags\x18\b \x01(\rR\x05flags\x12\x14\n" + + "\x05width\x18\t \x01(\rR\x05width\x12\x16\n" + + "\x06height\x18\n" + + " \x01(\rR\x06height\x12\x18\n" + + "\acaption\x18\v \x01(\tR\acaption\x12\x1a\n" + + "\bblurHash\x18\f \x01(\tR\bblurHash\x12(\n" + + "\x0fuploadTimestamp\x18\r \x01(\x04R\x0fuploadTimestamp\x12\x1c\n" + + "\tcdnNumber\x18\x0e \x01(\rR\tcdnNumber\"9\n" + + "\x05Flags\x12\x11\n" + + "\rVOICE_MESSAGE\x10\x01\x12\x0e\n" + + "\n" + + "BORDERLESS\x10\x02\x12\a\n" + + "\x03GIF\x10\b\"\x04\b\x04\x10\x04B\x17\n" + + "\x15attachment_identifierJ\x04\b\x10\x10\x11J\x04\b\x12\x10\x13\"l\n" + + "\x0eGroupContextV2\x12\x1c\n" + + "\tmasterKey\x18\x01 \x01(\fR\tmasterKey\x12\x1a\n" + + "\brevision\x18\x02 \x01(\rR\brevision\x12 \n" + + "\vgroupChange\x18\x03 \x01(\fR\vgroupChange\"\xe6\x02\n" + + "\x0eContactDetails\x12\x16\n" + + "\x06number\x18\x01 \x01(\tR\x06number\x12\x10\n" + + "\x03aci\x18\t \x01(\tR\x03aci\x12\x12\n" + + "\x04name\x18\x02 \x01(\tR\x04name\x12<\n" + + "\x06avatar\x18\x03 \x01(\v2$.signalservice.ContactDetails.AvatarR\x06avatar\x12 \n" + + "\vexpireTimer\x18\b \x01(\rR\vexpireTimer\x12.\n" + + "\x12expireTimerVersion\x18\f \x01(\rR\x12expireTimerVersion\x12$\n" + + "\rinboxPosition\x18\n" + + " \x01(\rR\rinboxPosition\x1aB\n" + + "\x06Avatar\x12 \n" + + "\vcontentType\x18\x01 \x01(\tR\vcontentType\x12\x16\n" + + "\x06length\x18\x02 \x01(\rR\x06lengthJ\x04\b\x04\x10\x05J\x04\b\x05\x10\x06J\x04\b\x06\x10\aJ\x04\b\a\x10\bJ\x04\b\v\x10\f\"\xb9\x01\n" + + "\x0ePaymentAddress\x12J\n" + + "\n" + + "mobileCoin\x18\x01 \x01(\v2(.signalservice.PaymentAddress.MobileCoinH\x00R\n" + + "mobileCoin\x1aP\n" + + "\n" + + "MobileCoin\x12$\n" + + "\rpublicAddress\x18\x01 \x01(\fR\rpublicAddress\x12\x1c\n" + + "\tsignature\x18\x02 \x01(\fR\tsignatureB\t\n" + + "\aAddress\"r\n" + + "\x16DecryptionErrorMessage\x12\x1e\n" + + "\n" + + "ratchetKey\x18\x01 \x01(\fR\n" + + "ratchetKey\x12\x1c\n" + + "\ttimestamp\x18\x02 \x01(\x04R\ttimestamp\x12\x1a\n" + + "\bdeviceId\x18\x03 \x01(\rR\bdeviceId\"E\n" + + "\x13PniSignatureMessage\x12\x10\n" + + "\x03pni\x18\x01 \x01(\fR\x03pni\x12\x1c\n" + + "\tsignature\x18\x02 \x01(\fR\tsignature\"}\n" + + "\vEditMessage\x120\n" + + "\x13targetSentTimestamp\x18\x01 \x01(\x04R\x13targetSentTimestamp\x12<\n" + + "\vdataMessage\x18\x02 \x01(\v2\x1a.signalservice.DataMessageR\vdataMessage\"\xfe\x01\n" + + "\tBodyRange\x12\x14\n" + + "\x05start\x18\x01 \x01(\rR\x05start\x12\x16\n" + + "\x06length\x18\x02 \x01(\rR\x06length\x12 \n" + + "\n" + + "mentionAci\x18\x03 \x01(\tH\x00R\n" + + "mentionAci\x126\n" + + "\x05style\x18\x04 \x01(\x0e2\x1e.signalservice.BodyRange.StyleH\x00R\x05style\"V\n" + + "\x05Style\x12\b\n" + + "\x04NONE\x10\x00\x12\b\n" + + "\x04BOLD\x10\x01\x12\n" + + "\n" + + "\x06ITALIC\x10\x02\x12\v\n" + + "\aSPOILER\x10\x03\x12\x11\n" + + "\rSTRIKETHROUGH\x10\x04\x12\r\n" + + "\tMONOSPACE\x10\x05B\x11\n" + + "\x0fassociatedValue\"\x92\x01\n" + + "\x12AddressableMessage\x12*\n" + + "\x0fauthorServiceId\x18\x01 \x01(\tH\x00R\x0fauthorServiceId\x12 \n" + + "\n" + + "authorE164\x18\x02 \x01(\tH\x00R\n" + + "authorE164\x12$\n" + + "\rsentTimestamp\x18\x03 \x01(\x04R\rsentTimestampB\b\n" + + "\x06author\"\x9c\x01\n" + + "\x16ConversationIdentifier\x12*\n" + + "\x0fthreadServiceId\x18\x01 \x01(\tH\x00R\x0fthreadServiceId\x12&\n" + + "\rthreadGroupId\x18\x02 \x01(\fH\x00R\rthreadGroupId\x12 \n" + + "\n" + + "threadE164\x18\x03 \x01(\tH\x00R\n" + + "threadE164B\f\n" + + "\n" + + "identifierBE\n" + + ".org.whispersystems.signalservice.internal.pushB\x13SignalServiceProtos" var ( file_SignalService_proto_rawDescOnce sync.Once - file_SignalService_proto_rawDescData = file_SignalService_proto_rawDesc + file_SignalService_proto_rawDescData []byte ) func file_SignalService_proto_rawDescGZIP() []byte { file_SignalService_proto_rawDescOnce.Do(func() { - file_SignalService_proto_rawDescData = protoimpl.X.CompressGZIP(file_SignalService_proto_rawDescData) + file_SignalService_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_SignalService_proto_rawDesc), len(file_SignalService_proto_rawDesc))) }) return file_SignalService_proto_rawDescData } @@ -8079,7 +8730,7 @@ func file_SignalService_proto_init() { out := protoimpl.TypeBuilder{ File: protoimpl.DescBuilder{ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: file_SignalService_proto_rawDesc, + RawDescriptor: unsafe.Slice(unsafe.StringData(file_SignalService_proto_rawDesc), len(file_SignalService_proto_rawDesc)), NumEnums: 28, NumMessages: 82, NumExtensions: 0, @@ -8091,7 +8742,6 @@ func file_SignalService_proto_init() { MessageInfos: file_SignalService_proto_msgTypes, }.Build() File_SignalService_proto = out.File - file_SignalService_proto_rawDesc = nil file_SignalService_proto_goTypes = nil file_SignalService_proto_depIdxs = nil } diff --git a/pkg/signalmeow/protobuf/SignalService.pb.raw b/pkg/signalmeow/protobuf/SignalService.pb.raw deleted file mode 100644 index befb7053450b2a5831204736297be0cfa084b7e8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 19700 zcmd5^-*0QlUEd^5;*1kt-*b2Gdfn}IYs$7=AhhnXZMQApU&-~}#P*JzY%c<(zV=CS zdL7$6w(o8#@dV-#p@Mj*kaz*{LkN(NkSZkl5AXm_Ji!AJAW?(_F9-=CKA)L6=gc{F ze6!U>;w3pVXTCFYX1??N@%eto;$FwQ81;r7*MI8u-TjF_o{gQosj8gn%Hr>BigbPS z)E$l|uJbvOnq5!a{MzelpUIY9-H$ch51Q?F(MGD4&S%7(>3HtCeGoq40)%o~rQF85TIOW!%Kik+Ev1*+cFB)^Go(H4e~o`1gl1UnR?$1dl#zrJDM!4<_z4)rF-T2 zyY&ta8$<9o2Ii&d0>dow_`&%d=YjsDb~F&Sbq> zZ?wC)P3L8C@1)tN)tlYML8D$f>(raIy3B1kFNwSQnSCACJDu`jJ-5y3_EEXf1i#jz7Se7`>gn~UA5gDj;TEYoQ447|Cw0F!90t@IOR1|-3u!ke z^=KYZr<1?j?Cq7-q8p#BaQxSVO=icZd=w(awl05KW zo2ZS9lc0}Rr|xLr`VZafnm3*K-s3q>ZO|pp_pV&o#(7)ZAGm%0dP2gw?~na}S|8RM z-a0=6S;A8hwC3r}ls=YNgpSn&g2pO2U2$(R@|1X-&3!lMhX*`UDkl2D$xODC%gDL6 z?!XJThJtXBuj)|?X*VzaM_Obow!z|Tj?d3sUrFOk>Gi~{tfu=dwv)QK^JTHs8%;j| zp=Rt)t{^O{hSCsVPj?`iPn1B)Z@j*N>3?bkbt7miBQoa;BK3Gay;h<)Q~JaT@(P+s z)tGa>?2Rtw6Qve1rB!o&pc+a;0G)Nu(ivL0Knsy2_T;ix9Be%4eQWOK^?t7!tfd-C zLs0m`HLTDY@t(M2s>;=Bz1^+XpbewSTD^MIXrgl6xg#>BW#y#v2nw~_#Vfl~Jv&vgt&D>HwK}BP(q~tEtL|t2 zgjPiVS_YKG&q1N-8_MV8u)^VakQ1I4XxN+G7s}moIH1 z=Zj+d!XM8krzK_NENZMnzE$e|!`W#`2CZoToez5#(>%|{p40{Bbx7I|C!X)p3iFk$ z*@HBVs+@h{SjAJ=#QBnV*>}G+$FdLF^d&-N7Zr$2UQ-RFA;4D& zvbls>ai@7lEo441dL?Ket+uct?kJ|FDmF^#pGty^M;^@H=!m`3I(M3at#6B%( zD1GK?7<5%){WB=g1qxocdD(PpSVS* z<&X$nT3r;r1LZ$OC5YaojsS~e1 zMvWRGh5gjUN;;TH;rnZ1*Iowa=a)?Fom))J?&QV^QWIdWT&16&3HZD?Y2%EjNyE1` z#mb(@bbT11`b59GmHxqY?q9bH9|{pIxpNQ$8%npBctmU|{$ermZ)N?xlX|BM4G4u; zu67%z(0ownl`WBK%-k!?v>hc77Tt&E@>+@u=qw)v7Hj$!G}z z3nC&3H(7|S&~yWaao9NMo>j^|gXo-nX@& zC1>r(SY6@Ifi`gsX)j%PPu&p=rDWbMHfQ!c2+v z)A>2;X%6m4Q(}Kt-e6#ukDdwoi)zT4BbYthSLI>u$gr%(FOAL$n`ERACLXZ@pxdQeXNcGzwgboV*r8AXO7~#7c^P* zNiZcc+XUa+9}l!Y0A>ry8jpru0YsMw#SV>mRV==-zz4zJuUmV+QTPT70(~C86dq|U z-=6J~1t%GY)0@JCr?^%M9*A{VQTW|8v2ARBbr5^~C-A8`2HgFLDk*~nPxO_z^3eT! zfg%sSaWO(iJgRWsGS0BZJ)b>e?Ji^A+^g|714XP0h3~G3bl?hbYjqQIYE?mR(bf2A z@RisimI&@c6kfQqa;W3AKuJ~;UeYZ)Fvvs9U-3vvE_(%e0t}?^j@Z(E#!WqNp38eE zd|KQ|cnRwB{GQnc$PUCB8iRrqySDYtwU3Mzy%14_^C__h#Mb%xIX8^Wn%H<1OuD_1uv{+!r6pbt+71#tod3p7l!#u!8W>+OatcLAH6 zbsNV(xlY{u~PA-L|%~xwpO#P@{?Y4l$ zb-U&2gJXm-ItYjCiZmZp+bx#bAf2 zahV8)6@PzC?8U+ZE1EU_(^SCo}nfhOJiSYP`z^v5F@9_l~WM)}!Bpg`D| zBFw@q-IlA|>6Q`Bs$tHm062`cfAOEz%_%V`e*)^^RO3+37sRIOUrqIyNR@62TP;gz z8X2*-wQ}JXCMcalk)=mr^`*sSGRo79HDX6`GM;z<4dV}{(wz)Fpc}M|(lTC|06;#1 zk5So$;~nCD#ovbBFo=_r6B~1XXiO+RQi9FAnb9|pV5-0%hj+ygo(`iuTOsJ?^hSXC z_kBdd$W&T*+f~%q1H@I0q*l+xze$N~e9=NrPD@Me$(6y%SlZ6)+DtdQ07u1p*;h>w zcMhnO&`0553=09s=4enI56AQ*R8)fP60ZV^3e>1g!7oD`gA|EZpa^h1^^v!L|7s$A z;r9j}#J6z+k{Em9yADlj@K#6(xx5MF4_`yGXAiG*k*G;JAmAZ`AL7sScXM_3q*X&B z3DHCSmLdUgeNZN=0F1-h>*dk~>T)$Kq2LX)Hzf)lm{%V8K>JDSGO8%PCpOjQP$tys z2j!C^!UHJC`r*k@SwgNs!c|&Fg!p&RxGoz9+T89`C4=25sseP*8wc?!b9NWUXLS1RW%5$-bUar?czGgtDs;MnkNh{L3}SE(Cak5y5$ABz0SM zn+z`R#sbLjHn1F^h%W~uKH~c-l8^O(UwzUH%j+;`)*$i!y(%(ROq_8(ngQyFFUI+- zmix4vq-so@x34{I#u1j`yf&fnq^2??A~;G2+MUkSnO_9VZF;F&5|>gWoHJl%TKM#) zld;J-X>TA^V-ERvI0j}uFlQ#IZ*97YZYcv244HmvxWmLYUrzWt!B)z!q0UcsDnY9Nr9zu*v zF71q%G=mhx{xQPHgdUP`jNN$$|_R&xW+=v1o4jwkM4>8z80yWHsnl1E21GNmNoXV1hKAPGWwLx&76jOVip z;LaBY1~;*@WO%_IqZOx+$u1Zv;bwrFbLtc%qu+LC+y-|b4FM;FtcfZk^=?x`V~$$8 zRTDz?giRrnT`%MST)&E zL?9C#kZDzy;|o2r<$;ui4o!0zBPP@8@D#NEaS%#L>R!7q?K`U0$X!waD^+mb7dai~ zCUT}1Rz)>4r5{Vkm3Vi|xr<2TLMM(dUWsfuni?=?hlW-2d9}^SxQ9JLWUMA=<;~qX zb5U3}ra4frs6mtP(6a{B#BxQ)h5z0bDJmtx0G7J0fBx;ajK!L)zA-aVBR{vuOw_)% z8b>-swg|sf}s*jY` zbtUfGX;x{8O_bcmoASL1f4L?KH?QiA97lU_ zM=s|$Aer_KD-$a%V|AGHD;Cc~IyWpsROj^E+(6rc_{#*JKUotmEnTo1=dPWs<#T5q zmz73%gy+UUXPfLGk8AN2vS4%Gv`qij9dyTZaj(@;O3Q_MJ!AaMm1E58)u<4XdRdy(SAkDH- zMI0+iN=D6Ng?E8ADf8nw^z};!LBtGXV*d053{=LAAutlFLxB1<`!oeouQ3`he_`xv z7bY#A(TaSEoq`o-QF2MZr^$Mv07yf6>M>gh6z~mH-V)CxP=F<`_$5P_JqCE0Djx-3 zV%M4T`e$q6#bs7IJ!=i?t7W(i$d7GS%%`2xRd&I$0c}qFM8t`WCJ;Q8+X$pl){k4K zh=vu~V%PQto&z@^zLBw<0;nDPB&{-|EGqjOPNHv!P7{s{j!*gM%wX6!Qb^fE08b(# z{_MEiY#cCEVV$Y;os)_N8;F8q5xOTGM6!Pwu~d2<+@Gu76ghQDpkse@i8*e)zKS2! z5m6dXuG`~r5M5mIhV8GApxl$=u>zCk6M_#k8+PTAH|8Kd6d6lPaQ!Fq$3w4AS{|ES zz%44Xxa6Uv$RH&$E@nZ+%@{C{SG|4w zj%?}e6;|-_f$g3A=CYjxH|pF_Y$2Y3jn`Ft0%(zvkdTkqS@n2^tV>>(U;`y0JMHo@ z;sXdmMDJDImRa53Oo=-QpN;$E2c}bW2}Uc=C2y!klBqiI6Rd0_V_~i`e-d-JF)yfq zaIT%X1mPCW)g&Dlu2`s7aI{K`YMWdqE&BI*b|qQp+;xK{lrSme281=_1dPZ#5QcSw zBF&DWi&QmVY2IY8Zs|J;XNv|B+Wk<8(3D)LC%QKUATa~yHwao!f#__2!4tLY6OQ|2 zK5GZ(Vv592wp^&MyewXdT%fbiI`<2I%fMFLcc#B$!G`Ugr!NQK)=#3ET49QNUQE=q zPGYPMw$DpLh!q?_+$4He0o* zAEbb%23|b-1J(t1VjA?Pg-W7U!M`BFc$#ar=$$u|r4hxQG`Cn@*4JXf;aPBi^7Jiv z;2epa0n%M{pp5TjN7M#g=Pl4_Z}Skt!lXE1Wd1YX$w+ z8o2ev$R-AXh1h6TTgQ#&A!H#+t&{Fyi>38qS8S@O(pC&;>!*x*Dmp8>9+Pjjx@TdH z%5N}2b3^r7Q5Vl@2&4ZIf}dQA2&hr#9||l|Kij@8lIeScD{s{9O{Y)7%!F7S&?eh* zdDdn|!&+QX%$r?+GB82u7hwLb!C3i?b+N0aYhWO3xoung_%nFt$dFlsDYa$I%QTU#~EdvY0`UR0S*oUswj!~wxNJCz@Xb2&@Qb$`JOc5|7cch6teb3n{gKbLYp=J`|Cz-*P}YJr6y^XF$_G$t z)jMAkX~P-X`(4cBH%3P9@i4fyCqt6L@2rbl@*|$-^bT=xQsoVq6;Qh9R&$Kg(a7l| zA`fVcw~zIiwQ8sp0h0|GXRLX!Gy+>EQA-^jv}+H0ym<5B>_KmOsUpI=a{0@`_t%B9 z$g0nCq27b5fgCsqLv0jXi2MjUx`de0-J2fZW~}B-wP9>wff#8QMfek#G^aTGxS9$*a@K8_Jfx^23dzZeKH(L-keoH%R&T(6F4W zWFNyZ&&=0Bj}{el6jE_j*nw=DEj|3%hm5#a6fc8q3sx&1u7KjzvSH#@E49yb2;`dwWg-Ui$#C2oL}&=p9a1t`t-fwBGGTq*(B#(z z6~!+HDZKFRPFsyC5KQyi9?I3Mv?PB1;|Nu71h&Nn?&YXo_ekYZHzFM1v|R2k{_@8? zh9Y|yy8+DkXqb}>WpKu@g5S)$tqL4B8Zao6n^eTaM8`GH*i}pk%|c`G#!t zS~2eBBqQ52NKA{^@9Px*XHD#cH>N54p!0p5DG1@G3KVn8_z8zsP!1#f6-EweLqv5< z8J?=lTp}6S(rXE291g6La;ctF^Wv#6nV^VVHd{@CW_VJWp9@I=XW+tj z^!1DcsE;`&UvM3CTZN!1S;KXR>K3nakeQO#Ie33q(-ePeP29K5^vDM1#B`)($;1*b zpe^@wm6F#6j@`xF;??{B-A;V~=eENSi0YU}>xDQ#r7reyyKw)5OAi>kKfOl0>uQ?V YTlK>d_(ik*$$WZQiT}Krx&$))UvGw&JOBUy diff --git a/pkg/signalmeow/protobuf/StickerResources.pb.go b/pkg/signalmeow/protobuf/StickerResources.pb.go index c194ebc..b1969bc 100644 --- a/pkg/signalmeow/protobuf/StickerResources.pb.go +++ b/pkg/signalmeow/protobuf/StickerResources.pb.go @@ -5,7 +5,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.36.1 +// protoc-gen-go v1.36.6 // protoc v3.21.12 // source: StickerResources.proto @@ -16,10 +16,9 @@ import ( protoimpl "google.golang.org/protobuf/runtime/protoimpl" reflect "reflect" sync "sync" + unsafe "unsafe" ) -import _ "embed" - const ( // Verify that this generated code is sufficiently up-to-date. _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) @@ -157,17 +156,28 @@ func (x *Pack_Sticker) GetContentType() string { var File_StickerResources_proto protoreflect.FileDescriptor -//go:embed StickerResources.pb.raw -var file_StickerResources_proto_rawDesc []byte +const file_StickerResources_proto_rawDesc = "" + + "\n" + + "\x16StickerResources.proto\x12\rsignalservice\"\xf3\x01\n" + + "\x04Pack\x12\x14\n" + + "\x05title\x18\x01 \x01(\tR\x05title\x12\x16\n" + + "\x06author\x18\x02 \x01(\tR\x06author\x121\n" + + "\x05cover\x18\x03 \x01(\v2\x1b.signalservice.Pack.StickerR\x05cover\x127\n" + + "\bstickers\x18\x04 \x03(\v2\x1b.signalservice.Pack.StickerR\bstickers\x1aQ\n" + + "\aSticker\x12\x0e\n" + + "\x02id\x18\x01 \x01(\rR\x02id\x12\x14\n" + + "\x05emoji\x18\x02 \x01(\tR\x05emoji\x12 \n" + + "\vcontentType\x18\x03 \x01(\tR\vcontentTypeBB\n" + + "1org.whispersystems.signalservice.internal.stickerB\rStickerProtos" var ( file_StickerResources_proto_rawDescOnce sync.Once - file_StickerResources_proto_rawDescData = file_StickerResources_proto_rawDesc + file_StickerResources_proto_rawDescData []byte ) func file_StickerResources_proto_rawDescGZIP() []byte { file_StickerResources_proto_rawDescOnce.Do(func() { - file_StickerResources_proto_rawDescData = protoimpl.X.CompressGZIP(file_StickerResources_proto_rawDescData) + file_StickerResources_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_StickerResources_proto_rawDesc), len(file_StickerResources_proto_rawDesc))) }) return file_StickerResources_proto_rawDescData } @@ -196,7 +206,7 @@ func file_StickerResources_proto_init() { out := protoimpl.TypeBuilder{ File: protoimpl.DescBuilder{ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: file_StickerResources_proto_rawDesc, + RawDescriptor: unsafe.Slice(unsafe.StringData(file_StickerResources_proto_rawDesc), len(file_StickerResources_proto_rawDesc)), NumEnums: 0, NumMessages: 2, NumExtensions: 0, @@ -207,7 +217,6 @@ func file_StickerResources_proto_init() { MessageInfos: file_StickerResources_proto_msgTypes, }.Build() File_StickerResources_proto = out.File - file_StickerResources_proto_rawDesc = nil file_StickerResources_proto_goTypes = nil file_StickerResources_proto_depIdxs = nil } diff --git a/pkg/signalmeow/protobuf/StickerResources.pb.raw b/pkg/signalmeow/protobuf/StickerResources.pb.raw deleted file mode 100644 index 03768ca..0000000 --- a/pkg/signalmeow/protobuf/StickerResources.pb.raw +++ /dev/null @@ -1,12 +0,0 @@ - -StickerResources.proto signalservice"ó -Pack -title ( Rtitle -author ( Rauthor1 -cover ( 2.signalservice.Pack.StickerRcover7 -stickers ( 2.signalservice.Pack.StickerRstickersQ -Sticker -id ( Rid -emoji ( Remoji - contentType ( R contentTypeBB -1org.whispersystems.signalservice.internal.stickerB StickerProtos \ No newline at end of file diff --git a/pkg/signalmeow/protobuf/StorageService.pb.go b/pkg/signalmeow/protobuf/StorageService.pb.go index 3aad8ab..3826c83 100644 --- a/pkg/signalmeow/protobuf/StorageService.pb.go +++ b/pkg/signalmeow/protobuf/StorageService.pb.go @@ -5,7 +5,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.36.1 +// protoc-gen-go v1.36.6 // protoc v3.21.12 // source: StorageService.proto @@ -16,10 +16,9 @@ import ( protoimpl "google.golang.org/protobuf/runtime/protoimpl" reflect "reflect" sync "sync" + unsafe "unsafe" ) -import _ "embed" - const ( // Verify that this generated code is sufficiently up-to-date. _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) @@ -2613,17 +2612,279 @@ func (x *ChatFolderRecord_Recipient_Contact) GetE164() string { var File_StorageService_proto protoreflect.FileDescriptor -//go:embed StorageService.pb.raw -var file_StorageService_proto_rawDesc []byte +const file_StorageService_proto_rawDesc = "" + + "\n" + + "\x14StorageService.proto\x12\rsignalservice\"A\n" + + "\x0fStorageManifest\x12\x18\n" + + "\aversion\x18\x01 \x01(\x04R\aversion\x12\x14\n" + + "\x05value\x18\x02 \x01(\fR\x05value\"5\n" + + "\vStorageItem\x12\x10\n" + + "\x03key\x18\x01 \x01(\fR\x03key\x12\x14\n" + + "\x05value\x18\x02 \x01(\fR\x05value\"@\n" + + "\fStorageItems\x120\n" + + "\x05items\x18\x01 \x03(\v2\x1a.signalservice.StorageItemR\x05items\")\n" + + "\rReadOperation\x12\x18\n" + + "\areadKey\x18\x01 \x03(\fR\areadKey\"\xc2\x01\n" + + "\x0eWriteOperation\x12:\n" + + "\bmanifest\x18\x01 \x01(\v2\x1e.signalservice.StorageManifestR\bmanifest\x12:\n" + + "\n" + + "insertItem\x18\x02 \x03(\v2\x1a.signalservice.StorageItemR\n" + + "insertItem\x12\x1c\n" + + "\tdeleteKey\x18\x03 \x03(\fR\tdeleteKey\x12\x1a\n" + + "\bclearAll\x18\x04 \x01(\bR\bclearAll\"\xa3\x03\n" + + "\x0eManifestRecord\x12\x18\n" + + "\aversion\x18\x01 \x01(\x04R\aversion\x12\"\n" + + "\fsourceDevice\x18\x03 \x01(\rR\fsourceDevice\x12J\n" + + "\videntifiers\x18\x02 \x03(\v2(.signalservice.ManifestRecord.IdentifierR\videntifiers\x12\x1c\n" + + "\trecordIkm\x18\x04 \x01(\fR\trecordIkm\x1a\xe8\x01\n" + + "\n" + + "Identifier\x12\x10\n" + + "\x03raw\x18\x01 \x01(\fR\x03raw\x12A\n" + + "\x04type\x18\x02 \x01(\x0e2-.signalservice.ManifestRecord.Identifier.TypeR\x04type\"\x84\x01\n" + + "\x04Type\x12\v\n" + + "\aUNKNOWN\x10\x00\x12\v\n" + + "\aCONTACT\x10\x01\x12\v\n" + + "\aGROUPV1\x10\x02\x12\v\n" + + "\aGROUPV2\x10\x03\x12\v\n" + + "\aACCOUNT\x10\x04\x12\x1b\n" + + "\x17STORY_DISTRIBUTION_LIST\x10\x05\x12\r\n" + + "\tCALL_LINK\x10\a\x12\x0f\n" + + "\vCHAT_FOLDER\x10\b\"\xe5\x03\n" + + "\rStorageRecord\x128\n" + + "\acontact\x18\x01 \x01(\v2\x1c.signalservice.ContactRecordH\x00R\acontact\x128\n" + + "\agroupV1\x18\x02 \x01(\v2\x1c.signalservice.GroupV1RecordH\x00R\agroupV1\x128\n" + + "\agroupV2\x18\x03 \x01(\v2\x1c.signalservice.GroupV2RecordH\x00R\agroupV2\x128\n" + + "\aaccount\x18\x04 \x01(\v2\x1c.signalservice.AccountRecordH\x00R\aaccount\x12b\n" + + "\x15storyDistributionList\x18\x05 \x01(\v2*.signalservice.StoryDistributionListRecordH\x00R\x15storyDistributionList\x12;\n" + + "\bcallLink\x18\a \x01(\v2\x1d.signalservice.CallLinkRecordH\x00R\bcallLink\x12A\n" + + "\n" + + "chatFolder\x18\b \x01(\v2\x1f.signalservice.ChatFolderRecordH\x00R\n" + + "chatFolderB\b\n" + + "\x06record\"\x9d\b\n" + + "\rContactRecord\x12\x10\n" + + "\x03aci\x18\x01 \x01(\tR\x03aci\x12\x12\n" + + "\x04e164\x18\x02 \x01(\tR\x04e164\x12\x10\n" + + "\x03pni\x18\x0f \x01(\tR\x03pni\x12\x1e\n" + + "\n" + + "profileKey\x18\x03 \x01(\fR\n" + + "profileKey\x12 \n" + + "\videntityKey\x18\x04 \x01(\fR\videntityKey\x12P\n" + + "\ridentityState\x18\x05 \x01(\x0e2*.signalservice.ContactRecord.IdentityStateR\ridentityState\x12\x1c\n" + + "\tgivenName\x18\x06 \x01(\tR\tgivenName\x12\x1e\n" + + "\n" + + "familyName\x18\a \x01(\tR\n" + + "familyName\x12\x1a\n" + + "\busername\x18\b \x01(\tR\busername\x12\x18\n" + + "\ablocked\x18\t \x01(\bR\ablocked\x12 \n" + + "\vwhitelisted\x18\n" + + " \x01(\bR\vwhitelisted\x12\x1a\n" + + "\barchived\x18\v \x01(\bR\barchived\x12\"\n" + + "\fmarkedUnread\x18\f \x01(\bR\fmarkedUnread\x120\n" + + "\x13mutedUntilTimestamp\x18\r \x01(\x04R\x13mutedUntilTimestamp\x12\x1c\n" + + "\thideStory\x18\x0e \x01(\bR\thideStory\x128\n" + + "\x17unregisteredAtTimestamp\x18\x10 \x01(\x04R\x17unregisteredAtTimestamp\x12(\n" + + "\x0fsystemGivenName\x18\x11 \x01(\tR\x0fsystemGivenName\x12*\n" + + "\x10systemFamilyName\x18\x12 \x01(\tR\x10systemFamilyName\x12&\n" + + "\x0esystemNickname\x18\x13 \x01(\tR\x0esystemNickname\x12\x16\n" + + "\x06hidden\x18\x14 \x01(\bR\x06hidden\x122\n" + + "\x14pniSignatureVerified\x18\x15 \x01(\bR\x14pniSignatureVerified\x12=\n" + + "\bnickname\x18\x16 \x01(\v2!.signalservice.ContactRecord.NameR\bnickname\x12\x12\n" + + "\x04note\x18\x17 \x01(\tR\x04note\x12A\n" + + "\vavatarColor\x18\x18 \x01(\x0e2\x1a.signalservice.AvatarColorH\x00R\vavatarColor\x88\x01\x01\x1a4\n" + + "\x04Name\x12\x14\n" + + "\x05given\x18\x01 \x01(\tR\x05given\x12\x16\n" + + "\x06family\x18\x02 \x01(\tR\x06family\":\n" + + "\rIdentityState\x12\v\n" + + "\aDEFAULT\x10\x00\x12\f\n" + + "\bVERIFIED\x10\x01\x12\x0e\n" + + "\n" + + "UNVERIFIED\x10\x02B\x0e\n" + + "\f_avatarColor\"\xcd\x01\n" + + "\rGroupV1Record\x12\x0e\n" + + "\x02id\x18\x01 \x01(\fR\x02id\x12\x18\n" + + "\ablocked\x18\x02 \x01(\bR\ablocked\x12 \n" + + "\vwhitelisted\x18\x03 \x01(\bR\vwhitelisted\x12\x1a\n" + + "\barchived\x18\x04 \x01(\bR\barchived\x12\"\n" + + "\fmarkedUnread\x18\x05 \x01(\bR\fmarkedUnread\x120\n" + + "\x13mutedUntilTimestamp\x18\x06 \x01(\x04R\x13mutedUntilTimestamp\"\xa1\x04\n" + + "\rGroupV2Record\x12\x1c\n" + + "\tmasterKey\x18\x01 \x01(\fR\tmasterKey\x12\x18\n" + + "\ablocked\x18\x02 \x01(\bR\ablocked\x12 \n" + + "\vwhitelisted\x18\x03 \x01(\bR\vwhitelisted\x12\x1a\n" + + "\barchived\x18\x04 \x01(\bR\barchived\x12\"\n" + + "\fmarkedUnread\x18\x05 \x01(\bR\fmarkedUnread\x120\n" + + "\x13mutedUntilTimestamp\x18\x06 \x01(\x04R\x13mutedUntilTimestamp\x12B\n" + + "\x1cdontNotifyForMentionsIfMuted\x18\a \x01(\bR\x1cdontNotifyForMentionsIfMuted\x12\x1c\n" + + "\thideStory\x18\b \x01(\bR\thideStory\x12P\n" + + "\rstorySendMode\x18\n" + + " \x01(\x0e2*.signalservice.GroupV2Record.StorySendModeR\rstorySendMode\x12A\n" + + "\vavatarColor\x18\v \x01(\x0e2\x1a.signalservice.AvatarColorH\x00R\vavatarColor\x88\x01\x01\"7\n" + + "\rStorySendMode\x12\v\n" + + "\aDEFAULT\x10\x00\x12\f\n" + + "\bDISABLED\x10\x01\x12\v\n" + + "\aENABLED\x10\x02B\x0e\n" + + "\f_avatarColorJ\x04\b\t\x10\n" + + "\">\n" + + "\bPayments\x12\x18\n" + + "\aenabled\x18\x01 \x01(\bR\aenabled\x12\x18\n" + + "\aentropy\x18\x02 \x01(\fR\aentropy\"\xf7\x15\n" + + "\rAccountRecord\x12\x1e\n" + + "\n" + + "profileKey\x18\x01 \x01(\fR\n" + + "profileKey\x12\x1c\n" + + "\tgivenName\x18\x02 \x01(\tR\tgivenName\x12\x1e\n" + + "\n" + + "familyName\x18\x03 \x01(\tR\n" + + "familyName\x12$\n" + + "\ravatarUrlPath\x18\x04 \x01(\tR\ravatarUrlPath\x12.\n" + + "\x12noteToSelfArchived\x18\x05 \x01(\bR\x12noteToSelfArchived\x12\"\n" + + "\freadReceipts\x18\x06 \x01(\bR\freadReceipts\x126\n" + + "\x16sealedSenderIndicators\x18\a \x01(\bR\x16sealedSenderIndicators\x12*\n" + + "\x10typingIndicators\x18\b \x01(\bR\x10typingIndicators\x126\n" + + "\x16noteToSelfMarkedUnread\x18\n" + + " \x01(\bR\x16noteToSelfMarkedUnread\x12\"\n" + + "\flinkPreviews\x18\v \x01(\bR\flinkPreviews\x12k\n" + + "\x16phoneNumberSharingMode\x18\f \x01(\x0e23.signalservice.AccountRecord.PhoneNumberSharingModeR\x16phoneNumberSharingMode\x120\n" + + "\x13unlistedPhoneNumber\x18\r \x01(\bR\x13unlistedPhoneNumber\x12a\n" + + "\x13pinnedConversations\x18\x0e \x03(\v2/.signalservice.AccountRecord.PinnedConversationR\x13pinnedConversations\x122\n" + + "\x14preferContactAvatars\x18\x0f \x01(\bR\x14preferContactAvatars\x123\n" + + "\bpayments\x18\x10 \x01(\v2\x17.signalservice.PaymentsR\bpayments\x122\n" + + "\x14universalExpireTimer\x18\x11 \x01(\rR\x14universalExpireTimer\x12(\n" + + "\x0fprimarySendsSms\x18\x12 \x01(\bR\x0fprimarySendsSms\x12\x12\n" + + "\x04e164\x18\x13 \x01(\tR\x04e164\x126\n" + + "\x16preferredReactionEmoji\x18\x14 \x03(\tR\x16preferredReactionEmoji\x12\"\n" + + "\fsubscriberId\x18\x15 \x01(\fR\fsubscriberId\x126\n" + + "\x16subscriberCurrencyCode\x18\x16 \x01(\tR\x16subscriberCurrencyCode\x126\n" + + "\x16displayBadgesOnProfile\x18\x17 \x01(\bR\x16displayBadgesOnProfile\x12D\n" + + "\x1dsubscriptionManuallyCancelled\x18\x18 \x01(\bR\x1dsubscriptionManuallyCancelled\x126\n" + + "\x16keepMutedChatsArchived\x18\x19 \x01(\bR\x16keepMutedChatsArchived\x126\n" + + "\x16hasSetMyStoriesPrivacy\x18\x1a \x01(\bR\x16hasSetMyStoriesPrivacy\x12:\n" + + "\x18hasViewedOnboardingStory\x18\x1b \x01(\bR\x18hasViewedOnboardingStory\x12(\n" + + "\x0fstoriesDisabled\x18\x1d \x01(\bR\x0fstoriesDisabled\x12W\n" + + "\x18storyViewReceiptsEnabled\x18\x1e \x01(\x0e2\x1b.signalservice.OptionalBoolR\x18storyViewReceiptsEnabled\x12H\n" + + "\x1fhasSeenGroupStoryEducationSheet\x18 \x01(\bR\x1fhasSeenGroupStoryEducationSheet\x12\x1a\n" + + "\busername\x18! \x01(\tR\busername\x12F\n" + + "\x1ehasCompletedUsernameOnboarding\x18\" \x01(\bR\x1ehasCompletedUsernameOnboarding\x12M\n" + + "\fusernameLink\x18# \x01(\v2).signalservice.AccountRecord.UsernameLinkR\fusernameLink\x12!\n" + + "\thasBackup\x18' \x01(\bH\x00R\thasBackup\x88\x01\x01\x12#\n" + + "\n" + + "backupTier\x18( \x01(\x04H\x01R\n" + + "backupTier\x88\x01\x01\x12b\n" + + "\x14backupSubscriberData\x18) \x01(\v2..signalservice.AccountRecord.IAPSubscriberDataR\x14backupSubscriberData\x12A\n" + + "\vavatarColor\x18* \x01(\x0e2\x1a.signalservice.AvatarColorH\x02R\vavatarColor\x88\x01\x01\x1a\x86\x02\n" + + "\x12PinnedConversation\x12S\n" + + "\acontact\x18\x01 \x01(\v27.signalservice.AccountRecord.PinnedConversation.ContactH\x00R\acontact\x12&\n" + + "\rlegacyGroupId\x18\x03 \x01(\fH\x00R\rlegacyGroupId\x12(\n" + + "\x0egroupMasterKey\x18\x04 \x01(\fH\x00R\x0egroupMasterKey\x1a;\n" + + "\aContact\x12\x1c\n" + + "\tserviceId\x18\x01 \x01(\tR\tserviceId\x12\x12\n" + + "\x04e164\x18\x02 \x01(\tR\x04e164B\f\n" + + "\n" + + "identifier\x1a\xf8\x01\n" + + "\fUsernameLink\x12\x18\n" + + "\aentropy\x18\x01 \x01(\fR\aentropy\x12\x1a\n" + + "\bserverId\x18\x02 \x01(\fR\bserverId\x12E\n" + + "\x05color\x18\x03 \x01(\x0e2/.signalservice.AccountRecord.UsernameLink.ColorR\x05color\"k\n" + + "\x05Color\x12\v\n" + + "\aUNKNOWN\x10\x00\x12\b\n" + + "\x04BLUE\x10\x01\x12\t\n" + + "\x05WHITE\x10\x02\x12\b\n" + + "\x04GREY\x10\x03\x12\t\n" + + "\x05OLIVE\x10\x04\x12\t\n" + + "\x05GREEN\x10\x05\x12\n" + + "\n" + + "\x06ORANGE\x10\x06\x12\b\n" + + "\x04PINK\x10\a\x12\n" + + "\n" + + "\x06PURPLE\x10\b\x1a\xac\x01\n" + + "\x11IAPSubscriberData\x12\"\n" + + "\fsubscriberId\x18\x01 \x01(\fR\fsubscriberId\x12&\n" + + "\rpurchaseToken\x18\x02 \x01(\tH\x00R\rpurchaseToken\x126\n" + + "\x15originalTransactionId\x18\x03 \x01(\x04H\x00R\x15originalTransactionIdB\x13\n" + + "\x11iapSubscriptionId\"@\n" + + "\x16PhoneNumberSharingMode\x12\v\n" + + "\aUNKNOWN\x10\x00\x12\r\n" + + "\tEVERYBODY\x10\x01\x12\n" + + "\n" + + "\x06NOBODY\x10\x02B\f\n" + + "\n" + + "_hasBackupB\r\n" + + "\v_backupTierB\x0e\n" + + "\f_avatarColorJ\x04\b\t\x10\n" + + "J\x04\b\x1c\x10\x1dJ\x04\b\x1f\x10 J\x04\b$\x10%J\x04\b%\x10&J\x04\b&\x10'\"\xfb\x01\n" + + "\x1bStoryDistributionListRecord\x12\x1e\n" + + "\n" + + "identifier\x18\x01 \x01(\fR\n" + + "identifier\x12\x12\n" + + "\x04name\x18\x02 \x01(\tR\x04name\x120\n" + + "\x13recipientServiceIds\x18\x03 \x03(\tR\x13recipientServiceIds\x12.\n" + + "\x12deletedAtTimestamp\x18\x04 \x01(\x04R\x12deletedAtTimestamp\x12$\n" + + "\rallowsReplies\x18\x05 \x01(\bR\rallowsReplies\x12 \n" + + "\visBlockList\x18\x06 \x01(\bR\visBlockList\"\x82\x01\n" + + "\x0eCallLinkRecord\x12\x18\n" + + "\arootKey\x18\x01 \x01(\fR\arootKey\x12\"\n" + + "\fadminPasskey\x18\x02 \x01(\fR\fadminPasskey\x122\n" + + "\x14deletedAtTimestampMs\x18\x03 \x01(\x04R\x14deletedAtTimestampMs\"\x84\a\n" + + "\x10ChatFolderRecord\x12\x1e\n" + + "\n" + + "identifier\x18\x01 \x01(\fR\n" + + "identifier\x12\x12\n" + + "\x04name\x18\x02 \x01(\tR\x04name\x12\x1a\n" + + "\bposition\x18\x03 \x01(\rR\bposition\x12&\n" + + "\x0eshowOnlyUnread\x18\x04 \x01(\bR\x0eshowOnlyUnread\x12&\n" + + "\x0eshowMutedChats\x18\x05 \x01(\bR\x0eshowMutedChats\x12<\n" + + "\x19includeAllIndividualChats\x18\x06 \x01(\bR\x19includeAllIndividualChats\x122\n" + + "\x14includeAllGroupChats\x18\a \x01(\bR\x14includeAllGroupChats\x12J\n" + + "\n" + + "folderType\x18\b \x01(\x0e2*.signalservice.ChatFolderRecord.FolderTypeR\n" + + "folderType\x12Y\n" + + "\x12includedRecipients\x18\t \x03(\v2).signalservice.ChatFolderRecord.RecipientR\x12includedRecipients\x12Y\n" + + "\x12excludedRecipients\x18\n" + + " \x03(\v2).signalservice.ChatFolderRecord.RecipientR\x12excludedRecipients\x122\n" + + "\x14deletedAtTimestampMs\x18\v \x01(\x04R\x14deletedAtTimestampMs\x1a\xf7\x01\n" + + "\tRecipient\x12M\n" + + "\acontact\x18\x01 \x01(\v21.signalservice.ChatFolderRecord.Recipient.ContactH\x00R\acontact\x12&\n" + + "\rlegacyGroupId\x18\x02 \x01(\fH\x00R\rlegacyGroupId\x12(\n" + + "\x0egroupMasterKey\x18\x03 \x01(\fH\x00R\x0egroupMasterKey\x1a;\n" + + "\aContact\x12\x1c\n" + + "\tserviceId\x18\x01 \x01(\tR\tserviceId\x12\x12\n" + + "\x04e164\x18\x02 \x01(\tR\x04e164B\f\n" + + "\n" + + "identifier\".\n" + + "\n" + + "FolderType\x12\v\n" + + "\aUNKNOWN\x10\x00\x12\a\n" + + "\x03ALL\x10\x01\x12\n" + + "\n" + + "\x06CUSTOM\x10\x02*4\n" + + "\fOptionalBool\x12\t\n" + + "\x05UNSET\x10\x00\x12\v\n" + + "\aENABLED\x10\x01\x12\f\n" + + "\bDISABLED\x10\x02*\x85\x01\n" + + "\vAvatarColor\x12\b\n" + + "\x04A100\x10\x00\x12\b\n" + + "\x04A110\x10\x01\x12\b\n" + + "\x04A120\x10\x02\x12\b\n" + + "\x04A130\x10\x03\x12\b\n" + + "\x04A140\x10\x04\x12\b\n" + + "\x04A150\x10\x05\x12\b\n" + + "\x04A160\x10\x06\x12\b\n" + + "\x04A170\x10\a\x12\b\n" + + "\x04A180\x10\b\x12\b\n" + + "\x04A190\x10\t\x12\b\n" + + "\x04A200\x10\n" + + "\x12\b\n" + + "\x04A210\x10\vB<\n" + + "8org.whispersystems.signalservice.internal.storage.protosP\x01b\x06proto3" var ( file_StorageService_proto_rawDescOnce sync.Once - file_StorageService_proto_rawDescData = file_StorageService_proto_rawDesc + file_StorageService_proto_rawDescData []byte ) func file_StorageService_proto_rawDescGZIP() []byte { file_StorageService_proto_rawDescOnce.Do(func() { - file_StorageService_proto_rawDescData = protoimpl.X.CompressGZIP(file_StorageService_proto_rawDescData) + file_StorageService_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_StorageService_proto_rawDesc), len(file_StorageService_proto_rawDesc))) }) return file_StorageService_proto_rawDescData } @@ -2736,7 +2997,7 @@ func file_StorageService_proto_init() { out := protoimpl.TypeBuilder{ File: protoimpl.DescBuilder{ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: file_StorageService_proto_rawDesc, + RawDescriptor: unsafe.Slice(unsafe.StringData(file_StorageService_proto_rawDesc), len(file_StorageService_proto_rawDesc)), NumEnums: 8, NumMessages: 23, NumExtensions: 0, @@ -2748,7 +3009,6 @@ func file_StorageService_proto_init() { MessageInfos: file_StorageService_proto_msgTypes, }.Build() File_StorageService_proto = out.File - file_StorageService_proto_rawDesc = nil file_StorageService_proto_goTypes = nil file_StorageService_proto_depIdxs = nil } diff --git a/pkg/signalmeow/protobuf/StorageService.pb.raw b/pkg/signalmeow/protobuf/StorageService.pb.raw deleted file mode 100644 index 1e4142f2f966d232fa2d25f4dc748e115b3520bd..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7611 zcmdT}OK%(36%HlJ8eTq3k6#n{%_NR(psYkYwwt6yNQ$x zP!6|6TJ%qJQFPm1(S3hLf&POO=%(kKJDe9u*+J1oH^kiYxX<(W&LO+f_Z?S17JcEK znIlo1xQ_3rMbA98b<2~)N}XK{#13@ZJQAL-YHagNxSr|QTIO!%L6*;l>J_$erdv~? ztpUBj<)HEv%Lh}meKA(cZ2eTsNVUN6bA{S>tPoT4)NQt5g1!fu>ksm^t!iSU)tD@o zf|ZA?$c1inC&JZz*e>qe1;Q&@ejRo=A6EXBVWl@N%pVDV&6II)WZG=Lc6<4f^NZo3 zy!tg`rVUr<fTh@|Sg1 z3O6H0j%%FrRuxw8oT)n!y8>SyR?0jm@&rx&p5;wL*uHsW!h;9rc#yh<n!WfCepG>wO@Sf9;yRS;-p&nF~hPr zRP$_e*m>3IzUh=d!9laz8PuDDas~%4cz4))y;EL`2DS1!4(iQjci0(}v+50Yy+7#k zx9@h_{Q++`hJ$vu^KKsor6!q@hP5l|h3=9i}x$_Z8?XjYCWPjH8bzjhpmlke3vE9Iv0}Y;>0Nwf6JQH?D z9}DdQ?KL9cj*s-QY0Zd@?~vm$3P!Ohghv~d@tSiy9An5jw4BkYFti-76h0r~Ip3c^ zjJCjLfXj#*C*i!hJ34`l8Css$;aG)$H`ZO4c4%V~&+WL9#3KJA;dguV2&Z( z>Enr31ko&C#=?6zfvY83)k-vFL;zp8K84keal@`K>V7n5ndV%@Rv)m7-VC(HFTz{C z1R6P>CaaHFSxW9jH?ETC0$sh&N>a9Cj!xF>^SgBIl%Kv`wcuZ7*)PzMVX}n zufVjh+uExS_Xm(l3QT$3;_bb5YZr1!iLqfP9IrJ>tne&o9Vte6PTps{8eLDGY- zxF;Z>TI~s#yA{6D69Swt_lyNk!0@Z^kMacc^yQvV`Ez!Do*-$UZ;W-cdkfvJ3<4K}gWh#cKfzub(QGK3&q*pEBp#Nb80{kG% ziSJSR1pkZE)Tiv4Cv>?`2m*?+oL60w+i*ltajszqr z!uB#Bc?9efer2+Rr#@!NB=8Rn0YbiZJ++s)`|wZ@7n<6D65te8>xYTy3Pc&MhIpaK zm+}x^Ok5N25P7!Ohq4+mgTm9~5TZ(;AR#Ikj@&+A8ZMx2fk@aIJHIsnF06wKt>B{J zc+*2~1mGV`TEd0`)SNLI8Gbl!PF+{nqgfNdy#AtsaynouElVHo(7)K_p( z??m_d!ao3D?zpD#daik zGun5{m_meuC+MFD;cItkOCJ(TR1)_gp(-}{&onj1wiX*x&twM`@KuSGe zg?Y6?b>(NEm9ITa9X%Pr=8K^MPpGT+pk&a!hCVu-PP8v^2Y^o_5};G{GsX^yKY+%I z_5ftEFEczwL!m=88iCb2q#=Lp6x2@qWmCRNrz1&~OR!39dk*cmwp;VBi(Aef?W zeFNwmQ)9V(dbf*E=s-w4howkMNPU;$Z>U(Rk^ zW|vHT68HiIueMS7j$Mo4h!}WDUKVuvT2SD;{F&bn{Ghp%4d0rWVwYF$$H@ z*lh{S6Kj8jP0*_{Cnmt_zU=q64Uc-xIlhdANLTiz6RiyNoh)C%Q4v2|mh;}@Vq!sN zp}vy>_&H9b{*~9jo)2{cvBrdI){ID%-$8pm*|$UIaUI8xO3V2W%}O`Mrrpy$?-crB z(t#2*#7v6^Il!~yQI_&5KW?%z=62a0{4eeuynEt!CgwU?un1r-7*mJl#ChMfty$2g zlGS_3OHk)>5#R`}mgFL;`Yrp^v`5y|5OvGKn&8Yd0N@Zt2?~$Z0(ec4HpNt_h#ft^ zu*-PxrvW>n1}gU2sk^sW#HO#YD({q<^)YSrEmMOvuv(Iq>Oor&QF=Q6F3cHf@FkPr z)Zz!anE2G}XHUI2$x7qG0(^yWZT*yCxp2dPIOZ*Wa^-w&CzTvmANHftBDuuJq{Vsu z{NJU;N|mwb^^*a1ldZ!)DKfM+hwzunL3!=b6IO_$OiV<>PQQf>xL5}wgWb5WIkEQW z_ZgOtbp$a_)pxeHL5aS0wqX_es%^`RSKoQO4H=JUPqrc9(breoknia0>9)*v^_^$i z@HY?9o^O{G`Sq*qa*n=gum+P~utvV|Eqm^`$5rTKd+@iUY{q)2$2D!}nL#3}BKU?s RXyre%UN3Waf&Qa?{2zQv9oGN= diff --git a/pkg/signalmeow/protobuf/UnidentifiedDelivery.pb.go b/pkg/signalmeow/protobuf/UnidentifiedDelivery.pb.go index 1d1da9b..adc1e3f 100644 --- a/pkg/signalmeow/protobuf/UnidentifiedDelivery.pb.go +++ b/pkg/signalmeow/protobuf/UnidentifiedDelivery.pb.go @@ -1,6 +1,6 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.36.1 +// protoc-gen-go v1.36.6 // protoc v3.21.12 // source: UnidentifiedDelivery.proto @@ -14,10 +14,9 @@ import ( protoimpl "google.golang.org/protobuf/runtime/protoimpl" reflect "reflect" sync "sync" + unsafe "unsafe" ) -import _ "embed" - const ( // Verify that this generated code is sufficiently up-to-date. _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) @@ -527,17 +526,59 @@ func (x *UnidentifiedSenderMessage_Message) GetGroupId() []byte { var File_UnidentifiedDelivery_proto protoreflect.FileDescriptor -//go:embed UnidentifiedDelivery.pb.raw -var file_UnidentifiedDelivery_proto_rawDesc []byte +const file_UnidentifiedDelivery_proto_rawDesc = "" + + "\n" + + "\x1aUnidentifiedDelivery.proto\x12\rsignalservice\"\x84\x01\n" + + "\x11ServerCertificate\x12 \n" + + "\vcertificate\x18\x01 \x01(\fR\vcertificate\x12\x1c\n" + + "\tsignature\x18\x02 \x01(\fR\tsignature\x1a/\n" + + "\vCertificate\x12\x0e\n" + + "\x02id\x18\x01 \x01(\rR\x02id\x12\x10\n" + + "\x03key\x18\x02 \x01(\fR\x03key\"\xbd\x02\n" + + "\x11SenderCertificate\x12 \n" + + "\vcertificate\x18\x01 \x01(\fR\vcertificate\x12\x1c\n" + + "\tsignature\x18\x02 \x01(\fR\tsignature\x1a\xe7\x01\n" + + "\vCertificate\x12\x1e\n" + + "\n" + + "senderE164\x18\x01 \x01(\tR\n" + + "senderE164\x12\x1e\n" + + "\n" + + "senderUuid\x18\x06 \x01(\tR\n" + + "senderUuid\x12\"\n" + + "\fsenderDevice\x18\x02 \x01(\rR\fsenderDevice\x12\x18\n" + + "\aexpires\x18\x03 \x01(\x06R\aexpires\x12 \n" + + "\videntityKey\x18\x04 \x01(\fR\videntityKey\x128\n" + + "\x06signer\x18\x05 \x01(\v2 .signalservice.ServerCertificateR\x06signer\"\xe7\x04\n" + + "\x19UnidentifiedSenderMessage\x12(\n" + + "\x0fephemeralPublic\x18\x01 \x01(\fR\x0fephemeralPublic\x12(\n" + + "\x0fencryptedStatic\x18\x02 \x01(\fR\x0fencryptedStatic\x12*\n" + + "\x10encryptedMessage\x18\x03 \x01(\fR\x10encryptedMessage\x1a\xc9\x03\n" + + "\aMessage\x12I\n" + + "\x04type\x18\x01 \x01(\x0e25.signalservice.UnidentifiedSenderMessage.Message.TypeR\x04type\x12N\n" + + "\x11senderCertificate\x18\x02 \x01(\v2 .signalservice.SenderCertificateR\x11senderCertificate\x12\x18\n" + + "\acontent\x18\x03 \x01(\fR\acontent\x12^\n" + + "\vcontentHint\x18\x04 \x01(\x0e2<.signalservice.UnidentifiedSenderMessage.Message.ContentHintR\vcontentHint\x12\x18\n" + + "\agroupId\x18\x05 \x01(\fR\agroupId\"U\n" + + "\x04Type\x12\x12\n" + + "\x0ePREKEY_MESSAGE\x10\x01\x12\v\n" + + "\aMESSAGE\x10\x02\x12\x15\n" + + "\x11SENDERKEY_MESSAGE\x10\a\x12\x15\n" + + "\x11PLAINTEXT_CONTENT\x10\b\"8\n" + + "\vContentHint\x12\v\n" + + "\aDEFAULT\x10\x00\x12\x0e\n" + + "\n" + + "RESENDABLE\x10\x01\x12\f\n" + + "\bIMPLICIT\x10\x02B6\n" + + "%org.whispersystems.libsignal.protocolB\rWhisperProtos" var ( file_UnidentifiedDelivery_proto_rawDescOnce sync.Once - file_UnidentifiedDelivery_proto_rawDescData = file_UnidentifiedDelivery_proto_rawDesc + file_UnidentifiedDelivery_proto_rawDescData []byte ) func file_UnidentifiedDelivery_proto_rawDescGZIP() []byte { file_UnidentifiedDelivery_proto_rawDescOnce.Do(func() { - file_UnidentifiedDelivery_proto_rawDescData = protoimpl.X.CompressGZIP(file_UnidentifiedDelivery_proto_rawDescData) + file_UnidentifiedDelivery_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_UnidentifiedDelivery_proto_rawDesc), len(file_UnidentifiedDelivery_proto_rawDesc))) }) return file_UnidentifiedDelivery_proto_rawDescData } @@ -575,7 +616,7 @@ func file_UnidentifiedDelivery_proto_init() { out := protoimpl.TypeBuilder{ File: protoimpl.DescBuilder{ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: file_UnidentifiedDelivery_proto_rawDesc, + RawDescriptor: unsafe.Slice(unsafe.StringData(file_UnidentifiedDelivery_proto_rawDesc), len(file_UnidentifiedDelivery_proto_rawDesc)), NumEnums: 2, NumMessages: 6, NumExtensions: 0, @@ -587,7 +628,6 @@ func file_UnidentifiedDelivery_proto_init() { MessageInfos: file_UnidentifiedDelivery_proto_msgTypes, }.Build() File_UnidentifiedDelivery_proto = out.File - file_UnidentifiedDelivery_proto_rawDesc = nil file_UnidentifiedDelivery_proto_goTypes = nil file_UnidentifiedDelivery_proto_depIdxs = nil } diff --git a/pkg/signalmeow/protobuf/UnidentifiedDelivery.pb.raw b/pkg/signalmeow/protobuf/UnidentifiedDelivery.pb.raw deleted file mode 100644 index 7d8db350b01354f7b5508c6ea3789823fdc2239c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1172 zcmb_c%Wl&^6eSOm_U2J{B%}}_R9Ql*ShymBstY!G7_gdzXyORiP^I=I9pT#6*eQ6= zZ}9Wxv6DCnERa}v?zyjX@0l^QXFhY$kJ%T7?f^Y@hdePt9>f7@L~P;Dy$Jao zb5Q?Lfa9q+Bkv=Z3C=u5asoAHW3~z>h0{9CL*xk@szULSW2>nA8=!p#wS2iI6q&24 zG^jWc4N6}z$8{6pj#MeK^4D;jAPU)i2@b6GUZZJRpR7QOkYlynuEv%ROC{Tw;l>-t#e{* ziDm2wMYDMQz6_7^qNlqYVHC|5NKWAh!yCLsKKCZeYmYgZq`R<+^c|jrF}l-u9*f9S z+#}qE$#c-wP}WBcT&H_@`&S97D=rq4<0M2ypxJq~GvQxnFtU8Z7RgkVAY(XA<;dMN zMfXpe+qqkGKUGTS1b!?YPBzKPB%j55NImbE@Ji{Lo!9@&y}zj;Uem^qofkYBp#4C9+)&AQFRnxzW6L`JGhcsj&e>>4{Z((U# diff --git a/pkg/signalmeow/protobuf/WebSocketResources.pb.go b/pkg/signalmeow/protobuf/WebSocketResources.pb.go index 45d5396..ff48cda 100644 --- a/pkg/signalmeow/protobuf/WebSocketResources.pb.go +++ b/pkg/signalmeow/protobuf/WebSocketResources.pb.go @@ -5,7 +5,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.36.1 +// protoc-gen-go v1.36.6 // protoc v3.21.12 // source: WebSocketResources.proto @@ -16,10 +16,9 @@ import ( protoimpl "google.golang.org/protobuf/runtime/protoimpl" reflect "reflect" sync "sync" + unsafe "unsafe" ) -import _ "embed" - const ( // Verify that this generated code is sufficiently up-to-date. _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) @@ -300,17 +299,39 @@ func (x *WebSocketMessage) GetResponse() *WebSocketResponseMessage { var File_WebSocketResources_proto protoreflect.FileDescriptor -//go:embed WebSocketResources.pb.raw -var file_WebSocketResources_proto_rawDesc []byte +const file_WebSocketResources_proto_rawDesc = "" + + "\n" + + "\x18WebSocketResources.proto\x12\rsignalservice\"\x7f\n" + + "\x17WebSocketRequestMessage\x12\x12\n" + + "\x04verb\x18\x01 \x01(\tR\x04verb\x12\x12\n" + + "\x04path\x18\x02 \x01(\tR\x04path\x12\x12\n" + + "\x04body\x18\x03 \x01(\fR\x04body\x12\x18\n" + + "\aheaders\x18\x05 \x03(\tR\aheaders\x12\x0e\n" + + "\x02id\x18\x04 \x01(\x04R\x02id\"\x8a\x01\n" + + "\x18WebSocketResponseMessage\x12\x0e\n" + + "\x02id\x18\x01 \x01(\x04R\x02id\x12\x16\n" + + "\x06status\x18\x02 \x01(\rR\x06status\x12\x18\n" + + "\amessage\x18\x03 \x01(\tR\amessage\x12\x18\n" + + "\aheaders\x18\x05 \x03(\tR\aheaders\x12\x12\n" + + "\x04body\x18\x04 \x01(\fR\x04body\"\x83\x02\n" + + "\x10WebSocketMessage\x128\n" + + "\x04type\x18\x01 \x01(\x0e2$.signalservice.WebSocketMessage.TypeR\x04type\x12@\n" + + "\arequest\x18\x02 \x01(\v2&.signalservice.WebSocketRequestMessageR\arequest\x12C\n" + + "\bresponse\x18\x03 \x01(\v2'.signalservice.WebSocketResponseMessageR\bresponse\".\n" + + "\x04Type\x12\v\n" + + "\aUNKNOWN\x10\x00\x12\v\n" + + "\aREQUEST\x10\x01\x12\f\n" + + "\bRESPONSE\x10\x02BF\n" + + "3org.whispersystems.signalservice.internal.websocketB\x0fWebSocketProtos" var ( file_WebSocketResources_proto_rawDescOnce sync.Once - file_WebSocketResources_proto_rawDescData = file_WebSocketResources_proto_rawDesc + file_WebSocketResources_proto_rawDescData []byte ) func file_WebSocketResources_proto_rawDescGZIP() []byte { file_WebSocketResources_proto_rawDescOnce.Do(func() { - file_WebSocketResources_proto_rawDescData = protoimpl.X.CompressGZIP(file_WebSocketResources_proto_rawDescData) + file_WebSocketResources_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_WebSocketResources_proto_rawDesc), len(file_WebSocketResources_proto_rawDesc))) }) return file_WebSocketResources_proto_rawDescData } @@ -343,7 +364,7 @@ func file_WebSocketResources_proto_init() { out := protoimpl.TypeBuilder{ File: protoimpl.DescBuilder{ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: file_WebSocketResources_proto_rawDesc, + RawDescriptor: unsafe.Slice(unsafe.StringData(file_WebSocketResources_proto_rawDesc), len(file_WebSocketResources_proto_rawDesc)), NumEnums: 1, NumMessages: 3, NumExtensions: 0, @@ -355,7 +376,6 @@ func file_WebSocketResources_proto_init() { MessageInfos: file_WebSocketResources_proto_msgTypes, }.Build() File_WebSocketResources_proto = out.File - file_WebSocketResources_proto_rawDesc = nil file_WebSocketResources_proto_goTypes = nil file_WebSocketResources_proto_depIdxs = nil } diff --git a/pkg/signalmeow/protobuf/WebSocketResources.pb.raw b/pkg/signalmeow/protobuf/WebSocketResources.pb.raw deleted file mode 100644 index a521defa0604210f4e9dc97d2d2b08983e362deb..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 645 zcmaKq%}>HW5XEh&g3E`^9<)c&81>WxUOXC1y%-B_A)H&7K%>yQvp{*VJ`ngOnS%R8uKq|r*MQ;`5TiLz zN~{g=*fF}s-8s{>nq`q#IA$?ZwVK80EO%;h)?&J*4yi97ngK`Wv|E$*s-+!bCNsy9 zT8qib{V~WMY?iJNDuhC;0JNB1k~0*MSfd7Lv$9j`mIbw@kn76!ACL-Lp_JI}w@K_> z92LX^u|%GM&Y{!0_Vxnw4&~lRYMFM>M^fjYGu6D!-pw&HD`e$LR@vwiX>dTDiT<)? z@Ami;g|2#IXLLPcDJa?`^>OeL3?_knq8jGEjs0+B8?;3l%nyfyAoOjs|4i;vKKHhZ h1T*;ua}=<|gSE*@0GD^ diff --git a/pkg/signalmeow/protobuf/backuppb/Backup.pb.go b/pkg/signalmeow/protobuf/backuppb/Backup.pb.go index 4e68cdc..cce9b50 100644 --- a/pkg/signalmeow/protobuf/backuppb/Backup.pb.go +++ b/pkg/signalmeow/protobuf/backuppb/Backup.pb.go @@ -1,6 +1,6 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.36.1 +// protoc-gen-go v1.36.6 // protoc v3.21.12 // source: backuppb/Backup.proto @@ -11,10 +11,9 @@ import ( protoimpl "google.golang.org/protobuf/runtime/protoimpl" reflect "reflect" sync "sync" + unsafe "unsafe" ) -import _ "embed" - const ( // Verify that this generated code is sufficiently up-to-date. _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) @@ -11178,17 +11177,1084 @@ func (*ChatStyle_AutomaticBubbleColor) Descriptor() ([]byte, []int) { var File_backuppb_Backup_proto protoreflect.FileDescriptor -//go:embed Backup.pb.raw -var file_backuppb_Backup_proto_rawDesc []byte +const file_backuppb_Backup_proto_rawDesc = "" + + "\n" + + "\x15backuppb/Backup.proto\x12\rsignal.backup\"\xd2\x01\n" + + "\n" + + "BackupInfo\x12\x18\n" + + "\aversion\x18\x01 \x01(\x04R\aversion\x12\"\n" + + "\fbackupTimeMs\x18\x02 \x01(\x04R\fbackupTimeMs\x12.\n" + + "\x12mediaRootBackupKey\x18\x03 \x01(\fR\x12mediaRootBackupKey\x12,\n" + + "\x11currentAppVersion\x18\x04 \x01(\tR\x11currentAppVersion\x12(\n" + + "\x0ffirstAppVersion\x18\x05 \x01(\tR\x0ffirstAppVersion\"\xf2\x03\n" + + "\x05Frame\x126\n" + + "\aaccount\x18\x01 \x01(\v2\x1a.signal.backup.AccountDataH\x00R\aaccount\x128\n" + + "\trecipient\x18\x02 \x01(\v2\x18.signal.backup.RecipientH\x00R\trecipient\x12)\n" + + "\x04chat\x18\x03 \x01(\v2\x13.signal.backup.ChatH\x00R\x04chat\x125\n" + + "\bchatItem\x18\x04 \x01(\v2\x17.signal.backup.ChatItemH\x00R\bchatItem\x12>\n" + + "\vstickerPack\x18\x05 \x01(\v2\x1a.signal.backup.StickerPackH\x00R\vstickerPack\x128\n" + + "\tadHocCall\x18\x06 \x01(\v2\x18.signal.backup.AdHocCallH\x00R\tadHocCall\x12V\n" + + "\x13notificationProfile\x18\a \x01(\v2\".signal.backup.NotificationProfileH\x00R\x13notificationProfile\x12;\n" + + "\n" + + "chatFolder\x18\b \x01(\v2\x19.signal.backup.ChatFolderH\x00R\n" + + "chatFolderB\x06\n" + + "\x04item\"\xf1\x12\n" + + "\vAccountData\x12\x1e\n" + + "\n" + + "profileKey\x18\x01 \x01(\fR\n" + + "profileKey\x12\x1f\n" + + "\busername\x18\x02 \x01(\tH\x00R\busername\x88\x01\x01\x12K\n" + + "\fusernameLink\x18\x03 \x01(\v2'.signal.backup.AccountData.UsernameLinkR\fusernameLink\x12\x1c\n" + + "\tgivenName\x18\x04 \x01(\tR\tgivenName\x12\x1e\n" + + "\n" + + "familyName\x18\x05 \x01(\tR\n" + + "familyName\x12$\n" + + "\ravatarUrlPath\x18\x06 \x01(\tR\ravatarUrlPath\x12a\n" + + "\x16donationSubscriberData\x18\a \x01(\v2).signal.backup.AccountData.SubscriberDataR\x16donationSubscriberData\x12T\n" + + "\x0faccountSettings\x18\t \x01(\v2*.signal.backup.AccountData.AccountSettingsR\x0faccountSettings\x12b\n" + + "\x15backupsSubscriberData\x18\n" + + " \x01(\v2,.signal.backup.AccountData.IAPSubscriberDataR\x15backupsSubscriberData\x12\x16\n" + + "\x06svrPin\x18\v \x01(\tR\x06svrPin\x1a\xf6\x01\n" + + "\fUsernameLink\x12\x18\n" + + "\aentropy\x18\x01 \x01(\fR\aentropy\x12\x1a\n" + + "\bserverId\x18\x02 \x01(\fR\bserverId\x12C\n" + + "\x05color\x18\x03 \x01(\x0e2-.signal.backup.AccountData.UsernameLink.ColorR\x05color\"k\n" + + "\x05Color\x12\v\n" + + "\aUNKNOWN\x10\x00\x12\b\n" + + "\x04BLUE\x10\x01\x12\t\n" + + "\x05WHITE\x10\x02\x12\b\n" + + "\x04GREY\x10\x03\x12\t\n" + + "\x05OLIVE\x10\x04\x12\t\n" + + "\x05GREEN\x10\x05\x12\n" + + "\n" + + "\x06ORANGE\x10\x06\x12\b\n" + + "\x04PINK\x10\a\x12\n" + + "\n" + + "\x06PURPLE\x10\b\x1a\xb4\t\n" + + "\x0fAccountSettings\x12\"\n" + + "\freadReceipts\x18\x01 \x01(\bR\freadReceipts\x126\n" + + "\x16sealedSenderIndicators\x18\x02 \x01(\bR\x16sealedSenderIndicators\x12*\n" + + "\x10typingIndicators\x18\x03 \x01(\bR\x10typingIndicators\x12\"\n" + + "\flinkPreviews\x18\x04 \x01(\bR\flinkPreviews\x12B\n" + + "\x1cnotDiscoverableByPhoneNumber\x18\x05 \x01(\bR\x1cnotDiscoverableByPhoneNumber\x122\n" + + "\x14preferContactAvatars\x18\x06 \x01(\bR\x14preferContactAvatars\x12@\n" + + "\x1buniversalExpireTimerSeconds\x18\a \x01(\rR\x1buniversalExpireTimerSeconds\x126\n" + + "\x16preferredReactionEmoji\x18\b \x03(\tR\x16preferredReactionEmoji\x126\n" + + "\x16displayBadgesOnProfile\x18\t \x01(\bR\x16displayBadgesOnProfile\x126\n" + + "\x16keepMutedChatsArchived\x18\n" + + " \x01(\bR\x16keepMutedChatsArchived\x126\n" + + "\x16hasSetMyStoriesPrivacy\x18\v \x01(\bR\x16hasSetMyStoriesPrivacy\x12:\n" + + "\x18hasViewedOnboardingStory\x18\f \x01(\bR\x18hasViewedOnboardingStory\x12(\n" + + "\x0fstoriesDisabled\x18\r \x01(\bR\x0fstoriesDisabled\x12?\n" + + "\x18storyViewReceiptsEnabled\x18\x0e \x01(\bH\x00R\x18storyViewReceiptsEnabled\x88\x01\x01\x12H\n" + + "\x1fhasSeenGroupStoryEducationSheet\x18\x0f \x01(\bR\x1fhasSeenGroupStoryEducationSheet\x12F\n" + + "\x1ehasCompletedUsernameOnboarding\x18\x10 \x01(\bR\x1ehasCompletedUsernameOnboarding\x12i\n" + + "\x16phoneNumberSharingMode\x18\x11 \x01(\x0e21.signal.backup.AccountData.PhoneNumberSharingModeR\x16phoneNumberSharingMode\x12D\n" + + "\x10defaultChatStyle\x18\x12 \x01(\v2\x18.signal.backup.ChatStyleR\x10defaultChatStyle\x12T\n" + + "\x10customChatColors\x18\x13 \x03(\v2(.signal.backup.ChatStyle.CustomChatColorR\x10customChatColorsB\x1b\n" + + "\x19_storyViewReceiptsEnabled\x1a\x86\x01\n" + + "\x0eSubscriberData\x12\"\n" + + "\fsubscriberId\x18\x01 \x01(\fR\fsubscriberId\x12\"\n" + + "\fcurrencyCode\x18\x02 \x01(\tR\fcurrencyCode\x12,\n" + + "\x11manuallyCancelled\x18\x03 \x01(\bR\x11manuallyCancelled\x1a\xac\x01\n" + + "\x11IAPSubscriberData\x12\"\n" + + "\fsubscriberId\x18\x01 \x01(\fR\fsubscriberId\x12&\n" + + "\rpurchaseToken\x18\x02 \x01(\tH\x00R\rpurchaseToken\x126\n" + + "\x15originalTransactionId\x18\x03 \x01(\x04H\x00R\x15originalTransactionIdB\x13\n" + + "\x11iapSubscriptionId\"@\n" + + "\x16PhoneNumberSharingMode\x12\v\n" + + "\aUNKNOWN\x10\x00\x12\r\n" + + "\tEVERYBODY\x10\x01\x12\n" + + "\n" + + "\x06NOBODY\x10\x02B\v\n" + + "\t_usernameJ\x04\b\b\x10\t\"\x84\x03\n" + + "\tRecipient\x12\x0e\n" + + "\x02id\x18\x01 \x01(\x04R\x02id\x122\n" + + "\acontact\x18\x02 \x01(\v2\x16.signal.backup.ContactH\x00R\acontact\x12,\n" + + "\x05group\x18\x03 \x01(\v2\x14.signal.backup.GroupH\x00R\x05group\x12Q\n" + + "\x10distributionList\x18\x04 \x01(\v2#.signal.backup.DistributionListItemH\x00R\x10distributionList\x12)\n" + + "\x04self\x18\x05 \x01(\v2\x13.signal.backup.SelfH\x00R\x04self\x12A\n" + + "\freleaseNotes\x18\x06 \x01(\v2\x1b.signal.backup.ReleaseNotesH\x00R\freleaseNotes\x125\n" + + "\bcallLink\x18\a \x01(\v2\x17.signal.backup.CallLinkH\x00R\bcallLinkB\r\n" + + "\vdestination\"\xcb\n" + + "\n" + + "\aContact\x12\x15\n" + + "\x03aci\x18\x01 \x01(\fH\x01R\x03aci\x88\x01\x01\x12\x15\n" + + "\x03pni\x18\x02 \x01(\fH\x02R\x03pni\x88\x01\x01\x12\x1f\n" + + "\busername\x18\x03 \x01(\tH\x03R\busername\x88\x01\x01\x12\x17\n" + + "\x04e164\x18\x04 \x01(\x04H\x04R\x04e164\x88\x01\x01\x12\x18\n" + + "\ablocked\x18\x05 \x01(\bR\ablocked\x12A\n" + + "\n" + + "visibility\x18\x06 \x01(\x0e2!.signal.backup.Contact.VisibilityR\n" + + "visibility\x12C\n" + + "\n" + + "registered\x18\a \x01(\v2!.signal.backup.Contact.RegisteredH\x00R\n" + + "registered\x12L\n" + + "\rnotRegistered\x18\b \x01(\v2$.signal.backup.Contact.NotRegisteredH\x00R\rnotRegistered\x12#\n" + + "\n" + + "profileKey\x18\t \x01(\fH\x05R\n" + + "profileKey\x88\x01\x01\x12&\n" + + "\x0eprofileSharing\x18\n" + + " \x01(\bR\x0eprofileSharing\x12/\n" + + "\x10profileGivenName\x18\v \x01(\tH\x06R\x10profileGivenName\x88\x01\x01\x121\n" + + "\x11profileFamilyName\x18\f \x01(\tH\aR\x11profileFamilyName\x88\x01\x01\x12\x1c\n" + + "\thideStory\x18\r \x01(\bR\thideStory\x12%\n" + + "\videntityKey\x18\x0e \x01(\fH\bR\videntityKey\x88\x01\x01\x12J\n" + + "\ridentityState\x18\x0f \x01(\x0e2$.signal.backup.Contact.IdentityStateR\ridentityState\x127\n" + + "\bnickname\x18\x10 \x01(\v2\x1b.signal.backup.Contact.NameR\bnickname\x12\x12\n" + + "\x04note\x18\x11 \x01(\tR\x04note\x12(\n" + + "\x0fsystemGivenName\x18\x12 \x01(\tR\x0fsystemGivenName\x12*\n" + + "\x10systemFamilyName\x18\x13 \x01(\tR\x10systemFamilyName\x12&\n" + + "\x0esystemNickname\x18\x14 \x01(\tR\x0esystemNickname\x12A\n" + + "\vavatarColor\x18\x15 \x01(\x0e2\x1a.signal.backup.AvatarColorH\tR\vavatarColor\x88\x01\x01\x1a\f\n" + + "\n" + + "Registered\x1aE\n" + + "\rNotRegistered\x124\n" + + "\x15unregisteredTimestamp\x18\x01 \x01(\x04R\x15unregisteredTimestamp\x1a4\n" + + "\x04Name\x12\x14\n" + + "\x05given\x18\x01 \x01(\tR\x05given\x12\x16\n" + + "\x06family\x18\x02 \x01(\tR\x06family\":\n" + + "\rIdentityState\x12\v\n" + + "\aDEFAULT\x10\x00\x12\f\n" + + "\bVERIFIED\x10\x01\x12\x0e\n" + + "\n" + + "UNVERIFIED\x10\x02\"A\n" + + "\n" + + "Visibility\x12\v\n" + + "\aVISIBLE\x10\x00\x12\n" + + "\n" + + "\x06HIDDEN\x10\x01\x12\x1a\n" + + "\x16HIDDEN_MESSAGE_REQUEST\x10\x02B\x0e\n" + + "\fregistrationB\x06\n" + + "\x04_aciB\x06\n" + + "\x04_pniB\v\n" + + "\t_usernameB\a\n" + + "\x05_e164B\r\n" + + "\v_profileKeyB\x13\n" + + "\x11_profileGivenNameB\x14\n" + + "\x12_profileFamilyNameB\x0e\n" + + "\f_identityKeyB\x0e\n" + + "\f_avatarColor\"\x8f\x12\n" + + "\x05Group\x12\x1c\n" + + "\tmasterKey\x18\x01 \x01(\fR\tmasterKey\x12 \n" + + "\vwhitelisted\x18\x02 \x01(\bR\vwhitelisted\x12\x1c\n" + + "\thideStory\x18\x03 \x01(\bR\thideStory\x12H\n" + + "\rstorySendMode\x18\x04 \x01(\x0e2\".signal.backup.Group.StorySendModeR\rstorySendMode\x12>\n" + + "\bsnapshot\x18\x05 \x01(\v2\".signal.backup.Group.GroupSnapshotR\bsnapshot\x12\x18\n" + + "\ablocked\x18\x06 \x01(\bR\ablocked\x12A\n" + + "\vavatarColor\x18\a \x01(\x0e2\x1a.signal.backup.AvatarColorH\x00R\vavatarColor\x88\x01\x01\x1a\xc5\x06\n" + + "\rGroupSnapshot\x12=\n" + + "\x05title\x18\x02 \x01(\v2'.signal.backup.Group.GroupAttributeBlobR\x05title\x12I\n" + + "\vdescription\x18\v \x01(\v2'.signal.backup.Group.GroupAttributeBlobR\vdescription\x12\x1c\n" + + "\tavatarUrl\x18\x03 \x01(\tR\tavatarUrl\x12e\n" + + "\x19disappearingMessagesTimer\x18\x04 \x01(\v2'.signal.backup.Group.GroupAttributeBlobR\x19disappearingMessagesTimer\x12H\n" + + "\raccessControl\x18\x05 \x01(\v2\".signal.backup.Group.AccessControlR\raccessControl\x12\x18\n" + + "\aversion\x18\x06 \x01(\rR\aversion\x125\n" + + "\amembers\x18\a \x03(\v2\x1b.signal.backup.Group.MemberR\amembers\x12h\n" + + "\x18membersPendingProfileKey\x18\b \x03(\v2,.signal.backup.Group.MemberPendingProfileKeyR\x18membersPendingProfileKey\x12q\n" + + "\x1bmembersPendingAdminApproval\x18\t \x03(\v2/.signal.backup.Group.MemberPendingAdminApprovalR\x1bmembersPendingAdminApproval\x12.\n" + + "\x12inviteLinkPassword\x18\n" + + " \x01(\fR\x12inviteLinkPassword\x12-\n" + + "\x12announcements_only\x18\f \x01(\bR\x11announcementsOnly\x12H\n" + + "\x0emembers_banned\x18\r \x03(\v2!.signal.backup.Group.MemberBannedR\rmembersBannedJ\x04\b\x01\x10\x02\x1a\xc3\x01\n" + + "\x12GroupAttributeBlob\x12\x16\n" + + "\x05title\x18\x01 \x01(\tH\x00R\x05title\x12\x18\n" + + "\x06avatar\x18\x02 \x01(\fH\x00R\x06avatar\x12D\n" + + "\x1cdisappearingMessagesDuration\x18\x03 \x01(\rH\x00R\x1cdisappearingMessagesDuration\x12*\n" + + "\x0fdescriptionText\x18\x04 \x01(\tH\x00R\x0fdescriptionTextB\t\n" + + "\acontent\x1a\xc1\x01\n" + + "\x06Member\x12\x16\n" + + "\x06userId\x18\x01 \x01(\fR\x06userId\x124\n" + + "\x04role\x18\x02 \x01(\x0e2 .signal.backup.Group.Member.RoleR\x04role\x12(\n" + + "\x0fjoinedAtVersion\x18\x05 \x01(\rR\x0fjoinedAtVersion\"3\n" + + "\x04Role\x12\v\n" + + "\aUNKNOWN\x10\x00\x12\v\n" + + "\aDEFAULT\x10\x01\x12\x11\n" + + "\rADMINISTRATOR\x10\x02J\x04\b\x03\x10\x04J\x04\b\x04\x10\x05\x1a\x92\x01\n" + + "\x17MemberPendingProfileKey\x123\n" + + "\x06member\x18\x01 \x01(\v2\x1b.signal.backup.Group.MemberR\x06member\x12$\n" + + "\raddedByUserId\x18\x02 \x01(\fR\raddedByUserId\x12\x1c\n" + + "\ttimestamp\x18\x03 \x01(\x04R\ttimestamp\x1a^\n" + + "\x1aMemberPendingAdminApproval\x12\x16\n" + + "\x06userId\x18\x01 \x01(\fR\x06userId\x12\x1c\n" + + "\ttimestamp\x18\x04 \x01(\x04R\ttimestampJ\x04\b\x02\x10\x03J\x04\b\x03\x10\x04\x1aD\n" + + "\fMemberBanned\x12\x16\n" + + "\x06userId\x18\x01 \x01(\fR\x06userId\x12\x1c\n" + + "\ttimestamp\x18\x02 \x01(\x04R\ttimestamp\x1a\xea\x02\n" + + "\rAccessControl\x12Q\n" + + "\n" + + "attributes\x18\x01 \x01(\x0e21.signal.backup.Group.AccessControl.AccessRequiredR\n" + + "attributes\x12K\n" + + "\amembers\x18\x02 \x01(\x0e21.signal.backup.Group.AccessControl.AccessRequiredR\amembers\x12_\n" + + "\x11addFromInviteLink\x18\x03 \x01(\x0e21.signal.backup.Group.AccessControl.AccessRequiredR\x11addFromInviteLink\"X\n" + + "\x0eAccessRequired\x12\v\n" + + "\aUNKNOWN\x10\x00\x12\a\n" + + "\x03ANY\x10\x01\x12\n" + + "\n" + + "\x06MEMBER\x10\x02\x12\x11\n" + + "\rADMINISTRATOR\x10\x03\x12\x11\n" + + "\rUNSATISFIABLE\x10\x04\"7\n" + + "\rStorySendMode\x12\v\n" + + "\aDEFAULT\x10\x00\x12\f\n" + + "\bDISABLED\x10\x01\x12\v\n" + + "\aENABLED\x10\x02B\x0e\n" + + "\f_avatarColor\"Y\n" + + "\x04Self\x12A\n" + + "\vavatarColor\x18\x01 \x01(\x0e2\x1a.signal.backup.AvatarColorH\x00R\vavatarColor\x88\x01\x01B\x0e\n" + + "\f_avatarColor\"\x0e\n" + + "\fReleaseNotes\"\xd3\x03\n" + + "\x04Chat\x12\x0e\n" + + "\x02id\x18\x01 \x01(\x04R\x02id\x12 \n" + + "\vrecipientId\x18\x02 \x01(\x04R\vrecipientId\x12\x1a\n" + + "\barchived\x18\x03 \x01(\bR\barchived\x12%\n" + + "\vpinnedOrder\x18\x04 \x01(\rH\x00R\vpinnedOrder\x88\x01\x01\x121\n" + + "\x11expirationTimerMs\x18\x05 \x01(\x04H\x01R\x11expirationTimerMs\x88\x01\x01\x12%\n" + + "\vmuteUntilMs\x18\x06 \x01(\x04H\x02R\vmuteUntilMs\x88\x01\x01\x12\"\n" + + "\fmarkedUnread\x18\a \x01(\bR\fmarkedUnread\x12B\n" + + "\x1cdontNotifyForMentionsIfMuted\x18\b \x01(\bR\x1cdontNotifyForMentionsIfMuted\x12.\n" + + "\x05style\x18\t \x01(\v2\x18.signal.backup.ChatStyleR\x05style\x12.\n" + + "\x12expireTimerVersion\x18\n" + + " \x01(\rR\x12expireTimerVersionB\x0e\n" + + "\f_pinnedOrderB\x14\n" + + "\x12_expirationTimerMsB\x0e\n" + + "\f_muteUntilMs\"\x8f\x02\n" + + "\bCallLink\x12\x18\n" + + "\arootKey\x18\x01 \x01(\fR\arootKey\x12\x1f\n" + + "\badminKey\x18\x02 \x01(\fH\x00R\badminKey\x88\x01\x01\x12\x12\n" + + "\x04name\x18\x03 \x01(\tR\x04name\x12H\n" + + "\frestrictions\x18\x04 \x01(\x0e2$.signal.backup.CallLink.RestrictionsR\frestrictions\x12\"\n" + + "\fexpirationMs\x18\x05 \x01(\x04R\fexpirationMs\"9\n" + + "\fRestrictions\x12\v\n" + + "\aUNKNOWN\x10\x00\x12\b\n" + + "\x04NONE\x10\x01\x12\x12\n" + + "\x0eADMIN_APPROVAL\x10\x02B\v\n" + + "\t_adminKey\"\xca\x01\n" + + "\tAdHocCall\x12\x16\n" + + "\x06callId\x18\x01 \x01(\x04R\x06callId\x12 \n" + + "\vrecipientId\x18\x02 \x01(\x04R\vrecipientId\x124\n" + + "\x05state\x18\x03 \x01(\x0e2\x1e.signal.backup.AdHocCall.StateR\x05state\x12$\n" + + "\rcallTimestamp\x18\x04 \x01(\x04R\rcallTimestamp\"'\n" + + "\x05State\x12\x11\n" + + "\rUNKNOWN_STATE\x10\x00\x12\v\n" + + "\aGENERIC\x10\x01\"\xc5\x01\n" + + "\x14DistributionListItem\x12&\n" + + "\x0edistributionId\x18\x01 \x01(\fR\x0edistributionId\x12.\n" + + "\x11deletionTimestamp\x18\x02 \x01(\x04H\x00R\x11deletionTimestamp\x12M\n" + + "\x10distributionList\x18\x03 \x01(\v2\x1f.signal.backup.DistributionListH\x00R\x10distributionListB\x06\n" + + "\x04item\"\x8d\x02\n" + + "\x10DistributionList\x12\x12\n" + + "\x04name\x18\x01 \x01(\tR\x04name\x12\"\n" + + "\fallowReplies\x18\x02 \x01(\bR\fallowReplies\x12M\n" + + "\vprivacyMode\x18\x03 \x01(\x0e2+.signal.backup.DistributionList.PrivacyModeR\vprivacyMode\x12.\n" + + "\x12memberRecipientIds\x18\x04 \x03(\x04R\x12memberRecipientIds\"B\n" + + "\vPrivacyMode\x12\v\n" + + "\aUNKNOWN\x10\x00\x12\r\n" + + "\tONLY_WITH\x10\x01\x12\x0e\n" + + "\n" + + "ALL_EXCEPT\x10\x02\x12\a\n" + + "\x03ALL\x10\x03\"\xa4\f\n" + + "\bChatItem\x12\x16\n" + + "\x06chatId\x18\x01 \x01(\x04R\x06chatId\x12\x1a\n" + + "\bauthorId\x18\x02 \x01(\x04R\bauthorId\x12\x1a\n" + + "\bdateSent\x18\x03 \x01(\x04R\bdateSent\x12-\n" + + "\x0fexpireStartDate\x18\x04 \x01(\x04H\x02R\x0fexpireStartDate\x88\x01\x01\x12%\n" + + "\vexpiresInMs\x18\x05 \x01(\x04H\x03R\vexpiresInMs\x88\x01\x01\x125\n" + + "\trevisions\x18\x06 \x03(\v2\x17.signal.backup.ChatItemR\trevisions\x12\x10\n" + + "\x03sms\x18\a \x01(\bR\x03sms\x12L\n" + + "\bincoming\x18\b \x01(\v2..signal.backup.ChatItem.IncomingMessageDetailsH\x00R\bincoming\x12L\n" + + "\boutgoing\x18\t \x01(\v2..signal.backup.ChatItem.OutgoingMessageDetailsH\x00R\boutgoing\x12[\n" + + "\rdirectionless\x18\n" + + " \x01(\v23.signal.backup.ChatItem.DirectionlessMessageDetailsH\x00R\rdirectionless\x12J\n" + + "\x0fstandardMessage\x18\v \x01(\v2\x1e.signal.backup.StandardMessageH\x01R\x0fstandardMessage\x12G\n" + + "\x0econtactMessage\x18\f \x01(\v2\x1d.signal.backup.ContactMessageH\x01R\x0econtactMessage\x12G\n" + + "\x0estickerMessage\x18\r \x01(\v2\x1d.signal.backup.StickerMessageH\x01R\x0estickerMessage\x12Y\n" + + "\x14remoteDeletedMessage\x18\x0e \x01(\v2#.signal.backup.RemoteDeletedMessageH\x01R\x14remoteDeletedMessage\x12H\n" + + "\rupdateMessage\x18\x0f \x01(\v2 .signal.backup.ChatUpdateMessageH\x01R\rupdateMessage\x12V\n" + + "\x13paymentNotification\x18\x10 \x01(\v2\".signal.backup.PaymentNotificationH\x01R\x13paymentNotification\x128\n" + + "\tgiftBadge\x18\x11 \x01(\v2\x18.signal.backup.GiftBadgeH\x01R\tgiftBadge\x12J\n" + + "\x0fviewOnceMessage\x18\x12 \x01(\v2\x1e.signal.backup.ViewOnceMessageH\x01R\x0fviewOnceMessage\x12b\n" + + "\x17directStoryReplyMessage\x18\x13 \x01(\v2&.signal.backup.DirectStoryReplyMessageH\x01R\x17directStoryReplyMessage\x1a\xb4\x01\n" + + "\x16IncomingMessageDetails\x12\"\n" + + "\fdateReceived\x18\x01 \x01(\x04R\fdateReceived\x12+\n" + + "\x0edateServerSent\x18\x02 \x01(\x04H\x00R\x0edateServerSent\x88\x01\x01\x12\x12\n" + + "\x04read\x18\x03 \x01(\bR\x04read\x12\"\n" + + "\fsealedSender\x18\x04 \x01(\bR\fsealedSenderB\x11\n" + + "\x0f_dateServerSent\x1aS\n" + + "\x16OutgoingMessageDetails\x129\n" + + "\n" + + "sendStatus\x18\x01 \x03(\v2\x19.signal.backup.SendStatusR\n" + + "sendStatus\x1a\x1d\n" + + "\x1bDirectionlessMessageDetailsB\x14\n" + + "\x12directionalDetailsB\x06\n" + + "\x04itemB\x12\n" + + "\x10_expireStartDateB\x0e\n" + + "\f_expiresInMs\"\xeb\x06\n" + + "\n" + + "SendStatus\x12 \n" + + "\vrecipientId\x18\x01 \x01(\x04R\vrecipientId\x12\x1c\n" + + "\ttimestamp\x18\x02 \x01(\x04R\ttimestamp\x12=\n" + + "\apending\x18\x03 \x01(\v2!.signal.backup.SendStatus.PendingH\x00R\apending\x124\n" + + "\x04sent\x18\x04 \x01(\v2\x1e.signal.backup.SendStatus.SentH\x00R\x04sent\x12C\n" + + "\tdelivered\x18\x05 \x01(\v2#.signal.backup.SendStatus.DeliveredH\x00R\tdelivered\x124\n" + + "\x04read\x18\x06 \x01(\v2\x1e.signal.backup.SendStatus.ReadH\x00R\x04read\x12:\n" + + "\x06viewed\x18\a \x01(\v2 .signal.backup.SendStatus.ViewedH\x00R\x06viewed\x12=\n" + + "\askipped\x18\b \x01(\v2!.signal.backup.SendStatus.SkippedH\x00R\askipped\x12:\n" + + "\x06failed\x18\t \x01(\v2 .signal.backup.SendStatus.FailedH\x00R\x06failed\x1a\t\n" + + "\aPending\x1a*\n" + + "\x04Sent\x12\"\n" + + "\fsealedSender\x18\x01 \x01(\bR\fsealedSender\x1a/\n" + + "\tDelivered\x12\"\n" + + "\fsealedSender\x18\x01 \x01(\bR\fsealedSender\x1a*\n" + + "\x04Read\x12\"\n" + + "\fsealedSender\x18\x01 \x01(\bR\fsealedSender\x1a,\n" + + "\x06Viewed\x12\"\n" + + "\fsealedSender\x18\x01 \x01(\bR\fsealedSender\x1a\t\n" + + "\aSkipped\x1a\x96\x01\n" + + "\x06Failed\x12F\n" + + "\x06reason\x18\x01 \x01(\x0e2..signal.backup.SendStatus.Failed.FailureReasonR\x06reason\"D\n" + + "\rFailureReason\x12\v\n" + + "\aUNKNOWN\x10\x00\x12\v\n" + + "\aNETWORK\x10\x01\x12\x19\n" + + "\x15IDENTITY_KEY_MISMATCH\x10\x02B\x10\n" + + "\x0edeliveryStatus\"T\n" + + "\x04Text\x12\x12\n" + + "\x04body\x18\x01 \x01(\tR\x04body\x128\n" + + "\n" + + "bodyRanges\x18\x02 \x03(\v2\x18.signal.backup.BodyRangeR\n" + + "bodyRanges\"\x86\x03\n" + + "\x0fStandardMessage\x12/\n" + + "\x05quote\x18\x01 \x01(\v2\x14.signal.backup.QuoteH\x00R\x05quote\x88\x01\x01\x12,\n" + + "\x04text\x18\x02 \x01(\v2\x13.signal.backup.TextH\x01R\x04text\x88\x01\x01\x12B\n" + + "\vattachments\x18\x03 \x03(\v2 .signal.backup.MessageAttachmentR\vattachments\x12<\n" + + "\vlinkPreview\x18\x04 \x03(\v2\x1a.signal.backup.LinkPreviewR\vlinkPreview\x12;\n" + + "\blongText\x18\x05 \x01(\v2\x1a.signal.backup.FilePointerH\x02R\blongText\x88\x01\x01\x125\n" + + "\treactions\x18\x06 \x03(\v2\x17.signal.backup.ReactionR\treactionsB\b\n" + + "\x06_quoteB\a\n" + + "\x05_textB\v\n" + + "\t_longText\"\x83\x01\n" + + "\x0eContactMessage\x12:\n" + + "\acontact\x18\x01 \x01(\v2 .signal.backup.ContactAttachmentR\acontact\x125\n" + + "\treactions\x18\x02 \x03(\v2\x17.signal.backup.ReactionR\treactions\"\xb7\x02\n" + + "\x17DirectStoryReplyMessage\x12P\n" + + "\ttextReply\x18\x01 \x01(\v20.signal.backup.DirectStoryReplyMessage.TextReplyH\x00R\ttextReply\x12\x16\n" + + "\x05emoji\x18\x02 \x01(\tH\x00R\x05emoji\x125\n" + + "\treactions\x18\x03 \x03(\v2\x17.signal.backup.ReactionR\treactions\x1al\n" + + "\tTextReply\x12'\n" + + "\x04text\x18\x01 \x01(\v2\x13.signal.backup.TextR\x04text\x126\n" + + "\blongText\x18\x02 \x01(\v2\x1a.signal.backup.FilePointerR\blongTextB\a\n" + + "\x05replyJ\x04\b\x04\x10\x05\"\xdb\n" + + "\n" + + "\x13PaymentNotification\x12!\n" + + "\tamountMob\x18\x01 \x01(\tH\x00R\tamountMob\x88\x01\x01\x12\x1b\n" + + "\x06feeMob\x18\x02 \x01(\tH\x01R\x06feeMob\x88\x01\x01\x12\x17\n" + + "\x04note\x18\x03 \x01(\tH\x02R\x04note\x88\x01\x01\x12e\n" + + "\x12transactionDetails\x18\x04 \x01(\v25.signal.backup.PaymentNotification.TransactionDetailsR\x12transactionDetails\x1a\xe1\b\n" + + "\x12TransactionDetails\x12e\n" + + "\vtransaction\x18\x01 \x01(\v2A.signal.backup.PaymentNotification.TransactionDetails.TransactionH\x00R\vtransaction\x12w\n" + + "\x11failedTransaction\x18\x02 \x01(\v2G.signal.backup.PaymentNotification.TransactionDetails.FailedTransactionH\x00R\x11failedTransaction\x1aY\n" + + "\x1bMobileCoinTxoIdentification\x12\x1c\n" + + "\tpublicKey\x18\x01 \x03(\fR\tpublicKey\x12\x1c\n" + + "\tkeyImages\x18\x02 \x03(\fR\tkeyImages\x1a\xc5\x01\n" + + "\x11FailedTransaction\x12m\n" + + "\x06reason\x18\x01 \x01(\x0e2U.signal.backup.PaymentNotification.TransactionDetails.FailedTransaction.FailureReasonR\x06reason\"A\n" + + "\rFailureReason\x12\v\n" + + "\aGENERIC\x10\x00\x12\v\n" + + "\aNETWORK\x10\x01\x12\x16\n" + + "\x12INSUFFICIENT_FUNDS\x10\x02\x1a\xbc\x04\n" + + "\vTransaction\x12`\n" + + "\x06status\x18\x01 \x01(\x0e2H.signal.backup.PaymentNotification.TransactionDetails.Transaction.StatusR\x06status\x12\x8d\x01\n" + + "\x18mobileCoinIdentification\x18\x02 \x01(\v2Q.signal.backup.PaymentNotification.TransactionDetails.MobileCoinTxoIdentificationR\x18mobileCoinIdentification\x12!\n" + + "\ttimestamp\x18\x03 \x01(\x04H\x00R\ttimestamp\x88\x01\x01\x12#\n" + + "\n" + + "blockIndex\x18\x04 \x01(\x04H\x01R\n" + + "blockIndex\x88\x01\x01\x12+\n" + + "\x0eblockTimestamp\x18\x05 \x01(\x04H\x02R\x0eblockTimestamp\x88\x01\x01\x12%\n" + + "\vtransaction\x18\x06 \x01(\fH\x03R\vtransaction\x88\x01\x01\x12\x1d\n" + + "\areceipt\x18\a \x01(\fH\x04R\areceipt\x88\x01\x01\"4\n" + + "\x06Status\x12\v\n" + + "\aINITIAL\x10\x00\x12\r\n" + + "\tSUBMITTED\x10\x01\x12\x0e\n" + + "\n" + + "SUCCESSFUL\x10\x02B\f\n" + + "\n" + + "_timestampB\r\n" + + "\v_blockIndexB\x11\n" + + "\x0f_blockTimestampB\x0e\n" + + "\f_transactionB\n" + + "\n" + + "\b_receiptB\t\n" + + "\apaymentB\f\n" + + "\n" + + "_amountMobB\t\n" + + "\a_feeMobB\a\n" + + "\x05_note\"\xc4\x01\n" + + "\tGiftBadge\x12D\n" + + "\x1dreceiptCredentialPresentation\x18\x01 \x01(\fR\x1dreceiptCredentialPresentation\x124\n" + + "\x05state\x18\x02 \x01(\x0e2\x1e.signal.backup.GiftBadge.StateR\x05state\";\n" + + "\x05State\x12\f\n" + + "\bUNOPENED\x10\x00\x12\n" + + "\n" + + "\x06OPENED\x10\x01\x12\f\n" + + "\bREDEEMED\x10\x02\x12\n" + + "\n" + + "\x06FAILED\x10\x03\"\x8a\x01\n" + + "\x0fViewOnceMessage\x12@\n" + + "\n" + + "attachment\x18\x01 \x01(\v2 .signal.backup.MessageAttachmentR\n" + + "attachment\x125\n" + + "\treactions\x18\x02 \x03(\v2\x17.signal.backup.ReactionR\treactions\"\x89\n" + + "\n" + + "\x11ContactAttachment\x12>\n" + + "\x04name\x18\x01 \x01(\v2%.signal.backup.ContactAttachment.NameH\x00R\x04name\x88\x01\x01\x12>\n" + + "\x06number\x18\x03 \x03(\v2&.signal.backup.ContactAttachment.PhoneR\x06number\x12<\n" + + "\x05email\x18\x04 \x03(\v2&.signal.backup.ContactAttachment.EmailR\x05email\x12H\n" + + "\aaddress\x18\x05 \x03(\v2..signal.backup.ContactAttachment.PostalAddressR\aaddress\x127\n" + + "\x06avatar\x18\x06 \x01(\v2\x1a.signal.backup.FilePointerH\x01R\x06avatar\x88\x01\x01\x12\"\n" + + "\forganization\x18\a \x01(\tR\forganization\x1a\xb0\x01\n" + + "\x04Name\x12\x1c\n" + + "\tgivenName\x18\x01 \x01(\tR\tgivenName\x12\x1e\n" + + "\n" + + "familyName\x18\x02 \x01(\tR\n" + + "familyName\x12\x16\n" + + "\x06prefix\x18\x03 \x01(\tR\x06prefix\x12\x16\n" + + "\x06suffix\x18\x04 \x01(\tR\x06suffix\x12\x1e\n" + + "\n" + + "middleName\x18\x05 \x01(\tR\n" + + "middleName\x12\x1a\n" + + "\bnickname\x18\x06 \x01(\tR\bnickname\x1a\xb5\x01\n" + + "\x05Phone\x12\x14\n" + + "\x05value\x18\x01 \x01(\tR\x05value\x12?\n" + + "\x04type\x18\x02 \x01(\x0e2+.signal.backup.ContactAttachment.Phone.TypeR\x04type\x12\x14\n" + + "\x05label\x18\x03 \x01(\tR\x05label\"?\n" + + "\x04Type\x12\v\n" + + "\aUNKNOWN\x10\x00\x12\b\n" + + "\x04HOME\x10\x01\x12\n" + + "\n" + + "\x06MOBILE\x10\x02\x12\b\n" + + "\x04WORK\x10\x03\x12\n" + + "\n" + + "\x06CUSTOM\x10\x04\x1a\xb5\x01\n" + + "\x05Email\x12\x14\n" + + "\x05value\x18\x01 \x01(\tR\x05value\x12?\n" + + "\x04type\x18\x02 \x01(\x0e2+.signal.backup.ContactAttachment.Email.TypeR\x04type\x12\x14\n" + + "\x05label\x18\x03 \x01(\tR\x05label\"?\n" + + "\x04Type\x12\v\n" + + "\aUNKNOWN\x10\x00\x12\b\n" + + "\x04HOME\x10\x01\x12\n" + + "\n" + + "\x06MOBILE\x10\x02\x12\b\n" + + "\x04WORK\x10\x03\x12\n" + + "\n" + + "\x06CUSTOM\x10\x04\x1a\xd7\x02\n" + + "\rPostalAddress\x12G\n" + + "\x04type\x18\x01 \x01(\x0e23.signal.backup.ContactAttachment.PostalAddress.TypeR\x04type\x12\x14\n" + + "\x05label\x18\x02 \x01(\tR\x05label\x12\x16\n" + + "\x06street\x18\x03 \x01(\tR\x06street\x12\x14\n" + + "\x05pobox\x18\x04 \x01(\tR\x05pobox\x12\"\n" + + "\fneighborhood\x18\x05 \x01(\tR\fneighborhood\x12\x12\n" + + "\x04city\x18\x06 \x01(\tR\x04city\x12\x16\n" + + "\x06region\x18\a \x01(\tR\x06region\x12\x1a\n" + + "\bpostcode\x18\b \x01(\tR\bpostcode\x12\x18\n" + + "\acountry\x18\t \x01(\tR\acountry\"3\n" + + "\x04Type\x12\v\n" + + "\aUNKNOWN\x10\x00\x12\b\n" + + "\x04HOME\x10\x01\x12\b\n" + + "\x04WORK\x10\x02\x12\n" + + "\n" + + "\x06CUSTOM\x10\x03B\a\n" + + "\x05_nameB\t\n" + + "\a_avatar\"y\n" + + "\x0eStickerMessage\x120\n" + + "\asticker\x18\x01 \x01(\v2\x16.signal.backup.StickerR\asticker\x125\n" + + "\treactions\x18\x02 \x03(\v2\x17.signal.backup.ReactionR\treactions\"\x16\n" + + "\x14RemoteDeletedMessage\"\xae\x01\n" + + "\aSticker\x12\x16\n" + + "\x06packId\x18\x01 \x01(\fR\x06packId\x12\x18\n" + + "\apackKey\x18\x02 \x01(\fR\apackKey\x12\x1c\n" + + "\tstickerId\x18\x03 \x01(\rR\tstickerId\x12\x19\n" + + "\x05emoji\x18\x04 \x01(\tH\x00R\x05emoji\x88\x01\x01\x12.\n" + + "\x04data\x18\x05 \x01(\v2\x1a.signal.backup.FilePointerR\x04dataB\b\n" + + "\x06_emoji\"\xde\x01\n" + + "\vLinkPreview\x12\x10\n" + + "\x03url\x18\x01 \x01(\tR\x03url\x12\x19\n" + + "\x05title\x18\x02 \x01(\tH\x00R\x05title\x88\x01\x01\x125\n" + + "\x05image\x18\x03 \x01(\v2\x1a.signal.backup.FilePointerH\x01R\x05image\x88\x01\x01\x12%\n" + + "\vdescription\x18\x04 \x01(\tH\x02R\vdescription\x88\x01\x01\x12\x17\n" + + "\x04date\x18\x05 \x01(\x04H\x03R\x04date\x88\x01\x01B\b\n" + + "\x06_titleB\b\n" + + "\x06_imageB\x0e\n" + + "\f_descriptionB\a\n" + + "\x05_date\"\x9c\x02\n" + + "\x11MessageAttachment\x124\n" + + "\apointer\x18\x01 \x01(\v2\x1a.signal.backup.FilePointerR\apointer\x129\n" + + "\x04flag\x18\x02 \x01(\x0e2%.signal.backup.MessageAttachment.FlagR\x04flag\x12$\n" + + "\rwasDownloaded\x18\x03 \x01(\bR\rwasDownloaded\x12#\n" + + "\n" + + "clientUuid\x18\x04 \x01(\fH\x00R\n" + + "clientUuid\x88\x01\x01\"<\n" + + "\x04Flag\x12\b\n" + + "\x04NONE\x10\x00\x12\x11\n" + + "\rVOICE_MESSAGE\x10\x01\x12\x0e\n" + + "\n" + + "BORDERLESS\x10\x02\x12\a\n" + + "\x03GIF\x10\x03B\r\n" + + "\v_clientUuid\"\xec\t\n" + + "\vFilePointer\x12P\n" + + "\rbackupLocator\x18\x01 \x01(\v2(.signal.backup.FilePointer.BackupLocatorH\x00R\rbackupLocator\x12\\\n" + + "\x11attachmentLocator\x18\x02 \x01(\v2,.signal.backup.FilePointer.AttachmentLocatorH\x00R\x11attachmentLocator\x12q\n" + + "\x18invalidAttachmentLocator\x18\x03 \x01(\v23.signal.backup.FilePointer.InvalidAttachmentLocatorH\x00R\x18invalidAttachmentLocator\x12%\n" + + "\vcontentType\x18\x04 \x01(\tH\x01R\vcontentType\x88\x01\x01\x12+\n" + + "\x0eincrementalMac\x18\x05 \x01(\fH\x02R\x0eincrementalMac\x88\x01\x01\x12=\n" + + "\x17incrementalMacChunkSize\x18\x06 \x01(\rH\x03R\x17incrementalMacChunkSize\x88\x01\x01\x12\x1f\n" + + "\bfileName\x18\a \x01(\tH\x04R\bfileName\x88\x01\x01\x12\x19\n" + + "\x05width\x18\b \x01(\rH\x05R\x05width\x88\x01\x01\x12\x1b\n" + + "\x06height\x18\t \x01(\rH\x06R\x06height\x88\x01\x01\x12\x1d\n" + + "\acaption\x18\n" + + " \x01(\tH\aR\acaption\x88\x01\x01\x12\x1f\n" + + "\bblurHash\x18\v \x01(\tH\bR\bblurHash\x88\x01\x01\x1a\x9f\x02\n" + + "\rBackupLocator\x12\x1c\n" + + "\tmediaName\x18\x01 \x01(\tR\tmediaName\x12!\n" + + "\tcdnNumber\x18\x02 \x01(\rH\x00R\tcdnNumber\x88\x01\x01\x12\x10\n" + + "\x03key\x18\x03 \x01(\fR\x03key\x12\x16\n" + + "\x06digest\x18\x04 \x01(\fR\x06digest\x12\x12\n" + + "\x04size\x18\x05 \x01(\rR\x04size\x12)\n" + + "\rtransitCdnKey\x18\x06 \x01(\tH\x01R\rtransitCdnKey\x88\x01\x01\x12/\n" + + "\x10transitCdnNumber\x18\a \x01(\rH\x02R\x10transitCdnNumber\x88\x01\x01B\f\n" + + "\n" + + "_cdnNumberB\x10\n" + + "\x0e_transitCdnKeyB\x13\n" + + "\x11_transitCdnNumber\x1a\xca\x01\n" + + "\x11AttachmentLocator\x12\x16\n" + + "\x06cdnKey\x18\x01 \x01(\tR\x06cdnKey\x12\x1c\n" + + "\tcdnNumber\x18\x02 \x01(\rR\tcdnNumber\x12-\n" + + "\x0fuploadTimestamp\x18\x03 \x01(\x04H\x00R\x0fuploadTimestamp\x88\x01\x01\x12\x10\n" + + "\x03key\x18\x04 \x01(\fR\x03key\x12\x16\n" + + "\x06digest\x18\x05 \x01(\fR\x06digest\x12\x12\n" + + "\x04size\x18\x06 \x01(\rR\x04sizeB\x12\n" + + "\x10_uploadTimestamp\x1a\x1a\n" + + "\x18InvalidAttachmentLocatorB\t\n" + + "\alocatorB\x0e\n" + + "\f_contentTypeB\x11\n" + + "\x0f_incrementalMacB\x1a\n" + + "\x18_incrementalMacChunkSizeB\v\n" + + "\t_fileNameB\b\n" + + "\x06_widthB\t\n" + + "\a_heightB\n" + + "\n" + + "\b_captionB\v\n" + + "\t_blurHash\"\xae\x04\n" + + "\x05Quote\x125\n" + + "\x13targetSentTimestamp\x18\x01 \x01(\x04H\x00R\x13targetSentTimestamp\x88\x01\x01\x12\x1a\n" + + "\bauthorId\x18\x02 \x01(\x04R\bauthorId\x12,\n" + + "\x04text\x18\x03 \x01(\v2\x13.signal.backup.TextH\x01R\x04text\x88\x01\x01\x12G\n" + + "\vattachments\x18\x04 \x03(\v2%.signal.backup.Quote.QuotedAttachmentR\vattachments\x12-\n" + + "\x04type\x18\x05 \x01(\x0e2\x19.signal.backup.Quote.TypeR\x04type\x1a\xca\x01\n" + + "\x10QuotedAttachment\x12%\n" + + "\vcontentType\x18\x01 \x01(\tH\x00R\vcontentType\x88\x01\x01\x12\x1f\n" + + "\bfileName\x18\x02 \x01(\tH\x01R\bfileName\x88\x01\x01\x12C\n" + + "\tthumbnail\x18\x03 \x01(\v2 .signal.backup.MessageAttachmentH\x02R\tthumbnail\x88\x01\x01B\x0e\n" + + "\f_contentTypeB\v\n" + + "\t_fileNameB\f\n" + + "\n" + + "_thumbnail\">\n" + + "\x04Type\x12\v\n" + + "\aUNKNOWN\x10\x00\x12\n" + + "\n" + + "\x06NORMAL\x10\x01\x12\x0e\n" + + "\n" + + "GIFT_BADGE\x10\x02\x12\r\n" + + "\tVIEW_ONCE\x10\x03B\x16\n" + + "\x14_targetSentTimestampB\a\n" + + "\x05_text\"\xfe\x01\n" + + "\tBodyRange\x12\x14\n" + + "\x05start\x18\x01 \x01(\rR\x05start\x12\x16\n" + + "\x06length\x18\x02 \x01(\rR\x06length\x12 \n" + + "\n" + + "mentionAci\x18\x03 \x01(\fH\x00R\n" + + "mentionAci\x126\n" + + "\x05style\x18\x04 \x01(\x0e2\x1e.signal.backup.BodyRange.StyleH\x00R\x05style\"V\n" + + "\x05Style\x12\b\n" + + "\x04NONE\x10\x00\x12\b\n" + + "\x04BOLD\x10\x01\x12\n" + + "\n" + + "\x06ITALIC\x10\x02\x12\v\n" + + "\aSPOILER\x10\x03\x12\x11\n" + + "\rSTRIKETHROUGH\x10\x04\x12\r\n" + + "\tMONOSPACE\x10\x05B\x11\n" + + "\x0fassociatedValue\"\x80\x01\n" + + "\bReaction\x12\x14\n" + + "\x05emoji\x18\x01 \x01(\tR\x05emoji\x12\x1a\n" + + "\bauthorId\x18\x02 \x01(\x04R\bauthorId\x12$\n" + + "\rsentTimestamp\x18\x03 \x01(\x04R\rsentTimestamp\x12\x1c\n" + + "\tsortOrder\x18\x04 \x01(\x04R\tsortOrder\"\xe8\x05\n" + + "\x11ChatUpdateMessage\x12E\n" + + "\fsimpleUpdate\x18\x01 \x01(\v2\x1f.signal.backup.SimpleChatUpdateH\x00R\fsimpleUpdate\x12H\n" + + "\vgroupChange\x18\x02 \x01(\v2$.signal.backup.GroupChangeChatUpdateH\x00R\vgroupChange\x12`\n" + + "\x15expirationTimerChange\x18\x03 \x01(\v2(.signal.backup.ExpirationTimerChatUpdateH\x00R\x15expirationTimerChange\x12N\n" + + "\rprofileChange\x18\x04 \x01(\v2&.signal.backup.ProfileChangeChatUpdateH\x00R\rprofileChange\x12H\n" + + "\vthreadMerge\x18\x05 \x01(\v2$.signal.backup.ThreadMergeChatUpdateH\x00R\vthreadMerge\x12Z\n" + + "\x11sessionSwitchover\x18\x06 \x01(\v2*.signal.backup.SessionSwitchoverChatUpdateH\x00R\x11sessionSwitchover\x12G\n" + + "\x0eindividualCall\x18\a \x01(\v2\x1d.signal.backup.IndividualCallH\x00R\x0eindividualCall\x128\n" + + "\tgroupCall\x18\b \x01(\v2\x18.signal.backup.GroupCallH\x00R\tgroupCall\x12]\n" + + "\x14learnedProfileChange\x18\t \x01(\v2'.signal.backup.LearnedProfileChatUpdateH\x00R\x14learnedProfileChangeB\b\n" + + "\x06update\"\x9d\x04\n" + + "\x0eIndividualCall\x12\x1b\n" + + "\x06callId\x18\x01 \x01(\x04H\x00R\x06callId\x88\x01\x01\x126\n" + + "\x04type\x18\x02 \x01(\x0e2\".signal.backup.IndividualCall.TypeR\x04type\x12E\n" + + "\tdirection\x18\x03 \x01(\x0e2'.signal.backup.IndividualCall.DirectionR\tdirection\x129\n" + + "\x05state\x18\x04 \x01(\x0e2#.signal.backup.IndividualCall.StateR\x05state\x122\n" + + "\x14startedCallTimestamp\x18\x05 \x01(\x04R\x14startedCallTimestamp\x12\x12\n" + + "\x04read\x18\x06 \x01(\bR\x04read\"8\n" + + "\x04Type\x12\x10\n" + + "\fUNKNOWN_TYPE\x10\x00\x12\x0e\n" + + "\n" + + "AUDIO_CALL\x10\x01\x12\x0e\n" + + "\n" + + "VIDEO_CALL\x10\x02\">\n" + + "\tDirection\x12\x15\n" + + "\x11UNKNOWN_DIRECTION\x10\x00\x12\f\n" + + "\bINCOMING\x10\x01\x12\f\n" + + "\bOUTGOING\x10\x02\"g\n" + + "\x05State\x12\x11\n" + + "\rUNKNOWN_STATE\x10\x00\x12\f\n" + + "\bACCEPTED\x10\x01\x12\x10\n" + + "\fNOT_ACCEPTED\x10\x02\x12\n" + + "\n" + + "\x06MISSED\x10\x03\x12\x1f\n" + + "\x1bMISSED_NOTIFICATION_PROFILE\x10\x04B\t\n" + + "\a_callId\"\xbd\x04\n" + + "\tGroupCall\x12\x1b\n" + + "\x06callId\x18\x01 \x01(\x04H\x00R\x06callId\x88\x01\x01\x124\n" + + "\x05state\x18\x02 \x01(\x0e2\x1e.signal.backup.GroupCall.StateR\x05state\x121\n" + + "\x11ringerRecipientId\x18\x03 \x01(\x04H\x01R\x11ringerRecipientId\x88\x01\x01\x12;\n" + + "\x16startedCallRecipientId\x18\x04 \x01(\x04H\x02R\x16startedCallRecipientId\x88\x01\x01\x122\n" + + "\x14startedCallTimestamp\x18\x05 \x01(\x04R\x14startedCallTimestamp\x123\n" + + "\x12endedCallTimestamp\x18\x06 \x01(\x04H\x03R\x12endedCallTimestamp\x88\x01\x01\x12\x12\n" + + "\x04read\x18\a \x01(\bR\x04read\"\x9c\x01\n" + + "\x05State\x12\x11\n" + + "\rUNKNOWN_STATE\x10\x00\x12\v\n" + + "\aGENERIC\x10\x01\x12\n" + + "\n" + + "\x06JOINED\x10\x02\x12\v\n" + + "\aRINGING\x10\x03\x12\f\n" + + "\bACCEPTED\x10\x04\x12\f\n" + + "\bDECLINED\x10\x05\x12\n" + + "\n" + + "\x06MISSED\x10\x06\x12\x1f\n" + + "\x1bMISSED_NOTIFICATION_PROFILE\x10\a\x12\x11\n" + + "\rOUTGOING_RING\x10\bB\t\n" + + "\a_callIdB\x14\n" + + "\x12_ringerRecipientIdB\x19\n" + + "\x17_startedCallRecipientIdB\x15\n" + + "\x13_endedCallTimestamp\"\xd3\x03\n" + + "\x10SimpleChatUpdate\x128\n" + + "\x04type\x18\x01 \x01(\x0e2$.signal.backup.SimpleChatUpdate.TypeR\x04type\"\x84\x03\n" + + "\x04Type\x12\v\n" + + "\aUNKNOWN\x10\x00\x12\x11\n" + + "\rJOINED_SIGNAL\x10\x01\x12\x13\n" + + "\x0fIDENTITY_UPDATE\x10\x02\x12\x15\n" + + "\x11IDENTITY_VERIFIED\x10\x03\x12\x14\n" + + "\x10IDENTITY_DEFAULT\x10\x04\x12\x11\n" + + "\rCHANGE_NUMBER\x10\x05\x12$\n" + + " RELEASE_CHANNEL_DONATION_REQUEST\x10\x06\x12\x0f\n" + + "\vEND_SESSION\x10\a\x12\x18\n" + + "\x14CHAT_SESSION_REFRESH\x10\b\x12\x0f\n" + + "\vBAD_DECRYPT\x10\t\x12\x16\n" + + "\x12PAYMENTS_ACTIVATED\x10\n" + + "\x12\x1e\n" + + "\x1aPAYMENT_ACTIVATION_REQUEST\x10\v\x12 \n" + + "\x1cUNSUPPORTED_PROTOCOL_MESSAGE\x10\f\x12\x11\n" + + "\rREPORTED_SPAM\x10\r\x12\v\n" + + "\aBLOCKED\x10\x0e\x12\r\n" + + "\tUNBLOCKED\x10\x0f\x12\x1c\n" + + "\x18MESSAGE_REQUEST_ACCEPTED\x10\x10\"=\n" + + "\x19ExpirationTimerChatUpdate\x12 \n" + + "\vexpiresInMs\x18\x01 \x01(\x04R\vexpiresInMs\"W\n" + + "\x17ProfileChangeChatUpdate\x12\"\n" + + "\fpreviousName\x18\x01 \x01(\tR\fpreviousName\x12\x18\n" + + "\anewName\x18\x02 \x01(\tR\anewName\"^\n" + + "\x18LearnedProfileChatUpdate\x12\x14\n" + + "\x04e164\x18\x01 \x01(\x04H\x00R\x04e164\x12\x1c\n" + + "\busername\x18\x02 \x01(\tH\x00R\busernameB\x0e\n" + + "\fpreviousName\";\n" + + "\x15ThreadMergeChatUpdate\x12\"\n" + + "\fpreviousE164\x18\x01 \x01(\x04R\fpreviousE164\"1\n" + + "\x1bSessionSwitchoverChatUpdate\x12\x12\n" + + "\x04e164\x18\x01 \x01(\x04R\x04e164\"\x86\x1f\n" + + "\x15GroupChangeChatUpdate\x12E\n" + + "\aupdates\x18\x01 \x03(\v2+.signal.backup.GroupChangeChatUpdate.UpdateR\aupdates\x1a\xa5\x1e\n" + + "\x06Update\x12S\n" + + "\x12genericGroupUpdate\x18\x01 \x01(\v2!.signal.backup.GenericGroupUpdateH\x00R\x12genericGroupUpdate\x12V\n" + + "\x13groupCreationUpdate\x18\x02 \x01(\v2\".signal.backup.GroupCreationUpdateH\x00R\x13groupCreationUpdate\x12J\n" + + "\x0fgroupNameUpdate\x18\x03 \x01(\v2\x1e.signal.backup.GroupNameUpdateH\x00R\x0fgroupNameUpdate\x12P\n" + + "\x11groupAvatarUpdate\x18\x04 \x01(\v2 .signal.backup.GroupAvatarUpdateH\x00R\x11groupAvatarUpdate\x12_\n" + + "\x16groupDescriptionUpdate\x18\x05 \x01(\v2%.signal.backup.GroupDescriptionUpdateH\x00R\x16groupDescriptionUpdate\x12\x8f\x01\n" + + "&groupMembershipAccessLevelChangeUpdate\x18\x06 \x01(\v25.signal.backup.GroupMembershipAccessLevelChangeUpdateH\x00R&groupMembershipAccessLevelChangeUpdate\x12\x8f\x01\n" + + "&groupAttributesAccessLevelChangeUpdate\x18\a \x01(\v25.signal.backup.GroupAttributesAccessLevelChangeUpdateH\x00R&groupAttributesAccessLevelChangeUpdate\x12\x80\x01\n" + + "!groupAnnouncementOnlyChangeUpdate\x18\b \x01(\v20.signal.backup.GroupAnnouncementOnlyChangeUpdateH\x00R!groupAnnouncementOnlyChangeUpdate\x12_\n" + + "\x16groupAdminStatusUpdate\x18\t \x01(\v2%.signal.backup.GroupAdminStatusUpdateH\x00R\x16groupAdminStatusUpdate\x12\\\n" + + "\x15groupMemberLeftUpdate\x18\n" + + " \x01(\v2$.signal.backup.GroupMemberLeftUpdateH\x00R\x15groupMemberLeftUpdate\x12e\n" + + "\x18groupMemberRemovedUpdate\x18\v \x01(\v2'.signal.backup.GroupMemberRemovedUpdateH\x00R\x18groupMemberRemovedUpdate\x12e\n" + + "\x18selfInvitedToGroupUpdate\x18\f \x01(\v2'.signal.backup.SelfInvitedToGroupUpdateH\x00R\x18selfInvitedToGroupUpdate\x12\x80\x01\n" + + "!selfInvitedOtherUserToGroupUpdate\x18\r \x01(\v20.signal.backup.SelfInvitedOtherUserToGroupUpdateH\x00R!selfInvitedOtherUserToGroupUpdate\x12h\n" + + "\x19groupUnknownInviteeUpdate\x18\x0e \x01(\v2(.signal.backup.GroupUnknownInviteeUpdateH\x00R\x19groupUnknownInviteeUpdate\x12t\n" + + "\x1dgroupInvitationAcceptedUpdate\x18\x0f \x01(\v2,.signal.backup.GroupInvitationAcceptedUpdateH\x00R\x1dgroupInvitationAcceptedUpdate\x12t\n" + + "\x1dgroupInvitationDeclinedUpdate\x18\x10 \x01(\v2,.signal.backup.GroupInvitationDeclinedUpdateH\x00R\x1dgroupInvitationDeclinedUpdate\x12b\n" + + "\x17groupMemberJoinedUpdate\x18\x11 \x01(\v2&.signal.backup.GroupMemberJoinedUpdateH\x00R\x17groupMemberJoinedUpdate\x12_\n" + + "\x16groupMemberAddedUpdate\x18\x12 \x01(\v2%.signal.backup.GroupMemberAddedUpdateH\x00R\x16groupMemberAddedUpdate\x12}\n" + + " groupSelfInvitationRevokedUpdate\x18\x13 \x01(\v2/.signal.backup.GroupSelfInvitationRevokedUpdateH\x00R groupSelfInvitationRevokedUpdate\x12q\n" + + "\x1cgroupInvitationRevokedUpdate\x18\x14 \x01(\v2+.signal.backup.GroupInvitationRevokedUpdateH\x00R\x1cgroupInvitationRevokedUpdate\x12_\n" + + "\x16groupJoinRequestUpdate\x18\x15 \x01(\v2%.signal.backup.GroupJoinRequestUpdateH\x00R\x16groupJoinRequestUpdate\x12w\n" + + "\x1egroupJoinRequestApprovalUpdate\x18\x16 \x01(\v2-.signal.backup.GroupJoinRequestApprovalUpdateH\x00R\x1egroupJoinRequestApprovalUpdate\x12w\n" + + "\x1egroupJoinRequestCanceledUpdate\x18\x17 \x01(\v2-.signal.backup.GroupJoinRequestCanceledUpdateH\x00R\x1egroupJoinRequestCanceledUpdate\x12k\n" + + "\x1agroupInviteLinkResetUpdate\x18\x18 \x01(\v2).signal.backup.GroupInviteLinkResetUpdateH\x00R\x1agroupInviteLinkResetUpdate\x12q\n" + + "\x1cgroupInviteLinkEnabledUpdate\x18\x19 \x01(\v2+.signal.backup.GroupInviteLinkEnabledUpdateH\x00R\x1cgroupInviteLinkEnabledUpdate\x12\x83\x01\n" + + "\"groupInviteLinkAdminApprovalUpdate\x18\x1a \x01(\v21.signal.backup.GroupInviteLinkAdminApprovalUpdateH\x00R\"groupInviteLinkAdminApprovalUpdate\x12t\n" + + "\x1dgroupInviteLinkDisabledUpdate\x18\x1b \x01(\v2,.signal.backup.GroupInviteLinkDisabledUpdateH\x00R\x1dgroupInviteLinkDisabledUpdate\x12t\n" + + "\x1dgroupMemberJoinedByLinkUpdate\x18\x1c \x01(\v2,.signal.backup.GroupMemberJoinedByLinkUpdateH\x00R\x1dgroupMemberJoinedByLinkUpdate\x12_\n" + + "\x16groupV2MigrationUpdate\x18\x1d \x01(\v2%.signal.backup.GroupV2MigrationUpdateH\x00R\x16groupV2MigrationUpdate\x12\x80\x01\n" + + "!groupV2MigrationSelfInvitedUpdate\x18\x1e \x01(\v20.signal.backup.GroupV2MigrationSelfInvitedUpdateH\x00R!groupV2MigrationSelfInvitedUpdate\x12\x89\x01\n" + + "$groupV2MigrationInvitedMembersUpdate\x18\x1f \x01(\v23.signal.backup.GroupV2MigrationInvitedMembersUpdateH\x00R$groupV2MigrationInvitedMembersUpdate\x12\x89\x01\n" + + "$groupV2MigrationDroppedMembersUpdate\x18 \x01(\v23.signal.backup.GroupV2MigrationDroppedMembersUpdateH\x00R$groupV2MigrationDroppedMembersUpdate\x12\x92\x01\n" + + "'groupSequenceOfRequestsAndCancelsUpdate\x18! \x01(\v26.signal.backup.GroupSequenceOfRequestsAndCancelsUpdateH\x00R'groupSequenceOfRequestsAndCancelsUpdate\x12k\n" + + "\x1agroupExpirationTimerUpdate\x18\" \x01(\v2).signal.backup.GroupExpirationTimerUpdateH\x00R\x1agroupExpirationTimerUpdateB\b\n" + + "\x06update\"H\n" + + "\x12GenericGroupUpdate\x12#\n" + + "\n" + + "updaterAci\x18\x01 \x01(\fH\x00R\n" + + "updaterAci\x88\x01\x01B\r\n" + + "\v_updaterAci\"I\n" + + "\x13GroupCreationUpdate\x12#\n" + + "\n" + + "updaterAci\x18\x01 \x01(\fH\x00R\n" + + "updaterAci\x88\x01\x01B\r\n" + + "\v_updaterAci\"\x7f\n" + + "\x0fGroupNameUpdate\x12#\n" + + "\n" + + "updaterAci\x18\x01 \x01(\fH\x00R\n" + + "updaterAci\x88\x01\x01\x12'\n" + + "\fnewGroupName\x18\x02 \x01(\tH\x01R\fnewGroupName\x88\x01\x01B\r\n" + + "\v_updaterAciB\x0f\n" + + "\r_newGroupName\"g\n" + + "\x11GroupAvatarUpdate\x12#\n" + + "\n" + + "updaterAci\x18\x01 \x01(\fH\x00R\n" + + "updaterAci\x88\x01\x01\x12\x1e\n" + + "\n" + + "wasRemoved\x18\x02 \x01(\bR\n" + + "wasRemovedB\r\n" + + "\v_updaterAci\"\x8c\x01\n" + + "\x16GroupDescriptionUpdate\x12#\n" + + "\n" + + "updaterAci\x18\x01 \x01(\fH\x00R\n" + + "updaterAci\x88\x01\x01\x12+\n" + + "\x0enewDescription\x18\x02 \x01(\tH\x01R\x0enewDescription\x88\x01\x01B\r\n" + + "\v_updaterAciB\x11\n" + + "\x0f_newDescription\"\xa1\x01\n" + + "&GroupMembershipAccessLevelChangeUpdate\x12#\n" + + "\n" + + "updaterAci\x18\x01 \x01(\fH\x00R\n" + + "updaterAci\x88\x01\x01\x12C\n" + + "\vaccessLevel\x18\x02 \x01(\x0e2!.signal.backup.GroupV2AccessLevelR\vaccessLevelB\r\n" + + "\v_updaterAci\"\xa1\x01\n" + + "&GroupAttributesAccessLevelChangeUpdate\x12#\n" + + "\n" + + "updaterAci\x18\x01 \x01(\fH\x00R\n" + + "updaterAci\x88\x01\x01\x12C\n" + + "\vaccessLevel\x18\x02 \x01(\x0e2!.signal.backup.GroupV2AccessLevelR\vaccessLevelB\r\n" + + "\v_updaterAci\"\x87\x01\n" + + "!GroupAnnouncementOnlyChangeUpdate\x12#\n" + + "\n" + + "updaterAci\x18\x01 \x01(\fH\x00R\n" + + "updaterAci\x88\x01\x01\x12.\n" + + "\x12isAnnouncementOnly\x18\x02 \x01(\bR\x12isAnnouncementOnlyB\r\n" + + "\v_updaterAci\"\xa0\x01\n" + + "\x16GroupAdminStatusUpdate\x12#\n" + + "\n" + + "updaterAci\x18\x01 \x01(\fH\x00R\n" + + "updaterAci\x88\x01\x01\x12\x1c\n" + + "\tmemberAci\x18\x02 \x01(\fR\tmemberAci\x124\n" + + "\x15wasAdminStatusGranted\x18\x03 \x01(\bR\x15wasAdminStatusGrantedB\r\n" + + "\v_updaterAci\")\n" + + "\x15GroupMemberLeftUpdate\x12\x10\n" + + "\x03aci\x18\x01 \x01(\fR\x03aci\"n\n" + + "\x18GroupMemberRemovedUpdate\x12#\n" + + "\n" + + "removerAci\x18\x01 \x01(\fH\x00R\n" + + "removerAci\x88\x01\x01\x12\x1e\n" + + "\n" + + "removedAci\x18\x02 \x01(\fR\n" + + "removedAciB\r\n" + + "\v_removerAci\"N\n" + + "\x18SelfInvitedToGroupUpdate\x12#\n" + + "\n" + + "inviterAci\x18\x01 \x01(\fH\x00R\n" + + "inviterAci\x88\x01\x01B\r\n" + + "\v_inviterAci\"O\n" + + "!SelfInvitedOtherUserToGroupUpdate\x12*\n" + + "\x10inviteeServiceId\x18\x01 \x01(\fR\x10inviteeServiceId\"s\n" + + "\x19GroupUnknownInviteeUpdate\x12#\n" + + "\n" + + "inviterAci\x18\x01 \x01(\fH\x00R\n" + + "inviterAci\x88\x01\x01\x12\"\n" + + "\finviteeCount\x18\x02 \x01(\rR\finviteeCountB\r\n" + + "\v_inviterAci\"w\n" + + "\x1dGroupInvitationAcceptedUpdate\x12#\n" + + "\n" + + "inviterAci\x18\x01 \x01(\fH\x00R\n" + + "inviterAci\x88\x01\x01\x12\"\n" + + "\fnewMemberAci\x18\x02 \x01(\fR\fnewMemberAciB\r\n" + + "\v_inviterAci\"\x87\x01\n" + + "\x1dGroupInvitationDeclinedUpdate\x12#\n" + + "\n" + + "inviterAci\x18\x01 \x01(\fH\x00R\n" + + "inviterAci\x88\x01\x01\x12#\n" + + "\n" + + "inviteeAci\x18\x02 \x01(\fH\x01R\n" + + "inviteeAci\x88\x01\x01B\r\n" + + "\v_inviterAciB\r\n" + + "\v_inviteeAci\"=\n" + + "\x17GroupMemberJoinedUpdate\x12\"\n" + + "\fnewMemberAci\x18\x01 \x01(\fR\fnewMemberAci\"\xd2\x01\n" + + "\x16GroupMemberAddedUpdate\x12#\n" + + "\n" + + "updaterAci\x18\x01 \x01(\fH\x00R\n" + + "updaterAci\x88\x01\x01\x12\"\n" + + "\fnewMemberAci\x18\x02 \x01(\fR\fnewMemberAci\x12,\n" + + "\x11hadOpenInvitation\x18\x03 \x01(\bR\x11hadOpenInvitation\x12#\n" + + "\n" + + "inviterAci\x18\x04 \x01(\fH\x01R\n" + + "inviterAci\x88\x01\x01B\r\n" + + "\v_updaterAciB\r\n" + + "\v_inviterAci\"V\n" + + " GroupSelfInvitationRevokedUpdate\x12#\n" + + "\n" + + "revokerAci\x18\x01 \x01(\fH\x00R\n" + + "revokerAci\x88\x01\x01B\r\n" + + "\v_revokerAci\"\xcb\x02\n" + + "\x1cGroupInvitationRevokedUpdate\x12#\n" + + "\n" + + "updaterAci\x18\x01 \x01(\fH\x00R\n" + + "updaterAci\x88\x01\x01\x12O\n" + + "\binvitees\x18\x02 \x03(\v23.signal.backup.GroupInvitationRevokedUpdate.InviteeR\binvitees\x1a\xa5\x01\n" + + "\aInvitee\x12#\n" + + "\n" + + "inviterAci\x18\x01 \x01(\fH\x00R\n" + + "inviterAci\x88\x01\x01\x12#\n" + + "\n" + + "inviteeAci\x18\x02 \x01(\fH\x01R\n" + + "inviteeAci\x88\x01\x01\x12#\n" + + "\n" + + "inviteePni\x18\x03 \x01(\fH\x02R\n" + + "inviteePni\x88\x01\x01B\r\n" + + "\v_inviterAciB\r\n" + + "\v_inviteeAciB\r\n" + + "\v_inviteePniB\r\n" + + "\v_updaterAci\"<\n" + + "\x16GroupJoinRequestUpdate\x12\"\n" + + "\frequestorAci\x18\x01 \x01(\fR\frequestorAci\"\x9a\x01\n" + + "\x1eGroupJoinRequestApprovalUpdate\x12\"\n" + + "\frequestorAci\x18\x01 \x01(\fR\frequestorAci\x12#\n" + + "\n" + + "updaterAci\x18\x02 \x01(\fH\x00R\n" + + "updaterAci\x88\x01\x01\x12 \n" + + "\vwasApproved\x18\x03 \x01(\bR\vwasApprovedB\r\n" + + "\v_updaterAci\"D\n" + + "\x1eGroupJoinRequestCanceledUpdate\x12\"\n" + + "\frequestorAci\x18\x01 \x01(\fR\frequestorAci\"c\n" + + "'GroupSequenceOfRequestsAndCancelsUpdate\x12\"\n" + + "\frequestorAci\x18\x01 \x01(\fR\frequestorAci\x12\x14\n" + + "\x05count\x18\x02 \x01(\rR\x05count\"P\n" + + "\x1aGroupInviteLinkResetUpdate\x12#\n" + + "\n" + + "updaterAci\x18\x01 \x01(\fH\x00R\n" + + "updaterAci\x88\x01\x01B\r\n" + + "\v_updaterAci\"\x90\x01\n" + + "\x1cGroupInviteLinkEnabledUpdate\x12#\n" + + "\n" + + "updaterAci\x18\x01 \x01(\fH\x00R\n" + + "updaterAci\x88\x01\x01\x12<\n" + + "\x19linkRequiresAdminApproval\x18\x02 \x01(\bR\x19linkRequiresAdminApprovalB\r\n" + + "\v_updaterAci\"\x96\x01\n" + + "\"GroupInviteLinkAdminApprovalUpdate\x12#\n" + + "\n" + + "updaterAci\x18\x01 \x01(\fH\x00R\n" + + "updaterAci\x88\x01\x01\x12<\n" + + "\x19linkRequiresAdminApproval\x18\x02 \x01(\bR\x19linkRequiresAdminApprovalB\r\n" + + "\v_updaterAci\"S\n" + + "\x1dGroupInviteLinkDisabledUpdate\x12#\n" + + "\n" + + "updaterAci\x18\x01 \x01(\fH\x00R\n" + + "updaterAci\x88\x01\x01B\r\n" + + "\v_updaterAci\"C\n" + + "\x1dGroupMemberJoinedByLinkUpdate\x12\"\n" + + "\fnewMemberAci\x18\x01 \x01(\fR\fnewMemberAci\"\x18\n" + + "\x16GroupV2MigrationUpdate\"#\n" + + "!GroupV2MigrationSelfInvitedUpdate\"X\n" + + "$GroupV2MigrationInvitedMembersUpdate\x120\n" + + "\x13invitedMembersCount\x18\x01 \x01(\rR\x13invitedMembersCount\"X\n" + + "$GroupV2MigrationDroppedMembersUpdate\x120\n" + + "\x13droppedMembersCount\x18\x01 \x01(\rR\x13droppedMembersCount\"r\n" + + "\x1aGroupExpirationTimerUpdate\x12 \n" + + "\vexpiresInMs\x18\x01 \x01(\x04R\vexpiresInMs\x12#\n" + + "\n" + + "updaterAci\x18\x02 \x01(\fH\x00R\n" + + "updaterAci\x88\x01\x01B\r\n" + + "\v_updaterAci\"?\n" + + "\vStickerPack\x12\x16\n" + + "\x06packId\x18\x01 \x01(\fR\x06packId\x12\x18\n" + + "\apackKey\x18\x02 \x01(\fR\apackKey\"\x80\r\n" + + "\tChatStyle\x12T\n" + + "\x0fwallpaperPreset\x18\x01 \x01(\x0e2(.signal.backup.ChatStyle.WallpaperPresetH\x00R\x0fwallpaperPreset\x12D\n" + + "\x0ewallpaperPhoto\x18\x02 \x01(\v2\x1a.signal.backup.FilePointerH\x00R\x0ewallpaperPhoto\x12Y\n" + + "\x0fautoBubbleColor\x18\x03 \x01(\v2-.signal.backup.ChatStyle.AutomaticBubbleColorH\x01R\x0fautoBubbleColor\x12Z\n" + + "\x11bubbleColorPreset\x18\x04 \x01(\x0e2*.signal.backup.ChatStyle.BubbleColorPresetH\x01R\x11bubbleColorPreset\x12&\n" + + "\rcustomColorId\x18\x05 \x01(\x04H\x01R\rcustomColorId\x126\n" + + "\x16dimWallpaperInDarkMode\x18\a \x01(\bR\x16dimWallpaperInDarkMode\x1aV\n" + + "\bGradient\x12\x14\n" + + "\x05angle\x18\x01 \x01(\rR\x05angle\x12\x16\n" + + "\x06colors\x18\x02 \x03(\aR\x06colors\x12\x1c\n" + + "\tpositions\x18\x03 \x03(\x02R\tpositions\x1a\x83\x01\n" + + "\x0fCustomChatColor\x12\x0e\n" + + "\x02id\x18\x01 \x01(\x04R\x02id\x12\x16\n" + + "\x05solid\x18\x02 \x01(\aH\x00R\x05solid\x12?\n" + + "\bgradient\x18\x03 \x01(\v2!.signal.backup.ChatStyle.GradientH\x00R\bgradientB\a\n" + + "\x05color\x1a\x16\n" + + "\x14AutomaticBubbleColor\"\xc1\x03\n" + + "\x0fWallpaperPreset\x12\x1c\n" + + "\x18UNKNOWN_WALLPAPER_PRESET\x10\x00\x12\x0f\n" + + "\vSOLID_BLUSH\x10\x01\x12\x10\n" + + "\fSOLID_COPPER\x10\x02\x12\x0e\n" + + "\n" + + "SOLID_DUST\x10\x03\x12\x11\n" + + "\rSOLID_CELADON\x10\x04\x12\x14\n" + + "\x10SOLID_RAINFOREST\x10\x05\x12\x11\n" + + "\rSOLID_PACIFIC\x10\x06\x12\x0f\n" + + "\vSOLID_FROST\x10\a\x12\x0e\n" + + "\n" + + "SOLID_NAVY\x10\b\x12\x0f\n" + + "\vSOLID_LILAC\x10\t\x12\x0e\n" + + "\n" + + "SOLID_PINK\x10\n" + + "\x12\x12\n" + + "\x0eSOLID_EGGPLANT\x10\v\x12\x10\n" + + "\fSOLID_SILVER\x10\f\x12\x13\n" + + "\x0fGRADIENT_SUNSET\x10\r\x12\x11\n" + + "\rGRADIENT_NOIR\x10\x0e\x12\x14\n" + + "\x10GRADIENT_HEATMAP\x10\x0f\x12\x11\n" + + "\rGRADIENT_AQUA\x10\x10\x12\x17\n" + + "\x13GRADIENT_IRIDESCENT\x10\x11\x12\x15\n" + + "\x11GRADIENT_MONSTERA\x10\x12\x12\x12\n" + + "\x0eGRADIENT_BLISS\x10\x13\x12\x10\n" + + "\fGRADIENT_SKY\x10\x14\x12\x12\n" + + "\x0eGRADIENT_PEACH\x10\x15\"\xe9\x03\n" + + "\x11BubbleColorPreset\x12\x1f\n" + + "\x1bUNKNOWN_BUBBLE_COLOR_PRESET\x10\x00\x12\x15\n" + + "\x11SOLID_ULTRAMARINE\x10\x01\x12\x11\n" + + "\rSOLID_CRIMSON\x10\x02\x12\x13\n" + + "\x0fSOLID_VERMILION\x10\x03\x12\x10\n" + + "\fSOLID_BURLAP\x10\x04\x12\x10\n" + + "\fSOLID_FOREST\x10\x05\x12\x15\n" + + "\x11SOLID_WINTERGREEN\x10\x06\x12\x0e\n" + + "\n" + + "SOLID_TEAL\x10\a\x12\x0e\n" + + "\n" + + "SOLID_BLUE\x10\b\x12\x10\n" + + "\fSOLID_INDIGO\x10\t\x12\x10\n" + + "\fSOLID_VIOLET\x10\n" + + "\x12\x0e\n" + + "\n" + + "SOLID_PLUM\x10\v\x12\x0f\n" + + "\vSOLID_TAUPE\x10\f\x12\x0f\n" + + "\vSOLID_STEEL\x10\r\x12\x12\n" + + "\x0eGRADIENT_EMBER\x10\x0e\x12\x15\n" + + "\x11GRADIENT_MIDNIGHT\x10\x0f\x12\x15\n" + + "\x11GRADIENT_INFRARED\x10\x10\x12\x13\n" + + "\x0fGRADIENT_LAGOON\x10\x11\x12\x18\n" + + "\x14GRADIENT_FLUORESCENT\x10\x12\x12\x12\n" + + "\x0eGRADIENT_BASIL\x10\x13\x12\x14\n" + + "\x10GRADIENT_SUBLIME\x10\x14\x12\x10\n" + + "\fGRADIENT_SEA\x10\x15\x12\x16\n" + + "\x12GRADIENT_TANGERINE\x10\x16B\v\n" + + "\twallpaperB\r\n" + + "\vbubbleColor\"\xd8\x04\n" + + "\x13NotificationProfile\x12\x12\n" + + "\x04name\x18\x01 \x01(\tR\x04name\x12\x19\n" + + "\x05emoji\x18\x02 \x01(\tH\x00R\x05emoji\x88\x01\x01\x12\x14\n" + + "\x05color\x18\x03 \x01(\aR\x05color\x12 \n" + + "\vcreatedAtMs\x18\x04 \x01(\x04R\vcreatedAtMs\x12$\n" + + "\rallowAllCalls\x18\x05 \x01(\bR\rallowAllCalls\x12*\n" + + "\x10allowAllMentions\x18\x06 \x01(\bR\x10allowAllMentions\x12&\n" + + "\x0eallowedMembers\x18\a \x03(\x04R\x0eallowedMembers\x12(\n" + + "\x0fscheduleEnabled\x18\b \x01(\bR\x0fscheduleEnabled\x12,\n" + + "\x11scheduleStartTime\x18\t \x01(\rR\x11scheduleStartTime\x12(\n" + + "\x0fscheduleEndTime\x18\n" + + " \x01(\rR\x0fscheduleEndTime\x12^\n" + + "\x13scheduleDaysEnabled\x18\v \x03(\x0e2,.signal.backup.NotificationProfile.DayOfWeekR\x13scheduleDaysEnabled\"t\n" + + "\tDayOfWeek\x12\v\n" + + "\aUNKNOWN\x10\x00\x12\n" + + "\n" + + "\x06MONDAY\x10\x01\x12\v\n" + + "\aTUESDAY\x10\x02\x12\r\n" + + "\tWEDNESDAY\x10\x03\x12\f\n" + + "\bTHURSDAY\x10\x04\x12\n" + + "\n" + + "\x06FRIDAY\x10\x05\x12\f\n" + + "\bSATURDAY\x10\x06\x12\n" + + "\n" + + "\x06SUNDAY\x10\aB\b\n" + + "\x06_emoji\"\xd0\x03\n" + + "\n" + + "ChatFolder\x12\x12\n" + + "\x04name\x18\x01 \x01(\tR\x04name\x12&\n" + + "\x0eshowOnlyUnread\x18\x02 \x01(\bR\x0eshowOnlyUnread\x12&\n" + + "\x0eshowMutedChats\x18\x03 \x01(\bR\x0eshowMutedChats\x12<\n" + + "\x19includeAllIndividualChats\x18\x04 \x01(\bR\x19includeAllIndividualChats\x122\n" + + "\x14includeAllGroupChats\x18\x05 \x01(\bR\x14includeAllGroupChats\x12D\n" + + "\n" + + "folderType\x18\x06 \x01(\x0e2$.signal.backup.ChatFolder.FolderTypeR\n" + + "folderType\x122\n" + + "\x14includedRecipientIds\x18\a \x03(\x04R\x14includedRecipientIds\x122\n" + + "\x14excludedRecipientIds\x18\b \x03(\x04R\x14excludedRecipientIds\x12\x0e\n" + + "\x02id\x18\t \x01(\fR\x02id\".\n" + + "\n" + + "FolderType\x12\v\n" + + "\aUNKNOWN\x10\x00\x12\a\n" + + "\x03ALL\x10\x01\x12\n" + + "\n" + + "\x06CUSTOM\x10\x02*\x85\x01\n" + + "\vAvatarColor\x12\b\n" + + "\x04A100\x10\x00\x12\b\n" + + "\x04A110\x10\x01\x12\b\n" + + "\x04A120\x10\x02\x12\b\n" + + "\x04A130\x10\x03\x12\b\n" + + "\x04A140\x10\x04\x12\b\n" + + "\x04A150\x10\x05\x12\b\n" + + "\x04A160\x10\x06\x12\b\n" + + "\x04A170\x10\a\x12\b\n" + + "\x04A180\x10\b\x12\b\n" + + "\x04A190\x10\t\x12\b\n" + + "\x04A200\x10\n" + + "\x12\b\n" + + "\x04A210\x10\v*\\\n" + + "\x12GroupV2AccessLevel\x12\v\n" + + "\aUNKNOWN\x10\x00\x12\a\n" + + "\x03ANY\x10\x01\x12\n" + + "\n" + + "\x06MEMBER\x10\x02\x12\x11\n" + + "\rADMINISTRATOR\x10\x03\x12\x11\n" + + "\rUNSATISFIABLE\x10\x04B;\n" + + "*org.thoughtcrime.securesms.backup.v2.proto\xba\x02\fBackupProto_b\x06proto3" var ( file_backuppb_Backup_proto_rawDescOnce sync.Once - file_backuppb_Backup_proto_rawDescData = file_backuppb_Backup_proto_rawDesc + file_backuppb_Backup_proto_rawDescData []byte ) func file_backuppb_Backup_proto_rawDescGZIP() []byte { file_backuppb_Backup_proto_rawDescOnce.Do(func() { - file_backuppb_Backup_proto_rawDescData = protoimpl.X.CompressGZIP(file_backuppb_Backup_proto_rawDescData) + file_backuppb_Backup_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_backuppb_Backup_proto_rawDesc), len(file_backuppb_Backup_proto_rawDesc))) }) return file_backuppb_Backup_proto_rawDescData } @@ -11725,7 +12791,7 @@ func file_backuppb_Backup_proto_init() { out := protoimpl.TypeBuilder{ File: protoimpl.DescBuilder{ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: file_backuppb_Backup_proto_rawDesc, + RawDescriptor: unsafe.Slice(unsafe.StringData(file_backuppb_Backup_proto_rawDesc), len(file_backuppb_Backup_proto_rawDesc)), NumEnums: 31, NumMessages: 122, NumExtensions: 0, @@ -11737,7 +12803,6 @@ func file_backuppb_Backup_proto_init() { MessageInfos: file_backuppb_Backup_proto_msgTypes, }.Build() File_backuppb_Backup_proto = out.File - file_backuppb_Backup_proto_rawDesc = nil file_backuppb_Backup_proto_goTypes = nil file_backuppb_Backup_proto_depIdxs = nil } diff --git a/pkg/signalmeow/protobuf/build-protos.sh b/pkg/signalmeow/protobuf/build-protos.sh index 86cc261..54116ec 100755 --- a/pkg/signalmeow/protobuf/build-protos.sh +++ b/pkg/signalmeow/protobuf/build-protos.sh @@ -6,12 +6,10 @@ do protoc --go_out=. \ --go_opt=M${file}=$PKG_IMPORT_PATH \ --go_opt=paths=source_relative \ - --go_opt=embed_raw=true \ $file done protoc --go_out=. \ --go_opt=Mbackuppb/Backup.proto=$PKG_IMPORT_PATH/backuppb \ --go_opt=paths=source_relative \ - --go_opt=embed_raw=true \ backuppb/Backup.proto pre-commit run -a From 408cfbd9b5c6519540140f16c4dc1eb9be7af081 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Thu, 24 Apr 2025 19:18:01 +0300 Subject: [PATCH 320/580] signalmeow/store: fix reading last message ID --- pkg/signalmeow/store/backup_store.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/signalmeow/store/backup_store.go b/pkg/signalmeow/store/backup_store.go index 823fe54..edcb658 100644 --- a/pkg/signalmeow/store/backup_store.go +++ b/pkg/signalmeow/store/backup_store.go @@ -271,7 +271,7 @@ func scanChat(row dbutil.Scannable) (*BackupChat, error) { return &BackupChat{ Chat: &chat, TotalMessages: int(totalMessageCount.Int64), - LatestMessageID: uint64(totalMessageCount.Int64), + LatestMessageID: uint64(latestMessageID.Int64), }, nil } From 5e72e4daddf617a586dcd5dcdf9da21728b6ed63 Mon Sep 17 00:00:00 2001 From: Toni Spets Date: Tue, 29 Apr 2025 14:12:08 +0300 Subject: [PATCH 321/580] signalwebsocket: Close and wait for main loop when socket is closed (#597) --- pkg/signalmeow/web/signalwebsocket.go | 34 ++++++++++++++++++--------- 1 file changed, 23 insertions(+), 11 deletions(-) diff --git a/pkg/signalmeow/web/signalwebsocket.go b/pkg/signalmeow/web/signalwebsocket.go index 47cc2e3..f856ec9 100644 --- a/pkg/signalmeow/web/signalwebsocket.go +++ b/pkg/signalmeow/web/signalwebsocket.go @@ -50,6 +50,8 @@ type SignalWebsocket struct { statusChannel chan SignalWebsocketConnectionStatus closeLock sync.RWMutex closeEvt *exsync.Event + closeCalled bool + cancel context.CancelFunc } func NewSignalWebsocket(basicAuth *url.Userinfo) *SignalWebsocket { @@ -96,16 +98,22 @@ func (s *SignalWebsocket) IsConnected() bool { return s.ws != nil } -func (s *SignalWebsocket) Close() error { - defer func() { - if s != nil { - s.ws = nil - } - }() - if s != nil && s.ws != nil { - return s.ws.Close(websocket.StatusNormalClosure, "") +func (s *SignalWebsocket) Close() (err error) { + if s == nil { + return nil } - return nil + + s.closeCalled = true + if s.ws != nil { + err = s.ws.Close(websocket.StatusNormalClosure, "") + s.ws = nil + } + if s.cancel != nil { + s.cancel() + s.cancel = nil + } + <-s.closeEvt.GetChan() + return err } func (s *SignalWebsocket) Connect(ctx context.Context, requestHandler RequestHandlerFunc) chan SignalWebsocketConnectionStatus { @@ -149,12 +157,12 @@ func (s *SignalWebsocket) connectLoop( log := zerolog.Ctx(ctx).With(). Str("loop", "signal_websocket_connect_loop"). Logger() - ctx, cancel := context.WithCancel(ctx) + ctx, s.cancel = context.WithCancel(ctx) incomingRequestChan := make(chan *signalpb.WebSocketRequestMessage, 256) defer func() { s.closeEvt.Set() - cancel() + s.cancel() s.closeLock.Lock() defer s.closeLock.Unlock() @@ -298,6 +306,10 @@ func (s *SignalWebsocket) connectLoop( if err != nil { err = fmt.Errorf("error in readLoop: %w", err) } + if s.closeCalled { + // Exit during Close() so cancel the reconnect loop as well + s.cancel() + } loopCancel(err) log.Info().Msg("readLoop exited") }() From 760ae1ed0935b892d7dc137e82bed74ff842d169 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Tue, 29 Apr 2025 23:41:49 +0300 Subject: [PATCH 322/580] signalmeow/web: fix panic caused by race on close --- pkg/signalmeow/web/signalwebsocket.go | 34 +++++++++++++-------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/pkg/signalmeow/web/signalwebsocket.go b/pkg/signalmeow/web/signalwebsocket.go index f856ec9..089a601 100644 --- a/pkg/signalmeow/web/signalwebsocket.go +++ b/pkg/signalmeow/web/signalwebsocket.go @@ -25,6 +25,7 @@ import ( "net/url" "strings" "sync" + "sync/atomic" "time" "github.com/coder/websocket" @@ -44,14 +45,14 @@ type SimpleResponse struct { type RequestHandlerFunc func(context.Context, *signalpb.WebSocketRequestMessage) (*SimpleResponse, error) type SignalWebsocket struct { - ws *websocket.Conn + ws atomic.Pointer[websocket.Conn] basicAuth *url.Userinfo sendChannel chan SignalWebsocketSendMessage statusChannel chan SignalWebsocketConnectionStatus closeLock sync.RWMutex closeEvt *exsync.Event - closeCalled bool - cancel context.CancelFunc + closeCalled atomic.Bool + cancel atomic.Pointer[context.CancelFunc] } func NewSignalWebsocket(basicAuth *url.Userinfo) *SignalWebsocket { @@ -95,7 +96,7 @@ type SignalWebsocketConnectionStatus struct { } func (s *SignalWebsocket) IsConnected() bool { - return s.ws != nil + return s.ws.Load() != nil } func (s *SignalWebsocket) Close() (err error) { @@ -103,14 +104,12 @@ func (s *SignalWebsocket) Close() (err error) { return nil } - s.closeCalled = true - if s.ws != nil { - err = s.ws.Close(websocket.StatusNormalClosure, "") - s.ws = nil + s.closeCalled.Store(true) + if ws := s.ws.Swap(nil); ws != nil { + err = ws.Close(websocket.StatusNormalClosure, "") } - if s.cancel != nil { - s.cancel() - s.cancel = nil + if cancelLoop := s.cancel.Swap(nil); cancelLoop != nil { + (*cancelLoop)() } <-s.closeEvt.GetChan() return err @@ -157,12 +156,13 @@ func (s *SignalWebsocket) connectLoop( log := zerolog.Ctx(ctx).With(). Str("loop", "signal_websocket_connect_loop"). Logger() - ctx, s.cancel = context.WithCancel(ctx) + ctx, cancel := context.WithCancel(ctx) + s.cancel.Store(&cancel) incomingRequestChan := make(chan *signalpb.WebSocketRequestMessage, 256) defer func() { s.closeEvt.Set() - s.cancel() + cancel() s.closeLock.Lock() defer s.closeLock.Unlock() @@ -178,7 +178,7 @@ func (s *SignalWebsocket) connectLoop( const backoffIncrement = 5 * time.Second const maxBackoff = 60 * time.Second - if s.ws != nil { + if s.ws.Load() != nil { panic("Already connected") } @@ -289,7 +289,7 @@ func (s *SignalWebsocket) connectLoop( // Succssfully connected s.pushStatus(ctx, SignalWebsocketConnectionEventConnected, nil) - s.ws = ws + s.ws.Store(ws) retrying = false backoff = initialBackoff @@ -306,9 +306,9 @@ func (s *SignalWebsocket) connectLoop( if err != nil { err = fmt.Errorf("error in readLoop: %w", err) } - if s.closeCalled { + if s.closeCalled.Load() { // Exit during Close() so cancel the reconnect loop as well - s.cancel() + cancel() } loopCancel(err) log.Info().Msg("readLoop exited") From cfa7f3c496783a9990d35ede7fb43870f399a13d Mon Sep 17 00:00:00 2001 From: Nick Mills-Barrett Date: Wed, 7 May 2025 15:01:13 +0100 Subject: [PATCH 323/580] signalmeow: increase initial backoff to 10s --- pkg/signalmeow/web/signalwebsocket.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/signalmeow/web/signalwebsocket.go b/pkg/signalmeow/web/signalwebsocket.go index 089a601..3ea0b0a 100644 --- a/pkg/signalmeow/web/signalwebsocket.go +++ b/pkg/signalmeow/web/signalwebsocket.go @@ -174,7 +174,7 @@ func (s *SignalWebsocket) connectLoop( s.sendChannel = nil }() - const initialBackoff = 2 * time.Second + const initialBackoff = 10 * time.Second const backoffIncrement = 5 * time.Second const maxBackoff = 60 * time.Second From d3b05748cb1012a3da27f8b19282c7d5e7388f7a Mon Sep 17 00:00:00 2001 From: Nick Mills-Barrett Date: Wed, 7 May 2025 15:01:34 +0100 Subject: [PATCH 324/580] signalmeow: immediately react to context cancellations in the websocket loop --- pkg/signalmeow/web/signalwebsocket.go | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/pkg/signalmeow/web/signalwebsocket.go b/pkg/signalmeow/web/signalwebsocket.go index 3ea0b0a..f4cf4aa 100644 --- a/pkg/signalmeow/web/signalwebsocket.go +++ b/pkg/signalmeow/web/signalwebsocket.go @@ -241,10 +241,16 @@ func (s *SignalWebsocket) connectLoop( backoff = maxBackoff } log.Warn().Dur("backoff", backoff).Msg("Failed to connect, waiting to retry...") - time.Sleep(backoff) + select { + case <-time.After(backoff): + case <-ctx.Done(): + } backoff += backoffIncrement - } else if !isFirstConnect && s.basicAuth != nil && ctx.Err() == nil { - time.Sleep(initialBackoff) + } else if !isFirstConnect && s.basicAuth != nil { + select { + case <-time.After(initialBackoff): + case <-ctx.Done(): + } } if ctx.Err() != nil { log.Info().Msg("ctx done, stopping connection loop") From f6c5e01165d2a023553218b01996beb9517aa650 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Thu, 8 May 2025 15:09:39 +0300 Subject: [PATCH 325/580] handlematrix: use client-generated transaction IDs --- go.mod | 6 +++--- go.sum | 8 ++++---- pkg/connector/connector.go | 10 +++++++++ pkg/connector/handlematrix.go | 38 +++++++++++++++++++++++++++-------- pkg/msgconv/from-matrix.go | 10 ++------- 5 files changed, 49 insertions(+), 23 deletions(-) diff --git a/go.mod b/go.mod index 28e17e8..4322e00 100644 --- a/go.mod +++ b/go.mod @@ -2,7 +2,7 @@ module go.mau.fi/mautrix-signal go 1.23.0 -toolchain go1.24.2 +toolchain go1.24.3 require ( github.com/coder/websocket v1.8.13 @@ -13,12 +13,12 @@ require ( github.com/rs/zerolog v1.34.0 github.com/stretchr/testify v1.10.0 github.com/tidwall/gjson v1.18.0 - go.mau.fi/util v0.8.6 + go.mau.fi/util v0.8.7-0.20250504163337-fc01e957f535 golang.org/x/crypto v0.37.0 golang.org/x/exp v0.0.0-20250408133849-7e4ce0ab07d0 golang.org/x/net v0.39.0 google.golang.org/protobuf v1.36.6 - maunium.net/go/mautrix v0.23.3 + maunium.net/go/mautrix v0.23.4-0.20250508122520-376fa1f36898 ) require ( diff --git a/go.sum b/go.sum index fc57e3c..e45bd46 100644 --- a/go.sum +++ b/go.sum @@ -69,8 +69,8 @@ github.com/tidwall/sjson v1.2.5 h1:kLy8mja+1c9jlljvWTlSazM7cKDRfJuR/bOJhcY5NcY= github.com/tidwall/sjson v1.2.5/go.mod h1:Fvgq9kS/6ociJEDnK0Fk1cpYF4FIW6ZF7LAe+6jwd28= github.com/yuin/goldmark v1.7.10 h1:S+LrtBjRmqMac2UdtB6yyCEJm+UILZ2fefI4p7o0QpI= github.com/yuin/goldmark v1.7.10/go.mod h1:ip/1k0VRfGynBgxOz0yCqHrbZXhcjxyuS66Brc7iBKg= -go.mau.fi/util v0.8.6 h1:AEK13rfgtiZJL2YsNK+W4ihhYCuukcRom8WPP/w/L54= -go.mau.fi/util v0.8.6/go.mod h1:uNB3UTXFbkpp7xL1M/WvQks90B/L4gvbLpbS0603KOE= +go.mau.fi/util v0.8.7-0.20250504163337-fc01e957f535 h1:ESKcyK5hWCzx8dzfSGKEuhuRD3Dg3eCtxOjxmjpnO5s= +go.mau.fi/util v0.8.7-0.20250504163337-fc01e957f535/go.mod h1:uNB3UTXFbkpp7xL1M/WvQks90B/L4gvbLpbS0603KOE= go.mau.fi/zeroconfig v0.1.3 h1:As9wYDKmktjmNZW5i1vn8zvJlmGKHeVxHVIBMXsm4kM= go.mau.fi/zeroconfig v0.1.3/go.mod h1:NcSJkf180JT+1IId76PcMuLTNa1CzsFFZ0nBygIQM70= golang.org/x/crypto v0.37.0 h1:kJNSjF/Xp7kU0iB2Z+9viTPMW4EqqsrywMXLJOOsXSE= @@ -99,5 +99,5 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= maunium.net/go/mauflag v1.0.0 h1:YiaRc0tEI3toYtJMRIfjP+jklH45uDHtT80nUamyD4M= maunium.net/go/mauflag v1.0.0/go.mod h1:nLivPOpTpHnpzEh8jEdSL9UqO9+/KBJFmNRlwKfkPeA= -maunium.net/go/mautrix v0.23.3 h1:U+fzdcLhFKLUm5gf2+Q0hEUqWkwDMRfvE+paUH9ogSk= -maunium.net/go/mautrix v0.23.3/go.mod h1:LX+3evXVKSvh/b43BVC3rkvN2qV7b0bkIV4fY7Snn/4= +maunium.net/go/mautrix v0.23.4-0.20250508122520-376fa1f36898 h1:ZS1FV3+vmGquh//RGBRk3TzdoqCPOwEr40cA7k9e/jA= +maunium.net/go/mautrix v0.23.4-0.20250508122520-376fa1f36898/go.mod h1:pT4G5RZQ+nLfKzsmeDa4NhHghOVTrasLLwY9tZ2mO08= diff --git a/pkg/connector/connector.go b/pkg/connector/connector.go index 229d4ea..00032b8 100644 --- a/pkg/connector/connector.go +++ b/pkg/connector/connector.go @@ -19,12 +19,17 @@ package connector import ( "context" "fmt" + "strconv" "text/template" + "time" "github.com/google/uuid" "go.mau.fi/util/dbutil" "go.mau.fi/util/exsync" "maunium.net/go/mautrix/bridgev2" + "maunium.net/go/mautrix/bridgev2/networkid" + "maunium.net/go/mautrix/event" + "maunium.net/go/mautrix/id" "go.mau.fi/mautrix-signal/pkg/msgconv" "go.mau.fi/mautrix-signal/pkg/signalmeow" @@ -40,6 +45,7 @@ type SignalConnector struct { var _ bridgev2.NetworkConnector = (*SignalConnector)(nil) var _ bridgev2.MaxFileSizeingNetwork = (*SignalConnector)(nil) +var _ bridgev2.TransactionIDGeneratingNetwork = (*SignalConnector)(nil) func (s *SignalConnector) GetName() bridgev2.BridgeName { return bridgev2.BridgeName{ @@ -105,3 +111,7 @@ func (s *SignalConnector) LoadUserLogin(ctx context.Context, login *bridgev2.Use login.Client = sc return nil } + +func (s *SignalConnector) GenerateTransactionID(userID id.UserID, roomID id.RoomID, eventType event.Type) networkid.RawTransactionID { + return networkid.RawTransactionID(strconv.FormatInt(time.Now().UnixMilli(), 10)) +} diff --git a/pkg/connector/handlematrix.go b/pkg/connector/handlematrix.go index a329c0c..8137c84 100644 --- a/pkg/connector/handlematrix.go +++ b/pkg/connector/handlematrix.go @@ -21,6 +21,7 @@ import ( "crypto/sha256" "errors" "fmt" + "strconv" "time" "github.com/google/uuid" @@ -78,12 +79,29 @@ func (s *SignalClient) sendMessage(ctx context.Context, portalID networkid.Porta } } +func getTimestampForEvent(txnID networkid.RawTransactionID, evt *event.Event, origSender *bridgev2.OrigSender) uint64 { + if origSender != nil { + // Relaybot messages are never allowed to set the timestamp + return uint64(time.Now().UnixMilli()) + } + if len(txnID) > 0 { + parsed, err := strconv.ParseUint(string(txnID), 10, 64) + if err == nil { + return parsed + } + } + return uint64(evt.Timestamp) +} + func (s *SignalClient) HandleMatrixMessage(ctx context.Context, msg *bridgev2.MatrixMessage) (message *bridgev2.MatrixMessageResponse, err error) { - converted, err := s.Main.MsgConv.ToSignal(ctx, s.Client, msg.Portal, msg.Event, msg.Content, msg.OrigSender != nil, msg.ReplyTo) + ts := getTimestampForEvent(msg.InputTransactionID, msg.Event, msg.OrigSender) + converted, err := s.Main.MsgConv.ToSignal( + ctx, s.Client, msg.Portal, msg.Event, msg.Content, ts, msg.OrigSender != nil, msg.ReplyTo, + ) if err != nil { return nil, err } - msgID := signalid.MakeMessageID(s.Client.Store.ACI, converted.GetTimestamp()) + msgID := signalid.MakeMessageID(s.Client.Store.ACI, ts) msg.AddPendingToIgnore(networkid.TransactionID(msgID)) err = s.sendMessage(ctx, msg.Portal.ID, &signalpb.Content{DataMessage: converted}) if err != nil { @@ -92,7 +110,7 @@ func (s *SignalClient) HandleMatrixMessage(ctx context.Context, msg *bridgev2.Ma dbMsg := &database.Message{ ID: msgID, SenderID: signalid.MakeUserID(s.Client.Store.ACI), - Timestamp: time.UnixMilli(int64(converted.GetTimestamp())), + Timestamp: time.UnixMilli(int64(ts)), Metadata: &signalid.MessageMetadata{ ContainsAttachments: len(converted.Attachments) > 0, }, @@ -117,7 +135,8 @@ func (s *SignalClient) HandleMatrixEdit(ctx context.Context, msg *bridgev2.Matri return fmt.Errorf("failed to get message reply target: %w", err) } } - converted, err := s.Main.MsgConv.ToSignal(ctx, s.Client, msg.Portal, msg.Event, msg.Content, msg.OrigSender != nil, replyTo) + ts := getTimestampForEvent(msg.InputTransactionID, msg.Event, msg.OrigSender) + converted, err := s.Main.MsgConv.ToSignal(ctx, s.Client, msg.Portal, msg.Event, msg.Content, ts, msg.OrigSender != nil, replyTo) if err != nil { return err } @@ -128,7 +147,7 @@ func (s *SignalClient) HandleMatrixEdit(ctx context.Context, msg *bridgev2.Matri if err != nil { return bridgev2.WrapErrorInStatus(err).WithSendNotice(true) } - msg.EditTarget.ID = signalid.MakeMessageID(s.Client.Store.ACI, converted.GetTimestamp()) + msg.EditTarget.ID = signalid.MakeMessageID(s.Client.Store.ACI, ts) msg.EditTarget.Metadata = &signalid.MessageMetadata{ContainsAttachments: len(converted.Attachments) > 0} msg.EditTarget.EditCount++ return nil @@ -147,9 +166,10 @@ func (s *SignalClient) HandleMatrixReaction(ctx context.Context, msg *bridgev2.M if err != nil { return nil, fmt.Errorf("failed to parse target message ID: %w", err) } + ts := getTimestampForEvent(msg.InputTransactionID, msg.Event, msg.OrigSender) wrappedContent := &signalpb.Content{ DataMessage: &signalpb.DataMessage{ - Timestamp: proto.Uint64(uint64(msg.Event.Timestamp)), + Timestamp: proto.Uint64(ts), RequiredProtocolVersion: proto.Uint32(uint32(signalpb.DataMessage_REACTIONS)), Reaction: &signalpb.DataMessage_Reaction{ Emoji: proto.String(msg.PreHandleResp.Emoji), @@ -171,9 +191,10 @@ func (s *SignalClient) HandleMatrixReactionRemove(ctx context.Context, msg *brid if err != nil { return fmt.Errorf("failed to parse target message ID: %w", err) } + ts := getTimestampForEvent(msg.InputTransactionID, msg.Event, msg.OrigSender) wrappedContent := &signalpb.Content{ DataMessage: &signalpb.DataMessage{ - Timestamp: proto.Uint64(uint64(msg.Event.Timestamp)), + Timestamp: proto.Uint64(ts), RequiredProtocolVersion: proto.Uint32(uint32(signalpb.DataMessage_REACTIONS)), Reaction: &signalpb.DataMessage_Reaction{ Emoji: proto.String(msg.TargetReaction.Emoji), @@ -197,9 +218,10 @@ func (s *SignalClient) HandleMatrixMessageRemove(ctx context.Context, msg *bridg } else if msg.TargetMessage.SenderID != signalid.MakeUserID(s.Client.Store.ACI) { return fmt.Errorf("cannot delete other people's messages") } + ts := getTimestampForEvent(msg.InputTransactionID, msg.Event, msg.OrigSender) wrappedContent := &signalpb.Content{ DataMessage: &signalpb.DataMessage{ - Timestamp: proto.Uint64(uint64(msg.Event.Timestamp)), + Timestamp: proto.Uint64(ts), Delete: &signalpb.DataMessage_Delete{ TargetSentTimestamp: proto.Uint64(targetSentTimestamp), }, diff --git a/pkg/msgconv/from-matrix.go b/pkg/msgconv/from-matrix.go index 8edf40f..367bb1f 100644 --- a/pkg/msgconv/from-matrix.go +++ b/pkg/msgconv/from-matrix.go @@ -20,7 +20,6 @@ import ( "context" "fmt" "strings" - "time" "github.com/rs/zerolog" "go.mau.fi/util/exmime" @@ -44,6 +43,7 @@ func (mc *MessageConverter) ToSignal( portal *bridgev2.Portal, evt *event.Event, content *event.MessageEventContent, + timestamp uint64, relaybotFormatted bool, replyTo *database.Message, ) (*signalpb.DataMessage, error) { @@ -53,14 +53,8 @@ func (mc *MessageConverter) ToSignal( content.MsgType = event.MessageType(event.EventSticker.Type) } - // Matrix timestamps can be faked, but if the user is using their own Signal account, faking timestamps is their problem. - ts := uint64(evt.Timestamp) - // However, when relaying, timestamps shouldn't be trusted because anyone can send a message with any timestamp. - if relaybotFormatted { - ts = uint64(time.Now().UnixMilli()) - } dm := &signalpb.DataMessage{ - Timestamp: &ts, + Timestamp: ×tamp, Preview: mc.convertURLPreviewToSignal(ctx, content), } if replyTo != nil { From 9944eb3507c8916d8180878c1d4a937220e03891 Mon Sep 17 00:00:00 2001 From: Toni Spets Date: Fri, 9 May 2025 13:57:28 +0300 Subject: [PATCH 326/580] Initial direct media support Everything still happens in-memory but any file can be downloaded using direct media URIs. --- pkg/connector/chatinfo.go | 48 +++++-- pkg/connector/directmedia.go | 122 ++++++++++++++++ pkg/connector/groupinfo.go | 65 +++++++-- pkg/connector/handlesignal.go | 11 +- pkg/msgconv/from-signal.go | 59 +++++--- pkg/msgconv/msgconv.go | 1 + pkg/signalid/media.go | 230 ++++++++++++++++++++++++++++++ pkg/signalmeow/attachments.go | 12 +- pkg/signalmeow/groups.go | 45 ++---- pkg/signalmeow/receiving.go | 2 +- pkg/signalmeow/types/identifer.go | 2 +- 11 files changed, 509 insertions(+), 88 deletions(-) create mode 100644 pkg/connector/directmedia.go create mode 100644 pkg/signalid/media.go diff --git a/pkg/connector/chatinfo.go b/pkg/connector/chatinfo.go index 5b142cf..6fff853 100644 --- a/pkg/connector/chatinfo.go +++ b/pkg/connector/chatinfo.go @@ -58,13 +58,13 @@ func (s *SignalClient) GetUserInfo(ctx context.Context, ghost *bridgev2.Ghost) ( if !s.Main.Config.UseOutdatedProfiles && meta.ProfileFetchedAt.After(contact.Profile.FetchedAt) { return nil, nil } - return s.contactToUserInfo(contact), nil + return s.contactToUserInfo(ctx, contact) } func (s *SignalClient) GetChatInfo(ctx context.Context, portal *bridgev2.Portal) (*bridgev2.ChatInfo, error) { userID, groupID, err := signalid.ParsePortalID(portal.ID) if err != nil { - return nil, err + return nil, fmt.Errorf("failed to parse portal id: %w", err) } if groupID != "" { return s.getGroupInfo(ctx, groupID, 0, nil) @@ -78,7 +78,7 @@ func (s *SignalClient) GetChatInfo(ctx context.Context, portal *bridgev2.Portal) } } -func (s *SignalClient) contactToUserInfo(contact *types.Recipient) *bridgev2.UserInfo { +func (s *SignalClient) contactToUserInfo(ctx context.Context, contact *types.Recipient) (*bridgev2.UserInfo, error) { isBot := false ui := &bridgev2.UserInfo{ IsBot: &isBot, @@ -115,12 +115,33 @@ func (s *SignalClient) contactToUserInfo(contact *types.Recipient) *bridgev2.Use } else if contact.Profile.AvatarPath != "" { ui.Avatar = &bridgev2.Avatar{ ID: makeAvatarPathID(contact.Profile.AvatarPath), - Get: func(ctx context.Context) ([]byte, error) { + } + + if s.Main.MsgConv.DirectMedia { + userID, err := signalid.ParseUserLoginID(s.UserLogin.ID) + if err != nil { + return nil, fmt.Errorf("failed to parse user login ID: %w", err) + } + mediaID, err := signalid.DirectMediaProfileAvatar{ + UserID: userID, + ContactID: contact.ACI, + ProfileAvatarPath: contact.Profile.AvatarPath, + }.AsMediaID() + if err != nil { + return nil, err + } + ui.Avatar.MXC, err = s.Main.Bridge.Matrix.GenerateContentURI(ctx, mediaID) + if err != nil { + return nil, err + } + ui.Avatar.Hash = signalid.HashMediaID(mediaID) + } else { + ui.Avatar.Get = func(ctx context.Context) ([]byte, error) { return s.Client.DownloadUserAvatar(ctx, contact.Profile.AvatarPath, contact.Profile.Key) - }, + } } } - return ui + return ui, nil } var _ bridgev2.IdentifierValidatingNetwork = (*SignalConnector)(nil) @@ -177,6 +198,11 @@ func (s *SignalClient) ResolveIdentifier(ctx context.Context, number string, cre Stringer("pni", pni). Msg("Found resolve identifier target user") + userInfo, err := s.contactToUserInfo(ctx, recipient) + if err != nil { + return nil, fmt.Errorf("failed to convert contact: %w", err) + } + // createChat is a no-op: chats don't need to be created, and we always return chat info if aci != uuid.Nil { ghost, err := s.Main.Bridge.GetGhostByID(ctx, signalid.MakeUserID(aci)) @@ -185,14 +211,14 @@ func (s *SignalClient) ResolveIdentifier(ctx context.Context, number string, cre } return &bridgev2.ResolveIdentifierResponse{ UserID: signalid.MakeUserID(aci), - UserInfo: s.contactToUserInfo(recipient), + UserInfo: userInfo, Ghost: ghost, Chat: s.makeCreateDMResponse(ctx, recipient, nil), }, nil } else { return &bridgev2.ResolveIdentifierResponse{ UserID: signalid.MakeUserIDFromServiceID(libsignalgo.NewPNIServiceID(pni)), - UserInfo: s.contactToUserInfo(recipient), + UserInfo: userInfo, Chat: s.makeCreateDMResponse(ctx, recipient, nil), }, nil } @@ -210,8 +236,12 @@ func (s *SignalClient) GetContactList(ctx context.Context) ([]*bridgev2.ResolveI } resp := make([]*bridgev2.ResolveIdentifierResponse, len(recipients)) for i, recipient := range recipients { + userInfo, err := s.contactToUserInfo(ctx, recipient) + if err != nil { + return nil, fmt.Errorf("failed to convert contact: %w", err) + } recipientResp := &bridgev2.ResolveIdentifierResponse{ - UserInfo: s.contactToUserInfo(recipient), + UserInfo: userInfo, Chat: s.makeCreateDMResponse(ctx, recipient, nil), } if recipient.ACI != uuid.Nil { diff --git a/pkg/connector/directmedia.go b/pkg/connector/directmedia.go new file mode 100644 index 0000000..b24c033 --- /dev/null +++ b/pkg/connector/directmedia.go @@ -0,0 +1,122 @@ +package connector + +import ( + "context" + "encoding/base64" + "fmt" + "io" + + "maunium.net/go/mautrix/bridgev2" + "maunium.net/go/mautrix/bridgev2/networkid" + "maunium.net/go/mautrix/mediaproxy" + + "go.mau.fi/mautrix-signal/pkg/signalid" + "go.mau.fi/mautrix-signal/pkg/signalmeow" + "go.mau.fi/mautrix-signal/pkg/signalmeow/types" +) + +var _ bridgev2.DirectMediableNetwork = (*SignalConnector)(nil) + +func (s *SignalConnector) SetUseDirectMedia() { + s.MsgConv.DirectMedia = true +} + +func (s *SignalConnector) Download(ctx context.Context, mediaID networkid.MediaID, params map[string]string) (mediaproxy.GetMediaResponse, error) { + log := s.Bridge.Log.With().Str("component", "direct download").Logger() + + info, err := signalid.ParseDirectMediaInfo(mediaID) + if err != nil { + return nil, fmt.Errorf("failed to parse direct media id: %w", err) + } + + switch info := info.(type) { + case *signalid.DirectMediaAttachment: + log.Info(). + Uint64("cdn_id", info.CDNID). + Str("cdn_key", info.CDNKey). + Uint32("cdn_number", info.CDNNumber). + Int("key_len", len(info.Key)). + Int("digest_len", len(info.Digest)). + Uint32("size", info.Size). + Msg("Direct downloading attachment") + + return &mediaproxy.GetMediaResponseCallback{ + Callback: func(w io.Writer) (int64, error) { + data, err := signalmeow.DownloadAttachment(ctx, info.CDNID, info.CDNKey, info.CDNNumber, info.Key, info.Digest, info.Size) + if err != nil { + log.Err(err).Msg("Direct download failed") + return 0, err + } + + _, err = w.Write(data) + return int64(info.Size), err + }, + }, nil + case *signalid.DirectMediaGroupAvatar: + log.Info(). + Stringer("user_id", info.UserID). + Hex("group_id", info.GroupID[:]). + Str("group_avatar_path", info.GroupAvatarPath). + Msg("Direct downloading group avatar") + + groupID := types.GroupIdentifier(base64.StdEncoding.EncodeToString(info.GroupID[:])) + + userLogin, err := s.Bridge.GetExistingUserLoginByID(ctx, signalid.MakeUserLoginID(info.UserID)) + if err != nil { + return nil, fmt.Errorf("failed to get user login: %w", err) + } + + client := userLogin.Client.(*SignalClient) + + groupMasterKey, err := client.Client.Store.GroupStore.MasterKeyFromGroupIdentifier(ctx, groupID) + if err != nil { + return nil, fmt.Errorf("failed to to get group master key: %w", err) + } + + return &mediaproxy.GetMediaResponseCallback{ + Callback: func(w io.Writer) (int64, error) { + data, err := client.Client.DownloadGroupAvatar(ctx, info.GroupAvatarPath, groupMasterKey) + if err != nil { + log.Err(err).Msg("Direct download failed") + return 0, err + } + + _, err = w.Write(data) + return int64(len(data)), err + }, + }, nil + case *signalid.DirectMediaProfileAvatar: + log.Info(). + Stringer("user_id", info.UserID). + Stringer("contact_id", info.ContactID). + Str("profile_avatar_path", info.ProfileAvatarPath). + Msg("Direct downloading profile avatar") + + userLogin, err := s.Bridge.GetExistingUserLoginByID(ctx, signalid.MakeUserLoginID(info.UserID)) + if err != nil { + return nil, fmt.Errorf("failed to get user login: %w", err) + } + + client := userLogin.Client.(*SignalClient) + + profileKey, err := client.Client.Store.RecipientStore.LoadProfileKey(ctx, info.ContactID) + if err != nil { + return nil, fmt.Errorf("failed to get contact: %w", err) + } + + return &mediaproxy.GetMediaResponseCallback{ + Callback: func(w io.Writer) (int64, error) { + data, err := client.Client.DownloadUserAvatar(ctx, info.ProfileAvatarPath, *profileKey) + if err != nil { + log.Err(err).Msg("Direct download failed") + return 0, err + } + + _, err = w.Write(data) + return int64(len(data)), err + }, + }, nil + default: + return nil, fmt.Errorf("no downloader for direct media type: %T", info) + } +} diff --git a/pkg/connector/groupinfo.go b/pkg/connector/groupinfo.go index 0cb3ce5..0527ecf 100644 --- a/pkg/connector/groupinfo.go +++ b/pkg/connector/groupinfo.go @@ -18,6 +18,7 @@ package connector import ( "context" + "fmt" "time" "github.com/google/uuid" @@ -97,7 +98,7 @@ func inviteLinkToJoinRule(inviteLinkAccess signalmeow.AccessControl) event.JoinR func (s *SignalClient) getGroupInfo(ctx context.Context, groupID types.GroupIdentifier, minRevision uint32, backupChat *store.BackupChat) (*bridgev2.ChatInfo, error) { groupInfo, err := s.Client.RetrieveGroupByID(ctx, groupID, minRevision) if err != nil { - return nil, err + return nil, fmt.Errorf("failed to retrieve group by id: %w", err) } members := &bridgev2.ChatMemberList{ IsFull: true, @@ -160,10 +161,14 @@ func (s *SignalClient) getGroupInfo(ctx context.Context, groupID types.GroupIden zerolog.Ctx(ctx).Warn().Err(err).Msg("Failed to get backup chat for group") } } + avatar, err := s.makeGroupAvatar(ctx, groupID, &groupInfo.AvatarPath, groupInfo.GroupMasterKey) + if err != nil { + return nil, fmt.Errorf("failed to make group avatar: %w", err) + } return &bridgev2.ChatInfo{ Name: &groupInfo.Title, Topic: &groupInfo.Description, - Avatar: s.makeGroupAvatar(groupInfo), + Avatar: avatar, Disappear: &database.DisappearingSetting{ Type: database.DisappearingTypeAfterRead, Timer: time.Duration(groupInfo.DisappearingMessagesDuration) * time.Second, @@ -176,18 +181,42 @@ func (s *SignalClient) getGroupInfo(ctx context.Context, groupID types.GroupIden }, nil } -func (s *SignalClient) makeGroupAvatar(meta signalmeow.GroupAvatarMeta) *bridgev2.Avatar { - path := meta.GetAvatarPath() +func (s *SignalClient) makeGroupAvatar(ctx context.Context, groupID types.GroupIdentifier, path *string, groupMasterKey types.SerializedGroupMasterKey) (*bridgev2.Avatar, error) { if path == nil { - return nil + return nil, nil } - return &bridgev2.Avatar{ - ID: makeAvatarPathID(*path), - Get: func(ctx context.Context) ([]byte, error) { - return s.Client.DownloadGroupAvatar(ctx, meta) - }, + avatar := &bridgev2.Avatar{ + ID: makeAvatarPathID(*path), Remove: *path == "", } + if s.Main.MsgConv.DirectMedia { + userID, err := signalid.ParseUserLoginID(s.UserLogin.ID) + if err != nil { + return nil, fmt.Errorf("failed to parse user login ID: %w", err) + } + groupIDBytes, err := groupID.Bytes() + if err != nil { + return nil, fmt.Errorf("failed to get group id bytes: %w", err) + } + mediaID, err := signalid.DirectMediaGroupAvatar{ + UserID: userID, + GroupID: groupIDBytes, + GroupAvatarPath: *path, + }.AsMediaID() + if err != nil { + return nil, err + } + avatar.MXC, err = s.Main.Bridge.Matrix.GenerateContentURI(ctx, mediaID) + if err != nil { + return nil, err + } + avatar.Hash = signalid.HashMediaID(mediaID) + } else { + avatar.Get = func(ctx context.Context) ([]byte, error) { + return s.Client.DownloadGroupAvatar(ctx, *path, groupMasterKey) + } + } + return avatar, nil } func makeRevisionUpdater(rev uint32) func(ctx context.Context, portal *bridgev2.Portal) bool { @@ -201,13 +230,17 @@ func makeRevisionUpdater(rev uint32) func(ctx context.Context, portal *bridgev2. } } -func (s *SignalClient) groupChangeToChatInfoChange(ctx context.Context, rev uint32, groupChange *signalmeow.GroupChange) *bridgev2.ChatInfoChange { +func (s *SignalClient) groupChangeToChatInfoChange(ctx context.Context, groupID types.GroupIdentifier, rev uint32, groupChange *signalmeow.GroupChange) (*bridgev2.ChatInfoChange, error) { + avatar, err := s.makeGroupAvatar(ctx, groupID, groupChange.ModifyAvatar, groupChange.GroupMasterKey) + if err != nil { + return nil, err + } ic := &bridgev2.ChatInfoChange{ ChatInfo: &bridgev2.ChatInfo{ ExtraUpdates: makeRevisionUpdater(rev), Name: groupChange.ModifyTitle, Topic: groupChange.ModifyDescription, - Avatar: s.makeGroupAvatar(groupChange), + Avatar: avatar, }, } if groupChange.ModifyDisappearingMessagesDuration != nil { @@ -350,7 +383,7 @@ func (s *SignalClient) groupChangeToChatInfoChange(ctx context.Context, rev uint if len(mc) > 0 || pls != nil { ic.MemberChanges = &bridgev2.ChatMemberList{Members: mc, PowerLevels: pls} } - return ic + return ic, nil } func (s *SignalClient) maybeResolvePNItoACI(ctx context.Context, serviceID *libsignalgo.ServiceID) *uuid.UUID { @@ -390,8 +423,10 @@ func (s *SignalClient) catchUpGroup(ctx context.Context, portal *bridgev2.Portal } for _, gc := range groupChanges { log.Debug().Uint32("current_rev", gc.GroupChange.Revision).Msg("Processing group change") - chatInfoChange := s.groupChangeToChatInfoChange(ctx, gc.GroupChange.Revision, gc.GroupChange) - if gc.GroupChange.SourceServiceID.Type == libsignalgo.ServiceIDTypeACI { + chatInfoChange, err := s.groupChangeToChatInfoChange(ctx, types.GroupIdentifier(portal.ID), gc.GroupChange.Revision, gc.GroupChange) + if err != nil { + log.Err(err).Msg("Failed to convert group info") + } else if gc.GroupChange.SourceServiceID.Type == libsignalgo.ServiceIDTypeACI { portal.ProcessChatInfoChange(ctx, s.makeEventSender(gc.GroupChange.SourceServiceID.UUID), s.UserLogin, chatInfoChange, time.UnixMilli(int64(ts))) } if gc.GroupChange.Revision == toRevision { diff --git a/pkg/connector/handlesignal.go b/pkg/connector/handlesignal.go index 16cfb50..8a94016 100644 --- a/pkg/connector/handlesignal.go +++ b/pkg/connector/handlesignal.go @@ -34,6 +34,7 @@ import ( "go.mau.fi/mautrix-signal/pkg/signalid" "go.mau.fi/mautrix-signal/pkg/signalmeow/events" signalpb "go.mau.fi/mautrix-signal/pkg/signalmeow/protobuf" + "go.mau.fi/mautrix-signal/pkg/signalmeow/types" ) func (s *SignalClient) handleSignalEvent(rawEvt events.SignalEvent) { @@ -188,7 +189,8 @@ func (evt *Bv2ChatEvent) GetChatInfoChange(ctx context.Context) (*bridgev2.ChatI if err != nil { return nil, fmt.Errorf("failed to decrypt group change: %w", err) } - return evt.s.groupChangeToChatInfoChange(ctx, gv2.GetRevision(), groupChange), nil + // XXX: is this ID compatible with types.GroupIdentifier? + return evt.s.groupChangeToChatInfoChange(ctx, types.GroupIdentifier(evt.Info.ChatID), gv2.GetRevision(), groupChange) } func (evt *Bv2ChatEvent) PreHandle(ctx context.Context, portal *bridgev2.Portal) { @@ -503,7 +505,12 @@ func (s *SignalClient) handleSignalContactList(evt *events.ContactList) { log.Err(err).Msg("Failed to get ghost to update contact info") continue } - ghost.UpdateInfo(ctx, s.contactToUserInfo(contact)) + userInfo, err := s.contactToUserInfo(ctx, contact) + if err != nil { + log.Err(err).Msg("Failed to convert contact info") + continue + } + ghost.UpdateInfo(ctx, userInfo) if contact.ACI == s.Client.Store.ACI { s.updateRemoteProfile(ctx, true) } diff --git a/pkg/msgconv/from-signal.go b/pkg/msgconv/from-signal.go index fb80394..da5becb 100644 --- a/pkg/msgconv/from-signal.go +++ b/pkg/msgconv/from-signal.go @@ -478,40 +478,55 @@ func (mc *MessageConverter) downloadAttachment(ctx context.Context, att *signalp return nil, ErrBackupNotSupported } } - return signalmeow.DownloadAttachment(ctx, att) + return signalmeow.DownloadAttachmentWithPointer(ctx, att) } func (mc *MessageConverter) reuploadAttachment(ctx context.Context, att *signalpb.AttachmentPointer, attMap AttachmentMap) (*bridgev2.ConvertedMessagePart, error) { - data, err := mc.downloadAttachment(ctx, att, attMap) - if err != nil { - return nil, err - } - mimeType := att.GetContentType() - if mimeType == "" { - mimeType = http.DetectContentType(data) - } fileName := att.GetFileName() content := &event.MessageEventContent{ Info: &event.FileInfo{ Width: int(att.GetWidth()), Height: int(att.GetHeight()), - Size: len(data), + Size: int(att.GetSize()), }, } - if att.GetFlags()&uint32(signalpb.AttachmentPointer_VOICE_MESSAGE) != 0 && ffmpeg.Supported() { - data, err = ffmpeg.ConvertBytes(ctx, data, ".ogg", []string{}, []string{"-c:a", "libopus"}, mimeType) + mimeType := att.GetContentType() + if mc.DirectMedia { + mediaID, err := signalid.DirectMediaAttachment{ + CDNID: att.GetCdnId(), + CDNKey: att.GetCdnKey(), + CDNNumber: att.GetCdnNumber(), + Key: att.Key, + Digest: att.Digest, + Size: att.GetSize(), + }.AsMediaID() if err != nil { - return nil, fmt.Errorf("failed to convert audio to ogg/opus: %w", err) + return nil, err + } + content.URL, err = mc.Bridge.Matrix.GenerateContentURI(ctx, mediaID) + } else { + data, err := mc.downloadAttachment(ctx, att, attMap) + if err != nil { + return nil, err + } + if mimeType == "" { + mimeType = http.DetectContentType(data) + } + if att.GetFlags()&uint32(signalpb.AttachmentPointer_VOICE_MESSAGE) != 0 && ffmpeg.Supported() { + data, err = ffmpeg.ConvertBytes(ctx, data, ".ogg", []string{}, []string{"-c:a", "libopus"}, mimeType) + if err != nil { + return nil, fmt.Errorf("failed to convert audio to ogg/opus: %w", err) + } + fileName += ".ogg" + mimeType = "audio/ogg" + content.MSC3245Voice = &event.MSC3245Voice{} + // TODO include duration here (and in info) if there's some easy way to extract it with ffmpeg + //content.MSC1767Audio = &event.MSC1767Audio{} + } + content.URL, content.File, err = getIntent(ctx).UploadMedia(ctx, getPortal(ctx).MXID, data, fileName, mimeType) + if err != nil { + return nil, err } - fileName += ".ogg" - mimeType = "audio/ogg" - content.MSC3245Voice = &event.MSC3245Voice{} - // TODO include duration here (and in info) if there's some easy way to extract it with ffmpeg - //content.MSC1767Audio = &event.MSC1767Audio{} - } - content.URL, content.File, err = getIntent(ctx).UploadMedia(ctx, getPortal(ctx).MXID, data, fileName, mimeType) - if err != nil { - return nil, err } if att.GetBlurHash() != "" { content.Info.Blurhash = att.GetBlurHash() diff --git a/pkg/msgconv/msgconv.go b/pkg/msgconv/msgconv.go index 80717fc..01d46a6 100644 --- a/pkg/msgconv/msgconv.go +++ b/pkg/msgconv/msgconv.go @@ -47,6 +47,7 @@ type MessageConverter struct { MaxFileSize int64 LocationFormat string DisappearViewOnce bool + DirectMedia bool } func NewMessageConverter(br *bridgev2.Bridge) *MessageConverter { diff --git a/pkg/signalid/media.go b/pkg/signalid/media.go new file mode 100644 index 0000000..defd4e5 --- /dev/null +++ b/pkg/signalid/media.go @@ -0,0 +1,230 @@ +// mautrix-signal - A Matrix-Signal puppeting bridge. +// Copyright (C) 2025 Tulir Asokan +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +package signalid + +import ( + "bufio" + "bytes" + "crypto/sha256" + "encoding/binary" + "fmt" + "io" + + "github.com/google/uuid" + "maunium.net/go/mautrix/bridgev2/networkid" +) + +type directMediaType byte + +const ( + directMediaTypeAttachment directMediaType = iota + directMediaTypeGroupAvatar + directMediaTypeProfileAvatar +) + +type DirectMediaInfo interface { + AsMediaID() (networkid.MediaID, error) +} + +var ( + _ DirectMediaInfo = (*DirectMediaAttachment)(nil) + _ DirectMediaInfo = (*DirectMediaGroupAvatar)(nil) + _ DirectMediaInfo = (*DirectMediaProfileAvatar)(nil) +) + +type DirectMediaAttachment struct { + CDNID uint64 + CDNKey string + CDNNumber uint32 + Key []byte + Digest []byte + Size uint32 +} + +func (m DirectMediaAttachment) AsMediaID() (mediaID networkid.MediaID, err error) { + buf := &bytes.Buffer{} + + if err = binary.Write(buf, binary.BigEndian, directMediaTypeAttachment); err != nil { + return + } else if err = writeUvarint(buf, m.CDNID); err != nil { + return + } else if err = writeByteSlice(buf, []byte(m.CDNKey)); err != nil { + return + } else if err = writeUvarint(buf, uint64(m.CDNNumber)); err != nil { + return + } else if err = writeByteSlice(buf, m.Key); err != nil { + return + } else if err = writeByteSlice(buf, m.Digest); err != nil { + return + } else if err = writeUvarint(buf, uint64(m.Size)); err != nil { + return + } + + return networkid.MediaID(buf.Bytes()), nil +} + +type DirectMediaGroupAvatar struct { + UserID uuid.UUID + GroupID [32]byte + GroupAvatarPath string +} + +func (m DirectMediaGroupAvatar) AsMediaID() (mediaID networkid.MediaID, err error) { + buf := &bytes.Buffer{} + + if err = binary.Write(buf, binary.BigEndian, directMediaTypeGroupAvatar); err != nil { + return + } else if err = binary.Write(buf, binary.BigEndian, m.UserID); err != nil { + return + } else if err = binary.Write(buf, binary.BigEndian, m.GroupID); err != nil { + return + } else if err = writeByteSlice(buf, []byte(m.GroupAvatarPath)); err != nil { + return + } + + return networkid.MediaID(buf.Bytes()), nil +} + +type DirectMediaProfileAvatar struct { + UserID uuid.UUID + ContactID uuid.UUID + ProfileAvatarPath string +} + +func (m DirectMediaProfileAvatar) AsMediaID() (mediaID networkid.MediaID, err error) { + buf := &bytes.Buffer{} + + if err = binary.Write(buf, binary.BigEndian, directMediaTypeProfileAvatar); err != nil { + return + } else if err = binary.Write(buf, binary.BigEndian, m.UserID); err != nil { + return + } else if err = binary.Write(buf, binary.BigEndian, m.ContactID); err != nil { + return + } else if err = writeByteSlice(buf, []byte(m.ProfileAvatarPath)); err != nil { + return + } + + return networkid.MediaID(buf.Bytes()), nil +} + +func ParseDirectMediaInfo(mediaID networkid.MediaID) (_ DirectMediaInfo, err error) { + mediaIDLen := len(mediaID) + if mediaIDLen == 0 { + return nil, fmt.Errorf("empty media ID") + } + + buf := bufio.NewReader(bytes.NewBuffer(mediaID)) + + // type byte + var mediaType directMediaType + if err := binary.Read(buf, binary.BigEndian, &mediaType); err != nil { + return nil, fmt.Errorf("failed to read media type: %w", err) + } + + switch mediaType { + case directMediaTypeAttachment: + var info DirectMediaAttachment + + if info.CDNID, err = binary.ReadUvarint(buf); err != nil { + return info, fmt.Errorf("failed to read cdn id: %w", err) + } + if cdnKey, err := readByteSlice(buf, mediaIDLen); err != nil { + return info, fmt.Errorf("failed to read cdn key: %w", err) + } else { + info.CDNKey = string(cdnKey) + } + if cdnNumber, err := binary.ReadUvarint(buf); err != nil { + return info, fmt.Errorf("failed to read cdn number: %w", err) + } else { + info.CDNNumber = uint32(cdnNumber) + } + if info.Key, err = readByteSlice(buf, mediaIDLen); err != nil { + return info, fmt.Errorf("failed to read key: %w", err) + } else if info.Digest, err = readByteSlice(buf, mediaIDLen); err != nil { + return info, fmt.Errorf("failed to read digest: %w", err) + } + if size, err := binary.ReadUvarint(buf); err != nil { + return info, fmt.Errorf("failed to read cdn id: %w", err) + } else { + info.Size = uint32(size) + } + + return &info, nil + case directMediaTypeGroupAvatar: + var info DirectMediaGroupAvatar + + if err = binary.Read(buf, binary.BigEndian, &info.UserID); err != nil { + return info, fmt.Errorf("failed to read user id: %w", err) + } else if binary.Read(buf, binary.BigEndian, &info.GroupID); err != nil { + return info, fmt.Errorf("failed to read group id: %w", err) + } + if groupAvatarPath, err := readByteSlice(buf, mediaIDLen); err != nil { + return info, fmt.Errorf("failed to read group avatar path: %w", err) + } else { + info.GroupAvatarPath = string(groupAvatarPath) + } + + return &info, nil + case directMediaTypeProfileAvatar: + var info DirectMediaProfileAvatar + + if err = binary.Read(buf, binary.BigEndian, &info.UserID); err != nil { + return info, fmt.Errorf("failed to read user id: %w", err) + } else if err = binary.Read(buf, binary.BigEndian, &info.ContactID); err != nil { + return info, fmt.Errorf("failed to read contact id: %w", err) + } + if profileAvatarPath, err := readByteSlice(buf, mediaIDLen); err != nil { + return info, fmt.Errorf("failed to read profile avatar path: %w", err) + } else { + info.ProfileAvatarPath = string(profileAvatarPath) + } + } + + return nil, fmt.Errorf("invalid direct media type %d", mediaType) +} + +func HashMediaID(mediaID networkid.MediaID) [32]byte { + return sha256.Sum256(mediaID) +} + +func writeUvarint(w io.Writer, i uint64) error { + _, err := w.Write(binary.AppendUvarint(nil, i)) + return err +} + +func writeByteSlice(w io.Writer, b []byte) error { + if err := writeUvarint(w, uint64(len(b))); err != nil { + return err + } + _, err := w.Write(b) + return err +} + +func readByteSlice(r *bufio.Reader, maxLength int) ([]byte, error) { + length, err := binary.ReadUvarint(r) + if err != nil { + return nil, fmt.Errorf("reading uvarint failed: %w", err) + } else if int(length) > maxLength { + return nil, fmt.Errorf("byte slice size larger than expected: %d > %d", length, maxLength) + } else if length == 0 { + return nil, nil + } + + buf := make([]byte, length) + _, err = io.ReadFull(r, buf) + return buf, err +} diff --git a/pkg/signalmeow/attachments.go b/pkg/signalmeow/attachments.go index d733b40..386d9cc 100644 --- a/pkg/signalmeow/attachments.go +++ b/pkg/signalmeow/attachments.go @@ -59,9 +59,13 @@ var ErrInvalidMACForAttachment = errors.New("invalid MAC for attachment") var ErrInvalidDigestForAttachment = errors.New("invalid digest for attachment") var ErrAttachmentNotFound = errors.New("attachment not found on server") -func DownloadAttachment(ctx context.Context, a *signalpb.AttachmentPointer) ([]byte, error) { - path := getAttachmentPath(a.GetCdnId(), a.GetCdnKey()) - resp, err := web.GetAttachment(ctx, path, a.GetCdnNumber(), nil) +func DownloadAttachmentWithPointer(ctx context.Context, a *signalpb.AttachmentPointer) ([]byte, error) { + return DownloadAttachment(ctx, a.GetCdnId(), a.GetCdnKey(), a.GetCdnNumber(), a.Key, a.Digest, a.GetSize()) +} + +func DownloadAttachment(ctx context.Context, cdnID uint64, cdnKey string, cdnNumber uint32, key, digest []byte, size uint32) ([]byte, error) { + path := getAttachmentPath(cdnID, cdnKey) + resp, err := web.GetAttachment(ctx, path, cdnNumber, nil) if err != nil { return nil, err } @@ -84,7 +88,7 @@ func DownloadAttachment(ctx context.Context, a *signalpb.AttachmentPointer) ([]b return nil, fmt.Errorf("unexpected status code %d", resp.StatusCode) } - return decryptAttachment(body, a.Key, a.Digest, *a.Size) + return decryptAttachment(body, key, digest, size) } const MACLength = 32 diff --git a/pkg/signalmeow/groups.go b/pkg/signalmeow/groups.go index ae44e12..f0b0815 100644 --- a/pkg/signalmeow/groups.go +++ b/pkg/signalmeow/groups.go @@ -42,11 +42,6 @@ import ( type GroupMemberRole int32 -type GroupAvatarMeta interface { - getGroupMasterKey() types.SerializedGroupMasterKey - GetAvatarPath() *string -} - const ( // Note: right now we assume these match the equivalent values in the protobuf (signalpb.Member_Role) GroupMember_UNKNOWN GroupMemberRole = 0 @@ -76,7 +71,7 @@ func (gm *GroupMember) UserServiceID() libsignalgo.ServiceID { } type Group struct { - groupMasterKey types.SerializedGroupMasterKey // We should keep this relatively private + GroupMasterKey types.SerializedGroupMasterKey // We should keep this relatively private GroupIdentifier types.GroupIdentifier // This is what we should use to identify a group outside this file Title string @@ -98,7 +93,7 @@ func (group *Group) GetInviteLink() (string, error) { if group.InviteLinkPassword == nil { return "", fmt.Errorf("no invite link password set") } - masterKeyBytes := masterKeyToBytes(group.groupMasterKey) + masterKeyBytes := masterKeyToBytes(group.GroupMasterKey) inviteLinkPasswordBytes, err := inviteLinkPasswordToBytes(*group.InviteLinkPassword) if err != nil { return "", fmt.Errorf("couldn't decode invite link password") @@ -124,13 +119,6 @@ type GroupAccessControl struct { Attributes AccessControl } -func (group *Group) getGroupMasterKey() types.SerializedGroupMasterKey { - return group.groupMasterKey -} -func (group *Group) GetAvatarPath() *string { - return &group.AvatarPath -} - type AddMember struct { GroupMember JoinFromInviteLink bool @@ -176,8 +164,7 @@ type BannedMember struct { } type GroupChange struct { - groupMasterKey types.SerializedGroupMasterKey - + GroupMasterKey types.SerializedGroupMasterKey SourceServiceID libsignalgo.ServiceID Revision uint32 AddMembers []*AddMember @@ -310,14 +297,6 @@ func (groupChange *GroupChange) resolveConflict(group *Group) { } } -func (groupChange *GroupChange) getGroupMasterKey() types.SerializedGroupMasterKey { - return groupChange.groupMasterKey -} - -func (groupChange *GroupChange) GetAvatarPath() *string { - return groupChange.ModifyAvatar -} - type GroupChangeState struct { GroupState *Group GroupChange *GroupChange @@ -481,7 +460,7 @@ func groupIdentifierFromMasterKey(masterKey types.SerializedGroupMasterKey) (typ func decryptGroup(ctx context.Context, encryptedGroup *signalpb.Group, groupMasterKey types.SerializedGroupMasterKey) (*Group, error) { log := zerolog.Ctx(ctx).With().Str("action", "decrypt group").Logger() decryptedGroup := &Group{ - groupMasterKey: groupMasterKey, + GroupMasterKey: groupMasterKey, } groupSecretParams, err := libsignalgo.DeriveGroupSecretParamsFromMasterKey(masterKeyToBytes(groupMasterKey)) @@ -642,7 +621,7 @@ func decryptGroupAvatar(encryptedAvatar []byte, groupMasterKey types.SerializedG } func groupMetadataForDataMessage(group Group) *signalpb.GroupContextV2 { - masterKey := masterKeyToBytes(group.groupMasterKey) + masterKey := masterKeyToBytes(group.GroupMasterKey) masterKeyBytes := masterKey[:] return &signalpb.GroupContextV2{ MasterKey: masterKeyBytes, @@ -710,16 +689,14 @@ func (cli *Client) fetchGroupWithMasterKey(ctx context.Context, groupMasterKey t return group, nil } -func (cli *Client) DownloadGroupAvatar(ctx context.Context, group GroupAvatarMeta) ([]byte, error) { - groupMasterKey := group.getGroupMasterKey() - avatarPath := group.GetAvatarPath() +func (cli *Client) DownloadGroupAvatar(ctx context.Context, avatarPath string, groupMasterKey types.SerializedGroupMasterKey) ([]byte, error) { username, password := cli.Store.BasicAuthCreds() opts := &web.HTTPReqOpt{ Host: web.CDN1Hostname, Username: &username, Password: &password, } - resp, err := web.SendHTTPRequest(ctx, http.MethodGet, *avatarPath, opts) + resp, err := web.SendHTTPRequest(ctx, http.MethodGet, avatarPath, opts) if err != nil { return nil, fmt.Errorf("failed to send request: %w", err) } @@ -853,7 +830,7 @@ func (cli *Client) decryptGroupChange(ctx context.Context, encryptedGroupChange return nil, fmt.Errorf("wrong serviceid kind: expected aci, got pni") } decryptedGroupChange := &GroupChange{ - groupMasterKey: groupMasterKey, + GroupMasterKey: groupMasterKey, Revision: encryptedActions.Revision, SourceServiceID: sourceServiceID, } @@ -1221,7 +1198,7 @@ func decryptRequestingMember(ctx context.Context, requestingMember *signalpb.Req func (cli *Client) EncryptAndSignGroupChange(ctx context.Context, decryptedGroupChange *GroupChange, gid types.GroupIdentifier) (*signalpb.GroupChange, error) { log := zerolog.Ctx(ctx).With().Str("action", "EncryptGroupChange").Logger() - groupMasterKey := decryptedGroupChange.groupMasterKey + groupMasterKey := decryptedGroupChange.GroupMasterKey masterKeyBytes := masterKeyToBytes(groupMasterKey) groupSecretParams, err := libsignalgo.DeriveGroupSecretParamsFromMasterKey(masterKeyBytes) if err != nil { @@ -1573,7 +1550,7 @@ func (cli *Client) UpdateGroup(ctx context.Context, groupChange *GroupChange, gi log.Err(err).Msg("Could not get master key from group id") return 0, err } - groupChange.groupMasterKey = groupMasterKey + groupChange.GroupMasterKey = groupMasterKey masterKeyBytes := masterKeyToBytes(groupMasterKey) var refetchedAddMemberCredentials bool var signedGroupChange *signalpb.GroupChange @@ -1789,7 +1766,7 @@ func (cli *Client) CreateGroup(ctx context.Context, decryptedGroup *Group, avata log.Err(err).Msg("Error creating group on server") return nil, err } - masterKeyBytes := masterKeyToBytes(group.groupMasterKey) + masterKeyBytes := masterKeyToBytes(group.GroupMasterKey) groupContext := &signalpb.GroupContextV2{Revision: &group.Revision, MasterKey: masterKeyBytes[:]} _, err = cli.SendGroupUpdate(ctx, group, groupContext, nil) if err != nil { diff --git a/pkg/signalmeow/receiving.go b/pkg/signalmeow/receiving.go index 6ea9885..f9324f7 100644 --- a/pkg/signalmeow/receiving.go +++ b/pkg/signalmeow/receiving.go @@ -812,7 +812,7 @@ func (cli *Client) handleDecryptedResult( log.Debug().Msg("Recieved sync message contacts") blob := content.SyncMessage.Contacts.Blob if blob != nil { - contactsBytes, err := DownloadAttachment(ctx, blob) + contactsBytes, err := DownloadAttachmentWithPointer(ctx, blob) if err != nil { log.Err(err).Msg("Contacts Sync DownloadAttachment error") } diff --git a/pkg/signalmeow/types/identifer.go b/pkg/signalmeow/types/identifer.go index c11238c..87ed647 100644 --- a/pkg/signalmeow/types/identifer.go +++ b/pkg/signalmeow/types/identifer.go @@ -31,7 +31,7 @@ func (gid GroupIdentifier) String() string { func (gid GroupIdentifier) Bytes() (raw libsignalgo.GroupIdentifier, err error) { var decoded []byte - decoded, err = base64.RawStdEncoding.DecodeString(string(gid)) + decoded, err = base64.StdEncoding.DecodeString(string(gid)) if err == nil { if len(decoded) != 32 { err = fmt.Errorf("invalid group identifier length") From 03af354d09444151bdece99545fb6f2e554c353d Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Mon, 12 May 2025 14:20:49 +0300 Subject: [PATCH 327/580] signalmeow/receiving: refactor decryption code --- pkg/signalmeow/receiving.go | 408 +++++++++++++----------------------- 1 file changed, 144 insertions(+), 264 deletions(-) diff --git a/pkg/signalmeow/receiving.go b/pkg/signalmeow/receiving.go index f9324f7..27394b2 100644 --- a/pkg/signalmeow/receiving.go +++ b/pkg/signalmeow/receiving.go @@ -345,12 +345,11 @@ func (cli *Client) decryptEnvelope( case signalpb.Envelope_UNIDENTIFIED_SENDER: result, err := cli.decryptUnidentifiedSenderEnvelope(ctx, destinationServiceID, envelope) if err != nil { - log.Err(err).Msg("Failed to decrypt sealed sender message") result.Err = fmt.Errorf("failed to decrypt unidentified sender envelope: %w", err) } return result - case signalpb.Envelope_PREKEY_BUNDLE: + case signalpb.Envelope_PREKEY_BUNDLE, signalpb.Envelope_CIPHERTEXT: sender, err := libsignalgo.NewUUIDAddressFromString( *envelope.SourceServiceId, uint(*envelope.SourceDevice), @@ -358,79 +357,23 @@ func (cli *Client) decryptEnvelope( if err != nil { return DecryptionResult{Err: fmt.Errorf("failed to wrap address: %v", err)} } - result, err := cli.prekeyDecrypt(ctx, destinationServiceID, sender, envelope.Content) - if err != nil { - log.Err(err).Msg("Failed to decrypt prekey bundle message") - return DecryptionResult{Err: fmt.Errorf("failed to decrypt prekey bundle envelope: %w", err), SenderAddress: sender} + var result *DecryptionResult + var bundleType string + if *envelope.Type == signalpb.Envelope_PREKEY_BUNDLE { + result, err = cli.prekeyDecrypt(ctx, destinationServiceID, sender, envelope.Content) + bundleType = "prekey bundle" + } else { + result, err = cli.decryptCiphertextEnvelope(ctx, destinationServiceID, sender, envelope.Content) + bundleType = "ciphertext" + } + if err != nil { + return DecryptionResult{Err: fmt.Errorf("failed to decrypt %s envelope: %w", bundleType, err), SenderAddress: sender} } - log.Trace(). - Any("sender_address", result.SenderAddress). - Any("content", result.Content). - Msg("Prekey bundle decryption result") return *result case signalpb.Envelope_PLAINTEXT_CONTENT: return DecryptionResult{Err: fmt.Errorf("plaintext messages are not supported")} - case signalpb.Envelope_CIPHERTEXT: - senderAddress, err := libsignalgo.NewUUIDAddressFromString( - *envelope.SourceServiceId, - uint(*envelope.SourceDevice), - ) - if err != nil { - return DecryptionResult{Err: fmt.Errorf("failed to wrap address: %w", err)} - } - message, err := libsignalgo.DeserializeMessage(envelope.Content) - if err != nil { - log.Err(err).Msg("Failed to deserialize ciphertext message") - return DecryptionResult{ - Err: fmt.Errorf("failed to deserialize message: %w", err), - SenderAddress: senderAddress, - } - } - sessionStore := cli.Store.SessionStore(destinationServiceID) - if sessionStore == nil { - return DecryptionResult{ - Err: fmt.Errorf("no session store for destination service ID %s", destinationServiceID), - SenderAddress: senderAddress, - } - } - identityStore := cli.Store.IdentityStore(destinationServiceID) - if identityStore == nil { - return DecryptionResult{ - Err: fmt.Errorf("no identity store for destination service ID %s", destinationServiceID), - SenderAddress: senderAddress, - } - } - decryptedText, err := libsignalgo.Decrypt( - ctx, - message, - senderAddress, - sessionStore, - identityStore, - ) - if err != nil { - if strings.Contains(err.Error(), "message with old counter") { - log.Warn().Err(err).Msg("Duplicate message error while decrypting whisper ciphertext") - } else { - log.Err(err).Msg("Failed to decrypt whisper ciphertext message") - } - return DecryptionResult{Err: fmt.Errorf("failed to decrypt ciphertext message: %w", err), SenderAddress: senderAddress} - } - err = stripPadding(&decryptedText) - if err != nil { - return DecryptionResult{Err: fmt.Errorf("failed to strip padding: %w", err), SenderAddress: senderAddress} - } - content := signalpb.Content{} - err = proto.Unmarshal(decryptedText, &content) - if err != nil { - return DecryptionResult{Err: fmt.Errorf("failed to unmarshal decrypted message: %w", err), SenderAddress: senderAddress} - } - return DecryptionResult{ - SenderAddress: senderAddress, - Content: &content, - } - case signalpb.Envelope_SERVER_DELIVERY_RECEIPT: return DecryptionResult{Err: fmt.Errorf("server delivery receipt envelopes are not yet supported")} @@ -441,10 +384,133 @@ func (cli *Client) decryptEnvelope( return DecryptionResult{Err: fmt.Errorf("unknown envelope type")} default: - return DecryptionResult{Err: fmt.Errorf("unrecognized envelope type")} + return DecryptionResult{Err: fmt.Errorf("unrecognized envelope type %d", envelope.GetType())} } } +func (cli *Client) prekeyDecrypt(ctx context.Context, destination libsignalgo.ServiceID, sender *libsignalgo.Address, encryptedContent []byte) (*DecryptionResult, error) { + preKeyMessage, err := libsignalgo.DeserializePreKeyMessage(encryptedContent) + if err != nil { + return nil, fmt.Errorf("failed to deserialize prekey message: %w", err) + } else if preKeyMessage == nil { + return nil, fmt.Errorf("deserializing prekey message returned nil") + } + pks := cli.Store.PreKeyStore(destination) + if pks == nil { + return nil, fmt.Errorf("no prekey store found for %s", destination) + } + ss := cli.Store.SessionStore(destination) + if ss == nil { + return nil, fmt.Errorf("no session store found for %s", destination) + } + is := cli.Store.IdentityStore(destination) + if is == nil { + return nil, fmt.Errorf("no identity store found for %s", destination) + } + + data, err := libsignalgo.DecryptPreKey( + ctx, + preKeyMessage, + sender, + ss, + is, + pks, + pks, + pks, + ) + if err != nil { + return nil, fmt.Errorf("failed to decrypt prekey message: %w", err) + } + err = stripPadding(&data) + if err != nil { + return nil, fmt.Errorf("failed to strip padding: %w", err) + } + content := &signalpb.Content{} + err = proto.Unmarshal(data, content) + if err != nil { + return nil, fmt.Errorf("failed to unmarshal decrypted prekey message: %w", err) + } + return &DecryptionResult{ + SenderAddress: sender, + Content: content, + }, nil +} + +func (cli *Client) decryptCiphertextEnvelope( + ctx context.Context, + destinationServiceID libsignalgo.ServiceID, + senderAddress *libsignalgo.Address, + ciphertext []byte, +) (*DecryptionResult, error) { + log := zerolog.Ctx(ctx) + message, err := libsignalgo.DeserializeMessage(ciphertext) + if err != nil { + log.Err(err).Msg("Failed to deserialize ciphertext message") + return nil, fmt.Errorf("failed to deserialize message: %w", err) + } + sessionStore := cli.Store.SessionStore(destinationServiceID) + if sessionStore == nil { + return nil, fmt.Errorf("no session store for destination service ID %s", destinationServiceID) + } + identityStore := cli.Store.IdentityStore(destinationServiceID) + if identityStore == nil { + return nil, fmt.Errorf("no identity store for destination service ID %s", destinationServiceID) + } + decryptedText, err := libsignalgo.Decrypt( + ctx, + message, + senderAddress, + sessionStore, + identityStore, + ) + if err != nil { + if strings.Contains(err.Error(), "message with old counter") { + log.Warn().Err(err).Msg("Duplicate message error while decrypting whisper ciphertext") + } else { + log.Err(err).Msg("Failed to decrypt whisper ciphertext message") + } + return nil, fmt.Errorf("failed to decrypt ciphertext message: %w", err) + } + err = stripPadding(&decryptedText) + if err != nil { + return nil, fmt.Errorf("failed to strip padding: %w", err) + } + content := signalpb.Content{} + err = proto.Unmarshal(decryptedText, &content) + if err != nil { + return nil, fmt.Errorf("failed to unmarshal decrypted message: %w", err) + } + return &DecryptionResult{ + SenderAddress: senderAddress, + Content: &content, + }, nil +} + +func (cli *Client) decryptSenderKeyMessage(ctx context.Context, senderAddress *libsignalgo.Address, ciphertext []byte) (*DecryptionResult, error) { + decryptedText, err := libsignalgo.GroupDecrypt( + ctx, + ciphertext, + senderAddress, + cli.Store.SenderKeyStore, + ) + if err != nil { + return nil, fmt.Errorf("failed to decrypt sender key message: %w", err) + } + err = stripPadding(&decryptedText) + if err != nil { + return nil, fmt.Errorf("failed to strip padding: %w", err) + } + content := signalpb.Content{} + err = proto.Unmarshal(decryptedText, &content) + if err != nil { + return nil, fmt.Errorf("failed to unmarshal decrypted sender key message: %w", err) + } + return &DecryptionResult{ + SenderAddress: senderAddress, + Content: &content, + }, nil +} + func (cli *Client) decryptUnidentifiedSenderEnvelope(ctx context.Context, destinationServiceID libsignalgo.ServiceID, envelope *signalpb.Envelope) (result DecryptionResult, err error) { log := zerolog.Ctx(ctx) @@ -515,121 +581,25 @@ func (cli *Client) decryptUnidentifiedSenderEnvelope(ctx context.Context, destin } } + var resultPtr *DecryptionResult switch messageType { case libsignalgo.CiphertextMessageTypeSenderKey: - decryptedText, err := libsignalgo.GroupDecrypt( - ctx, - usmcContents, - senderAddress, - cli.Store.SenderKeyStore, - ) - if err != nil { - if strings.Contains(err.Error(), "message with old counter") { - log.Warn().Err(err).Msg("Duplicate message error while decrypting sealed sender sender key") - return result, err - } - log.Err(err).Msg("Failed to decrypt sealed sender sender key message, trying generic function") - return cli.fallbackDecryptSealedSender(ctx, result, envelope) - } - err = stripPadding(&decryptedText) - if err != nil { - return result, fmt.Errorf("failed to strip padding: %w", err) - } - content := signalpb.Content{} - err = proto.Unmarshal(decryptedText, &content) - if err != nil { - return result, fmt.Errorf("failed to unmarshal decrypted sender key message: %w", err) - } - result.Content = &content - return result, nil - + resultPtr, err = cli.decryptSenderKeyMessage(ctx, senderAddress, usmcContents) case libsignalgo.CiphertextMessageTypePreKey: - var resultPtr *DecryptionResult resultPtr, err = cli.prekeyDecrypt(ctx, destinationServiceID, senderAddress, usmcContents) - if err != nil { - log.Err(err).Msg("Failed to decrypt sealed sender prekey message, trying generic function") - return cli.fallbackDecryptSealedSender(ctx, result, envelope) - } - return *resultPtr, nil - case libsignalgo.CiphertextMessageTypeWhisper: - message, err := libsignalgo.DeserializeMessage(usmcContents) - if err != nil { - return result, fmt.Errorf("failed to deserialize whisper message: %w", err) - } - decryptedText, err := libsignalgo.Decrypt( - ctx, - message, - senderAddress, - cli.Store.ACISessionStore, - cli.Store.ACIIdentityStore, - ) - if err != nil { - log.Err(err).Msg("Failed to decrypt whisper message, trying generic function") - return cli.fallbackDecryptSealedSender(ctx, result, envelope) - } - err = stripPadding(&decryptedText) - if err != nil { - return result, fmt.Errorf("failed to strip padding: %w", err) - } - content := signalpb.Content{} - err = proto.Unmarshal(decryptedText, &content) - if err != nil { - return result, fmt.Errorf("failed to unmarshal decrypted whisper message: %w", err) - } - result.Content = &content - return result, nil - + resultPtr, err = cli.decryptCiphertextEnvelope(ctx, destinationServiceID, senderAddress, usmcContents) case libsignalgo.CiphertextMessageTypePlaintext: - log.Warn().Msg("Unsupported plaintext sealed sender message") // TODO: handle plaintext (usually DecryptionErrorMessage) and retries - // when implementing SenderKey groups - - //plaintextContent, err := libsignalgo.DeserializePlaintextContent(usmcContents) - //if err != nil { - // log.Err(err).Msg("DeserializePlaintextContent error") - //} - //body, err := plaintextContent.GetBody() - //if err != nil { - // log.Err(err).Msg("PlaintextContent GetBody error") - //} - //content := signalpb.Content{} - //err = proto.Unmarshal(body, &content) - //if err != nil { - // log.Err(err).Msg("PlaintextContent Unmarshal error") - //} - //result = &DecryptionResult{ - // SenderAddress: *senderAddress, - // Content: &content, - // SealedSender: true, - //} - - return result, fmt.Errorf("plaintext sealed sender messages are not supported") - + // when implementing SenderKey groups + return result, fmt.Errorf("unsupported plaintext sealed sender message") default: - log.Warn().Msg("Unrecognized sealed sender message type") - return cli.fallbackDecryptSealedSender(ctx, result, envelope) + return result, fmt.Errorf("unsupported sealed sender message type %d", messageType) } -} - -func (cli *Client) fallbackDecryptSealedSender(ctx context.Context, fallbackResult DecryptionResult, envelope *signalpb.Envelope) (DecryptionResult, error) { - log := zerolog.Ctx(ctx) - result, err := cli.sealedSenderDecrypt(ctx, envelope) if err != nil { - if strings.Contains(err.Error(), "self send of a sealed sender message") { - log.Debug().Msg("Message sent by us, ignoring") - } else if strings.Contains(err.Error(), "message with old counter") { - log.Info().Msg("Duplicate message, ignoring (sealedSenderDecrypt)") - } else { - log.Err(err).Msg("Failed to decrypt sealed sender message with fallback method") - } - return fallbackResult, fmt.Errorf("failed to decrypt unrecognized sealed sender message: %w", err) + return result, err } - log.Trace(). - Any("sender_address", result.SenderAddress). - Any("content", result.Content). - Msg("SealedSender decrypt result") - return *result, nil + return *resultPtr, nil } // TODO: we should split this up into multiple functions @@ -1118,7 +1088,6 @@ type DecryptionResult struct { SenderAddress *libsignalgo.Address Content *signalpb.Content ContentHint signalpb.UnidentifiedSenderMessage_Message_ContentHint - SealedSender bool Err error } @@ -1132,95 +1101,6 @@ func init() { prodServerTrustRootKey.CancelFinalizer() } -func (cli *Client) sealedSenderDecrypt(ctx context.Context, envelope *signalpb.Envelope) (*DecryptionResult, error) { - localAddress := libsignalgo.NewSealedSenderAddress( - cli.Store.Number, - cli.Store.ACI, - uint32(cli.Store.DeviceID), - ) - result, err := libsignalgo.SealedSenderDecrypt( - ctx, - envelope.Content, - localAddress, - prodServerTrustRootKey, - envelope.GetTimestamp(), - cli.Store.ACISessionStore, - cli.Store.ACIIdentityStore, - cli.Store.ACIPreKeyStore, - cli.Store.ACIPreKeyStore, - ) - if err != nil { - return nil, err - } - - msg := result.Message - err = stripPadding(&msg) - if err != nil { - return nil, fmt.Errorf("failed to strip padding: %w", err) - } - address, err := libsignalgo.NewACIServiceID(result.Sender.UUID).Address(uint(result.Sender.DeviceID)) - if err != nil { - return nil, fmt.Errorf("failed to wrap sender address: %w", err) - } - content := &signalpb.Content{} - err = proto.Unmarshal(msg, content) - if err != nil { - return nil, fmt.Errorf("failed to unmarshal decrypted content: %w", err) - } - return &DecryptionResult{ - SenderAddress: address, - Content: content, - }, nil -} - -func (cli *Client) prekeyDecrypt(ctx context.Context, destination libsignalgo.ServiceID, sender *libsignalgo.Address, encryptedContent []byte) (*DecryptionResult, error) { - preKeyMessage, err := libsignalgo.DeserializePreKeyMessage(encryptedContent) - if err != nil { - return nil, fmt.Errorf("failed to deserialize prekey message: %w", err) - } else if preKeyMessage == nil { - return nil, fmt.Errorf("deserializing prekey message returned nil") - } - pks := cli.Store.PreKeyStore(destination) - if pks == nil { - return nil, fmt.Errorf("no prekey store found for %s", destination) - } - ss := cli.Store.SessionStore(destination) - if ss == nil { - return nil, fmt.Errorf("no session store found for %s", destination) - } - is := cli.Store.IdentityStore(destination) - if is == nil { - return nil, fmt.Errorf("no identity store found for %s", destination) - } - - data, err := libsignalgo.DecryptPreKey( - ctx, - preKeyMessage, - sender, - ss, - is, - pks, - pks, - pks, - ) - if err != nil { - return nil, fmt.Errorf("failed to decrypt prekey message: %w", err) - } - err = stripPadding(&data) - if err != nil { - return nil, fmt.Errorf("failed to strip padding: %w", err) - } - content := &signalpb.Content{} - err = proto.Unmarshal(data, content) - if err != nil { - return nil, fmt.Errorf("failed to unmarshal decrypted prekey message: %w", err) - } - return &DecryptionResult{ - SenderAddress: sender, - Content: content, - }, nil -} - func stripPadding(contents *[]byte) error { for i := len(*contents) - 1; i >= 0; i-- { if (*contents)[i] == 0x80 { From 25497d1601a6ab2ff88ebc1f43880d6b8c1e6bba Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Mon, 12 May 2025 14:27:16 +0300 Subject: [PATCH 328/580] signalmeow/receiving: split decrypting code to separate file --- pkg/signalmeow/receiving.go | 293 +------------------------ pkg/signalmeow/receiving_decrypt.go | 327 ++++++++++++++++++++++++++++ 2 files changed, 328 insertions(+), 292 deletions(-) create mode 100644 pkg/signalmeow/receiving_decrypt.go diff --git a/pkg/signalmeow/receiving.go b/pkg/signalmeow/receiving.go index 27394b2..18c2240 100644 --- a/pkg/signalmeow/receiving.go +++ b/pkg/signalmeow/receiving.go @@ -1,5 +1,6 @@ // mautrix-signal - A Matrix-signal puppeting bridge. // Copyright (C) 2023 Scott Weber +// Copyright (C) 2025 Tulir Asokan // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU Affero General Public License as published by @@ -329,279 +330,6 @@ func (cli *Client) incomingAPIMessageHandler(ctx context.Context, req *signalpb. }, nil } -func (cli *Client) decryptEnvelope( - ctx context.Context, - envelope *signalpb.Envelope, -) DecryptionResult { - log := zerolog.Ctx(ctx) - - destinationServiceID, err := libsignalgo.ServiceIDFromString(envelope.GetDestinationServiceId()) - if err != nil { - log.Err(err).Str("destination_service_id", envelope.GetDestinationServiceId()).Msg("Failed to parse destination service ID") - return DecryptionResult{Err: fmt.Errorf("failed to parse destination service ID: %w", err)} - } - - switch *envelope.Type { - case signalpb.Envelope_UNIDENTIFIED_SENDER: - result, err := cli.decryptUnidentifiedSenderEnvelope(ctx, destinationServiceID, envelope) - if err != nil { - result.Err = fmt.Errorf("failed to decrypt unidentified sender envelope: %w", err) - } - return result - - case signalpb.Envelope_PREKEY_BUNDLE, signalpb.Envelope_CIPHERTEXT: - sender, err := libsignalgo.NewUUIDAddressFromString( - *envelope.SourceServiceId, - uint(*envelope.SourceDevice), - ) - if err != nil { - return DecryptionResult{Err: fmt.Errorf("failed to wrap address: %v", err)} - } - var result *DecryptionResult - var bundleType string - if *envelope.Type == signalpb.Envelope_PREKEY_BUNDLE { - result, err = cli.prekeyDecrypt(ctx, destinationServiceID, sender, envelope.Content) - bundleType = "prekey bundle" - } else { - result, err = cli.decryptCiphertextEnvelope(ctx, destinationServiceID, sender, envelope.Content) - bundleType = "ciphertext" - } - if err != nil { - return DecryptionResult{Err: fmt.Errorf("failed to decrypt %s envelope: %w", bundleType, err), SenderAddress: sender} - } - return *result - - case signalpb.Envelope_PLAINTEXT_CONTENT: - return DecryptionResult{Err: fmt.Errorf("plaintext messages are not supported")} - - case signalpb.Envelope_SERVER_DELIVERY_RECEIPT: - return DecryptionResult{Err: fmt.Errorf("server delivery receipt envelopes are not yet supported")} - - case signalpb.Envelope_SENDERKEY_MESSAGE: - return DecryptionResult{Err: fmt.Errorf("senderkey message envelopes are not yet supported")} - - case signalpb.Envelope_UNKNOWN: - return DecryptionResult{Err: fmt.Errorf("unknown envelope type")} - - default: - return DecryptionResult{Err: fmt.Errorf("unrecognized envelope type %d", envelope.GetType())} - } -} - -func (cli *Client) prekeyDecrypt(ctx context.Context, destination libsignalgo.ServiceID, sender *libsignalgo.Address, encryptedContent []byte) (*DecryptionResult, error) { - preKeyMessage, err := libsignalgo.DeserializePreKeyMessage(encryptedContent) - if err != nil { - return nil, fmt.Errorf("failed to deserialize prekey message: %w", err) - } else if preKeyMessage == nil { - return nil, fmt.Errorf("deserializing prekey message returned nil") - } - pks := cli.Store.PreKeyStore(destination) - if pks == nil { - return nil, fmt.Errorf("no prekey store found for %s", destination) - } - ss := cli.Store.SessionStore(destination) - if ss == nil { - return nil, fmt.Errorf("no session store found for %s", destination) - } - is := cli.Store.IdentityStore(destination) - if is == nil { - return nil, fmt.Errorf("no identity store found for %s", destination) - } - - data, err := libsignalgo.DecryptPreKey( - ctx, - preKeyMessage, - sender, - ss, - is, - pks, - pks, - pks, - ) - if err != nil { - return nil, fmt.Errorf("failed to decrypt prekey message: %w", err) - } - err = stripPadding(&data) - if err != nil { - return nil, fmt.Errorf("failed to strip padding: %w", err) - } - content := &signalpb.Content{} - err = proto.Unmarshal(data, content) - if err != nil { - return nil, fmt.Errorf("failed to unmarshal decrypted prekey message: %w", err) - } - return &DecryptionResult{ - SenderAddress: sender, - Content: content, - }, nil -} - -func (cli *Client) decryptCiphertextEnvelope( - ctx context.Context, - destinationServiceID libsignalgo.ServiceID, - senderAddress *libsignalgo.Address, - ciphertext []byte, -) (*DecryptionResult, error) { - log := zerolog.Ctx(ctx) - message, err := libsignalgo.DeserializeMessage(ciphertext) - if err != nil { - log.Err(err).Msg("Failed to deserialize ciphertext message") - return nil, fmt.Errorf("failed to deserialize message: %w", err) - } - sessionStore := cli.Store.SessionStore(destinationServiceID) - if sessionStore == nil { - return nil, fmt.Errorf("no session store for destination service ID %s", destinationServiceID) - } - identityStore := cli.Store.IdentityStore(destinationServiceID) - if identityStore == nil { - return nil, fmt.Errorf("no identity store for destination service ID %s", destinationServiceID) - } - decryptedText, err := libsignalgo.Decrypt( - ctx, - message, - senderAddress, - sessionStore, - identityStore, - ) - if err != nil { - if strings.Contains(err.Error(), "message with old counter") { - log.Warn().Err(err).Msg("Duplicate message error while decrypting whisper ciphertext") - } else { - log.Err(err).Msg("Failed to decrypt whisper ciphertext message") - } - return nil, fmt.Errorf("failed to decrypt ciphertext message: %w", err) - } - err = stripPadding(&decryptedText) - if err != nil { - return nil, fmt.Errorf("failed to strip padding: %w", err) - } - content := signalpb.Content{} - err = proto.Unmarshal(decryptedText, &content) - if err != nil { - return nil, fmt.Errorf("failed to unmarshal decrypted message: %w", err) - } - return &DecryptionResult{ - SenderAddress: senderAddress, - Content: &content, - }, nil -} - -func (cli *Client) decryptSenderKeyMessage(ctx context.Context, senderAddress *libsignalgo.Address, ciphertext []byte) (*DecryptionResult, error) { - decryptedText, err := libsignalgo.GroupDecrypt( - ctx, - ciphertext, - senderAddress, - cli.Store.SenderKeyStore, - ) - if err != nil { - return nil, fmt.Errorf("failed to decrypt sender key message: %w", err) - } - err = stripPadding(&decryptedText) - if err != nil { - return nil, fmt.Errorf("failed to strip padding: %w", err) - } - content := signalpb.Content{} - err = proto.Unmarshal(decryptedText, &content) - if err != nil { - return nil, fmt.Errorf("failed to unmarshal decrypted sender key message: %w", err) - } - return &DecryptionResult{ - SenderAddress: senderAddress, - Content: &content, - }, nil -} - -func (cli *Client) decryptUnidentifiedSenderEnvelope(ctx context.Context, destinationServiceID libsignalgo.ServiceID, envelope *signalpb.Envelope) (result DecryptionResult, err error) { - log := zerolog.Ctx(ctx) - - if destinationServiceID != cli.Store.ACIServiceID() { - log.Warn().Stringer("destination_service_id", destinationServiceID). - Msg("Received UNIDENTIFIED_SENDER envelope for non-ACI destination") - return result, fmt.Errorf("received unidentified sender envelope for non-ACI destination") - } - usmc, err := libsignalgo.SealedSenderDecryptToUSMC( - ctx, - envelope.GetContent(), - cli.Store.ACIIdentityStore, - ) - if err != nil { - return result, fmt.Errorf("failed to decrypt to USMC: %w", err) - } else if usmc == nil { - return result, fmt.Errorf("decrypting to USMC returned nil") - } - - messageType, err := usmc.GetMessageType() - if err != nil { - return result, fmt.Errorf("failed to get message type: %w", err) - } - senderCertificate, err := usmc.GetSenderCertificate() - if err != nil { - return result, fmt.Errorf("failed to get sender certificate: %w", err) - } - contentHint, err := usmc.GetContentHint() - if err != nil { - return result, fmt.Errorf("failed to get content hint: %w", err) - } - result.ContentHint = signalpb.UnidentifiedSenderMessage_Message_ContentHint(contentHint) - senderUUID, err := senderCertificate.GetSenderUUID() - if err != nil { - return result, fmt.Errorf("failed to get sender UUID: %w", err) - } - senderDeviceID, err := senderCertificate.GetDeviceID() - if err != nil { - return result, fmt.Errorf("failed to get sender device ID: %w", err) - } - senderAddress, err := libsignalgo.NewACIServiceID(senderUUID).Address(uint(senderDeviceID)) - if err != nil { - return result, fmt.Errorf("failed to create sender address: %w", err) - } - result.SenderAddress = senderAddress - senderE164, err := senderCertificate.GetSenderE164() - if err != nil { - return result, fmt.Errorf("failed to get sender E164: %w", err) - } - usmcContents, err := usmc.GetContents() - if err != nil { - return result, fmt.Errorf("failed to get USMC contents: %w", err) - } - newLog := log.With(). - Stringer("sender_uuid", senderUUID). - Uint32("sender_device_id", senderDeviceID). - Str("sender_e164", senderE164). - Uint8("sealed_sender_type", uint8(messageType)). - Logger() - log = &newLog - ctx = log.WithContext(ctx) - log.Trace().Msg("Received SealedSender message") - - if senderE164 != "" { - _, err = cli.Store.RecipientStore.UpdateRecipientE164(ctx, senderUUID, uuid.Nil, senderE164) - if err != nil { - log.Warn().Err(err).Msg("Failed to update sender E164 in recipient store") - } - } - - var resultPtr *DecryptionResult - switch messageType { - case libsignalgo.CiphertextMessageTypeSenderKey: - resultPtr, err = cli.decryptSenderKeyMessage(ctx, senderAddress, usmcContents) - case libsignalgo.CiphertextMessageTypePreKey: - resultPtr, err = cli.prekeyDecrypt(ctx, destinationServiceID, senderAddress, usmcContents) - case libsignalgo.CiphertextMessageTypeWhisper: - resultPtr, err = cli.decryptCiphertextEnvelope(ctx, destinationServiceID, senderAddress, usmcContents) - case libsignalgo.CiphertextMessageTypePlaintext: - // TODO: handle plaintext (usually DecryptionErrorMessage) and retries - // when implementing SenderKey groups - return result, fmt.Errorf("unsupported plaintext sealed sender message") - default: - return result, fmt.Errorf("unsupported sealed sender message type %d", messageType) - } - if err != nil { - return result, err - } - return *resultPtr, nil -} - // TODO: we should split this up into multiple functions func (cli *Client) handleDecryptedResult( ctx context.Context, @@ -1084,13 +812,6 @@ func (cli *Client) sendDeliveryReceipts(ctx context.Context, deliveredTimestamps return nil } -type DecryptionResult struct { - SenderAddress *libsignalgo.Address - Content *signalpb.Content - ContentHint signalpb.UnidentifiedSenderMessage_Message_ContentHint - Err error -} - const prodServerTrustRootStr = "BXu6QIKVz5MA8gstzfOgRQGqyLqOwNKHL6INkv3IHWMF" var prodServerTrustRootBytes = exerrors.Must(base64.StdEncoding.DecodeString(prodServerTrustRootStr)) @@ -1100,15 +821,3 @@ func init() { // It's never going to be freed anyway prodServerTrustRootKey.CancelFinalizer() } - -func stripPadding(contents *[]byte) error { - for i := len(*contents) - 1; i >= 0; i-- { - if (*contents)[i] == 0x80 { - *contents = (*contents)[:i] - return nil - } else if (*contents)[i] != 0x00 { - return fmt.Errorf("Invalid ISO7816 padding") - } - } - return fmt.Errorf("Invalid ISO7816 padding, len(contents): %v", len(*contents)) -} diff --git a/pkg/signalmeow/receiving_decrypt.go b/pkg/signalmeow/receiving_decrypt.go new file mode 100644 index 0000000..1c9c408 --- /dev/null +++ b/pkg/signalmeow/receiving_decrypt.go @@ -0,0 +1,327 @@ +// mautrix-signal - A Matrix-signal puppeting bridge. +// Copyright (C) 2023 Scott Weber +// Copyright (C) 2025 Tulir Asokan +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +package signalmeow + +import ( + "context" + "fmt" + "strings" + + "github.com/google/uuid" + "github.com/rs/zerolog" + "google.golang.org/protobuf/proto" + + "go.mau.fi/mautrix-signal/pkg/libsignalgo" + signalpb "go.mau.fi/mautrix-signal/pkg/signalmeow/protobuf" +) + +type DecryptionResult struct { + SenderAddress *libsignalgo.Address + Content *signalpb.Content + ContentHint signalpb.UnidentifiedSenderMessage_Message_ContentHint + Err error +} + +func (cli *Client) decryptEnvelope( + ctx context.Context, + envelope *signalpb.Envelope, +) DecryptionResult { + log := zerolog.Ctx(ctx) + + destinationServiceID, err := libsignalgo.ServiceIDFromString(envelope.GetDestinationServiceId()) + if err != nil { + log.Err(err).Str("destination_service_id", envelope.GetDestinationServiceId()).Msg("Failed to parse destination service ID") + return DecryptionResult{Err: fmt.Errorf("failed to parse destination service ID: %w", err)} + } + + switch *envelope.Type { + case signalpb.Envelope_UNIDENTIFIED_SENDER: + result, err := cli.decryptUnidentifiedSenderEnvelope(ctx, destinationServiceID, envelope) + if err != nil { + result.Err = fmt.Errorf("failed to decrypt unidentified sender envelope: %w", err) + } + return result + + case signalpb.Envelope_PREKEY_BUNDLE, signalpb.Envelope_CIPHERTEXT: + sender, err := libsignalgo.NewUUIDAddressFromString( + *envelope.SourceServiceId, + uint(*envelope.SourceDevice), + ) + if err != nil { + return DecryptionResult{Err: fmt.Errorf("failed to wrap address: %v", err)} + } + var result *DecryptionResult + var bundleType string + if *envelope.Type == signalpb.Envelope_PREKEY_BUNDLE { + result, err = cli.prekeyDecrypt(ctx, destinationServiceID, sender, envelope.Content) + bundleType = "prekey bundle" + } else { + result, err = cli.decryptCiphertextEnvelope(ctx, destinationServiceID, sender, envelope.Content) + bundleType = "ciphertext" + } + if err != nil { + return DecryptionResult{Err: fmt.Errorf("failed to decrypt %s envelope: %w", bundleType, err), SenderAddress: sender} + } + return *result + + case signalpb.Envelope_PLAINTEXT_CONTENT: + return DecryptionResult{Err: fmt.Errorf("plaintext messages are not supported")} + + case signalpb.Envelope_SERVER_DELIVERY_RECEIPT: + return DecryptionResult{Err: fmt.Errorf("server delivery receipt envelopes are not yet supported")} + + case signalpb.Envelope_SENDERKEY_MESSAGE: + return DecryptionResult{Err: fmt.Errorf("senderkey message envelopes are not yet supported")} + + case signalpb.Envelope_UNKNOWN: + return DecryptionResult{Err: fmt.Errorf("unknown envelope type")} + + default: + return DecryptionResult{Err: fmt.Errorf("unrecognized envelope type %d", envelope.GetType())} + } +} + +func (cli *Client) prekeyDecrypt(ctx context.Context, destination libsignalgo.ServiceID, sender *libsignalgo.Address, encryptedContent []byte) (*DecryptionResult, error) { + preKeyMessage, err := libsignalgo.DeserializePreKeyMessage(encryptedContent) + if err != nil { + return nil, fmt.Errorf("failed to deserialize prekey message: %w", err) + } else if preKeyMessage == nil { + return nil, fmt.Errorf("deserializing prekey message returned nil") + } + pks := cli.Store.PreKeyStore(destination) + if pks == nil { + return nil, fmt.Errorf("no prekey store found for %s", destination) + } + ss := cli.Store.SessionStore(destination) + if ss == nil { + return nil, fmt.Errorf("no session store found for %s", destination) + } + is := cli.Store.IdentityStore(destination) + if is == nil { + return nil, fmt.Errorf("no identity store found for %s", destination) + } + + data, err := libsignalgo.DecryptPreKey( + ctx, + preKeyMessage, + sender, + ss, + is, + pks, + pks, + pks, + ) + if err != nil { + return nil, fmt.Errorf("failed to decrypt prekey message: %w", err) + } + err = stripPadding(&data) + if err != nil { + return nil, fmt.Errorf("failed to strip padding: %w", err) + } + content := &signalpb.Content{} + err = proto.Unmarshal(data, content) + if err != nil { + return nil, fmt.Errorf("failed to unmarshal decrypted prekey message: %w", err) + } + return &DecryptionResult{ + SenderAddress: sender, + Content: content, + }, nil +} + +func (cli *Client) decryptCiphertextEnvelope( + ctx context.Context, + destinationServiceID libsignalgo.ServiceID, + senderAddress *libsignalgo.Address, + ciphertext []byte, +) (*DecryptionResult, error) { + log := zerolog.Ctx(ctx) + message, err := libsignalgo.DeserializeMessage(ciphertext) + if err != nil { + log.Err(err).Msg("Failed to deserialize ciphertext message") + return nil, fmt.Errorf("failed to deserialize message: %w", err) + } + sessionStore := cli.Store.SessionStore(destinationServiceID) + if sessionStore == nil { + return nil, fmt.Errorf("no session store for destination service ID %s", destinationServiceID) + } + identityStore := cli.Store.IdentityStore(destinationServiceID) + if identityStore == nil { + return nil, fmt.Errorf("no identity store for destination service ID %s", destinationServiceID) + } + decryptedText, err := libsignalgo.Decrypt( + ctx, + message, + senderAddress, + sessionStore, + identityStore, + ) + if err != nil { + if strings.Contains(err.Error(), "message with old counter") { + log.Warn().Err(err).Msg("Duplicate message error while decrypting whisper ciphertext") + } else { + log.Err(err).Msg("Failed to decrypt whisper ciphertext message") + } + return nil, fmt.Errorf("failed to decrypt ciphertext message: %w", err) + } + err = stripPadding(&decryptedText) + if err != nil { + return nil, fmt.Errorf("failed to strip padding: %w", err) + } + content := signalpb.Content{} + err = proto.Unmarshal(decryptedText, &content) + if err != nil { + return nil, fmt.Errorf("failed to unmarshal decrypted message: %w", err) + } + return &DecryptionResult{ + SenderAddress: senderAddress, + Content: &content, + }, nil +} + +func (cli *Client) decryptSenderKeyMessage( + ctx context.Context, + senderAddress *libsignalgo.Address, + ciphertext []byte, +) (*DecryptionResult, error) { + decryptedText, err := libsignalgo.GroupDecrypt( + ctx, + ciphertext, + senderAddress, + cli.Store.SenderKeyStore, + ) + if err != nil { + return nil, fmt.Errorf("failed to decrypt sender key message: %w", err) + } + err = stripPadding(&decryptedText) + if err != nil { + return nil, fmt.Errorf("failed to strip padding: %w", err) + } + content := signalpb.Content{} + err = proto.Unmarshal(decryptedText, &content) + if err != nil { + return nil, fmt.Errorf("failed to unmarshal decrypted sender key message: %w", err) + } + return &DecryptionResult{ + SenderAddress: senderAddress, + Content: &content, + }, nil +} + +func (cli *Client) decryptUnidentifiedSenderEnvelope(ctx context.Context, destinationServiceID libsignalgo.ServiceID, envelope *signalpb.Envelope) (result DecryptionResult, err error) { + log := zerolog.Ctx(ctx) + + if destinationServiceID != cli.Store.ACIServiceID() { + log.Warn().Stringer("destination_service_id", destinationServiceID). + Msg("Received UNIDENTIFIED_SENDER envelope for non-ACI destination") + return result, fmt.Errorf("received unidentified sender envelope for non-ACI destination") + } + usmc, err := libsignalgo.SealedSenderDecryptToUSMC( + ctx, + envelope.GetContent(), + cli.Store.ACIIdentityStore, + ) + if err != nil { + return result, fmt.Errorf("failed to decrypt to USMC: %w", err) + } else if usmc == nil { + return result, fmt.Errorf("decrypting to USMC returned nil") + } + + messageType, err := usmc.GetMessageType() + if err != nil { + return result, fmt.Errorf("failed to get message type: %w", err) + } + senderCertificate, err := usmc.GetSenderCertificate() + if err != nil { + return result, fmt.Errorf("failed to get sender certificate: %w", err) + } + contentHint, err := usmc.GetContentHint() + if err != nil { + return result, fmt.Errorf("failed to get content hint: %w", err) + } + result.ContentHint = signalpb.UnidentifiedSenderMessage_Message_ContentHint(contentHint) + senderUUID, err := senderCertificate.GetSenderUUID() + if err != nil { + return result, fmt.Errorf("failed to get sender UUID: %w", err) + } + senderDeviceID, err := senderCertificate.GetDeviceID() + if err != nil { + return result, fmt.Errorf("failed to get sender device ID: %w", err) + } + senderAddress, err := libsignalgo.NewACIServiceID(senderUUID).Address(uint(senderDeviceID)) + if err != nil { + return result, fmt.Errorf("failed to create sender address: %w", err) + } + result.SenderAddress = senderAddress + senderE164, err := senderCertificate.GetSenderE164() + if err != nil { + return result, fmt.Errorf("failed to get sender E164: %w", err) + } + usmcContents, err := usmc.GetContents() + if err != nil { + return result, fmt.Errorf("failed to get USMC contents: %w", err) + } + newLog := log.With(). + Stringer("sender_uuid", senderUUID). + Uint32("sender_device_id", senderDeviceID). + Str("sender_e164", senderE164). + Uint8("sealed_sender_type", uint8(messageType)). + Logger() + log = &newLog + ctx = log.WithContext(ctx) + log.Trace().Msg("Received SealedSender message") + + if senderE164 != "" { + _, err = cli.Store.RecipientStore.UpdateRecipientE164(ctx, senderUUID, uuid.Nil, senderE164) + if err != nil { + log.Warn().Err(err).Msg("Failed to update sender E164 in recipient store") + } + } + + var resultPtr *DecryptionResult + switch messageType { + case libsignalgo.CiphertextMessageTypeSenderKey: + resultPtr, err = cli.decryptSenderKeyMessage(ctx, senderAddress, usmcContents) + case libsignalgo.CiphertextMessageTypePreKey: + resultPtr, err = cli.prekeyDecrypt(ctx, destinationServiceID, senderAddress, usmcContents) + case libsignalgo.CiphertextMessageTypeWhisper: + resultPtr, err = cli.decryptCiphertextEnvelope(ctx, destinationServiceID, senderAddress, usmcContents) + case libsignalgo.CiphertextMessageTypePlaintext: + // TODO: handle plaintext (usually DecryptionErrorMessage) and retries + // when implementing SenderKey groups + return result, fmt.Errorf("unsupported plaintext sealed sender message") + default: + return result, fmt.Errorf("unsupported sealed sender message type %d", messageType) + } + if err != nil { + return result, err + } + return *resultPtr, nil +} + +func stripPadding(contents *[]byte) error { + for i := len(*contents) - 1; i >= 0; i-- { + if (*contents)[i] == 0x80 { + *contents = (*contents)[:i] + return nil + } else if (*contents)[i] != 0x00 { + return fmt.Errorf("Invalid ISO7816 padding") + } + } + return fmt.Errorf("Invalid ISO7816 padding, len(contents): %v", len(*contents)) +} From 90c621853534f1828583c0cbd7c461fa7c7cf9ef Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Mon, 12 May 2025 14:28:58 +0300 Subject: [PATCH 329/580] signalmeow/receiving: remove unused server trust root --- pkg/signalmeow/receiving.go | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/pkg/signalmeow/receiving.go b/pkg/signalmeow/receiving.go index 18c2240..8720195 100644 --- a/pkg/signalmeow/receiving.go +++ b/pkg/signalmeow/receiving.go @@ -27,7 +27,6 @@ import ( "github.com/google/uuid" "github.com/rs/zerolog" - "go.mau.fi/util/exerrors" "google.golang.org/protobuf/proto" "google.golang.org/protobuf/reflect/protoreflect" @@ -811,13 +810,3 @@ func (cli *Client) sendDeliveryReceipts(ctx context.Context, deliveredTimestamps } return nil } - -const prodServerTrustRootStr = "BXu6QIKVz5MA8gstzfOgRQGqyLqOwNKHL6INkv3IHWMF" - -var prodServerTrustRootBytes = exerrors.Must(base64.StdEncoding.DecodeString(prodServerTrustRootStr)) -var prodServerTrustRootKey = exerrors.Must(libsignalgo.DeserializePublicKey(prodServerTrustRootBytes)) - -func init() { - // It's never going to be freed anyway - prodServerTrustRootKey.CancelFinalizer() -} From 3fb64cbc3338305b7a98831ad8e9f949ac2e4aa2 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Mon, 12 May 2025 14:31:31 +0300 Subject: [PATCH 330/580] signalmeow/receiving: don't use pointers for stripping padding --- pkg/signalmeow/receiving_decrypt.go | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/pkg/signalmeow/receiving_decrypt.go b/pkg/signalmeow/receiving_decrypt.go index 1c9c408..9d12ff6 100644 --- a/pkg/signalmeow/receiving_decrypt.go +++ b/pkg/signalmeow/receiving_decrypt.go @@ -129,7 +129,7 @@ func (cli *Client) prekeyDecrypt(ctx context.Context, destination libsignalgo.Se if err != nil { return nil, fmt.Errorf("failed to decrypt prekey message: %w", err) } - err = stripPadding(&data) + data, err = stripPadding(data) if err != nil { return nil, fmt.Errorf("failed to strip padding: %w", err) } @@ -179,7 +179,7 @@ func (cli *Client) decryptCiphertextEnvelope( } return nil, fmt.Errorf("failed to decrypt ciphertext message: %w", err) } - err = stripPadding(&decryptedText) + decryptedText, err = stripPadding(decryptedText) if err != nil { return nil, fmt.Errorf("failed to strip padding: %w", err) } @@ -208,7 +208,7 @@ func (cli *Client) decryptSenderKeyMessage( if err != nil { return nil, fmt.Errorf("failed to decrypt sender key message: %w", err) } - err = stripPadding(&decryptedText) + decryptedText, err = stripPadding(decryptedText) if err != nil { return nil, fmt.Errorf("failed to strip padding: %w", err) } @@ -314,14 +314,14 @@ func (cli *Client) decryptUnidentifiedSenderEnvelope(ctx context.Context, destin return *resultPtr, nil } -func stripPadding(contents *[]byte) error { - for i := len(*contents) - 1; i >= 0; i-- { - if (*contents)[i] == 0x80 { - *contents = (*contents)[:i] - return nil - } else if (*contents)[i] != 0x00 { - return fmt.Errorf("Invalid ISO7816 padding") +func stripPadding(contents []byte) ([]byte, error) { + for i := len(contents) - 1; i >= 0; i-- { + if contents[i] == 0x80 { + contents = contents[:i] + return contents, nil + } else if contents[i] != 0x00 { + return nil, fmt.Errorf("invalid ISO7816 padding") } } - return fmt.Errorf("Invalid ISO7816 padding, len(contents): %v", len(*contents)) + return nil, fmt.Errorf("invalid ISO7816 padding (length %d)", len(contents)) } From da84e97ceab6ae189aed71bd67825a28321d40e9 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Mon, 12 May 2025 16:39:54 +0300 Subject: [PATCH 331/580] signalmeow/receiving: add persistent buffer for decryption to prevent double processing --- pkg/signalmeow/receiving.go | 12 +- pkg/signalmeow/receiving_decrypt.go | 150 ++++++++++++------ pkg/signalmeow/store/container.go | 1 + pkg/signalmeow/store/device.go | 6 + pkg/signalmeow/store/event_buffer.go | 79 +++++++++ pkg/signalmeow/store/upgrades/00-latest.sql | 21 ++- .../store/upgrades/21-event-buffer.sql | 11 ++ 7 files changed, 223 insertions(+), 57 deletions(-) create mode 100644 pkg/signalmeow/store/event_buffer.go create mode 100644 pkg/signalmeow/store/upgrades/21-event-buffer.sql diff --git a/pkg/signalmeow/receiving.go b/pkg/signalmeow/receiving.go index 8720195..35d1d3a 100644 --- a/pkg/signalmeow/receiving.go +++ b/pkg/signalmeow/receiving.go @@ -21,6 +21,7 @@ import ( "bytes" "context" "encoding/base64" + "errors" "fmt" "net/http" "strings" @@ -337,6 +338,14 @@ func (cli *Client) handleDecryptedResult( destinationServiceID libsignalgo.ServiceID, ) error { log := zerolog.Ctx(ctx) + if result.CiphertextHash != nil { + defer func() { + err := cli.Store.EventBuffer.ClearBufferedEventPlaintext(ctx, *result.CiphertextHash) + if err != nil { + log.Err(err).Msg("Failed to clear buffered event plaintext") + } + }() + } // result.Err is set if there was an error during decryption and we // should notifiy the user that the message could not be decrypted @@ -361,7 +370,8 @@ func (cli *Client) handleDecryptedResult( // to prevent spamming errors for typing notifications and whatnot if envelope.GetUrgent() && result.ContentHint != signalpb.UnidentifiedSenderMessage_Message_IMPLICIT && - !strings.Contains(result.Err.Error(), "message with old counter") { + !strings.Contains(result.Err.Error(), "message with old counter") && + !errors.Is(err, EventAlreadyProcessed) { cli.handleEvent(&events.DecryptionError{ Sender: theirServiceID.UUID, Err: result.Err, diff --git a/pkg/signalmeow/receiving_decrypt.go b/pkg/signalmeow/receiving_decrypt.go index 9d12ff6..e8d30b0 100644 --- a/pkg/signalmeow/receiving_decrypt.go +++ b/pkg/signalmeow/receiving_decrypt.go @@ -19,8 +19,10 @@ package signalmeow import ( "context" + "crypto/sha256" + "errors" "fmt" - "strings" + "time" "github.com/google/uuid" "github.com/rs/zerolog" @@ -28,13 +30,15 @@ import ( "go.mau.fi/mautrix-signal/pkg/libsignalgo" signalpb "go.mau.fi/mautrix-signal/pkg/signalmeow/protobuf" + "go.mau.fi/mautrix-signal/pkg/signalmeow/store" ) type DecryptionResult struct { - SenderAddress *libsignalgo.Address - Content *signalpb.Content - ContentHint signalpb.UnidentifiedSenderMessage_Message_ContentHint - Err error + SenderAddress *libsignalgo.Address + CiphertextHash *[32]byte + Content *signalpb.Content + ContentHint signalpb.UnidentifiedSenderMessage_Message_ContentHint + Err error } func (cli *Client) decryptEnvelope( @@ -68,10 +72,10 @@ func (cli *Client) decryptEnvelope( var result *DecryptionResult var bundleType string if *envelope.Type == signalpb.Envelope_PREKEY_BUNDLE { - result, err = cli.prekeyDecrypt(ctx, destinationServiceID, sender, envelope.Content) + result, err = cli.prekeyDecrypt(ctx, destinationServiceID, sender, envelope.Content, envelope.GetServerTimestamp()) bundleType = "prekey bundle" } else { - result, err = cli.decryptCiphertextEnvelope(ctx, destinationServiceID, sender, envelope.Content) + result, err = cli.decryptCiphertextEnvelope(ctx, destinationServiceID, sender, envelope.Content, envelope.GetServerTimestamp()) bundleType = "ciphertext" } if err != nil { @@ -96,7 +100,45 @@ func (cli *Client) decryptEnvelope( } } -func (cli *Client) prekeyDecrypt(ctx context.Context, destination libsignalgo.ServiceID, sender *libsignalgo.Address, encryptedContent []byte) (*DecryptionResult, error) { +var EventAlreadyProcessed = errors.New("event was already processed") + +func (cli *Client) bufferedDecryptTxn(ctx context.Context, ciphertext []byte, serverTimestamp uint64, decrypt func(context.Context) ([]byte, error)) (plaintext []byte, ciphertextHash [32]byte, err error) { + ciphertextHash = sha256.Sum256(ciphertext) + + var buf *store.BufferedEvent + buf, err = cli.Store.EventBuffer.GetBufferedEvent(ctx, ciphertextHash) + if err != nil { + err = fmt.Errorf("failed to get buffered event: %w", err) + return + } else if buf != nil { + plaintext = buf.Plaintext + if plaintext == nil { + err = fmt.Errorf("%w at %s", EventAlreadyProcessed, time.UnixMilli(buf.InsertTimestamp).String()) + } + return + } + + err = cli.Store.DoDecryptionTxn(ctx, func(ctx context.Context) (innerErr error) { + plaintext, innerErr = decrypt(ctx) + if innerErr != nil { + return + } + innerErr = cli.Store.EventBuffer.PutBufferedEvent(ctx, ciphertextHash, plaintext, serverTimestamp) + if innerErr != nil { + innerErr = fmt.Errorf("failed to save decrypted event to buffer: %w", innerErr) + } + return + }) + return +} + +func (cli *Client) prekeyDecrypt( + ctx context.Context, + destination libsignalgo.ServiceID, + sender *libsignalgo.Address, + encryptedContent []byte, + serverTimestamp uint64, +) (*DecryptionResult, error) { preKeyMessage, err := libsignalgo.DeserializePreKeyMessage(encryptedContent) if err != nil { return nil, fmt.Errorf("failed to deserialize prekey message: %w", err) @@ -116,31 +158,34 @@ func (cli *Client) prekeyDecrypt(ctx context.Context, destination libsignalgo.Se return nil, fmt.Errorf("no identity store found for %s", destination) } - data, err := libsignalgo.DecryptPreKey( - ctx, - preKeyMessage, - sender, - ss, - is, - pks, - pks, - pks, - ) + plaintext, ciphertextHash, err := cli.bufferedDecryptTxn(ctx, encryptedContent, serverTimestamp, func(ctx context.Context) ([]byte, error) { + return libsignalgo.DecryptPreKey( + ctx, + preKeyMessage, + sender, + ss, + is, + pks, + pks, + pks, + ) + }) if err != nil { return nil, fmt.Errorf("failed to decrypt prekey message: %w", err) } - data, err = stripPadding(data) + plaintext, err = stripPadding(plaintext) if err != nil { return nil, fmt.Errorf("failed to strip padding: %w", err) } content := &signalpb.Content{} - err = proto.Unmarshal(data, content) + err = proto.Unmarshal(plaintext, content) if err != nil { return nil, fmt.Errorf("failed to unmarshal decrypted prekey message: %w", err) } return &DecryptionResult{ - SenderAddress: sender, - Content: content, + SenderAddress: sender, + Content: content, + CiphertextHash: &ciphertextHash, }, nil } @@ -149,6 +194,7 @@ func (cli *Client) decryptCiphertextEnvelope( destinationServiceID libsignalgo.ServiceID, senderAddress *libsignalgo.Address, ciphertext []byte, + serverTimestamp uint64, ) (*DecryptionResult, error) { log := zerolog.Ctx(ctx) message, err := libsignalgo.DeserializeMessage(ciphertext) @@ -164,33 +210,31 @@ func (cli *Client) decryptCiphertextEnvelope( if identityStore == nil { return nil, fmt.Errorf("no identity store for destination service ID %s", destinationServiceID) } - decryptedText, err := libsignalgo.Decrypt( - ctx, - message, - senderAddress, - sessionStore, - identityStore, - ) + plaintext, ciphertextHash, err := cli.bufferedDecryptTxn(ctx, ciphertext, serverTimestamp, func(ctx context.Context) ([]byte, error) { + return libsignalgo.Decrypt( + ctx, + message, + senderAddress, + sessionStore, + identityStore, + ) + }) if err != nil { - if strings.Contains(err.Error(), "message with old counter") { - log.Warn().Err(err).Msg("Duplicate message error while decrypting whisper ciphertext") - } else { - log.Err(err).Msg("Failed to decrypt whisper ciphertext message") - } return nil, fmt.Errorf("failed to decrypt ciphertext message: %w", err) } - decryptedText, err = stripPadding(decryptedText) + plaintext, err = stripPadding(plaintext) if err != nil { return nil, fmt.Errorf("failed to strip padding: %w", err) } content := signalpb.Content{} - err = proto.Unmarshal(decryptedText, &content) + err = proto.Unmarshal(plaintext, &content) if err != nil { return nil, fmt.Errorf("failed to unmarshal decrypted message: %w", err) } return &DecryptionResult{ - SenderAddress: senderAddress, - Content: &content, + SenderAddress: senderAddress, + Content: &content, + CiphertextHash: &ciphertextHash, }, nil } @@ -198,28 +242,32 @@ func (cli *Client) decryptSenderKeyMessage( ctx context.Context, senderAddress *libsignalgo.Address, ciphertext []byte, + serverTimestamp uint64, ) (*DecryptionResult, error) { - decryptedText, err := libsignalgo.GroupDecrypt( - ctx, - ciphertext, - senderAddress, - cli.Store.SenderKeyStore, - ) + plaintext, ciphertextHash, err := cli.bufferedDecryptTxn(ctx, ciphertext, serverTimestamp, func(ctx context.Context) ([]byte, error) { + return libsignalgo.GroupDecrypt( + ctx, + ciphertext, + senderAddress, + cli.Store.SenderKeyStore, + ) + }) if err != nil { return nil, fmt.Errorf("failed to decrypt sender key message: %w", err) } - decryptedText, err = stripPadding(decryptedText) + plaintext, err = stripPadding(plaintext) if err != nil { return nil, fmt.Errorf("failed to strip padding: %w", err) } content := signalpb.Content{} - err = proto.Unmarshal(decryptedText, &content) + err = proto.Unmarshal(plaintext, &content) if err != nil { return nil, fmt.Errorf("failed to unmarshal decrypted sender key message: %w", err) } return &DecryptionResult{ - SenderAddress: senderAddress, - Content: &content, + SenderAddress: senderAddress, + Content: &content, + CiphertextHash: &ciphertextHash, }, nil } @@ -296,11 +344,11 @@ func (cli *Client) decryptUnidentifiedSenderEnvelope(ctx context.Context, destin var resultPtr *DecryptionResult switch messageType { case libsignalgo.CiphertextMessageTypeSenderKey: - resultPtr, err = cli.decryptSenderKeyMessage(ctx, senderAddress, usmcContents) + resultPtr, err = cli.decryptSenderKeyMessage(ctx, senderAddress, usmcContents, envelope.GetServerTimestamp()) case libsignalgo.CiphertextMessageTypePreKey: - resultPtr, err = cli.prekeyDecrypt(ctx, destinationServiceID, senderAddress, usmcContents) + resultPtr, err = cli.prekeyDecrypt(ctx, destinationServiceID, senderAddress, usmcContents, envelope.GetServerTimestamp()) case libsignalgo.CiphertextMessageTypeWhisper: - resultPtr, err = cli.decryptCiphertextEnvelope(ctx, destinationServiceID, senderAddress, usmcContents) + resultPtr, err = cli.decryptCiphertextEnvelope(ctx, destinationServiceID, senderAddress, usmcContents, envelope.GetServerTimestamp()) case libsignalgo.CiphertextMessageTypePlaintext: // TODO: handle plaintext (usually DecryptionErrorMessage) and retries // when implementing SenderKey groups diff --git a/pkg/signalmeow/store/container.go b/pkg/signalmeow/store/container.go index 18f9b99..f6842ac 100644 --- a/pkg/signalmeow/store/container.go +++ b/pkg/signalmeow/store/container.go @@ -108,6 +108,7 @@ func (c *Container) scanDevice(row dbutil.Scannable) (*Device, error) { device.RecipientStore = baseStore device.DeviceStore = baseStore device.BackupStore = baseStore + device.EventBuffer = baseStore device.sqlStore = baseStore device.db = c.db return &device, nil diff --git a/pkg/signalmeow/store/device.go b/pkg/signalmeow/store/device.go index fc7fac6..aabee03 100644 --- a/pkg/signalmeow/store/device.go +++ b/pkg/signalmeow/store/device.go @@ -79,6 +79,7 @@ type Device struct { RecipientStore RecipientStore DeviceStore DeviceStore BackupStore BackupStore + EventBuffer EventBuffer sqlStore *sqlStore db *dbutil.Database @@ -98,6 +99,11 @@ func (d *Device) DoContactTxn(ctx context.Context, fn func(context.Context) erro return d.db.DoTxn(ctx, nil, fn) } +func (d *Device) DoDecryptionTxn(ctx context.Context, fn func(context.Context) error) error { + ctx = context.WithValue(ctx, dbutil.ContextKeyDoTxnCallerSkip, 2) + return d.db.DoTxn(ctx, nil, fn) +} + func (d *Device) ClearDeviceKeys(ctx context.Context) error { // We need to clear out keys associated with the Signal device that no longer has valid credentials if d == nil { diff --git a/pkg/signalmeow/store/event_buffer.go b/pkg/signalmeow/store/event_buffer.go new file mode 100644 index 0000000..f5aa314 --- /dev/null +++ b/pkg/signalmeow/store/event_buffer.go @@ -0,0 +1,79 @@ +// mautrix-signal - A Matrix-signal puppeting bridge. +// Copyright (C) 2025 Tulir Asokan +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +package store + +import ( + "context" + "database/sql" + "errors" + "time" +) + +type BufferedEvent struct { + Plaintext []byte + ServerTimestamp uint64 + InsertTimestamp int64 +} + +type EventBuffer interface { + GetBufferedEvent(ctx context.Context, ciphertextHash [32]byte) (*BufferedEvent, error) + PutBufferedEvent(ctx context.Context, ciphertextHash [32]byte, plaintext []byte, serverTimestamp uint64) error + ClearBufferedEventPlaintext(ctx context.Context, ciphertextHash [32]byte) error + DeleteBufferedEvent(ctx context.Context, ciphertextHash [32]byte) error +} + +var _ EventBuffer = (*sqlStore)(nil) + +const ( + getBufferedEventQuery = ` + SELECT plaintext, server_timestamp, insert_timestamp + FROM signalmeow_event_buffer + WHERE account_id=$1 AND ciphertext_hash=$2 + ` + putBufferedEventQuery = ` + INSERT INTO signalmeow_event_buffer (account_id, ciphertext_hash, plaintext, server_timestamp, insert_timestamp) + VALUES ($1, $2, $3, $4, $5) + ` + clearBufferedEventPlaintextQuery = `UPDATE signalmeow_event_buffer SET plaintext=NULL WHERE account_id=$1 AND ciphertext_hash=$2` + deleteBufferedEventQuery = `DELETE FROM signalmeow_event_buffer WHERE account_id=$1 AND ciphertext_hash=$2` +) + +func (s *sqlStore) GetBufferedEvent(ctx context.Context, ciphertextHash [32]byte) (*BufferedEvent, error) { + var evt BufferedEvent + err := s.db.QueryRow(ctx, getBufferedEventQuery, s.AccountID, ciphertextHash[:]).Scan(&evt.Plaintext, &evt.ServerTimestamp, &evt.InsertTimestamp) + if errors.Is(err, sql.ErrNoRows) { + return nil, nil + } else if err != nil { + return nil, err + } + return &evt, nil +} + +func (s *sqlStore) PutBufferedEvent(ctx context.Context, ciphertextHash [32]byte, plaintext []byte, serverTimestamp uint64) error { + _, err := s.db.Exec(ctx, putBufferedEventQuery, s.AccountID, ciphertextHash[:], plaintext, serverTimestamp, time.Now().UnixMilli()) + return err +} + +func (s *sqlStore) ClearBufferedEventPlaintext(ctx context.Context, ciphertextHash [32]byte) error { + _, err := s.db.Exec(ctx, clearBufferedEventPlaintextQuery, s.AccountID, ciphertextHash[:]) + return err +} + +func (s *sqlStore) DeleteBufferedEvent(ctx context.Context, ciphertextHash [32]byte) error { + _, err := s.db.Exec(ctx, deleteBufferedEventQuery, s.AccountID, ciphertextHash[:]) + return err +} diff --git a/pkg/signalmeow/store/upgrades/00-latest.sql b/pkg/signalmeow/store/upgrades/00-latest.sql index 670f0e0..cb7e693 100644 --- a/pkg/signalmeow/store/upgrades/00-latest.sql +++ b/pkg/signalmeow/store/upgrades/00-latest.sql @@ -1,4 +1,4 @@ --- v0 -> v20 (compatible with v13+): Latest revision +-- v0 -> v21 (compatible with v13+): Latest revision CREATE TABLE signalmeow_device ( aci_uuid TEXT PRIMARY KEY, @@ -63,6 +63,17 @@ CREATE TABLE signalmeow_sessions ( FOREIGN KEY (account_id) REFERENCES signalmeow_device (aci_uuid) ON DELETE CASCADE ON UPDATE CASCADE ); +CREATE TABLE signalmeow_event_buffer ( + account_id TEXT NOT NULL, + ciphertext_hash bytea NOT NULL, + plaintext bytea, + server_timestamp BIGINT NOT NULL, + insert_timestamp BIGINT NOT NULL, + + PRIMARY KEY (account_id, ciphertext_hash), + FOREIGN KEY (account_id) REFERENCES signalmeow_device (aci_uuid) ON DELETE CASCADE ON UPDATE CASCADE +); + CREATE TABLE signalmeow_profile_keys ( account_id TEXT NOT NULL, their_aci_uuid TEXT NOT NULL, @@ -131,10 +142,10 @@ CREATE INDEX signalmeow_backup_recipient_group_idx ON signalmeow_backup_recipien CREATE INDEX signalmeow_backup_recipient_aci_idx ON signalmeow_backup_recipient (account_id, aci_uuid); CREATE TABLE signalmeow_backup_chat ( - account_id TEXT NOT NULL, - chat_id BIGINT NOT NULL, - recipient_id BIGINT NOT NULL, - data bytea NOT NULL, + account_id TEXT NOT NULL, + chat_id BIGINT NOT NULL, + recipient_id BIGINT NOT NULL, + data bytea NOT NULL, latest_message_id BIGINT, total_message_count INTEGER, diff --git a/pkg/signalmeow/store/upgrades/21-event-buffer.sql b/pkg/signalmeow/store/upgrades/21-event-buffer.sql new file mode 100644 index 0000000..bfc289a --- /dev/null +++ b/pkg/signalmeow/store/upgrades/21-event-buffer.sql @@ -0,0 +1,11 @@ +-- v21 (compatible with v13+): Add event buffer +CREATE TABLE signalmeow_event_buffer ( + account_id TEXT NOT NULL, + ciphertext_hash bytea NOT NULL, + plaintext bytea, + server_timestamp BIGINT NOT NULL, + insert_timestamp BIGINT NOT NULL, + + PRIMARY KEY (account_id, ciphertext_hash), + FOREIGN KEY (account_id) REFERENCES signalmeow_device (aci_uuid) ON DELETE CASCADE ON UPDATE CASCADE +); From 901b812bb8efd1739548f7442e573970609a902f Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Mon, 12 May 2025 18:37:19 +0300 Subject: [PATCH 332/580] signalmeow/receiving: delete old incoming ciphertext hashes --- pkg/signalmeow/client.go | 2 ++ pkg/signalmeow/receiving.go | 39 +++++++++++++++++++++++++-- pkg/signalmeow/store/event_buffer.go | 8 +++--- pkg/signalmeow/web/signalwebsocket.go | 7 ++++- 4 files changed, 49 insertions(+), 7 deletions(-) diff --git a/pkg/signalmeow/client.go b/pkg/signalmeow/client.go index 0f03354..d3ba6b6 100644 --- a/pkg/signalmeow/client.go +++ b/pkg/signalmeow/client.go @@ -60,6 +60,8 @@ type Client struct { cdAuthLock sync.Mutex cdAuth *basicExpiringCredentials cdToken []byte + + writeCallbackCounter chan time.Time } func (cli *Client) handleEvent(evt events.SignalEvent) { diff --git a/pkg/signalmeow/receiving.go b/pkg/signalmeow/receiving.go index 35d1d3a..cd071c6 100644 --- a/pkg/signalmeow/receiving.go +++ b/pkg/signalmeow/receiving.go @@ -25,6 +25,7 @@ import ( "fmt" "net/http" "strings" + "time" "github.com/google/uuid" "github.com/rs/zerolog" @@ -100,6 +101,8 @@ func (cli *Client) startWebsocketsInternal( func (cli *Client) StartReceiveLoops(ctx context.Context) (chan SignalConnectionStatus, error) { log := zerolog.Ctx(ctx).With().Str("action", "start receive loops").Logger() + cbc := make(chan time.Time, 1) + cli.writeCallbackCounter = cbc authChan, unauthChan, loopCtx, loopCancel, err := cli.startWebsocketsInternal(log.WithContext(ctx)) if err != nil { @@ -110,7 +113,28 @@ func (cli *Client) StartReceiveLoops(ctx context.Context) (chan SignalConnection initialConnectChan := make(chan struct{}) // Combine both websocket status channels into a single, more generic "Signal" connection status channel - cli.loopWg.Add(1) + cli.loopWg.Add(2) + go func() { + defer cli.loopWg.Done() + writeCallbackTimer := time.Now() + callbackCount := 0 + for { + select { + case <-loopCtx.Done(): + return + case nextTS := <-cbc: + if callbackCount >= 4 && time.Since(writeCallbackTimer) > 1*time.Minute { + err := cli.Store.EventBuffer.DeleteBufferedEventsOlderThan(ctx, writeCallbackTimer) + if err != nil { + log.Err(err).Msg("Failed to delete old buffered event hashes") + } + writeCallbackTimer = nextTS + } else { + callbackCount++ + } + } + } + }() go func() { defer cli.loopWg.Done() defer close(statusChan) @@ -326,10 +350,21 @@ func (cli *Client) incomingAPIMessageHandler(ctx context.Context, req *signalpb. } return &web.SimpleResponse{ - Status: 200, + Status: 200, + WriteCallback: cli.writeCallback, }, nil } +func (cli *Client) writeCallback(preWriteTime time.Time) { + ch := cli.writeCallbackCounter + if ch != nil { + select { + case ch <- preWriteTime: + default: + } + } +} + // TODO: we should split this up into multiple functions func (cli *Client) handleDecryptedResult( ctx context.Context, diff --git a/pkg/signalmeow/store/event_buffer.go b/pkg/signalmeow/store/event_buffer.go index f5aa314..6b8d6cf 100644 --- a/pkg/signalmeow/store/event_buffer.go +++ b/pkg/signalmeow/store/event_buffer.go @@ -33,7 +33,7 @@ type EventBuffer interface { GetBufferedEvent(ctx context.Context, ciphertextHash [32]byte) (*BufferedEvent, error) PutBufferedEvent(ctx context.Context, ciphertextHash [32]byte, plaintext []byte, serverTimestamp uint64) error ClearBufferedEventPlaintext(ctx context.Context, ciphertextHash [32]byte) error - DeleteBufferedEvent(ctx context.Context, ciphertextHash [32]byte) error + DeleteBufferedEventsOlderThan(ctx context.Context, maxTS time.Time) error } var _ EventBuffer = (*sqlStore)(nil) @@ -49,7 +49,7 @@ const ( VALUES ($1, $2, $3, $4, $5) ` clearBufferedEventPlaintextQuery = `UPDATE signalmeow_event_buffer SET plaintext=NULL WHERE account_id=$1 AND ciphertext_hash=$2` - deleteBufferedEventQuery = `DELETE FROM signalmeow_event_buffer WHERE account_id=$1 AND ciphertext_hash=$2` + deleteOldBufferedEventsQuery = `DELETE FROM signalmeow_event_buffer WHERE account_id=$1 AND insert_timestamp<$2 AND plaintext IS NULL` ) func (s *sqlStore) GetBufferedEvent(ctx context.Context, ciphertextHash [32]byte) (*BufferedEvent, error) { @@ -73,7 +73,7 @@ func (s *sqlStore) ClearBufferedEventPlaintext(ctx context.Context, ciphertextHa return err } -func (s *sqlStore) DeleteBufferedEvent(ctx context.Context, ciphertextHash [32]byte) error { - _, err := s.db.Exec(ctx, deleteBufferedEventQuery, s.AccountID, ciphertextHash[:]) +func (s *sqlStore) DeleteBufferedEventsOlderThan(ctx context.Context, maxTS time.Time) error { + _, err := s.db.Exec(ctx, deleteOldBufferedEventsQuery, s.AccountID, maxTS.UnixMilli()) return err } diff --git a/pkg/signalmeow/web/signalwebsocket.go b/pkg/signalmeow/web/signalwebsocket.go index f4cf4aa..16a7463 100644 --- a/pkg/signalmeow/web/signalwebsocket.go +++ b/pkg/signalmeow/web/signalwebsocket.go @@ -40,7 +40,8 @@ const WebsocketProvisioningPath = "/v1/websocket/provisioning/" const WebsocketPath = "/v1/websocket/" type SimpleResponse struct { - Status int + Status int + WriteCallback func(time.Time) } type RequestHandlerFunc func(context.Context, *signalpb.WebSocketRequestMessage) (*SimpleResponse, error) @@ -541,10 +542,14 @@ func writeLoop( Uint64("request_id", *request.RequestMessage.Id). Int("response_status", request.ResponseMessage.Status). Msg("Sending WS response") + writeStartTime := time.Now() err := wspb.Write(ctx, ws, message) if err != nil { return fmt.Errorf("error writing response message: %w", err) } + if request.ResponseMessage.WriteCallback != nil { + request.ResponseMessage.WriteCallback(writeStartTime) + } } else { return fmt.Errorf("invalid request: %+v", request) } From f26198cce3678cc0b59545a8f9f110b1fcc24707 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Mon, 12 May 2025 18:55:32 +0300 Subject: [PATCH 333/580] signalmeow/receiving: reset write counter on disconnect --- pkg/signalmeow/receiving.go | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/pkg/signalmeow/receiving.go b/pkg/signalmeow/receiving.go index cd071c6..dd3589b 100644 --- a/pkg/signalmeow/receiving.go +++ b/pkg/signalmeow/receiving.go @@ -111,6 +111,7 @@ func (cli *Client) StartReceiveLoops(ctx context.Context) (chan SignalConnection statusChan := make(chan SignalConnectionStatus, 128) initialConnectChan := make(chan struct{}) + resetWriteCount := make(chan struct{}, 1) // Combine both websocket status channels into a single, more generic "Signal" connection status channel cli.loopWg.Add(2) @@ -122,6 +123,8 @@ func (cli *Client) StartReceiveLoops(ctx context.Context) (chan SignalConnection select { case <-loopCtx.Done(): return + case <-resetWriteCount: + callbackCount = 0 case nextTS := <-cbc: if callbackCount >= 4 && time.Since(writeCallbackTimer) > 1*time.Minute { err := cli.Store.EventBuffer.DeleteBufferedEventsOlderThan(ctx, writeCallbackTimer) @@ -165,6 +168,12 @@ func (cli *Client) StartReceiveLoops(ctx context.Context) (chan SignalConnection case web.SignalWebsocketConnectionEventCleanShutdown: log.Info().Msg("Authed websocket clean shutdown") } + if status.Event != web.SignalWebsocketConnectionEventConnected { + select { + case resetWriteCount <- struct{}{}: + default: + } + } case status := <-unauthChan: lastUnauthStatus = status currentStatus = status From 00af0d3cc677673a780c4aa7a3b0e949d12ef7c3 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Mon, 12 May 2025 19:10:19 +0300 Subject: [PATCH 334/580] signalmeow/receiving: log ciphertext hashes --- pkg/signalmeow/receiving.go | 8 +++++++- pkg/signalmeow/receiving_decrypt.go | 15 ++++++++++++++- 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/pkg/signalmeow/receiving.go b/pkg/signalmeow/receiving.go index dd3589b..7f2f21d 100644 --- a/pkg/signalmeow/receiving.go +++ b/pkg/signalmeow/receiving.go @@ -386,7 +386,13 @@ func (cli *Client) handleDecryptedResult( defer func() { err := cli.Store.EventBuffer.ClearBufferedEventPlaintext(ctx, *result.CiphertextHash) if err != nil { - log.Err(err).Msg("Failed to clear buffered event plaintext") + log.Err(err). + Hex("ciphertext_hash", result.CiphertextHash[:]). + Msg("Failed to clear buffered event plaintext") + } else { + log.Debug(). + Hex("ciphertext_hash", result.CiphertextHash[:]). + Msg("Deleted event plaintext from buffer") } }() } diff --git a/pkg/signalmeow/receiving_decrypt.go b/pkg/signalmeow/receiving_decrypt.go index e8d30b0..7d85c43 100644 --- a/pkg/signalmeow/receiving_decrypt.go +++ b/pkg/signalmeow/receiving_decrypt.go @@ -112,8 +112,18 @@ func (cli *Client) bufferedDecryptTxn(ctx context.Context, ciphertext []byte, se return } else if buf != nil { plaintext = buf.Plaintext + insertTime := time.UnixMilli(buf.InsertTimestamp) if plaintext == nil { - err = fmt.Errorf("%w at %s", EventAlreadyProcessed, time.UnixMilli(buf.InsertTimestamp).String()) + zerolog.Ctx(ctx).Debug(). + Hex("ciphertext_hash", ciphertextHash[:]). + Time("insertion_time", insertTime). + Msg("Returning event already processed error") + err = fmt.Errorf("%w at %s", EventAlreadyProcessed, insertTime.String()) + } else { + zerolog.Ctx(ctx).Debug(). + Hex("ciphertext_hash", ciphertextHash[:]). + Time("insertion_time", insertTime). + Msg("Returning previously decrypted plaintext") } return } @@ -127,6 +137,9 @@ func (cli *Client) bufferedDecryptTxn(ctx context.Context, ciphertext []byte, se if innerErr != nil { innerErr = fmt.Errorf("failed to save decrypted event to buffer: %w", innerErr) } + zerolog.Ctx(ctx).Debug(). + Hex("ciphertext_hash", ciphertextHash[:]). + Msg("Successfully decrypted and saved event") return }) return From c3bc814a9eb4ac4d83f5a63009027debf79261e5 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Mon, 12 May 2025 19:12:05 +0300 Subject: [PATCH 335/580] signalmeow/receiving: remove content fields log --- pkg/signalmeow/receiving.go | 53 ------------------------------------- pkg/signalmeow/sending.go | 1 - 2 files changed, 54 deletions(-) diff --git a/pkg/signalmeow/receiving.go b/pkg/signalmeow/receiving.go index 7f2f21d..4e46a66 100644 --- a/pkg/signalmeow/receiving.go +++ b/pkg/signalmeow/receiving.go @@ -30,7 +30,6 @@ import ( "github.com/google/uuid" "github.com/rs/zerolog" "google.golang.org/protobuf/proto" - "google.golang.org/protobuf/reflect/protoreflect" "go.mau.fi/mautrix-signal/pkg/libsignalgo" "go.mau.fi/mautrix-signal/pkg/signalmeow/events" @@ -451,7 +450,6 @@ func (cli *Client) handleDecryptedResult( Uint64("server_ts", envelope.GetServerTimestamp()). Uint64("client_ts", envelope.GetTimestamp()). Msg("Decrypted message") - printContentFieldString(ctx, content, "Decrypted content fields") // If there's a sender key distribution message, process it if content.GetSenderKeyDistributionMessage() != nil { @@ -672,57 +670,6 @@ func (cli *Client) handleDecryptedResult( return nil } -func printStructFields(message protoreflect.Message, parent string, builder *strings.Builder) { - message.Range(func(fd protoreflect.FieldDescriptor, v protoreflect.Value) bool { - fieldName := string(fd.Name()) - currentField := parent + fieldName - fmt.Fprintf(builder, "%s (%s), ", currentField, fd.Kind().String()) - //builder.WriteString(fmt.Sprintf("%s (%s): %s, ", currentField, fd.Kind().String(), v.String())) // DEBUG: printing value, don't commit - if fd.Kind() == protoreflect.MessageKind && !fd.IsList() && v.Message().IsValid() { - builder.WriteString("{ ") - printStructFields(v.Message(), "", builder) - builder.WriteString("} ") - } else if fd.Kind() == protoreflect.MessageKind && fd.IsList() { - builder.WriteString("[ ") - for i := 0; i < v.List().Len(); i++ { - v := v.List().Get(i) - builder.WriteString("{ ") - printStructFields(v.Message(), "", builder) - builder.WriteString("} ") - } - builder.WriteString("] ") - } else if fd.IsList() { - builder.WriteString("[ ") - for i := 0; i < v.List().Len(); i++ { - //v := v.List().Get(i) - //builder.WriteString(fmt.Sprintf("%s, ", v.String())) // DEBUG: printing value, don't commit - builder.WriteString("<>, ") - } - builder.WriteString("] ") - } - return true - }) -} - -func printContentFieldString(ctx context.Context, c *signalpb.Content, message string) { - log := zerolog.Ctx(ctx) - go func() { - // catch panic - defer func() { - if r := recover(); r != nil { - log.Warn().Any("recover", r).Msg("Panic in contentFieldsString") - } - }() - log.Debug().Str("content_fields", contentFieldsString(c)).Msg(message) - }() -} - -func contentFieldsString(c *signalpb.Content) string { - var builder strings.Builder - printStructFields(c.ProtoReflect(), "", &builder) - return builder.String() -} - func groupOrUserID(groupID types.GroupIdentifier, userID libsignalgo.ServiceID) string { if groupID == "" { return userID.String() diff --git a/pkg/signalmeow/sending.go b/pkg/signalmeow/sending.go index 7687da8..69545d9 100644 --- a/pkg/signalmeow/sending.go +++ b/pkg/signalmeow/sending.go @@ -849,7 +849,6 @@ func (cli *Client) sendContent( Uint64("timestamp", messageTimestamp). Logger() ctx = log.WithContext(ctx) - printContentFieldString(ctx, content, "Outgoing message") log.Trace().Any("raw_content", content).Stringer("recipient", recipient).Msg("Raw data of outgoing message") // If it's a data message, add our profile key From 708ef26c923c4a05fa45d4bb2979f8577c0923b1 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Mon, 12 May 2025 20:04:14 +0300 Subject: [PATCH 336/580] libsignal: update to v0.71.0 --- pkg/libsignalgo/libsignal | 2 +- pkg/libsignalgo/libsignal-ffi.h | 14 ++++++++++++++ pkg/libsignalgo/version.go | 2 +- 3 files changed, 16 insertions(+), 2 deletions(-) diff --git a/pkg/libsignalgo/libsignal b/pkg/libsignalgo/libsignal index efe13e9..eac4cf5 160000 --- a/pkg/libsignalgo/libsignal +++ b/pkg/libsignalgo/libsignal @@ -1 +1 @@ -Subproject commit efe13e9b363d2c115dba61b76e5e53bbfc2874bc +Subproject commit eac4cf58ed9b102778b477a9657d4a348cf28f9c diff --git a/pkg/libsignalgo/libsignal-ffi.h b/pkg/libsignalgo/libsignal-ffi.h index 82f1f7f..20bd8e1 100644 --- a/pkg/libsignalgo/libsignal-ffi.h +++ b/pkg/libsignalgo/libsignal-ffi.h @@ -143,6 +143,20 @@ typedef enum { SignalDirectionReceiving = 1, } SignalDirection; +/** + * The result of saving a new identity key for a protocol address. + */ +typedef enum { + /** + * The protocol address didn't have an identity key or had the same key. + */ + SignalIdentityChangeNewOrUnchanged, + /** + * The new identity key replaced a different key for the protocol address. + */ + SignalIdentityChangeReplacedExisting, +} SignalIdentityChange; + typedef enum { SignalLogLevelError = 1, SignalLogLevelWarn, diff --git a/pkg/libsignalgo/version.go b/pkg/libsignalgo/version.go index 631a0a2..bce148c 100644 --- a/pkg/libsignalgo/version.go +++ b/pkg/libsignalgo/version.go @@ -2,4 +2,4 @@ package libsignalgo -const Version = "v0.70.0" +const Version = "v0.71.0" From 5eec76697dc705d212ba4707577e3fc0fa829308 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Thu, 15 May 2025 16:00:53 +0300 Subject: [PATCH 337/580] libsignal: update to v0.72.1 --- pkg/libsignalgo/libsignal | 2 +- pkg/libsignalgo/libsignal-ffi.h | 294 +++++++++++++++++++++++++++++++- pkg/libsignalgo/sealedsender.go | 55 ------ pkg/libsignalgo/session_test.go | 90 ---------- pkg/libsignalgo/version.go | 2 +- 5 files changed, 294 insertions(+), 149 deletions(-) diff --git a/pkg/libsignalgo/libsignal b/pkg/libsignalgo/libsignal index eac4cf5..7d1cacb 160000 --- a/pkg/libsignalgo/libsignal +++ b/pkg/libsignalgo/libsignal @@ -1 +1 @@ -Subproject commit eac4cf58ed9b102778b477a9657d4a348cf28f9c +Subproject commit 7d1cacbaa8a885932b8838dfc3cddbf631dbddae diff --git a/pkg/libsignalgo/libsignal-ffi.h b/pkg/libsignalgo/libsignal-ffi.h index 20bd8e1..c2c0068 100644 --- a/pkg/libsignalgo/libsignal-ffi.h +++ b/pkg/libsignalgo/libsignal-ffi.h @@ -143,6 +143,12 @@ typedef enum { SignalDirectionReceiving = 1, } SignalDirection; +enum SignalFfiPublicKeyType { + SignalFfiPublicKeyTypeECC, + SignalFfiPublicKeyTypeKyber, +}; +typedef uint8_t SignalFfiPublicKeyType; + /** * The result of saving a new identity key for a protocol address. */ @@ -165,6 +171,12 @@ typedef enum { SignalLogLevelTrace, } SignalLogLevel; +enum SignalRequestedInformation { + SignalRequestedInformationPushChallenge, + SignalRequestedInformationCaptcha, +}; +typedef uint8_t SignalRequestedInformation; + typedef enum { SignalErrorCodeUnknownError = 1, SignalErrorCodeInvalidState = 2, @@ -227,8 +239,29 @@ typedef enum { SignalErrorCodeConnectionInvalidated = 172, SignalErrorCodeConnectedElsewhere = 173, SignalErrorCodeBackupValidation = 180, + SignalErrorCodeRegistrationInvalidSessionId = 190, + SignalErrorCodeRegistrationRequestNotValid, + SignalErrorCodeRegistrationUnknown, + SignalErrorCodeRegistrationSessionNotFound, + SignalErrorCodeRegistrationNotReadyForVerification, + SignalErrorCodeRegistrationSendVerificationCodeFailed, + SignalErrorCodeRegistrationCodeNotDeliverable, + SignalErrorCodeRegistrationSessionUpdateRejected, + SignalErrorCodeRegistrationCredentialsCouldNotBeParsed, + SignalErrorCodeRegistrationDeviceTransferPossible, + SignalErrorCodeRegistrationRecoveryVerificationFailed, + SignalErrorCodeRegistrationLock, } SignalErrorCode; +enum SignalSvr2CredentialsResult { + SignalSvr2CredentialsResultMatch, + SignalSvr2CredentialsResultNoMatch, + SignalSvr2CredentialsResultInvalid, +}; +typedef uint8_t SignalSvr2CredentialsResult; + +typedef struct SignalAccountAttributes SignalAccountAttributes; + /** * A wrapper around [`ctr::Ctr32BE`] that uses a smaller nonce and supports an initial counter. */ @@ -300,6 +333,14 @@ typedef struct SignalProtocolAddress SignalProtocolAddress; typedef struct SignalPublicKey SignalPublicKey; +typedef struct SignalRegisterAccountRequest SignalRegisterAccountRequest; + +typedef struct SignalRegisterAccountResponse SignalRegisterAccountResponse; + +typedef struct SignalRegistrationService SignalRegistrationService; + +typedef struct SignalRegistrationSession SignalRegistrationSession; + typedef struct SignalSanitizedMetadata SignalSanitizedMetadata; typedef struct SignalSenderCertificate SignalSenderCertificate; @@ -820,6 +861,32 @@ typedef struct { const SignalFingerprint *raw; } SignalConstPointerFingerprint; +typedef struct { + /** + * The badge ID. + */ + const char *id; + /** + * Whether the badge is currently configured to be visible. + */ + bool visible; + /** + * When the badge expires. + */ + double expiration_secs; +} SignalFfiRegisterResponseBadge; + +/** + * A representation of a array allocated on the Rust heap for use in C code. + */ +typedef struct { + SignalFfiRegisterResponseBadge *base; + /** + * The number of elements in the buffer (not necessarily the number of bytes). + */ + size_t length; +} SignalOwnedBufferOfFfiRegisterResponseBadge; + typedef struct { SignalSenderKeyRecord *raw; } SignalMutPointerSenderKeyRecord; @@ -994,6 +1061,145 @@ typedef struct { const SignalSenderKeyDistributionMessage *raw; } SignalConstPointerSenderKeyDistributionMessage; +typedef struct { + SignalRegisterAccountRequest *raw; +} SignalMutPointerRegisterAccountRequest; + +typedef struct { + const SignalRegisterAccountRequest *raw; +} SignalConstPointerRegisterAccountRequest; + +typedef struct { + uint32_t key_id; + SignalFfiPublicKeyType public_key_type; + const void *public_key; + SignalBorrowedBuffer signature; +} SignalFfiSignedPublicPreKey; + +typedef struct { + SignalRegisterAccountResponse *raw; +} SignalMutPointerRegisterAccountResponse; + +typedef struct { + const SignalRegisterAccountResponse *raw; +} SignalConstPointerRegisterAccountResponse; + +typedef uint8_t SignalOptionalUuid[17]; + +typedef SignalAccountAttributes SignalRegistrationAccountAttributes; + +typedef struct { + SignalRegistrationAccountAttributes *raw; +} SignalMutPointerRegistrationAccountAttributes; + +typedef struct { + const size_t *base; + size_t length; +} SignalBorrowedSliceOfusize; + +typedef struct { + SignalBorrowedBuffer bytes; + SignalBorrowedSliceOfusize lengths; +} SignalBorrowedBytestringArray; + +typedef struct { + /** + * Bridged as a string of bytes, but each entry is a UTF-8 `String` key + * concatenated with a byte for the value. + */ + SignalBytestringArray entries; +} SignalFfiCheckSvr2CredentialsResponse; + +/** + * A C callback used to report the results of Rust futures. + * + * cbindgen will produce independent C types like `SignalCPromisei32` and + * `SignalCPromiseProtocolAddress`. + * + * This derives Copy because it behaves like a C type; nevertheless, a promise should still only be + * completed once. + */ +typedef struct { + void (*complete)(SignalFfiError *error, const SignalFfiCheckSvr2CredentialsResponse *result, const void *context); + const void *context; + SignalCancellationId cancellation_id; +} SignalCPromiseFfiCheckSvr2CredentialsResponse; + +typedef struct { + const SignalRegistrationService *raw; +} SignalConstPointerRegistrationService; + +typedef struct { + SignalRegistrationService *raw; +} SignalMutPointerRegistrationService; + +/** + * A C callback used to report the results of Rust futures. + * + * cbindgen will produce independent C types like `SignalCPromisei32` and + * `SignalCPromiseProtocolAddress`. + * + * This derives Copy because it behaves like a C type; nevertheless, a promise should still only be + * completed once. + */ +typedef struct { + void (*complete)(SignalFfiError *error, const SignalMutPointerRegistrationService *result, const void *context); + const void *context; + SignalCancellationId cancellation_id; +} SignalCPromiseMutPointerRegistrationService; + +typedef struct { + const char *number; + const char *push_token; + const char *mcc; + const char *mnc; +} SignalFfiRegistrationCreateSessionRequest; + +typedef const SignalConnectionManager *(*SignalGetConnectChatConnectionManager)(void *ctx); + +typedef void (*SignalDestroyConnectChatBridge)(void *ctx); + +/** + * A ref-counting pointer to a [`ConnectionManager`] and a callback to + * decrement the count. + */ +typedef struct { + void *ctx; + SignalGetConnectChatConnectionManager get_connection_manager; + SignalDestroyConnectChatBridge destroy; +} SignalFfiConnectChatBridgeStruct; + +typedef struct { + const SignalFfiConnectChatBridgeStruct *raw; +} SignalConstPointerFfiConnectChatBridgeStruct; + +/** + * A C callback used to report the results of Rust futures. + * + * cbindgen will produce independent C types like `SignalCPromisei32` and + * `SignalCPromiseProtocolAddress`. + * + * This derives Copy because it behaves like a C type; nevertheless, a promise should still only be + * completed once. + */ +typedef struct { + void (*complete)(SignalFfiError *error, const SignalMutPointerRegisterAccountResponse *result, const void *context); + const void *context; + SignalCancellationId cancellation_id; +} SignalCPromiseMutPointerRegisterAccountResponse; + +typedef struct { + const SignalRegistrationAccountAttributes *raw; +} SignalConstPointerRegistrationAccountAttributes; + +typedef struct { + SignalRegistrationSession *raw; +} SignalMutPointerRegistrationSession; + +typedef struct { + const SignalRegistrationSession *raw; +} SignalConstPointerRegistrationSession; + typedef struct { const SignalSanitizedMetadata *raw; } SignalConstPointerSanitizedMetadata; @@ -1103,6 +1309,8 @@ typedef struct { typedef uint8_t SignalRandomnessBytes[SignalRANDOMNESS_LEN]; +typedef uint8_t SignalUnidentifiedAccessKey[SignalACCESS_KEY_LEN]; + SignalFfiError *signal_account_entropy_pool_derive_backup_key(uint8_t (*out)[SignalBACKUP_KEY_LEN], const char *account_entropy); SignalFfiError *signal_account_entropy_pool_derive_svr_key(uint8_t (*out)[SignalSVR_KEY_LEN], const char *account_entropy); @@ -1363,6 +1571,10 @@ SignalFfiError *signal_error_get_address(const SignalFfiError *err, SignalMutPoi SignalFfiError *signal_error_get_message(const SignalFfiError *err, const char **out); +SignalFfiError *signal_error_get_registration_error_not_deliverable(const SignalFfiError *err, const char **out_reason, bool *out_permanent); + +SignalFfiError *signal_error_get_registration_lock(const SignalFfiError *err, uint64_t *out_time_remaining_seconds, const char **out_svr2_username, const char **out_svr2_password); + SignalFfiError *signal_error_get_retry_after_seconds(const SignalFfiError *err, uint32_t *out); SignalFfiError *signal_error_get_tries_remaining(const SignalFfiError *err, uint32_t *out); @@ -1395,6 +1607,8 @@ void signal_free_buffer(const unsigned char *buf, size_t buf_len); void signal_free_bytestring_array(SignalBytestringArray array); +void signal_free_list_of_register_response_badges(SignalOwnedBufferOfFfiRegisterResponseBadge buffer); + void signal_free_list_of_strings(SignalOwnedBufferOfCStringPtr buffer); void signal_free_lookup_response_entry_list(SignalOwnedBufferOfFfiCdsiLookupResponseEntry buffer); @@ -1811,6 +2025,84 @@ SignalFfiError *signal_receipt_credential_request_context_get_request(unsigned c SignalFfiError *signal_receipt_credential_response_check_valid_contents(SignalBorrowedBuffer buffer); +SignalFfiError *signal_register_account_request_create(SignalMutPointerRegisterAccountRequest *out); + +SignalFfiError *signal_register_account_request_destroy(SignalMutPointerRegisterAccountRequest p); + +SignalFfiError *signal_register_account_request_set_account_password(SignalConstPointerRegisterAccountRequest register_account, const char *account_password); + +SignalFfiError *signal_register_account_request_set_apn_push_token(SignalConstPointerRegisterAccountRequest register_account, const char *apn_push_token); + +SignalFfiError *signal_register_account_request_set_identity_pq_last_resort_pre_key(SignalConstPointerRegisterAccountRequest register_account, uint8_t identity_type, SignalFfiSignedPublicPreKey pq_last_resort_pre_key); + +SignalFfiError *signal_register_account_request_set_identity_public_key(SignalConstPointerRegisterAccountRequest register_account, uint8_t identity_type, SignalConstPointerPublicKey identity_key); + +SignalFfiError *signal_register_account_request_set_identity_signed_pre_key(SignalConstPointerRegisterAccountRequest register_account, uint8_t identity_type, SignalFfiSignedPublicPreKey signed_pre_key); + +SignalFfiError *signal_register_account_request_set_skip_device_transfer(SignalConstPointerRegisterAccountRequest register_account); + +SignalFfiError *signal_register_account_response_destroy(SignalMutPointerRegisterAccountResponse p); + +SignalFfiError *signal_register_account_response_get_entitlement_backup_expiration_seconds(uint64_t *out, SignalConstPointerRegisterAccountResponse response); + +SignalFfiError *signal_register_account_response_get_entitlement_backup_level(uint64_t *out, SignalConstPointerRegisterAccountResponse response); + +SignalFfiError *signal_register_account_response_get_entitlement_badges(SignalOwnedBufferOfFfiRegisterResponseBadge *out, SignalConstPointerRegisterAccountResponse response); + +SignalFfiError *signal_register_account_response_get_identity(SignalServiceIdFixedWidthBinaryBytes *out, SignalConstPointerRegisterAccountResponse response, uint8_t identity_type); + +SignalFfiError *signal_register_account_response_get_number(const char **out, SignalConstPointerRegisterAccountResponse response); + +SignalFfiError *signal_register_account_response_get_reregistration(bool *out, SignalConstPointerRegisterAccountResponse response); + +SignalFfiError *signal_register_account_response_get_storage_capable(bool *out, SignalConstPointerRegisterAccountResponse response); + +SignalFfiError *signal_register_account_response_get_username_hash(SignalOwnedBuffer *out, SignalConstPointerRegisterAccountResponse response); + +SignalFfiError *signal_register_account_response_get_username_link_handle(SignalOptionalUuid *out, SignalConstPointerRegisterAccountResponse response); + +SignalFfiError *signal_registration_account_attributes_create(SignalMutPointerRegistrationAccountAttributes *out, SignalBorrowedBuffer recovery_password, uint16_t aci_registration_id, uint16_t pni_registration_id, const char *registration_lock, const uint8_t (*unidentified_access_key)[16], bool unrestricted_unidentified_access, SignalBorrowedBytestringArray capabilities, bool discoverable_by_phone_number); + +SignalFfiError *signal_registration_account_attributes_destroy(SignalMutPointerRegistrationAccountAttributes p); + +SignalFfiError *signal_registration_service_check_svr2_credentials(SignalCPromiseFfiCheckSvr2CredentialsResponse *promise, SignalConstPointerTokioAsyncContext async_runtime, SignalConstPointerRegistrationService service, SignalBorrowedBytestringArray svr_tokens); + +SignalFfiError *signal_registration_service_create_session(SignalCPromiseMutPointerRegistrationService *promise, SignalConstPointerTokioAsyncContext async_runtime, SignalFfiRegistrationCreateSessionRequest create_session, SignalConstPointerFfiConnectChatBridgeStruct connect_chat); + +SignalFfiError *signal_registration_service_destroy(SignalMutPointerRegistrationService p); + +SignalFfiError *signal_registration_service_register_account(SignalCPromiseMutPointerRegisterAccountResponse *promise, SignalConstPointerTokioAsyncContext async_runtime, SignalConstPointerRegistrationService service, SignalConstPointerRegisterAccountRequest register_account, SignalConstPointerRegistrationAccountAttributes account_attributes); + +SignalFfiError *signal_registration_service_registration_session(SignalMutPointerRegistrationSession *out, SignalConstPointerRegistrationService service); + +SignalFfiError *signal_registration_service_request_push_challenge(SignalCPromisebool *promise, SignalConstPointerTokioAsyncContext async_runtime, SignalConstPointerRegistrationService service, const char *push_token, const void *push_token_type); + +SignalFfiError *signal_registration_service_request_verification_code(SignalCPromisebool *promise, SignalConstPointerTokioAsyncContext async_runtime, SignalConstPointerRegistrationService service, const char *transport, const char *client, SignalBorrowedBytestringArray languages); + +SignalFfiError *signal_registration_service_resume_session(SignalCPromiseMutPointerRegistrationService *promise, SignalConstPointerTokioAsyncContext async_runtime, const char *session_id, const char *number, SignalConstPointerFfiConnectChatBridgeStruct connect_chat); + +SignalFfiError *signal_registration_service_session_id(const char **out, SignalConstPointerRegistrationService service); + +SignalFfiError *signal_registration_service_submit_captcha(SignalCPromisebool *promise, SignalConstPointerTokioAsyncContext async_runtime, SignalConstPointerRegistrationService service, const char *captcha_value); + +SignalFfiError *signal_registration_service_submit_push_challenge(SignalCPromisebool *promise, SignalConstPointerTokioAsyncContext async_runtime, SignalConstPointerRegistrationService service, const char *push_challenge); + +SignalFfiError *signal_registration_service_submit_verification_code(SignalCPromisebool *promise, SignalConstPointerTokioAsyncContext async_runtime, SignalConstPointerRegistrationService service, const char *code); + +SignalFfiError *signal_registration_session_destroy(SignalMutPointerRegistrationSession p); + +SignalFfiError *signal_registration_session_get_allowed_to_request_code(bool *out, SignalConstPointerRegistrationSession session); + +SignalFfiError *signal_registration_session_get_next_call_seconds(uint32_t *out, SignalConstPointerRegistrationSession session); + +SignalFfiError *signal_registration_session_get_next_sms_seconds(uint32_t *out, SignalConstPointerRegistrationSession session); + +SignalFfiError *signal_registration_session_get_next_verification_attempt_seconds(uint32_t *out, SignalConstPointerRegistrationSession session); + +SignalFfiError *signal_registration_session_get_requested_information(SignalOwnedBuffer *out, SignalConstPointerRegistrationSession session); + +SignalFfiError *signal_registration_session_get_verified(bool *out, SignalConstPointerRegistrationSession session); + #if defined(SIGNAL_MEDIA_SUPPORTED) SignalFfiError *signal_sanitized_metadata_clone(SignalMutPointerSanitizedMetadata *new_obj, SignalConstPointerSanitizedMetadata obj); #endif @@ -1835,8 +2127,6 @@ SignalFfiError *signal_sealed_sender_multi_recipient_encrypt(SignalOwnedBuffer * SignalFfiError *signal_sealed_sender_multi_recipient_message_for_single_recipient(SignalOwnedBuffer *out, SignalBorrowedBuffer encoded_multi_recipient_message); -SignalFfiError *signal_sealed_session_cipher_decrypt(SignalOwnedBuffer *out, const char **sender_e164, const char **sender_uuid, uint32_t *sender_device_id, SignalBorrowedBuffer ctext, SignalConstPointerPublicKey trust_root, uint64_t timestamp, const char *local_e164, const char *local_uuid, unsigned int local_device_id, SignalConstPointerFfiSessionStoreStruct session_store, SignalConstPointerFfiIdentityKeyStoreStruct identity_store, SignalConstPointerFfiPreKeyStoreStruct prekey_store, SignalConstPointerFfiSignedPreKeyStoreStruct signed_prekey_store); - SignalFfiError *signal_sealed_session_cipher_decrypt_to_usmc(SignalMutPointerUnidentifiedSenderMessageContent *out, SignalBorrowedBuffer ctext, SignalConstPointerFfiIdentityKeyStoreStruct identity_store); SignalFfiError *signal_sealed_session_cipher_encrypt(SignalOwnedBuffer *out, SignalConstPointerProtocolAddress destination, SignalConstPointerUnidentifiedSenderMessageContent content, SignalConstPointerFfiIdentityKeyStoreStruct identity_key_store); diff --git a/pkg/libsignalgo/sealedsender.go b/pkg/libsignalgo/sealedsender.go index 1e93410..1530183 100644 --- a/pkg/libsignalgo/sealedsender.go +++ b/pkg/libsignalgo/sealedsender.go @@ -107,61 +107,6 @@ func SealedSenderDecryptToUSMC( return wrapUnidentifiedSenderMessageContent(usmc.raw), nil } -func SealedSenderDecrypt( - ctx context.Context, - ciphertext []byte, - localAddress *SealedSenderAddress, - trustRoot *PublicKey, - timestamp uint64, - sessionStore SessionStore, - identityStore IdentityKeyStore, - preKeyStore PreKeyStore, - signedPreKeyStore SignedPreKeyStore, -) (result SealedSenderResult, err error) { - callbackCtx := NewCallbackContext(ctx) - defer callbackCtx.Unref() - - var decrypted C.SignalOwnedBuffer = C.SignalOwnedBuffer{} - var senderE164 *C.char - var senderUUID *C.char - var senderDeviceID C.uint32_t - - signalFfiError := C.signal_sealed_session_cipher_decrypt( - &decrypted, - &senderE164, - &senderUUID, - &senderDeviceID, - BytesToBuffer(ciphertext), - trustRoot.constPtr(), - C.uint64_t(timestamp), - C.CString(localAddress.E164), - C.CString(localAddress.UUID.String()), - C.uint32_t(localAddress.DeviceID), - callbackCtx.wrapSessionStore(sessionStore), - callbackCtx.wrapIdentityKeyStore(identityStore), - callbackCtx.wrapPreKeyStore(preKeyStore), - callbackCtx.wrapSignedPreKeyStore(signedPreKeyStore), - ) - runtime.KeepAlive(localAddress) - runtime.KeepAlive(trustRoot) - if signalFfiError != nil { - err = callbackCtx.wrapError(signalFfiError) - return - } - - defer C.signal_free_string(senderE164) - defer C.signal_free_string(senderUUID) - - return SealedSenderResult{ - Message: CopySignalOwnedBufferToBytes(decrypted), - Sender: SealedSenderAddress{ - E164: C.GoString(senderE164), - UUID: uuid.MustParse(C.GoString(senderUUID)), - DeviceID: uint32(senderDeviceID), - }, - }, nil -} - type UnidentifiedSenderMessageContentHint uint32 const ( diff --git a/pkg/libsignalgo/session_test.go b/pkg/libsignalgo/session_test.go index 1840fc3..30af762 100644 --- a/pkg/libsignalgo/session_test.go +++ b/pkg/libsignalgo/session_test.go @@ -247,96 +247,6 @@ func TestSealedSenderEncrypt_Repeated(t *testing.T) { } } -// From SessionTests.swift:testSealedSenderSession -func TestSealedSenderSession(t *testing.T) { - ctx := context.TODO() - - setupLogging() - - aliceAddress, err := libsignalgo.NewUUIDAddressFromString("9d0652a3-dcc3-4d11-975f-74d61598733f", 1) - assert.NoError(t, err) - bobAddress, err := libsignalgo.NewUUIDAddressFromString("6838237D-02F6-4098-B110-698253D15961", 1) - assert.NoError(t, err) - - aliceStore := NewInMemorySignalProtocolStore() - bobStore := NewInMemorySignalProtocolStore() - - initializeSessions(t, aliceStore, bobStore, bobAddress) - - trustRoot, err := libsignalgo.GenerateIdentityKeyPair() - assert.NoError(t, err) - serverKeys, err := libsignalgo.GenerateIdentityKeyPair() - assert.NoError(t, err) - serverCert, err := libsignalgo.NewServerCertificate(1, serverKeys.GetPublicKey(), trustRoot.GetPrivateKey()) - assert.NoError(t, err) - aliceName, err := aliceAddress.Name() - assert.NoError(t, err) - senderAddress := libsignalgo.NewSealedSenderAddress("+14151111111", uuid.MustParse(aliceName), 1) - - aliceIdentityKeyPair, err := aliceStore.GetIdentityKeyPair(ctx) - require.NoError(t, err) - senderCert, err := libsignalgo.NewSenderCertificate(senderAddress, aliceIdentityKeyPair.GetPublicKey(), time.UnixMilli(31337), serverCert, serverKeys.GetPrivateKey()) - assert.NoError(t, err) - - message := []byte("2020 vision") - ciphertext, err := libsignalgo.SealedSenderEncryptPlaintext(ctx, message, libsignalgo.UnidentifiedSenderMessageContentHintDefault, bobAddress, senderCert, aliceStore, aliceStore) - require.NoError(t, err) - assert.NotNil(t, ciphertext) - - bobName, err := bobAddress.Name() - require.NoError(t, err) - recipientAddress := libsignalgo.NewSealedSenderAddress("", uuid.MustParse(bobName), 1) - - t.Skip("This test is broken") // TODO fix - - plaintext, err := libsignalgo.SealedSenderDecrypt( - ctx, - ciphertext, - recipientAddress, - trustRoot.GetPublicKey(), - 31335, - bobStore, - bobStore, - bobStore, - bobStore, - ) - require.NoError(t, err) - assert.Equal(t, message, plaintext.Message) - assert.Equal(t, senderAddress.DeviceID, plaintext.Sender.DeviceID) - assert.Equal(t, senderAddress.E164, plaintext.Sender.E164) - assert.Equal(t, senderAddress.UUID, plaintext.Sender.UUID) - - innerMessage, err := libsignalgo.Encrypt(ctx, []byte{}, bobAddress, aliceStore, aliceStore) - require.NoError(t, err) - - hints := []libsignalgo.UnidentifiedSenderMessageContentHint{ - 200, - libsignalgo.UnidentifiedSenderMessageContentHintDefault, - libsignalgo.UnidentifiedSenderMessageContentHintResendable, - libsignalgo.UnidentifiedSenderMessageContentHintImplicit, - } - - for _, hint := range hints { - content, err := libsignalgo.NewUnidentifiedSenderMessageContent( - innerMessage, - senderCert, - hint, - []byte{}, - ) - require.NoError(t, err) - - _, err = libsignalgo.SealedSenderEncrypt(ctx, content, bobAddress, aliceStore) - require.NoError(t, err) - - // decryptedContent, err := libsignalgo.NewUnidentifiedSenderMessageContent(ciphertext) - - // let decryptedContent = try UnidentifiedSenderMessageContent(message: ciphertext, - // identityStore: bob_store, - // context: NullContext()) - // XCTAssertEqual(decryptedContent.contentHint, hint) - } -} - // From SessionTests.swift:testArchiveSession func TestArchiveSession(t *testing.T) { ctx := context.TODO() diff --git a/pkg/libsignalgo/version.go b/pkg/libsignalgo/version.go index bce148c..5a7e360 100644 --- a/pkg/libsignalgo/version.go +++ b/pkg/libsignalgo/version.go @@ -2,4 +2,4 @@ package libsignalgo -const Version = "v0.71.0" +const Version = "v0.72.1" From 79701f572a6ccfd5dbdc7c71a31f51e8adaf43bb Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Thu, 15 May 2025 16:01:09 +0300 Subject: [PATCH 338/580] dependencies: update --- go.mod | 22 +++++++++++----------- go.sum | 44 ++++++++++++++++++++++---------------------- 2 files changed, 33 insertions(+), 33 deletions(-) diff --git a/go.mod b/go.mod index 4322e00..5c63d64 100644 --- a/go.mod +++ b/go.mod @@ -13,12 +13,12 @@ require ( github.com/rs/zerolog v1.34.0 github.com/stretchr/testify v1.10.0 github.com/tidwall/gjson v1.18.0 - go.mau.fi/util v0.8.7-0.20250504163337-fc01e957f535 - golang.org/x/crypto v0.37.0 - golang.org/x/exp v0.0.0-20250408133849-7e4ce0ab07d0 - golang.org/x/net v0.39.0 + go.mau.fi/util v0.8.7-0.20250515110144-747f5904911e + golang.org/x/crypto v0.38.0 + golang.org/x/exp v0.0.0-20250506013437-ce4c2cf36ca6 + golang.org/x/net v0.40.0 google.golang.org/protobuf v1.36.6 - maunium.net/go/mautrix v0.23.4-0.20250508122520-376fa1f36898 + maunium.net/go/mautrix v0.23.4-0.20250515111534-978e0983eadf ) require ( @@ -30,8 +30,8 @@ require ( github.com/lib/pq v1.10.9 // indirect github.com/mattn/go-colorable v0.1.14 // indirect github.com/mattn/go-isatty v0.0.20 // indirect - github.com/mattn/go-sqlite3 v1.14.27 // indirect - github.com/petermattis/goid v0.0.0-20250319124200-ccd6737f222a // indirect + github.com/mattn/go-sqlite3 v1.14.28 // indirect + github.com/petermattis/goid v0.0.0-20250508124226-395b08cebbdb // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/rogpeppe/go-internal v1.10.0 // indirect github.com/rs/xid v1.6.0 // indirect @@ -39,11 +39,11 @@ require ( github.com/tidwall/match v1.1.1 // indirect github.com/tidwall/pretty v1.2.1 // indirect github.com/tidwall/sjson v1.2.5 // indirect - github.com/yuin/goldmark v1.7.10 // indirect + github.com/yuin/goldmark v1.7.11 // indirect go.mau.fi/zeroconfig v0.1.3 // indirect - golang.org/x/sync v0.13.0 // indirect - golang.org/x/sys v0.32.0 // indirect - golang.org/x/text v0.24.0 // indirect + golang.org/x/sync v0.14.0 // indirect + golang.org/x/sys v0.33.0 // indirect + golang.org/x/text v0.25.0 // indirect gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect gopkg.in/natefinch/lumberjack.v2 v2.2.1 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect diff --git a/go.sum b/go.sum index e45bd46..47ed096 100644 --- a/go.sum +++ b/go.sum @@ -38,10 +38,10 @@ github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWE github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mattn/go-pointer v0.0.1 h1:n+XhsuGeVO6MEAp7xyEukFINEa+Quek5psIR/ylA6o0= github.com/mattn/go-pointer v0.0.1/go.mod h1:2zXcozF6qYGgmsG+SeTZz3oAbFLdD3OWqnUbNvJZAlc= -github.com/mattn/go-sqlite3 v1.14.27 h1:drZCnuvf37yPfs95E5jd9s3XhdVWLal+6BOK6qrv6IU= -github.com/mattn/go-sqlite3 v1.14.27/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y= -github.com/petermattis/goid v0.0.0-20250319124200-ccd6737f222a h1:S+AGcmAESQ0pXCUNnRH7V+bOUIgkSX5qVt2cNKCrm0Q= -github.com/petermattis/goid v0.0.0-20250319124200-ccd6737f222a/go.mod h1:pxMtw7cyUw6B2bRH0ZBANSPg+AoSud1I1iyJHI69jH4= +github.com/mattn/go-sqlite3 v1.14.28 h1:ThEiQrnbtumT+QMknw63Befp/ce/nUPgBPMlRFEum7A= +github.com/mattn/go-sqlite3 v1.14.28/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y= +github.com/petermattis/goid v0.0.0-20250508124226-395b08cebbdb h1:3PrKuO92dUTMrQ9dx0YNejC6U/Si6jqKmyQ9vWjwqR4= +github.com/petermattis/goid v0.0.0-20250508124226-395b08cebbdb/go.mod h1:pxMtw7cyUw6B2bRH0ZBANSPg+AoSud1I1iyJHI69jH4= github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= @@ -67,27 +67,27 @@ github.com/tidwall/pretty v1.2.1 h1:qjsOFOWWQl+N3RsoF5/ssm1pHmJJwhjlSbZ51I6wMl4= github.com/tidwall/pretty v1.2.1/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU= github.com/tidwall/sjson v1.2.5 h1:kLy8mja+1c9jlljvWTlSazM7cKDRfJuR/bOJhcY5NcY= github.com/tidwall/sjson v1.2.5/go.mod h1:Fvgq9kS/6ociJEDnK0Fk1cpYF4FIW6ZF7LAe+6jwd28= -github.com/yuin/goldmark v1.7.10 h1:S+LrtBjRmqMac2UdtB6yyCEJm+UILZ2fefI4p7o0QpI= -github.com/yuin/goldmark v1.7.10/go.mod h1:ip/1k0VRfGynBgxOz0yCqHrbZXhcjxyuS66Brc7iBKg= -go.mau.fi/util v0.8.7-0.20250504163337-fc01e957f535 h1:ESKcyK5hWCzx8dzfSGKEuhuRD3Dg3eCtxOjxmjpnO5s= -go.mau.fi/util v0.8.7-0.20250504163337-fc01e957f535/go.mod h1:uNB3UTXFbkpp7xL1M/WvQks90B/L4gvbLpbS0603KOE= +github.com/yuin/goldmark v1.7.11 h1:ZCxLyDMtz0nT2HFfsYG8WZ47Trip2+JyLysKcMYE5bo= +github.com/yuin/goldmark v1.7.11/go.mod h1:ip/1k0VRfGynBgxOz0yCqHrbZXhcjxyuS66Brc7iBKg= +go.mau.fi/util v0.8.7-0.20250515110144-747f5904911e h1:8kfjOQ+L38Zq2HbhMFVhbkTdwiGbAmgTriioRnRB+LQ= +go.mau.fi/util v0.8.7-0.20250515110144-747f5904911e/go.mod h1:j6R3cENakc1f8HpQeFl0N15UiSTcNmIfDBNJUbL71RY= go.mau.fi/zeroconfig v0.1.3 h1:As9wYDKmktjmNZW5i1vn8zvJlmGKHeVxHVIBMXsm4kM= go.mau.fi/zeroconfig v0.1.3/go.mod h1:NcSJkf180JT+1IId76PcMuLTNa1CzsFFZ0nBygIQM70= -golang.org/x/crypto v0.37.0 h1:kJNSjF/Xp7kU0iB2Z+9viTPMW4EqqsrywMXLJOOsXSE= -golang.org/x/crypto v0.37.0/go.mod h1:vg+k43peMZ0pUMhYmVAWysMK35e6ioLh3wB8ZCAfbVc= -golang.org/x/exp v0.0.0-20250408133849-7e4ce0ab07d0 h1:R84qjqJb5nVJMxqWYb3np9L5ZsaDtB+a39EqjV0JSUM= -golang.org/x/exp v0.0.0-20250408133849-7e4ce0ab07d0/go.mod h1:S9Xr4PYopiDyqSyp5NjCrhFrqg6A5zA2E/iPHPhqnS8= -golang.org/x/net v0.39.0 h1:ZCu7HMWDxpXpaiKdhzIfaltL9Lp31x/3fCP11bc6/fY= -golang.org/x/net v0.39.0/go.mod h1:X7NRbYVEA+ewNkCNyJ513WmMdQ3BineSwVtN2zD/d+E= -golang.org/x/sync v0.13.0 h1:AauUjRAJ9OSnvULf/ARrrVywoJDy0YS2AwQ98I37610= -golang.org/x/sync v0.13.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= +golang.org/x/crypto v0.38.0 h1:jt+WWG8IZlBnVbomuhg2Mdq0+BBQaHbtqHEFEigjUV8= +golang.org/x/crypto v0.38.0/go.mod h1:MvrbAqul58NNYPKnOra203SB9vpuZW0e+RRZV+Ggqjw= +golang.org/x/exp v0.0.0-20250506013437-ce4c2cf36ca6 h1:y5zboxd6LQAqYIhHnB48p0ByQ/GnQx2BE33L8BOHQkI= +golang.org/x/exp v0.0.0-20250506013437-ce4c2cf36ca6/go.mod h1:U6Lno4MTRCDY+Ba7aCcauB9T60gsv5s4ralQzP72ZoQ= +golang.org/x/net v0.40.0 h1:79Xs7wF06Gbdcg4kdCCIQArK11Z1hr5POQ6+fIYHNuY= +golang.org/x/net v0.40.0/go.mod h1:y0hY0exeL2Pku80/zKK7tpntoX23cqL3Oa6njdgRtds= +golang.org/x/sync v0.14.0 h1:woo0S4Yywslg6hp4eUFjTVOyKt0RookbpAHG4c1HmhQ= +golang.org/x/sync v0.14.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.32.0 h1:s77OFDvIQeibCmezSnk/q6iAfkdiQaJi4VzroCFrN20= -golang.org/x/sys v0.32.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= -golang.org/x/text v0.24.0 h1:dd5Bzh4yt5KYA8f9CJHCP4FB4D51c2c6JvN37xJJkJ0= -golang.org/x/text v0.24.0/go.mod h1:L8rBsPeo2pSS+xqN0d5u2ikmjtmoJbDBT1b7nHvFCdU= +golang.org/x/sys v0.33.0 h1:q3i8TbbEz+JRD9ywIRlyRAQbM0qF7hu24q3teo2hbuw= +golang.org/x/sys v0.33.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= +golang.org/x/text v0.25.0 h1:qVyWApTSYLk/drJRO5mDlNYskwQznZmkpV2c8q9zls4= +golang.org/x/text v0.25.0/go.mod h1:WEdwpYrmk1qmdHvhkSTNPm3app7v4rsT8F2UD6+VHIA= google.golang.org/protobuf v1.36.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY= google.golang.org/protobuf v1.36.6/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= @@ -99,5 +99,5 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= maunium.net/go/mauflag v1.0.0 h1:YiaRc0tEI3toYtJMRIfjP+jklH45uDHtT80nUamyD4M= maunium.net/go/mauflag v1.0.0/go.mod h1:nLivPOpTpHnpzEh8jEdSL9UqO9+/KBJFmNRlwKfkPeA= -maunium.net/go/mautrix v0.23.4-0.20250508122520-376fa1f36898 h1:ZS1FV3+vmGquh//RGBRk3TzdoqCPOwEr40cA7k9e/jA= -maunium.net/go/mautrix v0.23.4-0.20250508122520-376fa1f36898/go.mod h1:pT4G5RZQ+nLfKzsmeDa4NhHghOVTrasLLwY9tZ2mO08= +maunium.net/go/mautrix v0.23.4-0.20250515111534-978e0983eadf h1:kCBKSVfLrKtaSD4XBp/cj+dkqNWesMdyu5KODrMtVYc= +maunium.net/go/mautrix v0.23.4-0.20250515111534-978e0983eadf/go.mod h1:A9WfZ8F6jxM7F8eKaVZ4TAC7dWoqHBShMA8baCvtpZU= From 99d026d51009f4de7a4a8a53d083afc0024ae955 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Fri, 16 May 2025 08:16:28 +0300 Subject: [PATCH 339/580] Bump version to v0.8.3 --- CHANGELOG.md | 12 +++++++++++- cmd/mautrix-signal/main.go | 2 +- go.mod | 4 ++-- go.sum | 8 ++++---- 4 files changed, 18 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 722ed55..e9da97b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,16 @@ +# v0.8.3 (2025-05-16) + +* Updated libsignal to v0.72.1. +* Added initial support for direct media access. + * Note that media is only kept on the Signal servers for 45 days, after which + any direct media links will permanently stop working. +* Added buffer for decrypted events to prevent losing messages if the bridge is + stopped in the middle of event handling. +* Fixed backfilling messages in existing portals after relogining. + # v0.8.2 (2025-04-16) -* Updated libsignal to v0.70.0 +* Updated libsignal to v0.70.0. * Fixed panics in some cases when the bridge was under heavy load. # v0.8.1 (2025-03-16) diff --git a/cmd/mautrix-signal/main.go b/cmd/mautrix-signal/main.go index c1689d6..b2eccfb 100644 --- a/cmd/mautrix-signal/main.go +++ b/cmd/mautrix-signal/main.go @@ -38,7 +38,7 @@ var m = mxmain.BridgeMain{ Name: "mautrix-signal", URL: "https://github.com/mautrix/signal", Description: "A Matrix-Signal puppeting bridge.", - Version: "0.8.2", + Version: "0.8.3", Connector: &connector.SignalConnector{}, } diff --git a/go.mod b/go.mod index 5c63d64..ac1eb60 100644 --- a/go.mod +++ b/go.mod @@ -13,12 +13,12 @@ require ( github.com/rs/zerolog v1.34.0 github.com/stretchr/testify v1.10.0 github.com/tidwall/gjson v1.18.0 - go.mau.fi/util v0.8.7-0.20250515110144-747f5904911e + go.mau.fi/util v0.8.7 golang.org/x/crypto v0.38.0 golang.org/x/exp v0.0.0-20250506013437-ce4c2cf36ca6 golang.org/x/net v0.40.0 google.golang.org/protobuf v1.36.6 - maunium.net/go/mautrix v0.23.4-0.20250515111534-978e0983eadf + maunium.net/go/mautrix v0.24.0 ) require ( diff --git a/go.sum b/go.sum index 47ed096..7e503f1 100644 --- a/go.sum +++ b/go.sum @@ -69,8 +69,8 @@ github.com/tidwall/sjson v1.2.5 h1:kLy8mja+1c9jlljvWTlSazM7cKDRfJuR/bOJhcY5NcY= github.com/tidwall/sjson v1.2.5/go.mod h1:Fvgq9kS/6ociJEDnK0Fk1cpYF4FIW6ZF7LAe+6jwd28= github.com/yuin/goldmark v1.7.11 h1:ZCxLyDMtz0nT2HFfsYG8WZ47Trip2+JyLysKcMYE5bo= github.com/yuin/goldmark v1.7.11/go.mod h1:ip/1k0VRfGynBgxOz0yCqHrbZXhcjxyuS66Brc7iBKg= -go.mau.fi/util v0.8.7-0.20250515110144-747f5904911e h1:8kfjOQ+L38Zq2HbhMFVhbkTdwiGbAmgTriioRnRB+LQ= -go.mau.fi/util v0.8.7-0.20250515110144-747f5904911e/go.mod h1:j6R3cENakc1f8HpQeFl0N15UiSTcNmIfDBNJUbL71RY= +go.mau.fi/util v0.8.7 h1:ywKarPxouJQEEijTs4mPlxC7F4AWEKokEpWc+2TYy6c= +go.mau.fi/util v0.8.7/go.mod h1:j6R3cENakc1f8HpQeFl0N15UiSTcNmIfDBNJUbL71RY= go.mau.fi/zeroconfig v0.1.3 h1:As9wYDKmktjmNZW5i1vn8zvJlmGKHeVxHVIBMXsm4kM= go.mau.fi/zeroconfig v0.1.3/go.mod h1:NcSJkf180JT+1IId76PcMuLTNa1CzsFFZ0nBygIQM70= golang.org/x/crypto v0.38.0 h1:jt+WWG8IZlBnVbomuhg2Mdq0+BBQaHbtqHEFEigjUV8= @@ -99,5 +99,5 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= maunium.net/go/mauflag v1.0.0 h1:YiaRc0tEI3toYtJMRIfjP+jklH45uDHtT80nUamyD4M= maunium.net/go/mauflag v1.0.0/go.mod h1:nLivPOpTpHnpzEh8jEdSL9UqO9+/KBJFmNRlwKfkPeA= -maunium.net/go/mautrix v0.23.4-0.20250515111534-978e0983eadf h1:kCBKSVfLrKtaSD4XBp/cj+dkqNWesMdyu5KODrMtVYc= -maunium.net/go/mautrix v0.23.4-0.20250515111534-978e0983eadf/go.mod h1:A9WfZ8F6jxM7F8eKaVZ4TAC7dWoqHBShMA8baCvtpZU= +maunium.net/go/mautrix v0.24.0 h1:kBeyWhgL1W8/d8BEFlBSlgIpItPgP1l37hzF8cN3R70= +maunium.net/go/mautrix v0.24.0/go.mod h1:HqA1HUutQYJkrYRPkK64itARDz79PCec1oWVEB72HVQ= From 1b1136537d3125d8ede55ce490dcfc6bd27a3f34 Mon Sep 17 00:00:00 2001 From: Adam Van Ymeren Date: Mon, 19 May 2025 08:00:11 -0700 Subject: [PATCH 340/580] directmedia: actually return properly decoded profile avatar info (#600) --- pkg/signalid/media.go | 1 + 1 file changed, 1 insertion(+) diff --git a/pkg/signalid/media.go b/pkg/signalid/media.go index defd4e5..533463c 100644 --- a/pkg/signalid/media.go +++ b/pkg/signalid/media.go @@ -192,6 +192,7 @@ func ParseDirectMediaInfo(mediaID networkid.MediaID) (_ DirectMediaInfo, err err } else { info.ProfileAvatarPath = string(profileAvatarPath) } + return &info, nil } return nil, fmt.Errorf("invalid direct media type %d", mediaType) From 6b06430c028aada0c518800e88517a6360a5c1da Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Mon, 26 May 2025 15:33:49 +0300 Subject: [PATCH 341/580] signalmeow/receiving: change log level for already processed events --- pkg/signalmeow/receiving.go | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/pkg/signalmeow/receiving.go b/pkg/signalmeow/receiving.go index 4e46a66..b24d167 100644 --- a/pkg/signalmeow/receiving.go +++ b/pkg/signalmeow/receiving.go @@ -414,13 +414,23 @@ func (cli *Client) handleDecryptedResult( } else if theirServiceID.Type != libsignalgo.ServiceIDTypeACI { log.Warn().Any("their_service_id", theirServiceID).Msg("Sender ServiceID is not an ACI") } + if errors.Is(result.Err, EventAlreadyProcessed) { + logEvt.Discard().Msg("") + log.Debug().Err(result.Err). + Bool("urgent", envelope.GetUrgent()). + Stringer("content_hint", result.ContentHint). + Uint64("server_ts", envelope.GetServerTimestamp()). + Uint64("client_ts", envelope.GetTimestamp()). + Stringer("sender", theirServiceID). + Msg("Ignoring already processed event") + return nil + } logEvt.Stringer("sender", theirServiceID).Msg("Decryption error with known sender") // Only send decryption error event if the message was urgent, // to prevent spamming errors for typing notifications and whatnot if envelope.GetUrgent() && result.ContentHint != signalpb.UnidentifiedSenderMessage_Message_IMPLICIT && - !strings.Contains(result.Err.Error(), "message with old counter") && - !errors.Is(err, EventAlreadyProcessed) { + !strings.Contains(result.Err.Error(), "message with old counter") { cli.handleEvent(&events.DecryptionError{ Sender: theirServiceID.UUID, Err: result.Err, From 7eb997b46067bacec0cff9ce870adee481194dd2 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Mon, 26 May 2025 15:37:05 +0300 Subject: [PATCH 342/580] handlesignal: add missing details to decryption error event --- pkg/connector/handlesignal.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/pkg/connector/handlesignal.go b/pkg/connector/handlesignal.go index 8a94016..183cfa4 100644 --- a/pkg/connector/handlesignal.go +++ b/pkg/connector/handlesignal.go @@ -107,12 +107,14 @@ func (s *SignalClient) wrapDecryptionError(evt *events.DecryptionError) bridgev2 Type: bridgev2.RemoteEventMessage, LogContext: func(c zerolog.Context) zerolog.Context { c = c.Stringer("sender_id", evt.Sender) + c = c.Uint64("message_ts", evt.Timestamp) return c }, PortalKey: s.makePortalKey(evt.Sender.String()), CreatePortal: true, Sender: s.makeEventSender(evt.Sender), Timestamp: time.UnixMilli(int64(evt.Timestamp)), + StreamOrder: int64(evt.Timestamp), }, Data: evt, // TODO use main message id and edit it if it later becomes decryptable? From 55321a53e63022f027678159b33e93792b67f9ce Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Tue, 27 May 2025 11:44:34 +0300 Subject: [PATCH 343/580] dependencies: update mautrix-go --- go.mod | 2 +- go.sum | 4 ++-- pkg/msgconv/urlpreview.go | 6 +++--- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/go.mod b/go.mod index ac1eb60..c1184f2 100644 --- a/go.mod +++ b/go.mod @@ -18,7 +18,7 @@ require ( golang.org/x/exp v0.0.0-20250506013437-ce4c2cf36ca6 golang.org/x/net v0.40.0 google.golang.org/protobuf v1.36.6 - maunium.net/go/mautrix v0.24.0 + maunium.net/go/mautrix v0.24.1-0.20250527083757-8a745c0d03ec ) require ( diff --git a/go.sum b/go.sum index 7e503f1..138e781 100644 --- a/go.sum +++ b/go.sum @@ -99,5 +99,5 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= maunium.net/go/mauflag v1.0.0 h1:YiaRc0tEI3toYtJMRIfjP+jklH45uDHtT80nUamyD4M= maunium.net/go/mauflag v1.0.0/go.mod h1:nLivPOpTpHnpzEh8jEdSL9UqO9+/KBJFmNRlwKfkPeA= -maunium.net/go/mautrix v0.24.0 h1:kBeyWhgL1W8/d8BEFlBSlgIpItPgP1l37hzF8cN3R70= -maunium.net/go/mautrix v0.24.0/go.mod h1:HqA1HUutQYJkrYRPkK64itARDz79PCec1oWVEB72HVQ= +maunium.net/go/mautrix v0.24.1-0.20250527083757-8a745c0d03ec h1:kn/SHMTE4FiafMFS9WKXzHQc/Z9yN09Aa7TiFOgYfSY= +maunium.net/go/mautrix v0.24.1-0.20250527083757-8a745c0d03ec/go.mod h1:HqA1HUutQYJkrYRPkK64itARDz79PCec1oWVEB72HVQ= diff --git a/pkg/msgconv/urlpreview.go b/pkg/msgconv/urlpreview.go index fcb32fb..66b186a 100644 --- a/pkg/msgconv/urlpreview.go +++ b/pkg/msgconv/urlpreview.go @@ -52,9 +52,9 @@ func (mc *MessageConverter) convertURLPreviewToBeeper(ctx context.Context, previ output.ImageURL = msg.Content.URL output.ImageEncryption = msg.Content.File output.ImageType = msg.Content.Info.MimeType - output.ImageSize = msg.Content.Info.Size - output.ImageHeight = msg.Content.Info.Height - output.ImageWidth = msg.Content.Info.Width + output.ImageSize = event.IntOrString(msg.Content.Info.Size) + output.ImageHeight = event.IntOrString(msg.Content.Info.Height) + output.ImageWidth = event.IntOrString(msg.Content.Info.Width) } } return output From 58f62f72b7f8de5726a9fc1091add05451866a95 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Tue, 27 May 2025 14:42:51 +0300 Subject: [PATCH 344/580] signalmeow/contactdiscovery: update enclave id --- pkg/signalmeow/contactdiscovery.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/signalmeow/contactdiscovery.go b/pkg/signalmeow/contactdiscovery.go index 33b0ad3..2360457 100644 --- a/pkg/signalmeow/contactdiscovery.go +++ b/pkg/signalmeow/contactdiscovery.go @@ -40,7 +40,7 @@ import ( ) const ProdContactDiscoveryServer = "cdsi.signal.org" -const ProdContactDiscoveryMrenclave = "0f6fd79cdfdaa5b2e6337f534d3baf999318b0c462a7ac1f41297a3e4b424a57" +const ProdContactDiscoveryMrenclave = "c6ff0682219217f7045624be472a077c0d4b06193fe71632eb0adb50051d5da1" const ContactDiscoveryAuthTTL = 23 * time.Hour const rateLimitCloseCode = websocket.StatusCode(4008) From 3c960fe56288700af98b16cda18c76febb4ddb64 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Sat, 31 May 2025 18:07:07 +0300 Subject: [PATCH 345/580] dependencies: update mautrix-go --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index c1184f2..abd27a4 100644 --- a/go.mod +++ b/go.mod @@ -18,7 +18,7 @@ require ( golang.org/x/exp v0.0.0-20250506013437-ce4c2cf36ca6 golang.org/x/net v0.40.0 google.golang.org/protobuf v1.36.6 - maunium.net/go/mautrix v0.24.1-0.20250527083757-8a745c0d03ec + maunium.net/go/mautrix v0.24.1-0.20250531150347-788621f7e035 ) require ( diff --git a/go.sum b/go.sum index 138e781..6257f3b 100644 --- a/go.sum +++ b/go.sum @@ -99,5 +99,5 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= maunium.net/go/mauflag v1.0.0 h1:YiaRc0tEI3toYtJMRIfjP+jklH45uDHtT80nUamyD4M= maunium.net/go/mauflag v1.0.0/go.mod h1:nLivPOpTpHnpzEh8jEdSL9UqO9+/KBJFmNRlwKfkPeA= -maunium.net/go/mautrix v0.24.1-0.20250527083757-8a745c0d03ec h1:kn/SHMTE4FiafMFS9WKXzHQc/Z9yN09Aa7TiFOgYfSY= -maunium.net/go/mautrix v0.24.1-0.20250527083757-8a745c0d03ec/go.mod h1:HqA1HUutQYJkrYRPkK64itARDz79PCec1oWVEB72HVQ= +maunium.net/go/mautrix v0.24.1-0.20250531150347-788621f7e035 h1:jGg4WFHZhtnr7Lo6Y0RVPaxmHiPNLHhfcf8lrCz+pXY= +maunium.net/go/mautrix v0.24.1-0.20250531150347-788621f7e035/go.mod h1:HqA1HUutQYJkrYRPkK64itARDz79PCec1oWVEB72HVQ= From c33b32631e0fafec77a6660d9301bf1b561df88e Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Sat, 31 May 2025 18:47:45 +0300 Subject: [PATCH 346/580] handlesignal: don't panic in getters --- pkg/connector/handlesignal.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pkg/connector/handlesignal.go b/pkg/connector/handlesignal.go index 183cfa4..c2b0139 100644 --- a/pkg/connector/handlesignal.go +++ b/pkg/connector/handlesignal.go @@ -252,7 +252,7 @@ func (evt *Bv2ChatEvent) GetSender() bridgev2.EventSender { func (evt *Bv2ChatEvent) GetID() networkid.MessageID { ts := evt.getDataMsgTimestamp() if ts == 0 { - panic(fmt.Errorf("GetID() called for non-DataMessage event")) + return "" } return signalid.MakeMessageID(evt.Info.Sender, ts) } @@ -288,12 +288,12 @@ func (evt *Bv2ChatEvent) GetTargetMessage() networkid.MessageID { case innerEvt.Delete != nil: targetSentTS = innerEvt.Delete.GetTargetSentTimestamp() default: - panic(fmt.Errorf("GetTargetMessage() called for message type without target")) + return "" } case *signalpb.EditMessage: targetSentTS = innerEvt.GetTargetSentTimestamp() default: - panic(fmt.Errorf("GetTargetMessage() called for message type without target")) + return "" } targetAuthorUUID := evt.Info.Sender if targetAuthorACI != "" { From 286197927ca0dc9769a576327b868dfc9af96635 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Mon, 2 Jun 2025 18:11:30 +0300 Subject: [PATCH 347/580] directmedia: add nil checks for direct media --- pkg/connector/directmedia.go | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/pkg/connector/directmedia.go b/pkg/connector/directmedia.go index b24c033..8507626 100644 --- a/pkg/connector/directmedia.go +++ b/pkg/connector/directmedia.go @@ -64,6 +64,8 @@ func (s *SignalConnector) Download(ctx context.Context, mediaID networkid.MediaI userLogin, err := s.Bridge.GetExistingUserLoginByID(ctx, signalid.MakeUserLoginID(info.UserID)) if err != nil { return nil, fmt.Errorf("failed to get user login: %w", err) + } else if userLogin == nil { + return nil, bridgev2.ErrNotLoggedIn } client := userLogin.Client.(*SignalClient) @@ -95,6 +97,8 @@ func (s *SignalConnector) Download(ctx context.Context, mediaID networkid.MediaI userLogin, err := s.Bridge.GetExistingUserLoginByID(ctx, signalid.MakeUserLoginID(info.UserID)) if err != nil { return nil, fmt.Errorf("failed to get user login: %w", err) + } else if userLogin == nil { + return nil, bridgev2.ErrNotLoggedIn } client := userLogin.Client.(*SignalClient) @@ -102,6 +106,8 @@ func (s *SignalConnector) Download(ctx context.Context, mediaID networkid.MediaI profileKey, err := client.Client.Store.RecipientStore.LoadProfileKey(ctx, info.ContactID) if err != nil { return nil, fmt.Errorf("failed to get contact: %w", err) + } else if profileKey == nil { + return nil, fmt.Errorf("profile key not found") } return &mediaproxy.GetMediaResponseCallback{ From 18ecb3fff9ab76d4c17e58a2e8e85553779d54a4 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Mon, 2 Jun 2025 19:33:43 +0300 Subject: [PATCH 348/580] msgconv/from-matrix: guess mime type if not specified --- pkg/msgconv/from-matrix.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/pkg/msgconv/from-matrix.go b/pkg/msgconv/from-matrix.go index 367bb1f..36391f3 100644 --- a/pkg/msgconv/from-matrix.go +++ b/pkg/msgconv/from-matrix.go @@ -19,6 +19,7 @@ package msgconv import ( "context" "fmt" + "net/http" "strings" "github.com/rs/zerolog" @@ -154,6 +155,9 @@ func (mc *MessageConverter) convertFileToSignal(ctx context.Context, evt *event. fileName = content.FileName } mime := content.GetInfo().MimeType + if mime == "" { + mime = http.DetectContentType(data) + } if content.MSC3245Voice != nil && mime != "audio/aac" && ffmpeg.Supported() { data, err = ffmpeg.ConvertBytes(ctx, data, ".aac", []string{}, []string{"-c:a", "aac"}, mime) if err != nil { From f378624e8703c91750605df1887084170d93ecc9 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Tue, 3 Jun 2025 16:54:03 +0300 Subject: [PATCH 349/580] legacymigrate: drop invalid disappearing message rows --- cmd/mautrix-signal/legacymigrate.sql | 3 ++- cmd/mautrix-signal/main.go | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/cmd/mautrix-signal/legacymigrate.sql b/cmd/mautrix-signal/legacymigrate.sql index 1895bfd..cbf06e3 100644 --- a/cmd/mautrix-signal/legacymigrate.sql +++ b/cmd/mautrix-signal/legacymigrate.sql @@ -129,7 +129,8 @@ SELECT expiration_seconds * 1000000000, -- timer CASE WHEN expiration_ts IS NOT NULL THEN expiration_ts * 1000000000 END -- disappear_at FROM disappearing_message_old -WHERE expiration_ts < 9000000000; +WHERE expiration_ts < 9000000000 + AND room_id IN (SELECT mxid FROM portal WHERE mxid IS NOT NULL); INSERT INTO reaction ( bridge_id, message_id, message_part_id, sender_id, emoji_id, emoji, diff --git a/cmd/mautrix-signal/main.go b/cmd/mautrix-signal/main.go index b2eccfb..72b91c8 100644 --- a/cmd/mautrix-signal/main.go +++ b/cmd/mautrix-signal/main.go @@ -51,7 +51,7 @@ func main() { 20, "v0.5.1", "v0.7.0", - m.LegacyMigrateSimple(legacyMigrateRenameTables, legacyMigrateCopyData, 18), + m.LegacyMigrateSimple(legacyMigrateRenameTables, legacyMigrateCopyData, 21), true, ) } From 6bba293cd45cf0c8ec52e5ef0a9a8d15d44fad45 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Tue, 3 Jun 2025 20:25:55 +0300 Subject: [PATCH 350/580] libsignal: update to v0.73.2 --- pkg/libsignalgo/libsignal | 2 +- pkg/libsignalgo/libsignal-ffi.h | 68 +++++++++++++++++++++++++-------- pkg/libsignalgo/version.go | 2 +- 3 files changed, 54 insertions(+), 18 deletions(-) diff --git a/pkg/libsignalgo/libsignal b/pkg/libsignalgo/libsignal index 7d1cacb..f8bcdb0 160000 --- a/pkg/libsignalgo/libsignal +++ b/pkg/libsignalgo/libsignal @@ -1 +1 @@ -Subproject commit 7d1cacbaa8a885932b8838dfc3cddbf631dbddae +Subproject commit f8bcdb016abb9edb3b8d92851636208f3aa4c238 diff --git a/pkg/libsignalgo/libsignal-ffi.h b/pkg/libsignalgo/libsignal-ffi.h index c2c0068..6c17995 100644 --- a/pkg/libsignalgo/libsignal-ffi.h +++ b/pkg/libsignalgo/libsignal-ffi.h @@ -240,17 +240,19 @@ typedef enum { SignalErrorCodeConnectedElsewhere = 173, SignalErrorCodeBackupValidation = 180, SignalErrorCodeRegistrationInvalidSessionId = 190, - SignalErrorCodeRegistrationRequestNotValid, - SignalErrorCodeRegistrationUnknown, - SignalErrorCodeRegistrationSessionNotFound, - SignalErrorCodeRegistrationNotReadyForVerification, - SignalErrorCodeRegistrationSendVerificationCodeFailed, - SignalErrorCodeRegistrationCodeNotDeliverable, - SignalErrorCodeRegistrationSessionUpdateRejected, - SignalErrorCodeRegistrationCredentialsCouldNotBeParsed, - SignalErrorCodeRegistrationDeviceTransferPossible, - SignalErrorCodeRegistrationRecoveryVerificationFailed, - SignalErrorCodeRegistrationLock, + SignalErrorCodeRegistrationRequestNotValid = 191, + SignalErrorCodeRegistrationUnknown = 192, + SignalErrorCodeRegistrationSessionNotFound = 193, + SignalErrorCodeRegistrationNotReadyForVerification = 194, + SignalErrorCodeRegistrationSendVerificationCodeFailed = 195, + SignalErrorCodeRegistrationCodeNotDeliverable = 196, + SignalErrorCodeRegistrationSessionUpdateRejected = 197, + SignalErrorCodeRegistrationCredentialsCouldNotBeParsed = 198, + SignalErrorCodeRegistrationDeviceTransferPossible = 199, + SignalErrorCodeRegistrationRecoveryVerificationFailed = 200, + SignalErrorCodeRegistrationLock = 201, + SignalErrorCodeKeyTransparencyError = 210, + SignalErrorCodeKeyTransparencyVerificationFailed = 211, } SignalErrorCode; enum SignalSvr2CredentialsResult { @@ -952,6 +954,30 @@ typedef struct { SignalLogFlushCallback flush; } SignalFfiLogger; +/** + * A C callback used to report the results of Rust futures. + * + * cbindgen will produce independent C types like `SignalCPromisei32` and + * `SignalCPromiseProtocolAddress`. + * + * This derives Copy because it behaves like a C type; nevertheless, a promise should still only be + * completed once. + */ +typedef struct { + void (*complete)(SignalFfiError *error, const SignalOwnedBuffer *result, const void *context); + const void *context; + SignalCancellationId cancellation_id; +} SignalCPromiseOwnedBufferOfc_uchar; + +typedef struct { + const SignalUnauthenticatedChatConnection *raw; +} SignalConstPointerUnauthenticatedChatConnection; + +typedef struct { + bool present; + SignalBorrowedBuffer value; +} SignalOptionalBorrowedSliceOfc_uchar; + typedef SignalKeyPair SignalKyberKeyPair; typedef struct { @@ -1293,10 +1319,6 @@ typedef struct { SignalCancellationId cancellation_id; } SignalCPromiseMutPointerUnauthenticatedChatConnection; -typedef struct { - const SignalUnauthenticatedChatConnection *raw; -} SignalConstPointerUnauthenticatedChatConnection; - typedef struct { SignalValidatingMac *raw; } SignalMutPointerValidatingMac; @@ -1733,6 +1755,18 @@ SignalFfiError *signal_incremental_mac_update(SignalOwnedBuffer *out, SignalMutP bool signal_init_logger(SignalLogLevel max_level, SignalFfiLogger logger); +SignalFfiError *signal_key_transparency_aci_search_key(SignalOwnedBuffer *out, const SignalServiceIdFixedWidthBinaryBytes *aci); + +SignalFfiError *signal_key_transparency_distinguished(SignalCPromiseOwnedBufferOfc_uchar *promise, SignalConstPointerTokioAsyncContext async_runtime, uint8_t environment, SignalConstPointerUnauthenticatedChatConnection chat_connection, SignalOptionalBorrowedSliceOfc_uchar last_distinguished_tree_head); + +SignalFfiError *signal_key_transparency_e164_search_key(SignalOwnedBuffer *out, const char *e164); + +SignalFfiError *signal_key_transparency_monitor(SignalCPromiseOwnedBufferOfc_uchar *promise, SignalConstPointerTokioAsyncContext async_runtime, uint8_t environment, SignalConstPointerUnauthenticatedChatConnection chat_connection, const SignalServiceIdFixedWidthBinaryBytes *aci, SignalConstPointerPublicKey aci_identity_key, const char *e164, SignalOptionalBorrowedSliceOfc_uchar unidentified_access_key, SignalOptionalBorrowedSliceOfc_uchar username_hash, SignalOptionalBorrowedSliceOfc_uchar account_data, SignalBorrowedBuffer last_distinguished_tree_head); + +SignalFfiError *signal_key_transparency_search(SignalCPromiseOwnedBufferOfc_uchar *promise, SignalConstPointerTokioAsyncContext async_runtime, uint8_t environment, SignalConstPointerUnauthenticatedChatConnection chat_connection, const SignalServiceIdFixedWidthBinaryBytes *aci, SignalConstPointerPublicKey aci_identity_key, const char *e164, SignalOptionalBorrowedSliceOfc_uchar unidentified_access_key, SignalOptionalBorrowedSliceOfc_uchar username_hash, SignalOptionalBorrowedSliceOfc_uchar account_data, SignalBorrowedBuffer last_distinguished_tree_head); + +SignalFfiError *signal_key_transparency_username_hash_search_key(SignalOwnedBuffer *out, SignalBorrowedBuffer hash); + SignalFfiError *signal_kyber_key_pair_clone(SignalMutPointerKyberKeyPair *new_obj, SignalConstPointerKyberKeyPair obj); SignalFfiError *signal_kyber_key_pair_destroy(SignalMutPointerKyberKeyPair p); @@ -1881,7 +1915,7 @@ SignalFfiError *signal_pre_key_bundle_get_device_id(uint32_t *out, SignalConstPo SignalFfiError *signal_pre_key_bundle_get_identity_key(SignalMutPointerPublicKey *out, SignalConstPointerPreKeyBundle p); -SignalFfiError *signal_pre_key_bundle_get_kyber_pre_key_id(uint32_t *out, SignalConstPointerPreKeyBundle obj); +SignalFfiError *signal_pre_key_bundle_get_kyber_pre_key_id(uint32_t *out, SignalConstPointerPreKeyBundle bundle); SignalFfiError *signal_pre_key_bundle_get_kyber_pre_key_public(SignalMutPointerKyberPublicKey *out, SignalConstPointerPreKeyBundle bundle); @@ -2079,6 +2113,8 @@ SignalFfiError *signal_registration_service_request_push_challenge(SignalCPromis SignalFfiError *signal_registration_service_request_verification_code(SignalCPromisebool *promise, SignalConstPointerTokioAsyncContext async_runtime, SignalConstPointerRegistrationService service, const char *transport, const char *client, SignalBorrowedBytestringArray languages); +SignalFfiError *signal_registration_service_reregister_account(SignalCPromiseMutPointerRegisterAccountResponse *promise, SignalConstPointerTokioAsyncContext async_runtime, SignalConstPointerFfiConnectChatBridgeStruct connect_chat, const char *number, SignalConstPointerRegisterAccountRequest register_account, SignalConstPointerRegistrationAccountAttributes account_attributes); + SignalFfiError *signal_registration_service_resume_session(SignalCPromiseMutPointerRegistrationService *promise, SignalConstPointerTokioAsyncContext async_runtime, const char *session_id, const char *number, SignalConstPointerFfiConnectChatBridgeStruct connect_chat); SignalFfiError *signal_registration_service_session_id(const char **out, SignalConstPointerRegistrationService service); diff --git a/pkg/libsignalgo/version.go b/pkg/libsignalgo/version.go index 5a7e360..0ea03a5 100644 --- a/pkg/libsignalgo/version.go +++ b/pkg/libsignalgo/version.go @@ -2,4 +2,4 @@ package libsignalgo -const Version = "v0.72.1" +const Version = "v0.73.2" From 086e97edac46d78b73428728815f56c1c7c98440 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Tue, 3 Jun 2025 20:26:10 +0300 Subject: [PATCH 351/580] signalmeow: update protobufs --- pkg/signalmeow/protobuf/backuppb/Backup.pb.go | 402 ++++++++++++------ pkg/signalmeow/protobuf/backuppb/Backup.proto | 20 + pkg/signalmeow/protobuf/update-protos.sh | 4 +- 3 files changed, 298 insertions(+), 128 deletions(-) diff --git a/pkg/signalmeow/protobuf/backuppb/Backup.pb.go b/pkg/signalmeow/protobuf/backuppb/Backup.pb.go index cce9b50..dc65ac7 100644 --- a/pkg/signalmeow/protobuf/backuppb/Backup.pb.go +++ b/pkg/signalmeow/protobuf/backuppb/Backup.pb.go @@ -4595,6 +4595,7 @@ type FilePointer struct { // *FilePointer_BackupLocator_ // *FilePointer_AttachmentLocator_ // *FilePointer_InvalidAttachmentLocator_ + // *FilePointer_LocalLocator_ Locator isFilePointer_Locator `protobuf_oneof:"locator"` ContentType *string `protobuf:"bytes,4,opt,name=contentType,proto3,oneof" json:"contentType,omitempty"` IncrementalMac []byte `protobuf:"bytes,5,opt,name=incrementalMac,proto3,oneof" json:"incrementalMac,omitempty"` @@ -4672,6 +4673,15 @@ func (x *FilePointer) GetInvalidAttachmentLocator() *FilePointer_InvalidAttachme return nil } +func (x *FilePointer) GetLocalLocator() *FilePointer_LocalLocator { + if x != nil { + if x, ok := x.Locator.(*FilePointer_LocalLocator_); ok { + return x.LocalLocator + } + } + return nil +} + func (x *FilePointer) GetContentType() string { if x != nil && x.ContentType != nil { return *x.ContentType @@ -4744,12 +4754,18 @@ type FilePointer_InvalidAttachmentLocator_ struct { InvalidAttachmentLocator *FilePointer_InvalidAttachmentLocator `protobuf:"bytes,3,opt,name=invalidAttachmentLocator,proto3,oneof"` } +type FilePointer_LocalLocator_ struct { + LocalLocator *FilePointer_LocalLocator `protobuf:"bytes,12,opt,name=localLocator,proto3,oneof"` +} + func (*FilePointer_BackupLocator_) isFilePointer_Locator() {} func (*FilePointer_AttachmentLocator_) isFilePointer_Locator() {} func (*FilePointer_InvalidAttachmentLocator_) isFilePointer_Locator() {} +func (*FilePointer_LocalLocator_) isFilePointer_Locator() {} + type Quote struct { state protoimpl.MessageState `protogen:"open.v1"` TargetSentTimestamp *uint64 `protobuf:"varint,1,opt,name=targetSentTimestamp,proto3,oneof" json:"targetSentTimestamp,omitempty"` // null if the target message could not be found at time of quote insert @@ -7643,6 +7659,7 @@ type NotificationProfile struct { ScheduleStartTime uint32 `protobuf:"varint,9,opt,name=scheduleStartTime,proto3" json:"scheduleStartTime,omitempty"` // 24-hour clock int, 0000-2359 (e.g., 15, 900, 1130, 2345) ScheduleEndTime uint32 `protobuf:"varint,10,opt,name=scheduleEndTime,proto3" json:"scheduleEndTime,omitempty"` // 24-hour clock int, 0000-2359 (e.g., 15, 900, 1130, 2345) ScheduleDaysEnabled []NotificationProfile_DayOfWeek `protobuf:"varint,11,rep,packed,name=scheduleDaysEnabled,proto3,enum=signal.backup.NotificationProfile_DayOfWeek" json:"scheduleDaysEnabled,omitempty"` + Id []byte `protobuf:"bytes,12,opt,name=id,proto3" json:"id,omitempty"` // should be 16 bytes unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } @@ -7754,6 +7771,13 @@ func (x *NotificationProfile) GetScheduleDaysEnabled() []NotificationProfile_Day return nil } +func (x *NotificationProfile) GetId() []byte { + if x != nil { + return x.Id + } + return nil +} + type ChatFolder struct { state protoimpl.MessageState `protogen:"open.v1"` Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` @@ -10245,6 +10269,113 @@ func (*FilePointer_InvalidAttachmentLocator) Descriptor() ([]byte, []int) { return file_backuppb_Backup_proto_rawDescGZIP(), []int{28, 2} } +// References attachments in a local encrypted backup. +// Importers should first attempt to read the file from the local backup, +// and on failure fallback to backup and transit cdn if possible. +type FilePointer_LocalLocator struct { + state protoimpl.MessageState `protogen:"open.v1"` + MediaName string `protobuf:"bytes,1,opt,name=mediaName,proto3" json:"mediaName,omitempty"` + // Separate key used to encrypt this file for the local backup. + // Generally required. Missing field indicates attachment was not + // available locally when the backup was generated, but remote + // backup or transit info was available. + LocalKey []byte `protobuf:"bytes,2,opt,name=localKey,proto3,oneof" json:"localKey,omitempty"` + RemoteKey []byte `protobuf:"bytes,3,opt,name=remoteKey,proto3" json:"remoteKey,omitempty"` + RemoteDigest []byte `protobuf:"bytes,4,opt,name=remoteDigest,proto3" json:"remoteDigest,omitempty"` + Size uint32 `protobuf:"varint,5,opt,name=size,proto3" json:"size,omitempty"` + BackupCdnNumber *uint32 `protobuf:"varint,6,opt,name=backupCdnNumber,proto3,oneof" json:"backupCdnNumber,omitempty"` + TransitCdnKey *string `protobuf:"bytes,7,opt,name=transitCdnKey,proto3,oneof" json:"transitCdnKey,omitempty"` + TransitCdnNumber *uint32 `protobuf:"varint,8,opt,name=transitCdnNumber,proto3,oneof" json:"transitCdnNumber,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *FilePointer_LocalLocator) Reset() { + *x = FilePointer_LocalLocator{} + mi := &file_backuppb_Backup_proto_msgTypes[116] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *FilePointer_LocalLocator) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*FilePointer_LocalLocator) ProtoMessage() {} + +func (x *FilePointer_LocalLocator) ProtoReflect() protoreflect.Message { + mi := &file_backuppb_Backup_proto_msgTypes[116] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use FilePointer_LocalLocator.ProtoReflect.Descriptor instead. +func (*FilePointer_LocalLocator) Descriptor() ([]byte, []int) { + return file_backuppb_Backup_proto_rawDescGZIP(), []int{28, 3} +} + +func (x *FilePointer_LocalLocator) GetMediaName() string { + if x != nil { + return x.MediaName + } + return "" +} + +func (x *FilePointer_LocalLocator) GetLocalKey() []byte { + if x != nil { + return x.LocalKey + } + return nil +} + +func (x *FilePointer_LocalLocator) GetRemoteKey() []byte { + if x != nil { + return x.RemoteKey + } + return nil +} + +func (x *FilePointer_LocalLocator) GetRemoteDigest() []byte { + if x != nil { + return x.RemoteDigest + } + return nil +} + +func (x *FilePointer_LocalLocator) GetSize() uint32 { + if x != nil { + return x.Size + } + return 0 +} + +func (x *FilePointer_LocalLocator) GetBackupCdnNumber() uint32 { + if x != nil && x.BackupCdnNumber != nil { + return *x.BackupCdnNumber + } + return 0 +} + +func (x *FilePointer_LocalLocator) GetTransitCdnKey() string { + if x != nil && x.TransitCdnKey != nil { + return *x.TransitCdnKey + } + return "" +} + +func (x *FilePointer_LocalLocator) GetTransitCdnNumber() uint32 { + if x != nil && x.TransitCdnNumber != nil { + return *x.TransitCdnNumber + } + return 0 +} + type Quote_QuotedAttachment struct { state protoimpl.MessageState `protogen:"open.v1"` ContentType *string `protobuf:"bytes,1,opt,name=contentType,proto3,oneof" json:"contentType,omitempty"` @@ -10256,7 +10387,7 @@ type Quote_QuotedAttachment struct { func (x *Quote_QuotedAttachment) Reset() { *x = Quote_QuotedAttachment{} - mi := &file_backuppb_Backup_proto_msgTypes[116] + mi := &file_backuppb_Backup_proto_msgTypes[117] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -10268,7 +10399,7 @@ func (x *Quote_QuotedAttachment) String() string { func (*Quote_QuotedAttachment) ProtoMessage() {} func (x *Quote_QuotedAttachment) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[116] + mi := &file_backuppb_Backup_proto_msgTypes[117] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -10352,7 +10483,7 @@ type GroupChangeChatUpdate_Update struct { func (x *GroupChangeChatUpdate_Update) Reset() { *x = GroupChangeChatUpdate_Update{} - mi := &file_backuppb_Backup_proto_msgTypes[117] + mi := &file_backuppb_Backup_proto_msgTypes[118] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -10364,7 +10495,7 @@ func (x *GroupChangeChatUpdate_Update) String() string { func (*GroupChangeChatUpdate_Update) ProtoMessage() {} func (x *GroupChangeChatUpdate_Update) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[117] + mi := &file_backuppb_Backup_proto_msgTypes[118] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -10938,7 +11069,7 @@ type GroupInvitationRevokedUpdate_Invitee struct { func (x *GroupInvitationRevokedUpdate_Invitee) Reset() { *x = GroupInvitationRevokedUpdate_Invitee{} - mi := &file_backuppb_Backup_proto_msgTypes[118] + mi := &file_backuppb_Backup_proto_msgTypes[119] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -10950,7 +11081,7 @@ func (x *GroupInvitationRevokedUpdate_Invitee) String() string { func (*GroupInvitationRevokedUpdate_Invitee) ProtoMessage() {} func (x *GroupInvitationRevokedUpdate_Invitee) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[118] + mi := &file_backuppb_Backup_proto_msgTypes[119] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -10998,7 +11129,7 @@ type ChatStyle_Gradient struct { func (x *ChatStyle_Gradient) Reset() { *x = ChatStyle_Gradient{} - mi := &file_backuppb_Backup_proto_msgTypes[119] + mi := &file_backuppb_Backup_proto_msgTypes[120] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -11010,7 +11141,7 @@ func (x *ChatStyle_Gradient) String() string { func (*ChatStyle_Gradient) ProtoMessage() {} func (x *ChatStyle_Gradient) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[119] + mi := &file_backuppb_Backup_proto_msgTypes[120] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -11063,7 +11194,7 @@ type ChatStyle_CustomChatColor struct { func (x *ChatStyle_CustomChatColor) Reset() { *x = ChatStyle_CustomChatColor{} - mi := &file_backuppb_Backup_proto_msgTypes[120] + mi := &file_backuppb_Backup_proto_msgTypes[121] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -11075,7 +11206,7 @@ func (x *ChatStyle_CustomChatColor) String() string { func (*ChatStyle_CustomChatColor) ProtoMessage() {} func (x *ChatStyle_CustomChatColor) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[120] + mi := &file_backuppb_Backup_proto_msgTypes[121] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -11147,7 +11278,7 @@ type ChatStyle_AutomaticBubbleColor struct { func (x *ChatStyle_AutomaticBubbleColor) Reset() { *x = ChatStyle_AutomaticBubbleColor{} - mi := &file_backuppb_Backup_proto_msgTypes[121] + mi := &file_backuppb_Backup_proto_msgTypes[122] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -11159,7 +11290,7 @@ func (x *ChatStyle_AutomaticBubbleColor) String() string { func (*ChatStyle_AutomaticBubbleColor) ProtoMessage() {} func (x *ChatStyle_AutomaticBubbleColor) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[121] + mi := &file_backuppb_Backup_proto_msgTypes[122] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -11698,11 +11829,12 @@ const file_backuppb_Backup_proto_rawDesc = "" + "\n" + "BORDERLESS\x10\x02\x12\a\n" + "\x03GIF\x10\x03B\r\n" + - "\v_clientUuid\"\xec\t\n" + + "\v_clientUuid\"\xb4\r\n" + "\vFilePointer\x12P\n" + "\rbackupLocator\x18\x01 \x01(\v2(.signal.backup.FilePointer.BackupLocatorH\x00R\rbackupLocator\x12\\\n" + "\x11attachmentLocator\x18\x02 \x01(\v2,.signal.backup.FilePointer.AttachmentLocatorH\x00R\x11attachmentLocator\x12q\n" + - "\x18invalidAttachmentLocator\x18\x03 \x01(\v23.signal.backup.FilePointer.InvalidAttachmentLocatorH\x00R\x18invalidAttachmentLocator\x12%\n" + + "\x18invalidAttachmentLocator\x18\x03 \x01(\v23.signal.backup.FilePointer.InvalidAttachmentLocatorH\x00R\x18invalidAttachmentLocator\x12M\n" + + "\flocalLocator\x18\f \x01(\v2'.signal.backup.FilePointer.LocalLocatorH\x00R\flocalLocator\x12%\n" + "\vcontentType\x18\x04 \x01(\tH\x01R\vcontentType\x88\x01\x01\x12+\n" + "\x0eincrementalMac\x18\x05 \x01(\fH\x02R\x0eincrementalMac\x88\x01\x01\x12=\n" + "\x17incrementalMacChunkSize\x18\x06 \x01(\rH\x03R\x17incrementalMacChunkSize\x88\x01\x01\x12\x1f\n" + @@ -11732,7 +11864,20 @@ const file_backuppb_Backup_proto_rawDesc = "" + "\x06digest\x18\x05 \x01(\fR\x06digest\x12\x12\n" + "\x04size\x18\x06 \x01(\rR\x04sizeB\x12\n" + "\x10_uploadTimestamp\x1a\x1a\n" + - "\x18InvalidAttachmentLocatorB\t\n" + + "\x18InvalidAttachmentLocator\x1a\xf6\x02\n" + + "\fLocalLocator\x12\x1c\n" + + "\tmediaName\x18\x01 \x01(\tR\tmediaName\x12\x1f\n" + + "\blocalKey\x18\x02 \x01(\fH\x00R\blocalKey\x88\x01\x01\x12\x1c\n" + + "\tremoteKey\x18\x03 \x01(\fR\tremoteKey\x12\"\n" + + "\fremoteDigest\x18\x04 \x01(\fR\fremoteDigest\x12\x12\n" + + "\x04size\x18\x05 \x01(\rR\x04size\x12-\n" + + "\x0fbackupCdnNumber\x18\x06 \x01(\rH\x01R\x0fbackupCdnNumber\x88\x01\x01\x12)\n" + + "\rtransitCdnKey\x18\a \x01(\tH\x02R\rtransitCdnKey\x88\x01\x01\x12/\n" + + "\x10transitCdnNumber\x18\b \x01(\rH\x03R\x10transitCdnNumber\x88\x01\x01B\v\n" + + "\t_localKeyB\x12\n" + + "\x10_backupCdnNumberB\x10\n" + + "\x0e_transitCdnKeyB\x13\n" + + "\x11_transitCdnNumberB\t\n" + "\alocatorB\x0e\n" + "\f_contentTypeB\x11\n" + "\x0f_incrementalMacB\x1a\n" + @@ -12178,7 +12323,7 @@ const file_backuppb_Backup_proto_rawDesc = "" + "\fGRADIENT_SEA\x10\x15\x12\x16\n" + "\x12GRADIENT_TANGERINE\x10\x16B\v\n" + "\twallpaperB\r\n" + - "\vbubbleColor\"\xd8\x04\n" + + "\vbubbleColor\"\xe8\x04\n" + "\x13NotificationProfile\x12\x12\n" + "\x04name\x18\x01 \x01(\tR\x04name\x12\x19\n" + "\x05emoji\x18\x02 \x01(\tH\x00R\x05emoji\x88\x01\x01\x12\x14\n" + @@ -12191,7 +12336,8 @@ const file_backuppb_Backup_proto_rawDesc = "" + "\x11scheduleStartTime\x18\t \x01(\rR\x11scheduleStartTime\x12(\n" + "\x0fscheduleEndTime\x18\n" + " \x01(\rR\x0fscheduleEndTime\x12^\n" + - "\x13scheduleDaysEnabled\x18\v \x03(\x0e2,.signal.backup.NotificationProfile.DayOfWeekR\x13scheduleDaysEnabled\"t\n" + + "\x13scheduleDaysEnabled\x18\v \x03(\x0e2,.signal.backup.NotificationProfile.DayOfWeekR\x13scheduleDaysEnabled\x12\x0e\n" + + "\x02id\x18\f \x01(\fR\x02id\"t\n" + "\tDayOfWeek\x12\v\n" + "\aUNKNOWN\x10\x00\x12\n" + "\n" + @@ -12260,7 +12406,7 @@ func file_backuppb_Backup_proto_rawDescGZIP() []byte { } var file_backuppb_Backup_proto_enumTypes = make([]protoimpl.EnumInfo, 31) -var file_backuppb_Backup_proto_msgTypes = make([]protoimpl.MessageInfo, 122) +var file_backuppb_Backup_proto_msgTypes = make([]protoimpl.MessageInfo, 123) var file_backuppb_Backup_proto_goTypes = []any{ (AvatarColor)(0), // 0: signal.backup.AvatarColor (GroupV2AccessLevel)(0), // 1: signal.backup.GroupV2AccessLevel @@ -12409,12 +12555,13 @@ var file_backuppb_Backup_proto_goTypes = []any{ (*FilePointer_BackupLocator)(nil), // 144: signal.backup.FilePointer.BackupLocator (*FilePointer_AttachmentLocator)(nil), // 145: signal.backup.FilePointer.AttachmentLocator (*FilePointer_InvalidAttachmentLocator)(nil), // 146: signal.backup.FilePointer.InvalidAttachmentLocator - (*Quote_QuotedAttachment)(nil), // 147: signal.backup.Quote.QuotedAttachment - (*GroupChangeChatUpdate_Update)(nil), // 148: signal.backup.GroupChangeChatUpdate.Update - (*GroupInvitationRevokedUpdate_Invitee)(nil), // 149: signal.backup.GroupInvitationRevokedUpdate.Invitee - (*ChatStyle_Gradient)(nil), // 150: signal.backup.ChatStyle.Gradient - (*ChatStyle_CustomChatColor)(nil), // 151: signal.backup.ChatStyle.CustomChatColor - (*ChatStyle_AutomaticBubbleColor)(nil), // 152: signal.backup.ChatStyle.AutomaticBubbleColor + (*FilePointer_LocalLocator)(nil), // 147: signal.backup.FilePointer.LocalLocator + (*Quote_QuotedAttachment)(nil), // 148: signal.backup.Quote.QuotedAttachment + (*GroupChangeChatUpdate_Update)(nil), // 149: signal.backup.GroupChangeChatUpdate.Update + (*GroupInvitationRevokedUpdate_Invitee)(nil), // 150: signal.backup.GroupInvitationRevokedUpdate.Invitee + (*ChatStyle_Gradient)(nil), // 151: signal.backup.ChatStyle.Gradient + (*ChatStyle_CustomChatColor)(nil), // 152: signal.backup.ChatStyle.CustomChatColor + (*ChatStyle_AutomaticBubbleColor)(nil), // 153: signal.backup.ChatStyle.AutomaticBubbleColor } var file_backuppb_Backup_proto_depIdxs = []int32{ 33, // 0: signal.backup.Frame.account:type_name -> signal.backup.AccountData @@ -12499,104 +12646,105 @@ var file_backuppb_Backup_proto_depIdxs = []int32{ 144, // 79: signal.backup.FilePointer.backupLocator:type_name -> signal.backup.FilePointer.BackupLocator 145, // 80: signal.backup.FilePointer.attachmentLocator:type_name -> signal.backup.FilePointer.AttachmentLocator 146, // 81: signal.backup.FilePointer.invalidAttachmentLocator:type_name -> signal.backup.FilePointer.InvalidAttachmentLocator - 46, // 82: signal.backup.Quote.text:type_name -> signal.backup.Text - 147, // 83: signal.backup.Quote.attachments:type_name -> signal.backup.Quote.QuotedAttachment - 20, // 84: signal.backup.Quote.type:type_name -> signal.backup.Quote.Type - 21, // 85: signal.backup.BodyRange.style:type_name -> signal.backup.BodyRange.Style - 66, // 86: signal.backup.ChatUpdateMessage.simpleUpdate:type_name -> signal.backup.SimpleChatUpdate - 72, // 87: signal.backup.ChatUpdateMessage.groupChange:type_name -> signal.backup.GroupChangeChatUpdate - 67, // 88: signal.backup.ChatUpdateMessage.expirationTimerChange:type_name -> signal.backup.ExpirationTimerChatUpdate - 68, // 89: signal.backup.ChatUpdateMessage.profileChange:type_name -> signal.backup.ProfileChangeChatUpdate - 70, // 90: signal.backup.ChatUpdateMessage.threadMerge:type_name -> signal.backup.ThreadMergeChatUpdate - 71, // 91: signal.backup.ChatUpdateMessage.sessionSwitchover:type_name -> signal.backup.SessionSwitchoverChatUpdate - 64, // 92: signal.backup.ChatUpdateMessage.individualCall:type_name -> signal.backup.IndividualCall - 65, // 93: signal.backup.ChatUpdateMessage.groupCall:type_name -> signal.backup.GroupCall - 69, // 94: signal.backup.ChatUpdateMessage.learnedProfileChange:type_name -> signal.backup.LearnedProfileChatUpdate - 22, // 95: signal.backup.IndividualCall.type:type_name -> signal.backup.IndividualCall.Type - 23, // 96: signal.backup.IndividualCall.direction:type_name -> signal.backup.IndividualCall.Direction - 24, // 97: signal.backup.IndividualCall.state:type_name -> signal.backup.IndividualCall.State - 25, // 98: signal.backup.GroupCall.state:type_name -> signal.backup.GroupCall.State - 26, // 99: signal.backup.SimpleChatUpdate.type:type_name -> signal.backup.SimpleChatUpdate.Type - 148, // 100: signal.backup.GroupChangeChatUpdate.updates:type_name -> signal.backup.GroupChangeChatUpdate.Update - 1, // 101: signal.backup.GroupMembershipAccessLevelChangeUpdate.accessLevel:type_name -> signal.backup.GroupV2AccessLevel - 1, // 102: signal.backup.GroupAttributesAccessLevelChangeUpdate.accessLevel:type_name -> signal.backup.GroupV2AccessLevel - 149, // 103: signal.backup.GroupInvitationRevokedUpdate.invitees:type_name -> signal.backup.GroupInvitationRevokedUpdate.Invitee - 27, // 104: signal.backup.ChatStyle.wallpaperPreset:type_name -> signal.backup.ChatStyle.WallpaperPreset - 59, // 105: signal.backup.ChatStyle.wallpaperPhoto:type_name -> signal.backup.FilePointer - 152, // 106: signal.backup.ChatStyle.autoBubbleColor:type_name -> signal.backup.ChatStyle.AutomaticBubbleColor - 28, // 107: signal.backup.ChatStyle.bubbleColorPreset:type_name -> signal.backup.ChatStyle.BubbleColorPreset - 29, // 108: signal.backup.NotificationProfile.scheduleDaysEnabled:type_name -> signal.backup.NotificationProfile.DayOfWeek - 30, // 109: signal.backup.ChatFolder.folderType:type_name -> signal.backup.ChatFolder.FolderType - 3, // 110: signal.backup.AccountData.UsernameLink.color:type_name -> signal.backup.AccountData.UsernameLink.Color - 2, // 111: signal.backup.AccountData.AccountSettings.phoneNumberSharingMode:type_name -> signal.backup.AccountData.PhoneNumberSharingMode - 108, // 112: signal.backup.AccountData.AccountSettings.defaultChatStyle:type_name -> signal.backup.ChatStyle - 151, // 113: signal.backup.AccountData.AccountSettings.customChatColors:type_name -> signal.backup.ChatStyle.CustomChatColor - 119, // 114: signal.backup.Group.GroupSnapshot.title:type_name -> signal.backup.Group.GroupAttributeBlob - 119, // 115: signal.backup.Group.GroupSnapshot.description:type_name -> signal.backup.Group.GroupAttributeBlob - 119, // 116: signal.backup.Group.GroupSnapshot.disappearingMessagesTimer:type_name -> signal.backup.Group.GroupAttributeBlob - 124, // 117: signal.backup.Group.GroupSnapshot.accessControl:type_name -> signal.backup.Group.AccessControl - 120, // 118: signal.backup.Group.GroupSnapshot.members:type_name -> signal.backup.Group.Member - 121, // 119: signal.backup.Group.GroupSnapshot.membersPendingProfileKey:type_name -> signal.backup.Group.MemberPendingProfileKey - 122, // 120: signal.backup.Group.GroupSnapshot.membersPendingAdminApproval:type_name -> signal.backup.Group.MemberPendingAdminApproval - 123, // 121: signal.backup.Group.GroupSnapshot.members_banned:type_name -> signal.backup.Group.MemberBanned - 7, // 122: signal.backup.Group.Member.role:type_name -> signal.backup.Group.Member.Role - 120, // 123: signal.backup.Group.MemberPendingProfileKey.member:type_name -> signal.backup.Group.Member - 8, // 124: signal.backup.Group.AccessControl.attributes:type_name -> signal.backup.Group.AccessControl.AccessRequired - 8, // 125: signal.backup.Group.AccessControl.members:type_name -> signal.backup.Group.AccessControl.AccessRequired - 8, // 126: signal.backup.Group.AccessControl.addFromInviteLink:type_name -> signal.backup.Group.AccessControl.AccessRequired - 45, // 127: signal.backup.ChatItem.OutgoingMessageDetails.sendStatus:type_name -> signal.backup.SendStatus - 12, // 128: signal.backup.SendStatus.Failed.reason:type_name -> signal.backup.SendStatus.Failed.FailureReason - 46, // 129: signal.backup.DirectStoryReplyMessage.TextReply.text:type_name -> signal.backup.Text - 59, // 130: signal.backup.DirectStoryReplyMessage.TextReply.longText:type_name -> signal.backup.FilePointer - 139, // 131: signal.backup.PaymentNotification.TransactionDetails.transaction:type_name -> signal.backup.PaymentNotification.TransactionDetails.Transaction - 138, // 132: signal.backup.PaymentNotification.TransactionDetails.failedTransaction:type_name -> signal.backup.PaymentNotification.TransactionDetails.FailedTransaction - 13, // 133: signal.backup.PaymentNotification.TransactionDetails.FailedTransaction.reason:type_name -> signal.backup.PaymentNotification.TransactionDetails.FailedTransaction.FailureReason - 14, // 134: signal.backup.PaymentNotification.TransactionDetails.Transaction.status:type_name -> signal.backup.PaymentNotification.TransactionDetails.Transaction.Status - 137, // 135: signal.backup.PaymentNotification.TransactionDetails.Transaction.mobileCoinIdentification:type_name -> signal.backup.PaymentNotification.TransactionDetails.MobileCoinTxoIdentification - 16, // 136: signal.backup.ContactAttachment.Phone.type:type_name -> signal.backup.ContactAttachment.Phone.Type - 17, // 137: signal.backup.ContactAttachment.Email.type:type_name -> signal.backup.ContactAttachment.Email.Type - 18, // 138: signal.backup.ContactAttachment.PostalAddress.type:type_name -> signal.backup.ContactAttachment.PostalAddress.Type - 58, // 139: signal.backup.Quote.QuotedAttachment.thumbnail:type_name -> signal.backup.MessageAttachment - 73, // 140: signal.backup.GroupChangeChatUpdate.Update.genericGroupUpdate:type_name -> signal.backup.GenericGroupUpdate - 74, // 141: signal.backup.GroupChangeChatUpdate.Update.groupCreationUpdate:type_name -> signal.backup.GroupCreationUpdate - 75, // 142: signal.backup.GroupChangeChatUpdate.Update.groupNameUpdate:type_name -> signal.backup.GroupNameUpdate - 76, // 143: signal.backup.GroupChangeChatUpdate.Update.groupAvatarUpdate:type_name -> signal.backup.GroupAvatarUpdate - 77, // 144: signal.backup.GroupChangeChatUpdate.Update.groupDescriptionUpdate:type_name -> signal.backup.GroupDescriptionUpdate - 78, // 145: signal.backup.GroupChangeChatUpdate.Update.groupMembershipAccessLevelChangeUpdate:type_name -> signal.backup.GroupMembershipAccessLevelChangeUpdate - 79, // 146: signal.backup.GroupChangeChatUpdate.Update.groupAttributesAccessLevelChangeUpdate:type_name -> signal.backup.GroupAttributesAccessLevelChangeUpdate - 80, // 147: signal.backup.GroupChangeChatUpdate.Update.groupAnnouncementOnlyChangeUpdate:type_name -> signal.backup.GroupAnnouncementOnlyChangeUpdate - 81, // 148: signal.backup.GroupChangeChatUpdate.Update.groupAdminStatusUpdate:type_name -> signal.backup.GroupAdminStatusUpdate - 82, // 149: signal.backup.GroupChangeChatUpdate.Update.groupMemberLeftUpdate:type_name -> signal.backup.GroupMemberLeftUpdate - 83, // 150: signal.backup.GroupChangeChatUpdate.Update.groupMemberRemovedUpdate:type_name -> signal.backup.GroupMemberRemovedUpdate - 84, // 151: signal.backup.GroupChangeChatUpdate.Update.selfInvitedToGroupUpdate:type_name -> signal.backup.SelfInvitedToGroupUpdate - 85, // 152: signal.backup.GroupChangeChatUpdate.Update.selfInvitedOtherUserToGroupUpdate:type_name -> signal.backup.SelfInvitedOtherUserToGroupUpdate - 86, // 153: signal.backup.GroupChangeChatUpdate.Update.groupUnknownInviteeUpdate:type_name -> signal.backup.GroupUnknownInviteeUpdate - 87, // 154: signal.backup.GroupChangeChatUpdate.Update.groupInvitationAcceptedUpdate:type_name -> signal.backup.GroupInvitationAcceptedUpdate - 88, // 155: signal.backup.GroupChangeChatUpdate.Update.groupInvitationDeclinedUpdate:type_name -> signal.backup.GroupInvitationDeclinedUpdate - 89, // 156: signal.backup.GroupChangeChatUpdate.Update.groupMemberJoinedUpdate:type_name -> signal.backup.GroupMemberJoinedUpdate - 90, // 157: signal.backup.GroupChangeChatUpdate.Update.groupMemberAddedUpdate:type_name -> signal.backup.GroupMemberAddedUpdate - 91, // 158: signal.backup.GroupChangeChatUpdate.Update.groupSelfInvitationRevokedUpdate:type_name -> signal.backup.GroupSelfInvitationRevokedUpdate - 92, // 159: signal.backup.GroupChangeChatUpdate.Update.groupInvitationRevokedUpdate:type_name -> signal.backup.GroupInvitationRevokedUpdate - 93, // 160: signal.backup.GroupChangeChatUpdate.Update.groupJoinRequestUpdate:type_name -> signal.backup.GroupJoinRequestUpdate - 94, // 161: signal.backup.GroupChangeChatUpdate.Update.groupJoinRequestApprovalUpdate:type_name -> signal.backup.GroupJoinRequestApprovalUpdate - 95, // 162: signal.backup.GroupChangeChatUpdate.Update.groupJoinRequestCanceledUpdate:type_name -> signal.backup.GroupJoinRequestCanceledUpdate - 97, // 163: signal.backup.GroupChangeChatUpdate.Update.groupInviteLinkResetUpdate:type_name -> signal.backup.GroupInviteLinkResetUpdate - 98, // 164: signal.backup.GroupChangeChatUpdate.Update.groupInviteLinkEnabledUpdate:type_name -> signal.backup.GroupInviteLinkEnabledUpdate - 99, // 165: signal.backup.GroupChangeChatUpdate.Update.groupInviteLinkAdminApprovalUpdate:type_name -> signal.backup.GroupInviteLinkAdminApprovalUpdate - 100, // 166: signal.backup.GroupChangeChatUpdate.Update.groupInviteLinkDisabledUpdate:type_name -> signal.backup.GroupInviteLinkDisabledUpdate - 101, // 167: signal.backup.GroupChangeChatUpdate.Update.groupMemberJoinedByLinkUpdate:type_name -> signal.backup.GroupMemberJoinedByLinkUpdate - 102, // 168: signal.backup.GroupChangeChatUpdate.Update.groupV2MigrationUpdate:type_name -> signal.backup.GroupV2MigrationUpdate - 103, // 169: signal.backup.GroupChangeChatUpdate.Update.groupV2MigrationSelfInvitedUpdate:type_name -> signal.backup.GroupV2MigrationSelfInvitedUpdate - 104, // 170: signal.backup.GroupChangeChatUpdate.Update.groupV2MigrationInvitedMembersUpdate:type_name -> signal.backup.GroupV2MigrationInvitedMembersUpdate - 105, // 171: signal.backup.GroupChangeChatUpdate.Update.groupV2MigrationDroppedMembersUpdate:type_name -> signal.backup.GroupV2MigrationDroppedMembersUpdate - 96, // 172: signal.backup.GroupChangeChatUpdate.Update.groupSequenceOfRequestsAndCancelsUpdate:type_name -> signal.backup.GroupSequenceOfRequestsAndCancelsUpdate - 106, // 173: signal.backup.GroupChangeChatUpdate.Update.groupExpirationTimerUpdate:type_name -> signal.backup.GroupExpirationTimerUpdate - 150, // 174: signal.backup.ChatStyle.CustomChatColor.gradient:type_name -> signal.backup.ChatStyle.Gradient - 175, // [175:175] is the sub-list for method output_type - 175, // [175:175] is the sub-list for method input_type - 175, // [175:175] is the sub-list for extension type_name - 175, // [175:175] is the sub-list for extension extendee - 0, // [0:175] is the sub-list for field type_name + 147, // 82: signal.backup.FilePointer.localLocator:type_name -> signal.backup.FilePointer.LocalLocator + 46, // 83: signal.backup.Quote.text:type_name -> signal.backup.Text + 148, // 84: signal.backup.Quote.attachments:type_name -> signal.backup.Quote.QuotedAttachment + 20, // 85: signal.backup.Quote.type:type_name -> signal.backup.Quote.Type + 21, // 86: signal.backup.BodyRange.style:type_name -> signal.backup.BodyRange.Style + 66, // 87: signal.backup.ChatUpdateMessage.simpleUpdate:type_name -> signal.backup.SimpleChatUpdate + 72, // 88: signal.backup.ChatUpdateMessage.groupChange:type_name -> signal.backup.GroupChangeChatUpdate + 67, // 89: signal.backup.ChatUpdateMessage.expirationTimerChange:type_name -> signal.backup.ExpirationTimerChatUpdate + 68, // 90: signal.backup.ChatUpdateMessage.profileChange:type_name -> signal.backup.ProfileChangeChatUpdate + 70, // 91: signal.backup.ChatUpdateMessage.threadMerge:type_name -> signal.backup.ThreadMergeChatUpdate + 71, // 92: signal.backup.ChatUpdateMessage.sessionSwitchover:type_name -> signal.backup.SessionSwitchoverChatUpdate + 64, // 93: signal.backup.ChatUpdateMessage.individualCall:type_name -> signal.backup.IndividualCall + 65, // 94: signal.backup.ChatUpdateMessage.groupCall:type_name -> signal.backup.GroupCall + 69, // 95: signal.backup.ChatUpdateMessage.learnedProfileChange:type_name -> signal.backup.LearnedProfileChatUpdate + 22, // 96: signal.backup.IndividualCall.type:type_name -> signal.backup.IndividualCall.Type + 23, // 97: signal.backup.IndividualCall.direction:type_name -> signal.backup.IndividualCall.Direction + 24, // 98: signal.backup.IndividualCall.state:type_name -> signal.backup.IndividualCall.State + 25, // 99: signal.backup.GroupCall.state:type_name -> signal.backup.GroupCall.State + 26, // 100: signal.backup.SimpleChatUpdate.type:type_name -> signal.backup.SimpleChatUpdate.Type + 149, // 101: signal.backup.GroupChangeChatUpdate.updates:type_name -> signal.backup.GroupChangeChatUpdate.Update + 1, // 102: signal.backup.GroupMembershipAccessLevelChangeUpdate.accessLevel:type_name -> signal.backup.GroupV2AccessLevel + 1, // 103: signal.backup.GroupAttributesAccessLevelChangeUpdate.accessLevel:type_name -> signal.backup.GroupV2AccessLevel + 150, // 104: signal.backup.GroupInvitationRevokedUpdate.invitees:type_name -> signal.backup.GroupInvitationRevokedUpdate.Invitee + 27, // 105: signal.backup.ChatStyle.wallpaperPreset:type_name -> signal.backup.ChatStyle.WallpaperPreset + 59, // 106: signal.backup.ChatStyle.wallpaperPhoto:type_name -> signal.backup.FilePointer + 153, // 107: signal.backup.ChatStyle.autoBubbleColor:type_name -> signal.backup.ChatStyle.AutomaticBubbleColor + 28, // 108: signal.backup.ChatStyle.bubbleColorPreset:type_name -> signal.backup.ChatStyle.BubbleColorPreset + 29, // 109: signal.backup.NotificationProfile.scheduleDaysEnabled:type_name -> signal.backup.NotificationProfile.DayOfWeek + 30, // 110: signal.backup.ChatFolder.folderType:type_name -> signal.backup.ChatFolder.FolderType + 3, // 111: signal.backup.AccountData.UsernameLink.color:type_name -> signal.backup.AccountData.UsernameLink.Color + 2, // 112: signal.backup.AccountData.AccountSettings.phoneNumberSharingMode:type_name -> signal.backup.AccountData.PhoneNumberSharingMode + 108, // 113: signal.backup.AccountData.AccountSettings.defaultChatStyle:type_name -> signal.backup.ChatStyle + 152, // 114: signal.backup.AccountData.AccountSettings.customChatColors:type_name -> signal.backup.ChatStyle.CustomChatColor + 119, // 115: signal.backup.Group.GroupSnapshot.title:type_name -> signal.backup.Group.GroupAttributeBlob + 119, // 116: signal.backup.Group.GroupSnapshot.description:type_name -> signal.backup.Group.GroupAttributeBlob + 119, // 117: signal.backup.Group.GroupSnapshot.disappearingMessagesTimer:type_name -> signal.backup.Group.GroupAttributeBlob + 124, // 118: signal.backup.Group.GroupSnapshot.accessControl:type_name -> signal.backup.Group.AccessControl + 120, // 119: signal.backup.Group.GroupSnapshot.members:type_name -> signal.backup.Group.Member + 121, // 120: signal.backup.Group.GroupSnapshot.membersPendingProfileKey:type_name -> signal.backup.Group.MemberPendingProfileKey + 122, // 121: signal.backup.Group.GroupSnapshot.membersPendingAdminApproval:type_name -> signal.backup.Group.MemberPendingAdminApproval + 123, // 122: signal.backup.Group.GroupSnapshot.members_banned:type_name -> signal.backup.Group.MemberBanned + 7, // 123: signal.backup.Group.Member.role:type_name -> signal.backup.Group.Member.Role + 120, // 124: signal.backup.Group.MemberPendingProfileKey.member:type_name -> signal.backup.Group.Member + 8, // 125: signal.backup.Group.AccessControl.attributes:type_name -> signal.backup.Group.AccessControl.AccessRequired + 8, // 126: signal.backup.Group.AccessControl.members:type_name -> signal.backup.Group.AccessControl.AccessRequired + 8, // 127: signal.backup.Group.AccessControl.addFromInviteLink:type_name -> signal.backup.Group.AccessControl.AccessRequired + 45, // 128: signal.backup.ChatItem.OutgoingMessageDetails.sendStatus:type_name -> signal.backup.SendStatus + 12, // 129: signal.backup.SendStatus.Failed.reason:type_name -> signal.backup.SendStatus.Failed.FailureReason + 46, // 130: signal.backup.DirectStoryReplyMessage.TextReply.text:type_name -> signal.backup.Text + 59, // 131: signal.backup.DirectStoryReplyMessage.TextReply.longText:type_name -> signal.backup.FilePointer + 139, // 132: signal.backup.PaymentNotification.TransactionDetails.transaction:type_name -> signal.backup.PaymentNotification.TransactionDetails.Transaction + 138, // 133: signal.backup.PaymentNotification.TransactionDetails.failedTransaction:type_name -> signal.backup.PaymentNotification.TransactionDetails.FailedTransaction + 13, // 134: signal.backup.PaymentNotification.TransactionDetails.FailedTransaction.reason:type_name -> signal.backup.PaymentNotification.TransactionDetails.FailedTransaction.FailureReason + 14, // 135: signal.backup.PaymentNotification.TransactionDetails.Transaction.status:type_name -> signal.backup.PaymentNotification.TransactionDetails.Transaction.Status + 137, // 136: signal.backup.PaymentNotification.TransactionDetails.Transaction.mobileCoinIdentification:type_name -> signal.backup.PaymentNotification.TransactionDetails.MobileCoinTxoIdentification + 16, // 137: signal.backup.ContactAttachment.Phone.type:type_name -> signal.backup.ContactAttachment.Phone.Type + 17, // 138: signal.backup.ContactAttachment.Email.type:type_name -> signal.backup.ContactAttachment.Email.Type + 18, // 139: signal.backup.ContactAttachment.PostalAddress.type:type_name -> signal.backup.ContactAttachment.PostalAddress.Type + 58, // 140: signal.backup.Quote.QuotedAttachment.thumbnail:type_name -> signal.backup.MessageAttachment + 73, // 141: signal.backup.GroupChangeChatUpdate.Update.genericGroupUpdate:type_name -> signal.backup.GenericGroupUpdate + 74, // 142: signal.backup.GroupChangeChatUpdate.Update.groupCreationUpdate:type_name -> signal.backup.GroupCreationUpdate + 75, // 143: signal.backup.GroupChangeChatUpdate.Update.groupNameUpdate:type_name -> signal.backup.GroupNameUpdate + 76, // 144: signal.backup.GroupChangeChatUpdate.Update.groupAvatarUpdate:type_name -> signal.backup.GroupAvatarUpdate + 77, // 145: signal.backup.GroupChangeChatUpdate.Update.groupDescriptionUpdate:type_name -> signal.backup.GroupDescriptionUpdate + 78, // 146: signal.backup.GroupChangeChatUpdate.Update.groupMembershipAccessLevelChangeUpdate:type_name -> signal.backup.GroupMembershipAccessLevelChangeUpdate + 79, // 147: signal.backup.GroupChangeChatUpdate.Update.groupAttributesAccessLevelChangeUpdate:type_name -> signal.backup.GroupAttributesAccessLevelChangeUpdate + 80, // 148: signal.backup.GroupChangeChatUpdate.Update.groupAnnouncementOnlyChangeUpdate:type_name -> signal.backup.GroupAnnouncementOnlyChangeUpdate + 81, // 149: signal.backup.GroupChangeChatUpdate.Update.groupAdminStatusUpdate:type_name -> signal.backup.GroupAdminStatusUpdate + 82, // 150: signal.backup.GroupChangeChatUpdate.Update.groupMemberLeftUpdate:type_name -> signal.backup.GroupMemberLeftUpdate + 83, // 151: signal.backup.GroupChangeChatUpdate.Update.groupMemberRemovedUpdate:type_name -> signal.backup.GroupMemberRemovedUpdate + 84, // 152: signal.backup.GroupChangeChatUpdate.Update.selfInvitedToGroupUpdate:type_name -> signal.backup.SelfInvitedToGroupUpdate + 85, // 153: signal.backup.GroupChangeChatUpdate.Update.selfInvitedOtherUserToGroupUpdate:type_name -> signal.backup.SelfInvitedOtherUserToGroupUpdate + 86, // 154: signal.backup.GroupChangeChatUpdate.Update.groupUnknownInviteeUpdate:type_name -> signal.backup.GroupUnknownInviteeUpdate + 87, // 155: signal.backup.GroupChangeChatUpdate.Update.groupInvitationAcceptedUpdate:type_name -> signal.backup.GroupInvitationAcceptedUpdate + 88, // 156: signal.backup.GroupChangeChatUpdate.Update.groupInvitationDeclinedUpdate:type_name -> signal.backup.GroupInvitationDeclinedUpdate + 89, // 157: signal.backup.GroupChangeChatUpdate.Update.groupMemberJoinedUpdate:type_name -> signal.backup.GroupMemberJoinedUpdate + 90, // 158: signal.backup.GroupChangeChatUpdate.Update.groupMemberAddedUpdate:type_name -> signal.backup.GroupMemberAddedUpdate + 91, // 159: signal.backup.GroupChangeChatUpdate.Update.groupSelfInvitationRevokedUpdate:type_name -> signal.backup.GroupSelfInvitationRevokedUpdate + 92, // 160: signal.backup.GroupChangeChatUpdate.Update.groupInvitationRevokedUpdate:type_name -> signal.backup.GroupInvitationRevokedUpdate + 93, // 161: signal.backup.GroupChangeChatUpdate.Update.groupJoinRequestUpdate:type_name -> signal.backup.GroupJoinRequestUpdate + 94, // 162: signal.backup.GroupChangeChatUpdate.Update.groupJoinRequestApprovalUpdate:type_name -> signal.backup.GroupJoinRequestApprovalUpdate + 95, // 163: signal.backup.GroupChangeChatUpdate.Update.groupJoinRequestCanceledUpdate:type_name -> signal.backup.GroupJoinRequestCanceledUpdate + 97, // 164: signal.backup.GroupChangeChatUpdate.Update.groupInviteLinkResetUpdate:type_name -> signal.backup.GroupInviteLinkResetUpdate + 98, // 165: signal.backup.GroupChangeChatUpdate.Update.groupInviteLinkEnabledUpdate:type_name -> signal.backup.GroupInviteLinkEnabledUpdate + 99, // 166: signal.backup.GroupChangeChatUpdate.Update.groupInviteLinkAdminApprovalUpdate:type_name -> signal.backup.GroupInviteLinkAdminApprovalUpdate + 100, // 167: signal.backup.GroupChangeChatUpdate.Update.groupInviteLinkDisabledUpdate:type_name -> signal.backup.GroupInviteLinkDisabledUpdate + 101, // 168: signal.backup.GroupChangeChatUpdate.Update.groupMemberJoinedByLinkUpdate:type_name -> signal.backup.GroupMemberJoinedByLinkUpdate + 102, // 169: signal.backup.GroupChangeChatUpdate.Update.groupV2MigrationUpdate:type_name -> signal.backup.GroupV2MigrationUpdate + 103, // 170: signal.backup.GroupChangeChatUpdate.Update.groupV2MigrationSelfInvitedUpdate:type_name -> signal.backup.GroupV2MigrationSelfInvitedUpdate + 104, // 171: signal.backup.GroupChangeChatUpdate.Update.groupV2MigrationInvitedMembersUpdate:type_name -> signal.backup.GroupV2MigrationInvitedMembersUpdate + 105, // 172: signal.backup.GroupChangeChatUpdate.Update.groupV2MigrationDroppedMembersUpdate:type_name -> signal.backup.GroupV2MigrationDroppedMembersUpdate + 96, // 173: signal.backup.GroupChangeChatUpdate.Update.groupSequenceOfRequestsAndCancelsUpdate:type_name -> signal.backup.GroupSequenceOfRequestsAndCancelsUpdate + 106, // 174: signal.backup.GroupChangeChatUpdate.Update.groupExpirationTimerUpdate:type_name -> signal.backup.GroupExpirationTimerUpdate + 151, // 175: signal.backup.ChatStyle.CustomChatColor.gradient:type_name -> signal.backup.ChatStyle.Gradient + 176, // [176:176] is the sub-list for method output_type + 176, // [176:176] is the sub-list for method input_type + 176, // [176:176] is the sub-list for extension type_name + 176, // [176:176] is the sub-list for extension extendee + 0, // [0:176] is the sub-list for field type_name } func init() { file_backuppb_Backup_proto_init() } @@ -12672,6 +12820,7 @@ func file_backuppb_Backup_proto_init() { (*FilePointer_BackupLocator_)(nil), (*FilePointer_AttachmentLocator_)(nil), (*FilePointer_InvalidAttachmentLocator_)(nil), + (*FilePointer_LocalLocator_)(nil), } file_backuppb_Backup_proto_msgTypes[29].OneofWrappers = []any{} file_backuppb_Backup_proto_msgTypes[30].OneofWrappers = []any{ @@ -12746,7 +12895,8 @@ func file_backuppb_Backup_proto_init() { file_backuppb_Backup_proto_msgTypes[113].OneofWrappers = []any{} file_backuppb_Backup_proto_msgTypes[114].OneofWrappers = []any{} file_backuppb_Backup_proto_msgTypes[116].OneofWrappers = []any{} - file_backuppb_Backup_proto_msgTypes[117].OneofWrappers = []any{ + file_backuppb_Backup_proto_msgTypes[117].OneofWrappers = []any{} + file_backuppb_Backup_proto_msgTypes[118].OneofWrappers = []any{ (*GroupChangeChatUpdate_Update_GenericGroupUpdate)(nil), (*GroupChangeChatUpdate_Update_GroupCreationUpdate)(nil), (*GroupChangeChatUpdate_Update_GroupNameUpdate)(nil), @@ -12782,8 +12932,8 @@ func file_backuppb_Backup_proto_init() { (*GroupChangeChatUpdate_Update_GroupSequenceOfRequestsAndCancelsUpdate)(nil), (*GroupChangeChatUpdate_Update_GroupExpirationTimerUpdate)(nil), } - file_backuppb_Backup_proto_msgTypes[118].OneofWrappers = []any{} - file_backuppb_Backup_proto_msgTypes[120].OneofWrappers = []any{ + file_backuppb_Backup_proto_msgTypes[119].OneofWrappers = []any{} + file_backuppb_Backup_proto_msgTypes[121].OneofWrappers = []any{ (*ChatStyle_CustomChatColor_Solid)(nil), (*ChatStyle_CustomChatColor_Gradient)(nil), } @@ -12793,7 +12943,7 @@ func file_backuppb_Backup_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: unsafe.Slice(unsafe.StringData(file_backuppb_Backup_proto_rawDesc), len(file_backuppb_Backup_proto_rawDesc)), NumEnums: 31, - NumMessages: 122, + NumMessages: 123, NumExtensions: 0, NumServices: 0, }, diff --git a/pkg/signalmeow/protobuf/backuppb/Backup.proto b/pkg/signalmeow/protobuf/backuppb/Backup.proto index 9fe2079..3840f93 100644 --- a/pkg/signalmeow/protobuf/backuppb/Backup.proto +++ b/pkg/signalmeow/protobuf/backuppb/Backup.proto @@ -724,11 +724,30 @@ message FilePointer { message InvalidAttachmentLocator { } + // References attachments in a local encrypted backup. + // Importers should first attempt to read the file from the local backup, + // and on failure fallback to backup and transit cdn if possible. + message LocalLocator { + string mediaName = 1; + // Separate key used to encrypt this file for the local backup. + // Generally required. Missing field indicates attachment was not + // available locally when the backup was generated, but remote + // backup or transit info was available. + optional bytes localKey = 2; + bytes remoteKey = 3; + bytes remoteDigest = 4; + uint32 size = 5; + optional uint32 backupCdnNumber = 6; + optional string transitCdnKey = 7; + optional uint32 transitCdnNumber = 8; + } + // If unset, importers should consider it to be an InvalidAttachmentLocator without throwing an error. oneof locator { BackupLocator backupLocator = 1; AttachmentLocator attachmentLocator = 2; InvalidAttachmentLocator invalidAttachmentLocator = 3; + LocalLocator localLocator = 12; } optional string contentType = 4; @@ -1291,6 +1310,7 @@ message NotificationProfile { uint32 scheduleStartTime = 9; // 24-hour clock int, 0000-2359 (e.g., 15, 900, 1130, 2345) uint32 scheduleEndTime = 10; // 24-hour clock int, 0000-2359 (e.g., 15, 900, 1130, 2345) repeated DayOfWeek scheduleDaysEnabled = 11; + bytes id = 12; // should be 16 bytes } message ChatFolder { diff --git a/pkg/signalmeow/protobuf/update-protos.sh b/pkg/signalmeow/protobuf/update-protos.sh index 1dd2e40..c95420d 100755 --- a/pkg/signalmeow/protobuf/update-protos.sh +++ b/pkg/signalmeow/protobuf/update-protos.sh @@ -1,8 +1,8 @@ #!/bin/bash set -euo pipefail -ANDROID_GIT_REVISION=${1:-68058264729cb237bd8523df404d9455cb3f622f} -DESKTOP_GIT_REVISION=${1:-c861161f22e553ecb81982bc2c7b7d495ee42fcc} +ANDROID_GIT_REVISION=${1:-23669c3c372284d42db486a218d9f29bef247abf} +DESKTOP_GIT_REVISION=${1:-010c38ae9bce84c676a9c464a04f7c26e7a2c9e0} update_proto() { case "$1" in From f029bbbef03333bf6a96ada1afe00c7c80186ef0 Mon Sep 17 00:00:00 2001 From: Nick Mills-Barrett Date: Tue, 3 Jun 2025 15:23:44 +0100 Subject: [PATCH 352/580] signalmeow: expose way to fetch profile with custom refresh interval --- pkg/connector/chatinfo.go | 10 ++++++++-- pkg/signalmeow/contact.go | 13 +++++++++---- pkg/signalmeow/profile.go | 10 ++++++---- 3 files changed, 23 insertions(+), 10 deletions(-) diff --git a/pkg/connector/chatinfo.go b/pkg/connector/chatinfo.go index 6fff853..1937318 100644 --- a/pkg/connector/chatinfo.go +++ b/pkg/connector/chatinfo.go @@ -22,6 +22,7 @@ import ( "fmt" "strconv" "strings" + "time" "github.com/google/uuid" "github.com/rs/zerolog" @@ -34,6 +35,7 @@ import ( "go.mau.fi/mautrix-signal/pkg/libsignalgo" "go.mau.fi/mautrix-signal/pkg/signalid" + "go.mau.fi/mautrix-signal/pkg/signalmeow" "go.mau.fi/mautrix-signal/pkg/signalmeow/store" "go.mau.fi/mautrix-signal/pkg/signalmeow/types" ) @@ -41,7 +43,7 @@ import ( const PrivateChatTopic = "Signal private chat" const NoteToSelfName = "Signal Note to Self" -func (s *SignalClient) GetUserInfo(ctx context.Context, ghost *bridgev2.Ghost) (*bridgev2.UserInfo, error) { +func (s *SignalClient) GetUserInfoWithRefreshAfter(ctx context.Context, ghost *bridgev2.Ghost, refreshAfter time.Duration) (*bridgev2.UserInfo, error) { userID, err := signalid.ParseUserID(ghost.ID) if err != nil { return nil, err @@ -50,7 +52,7 @@ func (s *SignalClient) GetUserInfo(ctx context.Context, ghost *bridgev2.Ghost) ( // Don't do unnecessary fetches in background mode return nil, nil } - contact, err := s.Client.ContactByACI(ctx, userID) + contact, err := s.Client.ContactByACIWithRefreshAfter(ctx, userID, refreshAfter) if err != nil { return nil, err } @@ -61,6 +63,10 @@ func (s *SignalClient) GetUserInfo(ctx context.Context, ghost *bridgev2.Ghost) ( return s.contactToUserInfo(ctx, contact) } +func (s *SignalClient) GetUserInfo(ctx context.Context, ghost *bridgev2.Ghost) (*bridgev2.UserInfo, error) { + return s.GetUserInfoWithRefreshAfter(ctx, ghost, signalmeow.DefaultProfileRefreshAfter) +} + func (s *SignalClient) GetChatInfo(ctx context.Context, portal *bridgev2.Portal) (*bridgev2.ChatInfo, error) { userID, groupID, err := signalid.ParsePortalID(portal.ID) if err != nil { diff --git a/pkg/signalmeow/contact.go b/pkg/signalmeow/contact.go index 9e7eec2..8407b74 100644 --- a/pkg/signalmeow/contact.go +++ b/pkg/signalmeow/contact.go @@ -25,6 +25,7 @@ import ( "fmt" "net/http" "strings" + "time" "github.com/google/uuid" "github.com/rs/zerolog" @@ -71,14 +72,14 @@ func (cli *Client) StoreContactDetailsAsContact(ctx context.Context, contactDeta }) } -func (cli *Client) fetchContactThenTryAndUpdateWithProfile(ctx context.Context, aci uuid.UUID) (*types.Recipient, error) { +func (cli *Client) fetchContactThenTryAndUpdateWithProfile(ctx context.Context, aci uuid.UUID, refreshAfter time.Duration) (*types.Recipient, error) { log := zerolog.Ctx(ctx).With(). Str("action", "fetch contact then try and update with profile"). Stringer("profile_aci", aci). Logger() ctx = log.WithContext(ctx) - profile, err := cli.RetrieveProfileByID(ctx, aci) + profile, err := cli.RetrieveProfileByID(ctx, aci, refreshAfter) if err != nil { log.Debug().Err(err).Msg("Failed to fetch profile") // Continue to return contact without profile @@ -96,7 +97,11 @@ func (cli *Client) fetchContactThenTryAndUpdateWithProfile(ctx context.Context, } func (cli *Client) ContactByACI(ctx context.Context, aci uuid.UUID) (*types.Recipient, error) { - return cli.fetchContactThenTryAndUpdateWithProfile(ctx, aci) + return cli.fetchContactThenTryAndUpdateWithProfile(ctx, aci, DefaultProfileRefreshAfter) +} + +func (cli *Client) ContactByACIWithRefreshAfter(ctx context.Context, aci uuid.UUID, refreshAfter time.Duration) (*types.Recipient, error) { + return cli.fetchContactThenTryAndUpdateWithProfile(ctx, aci, refreshAfter) } func (cli *Client) ContactByE164(ctx context.Context, e164 string) (*types.Recipient, error) { @@ -109,7 +114,7 @@ func (cli *Client) ContactByE164(ctx context.Context, e164 string) (*types.Recip return nil, nil } if contact.ACI != uuid.Nil { - contact, err = cli.fetchContactThenTryAndUpdateWithProfile(ctx, contact.ACI) + contact, err = cli.fetchContactThenTryAndUpdateWithProfile(ctx, contact.ACI, DefaultProfileRefreshAfter) } return contact, err } diff --git a/pkg/signalmeow/profile.go b/pkg/signalmeow/profile.go index bbd31f3..3aa88ff 100644 --- a/pkg/signalmeow/profile.go +++ b/pkg/signalmeow/profile.go @@ -41,6 +41,8 @@ import ( "go.mau.fi/mautrix-signal/pkg/signalmeow/web" ) +const DefaultProfileRefreshAfter = 1 * time.Hour + type Capabilities struct { SenderKey bool `json:"senderKey"` AnnouncementGroup bool `json:"announcementGroup"` @@ -114,11 +116,11 @@ func (cli *Client) ProfileKeyForSignalID(ctx context.Context, signalACI uuid.UUI var errProfileKeyNotFound = errors.New("profile key not found") -func (cli *Client) getCachedProfileByID(signalID uuid.UUID) (*types.Profile, error) { +func (cli *Client) getCachedProfileByID(signalID uuid.UUID, refreshAfter time.Duration) (*types.Profile, error) { cli.ProfileCache.lock.RLock() defer cli.ProfileCache.lock.RUnlock() lastFetched, ok := cli.ProfileCache.lastFetched[signalID.String()] - if ok && time.Since(lastFetched) < 1*time.Hour { + if ok && time.Since(lastFetched) < refreshAfter { profile, ok := cli.ProfileCache.profiles[signalID.String()] if ok { return profile, nil @@ -131,7 +133,7 @@ func (cli *Client) getCachedProfileByID(signalID uuid.UUID) (*types.Profile, err return nil, nil } -func (cli *Client) RetrieveProfileByID(ctx context.Context, signalID uuid.UUID) (*types.Profile, error) { +func (cli *Client) RetrieveProfileByID(ctx context.Context, signalID uuid.UUID, refreshAfter time.Duration) (*types.Profile, error) { if cli.ProfileCache == nil { cli.ProfileCache = &ProfileCache{ profiles: make(map[string]*types.Profile), @@ -142,7 +144,7 @@ func (cli *Client) RetrieveProfileByID(ctx context.Context, signalID uuid.UUID) // Check if we have a cached profile that is less than an hour old // or if we have a cached error that is less than an hour old - profile, err := cli.getCachedProfileByID(signalID) + profile, err := cli.getCachedProfileByID(signalID, refreshAfter) if err != nil || profile != nil { return profile, err } From cca55180cf4bed1ce9819bb137e1a5d8aa79bbe5 Mon Sep 17 00:00:00 2001 From: Nick Mills-Barrett Date: Tue, 3 Jun 2025 15:23:52 +0100 Subject: [PATCH 353/580] client: immediately sync DM ghosts when viewed --- pkg/connector/client.go | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/pkg/connector/client.go b/pkg/connector/client.go index 7a4d003..5a0b740 100644 --- a/pkg/connector/client.go +++ b/pkg/connector/client.go @@ -56,6 +56,7 @@ var ( _ bridgev2.RoomAvatarHandlingNetworkAPI = (*SignalClient)(nil) _ bridgev2.RoomTopicHandlingNetworkAPI = (*SignalClient)(nil) _ bridgev2.BackgroundSyncingNetworkAPI = (*SignalClient)(nil) + _ bridgev2.ChatViewingNetworkAPI = (*SignalClient)(nil) ) var pushCfg = &bridgev2.PushConfig{ @@ -338,3 +339,36 @@ func (s *SignalClient) IsLoggedIn() bool { } return s.Client.IsLoggedIn() } + +func (s *SignalClient) HandleMatrixViewingChat(ctx context.Context, msg *bridgev2.MatrixViewingChat) error { + if msg.Portal == nil || msg.Portal.OtherUserID == "" { + // Group chat changes are sent by Signal so no need to fetch them on view + return nil + } + + // Sync other user ghost info in DM rooms + ghost, err := s.Main.Bridge.GetExistingGhostByID(ctx, msg.Portal.OtherUserID) + if err != nil { + return fmt.Errorf("failed to get ghost for sync: %w", err) + } else if ghost == nil { + zerolog.Ctx(ctx).Warn(). + Str("other_user_id", string(msg.Portal.OtherUserID)). + Msg("No ghost found for other user in portal") + return nil + } + + meta := ghost.Metadata.(*signalid.GhostMetadata) + if meta.ProfileFetchedAt.Time.Add(5 * time.Minute).After(time.Now()) { + // Limit profile fetches to max one per 5 minutes + return nil + } + + // Reset, but don't save, portal last sync time for immediate sync now + meta.ProfileFetchedAt.Time = time.Time{} + info, err := s.GetUserInfoWithRefreshAfter(ctx, ghost, 5*time.Minute) + if err != nil { + return fmt.Errorf("failed to get user info: %w", err) + } + ghost.UpdateInfo(ctx, info) + return nil +} From 23ae2e2f7b7e1b1a7893ba7d02ead014a138ae8a Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Fri, 6 Jun 2025 14:08:48 +0300 Subject: [PATCH 354/580] login: fix invalid return in Start if provision state is error --- go.mod | 2 +- go.sum | 4 ++-- pkg/connector/login.go | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/go.mod b/go.mod index abd27a4..54ce972 100644 --- a/go.mod +++ b/go.mod @@ -18,7 +18,7 @@ require ( golang.org/x/exp v0.0.0-20250506013437-ce4c2cf36ca6 golang.org/x/net v0.40.0 google.golang.org/protobuf v1.36.6 - maunium.net/go/mautrix v0.24.1-0.20250531150347-788621f7e035 + maunium.net/go/mautrix v0.24.1-0.20250606110819-d296f7b6604b ) require ( diff --git a/go.sum b/go.sum index 6257f3b..5f5fe5f 100644 --- a/go.sum +++ b/go.sum @@ -99,5 +99,5 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= maunium.net/go/mauflag v1.0.0 h1:YiaRc0tEI3toYtJMRIfjP+jklH45uDHtT80nUamyD4M= maunium.net/go/mauflag v1.0.0/go.mod h1:nLivPOpTpHnpzEh8jEdSL9UqO9+/KBJFmNRlwKfkPeA= -maunium.net/go/mautrix v0.24.1-0.20250531150347-788621f7e035 h1:jGg4WFHZhtnr7Lo6Y0RVPaxmHiPNLHhfcf8lrCz+pXY= -maunium.net/go/mautrix v0.24.1-0.20250531150347-788621f7e035/go.mod h1:HqA1HUutQYJkrYRPkK64itARDz79PCec1oWVEB72HVQ= +maunium.net/go/mautrix v0.24.1-0.20250606110819-d296f7b6604b h1:coJOie9e6rdLBP8Ky9PjauvARytLvbue2pvdzEJssPM= +maunium.net/go/mautrix v0.24.1-0.20250606110819-d296f7b6604b/go.mod h1:HqA1HUutQYJkrYRPkK64itARDz79PCec1oWVEB72HVQ= diff --git a/pkg/connector/login.go b/pkg/connector/login.go index 15a48c3..1805be8 100644 --- a/pkg/connector/login.go +++ b/pkg/connector/login.go @@ -86,7 +86,7 @@ func (qr *QRLogin) Start(ctx context.Context) (*bridgev2.LoginStep, error) { var resp signalmeow.ProvisioningResponse select { case resp = <-qr.ProvChan: - if resp.Err != nil || resp.State == signalmeow.StateProvisioningError { + if resp.Err != nil { return nil, resp.Err } else if resp.State != signalmeow.StateProvisioningURLReceived { return nil, fmt.Errorf("unexpected state %v", resp.State) From b8d7cd4f494642b607224763efcb923045f7ac4f Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Mon, 9 Jun 2025 21:13:54 +0300 Subject: [PATCH 355/580] signalmeow/receiving: adjust decryption logs --- pkg/signalmeow/receiving.go | 20 ++++++++++++-------- pkg/signalmeow/receiving_decrypt.go | 2 +- pkg/signalmeow/web/signalwebsocket.go | 2 +- 3 files changed, 14 insertions(+), 10 deletions(-) diff --git a/pkg/signalmeow/receiving.go b/pkg/signalmeow/receiving.go index b24d167..aea9b08 100644 --- a/pkg/signalmeow/receiving.go +++ b/pkg/signalmeow/receiving.go @@ -330,17 +330,20 @@ func (cli *Client) incomingRequestHandler(ctx context.Context, req *signalpb.Web } func (cli *Client) incomingAPIMessageHandler(ctx context.Context, req *signalpb.WebSocketRequestMessage) (*web.SimpleResponse, error) { - log := zerolog.Ctx(ctx) + log := *zerolog.Ctx(ctx) envelope := &signalpb.Envelope{} err := proto.Unmarshal(req.Body, envelope) if err != nil { log.Err(err).Msg("Unmarshal error") return nil, err } - destinationServiceID, err := libsignalgo.ServiceIDFromString(envelope.GetDestinationServiceId()) - log.Trace(). - Uint64("timestamp", envelope.GetTimestamp()). + log = log.With(). + Uint64("envelope_timestamp", envelope.GetTimestamp()). Uint64("server_timestamp", envelope.GetServerTimestamp()). + Logger() + ctx = log.WithContext(ctx) + destinationServiceID, err := libsignalgo.ServiceIDFromString(envelope.GetDestinationServiceId()) + log.Debug(). Str("destination_service_id", envelope.GetDestinationServiceId()). Str("source_service_id", envelope.GetSourceServiceId()). Uint32("source_device_id", envelope.GetSourceDevice()). @@ -456,10 +459,11 @@ func (cli *Client) handleDecryptedResult( Logger() log = &newLog ctx = log.WithContext(ctx) - log.Debug(). - Uint64("server_ts", envelope.GetServerTimestamp()). - Uint64("client_ts", envelope.GetTimestamp()). - Msg("Decrypted message") + logEvt := log.Debug() + if result.CiphertextHash != nil { + logEvt = logEvt.Hex("ciphertext_hash", result.CiphertextHash[:]) + } + logEvt.Msg("Decrypted message") // If there's a sender key distribution message, process it if content.GetSenderKeyDistributionMessage() != nil { diff --git a/pkg/signalmeow/receiving_decrypt.go b/pkg/signalmeow/receiving_decrypt.go index 7d85c43..1ffceb0 100644 --- a/pkg/signalmeow/receiving_decrypt.go +++ b/pkg/signalmeow/receiving_decrypt.go @@ -137,7 +137,7 @@ func (cli *Client) bufferedDecryptTxn(ctx context.Context, ciphertext []byte, se if innerErr != nil { innerErr = fmt.Errorf("failed to save decrypted event to buffer: %w", innerErr) } - zerolog.Ctx(ctx).Debug(). + zerolog.Ctx(ctx).Trace(). Hex("ciphertext_hash", ciphertextHash[:]). Msg("Successfully decrypted and saved event") return diff --git a/pkg/signalmeow/web/signalwebsocket.go b/pkg/signalmeow/web/signalwebsocket.go index 16a7463..c4030d6 100644 --- a/pkg/signalmeow/web/signalwebsocket.go +++ b/pkg/signalmeow/web/signalwebsocket.go @@ -429,7 +429,7 @@ func readLoop( if msg.Request == nil { return errors.New("received request message with no request") } - log.Debug(). + log.Trace(). Uint64("request_id", *msg.Request.Id). Str("request_verb", *msg.Request.Verb). Str("request_path", *msg.Request.Path). From b39a9c4fd207a248a8ca508bd0ebd0d79c7151fa Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Wed, 11 Jun 2025 15:34:59 +0300 Subject: [PATCH 356/580] login: fix more invalid returns --- go.mod | 2 +- go.sum | 4 ++-- pkg/connector/login.go | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/go.mod b/go.mod index 54ce972..69eaa73 100644 --- a/go.mod +++ b/go.mod @@ -18,7 +18,7 @@ require ( golang.org/x/exp v0.0.0-20250506013437-ce4c2cf36ca6 golang.org/x/net v0.40.0 google.golang.org/protobuf v1.36.6 - maunium.net/go/mautrix v0.24.1-0.20250606110819-d296f7b6604b + maunium.net/go/mautrix v0.24.1-0.20250611123434-15d0b63eb6ab ) require ( diff --git a/go.sum b/go.sum index 5f5fe5f..cec7d6d 100644 --- a/go.sum +++ b/go.sum @@ -99,5 +99,5 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= maunium.net/go/mauflag v1.0.0 h1:YiaRc0tEI3toYtJMRIfjP+jklH45uDHtT80nUamyD4M= maunium.net/go/mauflag v1.0.0/go.mod h1:nLivPOpTpHnpzEh8jEdSL9UqO9+/KBJFmNRlwKfkPeA= -maunium.net/go/mautrix v0.24.1-0.20250606110819-d296f7b6604b h1:coJOie9e6rdLBP8Ky9PjauvARytLvbue2pvdzEJssPM= -maunium.net/go/mautrix v0.24.1-0.20250606110819-d296f7b6604b/go.mod h1:HqA1HUutQYJkrYRPkK64itARDz79PCec1oWVEB72HVQ= +maunium.net/go/mautrix v0.24.1-0.20250611123434-15d0b63eb6ab h1:2oysPkLLkQkLhtH29C+hOXFxRU486dLQCmngTFw7oAA= +maunium.net/go/mautrix v0.24.1-0.20250611123434-15d0b63eb6ab/go.mod h1:HqA1HUutQYJkrYRPkK64itARDz79PCec1oWVEB72HVQ= diff --git a/pkg/connector/login.go b/pkg/connector/login.go index 1805be8..12d548d 100644 --- a/pkg/connector/login.go +++ b/pkg/connector/login.go @@ -122,7 +122,7 @@ func (qr *QRLogin) Wait(ctx context.Context) (*bridgev2.LoginStep, error) { func (qr *QRLogin) qrWait(ctx context.Context) (*bridgev2.LoginStep, error) { select { case resp := <-qr.ProvChan: - if resp.Err != nil || resp.State == signalmeow.StateProvisioningError { + if resp.Err != nil { qr.cancelChan() return nil, resp.Err } else if resp.State != signalmeow.StateProvisioningDataReceived { @@ -164,7 +164,7 @@ func (qr *QRLogin) processingWait(ctx context.Context) (*bridgev2.LoginStep, err select { case resp := <-qr.ProvChan: - if resp.Err != nil || resp.State == signalmeow.StateProvisioningError { + if resp.Err != nil { return nil, resp.Err } else if resp.State != signalmeow.StateProvisioningPreKeysRegistered { return nil, fmt.Errorf("unexpected state %v", resp.State) From 483bc4b8f2c08f9387f8900ed3ba798bde7dd95d Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Wed, 11 Jun 2025 16:33:33 +0300 Subject: [PATCH 357/580] libsignal: update to v0.74.1 --- pkg/libsignalgo/libsignal | 2 +- pkg/libsignalgo/libsignal-ffi.h | 12 ++++++------ pkg/libsignalgo/prekey.go | 1 + pkg/libsignalgo/prekeybundle.go | 1 + pkg/libsignalgo/version.go | 2 +- 5 files changed, 10 insertions(+), 8 deletions(-) diff --git a/pkg/libsignalgo/libsignal b/pkg/libsignalgo/libsignal index f8bcdb0..fd34ab3 160000 --- a/pkg/libsignalgo/libsignal +++ b/pkg/libsignalgo/libsignal @@ -1 +1 @@ -Subproject commit f8bcdb016abb9edb3b8d92851636208f3aa4c238 +Subproject commit fd34ab35ce21d1133ff254a44a7060a3ef72cf1b diff --git a/pkg/libsignalgo/libsignal-ffi.h b/pkg/libsignalgo/libsignal-ffi.h index 6c17995..1967ddd 100644 --- a/pkg/libsignalgo/libsignal-ffi.h +++ b/pkg/libsignalgo/libsignal-ffi.h @@ -25,8 +25,6 @@ SPDX-License-Identifier: AGPL-3.0-only #define SignalMEDIA_ENCRYPTION_KEY_LEN (32 + 32) -#define SignalBackupKey_MASTER_KEY_LEN SignalSVR_KEY_LEN - #define SignalBackupId_LEN 16 #define SignalNUM_AUTH_CRED_ATTRIBUTES 3 @@ -1559,7 +1557,7 @@ SignalFfiError *signal_create_otp_from_base64(const char **out, const char *user SignalFfiError *signal_decrypt_message(SignalOwnedBuffer *out, SignalConstPointerSignalMessage message, SignalConstPointerProtocolAddress protocol_address, SignalConstPointerFfiSessionStoreStruct session_store, SignalConstPointerFfiIdentityKeyStoreStruct identity_key_store); -SignalFfiError *signal_decrypt_pre_key_message(SignalOwnedBuffer *out, SignalConstPointerPreKeySignalMessage message, SignalConstPointerProtocolAddress protocol_address, SignalConstPointerFfiSessionStoreStruct session_store, SignalConstPointerFfiIdentityKeyStoreStruct identity_key_store, SignalConstPointerFfiPreKeyStoreStruct prekey_store, SignalConstPointerFfiSignedPreKeyStoreStruct signed_prekey_store, SignalConstPointerFfiKyberPreKeyStoreStruct kyber_prekey_store); +SignalFfiError *signal_decrypt_pre_key_message(SignalOwnedBuffer *out, SignalConstPointerPreKeySignalMessage message, SignalConstPointerProtocolAddress protocol_address, SignalConstPointerFfiSessionStoreStruct session_store, SignalConstPointerFfiIdentityKeyStoreStruct identity_key_store, SignalConstPointerFfiPreKeyStoreStruct prekey_store, SignalConstPointerFfiSignedPreKeyStoreStruct signed_prekey_store, SignalConstPointerFfiKyberPreKeyStoreStruct kyber_prekey_store, bool use_pq_ratchet); SignalFfiError *signal_decryption_error_message_clone(SignalMutPointerDecryptionErrorMessage *new_obj, SignalConstPointerDecryptionErrorMessage obj); @@ -1859,11 +1857,13 @@ SignalFfiError *signal_message_get_counter(uint32_t *out, SignalConstPointerSign SignalFfiError *signal_message_get_message_version(uint32_t *out, SignalConstPointerSignalMessage obj); +SignalFfiError *signal_message_get_pq_ratchet(SignalOwnedBuffer *out, SignalConstPointerSignalMessage msg); + SignalFfiError *signal_message_get_sender_ratchet_key(SignalMutPointerPublicKey *out, SignalConstPointerSignalMessage m); SignalFfiError *signal_message_get_serialized(SignalOwnedBuffer *out, SignalConstPointerSignalMessage obj); -SignalFfiError *signal_message_new(SignalMutPointerSignalMessage *out, uint8_t message_version, SignalBorrowedBuffer mac_key, SignalConstPointerPublicKey sender_ratchet_key, uint32_t counter, uint32_t previous_counter, SignalBorrowedBuffer ciphertext, SignalConstPointerPublicKey sender_identity_key, SignalConstPointerPublicKey receiver_identity_key); +SignalFfiError *signal_message_new(SignalMutPointerSignalMessage *out, uint8_t message_version, SignalBorrowedBuffer mac_key, SignalConstPointerPublicKey sender_ratchet_key, uint32_t counter, uint32_t previous_counter, SignalBorrowedBuffer ciphertext, SignalConstPointerPublicKey sender_identity_key, SignalConstPointerPublicKey receiver_identity_key, SignalBorrowedBuffer pq_ratchet); SignalFfiError *signal_message_verify_mac(bool *out, SignalConstPointerSignalMessage msg, SignalConstPointerPublicKey sender_identity_key, SignalConstPointerPublicKey receiver_identity_key, SignalBorrowedBuffer mac_key); @@ -1993,7 +1993,7 @@ SignalFfiError *signal_privatekey_serialize(SignalOwnedBuffer *out, SignalConstP SignalFfiError *signal_privatekey_sign(SignalOwnedBuffer *out, SignalConstPointerPrivateKey key, SignalBorrowedBuffer message); -SignalFfiError *signal_process_prekey_bundle(SignalConstPointerPreKeyBundle bundle, SignalConstPointerProtocolAddress protocol_address, SignalConstPointerFfiSessionStoreStruct session_store, SignalConstPointerFfiIdentityKeyStoreStruct identity_key_store, uint64_t now); +SignalFfiError *signal_process_prekey_bundle(SignalConstPointerPreKeyBundle bundle, SignalConstPointerProtocolAddress protocol_address, SignalConstPointerFfiSessionStoreStruct session_store, SignalConstPointerFfiIdentityKeyStoreStruct identity_key_store, uint64_t now, bool use_pq_ratchet); SignalFfiError *signal_process_sender_key_distribution_message(SignalConstPointerProtocolAddress sender, SignalConstPointerSenderKeyDistributionMessage sender_key_distribution_message, SignalConstPointerFfiSenderKeyStoreStruct store); @@ -2447,4 +2447,4 @@ SignalFfiError *signal_validating_mac_update(int32_t *out, SignalMutPointerValid SignalFfiError *signal_webp_sanitizer_sanitize(SignalConstPointerFfiSyncInputStreamStruct input); #endif -#endif /* SIGNAL_FFI_H_ */ +#endif /* SIGNAL_FFI_H_ */ diff --git a/pkg/libsignalgo/prekey.go b/pkg/libsignalgo/prekey.go index 4d01f89..7713c76 100644 --- a/pkg/libsignalgo/prekey.go +++ b/pkg/libsignalgo/prekey.go @@ -39,6 +39,7 @@ func DecryptPreKey(ctx context.Context, preKeyMessage *PreKeyMessage, fromAddres callbackCtx.wrapPreKeyStore(preKeyStore), callbackCtx.wrapSignedPreKeyStore(signedPreKeyStore), callbackCtx.wrapKyberPreKeyStore(kyberPreKeyStore), + false, // no pq ratchets yet ) runtime.KeepAlive(preKeyMessage) runtime.KeepAlive(fromAddress) diff --git a/pkg/libsignalgo/prekeybundle.go b/pkg/libsignalgo/prekeybundle.go index 4cd5547..7d8536e 100644 --- a/pkg/libsignalgo/prekeybundle.go +++ b/pkg/libsignalgo/prekeybundle.go @@ -37,6 +37,7 @@ func ProcessPreKeyBundle(ctx context.Context, bundle *PreKeyBundle, forAddress * callbackCtx.wrapSessionStore(sessionStore), callbackCtx.wrapIdentityKeyStore(identityStore), now, + false, // no pq ratchets yet ) runtime.KeepAlive(bundle) runtime.KeepAlive(forAddress) diff --git a/pkg/libsignalgo/version.go b/pkg/libsignalgo/version.go index 0ea03a5..d7458b0 100644 --- a/pkg/libsignalgo/version.go +++ b/pkg/libsignalgo/version.go @@ -2,4 +2,4 @@ package libsignalgo -const Version = "v0.73.2" +const Version = "v0.74.1" From 17b67552dc3cc091ed18d81e4bd8ea3b918c70e5 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Wed, 11 Jun 2025 16:36:25 +0300 Subject: [PATCH 358/580] docker: update to Alpine 3.22 --- Dockerfile | 4 ++-- Dockerfile.ci | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Dockerfile b/Dockerfile index a022666..9c5e495 100644 --- a/Dockerfile +++ b/Dockerfile @@ -11,7 +11,7 @@ ARG DBG=0 RUN ./build-rust.sh # -- Build mautrix-signal (with Go) -- -FROM golang:1-alpine3.21 AS go-builder +FROM golang:1-alpine3.22 AS go-builder RUN apk add --no-cache git ca-certificates build-base olm-dev WORKDIR /build @@ -39,7 +39,7 @@ EOF RUN ./build-go.sh # -- Run mautrix-signal -- -FROM alpine:3.21 +FROM alpine:3.22 ENV UID=1337 \ GID=1337 diff --git a/Dockerfile.ci b/Dockerfile.ci index 556dfc1..dc554ab 100644 --- a/Dockerfile.ci +++ b/Dockerfile.ci @@ -1,4 +1,4 @@ -FROM alpine:3.21 +FROM alpine:3.22 ENV UID=1337 \ GID=1337 From 46e2158a6a46c65d413a5ff6b814a890d369ef38 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Mon, 16 Jun 2025 16:06:37 +0300 Subject: [PATCH 359/580] groupinfo: fall back to resyncing group if catchup fails --- pkg/connector/groupinfo.go | 1 + 1 file changed, 1 insertion(+) diff --git a/pkg/connector/groupinfo.go b/pkg/connector/groupinfo.go index 0527ecf..dfd4faf 100644 --- a/pkg/connector/groupinfo.go +++ b/pkg/connector/groupinfo.go @@ -419,6 +419,7 @@ func (s *SignalClient) catchUpGroup(ctx context.Context, portal *bridgev2.Portal groupChanges, err := s.Client.GetGroupHistoryPage(ctx, types.GroupIdentifier(portal.ID), fromRevision, false) if err != nil { log.Err(err).Msg("Failed to get group history page") + s.catchUpGroup(ctx, portal, 0, toRevision, ts) return } for _, gc := range groupChanges { From fa57784c65239e5c2a9a10d953e4bbe85448f5cc Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Mon, 16 Jun 2025 17:56:17 +0300 Subject: [PATCH 360/580] dependencies: update --- go.mod | 18 +++++++++--------- go.sum | 32 ++++++++++++++++---------------- pkg/signalmeow/groups.go | 1 + 3 files changed, 26 insertions(+), 25 deletions(-) diff --git a/go.mod b/go.mod index 69eaa73..5e58f75 100644 --- a/go.mod +++ b/go.mod @@ -2,7 +2,7 @@ module go.mau.fi/mautrix-signal go 1.23.0 -toolchain go1.24.3 +toolchain go1.24.4 require ( github.com/coder/websocket v1.8.13 @@ -13,12 +13,12 @@ require ( github.com/rs/zerolog v1.34.0 github.com/stretchr/testify v1.10.0 github.com/tidwall/gjson v1.18.0 - go.mau.fi/util v0.8.7 - golang.org/x/crypto v0.38.0 - golang.org/x/exp v0.0.0-20250506013437-ce4c2cf36ca6 - golang.org/x/net v0.40.0 + go.mau.fi/util v0.8.8 + golang.org/x/crypto v0.39.0 + golang.org/x/exp v0.0.0-20250606033433-dcc06ee1d476 + golang.org/x/net v0.41.0 google.golang.org/protobuf v1.36.6 - maunium.net/go/mautrix v0.24.1-0.20250611123434-15d0b63eb6ab + maunium.net/go/mautrix v0.24.1 ) require ( @@ -39,11 +39,11 @@ require ( github.com/tidwall/match v1.1.1 // indirect github.com/tidwall/pretty v1.2.1 // indirect github.com/tidwall/sjson v1.2.5 // indirect - github.com/yuin/goldmark v1.7.11 // indirect + github.com/yuin/goldmark v1.7.12 // indirect go.mau.fi/zeroconfig v0.1.3 // indirect - golang.org/x/sync v0.14.0 // indirect + golang.org/x/sync v0.15.0 // indirect golang.org/x/sys v0.33.0 // indirect - golang.org/x/text v0.25.0 // indirect + golang.org/x/text v0.26.0 // indirect gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect gopkg.in/natefinch/lumberjack.v2 v2.2.1 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect diff --git a/go.sum b/go.sum index cec7d6d..a23b95e 100644 --- a/go.sum +++ b/go.sum @@ -67,27 +67,27 @@ github.com/tidwall/pretty v1.2.1 h1:qjsOFOWWQl+N3RsoF5/ssm1pHmJJwhjlSbZ51I6wMl4= github.com/tidwall/pretty v1.2.1/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU= github.com/tidwall/sjson v1.2.5 h1:kLy8mja+1c9jlljvWTlSazM7cKDRfJuR/bOJhcY5NcY= github.com/tidwall/sjson v1.2.5/go.mod h1:Fvgq9kS/6ociJEDnK0Fk1cpYF4FIW6ZF7LAe+6jwd28= -github.com/yuin/goldmark v1.7.11 h1:ZCxLyDMtz0nT2HFfsYG8WZ47Trip2+JyLysKcMYE5bo= -github.com/yuin/goldmark v1.7.11/go.mod h1:ip/1k0VRfGynBgxOz0yCqHrbZXhcjxyuS66Brc7iBKg= -go.mau.fi/util v0.8.7 h1:ywKarPxouJQEEijTs4mPlxC7F4AWEKokEpWc+2TYy6c= -go.mau.fi/util v0.8.7/go.mod h1:j6R3cENakc1f8HpQeFl0N15UiSTcNmIfDBNJUbL71RY= +github.com/yuin/goldmark v1.7.12 h1:YwGP/rrea2/CnCtUHgjuolG/PnMxdQtPMO5PvaE2/nY= +github.com/yuin/goldmark v1.7.12/go.mod h1:ip/1k0VRfGynBgxOz0yCqHrbZXhcjxyuS66Brc7iBKg= +go.mau.fi/util v0.8.8 h1:OnuEEc/sIJFhnq4kFggiImUpcmnmL/xpvQMRu5Fiy5c= +go.mau.fi/util v0.8.8/go.mod h1:Y/kS3loxTEhy8Vill513EtPXr+CRDdae+Xj2BXXMy/c= go.mau.fi/zeroconfig v0.1.3 h1:As9wYDKmktjmNZW5i1vn8zvJlmGKHeVxHVIBMXsm4kM= go.mau.fi/zeroconfig v0.1.3/go.mod h1:NcSJkf180JT+1IId76PcMuLTNa1CzsFFZ0nBygIQM70= -golang.org/x/crypto v0.38.0 h1:jt+WWG8IZlBnVbomuhg2Mdq0+BBQaHbtqHEFEigjUV8= -golang.org/x/crypto v0.38.0/go.mod h1:MvrbAqul58NNYPKnOra203SB9vpuZW0e+RRZV+Ggqjw= -golang.org/x/exp v0.0.0-20250506013437-ce4c2cf36ca6 h1:y5zboxd6LQAqYIhHnB48p0ByQ/GnQx2BE33L8BOHQkI= -golang.org/x/exp v0.0.0-20250506013437-ce4c2cf36ca6/go.mod h1:U6Lno4MTRCDY+Ba7aCcauB9T60gsv5s4ralQzP72ZoQ= -golang.org/x/net v0.40.0 h1:79Xs7wF06Gbdcg4kdCCIQArK11Z1hr5POQ6+fIYHNuY= -golang.org/x/net v0.40.0/go.mod h1:y0hY0exeL2Pku80/zKK7tpntoX23cqL3Oa6njdgRtds= -golang.org/x/sync v0.14.0 h1:woo0S4Yywslg6hp4eUFjTVOyKt0RookbpAHG4c1HmhQ= -golang.org/x/sync v0.14.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= +golang.org/x/crypto v0.39.0 h1:SHs+kF4LP+f+p14esP5jAoDpHU8Gu/v9lFRK6IT5imM= +golang.org/x/crypto v0.39.0/go.mod h1:L+Xg3Wf6HoL4Bn4238Z6ft6KfEpN0tJGo53AAPC632U= +golang.org/x/exp v0.0.0-20250606033433-dcc06ee1d476 h1:bsqhLWFR6G6xiQcb+JoGqdKdRU6WzPWmK8E0jxTjzo4= +golang.org/x/exp v0.0.0-20250606033433-dcc06ee1d476/go.mod h1:3//PLf8L/X+8b4vuAfHzxeRUl04Adcb341+IGKfnqS8= +golang.org/x/net v0.41.0 h1:vBTly1HeNPEn3wtREYfy4GZ/NECgw2Cnl+nK6Nz3uvw= +golang.org/x/net v0.41.0/go.mod h1:B/K4NNqkfmg07DQYrbwvSluqCJOOXwUjeb/5lOisjbA= +golang.org/x/sync v0.15.0 h1:KWH3jNZsfyT6xfAfKiz6MRNmd46ByHDYaZ7KSkCtdW8= +golang.org/x/sync v0.15.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.33.0 h1:q3i8TbbEz+JRD9ywIRlyRAQbM0qF7hu24q3teo2hbuw= golang.org/x/sys v0.33.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= -golang.org/x/text v0.25.0 h1:qVyWApTSYLk/drJRO5mDlNYskwQznZmkpV2c8q9zls4= -golang.org/x/text v0.25.0/go.mod h1:WEdwpYrmk1qmdHvhkSTNPm3app7v4rsT8F2UD6+VHIA= +golang.org/x/text v0.26.0 h1:P42AVeLghgTYr4+xUnTRKDMqpar+PtX7KWuNQL21L8M= +golang.org/x/text v0.26.0/go.mod h1:QK15LZJUUQVJxhz7wXgxSy/CJaTFjd0G+YLonydOVQA= google.golang.org/protobuf v1.36.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY= google.golang.org/protobuf v1.36.6/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= @@ -99,5 +99,5 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= maunium.net/go/mauflag v1.0.0 h1:YiaRc0tEI3toYtJMRIfjP+jklH45uDHtT80nUamyD4M= maunium.net/go/mauflag v1.0.0/go.mod h1:nLivPOpTpHnpzEh8jEdSL9UqO9+/KBJFmNRlwKfkPeA= -maunium.net/go/mautrix v0.24.1-0.20250611123434-15d0b63eb6ab h1:2oysPkLLkQkLhtH29C+hOXFxRU486dLQCmngTFw7oAA= -maunium.net/go/mautrix v0.24.1-0.20250611123434-15d0b63eb6ab/go.mod h1:HqA1HUutQYJkrYRPkK64itARDz79PCec1oWVEB72HVQ= +maunium.net/go/mautrix v0.24.1 h1:09/xi4qTeA03g1n/DPmmqAlT8Cx4QrgwiPlmLVzA9AU= +maunium.net/go/mautrix v0.24.1/go.mod h1:Xy6o+pXmbqmgWsUWh15EQ1eozjC+k/VT/7kloByv9PI= diff --git a/pkg/signalmeow/groups.go b/pkg/signalmeow/groups.go index f0b0815..35544f7 100644 --- a/pkg/signalmeow/groups.go +++ b/pkg/signalmeow/groups.go @@ -795,6 +795,7 @@ func (cli *Client) DecryptGroupChange(ctx context.Context, groupContext *signalp } return cli.decryptGroupChange(ctx, encryptedGroupChange, groupMasterKey, true) } + func (cli *Client) decryptGroupChange(ctx context.Context, encryptedGroupChange *signalpb.GroupChange, groupMasterKey types.SerializedGroupMasterKey, verifySignature bool) (*GroupChange, error) { log := zerolog.Ctx(ctx).With().Str("action", "decrypt group change").Logger() serverSignature := encryptedGroupChange.ServerSignature From b690026f42e788615cac3749b3c5fdd233cc7c92 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Mon, 16 Jun 2025 18:06:43 +0300 Subject: [PATCH 361/580] Bump version to v0.8.4 --- CHANGELOG.md | 8 ++++++++ cmd/mautrix-signal/main.go | 2 +- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e9da97b..f314ccf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,11 @@ +# v0.8.4 (2025-06-16) + +* Updated libsignal to v0.74.1. +* Updated Docker image to Alpine 3.22. +* Fixed avatars when using direct media. +* Fixed starting chats with non-contact users. +* Fixed Matrix media being rejected if the mime type isn't specified. + # v0.8.3 (2025-05-16) * Updated libsignal to v0.72.1. diff --git a/cmd/mautrix-signal/main.go b/cmd/mautrix-signal/main.go index 72b91c8..565e9bf 100644 --- a/cmd/mautrix-signal/main.go +++ b/cmd/mautrix-signal/main.go @@ -38,7 +38,7 @@ var m = mxmain.BridgeMain{ Name: "mautrix-signal", URL: "https://github.com/mautrix/signal", Description: "A Matrix-Signal puppeting bridge.", - Version: "0.8.3", + Version: "0.8.4", Connector: &connector.SignalConnector{}, } From bb09c6fa0e434f4acdf58d955833f2f2eb321407 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Tue, 17 Jun 2025 22:24:34 +0530 Subject: [PATCH 362/580] handlesignal: plumb event handling result to signalmeow (#603) --- go.mod | 2 +- go.sum | 4 +-- pkg/connector/handlesignal.go | 28 ++++++++++++--------- pkg/signalmeow/client.go | 8 +++--- pkg/signalmeow/receiving.go | 46 ++++++++++++++++++++--------------- 5 files changed, 49 insertions(+), 39 deletions(-) diff --git a/go.mod b/go.mod index 5e58f75..54e1fd9 100644 --- a/go.mod +++ b/go.mod @@ -18,7 +18,7 @@ require ( golang.org/x/exp v0.0.0-20250606033433-dcc06ee1d476 golang.org/x/net v0.41.0 google.golang.org/protobuf v1.36.6 - maunium.net/go/mautrix v0.24.1 + maunium.net/go/mautrix v0.24.2-0.20250617163829-26da46dbbf6e ) require ( diff --git a/go.sum b/go.sum index a23b95e..b0dbd1c 100644 --- a/go.sum +++ b/go.sum @@ -99,5 +99,5 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= maunium.net/go/mauflag v1.0.0 h1:YiaRc0tEI3toYtJMRIfjP+jklH45uDHtT80nUamyD4M= maunium.net/go/mauflag v1.0.0/go.mod h1:nLivPOpTpHnpzEh8jEdSL9UqO9+/KBJFmNRlwKfkPeA= -maunium.net/go/mautrix v0.24.1 h1:09/xi4qTeA03g1n/DPmmqAlT8Cx4QrgwiPlmLVzA9AU= -maunium.net/go/mautrix v0.24.1/go.mod h1:Xy6o+pXmbqmgWsUWh15EQ1eozjC+k/VT/7kloByv9PI= +maunium.net/go/mautrix v0.24.2-0.20250617163829-26da46dbbf6e h1:Y8kbRpPcKMZn2gIjUFd15xzMB5GJ2bS6ZcOfvlx4KnE= +maunium.net/go/mautrix v0.24.2-0.20250617163829-26da46dbbf6e/go.mod h1:Xy6o+pXmbqmgWsUWh15EQ1eozjC+k/VT/7kloByv9PI= diff --git a/pkg/connector/handlesignal.go b/pkg/connector/handlesignal.go index c2b0139..634c5ca 100644 --- a/pkg/connector/handlesignal.go +++ b/pkg/connector/handlesignal.go @@ -37,18 +37,18 @@ import ( "go.mau.fi/mautrix-signal/pkg/signalmeow/types" ) -func (s *SignalClient) handleSignalEvent(rawEvt events.SignalEvent) { +func (s *SignalClient) handleSignalEvent(rawEvt events.SignalEvent) bool { switch evt := rawEvt.(type) { case *events.ChatEvent: - s.Main.Bridge.QueueRemoteEvent(s.UserLogin, &Bv2ChatEvent{ChatEvent: evt, s: s}) + return s.Main.Bridge.QueueRemoteEvent(s.UserLogin, &Bv2ChatEvent{ChatEvent: evt, s: s}).Success case *events.DecryptionError: - s.Main.Bridge.QueueRemoteEvent(s.UserLogin, s.wrapDecryptionError(evt)) + return s.Main.Bridge.QueueRemoteEvent(s.UserLogin, s.wrapDecryptionError(evt)).Success case *events.Receipt: - s.handleSignalReceipt(evt) + return s.handleSignalReceipt(evt) case *events.ReadSelf: - s.handleSignalReadSelf(evt) + return s.handleSignalReadSelf(evt) case *events.Call: - s.Main.Bridge.QueueRemoteEvent(s.UserLogin, s.wrapCallEvent(evt)) + return s.Main.Bridge.QueueRemoteEvent(s.UserLogin, s.wrapCallEvent(evt)).Success case *events.ContactList: s.handleSignalContactList(evt) case *events.ACIFound: @@ -58,6 +58,7 @@ func (s *SignalClient) handleSignalEvent(rawEvt events.SignalEvent) { default: s.UserLogin.Log.Warn().Type("event_type", evt).Msg("Unrecognized signalmeow event type") } + return true } func (s *SignalClient) wrapCallEvent(evt *events.Call) bridgev2.RemoteMessage { @@ -427,17 +428,20 @@ func convertReceipts[T any](ctx context.Context, input []T, getMessageFunc func( return receipts } -func (s *SignalClient) dispatchReceipts(sender uuid.UUID, receiptType signalpb.ReceiptMessage_Type, receipts map[networkid.PortalKey]*Bv2Receipt) { +func (s *SignalClient) dispatchReceipts(sender uuid.UUID, receiptType signalpb.ReceiptMessage_Type, receipts map[networkid.PortalKey]*Bv2Receipt) bool { evtSender := s.makeEventSender(sender) for chat, receiptEvt := range receipts { receiptEvt.Chat = chat receiptEvt.Sender = evtSender receiptEvt.Type = receiptType - s.Main.Bridge.QueueRemoteEvent(s.UserLogin, receiptEvt) + if !s.Main.Bridge.QueueRemoteEvent(s.UserLogin, receiptEvt).Success { + return false + } } + return true } -func (s *SignalClient) handleSignalReceipt(evt *events.Receipt) { +func (s *SignalClient) handleSignalReceipt(evt *events.Receipt) bool { log := s.UserLogin.Log.With(). Str("action", "handle signal receipt"). Stringer("sender_id", evt.Sender). @@ -447,10 +451,10 @@ func (s *SignalClient) handleSignalReceipt(evt *events.Receipt) { receipts := convertReceipts(ctx, evt.Content.Timestamp, func(ctx context.Context, msgTS uint64) (*database.Message, error) { return s.Main.Bridge.DB.Message.GetFirstPartByID(ctx, s.UserLogin.ID, signalid.MakeMessageID(s.Client.Store.ACI, msgTS)) }) - s.dispatchReceipts(evt.Sender, evt.Content.GetType(), receipts) + return s.dispatchReceipts(evt.Sender, evt.Content.GetType(), receipts) } -func (s *SignalClient) handleSignalReadSelf(evt *events.ReadSelf) { +func (s *SignalClient) handleSignalReadSelf(evt *events.ReadSelf) bool { log := s.UserLogin.Log.With(). Str("action", "handle signal read self"). Logger() @@ -462,7 +466,7 @@ func (s *SignalClient) handleSignalReadSelf(evt *events.ReadSelf) { } return s.Main.Bridge.DB.Message.GetFirstPartByID(ctx, s.UserLogin.ID, signalid.MakeMessageID(aciUUID, msgInfo.GetTimestamp())) }) - s.dispatchReceipts(s.Client.Store.ACI, signalpb.ReceiptMessage_READ, receipts) + return s.dispatchReceipts(s.Client.Store.ACI, signalpb.ReceiptMessage_READ, receipts) } func (s *SignalClient) handleSignalACIFound(evt *events.ACIFound) { diff --git a/pkg/signalmeow/client.go b/pkg/signalmeow/client.go index d3ba6b6..42979c1 100644 --- a/pkg/signalmeow/client.go +++ b/pkg/signalmeow/client.go @@ -53,7 +53,7 @@ type Client struct { loopCancel context.CancelFunc loopWg sync.WaitGroup - EventHandler func(events.SignalEvent) + EventHandler func(events.SignalEvent) bool storageAuthLock sync.Mutex storageAuth *basicExpiringCredentials @@ -64,10 +64,8 @@ type Client struct { writeCallbackCounter chan time.Time } -func (cli *Client) handleEvent(evt events.SignalEvent) { - if cli.EventHandler != nil { - cli.EventHandler(evt) - } +func (cli *Client) handleEvent(evt events.SignalEvent) bool { + return cli.EventHandler(evt) } func (cli *Client) IsConnected() bool { diff --git a/pkg/signalmeow/receiving.go b/pkg/signalmeow/receiving.go index aea9b08..5b9f212 100644 --- a/pkg/signalmeow/receiving.go +++ b/pkg/signalmeow/receiving.go @@ -376,6 +376,8 @@ func (cli *Client) writeCallback(preWriteTime time.Time) { } } +var ErrHandlerFailed = errors.New("event handler returned non-success status") + // TODO: we should split this up into multiple functions func (cli *Client) handleDecryptedResult( ctx context.Context, @@ -399,6 +401,7 @@ func (cli *Client) handleDecryptedResult( }() } + handlerSuccess := true // result.Err is set if there was an error during decryption and we // should notifiy the user that the message could not be decrypted if result.Err != nil { @@ -434,13 +437,16 @@ func (cli *Client) handleDecryptedResult( if envelope.GetUrgent() && result.ContentHint != signalpb.UnidentifiedSenderMessage_Message_IMPLICIT && !strings.Contains(result.Err.Error(), "message with old counter") { - cli.handleEvent(&events.DecryptionError{ + handlerSuccess = cli.handleEvent(&events.DecryptionError{ Sender: theirServiceID.UUID, Err: result.Err, Timestamp: envelope.GetTimestamp(), }) } - // TODO there are probably no cases with both content and an error + if !handlerSuccess { + return ErrHandlerFailed + } + return nil } content := result.Content @@ -612,28 +618,29 @@ func (cli *Client) handleDecryptedResult( if err != nil { log.Err(err).Msg("Error storing contacts") } else { - cli.handleEvent(&events.ContactList{ + handlerSuccess = cli.handleEvent(&events.ContactList{ Contacts: convertedContacts, }) } } } if content.SyncMessage.Read != nil { - cli.handleEvent(&events.ReadSelf{ + handlerSuccess = cli.handleEvent(&events.ReadSelf{ Messages: content.SyncMessage.GetRead(), }) } } - var sendDeliveryReceipt bool + sendDeliveryReceipt := true if content.DataMessage != nil { - sendDeliveryReceipt = cli.incomingDataMessage(ctx, content.DataMessage, theirServiceID.UUID, theirServiceID, envelope.GetServerTimestamp()) + handlerSuccess = cli.incomingDataMessage(ctx, content.DataMessage, theirServiceID.UUID, theirServiceID, envelope.GetServerTimestamp()) } else if content.EditMessage != nil { - sendDeliveryReceipt = cli.incomingEditMessage(ctx, content.EditMessage, theirServiceID.UUID, theirServiceID, envelope.GetServerTimestamp()) + handlerSuccess = cli.incomingEditMessage(ctx, content.EditMessage, theirServiceID.UUID, theirServiceID, envelope.GetServerTimestamp()) + } else { + sendDeliveryReceipt = false } - if sendDeliveryReceipt { - // TODO send delivery receipts after actually bridging instead of here + if sendDeliveryReceipt && handlerSuccess { err = cli.sendDeliveryReceipts(ctx, []uint64{content.DataMessage.GetTimestamp()}, theirServiceID.UUID) if err != nil { log.Err(err).Msg("sendDeliveryReceipts error") @@ -646,6 +653,7 @@ func (cli *Client) handleDecryptedResult( gidBytes := content.TypingMessage.GetGroupId() groupID = types.GroupIdentifier(base64.StdEncoding.EncodeToString(gidBytes)) } + // No handler success check here, nobody cares if typing notifications are dropped cli.handleEvent(&events.ChatEvent{ Info: events.MessageInfo{ Sender: theirServiceID.UUID, @@ -658,7 +666,7 @@ func (cli *Client) handleDecryptedResult( // DM call message (group call is an opaque callMessage and a groupCallUpdate in a dataMessage) if content.CallMessage != nil && (content.CallMessage.Offer != nil || content.CallMessage.Hangup != nil) { - cli.handleEvent(&events.Call{ + handlerSuccess = cli.handleEvent(&events.Call{ Info: events.MessageInfo{ Sender: theirServiceID.UUID, ChatID: theirServiceID.String(), @@ -667,7 +675,7 @@ func (cli *Client) handleDecryptedResult( // CallMessage doesn't have its own timestamp, use one from the envelope Timestamp: envelope.GetTimestamp(), IsRinging: content.CallMessage.Offer != nil, - }) + }) && handlerSuccess } // Read and delivery receipts @@ -676,10 +684,13 @@ func (cli *Client) handleDecryptedResult( // Ignore delivery receipts from other own devices return nil } - cli.handleEvent(&events.Receipt{ + handlerSuccess = cli.handleEvent(&events.Receipt{ Sender: theirServiceID.UUID, Content: content.ReceiptMessage, - }) + }) && handlerSuccess + } + if !handlerSuccess { + return ErrHandlerFailed } return nil } @@ -757,7 +768,7 @@ func (cli *Client) incomingEditMessage(ctx context.Context, editMessage *signalp } groupRevision = editMessage.GetDataMessage().GetGroupV2().GetRevision() } - cli.handleEvent(&events.ChatEvent{ + return cli.handleEvent(&events.ChatEvent{ Info: events.MessageInfo{ Sender: messageSenderACI, ChatID: groupOrUserID(groupID, chatRecipient), @@ -766,7 +777,6 @@ func (cli *Client) incomingEditMessage(ctx context.Context, editMessage *signalp }, Event: editMessage, }) - return true } func (cli *Client) incomingDataMessage(ctx context.Context, dataMessage *signalpb.DataMessage, messageSenderACI uuid.UUID, chatRecipient libsignalgo.ServiceID, serverTimestamp uint64) bool { @@ -805,19 +815,17 @@ func (cli *Client) incomingDataMessage(ctx context.Context, dataMessage *signalp // Hacky special case for group calls to cache the state if dataMessage.GroupCallUpdate != nil { isRinging := cli.UpdateActiveCalls(groupID, dataMessage.GroupCallUpdate.GetEraId()) - cli.handleEvent(&events.Call{ + return cli.handleEvent(&events.Call{ Info: evtInfo, Timestamp: dataMessage.GetTimestamp(), IsRinging: isRinging, }) } else { - cli.handleEvent(&events.ChatEvent{ + return cli.handleEvent(&events.ChatEvent{ Info: evtInfo, Event: dataMessage, }) } - - return true } func (cli *Client) sendDeliveryReceipts(ctx context.Context, deliveredTimestamps []uint64, senderUUID uuid.UUID) error { From 97287928b8d71d82f4397bcf8746d84a472d8a54 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Mon, 30 Jun 2025 13:18:41 +0300 Subject: [PATCH 363/580] libsignal: update to v0.76.1 --- pkg/libsignalgo/libsignal | 2 +- pkg/libsignalgo/libsignal-ffi.h | 51 +++++++++++++++++++-------------- pkg/libsignalgo/version.go | 2 +- 3 files changed, 32 insertions(+), 23 deletions(-) diff --git a/pkg/libsignalgo/libsignal b/pkg/libsignalgo/libsignal index fd34ab3..6dc0f85 160000 --- a/pkg/libsignalgo/libsignal +++ b/pkg/libsignalgo/libsignal @@ -1 +1 @@ -Subproject commit fd34ab35ce21d1133ff254a44a7060a3ef72cf1b +Subproject commit 6dc0f85b07d890fd02e727a0f8484a1f3f864f7e diff --git a/pkg/libsignalgo/libsignal-ffi.h b/pkg/libsignalgo/libsignal-ffi.h index 1967ddd..0288e34 100644 --- a/pkg/libsignalgo/libsignal-ffi.h +++ b/pkg/libsignalgo/libsignal-ffi.h @@ -123,6 +123,12 @@ SPDX-License-Identifier: AGPL-3.0-only */ #define SignalFourCC_ENCODED_LEN 4 +enum SignalChallengeOption { + SignalChallengeOptionPushChallenge, + SignalChallengeOptionCaptcha, +}; +typedef uint8_t SignalChallengeOption; + typedef enum { SignalCiphertextMessageTypeWhisper = 2, SignalCiphertextMessageTypePreKey = 3, @@ -169,12 +175,6 @@ typedef enum { SignalLogLevelTrace, } SignalLogLevel; -enum SignalRequestedInformation { - SignalRequestedInformationPushChallenge, - SignalRequestedInformationCaptcha, -}; -typedef uint8_t SignalRequestedInformation; - typedef enum { SignalErrorCodeUnknownError = 1, SignalErrorCodeInvalidState = 2, @@ -201,6 +201,7 @@ typedef enum { SignalErrorCodeInvalidRegistrationId = 81, SignalErrorCodeInvalidSession = 82, SignalErrorCodeInvalidSenderKeySession = 83, + SignalErrorCodeInvalidProtocolAddress = 84, SignalErrorCodeDuplicatedMessage = 90, SignalErrorCodeCallbackError = 100, SignalErrorCodeVerificationFailure = 110, @@ -229,6 +230,7 @@ typedef enum { SignalErrorCodeConnectionFailed = 148, SignalErrorCodeChatServiceInactive = 149, SignalErrorCodeRequestTimedOut = 150, + SignalErrorCodeRateLimitChallenge = 151, SignalErrorCodeSvrDataMissing = 160, SignalErrorCodeSvrRestoreFailed = 161, SignalErrorCodeSvrRotationMachineTooManySteps = 162, @@ -238,7 +240,6 @@ typedef enum { SignalErrorCodeConnectedElsewhere = 173, SignalErrorCodeBackupValidation = 180, SignalErrorCodeRegistrationInvalidSessionId = 190, - SignalErrorCodeRegistrationRequestNotValid = 191, SignalErrorCodeRegistrationUnknown = 192, SignalErrorCodeRegistrationSessionNotFound = 193, SignalErrorCodeRegistrationNotReadyForVerification = 194, @@ -466,6 +467,16 @@ typedef struct { const SignalConnectionManager *raw; } SignalConstPointerConnectionManager; +typedef struct { + const size_t *base; + size_t length; +} SignalBorrowedSliceOfusize; + +typedef struct { + SignalBorrowedBuffer bytes; + SignalBorrowedSliceOfusize lengths; +} SignalBorrowedBytestringArray; + /** * A C callback used to report the results of Rust futures. * @@ -1116,16 +1127,6 @@ typedef struct { SignalRegistrationAccountAttributes *raw; } SignalMutPointerRegistrationAccountAttributes; -typedef struct { - const size_t *base; - size_t length; -} SignalBorrowedSliceOfusize; - -typedef struct { - SignalBorrowedBuffer bytes; - SignalBorrowedSliceOfusize lengths; -} SignalBorrowedBytestringArray; - typedef struct { /** * Bridged as a string of bytes, but each entry is a UTF-8 `String` key @@ -1391,7 +1392,7 @@ SignalFfiError *signal_auth_credential_with_pni_check_valid_contents(SignalBorro SignalFfiError *signal_auth_credential_with_pni_response_check_valid_contents(SignalBorrowedBuffer bytes); -SignalFfiError *signal_authenticated_chat_connection_connect(SignalCPromiseMutPointerAuthenticatedChatConnection *promise, SignalConstPointerTokioAsyncContext async_runtime, SignalConstPointerConnectionManager connection_manager, const char *username, const char *password, bool receive_stories); +SignalFfiError *signal_authenticated_chat_connection_connect(SignalCPromiseMutPointerAuthenticatedChatConnection *promise, SignalConstPointerTokioAsyncContext async_runtime, SignalConstPointerConnectionManager connection_manager, const char *username, const char *password, bool receive_stories, SignalBorrowedBytestringArray languages); SignalFfiError *signal_authenticated_chat_connection_destroy(SignalMutPointerAuthenticatedChatConnection p); @@ -1589,14 +1590,22 @@ void signal_error_free(SignalFfiError *err); SignalFfiError *signal_error_get_address(const SignalFfiError *err, SignalMutPointerProtocolAddress *out); +SignalFfiError *signal_error_get_invalid_protocol_address(const SignalFfiError *err, const char **name_out, uint32_t *device_id_out); + SignalFfiError *signal_error_get_message(const SignalFfiError *err, const char **out); +SignalFfiError *signal_error_get_our_fingerprint_version(const SignalFfiError *err, uint32_t *out); + +SignalFfiError *signal_error_get_rate_limit_challenge(const SignalFfiError *err, const char **out_token, SignalOwnedBuffer *out_options); + SignalFfiError *signal_error_get_registration_error_not_deliverable(const SignalFfiError *err, const char **out_reason, bool *out_permanent); SignalFfiError *signal_error_get_registration_lock(const SignalFfiError *err, uint64_t *out_time_remaining_seconds, const char **out_svr2_username, const char **out_svr2_password); SignalFfiError *signal_error_get_retry_after_seconds(const SignalFfiError *err, uint32_t *out); +SignalFfiError *signal_error_get_their_fingerprint_version(const SignalFfiError *err, uint32_t *out); + SignalFfiError *signal_error_get_tries_remaining(const SignalFfiError *err, uint32_t *out); uint32_t signal_error_get_type(const SignalFfiError *err); @@ -1915,11 +1924,11 @@ SignalFfiError *signal_pre_key_bundle_get_device_id(uint32_t *out, SignalConstPo SignalFfiError *signal_pre_key_bundle_get_identity_key(SignalMutPointerPublicKey *out, SignalConstPointerPreKeyBundle p); -SignalFfiError *signal_pre_key_bundle_get_kyber_pre_key_id(uint32_t *out, SignalConstPointerPreKeyBundle bundle); +SignalFfiError *signal_pre_key_bundle_get_kyber_pre_key_id(uint32_t *out, SignalConstPointerPreKeyBundle obj); SignalFfiError *signal_pre_key_bundle_get_kyber_pre_key_public(SignalMutPointerKyberPublicKey *out, SignalConstPointerPreKeyBundle bundle); -SignalFfiError *signal_pre_key_bundle_get_kyber_pre_key_signature(SignalOwnedBuffer *out, SignalConstPointerPreKeyBundle bundle); +SignalFfiError *signal_pre_key_bundle_get_kyber_pre_key_signature(SignalOwnedBuffer *out, SignalConstPointerPreKeyBundle obj); SignalFfiError *signal_pre_key_bundle_get_pre_key_id(uint32_t *out, SignalConstPointerPreKeyBundle obj); @@ -2387,7 +2396,7 @@ SignalFfiError *signal_tokio_async_context_destroy(SignalMutPointerTokioAsyncCon SignalFfiError *signal_tokio_async_context_new(SignalMutPointerTokioAsyncContext *out); -SignalFfiError *signal_unauthenticated_chat_connection_connect(SignalCPromiseMutPointerUnauthenticatedChatConnection *promise, SignalConstPointerTokioAsyncContext async_runtime, SignalConstPointerConnectionManager connection_manager); +SignalFfiError *signal_unauthenticated_chat_connection_connect(SignalCPromiseMutPointerUnauthenticatedChatConnection *promise, SignalConstPointerTokioAsyncContext async_runtime, SignalConstPointerConnectionManager connection_manager, SignalBorrowedBytestringArray languages); SignalFfiError *signal_unauthenticated_chat_connection_destroy(SignalMutPointerUnauthenticatedChatConnection p); diff --git a/pkg/libsignalgo/version.go b/pkg/libsignalgo/version.go index d7458b0..e9ce0db 100644 --- a/pkg/libsignalgo/version.go +++ b/pkg/libsignalgo/version.go @@ -2,4 +2,4 @@ package libsignalgo -const Version = "v0.74.1" +const Version = "v0.76.1" From 3b2548d70c896b6241b1dc05f53b65e07ac0d385 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Mon, 30 Jun 2025 13:22:34 +0300 Subject: [PATCH 364/580] signalmeow: update protobufs --- pkg/signalmeow/protobuf/StorageService.pb.go | 999 +++++++++++++----- pkg/signalmeow/protobuf/StorageService.proto | 159 ++- .../protobuf/UnidentifiedDelivery.pb.go | 18 +- .../protobuf/UnidentifiedDelivery.proto | 5 +- pkg/signalmeow/protobuf/backuppb/Backup.pb.go | 521 ++++++--- pkg/signalmeow/protobuf/backuppb/Backup.proto | 59 ++ pkg/signalmeow/protobuf/update-protos.sh | 4 +- 7 files changed, 1302 insertions(+), 463 deletions(-) diff --git a/pkg/signalmeow/protobuf/StorageService.pb.go b/pkg/signalmeow/protobuf/StorageService.pb.go index 3826c83..c6ce93e 100644 --- a/pkg/signalmeow/protobuf/StorageService.pb.go +++ b/pkg/signalmeow/protobuf/StorageService.pb.go @@ -171,6 +171,7 @@ const ( ManifestRecord_Identifier_STORY_DISTRIBUTION_LIST ManifestRecord_Identifier_Type = 5 ManifestRecord_Identifier_CALL_LINK ManifestRecord_Identifier_Type = 7 ManifestRecord_Identifier_CHAT_FOLDER ManifestRecord_Identifier_Type = 8 + ManifestRecord_Identifier_NOTIFICATION_PROFILE ManifestRecord_Identifier_Type = 9 ) // Enum value maps for ManifestRecord_Identifier_Type. @@ -184,6 +185,7 @@ var ( 5: "STORY_DISTRIBUTION_LIST", 7: "CALL_LINK", 8: "CHAT_FOLDER", + 9: "NOTIFICATION_PROFILE", } ManifestRecord_Identifier_Type_value = map[string]int32{ "UNKNOWN": 0, @@ -194,6 +196,7 @@ var ( "STORY_DISTRIBUTION_LIST": 5, "CALL_LINK": 7, "CHAT_FOLDER": 8, + "NOTIFICATION_PROFILE": 9, } ) @@ -485,7 +488,71 @@ func (x ChatFolderRecord_FolderType) Number() protoreflect.EnumNumber { // Deprecated: Use ChatFolderRecord_FolderType.Descriptor instead. func (ChatFolderRecord_FolderType) EnumDescriptor() ([]byte, []int) { - return file_StorageService_proto_rawDescGZIP(), []int{14, 0} + return file_StorageService_proto_rawDescGZIP(), []int{15, 0} +} + +type NotificationProfile_DayOfWeek int32 + +const ( + NotificationProfile_UNKNOWN NotificationProfile_DayOfWeek = 0 // Interpret as "Monday" + NotificationProfile_MONDAY NotificationProfile_DayOfWeek = 1 + NotificationProfile_TUESDAY NotificationProfile_DayOfWeek = 2 + NotificationProfile_WEDNESDAY NotificationProfile_DayOfWeek = 3 + NotificationProfile_THURSDAY NotificationProfile_DayOfWeek = 4 + NotificationProfile_FRIDAY NotificationProfile_DayOfWeek = 5 + NotificationProfile_SATURDAY NotificationProfile_DayOfWeek = 6 + NotificationProfile_SUNDAY NotificationProfile_DayOfWeek = 7 +) + +// Enum value maps for NotificationProfile_DayOfWeek. +var ( + NotificationProfile_DayOfWeek_name = map[int32]string{ + 0: "UNKNOWN", + 1: "MONDAY", + 2: "TUESDAY", + 3: "WEDNESDAY", + 4: "THURSDAY", + 5: "FRIDAY", + 6: "SATURDAY", + 7: "SUNDAY", + } + NotificationProfile_DayOfWeek_value = map[string]int32{ + "UNKNOWN": 0, + "MONDAY": 1, + "TUESDAY": 2, + "WEDNESDAY": 3, + "THURSDAY": 4, + "FRIDAY": 5, + "SATURDAY": 6, + "SUNDAY": 7, + } +) + +func (x NotificationProfile_DayOfWeek) Enum() *NotificationProfile_DayOfWeek { + p := new(NotificationProfile_DayOfWeek) + *p = x + return p +} + +func (x NotificationProfile_DayOfWeek) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (NotificationProfile_DayOfWeek) Descriptor() protoreflect.EnumDescriptor { + return file_StorageService_proto_enumTypes[8].Descriptor() +} + +func (NotificationProfile_DayOfWeek) Type() protoreflect.EnumType { + return &file_StorageService_proto_enumTypes[8] +} + +func (x NotificationProfile_DayOfWeek) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use NotificationProfile_DayOfWeek.Descriptor instead. +func (NotificationProfile_DayOfWeek) EnumDescriptor() ([]byte, []int) { + return file_StorageService_proto_rawDescGZIP(), []int{16, 0} } type StorageManifest struct { @@ -827,6 +894,7 @@ type StorageRecord struct { // *StorageRecord_StoryDistributionList // *StorageRecord_CallLink // *StorageRecord_ChatFolder + // *StorageRecord_NotificationProfile Record isStorageRecord_Record `protobuf_oneof:"record"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache @@ -932,6 +1000,15 @@ func (x *StorageRecord) GetChatFolder() *ChatFolderRecord { return nil } +func (x *StorageRecord) GetNotificationProfile() *NotificationProfile { + if x != nil { + if x, ok := x.Record.(*StorageRecord_NotificationProfile); ok { + return x.NotificationProfile + } + } + return nil +} + type isStorageRecord_Record interface { isStorageRecord_Record() } @@ -964,6 +1041,10 @@ type StorageRecord_ChatFolder struct { ChatFolder *ChatFolderRecord `protobuf:"bytes,8,opt,name=chatFolder,proto3,oneof"` } +type StorageRecord_NotificationProfile struct { + NotificationProfile *NotificationProfile `protobuf:"bytes,9,opt,name=notificationProfile,proto3,oneof"` +} + func (*StorageRecord_Contact) isStorageRecord_Record() {} func (*StorageRecord_GroupV1) isStorageRecord_Record() {} @@ -978,6 +1059,8 @@ func (*StorageRecord_CallLink) isStorageRecord_Record() {} func (*StorageRecord_ChatFolder) isStorageRecord_Record() {} +func (*StorageRecord_NotificationProfile) isStorageRecord_Record() {} + type ContactRecord struct { state protoimpl.MessageState `protogen:"open.v1"` Aci string `protobuf:"bytes,1,opt,name=aci,proto3" json:"aci,omitempty"` @@ -1459,45 +1542,46 @@ func (x *Payments) GetEntropy() []byte { } type AccountRecord struct { - state protoimpl.MessageState `protogen:"open.v1"` - ProfileKey []byte `protobuf:"bytes,1,opt,name=profileKey,proto3" json:"profileKey,omitempty"` - GivenName string `protobuf:"bytes,2,opt,name=givenName,proto3" json:"givenName,omitempty"` - FamilyName string `protobuf:"bytes,3,opt,name=familyName,proto3" json:"familyName,omitempty"` - AvatarUrlPath string `protobuf:"bytes,4,opt,name=avatarUrlPath,proto3" json:"avatarUrlPath,omitempty"` - NoteToSelfArchived bool `protobuf:"varint,5,opt,name=noteToSelfArchived,proto3" json:"noteToSelfArchived,omitempty"` - ReadReceipts bool `protobuf:"varint,6,opt,name=readReceipts,proto3" json:"readReceipts,omitempty"` - SealedSenderIndicators bool `protobuf:"varint,7,opt,name=sealedSenderIndicators,proto3" json:"sealedSenderIndicators,omitempty"` - TypingIndicators bool `protobuf:"varint,8,opt,name=typingIndicators,proto3" json:"typingIndicators,omitempty"` - NoteToSelfMarkedUnread bool `protobuf:"varint,10,opt,name=noteToSelfMarkedUnread,proto3" json:"noteToSelfMarkedUnread,omitempty"` - LinkPreviews bool `protobuf:"varint,11,opt,name=linkPreviews,proto3" json:"linkPreviews,omitempty"` - PhoneNumberSharingMode AccountRecord_PhoneNumberSharingMode `protobuf:"varint,12,opt,name=phoneNumberSharingMode,proto3,enum=signalservice.AccountRecord_PhoneNumberSharingMode" json:"phoneNumberSharingMode,omitempty"` - UnlistedPhoneNumber bool `protobuf:"varint,13,opt,name=unlistedPhoneNumber,proto3" json:"unlistedPhoneNumber,omitempty"` - PinnedConversations []*AccountRecord_PinnedConversation `protobuf:"bytes,14,rep,name=pinnedConversations,proto3" json:"pinnedConversations,omitempty"` - PreferContactAvatars bool `protobuf:"varint,15,opt,name=preferContactAvatars,proto3" json:"preferContactAvatars,omitempty"` - Payments *Payments `protobuf:"bytes,16,opt,name=payments,proto3" json:"payments,omitempty"` - UniversalExpireTimer uint32 `protobuf:"varint,17,opt,name=universalExpireTimer,proto3" json:"universalExpireTimer,omitempty"` - PrimarySendsSms bool `protobuf:"varint,18,opt,name=primarySendsSms,proto3" json:"primarySendsSms,omitempty"` - E164 string `protobuf:"bytes,19,opt,name=e164,proto3" json:"e164,omitempty"` - PreferredReactionEmoji []string `protobuf:"bytes,20,rep,name=preferredReactionEmoji,proto3" json:"preferredReactionEmoji,omitempty"` - SubscriberId []byte `protobuf:"bytes,21,opt,name=subscriberId,proto3" json:"subscriberId,omitempty"` - SubscriberCurrencyCode string `protobuf:"bytes,22,opt,name=subscriberCurrencyCode,proto3" json:"subscriberCurrencyCode,omitempty"` - DisplayBadgesOnProfile bool `protobuf:"varint,23,opt,name=displayBadgesOnProfile,proto3" json:"displayBadgesOnProfile,omitempty"` - SubscriptionManuallyCancelled bool `protobuf:"varint,24,opt,name=subscriptionManuallyCancelled,proto3" json:"subscriptionManuallyCancelled,omitempty"` - KeepMutedChatsArchived bool `protobuf:"varint,25,opt,name=keepMutedChatsArchived,proto3" json:"keepMutedChatsArchived,omitempty"` - HasSetMyStoriesPrivacy bool `protobuf:"varint,26,opt,name=hasSetMyStoriesPrivacy,proto3" json:"hasSetMyStoriesPrivacy,omitempty"` - HasViewedOnboardingStory bool `protobuf:"varint,27,opt,name=hasViewedOnboardingStory,proto3" json:"hasViewedOnboardingStory,omitempty"` - StoriesDisabled bool `protobuf:"varint,29,opt,name=storiesDisabled,proto3" json:"storiesDisabled,omitempty"` - StoryViewReceiptsEnabled OptionalBool `protobuf:"varint,30,opt,name=storyViewReceiptsEnabled,proto3,enum=signalservice.OptionalBool" json:"storyViewReceiptsEnabled,omitempty"` - HasSeenGroupStoryEducationSheet bool `protobuf:"varint,32,opt,name=hasSeenGroupStoryEducationSheet,proto3" json:"hasSeenGroupStoryEducationSheet,omitempty"` - Username string `protobuf:"bytes,33,opt,name=username,proto3" json:"username,omitempty"` - HasCompletedUsernameOnboarding bool `protobuf:"varint,34,opt,name=hasCompletedUsernameOnboarding,proto3" json:"hasCompletedUsernameOnboarding,omitempty"` - UsernameLink *AccountRecord_UsernameLink `protobuf:"bytes,35,opt,name=usernameLink,proto3" json:"usernameLink,omitempty"` - HasBackup *bool `protobuf:"varint,39,opt,name=hasBackup,proto3,oneof" json:"hasBackup,omitempty"` // Set to true after backups are enabled and one is uploaded. - BackupTier *uint64 `protobuf:"varint,40,opt,name=backupTier,proto3,oneof" json:"backupTier,omitempty"` // See zkgroup for integer particular values - BackupSubscriberData *AccountRecord_IAPSubscriberData `protobuf:"bytes,41,opt,name=backupSubscriberData,proto3" json:"backupSubscriberData,omitempty"` - AvatarColor *AvatarColor `protobuf:"varint,42,opt,name=avatarColor,proto3,enum=signalservice.AvatarColor,oneof" json:"avatarColor,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` + ProfileKey []byte `protobuf:"bytes,1,opt,name=profileKey,proto3" json:"profileKey,omitempty"` + GivenName string `protobuf:"bytes,2,opt,name=givenName,proto3" json:"givenName,omitempty"` + FamilyName string `protobuf:"bytes,3,opt,name=familyName,proto3" json:"familyName,omitempty"` + AvatarUrlPath string `protobuf:"bytes,4,opt,name=avatarUrlPath,proto3" json:"avatarUrlPath,omitempty"` + NoteToSelfArchived bool `protobuf:"varint,5,opt,name=noteToSelfArchived,proto3" json:"noteToSelfArchived,omitempty"` + ReadReceipts bool `protobuf:"varint,6,opt,name=readReceipts,proto3" json:"readReceipts,omitempty"` + SealedSenderIndicators bool `protobuf:"varint,7,opt,name=sealedSenderIndicators,proto3" json:"sealedSenderIndicators,omitempty"` + TypingIndicators bool `protobuf:"varint,8,opt,name=typingIndicators,proto3" json:"typingIndicators,omitempty"` + NoteToSelfMarkedUnread bool `protobuf:"varint,10,opt,name=noteToSelfMarkedUnread,proto3" json:"noteToSelfMarkedUnread,omitempty"` + LinkPreviews bool `protobuf:"varint,11,opt,name=linkPreviews,proto3" json:"linkPreviews,omitempty"` + PhoneNumberSharingMode AccountRecord_PhoneNumberSharingMode `protobuf:"varint,12,opt,name=phoneNumberSharingMode,proto3,enum=signalservice.AccountRecord_PhoneNumberSharingMode" json:"phoneNumberSharingMode,omitempty"` + UnlistedPhoneNumber bool `protobuf:"varint,13,opt,name=unlistedPhoneNumber,proto3" json:"unlistedPhoneNumber,omitempty"` + PinnedConversations []*AccountRecord_PinnedConversation `protobuf:"bytes,14,rep,name=pinnedConversations,proto3" json:"pinnedConversations,omitempty"` + PreferContactAvatars bool `protobuf:"varint,15,opt,name=preferContactAvatars,proto3" json:"preferContactAvatars,omitempty"` + Payments *Payments `protobuf:"bytes,16,opt,name=payments,proto3" json:"payments,omitempty"` + UniversalExpireTimer uint32 `protobuf:"varint,17,opt,name=universalExpireTimer,proto3" json:"universalExpireTimer,omitempty"` + PrimarySendsSms bool `protobuf:"varint,18,opt,name=primarySendsSms,proto3" json:"primarySendsSms,omitempty"` + PreferredReactionEmoji []string `protobuf:"bytes,20,rep,name=preferredReactionEmoji,proto3" json:"preferredReactionEmoji,omitempty"` + SubscriberId []byte `protobuf:"bytes,21,opt,name=subscriberId,proto3" json:"subscriberId,omitempty"` + SubscriberCurrencyCode string `protobuf:"bytes,22,opt,name=subscriberCurrencyCode,proto3" json:"subscriberCurrencyCode,omitempty"` + DisplayBadgesOnProfile bool `protobuf:"varint,23,opt,name=displayBadgesOnProfile,proto3" json:"displayBadgesOnProfile,omitempty"` + SubscriptionManuallyCancelled bool `protobuf:"varint,24,opt,name=subscriptionManuallyCancelled,proto3" json:"subscriptionManuallyCancelled,omitempty"` + KeepMutedChatsArchived bool `protobuf:"varint,25,opt,name=keepMutedChatsArchived,proto3" json:"keepMutedChatsArchived,omitempty"` + HasSetMyStoriesPrivacy bool `protobuf:"varint,26,opt,name=hasSetMyStoriesPrivacy,proto3" json:"hasSetMyStoriesPrivacy,omitempty"` + HasViewedOnboardingStory bool `protobuf:"varint,27,opt,name=hasViewedOnboardingStory,proto3" json:"hasViewedOnboardingStory,omitempty"` + StoriesDisabled bool `protobuf:"varint,29,opt,name=storiesDisabled,proto3" json:"storiesDisabled,omitempty"` + StoryViewReceiptsEnabled OptionalBool `protobuf:"varint,30,opt,name=storyViewReceiptsEnabled,proto3,enum=signalservice.OptionalBool" json:"storyViewReceiptsEnabled,omitempty"` + HasSeenGroupStoryEducationSheet bool `protobuf:"varint,32,opt,name=hasSeenGroupStoryEducationSheet,proto3" json:"hasSeenGroupStoryEducationSheet,omitempty"` + Username string `protobuf:"bytes,33,opt,name=username,proto3" json:"username,omitempty"` + HasCompletedUsernameOnboarding bool `protobuf:"varint,34,opt,name=hasCompletedUsernameOnboarding,proto3" json:"hasCompletedUsernameOnboarding,omitempty"` + UsernameLink *AccountRecord_UsernameLink `protobuf:"bytes,35,opt,name=usernameLink,proto3" json:"usernameLink,omitempty"` + HasBackup *bool `protobuf:"varint,39,opt,name=hasBackup,proto3,oneof" json:"hasBackup,omitempty"` // Set to true after backups are enabled and one is uploaded. + BackupTier *uint64 `protobuf:"varint,40,opt,name=backupTier,proto3,oneof" json:"backupTier,omitempty"` // See zkgroup for integer particular values. Unset if backups are not enabled. + BackupSubscriberData *AccountRecord_IAPSubscriberData `protobuf:"bytes,41,opt,name=backupSubscriberData,proto3" json:"backupSubscriberData,omitempty"` + AvatarColor *AvatarColor `protobuf:"varint,42,opt,name=avatarColor,proto3,enum=signalservice.AvatarColor,oneof" json:"avatarColor,omitempty"` + BackupTierHistory *AccountRecord_BackupTierHistory `protobuf:"bytes,43,opt,name=backupTierHistory,proto3" json:"backupTierHistory,omitempty"` + NotificationProfileManualOverride *AccountRecord_NotificationProfileManualOverride `protobuf:"bytes,44,opt,name=notificationProfileManualOverride,proto3" json:"notificationProfileManualOverride,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } func (x *AccountRecord) Reset() { @@ -1649,13 +1733,6 @@ func (x *AccountRecord) GetPrimarySendsSms() bool { return false } -func (x *AccountRecord) GetE164() string { - if x != nil { - return x.E164 - } - return "" -} - func (x *AccountRecord) GetPreferredReactionEmoji() []string { if x != nil { return x.PreferredReactionEmoji @@ -1782,6 +1859,20 @@ func (x *AccountRecord) GetAvatarColor() AvatarColor { return AvatarColor_A100 } +func (x *AccountRecord) GetBackupTierHistory() *AccountRecord_BackupTierHistory { + if x != nil { + return x.BackupTierHistory + } + return nil +} + +func (x *AccountRecord) GetNotificationProfileManualOverride() *AccountRecord_NotificationProfileManualOverride { + if x != nil { + return x.NotificationProfileManualOverride + } + return nil +} + type StoryDistributionListRecord struct { state protoimpl.MessageState `protogen:"open.v1"` Identifier []byte `protobuf:"bytes,1,opt,name=identifier,proto3" json:"identifier,omitempty"` @@ -1926,26 +2017,124 @@ func (x *CallLinkRecord) GetDeletedAtTimestampMs() uint64 { return 0 } +type Recipient struct { + state protoimpl.MessageState `protogen:"open.v1"` + // Types that are valid to be assigned to Identifier: + // + // *Recipient_Contact_ + // *Recipient_LegacyGroupId + // *Recipient_GroupMasterKey + Identifier isRecipient_Identifier `protobuf_oneof:"identifier"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *Recipient) Reset() { + *x = Recipient{} + mi := &file_StorageService_proto_msgTypes[14] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *Recipient) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Recipient) ProtoMessage() {} + +func (x *Recipient) ProtoReflect() protoreflect.Message { + mi := &file_StorageService_proto_msgTypes[14] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Recipient.ProtoReflect.Descriptor instead. +func (*Recipient) Descriptor() ([]byte, []int) { + return file_StorageService_proto_rawDescGZIP(), []int{14} +} + +func (x *Recipient) GetIdentifier() isRecipient_Identifier { + if x != nil { + return x.Identifier + } + return nil +} + +func (x *Recipient) GetContact() *Recipient_Contact { + if x != nil { + if x, ok := x.Identifier.(*Recipient_Contact_); ok { + return x.Contact + } + } + return nil +} + +func (x *Recipient) GetLegacyGroupId() []byte { + if x != nil { + if x, ok := x.Identifier.(*Recipient_LegacyGroupId); ok { + return x.LegacyGroupId + } + } + return nil +} + +func (x *Recipient) GetGroupMasterKey() []byte { + if x != nil { + if x, ok := x.Identifier.(*Recipient_GroupMasterKey); ok { + return x.GroupMasterKey + } + } + return nil +} + +type isRecipient_Identifier interface { + isRecipient_Identifier() +} + +type Recipient_Contact_ struct { + Contact *Recipient_Contact `protobuf:"bytes,1,opt,name=contact,proto3,oneof"` +} + +type Recipient_LegacyGroupId struct { + LegacyGroupId []byte `protobuf:"bytes,2,opt,name=legacyGroupId,proto3,oneof"` +} + +type Recipient_GroupMasterKey struct { + GroupMasterKey []byte `protobuf:"bytes,3,opt,name=groupMasterKey,proto3,oneof"` +} + +func (*Recipient_Contact_) isRecipient_Identifier() {} + +func (*Recipient_LegacyGroupId) isRecipient_Identifier() {} + +func (*Recipient_GroupMasterKey) isRecipient_Identifier() {} + type ChatFolderRecord struct { - state protoimpl.MessageState `protogen:"open.v1"` - Identifier []byte `protobuf:"bytes,1,opt,name=identifier,proto3" json:"identifier,omitempty"` - Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` - Position uint32 `protobuf:"varint,3,opt,name=position,proto3" json:"position,omitempty"` - ShowOnlyUnread bool `protobuf:"varint,4,opt,name=showOnlyUnread,proto3" json:"showOnlyUnread,omitempty"` - ShowMutedChats bool `protobuf:"varint,5,opt,name=showMutedChats,proto3" json:"showMutedChats,omitempty"` - IncludeAllIndividualChats bool `protobuf:"varint,6,opt,name=includeAllIndividualChats,proto3" json:"includeAllIndividualChats,omitempty"` // Folder includes all 1:1 chats, unless excluded - IncludeAllGroupChats bool `protobuf:"varint,7,opt,name=includeAllGroupChats,proto3" json:"includeAllGroupChats,omitempty"` // Folder includes all group chats, unless excluded - FolderType ChatFolderRecord_FolderType `protobuf:"varint,8,opt,name=folderType,proto3,enum=signalservice.ChatFolderRecord_FolderType" json:"folderType,omitempty"` - IncludedRecipients []*ChatFolderRecord_Recipient `protobuf:"bytes,9,rep,name=includedRecipients,proto3" json:"includedRecipients,omitempty"` - ExcludedRecipients []*ChatFolderRecord_Recipient `protobuf:"bytes,10,rep,name=excludedRecipients,proto3" json:"excludedRecipients,omitempty"` - DeletedAtTimestampMs uint64 `protobuf:"varint,11,opt,name=deletedAtTimestampMs,proto3" json:"deletedAtTimestampMs,omitempty"` // When non-zero, `position` should be set to -1 and includedRecipients should be empty + state protoimpl.MessageState `protogen:"open.v1"` + Identifier []byte `protobuf:"bytes,1,opt,name=identifier,proto3" json:"identifier,omitempty"` + Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` + Position uint32 `protobuf:"varint,3,opt,name=position,proto3" json:"position,omitempty"` + ShowOnlyUnread bool `protobuf:"varint,4,opt,name=showOnlyUnread,proto3" json:"showOnlyUnread,omitempty"` + ShowMutedChats bool `protobuf:"varint,5,opt,name=showMutedChats,proto3" json:"showMutedChats,omitempty"` + IncludeAllIndividualChats bool `protobuf:"varint,6,opt,name=includeAllIndividualChats,proto3" json:"includeAllIndividualChats,omitempty"` // Folder includes all 1:1 chats, unless excluded + IncludeAllGroupChats bool `protobuf:"varint,7,opt,name=includeAllGroupChats,proto3" json:"includeAllGroupChats,omitempty"` // Folder includes all group chats, unless excluded + FolderType ChatFolderRecord_FolderType `protobuf:"varint,8,opt,name=folderType,proto3,enum=signalservice.ChatFolderRecord_FolderType" json:"folderType,omitempty"` + IncludedRecipients []*Recipient `protobuf:"bytes,9,rep,name=includedRecipients,proto3" json:"includedRecipients,omitempty"` + ExcludedRecipients []*Recipient `protobuf:"bytes,10,rep,name=excludedRecipients,proto3" json:"excludedRecipients,omitempty"` + DeletedAtTimestampMs uint64 `protobuf:"varint,11,opt,name=deletedAtTimestampMs,proto3" json:"deletedAtTimestampMs,omitempty"` // When non-zero, `position` should be set to -1 and includedRecipients should be empty unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } func (x *ChatFolderRecord) Reset() { *x = ChatFolderRecord{} - mi := &file_StorageService_proto_msgTypes[14] + mi := &file_StorageService_proto_msgTypes[15] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1957,7 +2146,7 @@ func (x *ChatFolderRecord) String() string { func (*ChatFolderRecord) ProtoMessage() {} func (x *ChatFolderRecord) ProtoReflect() protoreflect.Message { - mi := &file_StorageService_proto_msgTypes[14] + mi := &file_StorageService_proto_msgTypes[15] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1970,7 +2159,7 @@ func (x *ChatFolderRecord) ProtoReflect() protoreflect.Message { // Deprecated: Use ChatFolderRecord.ProtoReflect.Descriptor instead. func (*ChatFolderRecord) Descriptor() ([]byte, []int) { - return file_StorageService_proto_rawDescGZIP(), []int{14} + return file_StorageService_proto_rawDescGZIP(), []int{15} } func (x *ChatFolderRecord) GetIdentifier() []byte { @@ -2029,14 +2218,14 @@ func (x *ChatFolderRecord) GetFolderType() ChatFolderRecord_FolderType { return ChatFolderRecord_UNKNOWN } -func (x *ChatFolderRecord) GetIncludedRecipients() []*ChatFolderRecord_Recipient { +func (x *ChatFolderRecord) GetIncludedRecipients() []*Recipient { if x != nil { return x.IncludedRecipients } return nil } -func (x *ChatFolderRecord) GetExcludedRecipients() []*ChatFolderRecord_Recipient { +func (x *ChatFolderRecord) GetExcludedRecipients() []*Recipient { if x != nil { return x.ExcludedRecipients } @@ -2050,6 +2239,146 @@ func (x *ChatFolderRecord) GetDeletedAtTimestampMs() uint64 { return 0 } +type NotificationProfile struct { + state protoimpl.MessageState `protogen:"open.v1"` + Id []byte `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` + Emoji *string `protobuf:"bytes,3,opt,name=emoji,proto3,oneof" json:"emoji,omitempty"` + Color uint32 `protobuf:"fixed32,4,opt,name=color,proto3" json:"color,omitempty"` // 0xAARRGGBB + CreatedAtMs uint64 `protobuf:"varint,5,opt,name=createdAtMs,proto3" json:"createdAtMs,omitempty"` + AllowAllCalls bool `protobuf:"varint,6,opt,name=allowAllCalls,proto3" json:"allowAllCalls,omitempty"` + AllowAllMentions bool `protobuf:"varint,7,opt,name=allowAllMentions,proto3" json:"allowAllMentions,omitempty"` + AllowedMembers []*Recipient `protobuf:"bytes,8,rep,name=allowedMembers,proto3" json:"allowedMembers,omitempty"` + ScheduleEnabled bool `protobuf:"varint,9,opt,name=scheduleEnabled,proto3" json:"scheduleEnabled,omitempty"` + ScheduleStartTime uint32 `protobuf:"varint,10,opt,name=scheduleStartTime,proto3" json:"scheduleStartTime,omitempty"` // 24-hour clock int, 0000-2359 (e.g., 15, 900, 1130, 2345) + ScheduleEndTime uint32 `protobuf:"varint,11,opt,name=scheduleEndTime,proto3" json:"scheduleEndTime,omitempty"` // 24-hour clock int, 0000-2359 (e.g., 15, 900, 1130, 2345) + ScheduleDaysEnabled []NotificationProfile_DayOfWeek `protobuf:"varint,12,rep,packed,name=scheduleDaysEnabled,proto3,enum=signalservice.NotificationProfile_DayOfWeek" json:"scheduleDaysEnabled,omitempty"` + DeletedAtTimestampMs uint64 `protobuf:"varint,13,opt,name=deletedAtTimestampMs,proto3" json:"deletedAtTimestampMs,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *NotificationProfile) Reset() { + *x = NotificationProfile{} + mi := &file_StorageService_proto_msgTypes[16] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *NotificationProfile) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*NotificationProfile) ProtoMessage() {} + +func (x *NotificationProfile) ProtoReflect() protoreflect.Message { + mi := &file_StorageService_proto_msgTypes[16] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use NotificationProfile.ProtoReflect.Descriptor instead. +func (*NotificationProfile) Descriptor() ([]byte, []int) { + return file_StorageService_proto_rawDescGZIP(), []int{16} +} + +func (x *NotificationProfile) GetId() []byte { + if x != nil { + return x.Id + } + return nil +} + +func (x *NotificationProfile) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *NotificationProfile) GetEmoji() string { + if x != nil && x.Emoji != nil { + return *x.Emoji + } + return "" +} + +func (x *NotificationProfile) GetColor() uint32 { + if x != nil { + return x.Color + } + return 0 +} + +func (x *NotificationProfile) GetCreatedAtMs() uint64 { + if x != nil { + return x.CreatedAtMs + } + return 0 +} + +func (x *NotificationProfile) GetAllowAllCalls() bool { + if x != nil { + return x.AllowAllCalls + } + return false +} + +func (x *NotificationProfile) GetAllowAllMentions() bool { + if x != nil { + return x.AllowAllMentions + } + return false +} + +func (x *NotificationProfile) GetAllowedMembers() []*Recipient { + if x != nil { + return x.AllowedMembers + } + return nil +} + +func (x *NotificationProfile) GetScheduleEnabled() bool { + if x != nil { + return x.ScheduleEnabled + } + return false +} + +func (x *NotificationProfile) GetScheduleStartTime() uint32 { + if x != nil { + return x.ScheduleStartTime + } + return 0 +} + +func (x *NotificationProfile) GetScheduleEndTime() uint32 { + if x != nil { + return x.ScheduleEndTime + } + return 0 +} + +func (x *NotificationProfile) GetScheduleDaysEnabled() []NotificationProfile_DayOfWeek { + if x != nil { + return x.ScheduleDaysEnabled + } + return nil +} + +func (x *NotificationProfile) GetDeletedAtTimestampMs() uint64 { + if x != nil { + return x.DeletedAtTimestampMs + } + return 0 +} + type ManifestRecord_Identifier struct { state protoimpl.MessageState `protogen:"open.v1"` Raw []byte `protobuf:"bytes,1,opt,name=raw,proto3" json:"raw,omitempty"` @@ -2060,7 +2389,7 @@ type ManifestRecord_Identifier struct { func (x *ManifestRecord_Identifier) Reset() { *x = ManifestRecord_Identifier{} - mi := &file_StorageService_proto_msgTypes[15] + mi := &file_StorageService_proto_msgTypes[17] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2072,7 +2401,7 @@ func (x *ManifestRecord_Identifier) String() string { func (*ManifestRecord_Identifier) ProtoMessage() {} func (x *ManifestRecord_Identifier) ProtoReflect() protoreflect.Message { - mi := &file_StorageService_proto_msgTypes[15] + mi := &file_StorageService_proto_msgTypes[17] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2112,7 +2441,7 @@ type ContactRecord_Name struct { func (x *ContactRecord_Name) Reset() { *x = ContactRecord_Name{} - mi := &file_StorageService_proto_msgTypes[16] + mi := &file_StorageService_proto_msgTypes[18] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2124,7 +2453,7 @@ func (x *ContactRecord_Name) String() string { func (*ContactRecord_Name) ProtoMessage() {} func (x *ContactRecord_Name) ProtoReflect() protoreflect.Message { - mi := &file_StorageService_proto_msgTypes[16] + mi := &file_StorageService_proto_msgTypes[18] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2168,7 +2497,7 @@ type AccountRecord_PinnedConversation struct { func (x *AccountRecord_PinnedConversation) Reset() { *x = AccountRecord_PinnedConversation{} - mi := &file_StorageService_proto_msgTypes[17] + mi := &file_StorageService_proto_msgTypes[19] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2180,7 +2509,7 @@ func (x *AccountRecord_PinnedConversation) String() string { func (*AccountRecord_PinnedConversation) ProtoMessage() {} func (x *AccountRecord_PinnedConversation) ProtoReflect() protoreflect.Message { - mi := &file_StorageService_proto_msgTypes[17] + mi := &file_StorageService_proto_msgTypes[19] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2265,7 +2594,7 @@ type AccountRecord_UsernameLink struct { func (x *AccountRecord_UsernameLink) Reset() { *x = AccountRecord_UsernameLink{} - mi := &file_StorageService_proto_msgTypes[18] + mi := &file_StorageService_proto_msgTypes[20] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2277,7 +2606,7 @@ func (x *AccountRecord_UsernameLink) String() string { func (*AccountRecord_UsernameLink) ProtoMessage() {} func (x *AccountRecord_UsernameLink) ProtoReflect() protoreflect.Message { - mi := &file_StorageService_proto_msgTypes[18] + mi := &file_StorageService_proto_msgTypes[20] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2328,7 +2657,7 @@ type AccountRecord_IAPSubscriberData struct { func (x *AccountRecord_IAPSubscriberData) Reset() { *x = AccountRecord_IAPSubscriberData{} - mi := &file_StorageService_proto_msgTypes[19] + mi := &file_StorageService_proto_msgTypes[21] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2340,7 +2669,7 @@ func (x *AccountRecord_IAPSubscriberData) String() string { func (*AccountRecord_IAPSubscriberData) ProtoMessage() {} func (x *AccountRecord_IAPSubscriberData) ProtoReflect() protoreflect.Message { - mi := &file_StorageService_proto_msgTypes[19] + mi := &file_StorageService_proto_msgTypes[21] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2408,6 +2737,143 @@ func (*AccountRecord_IAPSubscriberData_PurchaseToken) isAccountRecord_IAPSubscri func (*AccountRecord_IAPSubscriberData_OriginalTransactionId) isAccountRecord_IAPSubscriberData_IapSubscriptionId() { } +type AccountRecord_BackupTierHistory struct { + state protoimpl.MessageState `protogen:"open.v1"` + // See zkgroup for integer particular values. Unset if backups are not enabled. + BackupTier *uint64 `protobuf:"varint,1,opt,name=backupTier,proto3,oneof" json:"backupTier,omitempty"` + EndedAtTimestamp *uint64 `protobuf:"varint,2,opt,name=endedAtTimestamp,proto3,oneof" json:"endedAtTimestamp,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *AccountRecord_BackupTierHistory) Reset() { + *x = AccountRecord_BackupTierHistory{} + mi := &file_StorageService_proto_msgTypes[22] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *AccountRecord_BackupTierHistory) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*AccountRecord_BackupTierHistory) ProtoMessage() {} + +func (x *AccountRecord_BackupTierHistory) ProtoReflect() protoreflect.Message { + mi := &file_StorageService_proto_msgTypes[22] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use AccountRecord_BackupTierHistory.ProtoReflect.Descriptor instead. +func (*AccountRecord_BackupTierHistory) Descriptor() ([]byte, []int) { + return file_StorageService_proto_rawDescGZIP(), []int{11, 3} +} + +func (x *AccountRecord_BackupTierHistory) GetBackupTier() uint64 { + if x != nil && x.BackupTier != nil { + return *x.BackupTier + } + return 0 +} + +func (x *AccountRecord_BackupTierHistory) GetEndedAtTimestamp() uint64 { + if x != nil && x.EndedAtTimestamp != nil { + return *x.EndedAtTimestamp + } + return 0 +} + +type AccountRecord_NotificationProfileManualOverride struct { + state protoimpl.MessageState `protogen:"open.v1"` + // Types that are valid to be assigned to Override: + // + // *AccountRecord_NotificationProfileManualOverride_DisabledAtTimestampMs + // *AccountRecord_NotificationProfileManualOverride_Enabled + Override isAccountRecord_NotificationProfileManualOverride_Override `protobuf_oneof:"override"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *AccountRecord_NotificationProfileManualOverride) Reset() { + *x = AccountRecord_NotificationProfileManualOverride{} + mi := &file_StorageService_proto_msgTypes[23] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *AccountRecord_NotificationProfileManualOverride) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*AccountRecord_NotificationProfileManualOverride) ProtoMessage() {} + +func (x *AccountRecord_NotificationProfileManualOverride) ProtoReflect() protoreflect.Message { + mi := &file_StorageService_proto_msgTypes[23] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use AccountRecord_NotificationProfileManualOverride.ProtoReflect.Descriptor instead. +func (*AccountRecord_NotificationProfileManualOverride) Descriptor() ([]byte, []int) { + return file_StorageService_proto_rawDescGZIP(), []int{11, 4} +} + +func (x *AccountRecord_NotificationProfileManualOverride) GetOverride() isAccountRecord_NotificationProfileManualOverride_Override { + if x != nil { + return x.Override + } + return nil +} + +func (x *AccountRecord_NotificationProfileManualOverride) GetDisabledAtTimestampMs() uint64 { + if x != nil { + if x, ok := x.Override.(*AccountRecord_NotificationProfileManualOverride_DisabledAtTimestampMs); ok { + return x.DisabledAtTimestampMs + } + } + return 0 +} + +func (x *AccountRecord_NotificationProfileManualOverride) GetEnabled() *AccountRecord_NotificationProfileManualOverride_ManuallyEnabled { + if x != nil { + if x, ok := x.Override.(*AccountRecord_NotificationProfileManualOverride_Enabled); ok { + return x.Enabled + } + } + return nil +} + +type isAccountRecord_NotificationProfileManualOverride_Override interface { + isAccountRecord_NotificationProfileManualOverride_Override() +} + +type AccountRecord_NotificationProfileManualOverride_DisabledAtTimestampMs struct { + DisabledAtTimestampMs uint64 `protobuf:"varint,1,opt,name=disabledAtTimestampMs,proto3,oneof"` +} + +type AccountRecord_NotificationProfileManualOverride_Enabled struct { + Enabled *AccountRecord_NotificationProfileManualOverride_ManuallyEnabled `protobuf:"bytes,2,opt,name=enabled,proto3,oneof"` +} + +func (*AccountRecord_NotificationProfileManualOverride_DisabledAtTimestampMs) isAccountRecord_NotificationProfileManualOverride_Override() { +} + +func (*AccountRecord_NotificationProfileManualOverride_Enabled) isAccountRecord_NotificationProfileManualOverride_Override() { +} + type AccountRecord_PinnedConversation_Contact struct { state protoimpl.MessageState `protogen:"open.v1"` ServiceId string `protobuf:"bytes,1,opt,name=serviceId,proto3" json:"serviceId,omitempty"` @@ -2418,7 +2884,7 @@ type AccountRecord_PinnedConversation_Contact struct { func (x *AccountRecord_PinnedConversation_Contact) Reset() { *x = AccountRecord_PinnedConversation_Contact{} - mi := &file_StorageService_proto_msgTypes[20] + mi := &file_StorageService_proto_msgTypes[24] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2430,7 +2896,7 @@ func (x *AccountRecord_PinnedConversation_Contact) String() string { func (*AccountRecord_PinnedConversation_Contact) ProtoMessage() {} func (x *AccountRecord_PinnedConversation_Contact) ProtoReflect() protoreflect.Message { - mi := &file_StorageService_proto_msgTypes[20] + mi := &file_StorageService_proto_msgTypes[24] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2460,33 +2926,30 @@ func (x *AccountRecord_PinnedConversation_Contact) GetE164() string { return "" } -type ChatFolderRecord_Recipient struct { +type AccountRecord_NotificationProfileManualOverride_ManuallyEnabled struct { state protoimpl.MessageState `protogen:"open.v1"` - // Types that are valid to be assigned to Identifier: - // - // *ChatFolderRecord_Recipient_Contact_ - // *ChatFolderRecord_Recipient_LegacyGroupId - // *ChatFolderRecord_Recipient_GroupMasterKey - Identifier isChatFolderRecord_Recipient_Identifier `protobuf_oneof:"identifier"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache + Id []byte `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + // This will be unset if no timespan was chosen in the UI. + EndAtTimestampMs uint64 `protobuf:"varint,3,opt,name=endAtTimestampMs,proto3" json:"endAtTimestampMs,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } -func (x *ChatFolderRecord_Recipient) Reset() { - *x = ChatFolderRecord_Recipient{} - mi := &file_StorageService_proto_msgTypes[21] +func (x *AccountRecord_NotificationProfileManualOverride_ManuallyEnabled) Reset() { + *x = AccountRecord_NotificationProfileManualOverride_ManuallyEnabled{} + mi := &file_StorageService_proto_msgTypes[25] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } -func (x *ChatFolderRecord_Recipient) String() string { +func (x *AccountRecord_NotificationProfileManualOverride_ManuallyEnabled) String() string { return protoimpl.X.MessageStringOf(x) } -func (*ChatFolderRecord_Recipient) ProtoMessage() {} +func (*AccountRecord_NotificationProfileManualOverride_ManuallyEnabled) ProtoMessage() {} -func (x *ChatFolderRecord_Recipient) ProtoReflect() protoreflect.Message { - mi := &file_StorageService_proto_msgTypes[21] +func (x *AccountRecord_NotificationProfileManualOverride_ManuallyEnabled) ProtoReflect() protoreflect.Message { + mi := &file_StorageService_proto_msgTypes[25] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2497,68 +2960,26 @@ func (x *ChatFolderRecord_Recipient) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use ChatFolderRecord_Recipient.ProtoReflect.Descriptor instead. -func (*ChatFolderRecord_Recipient) Descriptor() ([]byte, []int) { - return file_StorageService_proto_rawDescGZIP(), []int{14, 0} +// Deprecated: Use AccountRecord_NotificationProfileManualOverride_ManuallyEnabled.ProtoReflect.Descriptor instead. +func (*AccountRecord_NotificationProfileManualOverride_ManuallyEnabled) Descriptor() ([]byte, []int) { + return file_StorageService_proto_rawDescGZIP(), []int{11, 4, 0} } -func (x *ChatFolderRecord_Recipient) GetIdentifier() isChatFolderRecord_Recipient_Identifier { +func (x *AccountRecord_NotificationProfileManualOverride_ManuallyEnabled) GetId() []byte { if x != nil { - return x.Identifier + return x.Id } return nil } -func (x *ChatFolderRecord_Recipient) GetContact() *ChatFolderRecord_Recipient_Contact { +func (x *AccountRecord_NotificationProfileManualOverride_ManuallyEnabled) GetEndAtTimestampMs() uint64 { if x != nil { - if x, ok := x.Identifier.(*ChatFolderRecord_Recipient_Contact_); ok { - return x.Contact - } + return x.EndAtTimestampMs } - return nil + return 0 } -func (x *ChatFolderRecord_Recipient) GetLegacyGroupId() []byte { - if x != nil { - if x, ok := x.Identifier.(*ChatFolderRecord_Recipient_LegacyGroupId); ok { - return x.LegacyGroupId - } - } - return nil -} - -func (x *ChatFolderRecord_Recipient) GetGroupMasterKey() []byte { - if x != nil { - if x, ok := x.Identifier.(*ChatFolderRecord_Recipient_GroupMasterKey); ok { - return x.GroupMasterKey - } - } - return nil -} - -type isChatFolderRecord_Recipient_Identifier interface { - isChatFolderRecord_Recipient_Identifier() -} - -type ChatFolderRecord_Recipient_Contact_ struct { - Contact *ChatFolderRecord_Recipient_Contact `protobuf:"bytes,1,opt,name=contact,proto3,oneof"` -} - -type ChatFolderRecord_Recipient_LegacyGroupId struct { - LegacyGroupId []byte `protobuf:"bytes,2,opt,name=legacyGroupId,proto3,oneof"` -} - -type ChatFolderRecord_Recipient_GroupMasterKey struct { - GroupMasterKey []byte `protobuf:"bytes,3,opt,name=groupMasterKey,proto3,oneof"` -} - -func (*ChatFolderRecord_Recipient_Contact_) isChatFolderRecord_Recipient_Identifier() {} - -func (*ChatFolderRecord_Recipient_LegacyGroupId) isChatFolderRecord_Recipient_Identifier() {} - -func (*ChatFolderRecord_Recipient_GroupMasterKey) isChatFolderRecord_Recipient_Identifier() {} - -type ChatFolderRecord_Recipient_Contact struct { +type Recipient_Contact struct { state protoimpl.MessageState `protogen:"open.v1"` ServiceId string `protobuf:"bytes,1,opt,name=serviceId,proto3" json:"serviceId,omitempty"` E164 string `protobuf:"bytes,2,opt,name=e164,proto3" json:"e164,omitempty"` @@ -2566,21 +2987,21 @@ type ChatFolderRecord_Recipient_Contact struct { sizeCache protoimpl.SizeCache } -func (x *ChatFolderRecord_Recipient_Contact) Reset() { - *x = ChatFolderRecord_Recipient_Contact{} - mi := &file_StorageService_proto_msgTypes[22] +func (x *Recipient_Contact) Reset() { + *x = Recipient_Contact{} + mi := &file_StorageService_proto_msgTypes[26] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } -func (x *ChatFolderRecord_Recipient_Contact) String() string { +func (x *Recipient_Contact) String() string { return protoimpl.X.MessageStringOf(x) } -func (*ChatFolderRecord_Recipient_Contact) ProtoMessage() {} +func (*Recipient_Contact) ProtoMessage() {} -func (x *ChatFolderRecord_Recipient_Contact) ProtoReflect() protoreflect.Message { - mi := &file_StorageService_proto_msgTypes[22] +func (x *Recipient_Contact) ProtoReflect() protoreflect.Message { + mi := &file_StorageService_proto_msgTypes[26] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2591,19 +3012,19 @@ func (x *ChatFolderRecord_Recipient_Contact) ProtoReflect() protoreflect.Message return mi.MessageOf(x) } -// Deprecated: Use ChatFolderRecord_Recipient_Contact.ProtoReflect.Descriptor instead. -func (*ChatFolderRecord_Recipient_Contact) Descriptor() ([]byte, []int) { - return file_StorageService_proto_rawDescGZIP(), []int{14, 0, 0} +// Deprecated: Use Recipient_Contact.ProtoReflect.Descriptor instead. +func (*Recipient_Contact) Descriptor() ([]byte, []int) { + return file_StorageService_proto_rawDescGZIP(), []int{14, 0} } -func (x *ChatFolderRecord_Recipient_Contact) GetServiceId() string { +func (x *Recipient_Contact) GetServiceId() string { if x != nil { return x.ServiceId } return "" } -func (x *ChatFolderRecord_Recipient_Contact) GetE164() string { +func (x *Recipient_Contact) GetE164() string { if x != nil { return x.E164 } @@ -2631,16 +3052,16 @@ const file_StorageService_proto_rawDesc = "" + "insertItem\x18\x02 \x03(\v2\x1a.signalservice.StorageItemR\n" + "insertItem\x12\x1c\n" + "\tdeleteKey\x18\x03 \x03(\fR\tdeleteKey\x12\x1a\n" + - "\bclearAll\x18\x04 \x01(\bR\bclearAll\"\xa3\x03\n" + + "\bclearAll\x18\x04 \x01(\bR\bclearAll\"\xbd\x03\n" + "\x0eManifestRecord\x12\x18\n" + "\aversion\x18\x01 \x01(\x04R\aversion\x12\"\n" + "\fsourceDevice\x18\x03 \x01(\rR\fsourceDevice\x12J\n" + "\videntifiers\x18\x02 \x03(\v2(.signalservice.ManifestRecord.IdentifierR\videntifiers\x12\x1c\n" + - "\trecordIkm\x18\x04 \x01(\fR\trecordIkm\x1a\xe8\x01\n" + + "\trecordIkm\x18\x04 \x01(\fR\trecordIkm\x1a\x82\x02\n" + "\n" + "Identifier\x12\x10\n" + "\x03raw\x18\x01 \x01(\fR\x03raw\x12A\n" + - "\x04type\x18\x02 \x01(\x0e2-.signalservice.ManifestRecord.Identifier.TypeR\x04type\"\x84\x01\n" + + "\x04type\x18\x02 \x01(\x0e2-.signalservice.ManifestRecord.Identifier.TypeR\x04type\"\x9e\x01\n" + "\x04Type\x12\v\n" + "\aUNKNOWN\x10\x00\x12\v\n" + "\aCONTACT\x10\x01\x12\v\n" + @@ -2649,7 +3070,8 @@ const file_StorageService_proto_rawDesc = "" + "\aACCOUNT\x10\x04\x12\x1b\n" + "\x17STORY_DISTRIBUTION_LIST\x10\x05\x12\r\n" + "\tCALL_LINK\x10\a\x12\x0f\n" + - "\vCHAT_FOLDER\x10\b\"\xe5\x03\n" + + "\vCHAT_FOLDER\x10\b\x12\x18\n" + + "\x14NOTIFICATION_PROFILE\x10\t\"\xbd\x04\n" + "\rStorageRecord\x128\n" + "\acontact\x18\x01 \x01(\v2\x1c.signalservice.ContactRecordH\x00R\acontact\x128\n" + "\agroupV1\x18\x02 \x01(\v2\x1c.signalservice.GroupV1RecordH\x00R\agroupV1\x128\n" + @@ -2659,7 +3081,8 @@ const file_StorageService_proto_rawDesc = "" + "\bcallLink\x18\a \x01(\v2\x1d.signalservice.CallLinkRecordH\x00R\bcallLink\x12A\n" + "\n" + "chatFolder\x18\b \x01(\v2\x1f.signalservice.ChatFolderRecordH\x00R\n" + - "chatFolderB\b\n" + + "chatFolder\x12V\n" + + "\x13notificationProfile\x18\t \x01(\v2\".signalservice.NotificationProfileH\x00R\x13notificationProfileB\b\n" + "\x06record\"\x9d\b\n" + "\rContactRecord\x12\x10\n" + "\x03aci\x18\x01 \x01(\tR\x03aci\x12\x12\n" + @@ -2727,7 +3150,7 @@ const file_StorageService_proto_rawDesc = "" + "\">\n" + "\bPayments\x12\x18\n" + "\aenabled\x18\x01 \x01(\bR\aenabled\x12\x18\n" + - "\aentropy\x18\x02 \x01(\fR\aentropy\"\xf7\x15\n" + + "\aentropy\x18\x02 \x01(\fR\aentropy\"\x8b\x1b\n" + "\rAccountRecord\x12\x1e\n" + "\n" + "profileKey\x18\x01 \x01(\fR\n" + @@ -2750,8 +3173,7 @@ const file_StorageService_proto_rawDesc = "" + "\x14preferContactAvatars\x18\x0f \x01(\bR\x14preferContactAvatars\x123\n" + "\bpayments\x18\x10 \x01(\v2\x17.signalservice.PaymentsR\bpayments\x122\n" + "\x14universalExpireTimer\x18\x11 \x01(\rR\x14universalExpireTimer\x12(\n" + - "\x0fprimarySendsSms\x18\x12 \x01(\bR\x0fprimarySendsSms\x12\x12\n" + - "\x04e164\x18\x13 \x01(\tR\x04e164\x126\n" + + "\x0fprimarySendsSms\x18\x12 \x01(\bR\x0fprimarySendsSms\x126\n" + "\x16preferredReactionEmoji\x18\x14 \x03(\tR\x16preferredReactionEmoji\x12\"\n" + "\fsubscriberId\x18\x15 \x01(\fR\fsubscriberId\x126\n" + "\x16subscriberCurrencyCode\x18\x16 \x01(\tR\x16subscriberCurrencyCode\x126\n" + @@ -2771,7 +3193,9 @@ const file_StorageService_proto_rawDesc = "" + "backupTier\x18( \x01(\x04H\x01R\n" + "backupTier\x88\x01\x01\x12b\n" + "\x14backupSubscriberData\x18) \x01(\v2..signalservice.AccountRecord.IAPSubscriberDataR\x14backupSubscriberData\x12A\n" + - "\vavatarColor\x18* \x01(\x0e2\x1a.signalservice.AvatarColorH\x02R\vavatarColor\x88\x01\x01\x1a\x86\x02\n" + + "\vavatarColor\x18* \x01(\x0e2\x1a.signalservice.AvatarColorH\x02R\vavatarColor\x88\x01\x01\x12\\\n" + + "\x11backupTierHistory\x18+ \x01(\v2..signalservice.AccountRecord.BackupTierHistoryR\x11backupTierHistory\x12\x8c\x01\n" + + "!notificationProfileManualOverride\x18, \x01(\v2>.signalservice.AccountRecord.NotificationProfileManualOverrideR!notificationProfileManualOverride\x1a\x86\x02\n" + "\x12PinnedConversation\x12S\n" + "\acontact\x18\x01 \x01(\v27.signalservice.AccountRecord.PinnedConversation.ContactH\x00R\acontact\x12&\n" + "\rlegacyGroupId\x18\x03 \x01(\fH\x00R\rlegacyGroupId\x12(\n" + @@ -2801,7 +3225,22 @@ const file_StorageService_proto_rawDesc = "" + "\fsubscriberId\x18\x01 \x01(\fR\fsubscriberId\x12&\n" + "\rpurchaseToken\x18\x02 \x01(\tH\x00R\rpurchaseToken\x126\n" + "\x15originalTransactionId\x18\x03 \x01(\x04H\x00R\x15originalTransactionIdB\x13\n" + - "\x11iapSubscriptionId\"@\n" + + "\x11iapSubscriptionId\x1a\x8d\x01\n" + + "\x11BackupTierHistory\x12#\n" + + "\n" + + "backupTier\x18\x01 \x01(\x04H\x00R\n" + + "backupTier\x88\x01\x01\x12/\n" + + "\x10endedAtTimestamp\x18\x02 \x01(\x04H\x01R\x10endedAtTimestamp\x88\x01\x01B\r\n" + + "\v_backupTierB\x13\n" + + "\x11_endedAtTimestamp\x1a\xa2\x02\n" + + "!NotificationProfileManualOverride\x126\n" + + "\x15disabledAtTimestampMs\x18\x01 \x01(\x04H\x00R\x15disabledAtTimestampMs\x12j\n" + + "\aenabled\x18\x02 \x01(\v2N.signalservice.AccountRecord.NotificationProfileManualOverride.ManuallyEnabledH\x00R\aenabled\x1aM\n" + + "\x0fManuallyEnabled\x12\x0e\n" + + "\x02id\x18\x01 \x01(\fR\x02id\x12*\n" + + "\x10endAtTimestampMs\x18\x03 \x01(\x04R\x10endAtTimestampMsB\n" + + "\n" + + "\boverride\"@\n" + "\x16PhoneNumberSharingMode\x12\v\n" + "\aUNKNOWN\x10\x00\x12\r\n" + "\tEVERYBODY\x10\x01\x12\n" + @@ -2811,7 +3250,7 @@ const file_StorageService_proto_rawDesc = "" + "_hasBackupB\r\n" + "\v_backupTierB\x0e\n" + "\f_avatarColorJ\x04\b\t\x10\n" + - "J\x04\b\x1c\x10\x1dJ\x04\b\x1f\x10 J\x04\b$\x10%J\x04\b%\x10&J\x04\b&\x10'\"\xfb\x01\n" + + "J\x04\b\x13\x10\x14J\x04\b\x1c\x10\x1dJ\x04\b\x1f\x10 J\x04\b$\x10%J\x04\b%\x10&J\x04\b&\x10'\"\xfb\x01\n" + "\x1bStoryDistributionListRecord\x12\x1e\n" + "\n" + "identifier\x18\x01 \x01(\fR\n" + @@ -2824,7 +3263,16 @@ const file_StorageService_proto_rawDesc = "" + "\x0eCallLinkRecord\x12\x18\n" + "\arootKey\x18\x01 \x01(\fR\arootKey\x12\"\n" + "\fadminPasskey\x18\x02 \x01(\fR\fadminPasskey\x122\n" + - "\x14deletedAtTimestampMs\x18\x03 \x01(\x04R\x14deletedAtTimestampMs\"\x84\a\n" + + "\x14deletedAtTimestampMs\x18\x03 \x01(\x04R\x14deletedAtTimestampMs\"\xe6\x01\n" + + "\tRecipient\x12<\n" + + "\acontact\x18\x01 \x01(\v2 .signalservice.Recipient.ContactH\x00R\acontact\x12&\n" + + "\rlegacyGroupId\x18\x02 \x01(\fH\x00R\rlegacyGroupId\x12(\n" + + "\x0egroupMasterKey\x18\x03 \x01(\fH\x00R\x0egroupMasterKey\x1a;\n" + + "\aContact\x12\x1c\n" + + "\tserviceId\x18\x01 \x01(\tR\tserviceId\x12\x12\n" + + "\x04e164\x18\x02 \x01(\tR\x04e164B\f\n" + + "\n" + + "identifier\"\xe8\x04\n" + "\x10ChatFolderRecord\x12\x1e\n" + "\n" + "identifier\x18\x01 \x01(\fR\n" + @@ -2837,26 +3285,45 @@ const file_StorageService_proto_rawDesc = "" + "\x14includeAllGroupChats\x18\a \x01(\bR\x14includeAllGroupChats\x12J\n" + "\n" + "folderType\x18\b \x01(\x0e2*.signalservice.ChatFolderRecord.FolderTypeR\n" + - "folderType\x12Y\n" + - "\x12includedRecipients\x18\t \x03(\v2).signalservice.ChatFolderRecord.RecipientR\x12includedRecipients\x12Y\n" + + "folderType\x12H\n" + + "\x12includedRecipients\x18\t \x03(\v2\x18.signalservice.RecipientR\x12includedRecipients\x12H\n" + "\x12excludedRecipients\x18\n" + - " \x03(\v2).signalservice.ChatFolderRecord.RecipientR\x12excludedRecipients\x122\n" + - "\x14deletedAtTimestampMs\x18\v \x01(\x04R\x14deletedAtTimestampMs\x1a\xf7\x01\n" + - "\tRecipient\x12M\n" + - "\acontact\x18\x01 \x01(\v21.signalservice.ChatFolderRecord.Recipient.ContactH\x00R\acontact\x12&\n" + - "\rlegacyGroupId\x18\x02 \x01(\fH\x00R\rlegacyGroupId\x12(\n" + - "\x0egroupMasterKey\x18\x03 \x01(\fH\x00R\x0egroupMasterKey\x1a;\n" + - "\aContact\x12\x1c\n" + - "\tserviceId\x18\x01 \x01(\tR\tserviceId\x12\x12\n" + - "\x04e164\x18\x02 \x01(\tR\x04e164B\f\n" + - "\n" + - "identifier\".\n" + + " \x03(\v2\x18.signalservice.RecipientR\x12excludedRecipients\x122\n" + + "\x14deletedAtTimestampMs\x18\v \x01(\x04R\x14deletedAtTimestampMs\".\n" + "\n" + "FolderType\x12\v\n" + "\aUNKNOWN\x10\x00\x12\a\n" + "\x03ALL\x10\x01\x12\n" + "\n" + - "\x06CUSTOM\x10\x02*4\n" + + "\x06CUSTOM\x10\x02\"\xb6\x05\n" + + "\x13NotificationProfile\x12\x0e\n" + + "\x02id\x18\x01 \x01(\fR\x02id\x12\x12\n" + + "\x04name\x18\x02 \x01(\tR\x04name\x12\x19\n" + + "\x05emoji\x18\x03 \x01(\tH\x00R\x05emoji\x88\x01\x01\x12\x14\n" + + "\x05color\x18\x04 \x01(\aR\x05color\x12 \n" + + "\vcreatedAtMs\x18\x05 \x01(\x04R\vcreatedAtMs\x12$\n" + + "\rallowAllCalls\x18\x06 \x01(\bR\rallowAllCalls\x12*\n" + + "\x10allowAllMentions\x18\a \x01(\bR\x10allowAllMentions\x12@\n" + + "\x0eallowedMembers\x18\b \x03(\v2\x18.signalservice.RecipientR\x0eallowedMembers\x12(\n" + + "\x0fscheduleEnabled\x18\t \x01(\bR\x0fscheduleEnabled\x12,\n" + + "\x11scheduleStartTime\x18\n" + + " \x01(\rR\x11scheduleStartTime\x12(\n" + + "\x0fscheduleEndTime\x18\v \x01(\rR\x0fscheduleEndTime\x12^\n" + + "\x13scheduleDaysEnabled\x18\f \x03(\x0e2,.signalservice.NotificationProfile.DayOfWeekR\x13scheduleDaysEnabled\x122\n" + + "\x14deletedAtTimestampMs\x18\r \x01(\x04R\x14deletedAtTimestampMs\"t\n" + + "\tDayOfWeek\x12\v\n" + + "\aUNKNOWN\x10\x00\x12\n" + + "\n" + + "\x06MONDAY\x10\x01\x12\v\n" + + "\aTUESDAY\x10\x02\x12\r\n" + + "\tWEDNESDAY\x10\x03\x12\f\n" + + "\bTHURSDAY\x10\x04\x12\n" + + "\n" + + "\x06FRIDAY\x10\x05\x12\f\n" + + "\bSATURDAY\x10\x06\x12\n" + + "\n" + + "\x06SUNDAY\x10\aB\b\n" + + "\x06_emoji*4\n" + "\fOptionalBool\x12\t\n" + "\x05UNSET\x10\x00\x12\v\n" + "\aENABLED\x10\x01\x12\f\n" + @@ -2889,77 +3356,88 @@ func file_StorageService_proto_rawDescGZIP() []byte { return file_StorageService_proto_rawDescData } -var file_StorageService_proto_enumTypes = make([]protoimpl.EnumInfo, 8) -var file_StorageService_proto_msgTypes = make([]protoimpl.MessageInfo, 23) +var file_StorageService_proto_enumTypes = make([]protoimpl.EnumInfo, 9) +var file_StorageService_proto_msgTypes = make([]protoimpl.MessageInfo, 27) var file_StorageService_proto_goTypes = []any{ - (OptionalBool)(0), // 0: signalservice.OptionalBool - (AvatarColor)(0), // 1: signalservice.AvatarColor - (ManifestRecord_Identifier_Type)(0), // 2: signalservice.ManifestRecord.Identifier.Type - (ContactRecord_IdentityState)(0), // 3: signalservice.ContactRecord.IdentityState - (GroupV2Record_StorySendMode)(0), // 4: signalservice.GroupV2Record.StorySendMode - (AccountRecord_PhoneNumberSharingMode)(0), // 5: signalservice.AccountRecord.PhoneNumberSharingMode - (AccountRecord_UsernameLink_Color)(0), // 6: signalservice.AccountRecord.UsernameLink.Color - (ChatFolderRecord_FolderType)(0), // 7: signalservice.ChatFolderRecord.FolderType - (*StorageManifest)(nil), // 8: signalservice.StorageManifest - (*StorageItem)(nil), // 9: signalservice.StorageItem - (*StorageItems)(nil), // 10: signalservice.StorageItems - (*ReadOperation)(nil), // 11: signalservice.ReadOperation - (*WriteOperation)(nil), // 12: signalservice.WriteOperation - (*ManifestRecord)(nil), // 13: signalservice.ManifestRecord - (*StorageRecord)(nil), // 14: signalservice.StorageRecord - (*ContactRecord)(nil), // 15: signalservice.ContactRecord - (*GroupV1Record)(nil), // 16: signalservice.GroupV1Record - (*GroupV2Record)(nil), // 17: signalservice.GroupV2Record - (*Payments)(nil), // 18: signalservice.Payments - (*AccountRecord)(nil), // 19: signalservice.AccountRecord - (*StoryDistributionListRecord)(nil), // 20: signalservice.StoryDistributionListRecord - (*CallLinkRecord)(nil), // 21: signalservice.CallLinkRecord - (*ChatFolderRecord)(nil), // 22: signalservice.ChatFolderRecord - (*ManifestRecord_Identifier)(nil), // 23: signalservice.ManifestRecord.Identifier - (*ContactRecord_Name)(nil), // 24: signalservice.ContactRecord.Name - (*AccountRecord_PinnedConversation)(nil), // 25: signalservice.AccountRecord.PinnedConversation - (*AccountRecord_UsernameLink)(nil), // 26: signalservice.AccountRecord.UsernameLink - (*AccountRecord_IAPSubscriberData)(nil), // 27: signalservice.AccountRecord.IAPSubscriberData - (*AccountRecord_PinnedConversation_Contact)(nil), // 28: signalservice.AccountRecord.PinnedConversation.Contact - (*ChatFolderRecord_Recipient)(nil), // 29: signalservice.ChatFolderRecord.Recipient - (*ChatFolderRecord_Recipient_Contact)(nil), // 30: signalservice.ChatFolderRecord.Recipient.Contact + (OptionalBool)(0), // 0: signalservice.OptionalBool + (AvatarColor)(0), // 1: signalservice.AvatarColor + (ManifestRecord_Identifier_Type)(0), // 2: signalservice.ManifestRecord.Identifier.Type + (ContactRecord_IdentityState)(0), // 3: signalservice.ContactRecord.IdentityState + (GroupV2Record_StorySendMode)(0), // 4: signalservice.GroupV2Record.StorySendMode + (AccountRecord_PhoneNumberSharingMode)(0), // 5: signalservice.AccountRecord.PhoneNumberSharingMode + (AccountRecord_UsernameLink_Color)(0), // 6: signalservice.AccountRecord.UsernameLink.Color + (ChatFolderRecord_FolderType)(0), // 7: signalservice.ChatFolderRecord.FolderType + (NotificationProfile_DayOfWeek)(0), // 8: signalservice.NotificationProfile.DayOfWeek + (*StorageManifest)(nil), // 9: signalservice.StorageManifest + (*StorageItem)(nil), // 10: signalservice.StorageItem + (*StorageItems)(nil), // 11: signalservice.StorageItems + (*ReadOperation)(nil), // 12: signalservice.ReadOperation + (*WriteOperation)(nil), // 13: signalservice.WriteOperation + (*ManifestRecord)(nil), // 14: signalservice.ManifestRecord + (*StorageRecord)(nil), // 15: signalservice.StorageRecord + (*ContactRecord)(nil), // 16: signalservice.ContactRecord + (*GroupV1Record)(nil), // 17: signalservice.GroupV1Record + (*GroupV2Record)(nil), // 18: signalservice.GroupV2Record + (*Payments)(nil), // 19: signalservice.Payments + (*AccountRecord)(nil), // 20: signalservice.AccountRecord + (*StoryDistributionListRecord)(nil), // 21: signalservice.StoryDistributionListRecord + (*CallLinkRecord)(nil), // 22: signalservice.CallLinkRecord + (*Recipient)(nil), // 23: signalservice.Recipient + (*ChatFolderRecord)(nil), // 24: signalservice.ChatFolderRecord + (*NotificationProfile)(nil), // 25: signalservice.NotificationProfile + (*ManifestRecord_Identifier)(nil), // 26: signalservice.ManifestRecord.Identifier + (*ContactRecord_Name)(nil), // 27: signalservice.ContactRecord.Name + (*AccountRecord_PinnedConversation)(nil), // 28: signalservice.AccountRecord.PinnedConversation + (*AccountRecord_UsernameLink)(nil), // 29: signalservice.AccountRecord.UsernameLink + (*AccountRecord_IAPSubscriberData)(nil), // 30: signalservice.AccountRecord.IAPSubscriberData + (*AccountRecord_BackupTierHistory)(nil), // 31: signalservice.AccountRecord.BackupTierHistory + (*AccountRecord_NotificationProfileManualOverride)(nil), // 32: signalservice.AccountRecord.NotificationProfileManualOverride + (*AccountRecord_PinnedConversation_Contact)(nil), // 33: signalservice.AccountRecord.PinnedConversation.Contact + (*AccountRecord_NotificationProfileManualOverride_ManuallyEnabled)(nil), // 34: signalservice.AccountRecord.NotificationProfileManualOverride.ManuallyEnabled + (*Recipient_Contact)(nil), // 35: signalservice.Recipient.Contact } var file_StorageService_proto_depIdxs = []int32{ - 9, // 0: signalservice.StorageItems.items:type_name -> signalservice.StorageItem - 8, // 1: signalservice.WriteOperation.manifest:type_name -> signalservice.StorageManifest - 9, // 2: signalservice.WriteOperation.insertItem:type_name -> signalservice.StorageItem - 23, // 3: signalservice.ManifestRecord.identifiers:type_name -> signalservice.ManifestRecord.Identifier - 15, // 4: signalservice.StorageRecord.contact:type_name -> signalservice.ContactRecord - 16, // 5: signalservice.StorageRecord.groupV1:type_name -> signalservice.GroupV1Record - 17, // 6: signalservice.StorageRecord.groupV2:type_name -> signalservice.GroupV2Record - 19, // 7: signalservice.StorageRecord.account:type_name -> signalservice.AccountRecord - 20, // 8: signalservice.StorageRecord.storyDistributionList:type_name -> signalservice.StoryDistributionListRecord - 21, // 9: signalservice.StorageRecord.callLink:type_name -> signalservice.CallLinkRecord - 22, // 10: signalservice.StorageRecord.chatFolder:type_name -> signalservice.ChatFolderRecord - 3, // 11: signalservice.ContactRecord.identityState:type_name -> signalservice.ContactRecord.IdentityState - 24, // 12: signalservice.ContactRecord.nickname:type_name -> signalservice.ContactRecord.Name - 1, // 13: signalservice.ContactRecord.avatarColor:type_name -> signalservice.AvatarColor - 4, // 14: signalservice.GroupV2Record.storySendMode:type_name -> signalservice.GroupV2Record.StorySendMode - 1, // 15: signalservice.GroupV2Record.avatarColor:type_name -> signalservice.AvatarColor - 5, // 16: signalservice.AccountRecord.phoneNumberSharingMode:type_name -> signalservice.AccountRecord.PhoneNumberSharingMode - 25, // 17: signalservice.AccountRecord.pinnedConversations:type_name -> signalservice.AccountRecord.PinnedConversation - 18, // 18: signalservice.AccountRecord.payments:type_name -> signalservice.Payments - 0, // 19: signalservice.AccountRecord.storyViewReceiptsEnabled:type_name -> signalservice.OptionalBool - 26, // 20: signalservice.AccountRecord.usernameLink:type_name -> signalservice.AccountRecord.UsernameLink - 27, // 21: signalservice.AccountRecord.backupSubscriberData:type_name -> signalservice.AccountRecord.IAPSubscriberData - 1, // 22: signalservice.AccountRecord.avatarColor:type_name -> signalservice.AvatarColor - 7, // 23: signalservice.ChatFolderRecord.folderType:type_name -> signalservice.ChatFolderRecord.FolderType - 29, // 24: signalservice.ChatFolderRecord.includedRecipients:type_name -> signalservice.ChatFolderRecord.Recipient - 29, // 25: signalservice.ChatFolderRecord.excludedRecipients:type_name -> signalservice.ChatFolderRecord.Recipient - 2, // 26: signalservice.ManifestRecord.Identifier.type:type_name -> signalservice.ManifestRecord.Identifier.Type - 28, // 27: signalservice.AccountRecord.PinnedConversation.contact:type_name -> signalservice.AccountRecord.PinnedConversation.Contact - 6, // 28: signalservice.AccountRecord.UsernameLink.color:type_name -> signalservice.AccountRecord.UsernameLink.Color - 30, // 29: signalservice.ChatFolderRecord.Recipient.contact:type_name -> signalservice.ChatFolderRecord.Recipient.Contact - 30, // [30:30] is the sub-list for method output_type - 30, // [30:30] is the sub-list for method input_type - 30, // [30:30] is the sub-list for extension type_name - 30, // [30:30] is the sub-list for extension extendee - 0, // [0:30] is the sub-list for field type_name + 10, // 0: signalservice.StorageItems.items:type_name -> signalservice.StorageItem + 9, // 1: signalservice.WriteOperation.manifest:type_name -> signalservice.StorageManifest + 10, // 2: signalservice.WriteOperation.insertItem:type_name -> signalservice.StorageItem + 26, // 3: signalservice.ManifestRecord.identifiers:type_name -> signalservice.ManifestRecord.Identifier + 16, // 4: signalservice.StorageRecord.contact:type_name -> signalservice.ContactRecord + 17, // 5: signalservice.StorageRecord.groupV1:type_name -> signalservice.GroupV1Record + 18, // 6: signalservice.StorageRecord.groupV2:type_name -> signalservice.GroupV2Record + 20, // 7: signalservice.StorageRecord.account:type_name -> signalservice.AccountRecord + 21, // 8: signalservice.StorageRecord.storyDistributionList:type_name -> signalservice.StoryDistributionListRecord + 22, // 9: signalservice.StorageRecord.callLink:type_name -> signalservice.CallLinkRecord + 24, // 10: signalservice.StorageRecord.chatFolder:type_name -> signalservice.ChatFolderRecord + 25, // 11: signalservice.StorageRecord.notificationProfile:type_name -> signalservice.NotificationProfile + 3, // 12: signalservice.ContactRecord.identityState:type_name -> signalservice.ContactRecord.IdentityState + 27, // 13: signalservice.ContactRecord.nickname:type_name -> signalservice.ContactRecord.Name + 1, // 14: signalservice.ContactRecord.avatarColor:type_name -> signalservice.AvatarColor + 4, // 15: signalservice.GroupV2Record.storySendMode:type_name -> signalservice.GroupV2Record.StorySendMode + 1, // 16: signalservice.GroupV2Record.avatarColor:type_name -> signalservice.AvatarColor + 5, // 17: signalservice.AccountRecord.phoneNumberSharingMode:type_name -> signalservice.AccountRecord.PhoneNumberSharingMode + 28, // 18: signalservice.AccountRecord.pinnedConversations:type_name -> signalservice.AccountRecord.PinnedConversation + 19, // 19: signalservice.AccountRecord.payments:type_name -> signalservice.Payments + 0, // 20: signalservice.AccountRecord.storyViewReceiptsEnabled:type_name -> signalservice.OptionalBool + 29, // 21: signalservice.AccountRecord.usernameLink:type_name -> signalservice.AccountRecord.UsernameLink + 30, // 22: signalservice.AccountRecord.backupSubscriberData:type_name -> signalservice.AccountRecord.IAPSubscriberData + 1, // 23: signalservice.AccountRecord.avatarColor:type_name -> signalservice.AvatarColor + 31, // 24: signalservice.AccountRecord.backupTierHistory:type_name -> signalservice.AccountRecord.BackupTierHistory + 32, // 25: signalservice.AccountRecord.notificationProfileManualOverride:type_name -> signalservice.AccountRecord.NotificationProfileManualOverride + 35, // 26: signalservice.Recipient.contact:type_name -> signalservice.Recipient.Contact + 7, // 27: signalservice.ChatFolderRecord.folderType:type_name -> signalservice.ChatFolderRecord.FolderType + 23, // 28: signalservice.ChatFolderRecord.includedRecipients:type_name -> signalservice.Recipient + 23, // 29: signalservice.ChatFolderRecord.excludedRecipients:type_name -> signalservice.Recipient + 23, // 30: signalservice.NotificationProfile.allowedMembers:type_name -> signalservice.Recipient + 8, // 31: signalservice.NotificationProfile.scheduleDaysEnabled:type_name -> signalservice.NotificationProfile.DayOfWeek + 2, // 32: signalservice.ManifestRecord.Identifier.type:type_name -> signalservice.ManifestRecord.Identifier.Type + 33, // 33: signalservice.AccountRecord.PinnedConversation.contact:type_name -> signalservice.AccountRecord.PinnedConversation.Contact + 6, // 34: signalservice.AccountRecord.UsernameLink.color:type_name -> signalservice.AccountRecord.UsernameLink.Color + 34, // 35: signalservice.AccountRecord.NotificationProfileManualOverride.enabled:type_name -> signalservice.AccountRecord.NotificationProfileManualOverride.ManuallyEnabled + 36, // [36:36] is the sub-list for method output_type + 36, // [36:36] is the sub-list for method input_type + 36, // [36:36] is the sub-list for extension type_name + 36, // [36:36] is the sub-list for extension extendee + 0, // [0:36] is the sub-list for field type_name } func init() { file_StorageService_proto_init() } @@ -2975,31 +3453,38 @@ func file_StorageService_proto_init() { (*StorageRecord_StoryDistributionList)(nil), (*StorageRecord_CallLink)(nil), (*StorageRecord_ChatFolder)(nil), + (*StorageRecord_NotificationProfile)(nil), } file_StorageService_proto_msgTypes[7].OneofWrappers = []any{} file_StorageService_proto_msgTypes[9].OneofWrappers = []any{} file_StorageService_proto_msgTypes[11].OneofWrappers = []any{} - file_StorageService_proto_msgTypes[17].OneofWrappers = []any{ + file_StorageService_proto_msgTypes[14].OneofWrappers = []any{ + (*Recipient_Contact_)(nil), + (*Recipient_LegacyGroupId)(nil), + (*Recipient_GroupMasterKey)(nil), + } + file_StorageService_proto_msgTypes[16].OneofWrappers = []any{} + file_StorageService_proto_msgTypes[19].OneofWrappers = []any{ (*AccountRecord_PinnedConversation_Contact_)(nil), (*AccountRecord_PinnedConversation_LegacyGroupId)(nil), (*AccountRecord_PinnedConversation_GroupMasterKey)(nil), } - file_StorageService_proto_msgTypes[19].OneofWrappers = []any{ + file_StorageService_proto_msgTypes[21].OneofWrappers = []any{ (*AccountRecord_IAPSubscriberData_PurchaseToken)(nil), (*AccountRecord_IAPSubscriberData_OriginalTransactionId)(nil), } - file_StorageService_proto_msgTypes[21].OneofWrappers = []any{ - (*ChatFolderRecord_Recipient_Contact_)(nil), - (*ChatFolderRecord_Recipient_LegacyGroupId)(nil), - (*ChatFolderRecord_Recipient_GroupMasterKey)(nil), + file_StorageService_proto_msgTypes[22].OneofWrappers = []any{} + file_StorageService_proto_msgTypes[23].OneofWrappers = []any{ + (*AccountRecord_NotificationProfileManualOverride_DisabledAtTimestampMs)(nil), + (*AccountRecord_NotificationProfileManualOverride_Enabled)(nil), } type x struct{} out := protoimpl.TypeBuilder{ File: protoimpl.DescBuilder{ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: unsafe.Slice(unsafe.StringData(file_StorageService_proto_rawDesc), len(file_StorageService_proto_rawDesc)), - NumEnums: 8, - NumMessages: 23, + NumEnums: 9, + NumMessages: 27, NumExtensions: 0, NumServices: 0, }, diff --git a/pkg/signalmeow/protobuf/StorageService.proto b/pkg/signalmeow/protobuf/StorageService.proto index de8517f..eaa1453 100644 --- a/pkg/signalmeow/protobuf/StorageService.proto +++ b/pkg/signalmeow/protobuf/StorageService.proto @@ -52,6 +52,7 @@ message ManifestRecord { STORY_DISTRIBUTION_LIST = 5; CALL_LINK = 7; CHAT_FOLDER = 8; + NOTIFICATION_PROFILE = 9; } bytes raw = 1; @@ -74,6 +75,7 @@ message StorageRecord { StoryDistributionListRecord storyDistributionList = 5; CallLinkRecord callLink = 7; ChatFolderRecord chatFolder = 8; + NotificationProfile notificationProfile = 9; } } @@ -225,48 +227,70 @@ message AccountRecord { } } - bytes profileKey = 1; - string givenName = 2; - string familyName = 3; - string avatarUrlPath = 4; - bool noteToSelfArchived = 5; - bool readReceipts = 6; - bool sealedSenderIndicators = 7; - bool typingIndicators = 8; - reserved /* proxiedLinkPreviews */ 9; - bool noteToSelfMarkedUnread = 10; - bool linkPreviews = 11; - PhoneNumberSharingMode phoneNumberSharingMode = 12; - bool unlistedPhoneNumber = 13; - repeated PinnedConversation pinnedConversations = 14; - bool preferContactAvatars = 15; - Payments payments = 16; - uint32 universalExpireTimer = 17; - bool primarySendsSms = 18; - string e164 = 19; - repeated string preferredReactionEmoji = 20; - bytes subscriberId = 21; - string subscriberCurrencyCode = 22; - bool displayBadgesOnProfile = 23; - bool subscriptionManuallyCancelled = 24; - bool keepMutedChatsArchived = 25; - bool hasSetMyStoriesPrivacy = 26; - bool hasViewedOnboardingStory = 27; - reserved /* storiesDisabled */ 28; - bool storiesDisabled = 29; - OptionalBool storyViewReceiptsEnabled = 30; - reserved /* hasReadOnboardingStory */ 31; - bool hasSeenGroupStoryEducationSheet = 32; - string username = 33; - bool hasCompletedUsernameOnboarding = 34; - UsernameLink usernameLink = 35; - reserved /* backupsSubscriberId */ 36; - reserved /* backupsSubscriberCurrencyCode */ 37; - reserved /* backupsSubscriptionManuallyCancelled */ 38; - optional bool hasBackup = 39; // Set to true after backups are enabled and one is uploaded. - optional uint64 backupTier = 40; // See zkgroup for integer particular values - IAPSubscriberData backupSubscriberData = 41; - optional AvatarColor avatarColor = 42; + message BackupTierHistory { + // See zkgroup for integer particular values. Unset if backups are not enabled. + optional uint64 backupTier = 1; + optional uint64 endedAtTimestamp = 2; + } + + message NotificationProfileManualOverride { + message ManuallyEnabled { + bytes id = 1; + + // This will be unset if no timespan was chosen in the UI. + uint64 endAtTimestampMs = 3; + } + + oneof override { + uint64 disabledAtTimestampMs = 1; + ManuallyEnabled enabled = 2; + } + } + + bytes profileKey = 1; + string givenName = 2; + string familyName = 3; + string avatarUrlPath = 4; + bool noteToSelfArchived = 5; + bool readReceipts = 6; + bool sealedSenderIndicators = 7; + bool typingIndicators = 8; + reserved /* proxiedLinkPreviews */ 9; + bool noteToSelfMarkedUnread = 10; + bool linkPreviews = 11; + PhoneNumberSharingMode phoneNumberSharingMode = 12; + bool unlistedPhoneNumber = 13; + repeated PinnedConversation pinnedConversations = 14; + bool preferContactAvatars = 15; + Payments payments = 16; + uint32 universalExpireTimer = 17; + bool primarySendsSms = 18; + reserved /* e164 */ 19; + repeated string preferredReactionEmoji = 20; + bytes subscriberId = 21; + string subscriberCurrencyCode = 22; + bool displayBadgesOnProfile = 23; + bool subscriptionManuallyCancelled = 24; + bool keepMutedChatsArchived = 25; + bool hasSetMyStoriesPrivacy = 26; + bool hasViewedOnboardingStory = 27; + reserved /* storiesDisabled */ 28; + bool storiesDisabled = 29; + OptionalBool storyViewReceiptsEnabled = 30; + reserved /* hasReadOnboardingStory */ 31; + bool hasSeenGroupStoryEducationSheet = 32; + string username = 33; + bool hasCompletedUsernameOnboarding = 34; + UsernameLink usernameLink = 35; + reserved /* backupsSubscriberId */ 36; + reserved /* backupsSubscriberCurrencyCode */ 37; + reserved /* backupsSubscriptionManuallyCancelled */ 38; + optional bool hasBackup = 39; // Set to true after backups are enabled and one is uploaded. + optional uint64 backupTier = 40; // See zkgroup for integer particular values. Unset if backups are not enabled. + IAPSubscriberData backupSubscriberData = 41; + optional AvatarColor avatarColor = 42; + BackupTierHistory backupTierHistory = 43; + NotificationProfileManualOverride notificationProfileManualOverride = 44; } message StoryDistributionListRecord { @@ -284,20 +308,20 @@ message CallLinkRecord { uint64 deletedAtTimestampMs = 3; } -message ChatFolderRecord { - message Recipient { - message Contact { - string serviceId = 1; - string e164 = 2; - } - - oneof identifier { - Contact contact = 1; - bytes legacyGroupId = 2; - bytes groupMasterKey = 3; - } +message Recipient { + message Contact { + string serviceId = 1; + string e164 = 2; } + oneof identifier { + Contact contact = 1; + bytes legacyGroupId = 2; + bytes groupMasterKey = 3; + } +} + +message ChatFolderRecord { // Represents the default "All chats" folder record vs all other custom folders enum FolderType { UNKNOWN = 0; @@ -317,3 +341,30 @@ message ChatFolderRecord { repeated Recipient excludedRecipients = 10; uint64 deletedAtTimestampMs = 11; // When non-zero, `position` should be set to -1 and includedRecipients should be empty } + +message NotificationProfile { + enum DayOfWeek { + UNKNOWN = 0; // Interpret as "Monday" + MONDAY = 1; + TUESDAY = 2; + WEDNESDAY = 3; + THURSDAY = 4; + FRIDAY = 5; + SATURDAY = 6; + SUNDAY = 7; + } + + bytes id = 1; + string name = 2; + optional string emoji = 3; + fixed32 color = 4; // 0xAARRGGBB + uint64 createdAtMs = 5; + bool allowAllCalls = 6; + bool allowAllMentions = 7; + repeated Recipient allowedMembers = 8; + bool scheduleEnabled = 9; + uint32 scheduleStartTime = 10; // 24-hour clock int, 0000-2359 (e.g., 15, 900, 1130, 2345) + uint32 scheduleEndTime = 11; // 24-hour clock int, 0000-2359 (e.g., 15, 900, 1130, 2345) + repeated DayOfWeek scheduleDaysEnabled = 12; + uint64 deletedAtTimestampMs = 13; +} diff --git a/pkg/signalmeow/protobuf/UnidentifiedDelivery.pb.go b/pkg/signalmeow/protobuf/UnidentifiedDelivery.pb.go index adc1e3f..bb5b256 100644 --- a/pkg/signalmeow/protobuf/UnidentifiedDelivery.pb.go +++ b/pkg/signalmeow/protobuf/UnidentifiedDelivery.pb.go @@ -27,8 +27,10 @@ const ( type UnidentifiedSenderMessage_Message_Type int32 const ( - UnidentifiedSenderMessage_Message_PREKEY_MESSAGE UnidentifiedSenderMessage_Message_Type = 1 - UnidentifiedSenderMessage_Message_MESSAGE UnidentifiedSenderMessage_Message_Type = 2 // Further cases should line up with Envelope.Type, even though old cases don't. + // Our parser does not handle reserved in enums: DESKTOP-1569 + // reserved 1; + UnidentifiedSenderMessage_Message_MESSAGE UnidentifiedSenderMessage_Message_Type = 2 + UnidentifiedSenderMessage_Message_PREKEY_MESSAGE UnidentifiedSenderMessage_Message_Type = 3 // Further cases should line up with Envelope.Type, even though old cases don't. UnidentifiedSenderMessage_Message_SENDERKEY_MESSAGE UnidentifiedSenderMessage_Message_Type = 7 UnidentifiedSenderMessage_Message_PLAINTEXT_CONTENT UnidentifiedSenderMessage_Message_Type = 8 ) @@ -36,14 +38,14 @@ const ( // Enum value maps for UnidentifiedSenderMessage_Message_Type. var ( UnidentifiedSenderMessage_Message_Type_name = map[int32]string{ - 1: "PREKEY_MESSAGE", 2: "MESSAGE", + 3: "PREKEY_MESSAGE", 7: "SENDERKEY_MESSAGE", 8: "PLAINTEXT_CONTENT", } UnidentifiedSenderMessage_Message_Type_value = map[string]int32{ - "PREKEY_MESSAGE": 1, "MESSAGE": 2, + "PREKEY_MESSAGE": 3, "SENDERKEY_MESSAGE": 7, "PLAINTEXT_CONTENT": 8, } @@ -493,7 +495,7 @@ func (x *UnidentifiedSenderMessage_Message) GetType() UnidentifiedSenderMessage_ if x != nil && x.Type != nil { return *x.Type } - return UnidentifiedSenderMessage_Message_PREKEY_MESSAGE + return UnidentifiedSenderMessage_Message_MESSAGE } func (x *UnidentifiedSenderMessage_Message) GetSenderCertificate() *SenderCertificate { @@ -559,9 +561,9 @@ const file_UnidentifiedDelivery_proto_rawDesc = "" + "\acontent\x18\x03 \x01(\fR\acontent\x12^\n" + "\vcontentHint\x18\x04 \x01(\x0e2<.signalservice.UnidentifiedSenderMessage.Message.ContentHintR\vcontentHint\x12\x18\n" + "\agroupId\x18\x05 \x01(\fR\agroupId\"U\n" + - "\x04Type\x12\x12\n" + - "\x0ePREKEY_MESSAGE\x10\x01\x12\v\n" + - "\aMESSAGE\x10\x02\x12\x15\n" + + "\x04Type\x12\v\n" + + "\aMESSAGE\x10\x02\x12\x12\n" + + "\x0ePREKEY_MESSAGE\x10\x03\x12\x15\n" + "\x11SENDERKEY_MESSAGE\x10\a\x12\x15\n" + "\x11PLAINTEXT_CONTENT\x10\b\"8\n" + "\vContentHint\x12\v\n" + diff --git a/pkg/signalmeow/protobuf/UnidentifiedDelivery.proto b/pkg/signalmeow/protobuf/UnidentifiedDelivery.proto index fb86b60..255ab6e 100644 --- a/pkg/signalmeow/protobuf/UnidentifiedDelivery.proto +++ b/pkg/signalmeow/protobuf/UnidentifiedDelivery.proto @@ -34,11 +34,12 @@ message UnidentifiedSenderMessage { message Message { enum Type { - PREKEY_MESSAGE = 1; + // Our parser does not handle reserved in enums: DESKTOP-1569 + // reserved 1; MESSAGE = 2; + PREKEY_MESSAGE = 3; // Further cases should line up with Envelope.Type, even though old cases don't. - // Our parser does not handle reserved in enums: DESKTOP-1569 // reserved 3 to 6; SENDERKEY_MESSAGE = 7; diff --git a/pkg/signalmeow/protobuf/backuppb/Backup.pb.go b/pkg/signalmeow/protobuf/backuppb/Backup.pb.go index dc65ac7..06ebdea 100644 --- a/pkg/signalmeow/protobuf/backuppb/Backup.pb.go +++ b/pkg/signalmeow/protobuf/backuppb/Backup.pb.go @@ -4589,6 +4589,7 @@ func (x *MessageAttachment) GetClientUuid() []byte { type FilePointer struct { state protoimpl.MessageState `protogen:"open.v1"` // If unset, importers should consider it to be an InvalidAttachmentLocator without throwing an error. + // DEPRECATED; use locatorInfo instead. // // Types that are valid to be assigned to Locator: // @@ -4596,15 +4597,16 @@ type FilePointer struct { // *FilePointer_AttachmentLocator_ // *FilePointer_InvalidAttachmentLocator_ // *FilePointer_LocalLocator_ - Locator isFilePointer_Locator `protobuf_oneof:"locator"` - ContentType *string `protobuf:"bytes,4,opt,name=contentType,proto3,oneof" json:"contentType,omitempty"` - IncrementalMac []byte `protobuf:"bytes,5,opt,name=incrementalMac,proto3,oneof" json:"incrementalMac,omitempty"` - IncrementalMacChunkSize *uint32 `protobuf:"varint,6,opt,name=incrementalMacChunkSize,proto3,oneof" json:"incrementalMacChunkSize,omitempty"` - FileName *string `protobuf:"bytes,7,opt,name=fileName,proto3,oneof" json:"fileName,omitempty"` - Width *uint32 `protobuf:"varint,8,opt,name=width,proto3,oneof" json:"width,omitempty"` - Height *uint32 `protobuf:"varint,9,opt,name=height,proto3,oneof" json:"height,omitempty"` - Caption *string `protobuf:"bytes,10,opt,name=caption,proto3,oneof" json:"caption,omitempty"` - BlurHash *string `protobuf:"bytes,11,opt,name=blurHash,proto3,oneof" json:"blurHash,omitempty"` + Locator isFilePointer_Locator `protobuf_oneof:"locator"` + ContentType *string `protobuf:"bytes,4,opt,name=contentType,proto3,oneof" json:"contentType,omitempty"` + IncrementalMac []byte `protobuf:"bytes,5,opt,name=incrementalMac,proto3,oneof" json:"incrementalMac,omitempty"` + IncrementalMacChunkSize *uint32 `protobuf:"varint,6,opt,name=incrementalMacChunkSize,proto3,oneof" json:"incrementalMacChunkSize,omitempty"` + FileName *string `protobuf:"bytes,7,opt,name=fileName,proto3,oneof" json:"fileName,omitempty"` + Width *uint32 `protobuf:"varint,8,opt,name=width,proto3,oneof" json:"width,omitempty"` + Height *uint32 `protobuf:"varint,9,opt,name=height,proto3,oneof" json:"height,omitempty"` + Caption *string `protobuf:"bytes,10,opt,name=caption,proto3,oneof" json:"caption,omitempty"` + BlurHash *string `protobuf:"bytes,11,opt,name=blurHash,proto3,oneof" json:"blurHash,omitempty"` + LocatorInfo *FilePointer_LocatorInfo `protobuf:"bytes,13,opt,name=locatorInfo,proto3" json:"locatorInfo,omitempty"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } @@ -4738,6 +4740,13 @@ func (x *FilePointer) GetBlurHash() string { return "" } +func (x *FilePointer) GetLocatorInfo() *FilePointer_LocatorInfo { + if x != nil { + return x.LocatorInfo + } + return nil +} + type isFilePointer_Locator interface { isFilePointer_Locator() } @@ -7969,8 +7978,11 @@ type AccountData_AccountSettings struct { PhoneNumberSharingMode AccountData_PhoneNumberSharingMode `protobuf:"varint,17,opt,name=phoneNumberSharingMode,proto3,enum=signal.backup.AccountData_PhoneNumberSharingMode" json:"phoneNumberSharingMode,omitempty"` DefaultChatStyle *ChatStyle `protobuf:"bytes,18,opt,name=defaultChatStyle,proto3" json:"defaultChatStyle,omitempty"` CustomChatColors []*ChatStyle_CustomChatColor `protobuf:"bytes,19,rep,name=customChatColors,proto3" json:"customChatColors,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache + OptimizeOnDeviceStorage bool `protobuf:"varint,20,opt,name=optimizeOnDeviceStorage,proto3" json:"optimizeOnDeviceStorage,omitempty"` + // See zkgroup for integer particular values. Unset if backups are not enabled. + BackupTier *uint64 `protobuf:"varint,21,opt,name=backupTier,proto3,oneof" json:"backupTier,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } func (x *AccountData_AccountSettings) Reset() { @@ -8136,6 +8148,20 @@ func (x *AccountData_AccountSettings) GetCustomChatColors() []*ChatStyle_CustomC return nil } +func (x *AccountData_AccountSettings) GetOptimizeOnDeviceStorage() bool { + if x != nil { + return x.OptimizeOnDeviceStorage + } + return false +} + +func (x *AccountData_AccountSettings) GetBackupTier() uint64 { + if x != nil && x.BackupTier != nil { + return *x.BackupTier + } + return 0 +} + type AccountData_SubscriberData struct { state protoimpl.MessageState `protogen:"open.v1"` SubscriberId []byte `protobuf:"bytes,1,opt,name=subscriberId,proto3" json:"subscriberId,omitempty"` @@ -10044,6 +10070,7 @@ func (x *ContactAttachment_PostalAddress) GetCountry() string { } // References attachments in the backup (media) storage tier. +// DEPRECATED; use LocatorInfo instead if available. type FilePointer_BackupLocator struct { state protoimpl.MessageState `protogen:"open.v1"` MediaName string `protobuf:"bytes,1,opt,name=mediaName,proto3" json:"mediaName,omitempty"` @@ -10144,6 +10171,7 @@ func (x *FilePointer_BackupLocator) GetTransitCdnNumber() uint32 { // May be downloaded or not when the backup is generated; // primarily for free-tier users who cannot copy the // attachments to the backup (media) storage tier. +// DEPRECATED; use LocatorInfo instead if available. type FilePointer_AttachmentLocator struct { state protoimpl.MessageState `protogen:"open.v1"` CdnKey string `protobuf:"bytes,1,opt,name=cdnKey,proto3" json:"cdnKey,omitempty"` @@ -10233,6 +10261,7 @@ func (x *FilePointer_AttachmentLocator) GetSize() uint32 { // CDN keys or anything else that makes download attempts impossible. // This serves as a 'tombstone' so that the UX can show that an attachment // did exist, but for whatever reason it's not retrievable. +// DEPRECATED; use LocatorInfo instead if available. type FilePointer_InvalidAttachmentLocator struct { state protoimpl.MessageState `protogen:"open.v1"` unknownFields protoimpl.UnknownFields @@ -10272,6 +10301,7 @@ func (*FilePointer_InvalidAttachmentLocator) Descriptor() ([]byte, []int) { // References attachments in a local encrypted backup. // Importers should first attempt to read the file from the local backup, // and on failure fallback to backup and transit cdn if possible. +// DEPRECATED; use LocatorInfo instead if available. type FilePointer_LocalLocator struct { state protoimpl.MessageState `protogen:"open.v1"` MediaName string `protobuf:"bytes,1,opt,name=mediaName,proto3" json:"mediaName,omitempty"` @@ -10376,6 +10406,185 @@ func (x *FilePointer_LocalLocator) GetTransitCdnNumber() uint32 { return 0 } +type FilePointer_LocatorInfo struct { + state protoimpl.MessageState `protogen:"open.v1"` + // Must be non-empty if transitCdnKey or plaintextHash are set/nonempty. + // Otherwise must be empty. + Key []byte `protobuf:"bytes,1,opt,name=key,proto3" json:"key,omitempty"` + // From the sender of the attachment (incl. ourselves) + // Will be reserved once all clients start reading integrityCheck + LegacyDigest []byte `protobuf:"bytes,2,opt,name=legacyDigest,proto3" json:"legacyDigest,omitempty"` + // Types that are valid to be assigned to IntegrityCheck: + // + // *FilePointer_LocatorInfo_PlaintextHash + // *FilePointer_LocatorInfo_EncryptedDigest + IntegrityCheck isFilePointer_LocatorInfo_IntegrityCheck `protobuf_oneof:"integrityCheck"` + // NB: This is the plaintext size, and empty content attachments are legal, so this + // may be zero even if transitCdnKey or mediaName are set/nonempty. + Size uint32 `protobuf:"varint,3,opt,name=size,proto3" json:"size,omitempty"` + // Either both transit cdn key and number are set or neither should be set. + // Upload timestamp is optional but should only be set if key/number are set. + TransitCdnKey *string `protobuf:"bytes,4,opt,name=transitCdnKey,proto3,oneof" json:"transitCdnKey,omitempty"` + TransitCdnNumber *uint32 `protobuf:"varint,5,opt,name=transitCdnNumber,proto3,oneof" json:"transitCdnNumber,omitempty"` + TransitTierUploadTimestamp *uint64 `protobuf:"varint,6,opt,name=transitTierUploadTimestamp,proto3,oneof" json:"transitTierUploadTimestamp,omitempty"` + // If present, the cdn number of the succesful upload to media tier. + // If unset, may still have been uploaded, and clients + // can discover the cdn number via the list endpoint. + // Exporting clients should set this as long as their subscription + // has not rotated since last upload; even if currently free tier. + MediaTierCdnNumber *uint32 `protobuf:"varint,7,opt,name=mediaTierCdnNumber,proto3,oneof" json:"mediaTierCdnNumber,omitempty"` + // Nonempty any time the attachment was downloaded and its + // digest validated, whether free tier or paid subscription. + // Will be reserved once all clients start reading integrityCheck, + // when mediaName will be derived from the plaintextHash and encryption key + LegacyMediaName string `protobuf:"bytes,8,opt,name=legacyMediaName,proto3" json:"legacyMediaName,omitempty"` + // Separate key used to encrypt this file for the local backup. + // Generally required for local backups. + // Missing field indicates attachment was not available locally + // when the backup was generated, but remote backup or transit + // info was available. + LocalKey []byte `protobuf:"bytes,9,opt,name=localKey,proto3,oneof" json:"localKey,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *FilePointer_LocatorInfo) Reset() { + *x = FilePointer_LocatorInfo{} + mi := &file_backuppb_Backup_proto_msgTypes[117] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *FilePointer_LocatorInfo) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*FilePointer_LocatorInfo) ProtoMessage() {} + +func (x *FilePointer_LocatorInfo) ProtoReflect() protoreflect.Message { + mi := &file_backuppb_Backup_proto_msgTypes[117] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use FilePointer_LocatorInfo.ProtoReflect.Descriptor instead. +func (*FilePointer_LocatorInfo) Descriptor() ([]byte, []int) { + return file_backuppb_Backup_proto_rawDescGZIP(), []int{28, 4} +} + +func (x *FilePointer_LocatorInfo) GetKey() []byte { + if x != nil { + return x.Key + } + return nil +} + +func (x *FilePointer_LocatorInfo) GetLegacyDigest() []byte { + if x != nil { + return x.LegacyDigest + } + return nil +} + +func (x *FilePointer_LocatorInfo) GetIntegrityCheck() isFilePointer_LocatorInfo_IntegrityCheck { + if x != nil { + return x.IntegrityCheck + } + return nil +} + +func (x *FilePointer_LocatorInfo) GetPlaintextHash() []byte { + if x != nil { + if x, ok := x.IntegrityCheck.(*FilePointer_LocatorInfo_PlaintextHash); ok { + return x.PlaintextHash + } + } + return nil +} + +func (x *FilePointer_LocatorInfo) GetEncryptedDigest() []byte { + if x != nil { + if x, ok := x.IntegrityCheck.(*FilePointer_LocatorInfo_EncryptedDigest); ok { + return x.EncryptedDigest + } + } + return nil +} + +func (x *FilePointer_LocatorInfo) GetSize() uint32 { + if x != nil { + return x.Size + } + return 0 +} + +func (x *FilePointer_LocatorInfo) GetTransitCdnKey() string { + if x != nil && x.TransitCdnKey != nil { + return *x.TransitCdnKey + } + return "" +} + +func (x *FilePointer_LocatorInfo) GetTransitCdnNumber() uint32 { + if x != nil && x.TransitCdnNumber != nil { + return *x.TransitCdnNumber + } + return 0 +} + +func (x *FilePointer_LocatorInfo) GetTransitTierUploadTimestamp() uint64 { + if x != nil && x.TransitTierUploadTimestamp != nil { + return *x.TransitTierUploadTimestamp + } + return 0 +} + +func (x *FilePointer_LocatorInfo) GetMediaTierCdnNumber() uint32 { + if x != nil && x.MediaTierCdnNumber != nil { + return *x.MediaTierCdnNumber + } + return 0 +} + +func (x *FilePointer_LocatorInfo) GetLegacyMediaName() string { + if x != nil { + return x.LegacyMediaName + } + return "" +} + +func (x *FilePointer_LocatorInfo) GetLocalKey() []byte { + if x != nil { + return x.LocalKey + } + return nil +} + +type isFilePointer_LocatorInfo_IntegrityCheck interface { + isFilePointer_LocatorInfo_IntegrityCheck() +} + +type FilePointer_LocatorInfo_PlaintextHash struct { + // Set if file was at one point downloaded and its plaintextHash was calculated + PlaintextHash []byte `protobuf:"bytes,10,opt,name=plaintextHash,proto3,oneof"` +} + +type FilePointer_LocatorInfo_EncryptedDigest struct { + // Set if file has not been downloaded so its integrity has not been verified + // From the sender of the attachment + EncryptedDigest []byte `protobuf:"bytes,11,opt,name=encryptedDigest,proto3,oneof"` +} + +func (*FilePointer_LocatorInfo_PlaintextHash) isFilePointer_LocatorInfo_IntegrityCheck() {} + +func (*FilePointer_LocatorInfo_EncryptedDigest) isFilePointer_LocatorInfo_IntegrityCheck() {} + type Quote_QuotedAttachment struct { state protoimpl.MessageState `protogen:"open.v1"` ContentType *string `protobuf:"bytes,1,opt,name=contentType,proto3,oneof" json:"contentType,omitempty"` @@ -10387,7 +10596,7 @@ type Quote_QuotedAttachment struct { func (x *Quote_QuotedAttachment) Reset() { *x = Quote_QuotedAttachment{} - mi := &file_backuppb_Backup_proto_msgTypes[117] + mi := &file_backuppb_Backup_proto_msgTypes[118] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -10399,7 +10608,7 @@ func (x *Quote_QuotedAttachment) String() string { func (*Quote_QuotedAttachment) ProtoMessage() {} func (x *Quote_QuotedAttachment) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[117] + mi := &file_backuppb_Backup_proto_msgTypes[118] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -10483,7 +10692,7 @@ type GroupChangeChatUpdate_Update struct { func (x *GroupChangeChatUpdate_Update) Reset() { *x = GroupChangeChatUpdate_Update{} - mi := &file_backuppb_Backup_proto_msgTypes[118] + mi := &file_backuppb_Backup_proto_msgTypes[119] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -10495,7 +10704,7 @@ func (x *GroupChangeChatUpdate_Update) String() string { func (*GroupChangeChatUpdate_Update) ProtoMessage() {} func (x *GroupChangeChatUpdate_Update) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[118] + mi := &file_backuppb_Backup_proto_msgTypes[119] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -11069,7 +11278,7 @@ type GroupInvitationRevokedUpdate_Invitee struct { func (x *GroupInvitationRevokedUpdate_Invitee) Reset() { *x = GroupInvitationRevokedUpdate_Invitee{} - mi := &file_backuppb_Backup_proto_msgTypes[119] + mi := &file_backuppb_Backup_proto_msgTypes[120] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -11081,7 +11290,7 @@ func (x *GroupInvitationRevokedUpdate_Invitee) String() string { func (*GroupInvitationRevokedUpdate_Invitee) ProtoMessage() {} func (x *GroupInvitationRevokedUpdate_Invitee) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[119] + mi := &file_backuppb_Backup_proto_msgTypes[120] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -11129,7 +11338,7 @@ type ChatStyle_Gradient struct { func (x *ChatStyle_Gradient) Reset() { *x = ChatStyle_Gradient{} - mi := &file_backuppb_Backup_proto_msgTypes[120] + mi := &file_backuppb_Backup_proto_msgTypes[121] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -11141,7 +11350,7 @@ func (x *ChatStyle_Gradient) String() string { func (*ChatStyle_Gradient) ProtoMessage() {} func (x *ChatStyle_Gradient) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[120] + mi := &file_backuppb_Backup_proto_msgTypes[121] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -11194,7 +11403,7 @@ type ChatStyle_CustomChatColor struct { func (x *ChatStyle_CustomChatColor) Reset() { *x = ChatStyle_CustomChatColor{} - mi := &file_backuppb_Backup_proto_msgTypes[121] + mi := &file_backuppb_Backup_proto_msgTypes[122] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -11206,7 +11415,7 @@ func (x *ChatStyle_CustomChatColor) String() string { func (*ChatStyle_CustomChatColor) ProtoMessage() {} func (x *ChatStyle_CustomChatColor) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[121] + mi := &file_backuppb_Backup_proto_msgTypes[122] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -11278,7 +11487,7 @@ type ChatStyle_AutomaticBubbleColor struct { func (x *ChatStyle_AutomaticBubbleColor) Reset() { *x = ChatStyle_AutomaticBubbleColor{} - mi := &file_backuppb_Backup_proto_msgTypes[122] + mi := &file_backuppb_Backup_proto_msgTypes[123] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -11290,7 +11499,7 @@ func (x *ChatStyle_AutomaticBubbleColor) String() string { func (*ChatStyle_AutomaticBubbleColor) ProtoMessage() {} func (x *ChatStyle_AutomaticBubbleColor) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[122] + mi := &file_backuppb_Backup_proto_msgTypes[123] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -11329,7 +11538,7 @@ const file_backuppb_Backup_proto_rawDesc = "" + "\n" + "chatFolder\x18\b \x01(\v2\x19.signal.backup.ChatFolderH\x00R\n" + "chatFolderB\x06\n" + - "\x04item\"\xf1\x12\n" + + "\x04item\"\xdf\x13\n" + "\vAccountData\x12\x1e\n" + "\n" + "profileKey\x18\x01 \x01(\fR\n" + @@ -11361,7 +11570,8 @@ const file_backuppb_Backup_proto_rawDesc = "" + "\x06ORANGE\x10\x06\x12\b\n" + "\x04PINK\x10\a\x12\n" + "\n" + - "\x06PURPLE\x10\b\x1a\xb4\t\n" + + "\x06PURPLE\x10\b\x1a\xa2\n" + + "\n" + "\x0fAccountSettings\x12\"\n" + "\freadReceipts\x18\x01 \x01(\bR\freadReceipts\x126\n" + "\x16sealedSenderIndicators\x18\x02 \x01(\bR\x16sealedSenderIndicators\x12*\n" + @@ -11382,8 +11592,13 @@ const file_backuppb_Backup_proto_rawDesc = "" + "\x1ehasCompletedUsernameOnboarding\x18\x10 \x01(\bR\x1ehasCompletedUsernameOnboarding\x12i\n" + "\x16phoneNumberSharingMode\x18\x11 \x01(\x0e21.signal.backup.AccountData.PhoneNumberSharingModeR\x16phoneNumberSharingMode\x12D\n" + "\x10defaultChatStyle\x18\x12 \x01(\v2\x18.signal.backup.ChatStyleR\x10defaultChatStyle\x12T\n" + - "\x10customChatColors\x18\x13 \x03(\v2(.signal.backup.ChatStyle.CustomChatColorR\x10customChatColorsB\x1b\n" + - "\x19_storyViewReceiptsEnabled\x1a\x86\x01\n" + + "\x10customChatColors\x18\x13 \x03(\v2(.signal.backup.ChatStyle.CustomChatColorR\x10customChatColors\x128\n" + + "\x17optimizeOnDeviceStorage\x18\x14 \x01(\bR\x17optimizeOnDeviceStorage\x12#\n" + + "\n" + + "backupTier\x18\x15 \x01(\x04H\x01R\n" + + "backupTier\x88\x01\x01B\x1b\n" + + "\x19_storyViewReceiptsEnabledB\r\n" + + "\v_backupTier\x1a\x86\x01\n" + "\x0eSubscriberData\x12\"\n" + "\fsubscriberId\x18\x01 \x01(\fR\fsubscriberId\x12\"\n" + "\fcurrencyCode\x18\x02 \x01(\tR\fcurrencyCode\x12,\n" + @@ -11829,7 +12044,7 @@ const file_backuppb_Backup_proto_rawDesc = "" + "\n" + "BORDERLESS\x10\x02\x12\a\n" + "\x03GIF\x10\x03B\r\n" + - "\v_clientUuid\"\xb4\r\n" + + "\v_clientUuid\"\xc9\x12\n" + "\vFilePointer\x12P\n" + "\rbackupLocator\x18\x01 \x01(\v2(.signal.backup.FilePointer.BackupLocatorH\x00R\rbackupLocator\x12\\\n" + "\x11attachmentLocator\x18\x02 \x01(\v2,.signal.backup.FilePointer.AttachmentLocatorH\x00R\x11attachmentLocator\x12q\n" + @@ -11843,7 +12058,8 @@ const file_backuppb_Backup_proto_rawDesc = "" + "\x06height\x18\t \x01(\rH\x06R\x06height\x88\x01\x01\x12\x1d\n" + "\acaption\x18\n" + " \x01(\tH\aR\acaption\x88\x01\x01\x12\x1f\n" + - "\bblurHash\x18\v \x01(\tH\bR\bblurHash\x88\x01\x01\x1a\x9f\x02\n" + + "\bblurHash\x18\v \x01(\tH\bR\bblurHash\x88\x01\x01\x12H\n" + + "\vlocatorInfo\x18\r \x01(\v2&.signal.backup.FilePointer.LocatorInfoR\vlocatorInfo\x1a\x9f\x02\n" + "\rBackupLocator\x12\x1c\n" + "\tmediaName\x18\x01 \x01(\tR\tmediaName\x12!\n" + "\tcdnNumber\x18\x02 \x01(\rH\x00R\tcdnNumber\x88\x01\x01\x12\x10\n" + @@ -11877,7 +12093,26 @@ const file_backuppb_Backup_proto_rawDesc = "" + "\t_localKeyB\x12\n" + "\x10_backupCdnNumberB\x10\n" + "\x0e_transitCdnKeyB\x13\n" + - "\x11_transitCdnNumberB\t\n" + + "\x11_transitCdnNumber\x1a\xc8\x04\n" + + "\vLocatorInfo\x12\x10\n" + + "\x03key\x18\x01 \x01(\fR\x03key\x12\"\n" + + "\flegacyDigest\x18\x02 \x01(\fR\flegacyDigest\x12&\n" + + "\rplaintextHash\x18\n" + + " \x01(\fH\x00R\rplaintextHash\x12*\n" + + "\x0fencryptedDigest\x18\v \x01(\fH\x00R\x0fencryptedDigest\x12\x12\n" + + "\x04size\x18\x03 \x01(\rR\x04size\x12)\n" + + "\rtransitCdnKey\x18\x04 \x01(\tH\x01R\rtransitCdnKey\x88\x01\x01\x12/\n" + + "\x10transitCdnNumber\x18\x05 \x01(\rH\x02R\x10transitCdnNumber\x88\x01\x01\x12C\n" + + "\x1atransitTierUploadTimestamp\x18\x06 \x01(\x04H\x03R\x1atransitTierUploadTimestamp\x88\x01\x01\x123\n" + + "\x12mediaTierCdnNumber\x18\a \x01(\rH\x04R\x12mediaTierCdnNumber\x88\x01\x01\x12(\n" + + "\x0flegacyMediaName\x18\b \x01(\tR\x0flegacyMediaName\x12\x1f\n" + + "\blocalKey\x18\t \x01(\fH\x05R\blocalKey\x88\x01\x01B\x10\n" + + "\x0eintegrityCheckB\x10\n" + + "\x0e_transitCdnKeyB\x13\n" + + "\x11_transitCdnNumberB\x1d\n" + + "\x1b_transitTierUploadTimestampB\x15\n" + + "\x13_mediaTierCdnNumberB\v\n" + + "\t_localKeyB\t\n" + "\alocatorB\x0e\n" + "\f_contentTypeB\x11\n" + "\x0f_incrementalMacB\x1a\n" + @@ -12406,7 +12641,7 @@ func file_backuppb_Backup_proto_rawDescGZIP() []byte { } var file_backuppb_Backup_proto_enumTypes = make([]protoimpl.EnumInfo, 31) -var file_backuppb_Backup_proto_msgTypes = make([]protoimpl.MessageInfo, 123) +var file_backuppb_Backup_proto_msgTypes = make([]protoimpl.MessageInfo, 124) var file_backuppb_Backup_proto_goTypes = []any{ (AvatarColor)(0), // 0: signal.backup.AvatarColor (GroupV2AccessLevel)(0), // 1: signal.backup.GroupV2AccessLevel @@ -12556,12 +12791,13 @@ var file_backuppb_Backup_proto_goTypes = []any{ (*FilePointer_AttachmentLocator)(nil), // 145: signal.backup.FilePointer.AttachmentLocator (*FilePointer_InvalidAttachmentLocator)(nil), // 146: signal.backup.FilePointer.InvalidAttachmentLocator (*FilePointer_LocalLocator)(nil), // 147: signal.backup.FilePointer.LocalLocator - (*Quote_QuotedAttachment)(nil), // 148: signal.backup.Quote.QuotedAttachment - (*GroupChangeChatUpdate_Update)(nil), // 149: signal.backup.GroupChangeChatUpdate.Update - (*GroupInvitationRevokedUpdate_Invitee)(nil), // 150: signal.backup.GroupInvitationRevokedUpdate.Invitee - (*ChatStyle_Gradient)(nil), // 151: signal.backup.ChatStyle.Gradient - (*ChatStyle_CustomChatColor)(nil), // 152: signal.backup.ChatStyle.CustomChatColor - (*ChatStyle_AutomaticBubbleColor)(nil), // 153: signal.backup.ChatStyle.AutomaticBubbleColor + (*FilePointer_LocatorInfo)(nil), // 148: signal.backup.FilePointer.LocatorInfo + (*Quote_QuotedAttachment)(nil), // 149: signal.backup.Quote.QuotedAttachment + (*GroupChangeChatUpdate_Update)(nil), // 150: signal.backup.GroupChangeChatUpdate.Update + (*GroupInvitationRevokedUpdate_Invitee)(nil), // 151: signal.backup.GroupInvitationRevokedUpdate.Invitee + (*ChatStyle_Gradient)(nil), // 152: signal.backup.ChatStyle.Gradient + (*ChatStyle_CustomChatColor)(nil), // 153: signal.backup.ChatStyle.CustomChatColor + (*ChatStyle_AutomaticBubbleColor)(nil), // 154: signal.backup.ChatStyle.AutomaticBubbleColor } var file_backuppb_Backup_proto_depIdxs = []int32{ 33, // 0: signal.backup.Frame.account:type_name -> signal.backup.AccountData @@ -12647,104 +12883,105 @@ var file_backuppb_Backup_proto_depIdxs = []int32{ 145, // 80: signal.backup.FilePointer.attachmentLocator:type_name -> signal.backup.FilePointer.AttachmentLocator 146, // 81: signal.backup.FilePointer.invalidAttachmentLocator:type_name -> signal.backup.FilePointer.InvalidAttachmentLocator 147, // 82: signal.backup.FilePointer.localLocator:type_name -> signal.backup.FilePointer.LocalLocator - 46, // 83: signal.backup.Quote.text:type_name -> signal.backup.Text - 148, // 84: signal.backup.Quote.attachments:type_name -> signal.backup.Quote.QuotedAttachment - 20, // 85: signal.backup.Quote.type:type_name -> signal.backup.Quote.Type - 21, // 86: signal.backup.BodyRange.style:type_name -> signal.backup.BodyRange.Style - 66, // 87: signal.backup.ChatUpdateMessage.simpleUpdate:type_name -> signal.backup.SimpleChatUpdate - 72, // 88: signal.backup.ChatUpdateMessage.groupChange:type_name -> signal.backup.GroupChangeChatUpdate - 67, // 89: signal.backup.ChatUpdateMessage.expirationTimerChange:type_name -> signal.backup.ExpirationTimerChatUpdate - 68, // 90: signal.backup.ChatUpdateMessage.profileChange:type_name -> signal.backup.ProfileChangeChatUpdate - 70, // 91: signal.backup.ChatUpdateMessage.threadMerge:type_name -> signal.backup.ThreadMergeChatUpdate - 71, // 92: signal.backup.ChatUpdateMessage.sessionSwitchover:type_name -> signal.backup.SessionSwitchoverChatUpdate - 64, // 93: signal.backup.ChatUpdateMessage.individualCall:type_name -> signal.backup.IndividualCall - 65, // 94: signal.backup.ChatUpdateMessage.groupCall:type_name -> signal.backup.GroupCall - 69, // 95: signal.backup.ChatUpdateMessage.learnedProfileChange:type_name -> signal.backup.LearnedProfileChatUpdate - 22, // 96: signal.backup.IndividualCall.type:type_name -> signal.backup.IndividualCall.Type - 23, // 97: signal.backup.IndividualCall.direction:type_name -> signal.backup.IndividualCall.Direction - 24, // 98: signal.backup.IndividualCall.state:type_name -> signal.backup.IndividualCall.State - 25, // 99: signal.backup.GroupCall.state:type_name -> signal.backup.GroupCall.State - 26, // 100: signal.backup.SimpleChatUpdate.type:type_name -> signal.backup.SimpleChatUpdate.Type - 149, // 101: signal.backup.GroupChangeChatUpdate.updates:type_name -> signal.backup.GroupChangeChatUpdate.Update - 1, // 102: signal.backup.GroupMembershipAccessLevelChangeUpdate.accessLevel:type_name -> signal.backup.GroupV2AccessLevel - 1, // 103: signal.backup.GroupAttributesAccessLevelChangeUpdate.accessLevel:type_name -> signal.backup.GroupV2AccessLevel - 150, // 104: signal.backup.GroupInvitationRevokedUpdate.invitees:type_name -> signal.backup.GroupInvitationRevokedUpdate.Invitee - 27, // 105: signal.backup.ChatStyle.wallpaperPreset:type_name -> signal.backup.ChatStyle.WallpaperPreset - 59, // 106: signal.backup.ChatStyle.wallpaperPhoto:type_name -> signal.backup.FilePointer - 153, // 107: signal.backup.ChatStyle.autoBubbleColor:type_name -> signal.backup.ChatStyle.AutomaticBubbleColor - 28, // 108: signal.backup.ChatStyle.bubbleColorPreset:type_name -> signal.backup.ChatStyle.BubbleColorPreset - 29, // 109: signal.backup.NotificationProfile.scheduleDaysEnabled:type_name -> signal.backup.NotificationProfile.DayOfWeek - 30, // 110: signal.backup.ChatFolder.folderType:type_name -> signal.backup.ChatFolder.FolderType - 3, // 111: signal.backup.AccountData.UsernameLink.color:type_name -> signal.backup.AccountData.UsernameLink.Color - 2, // 112: signal.backup.AccountData.AccountSettings.phoneNumberSharingMode:type_name -> signal.backup.AccountData.PhoneNumberSharingMode - 108, // 113: signal.backup.AccountData.AccountSettings.defaultChatStyle:type_name -> signal.backup.ChatStyle - 152, // 114: signal.backup.AccountData.AccountSettings.customChatColors:type_name -> signal.backup.ChatStyle.CustomChatColor - 119, // 115: signal.backup.Group.GroupSnapshot.title:type_name -> signal.backup.Group.GroupAttributeBlob - 119, // 116: signal.backup.Group.GroupSnapshot.description:type_name -> signal.backup.Group.GroupAttributeBlob - 119, // 117: signal.backup.Group.GroupSnapshot.disappearingMessagesTimer:type_name -> signal.backup.Group.GroupAttributeBlob - 124, // 118: signal.backup.Group.GroupSnapshot.accessControl:type_name -> signal.backup.Group.AccessControl - 120, // 119: signal.backup.Group.GroupSnapshot.members:type_name -> signal.backup.Group.Member - 121, // 120: signal.backup.Group.GroupSnapshot.membersPendingProfileKey:type_name -> signal.backup.Group.MemberPendingProfileKey - 122, // 121: signal.backup.Group.GroupSnapshot.membersPendingAdminApproval:type_name -> signal.backup.Group.MemberPendingAdminApproval - 123, // 122: signal.backup.Group.GroupSnapshot.members_banned:type_name -> signal.backup.Group.MemberBanned - 7, // 123: signal.backup.Group.Member.role:type_name -> signal.backup.Group.Member.Role - 120, // 124: signal.backup.Group.MemberPendingProfileKey.member:type_name -> signal.backup.Group.Member - 8, // 125: signal.backup.Group.AccessControl.attributes:type_name -> signal.backup.Group.AccessControl.AccessRequired - 8, // 126: signal.backup.Group.AccessControl.members:type_name -> signal.backup.Group.AccessControl.AccessRequired - 8, // 127: signal.backup.Group.AccessControl.addFromInviteLink:type_name -> signal.backup.Group.AccessControl.AccessRequired - 45, // 128: signal.backup.ChatItem.OutgoingMessageDetails.sendStatus:type_name -> signal.backup.SendStatus - 12, // 129: signal.backup.SendStatus.Failed.reason:type_name -> signal.backup.SendStatus.Failed.FailureReason - 46, // 130: signal.backup.DirectStoryReplyMessage.TextReply.text:type_name -> signal.backup.Text - 59, // 131: signal.backup.DirectStoryReplyMessage.TextReply.longText:type_name -> signal.backup.FilePointer - 139, // 132: signal.backup.PaymentNotification.TransactionDetails.transaction:type_name -> signal.backup.PaymentNotification.TransactionDetails.Transaction - 138, // 133: signal.backup.PaymentNotification.TransactionDetails.failedTransaction:type_name -> signal.backup.PaymentNotification.TransactionDetails.FailedTransaction - 13, // 134: signal.backup.PaymentNotification.TransactionDetails.FailedTransaction.reason:type_name -> signal.backup.PaymentNotification.TransactionDetails.FailedTransaction.FailureReason - 14, // 135: signal.backup.PaymentNotification.TransactionDetails.Transaction.status:type_name -> signal.backup.PaymentNotification.TransactionDetails.Transaction.Status - 137, // 136: signal.backup.PaymentNotification.TransactionDetails.Transaction.mobileCoinIdentification:type_name -> signal.backup.PaymentNotification.TransactionDetails.MobileCoinTxoIdentification - 16, // 137: signal.backup.ContactAttachment.Phone.type:type_name -> signal.backup.ContactAttachment.Phone.Type - 17, // 138: signal.backup.ContactAttachment.Email.type:type_name -> signal.backup.ContactAttachment.Email.Type - 18, // 139: signal.backup.ContactAttachment.PostalAddress.type:type_name -> signal.backup.ContactAttachment.PostalAddress.Type - 58, // 140: signal.backup.Quote.QuotedAttachment.thumbnail:type_name -> signal.backup.MessageAttachment - 73, // 141: signal.backup.GroupChangeChatUpdate.Update.genericGroupUpdate:type_name -> signal.backup.GenericGroupUpdate - 74, // 142: signal.backup.GroupChangeChatUpdate.Update.groupCreationUpdate:type_name -> signal.backup.GroupCreationUpdate - 75, // 143: signal.backup.GroupChangeChatUpdate.Update.groupNameUpdate:type_name -> signal.backup.GroupNameUpdate - 76, // 144: signal.backup.GroupChangeChatUpdate.Update.groupAvatarUpdate:type_name -> signal.backup.GroupAvatarUpdate - 77, // 145: signal.backup.GroupChangeChatUpdate.Update.groupDescriptionUpdate:type_name -> signal.backup.GroupDescriptionUpdate - 78, // 146: signal.backup.GroupChangeChatUpdate.Update.groupMembershipAccessLevelChangeUpdate:type_name -> signal.backup.GroupMembershipAccessLevelChangeUpdate - 79, // 147: signal.backup.GroupChangeChatUpdate.Update.groupAttributesAccessLevelChangeUpdate:type_name -> signal.backup.GroupAttributesAccessLevelChangeUpdate - 80, // 148: signal.backup.GroupChangeChatUpdate.Update.groupAnnouncementOnlyChangeUpdate:type_name -> signal.backup.GroupAnnouncementOnlyChangeUpdate - 81, // 149: signal.backup.GroupChangeChatUpdate.Update.groupAdminStatusUpdate:type_name -> signal.backup.GroupAdminStatusUpdate - 82, // 150: signal.backup.GroupChangeChatUpdate.Update.groupMemberLeftUpdate:type_name -> signal.backup.GroupMemberLeftUpdate - 83, // 151: signal.backup.GroupChangeChatUpdate.Update.groupMemberRemovedUpdate:type_name -> signal.backup.GroupMemberRemovedUpdate - 84, // 152: signal.backup.GroupChangeChatUpdate.Update.selfInvitedToGroupUpdate:type_name -> signal.backup.SelfInvitedToGroupUpdate - 85, // 153: signal.backup.GroupChangeChatUpdate.Update.selfInvitedOtherUserToGroupUpdate:type_name -> signal.backup.SelfInvitedOtherUserToGroupUpdate - 86, // 154: signal.backup.GroupChangeChatUpdate.Update.groupUnknownInviteeUpdate:type_name -> signal.backup.GroupUnknownInviteeUpdate - 87, // 155: signal.backup.GroupChangeChatUpdate.Update.groupInvitationAcceptedUpdate:type_name -> signal.backup.GroupInvitationAcceptedUpdate - 88, // 156: signal.backup.GroupChangeChatUpdate.Update.groupInvitationDeclinedUpdate:type_name -> signal.backup.GroupInvitationDeclinedUpdate - 89, // 157: signal.backup.GroupChangeChatUpdate.Update.groupMemberJoinedUpdate:type_name -> signal.backup.GroupMemberJoinedUpdate - 90, // 158: signal.backup.GroupChangeChatUpdate.Update.groupMemberAddedUpdate:type_name -> signal.backup.GroupMemberAddedUpdate - 91, // 159: signal.backup.GroupChangeChatUpdate.Update.groupSelfInvitationRevokedUpdate:type_name -> signal.backup.GroupSelfInvitationRevokedUpdate - 92, // 160: signal.backup.GroupChangeChatUpdate.Update.groupInvitationRevokedUpdate:type_name -> signal.backup.GroupInvitationRevokedUpdate - 93, // 161: signal.backup.GroupChangeChatUpdate.Update.groupJoinRequestUpdate:type_name -> signal.backup.GroupJoinRequestUpdate - 94, // 162: signal.backup.GroupChangeChatUpdate.Update.groupJoinRequestApprovalUpdate:type_name -> signal.backup.GroupJoinRequestApprovalUpdate - 95, // 163: signal.backup.GroupChangeChatUpdate.Update.groupJoinRequestCanceledUpdate:type_name -> signal.backup.GroupJoinRequestCanceledUpdate - 97, // 164: signal.backup.GroupChangeChatUpdate.Update.groupInviteLinkResetUpdate:type_name -> signal.backup.GroupInviteLinkResetUpdate - 98, // 165: signal.backup.GroupChangeChatUpdate.Update.groupInviteLinkEnabledUpdate:type_name -> signal.backup.GroupInviteLinkEnabledUpdate - 99, // 166: signal.backup.GroupChangeChatUpdate.Update.groupInviteLinkAdminApprovalUpdate:type_name -> signal.backup.GroupInviteLinkAdminApprovalUpdate - 100, // 167: signal.backup.GroupChangeChatUpdate.Update.groupInviteLinkDisabledUpdate:type_name -> signal.backup.GroupInviteLinkDisabledUpdate - 101, // 168: signal.backup.GroupChangeChatUpdate.Update.groupMemberJoinedByLinkUpdate:type_name -> signal.backup.GroupMemberJoinedByLinkUpdate - 102, // 169: signal.backup.GroupChangeChatUpdate.Update.groupV2MigrationUpdate:type_name -> signal.backup.GroupV2MigrationUpdate - 103, // 170: signal.backup.GroupChangeChatUpdate.Update.groupV2MigrationSelfInvitedUpdate:type_name -> signal.backup.GroupV2MigrationSelfInvitedUpdate - 104, // 171: signal.backup.GroupChangeChatUpdate.Update.groupV2MigrationInvitedMembersUpdate:type_name -> signal.backup.GroupV2MigrationInvitedMembersUpdate - 105, // 172: signal.backup.GroupChangeChatUpdate.Update.groupV2MigrationDroppedMembersUpdate:type_name -> signal.backup.GroupV2MigrationDroppedMembersUpdate - 96, // 173: signal.backup.GroupChangeChatUpdate.Update.groupSequenceOfRequestsAndCancelsUpdate:type_name -> signal.backup.GroupSequenceOfRequestsAndCancelsUpdate - 106, // 174: signal.backup.GroupChangeChatUpdate.Update.groupExpirationTimerUpdate:type_name -> signal.backup.GroupExpirationTimerUpdate - 151, // 175: signal.backup.ChatStyle.CustomChatColor.gradient:type_name -> signal.backup.ChatStyle.Gradient - 176, // [176:176] is the sub-list for method output_type - 176, // [176:176] is the sub-list for method input_type - 176, // [176:176] is the sub-list for extension type_name - 176, // [176:176] is the sub-list for extension extendee - 0, // [0:176] is the sub-list for field type_name + 148, // 83: signal.backup.FilePointer.locatorInfo:type_name -> signal.backup.FilePointer.LocatorInfo + 46, // 84: signal.backup.Quote.text:type_name -> signal.backup.Text + 149, // 85: signal.backup.Quote.attachments:type_name -> signal.backup.Quote.QuotedAttachment + 20, // 86: signal.backup.Quote.type:type_name -> signal.backup.Quote.Type + 21, // 87: signal.backup.BodyRange.style:type_name -> signal.backup.BodyRange.Style + 66, // 88: signal.backup.ChatUpdateMessage.simpleUpdate:type_name -> signal.backup.SimpleChatUpdate + 72, // 89: signal.backup.ChatUpdateMessage.groupChange:type_name -> signal.backup.GroupChangeChatUpdate + 67, // 90: signal.backup.ChatUpdateMessage.expirationTimerChange:type_name -> signal.backup.ExpirationTimerChatUpdate + 68, // 91: signal.backup.ChatUpdateMessage.profileChange:type_name -> signal.backup.ProfileChangeChatUpdate + 70, // 92: signal.backup.ChatUpdateMessage.threadMerge:type_name -> signal.backup.ThreadMergeChatUpdate + 71, // 93: signal.backup.ChatUpdateMessage.sessionSwitchover:type_name -> signal.backup.SessionSwitchoverChatUpdate + 64, // 94: signal.backup.ChatUpdateMessage.individualCall:type_name -> signal.backup.IndividualCall + 65, // 95: signal.backup.ChatUpdateMessage.groupCall:type_name -> signal.backup.GroupCall + 69, // 96: signal.backup.ChatUpdateMessage.learnedProfileChange:type_name -> signal.backup.LearnedProfileChatUpdate + 22, // 97: signal.backup.IndividualCall.type:type_name -> signal.backup.IndividualCall.Type + 23, // 98: signal.backup.IndividualCall.direction:type_name -> signal.backup.IndividualCall.Direction + 24, // 99: signal.backup.IndividualCall.state:type_name -> signal.backup.IndividualCall.State + 25, // 100: signal.backup.GroupCall.state:type_name -> signal.backup.GroupCall.State + 26, // 101: signal.backup.SimpleChatUpdate.type:type_name -> signal.backup.SimpleChatUpdate.Type + 150, // 102: signal.backup.GroupChangeChatUpdate.updates:type_name -> signal.backup.GroupChangeChatUpdate.Update + 1, // 103: signal.backup.GroupMembershipAccessLevelChangeUpdate.accessLevel:type_name -> signal.backup.GroupV2AccessLevel + 1, // 104: signal.backup.GroupAttributesAccessLevelChangeUpdate.accessLevel:type_name -> signal.backup.GroupV2AccessLevel + 151, // 105: signal.backup.GroupInvitationRevokedUpdate.invitees:type_name -> signal.backup.GroupInvitationRevokedUpdate.Invitee + 27, // 106: signal.backup.ChatStyle.wallpaperPreset:type_name -> signal.backup.ChatStyle.WallpaperPreset + 59, // 107: signal.backup.ChatStyle.wallpaperPhoto:type_name -> signal.backup.FilePointer + 154, // 108: signal.backup.ChatStyle.autoBubbleColor:type_name -> signal.backup.ChatStyle.AutomaticBubbleColor + 28, // 109: signal.backup.ChatStyle.bubbleColorPreset:type_name -> signal.backup.ChatStyle.BubbleColorPreset + 29, // 110: signal.backup.NotificationProfile.scheduleDaysEnabled:type_name -> signal.backup.NotificationProfile.DayOfWeek + 30, // 111: signal.backup.ChatFolder.folderType:type_name -> signal.backup.ChatFolder.FolderType + 3, // 112: signal.backup.AccountData.UsernameLink.color:type_name -> signal.backup.AccountData.UsernameLink.Color + 2, // 113: signal.backup.AccountData.AccountSettings.phoneNumberSharingMode:type_name -> signal.backup.AccountData.PhoneNumberSharingMode + 108, // 114: signal.backup.AccountData.AccountSettings.defaultChatStyle:type_name -> signal.backup.ChatStyle + 153, // 115: signal.backup.AccountData.AccountSettings.customChatColors:type_name -> signal.backup.ChatStyle.CustomChatColor + 119, // 116: signal.backup.Group.GroupSnapshot.title:type_name -> signal.backup.Group.GroupAttributeBlob + 119, // 117: signal.backup.Group.GroupSnapshot.description:type_name -> signal.backup.Group.GroupAttributeBlob + 119, // 118: signal.backup.Group.GroupSnapshot.disappearingMessagesTimer:type_name -> signal.backup.Group.GroupAttributeBlob + 124, // 119: signal.backup.Group.GroupSnapshot.accessControl:type_name -> signal.backup.Group.AccessControl + 120, // 120: signal.backup.Group.GroupSnapshot.members:type_name -> signal.backup.Group.Member + 121, // 121: signal.backup.Group.GroupSnapshot.membersPendingProfileKey:type_name -> signal.backup.Group.MemberPendingProfileKey + 122, // 122: signal.backup.Group.GroupSnapshot.membersPendingAdminApproval:type_name -> signal.backup.Group.MemberPendingAdminApproval + 123, // 123: signal.backup.Group.GroupSnapshot.members_banned:type_name -> signal.backup.Group.MemberBanned + 7, // 124: signal.backup.Group.Member.role:type_name -> signal.backup.Group.Member.Role + 120, // 125: signal.backup.Group.MemberPendingProfileKey.member:type_name -> signal.backup.Group.Member + 8, // 126: signal.backup.Group.AccessControl.attributes:type_name -> signal.backup.Group.AccessControl.AccessRequired + 8, // 127: signal.backup.Group.AccessControl.members:type_name -> signal.backup.Group.AccessControl.AccessRequired + 8, // 128: signal.backup.Group.AccessControl.addFromInviteLink:type_name -> signal.backup.Group.AccessControl.AccessRequired + 45, // 129: signal.backup.ChatItem.OutgoingMessageDetails.sendStatus:type_name -> signal.backup.SendStatus + 12, // 130: signal.backup.SendStatus.Failed.reason:type_name -> signal.backup.SendStatus.Failed.FailureReason + 46, // 131: signal.backup.DirectStoryReplyMessage.TextReply.text:type_name -> signal.backup.Text + 59, // 132: signal.backup.DirectStoryReplyMessage.TextReply.longText:type_name -> signal.backup.FilePointer + 139, // 133: signal.backup.PaymentNotification.TransactionDetails.transaction:type_name -> signal.backup.PaymentNotification.TransactionDetails.Transaction + 138, // 134: signal.backup.PaymentNotification.TransactionDetails.failedTransaction:type_name -> signal.backup.PaymentNotification.TransactionDetails.FailedTransaction + 13, // 135: signal.backup.PaymentNotification.TransactionDetails.FailedTransaction.reason:type_name -> signal.backup.PaymentNotification.TransactionDetails.FailedTransaction.FailureReason + 14, // 136: signal.backup.PaymentNotification.TransactionDetails.Transaction.status:type_name -> signal.backup.PaymentNotification.TransactionDetails.Transaction.Status + 137, // 137: signal.backup.PaymentNotification.TransactionDetails.Transaction.mobileCoinIdentification:type_name -> signal.backup.PaymentNotification.TransactionDetails.MobileCoinTxoIdentification + 16, // 138: signal.backup.ContactAttachment.Phone.type:type_name -> signal.backup.ContactAttachment.Phone.Type + 17, // 139: signal.backup.ContactAttachment.Email.type:type_name -> signal.backup.ContactAttachment.Email.Type + 18, // 140: signal.backup.ContactAttachment.PostalAddress.type:type_name -> signal.backup.ContactAttachment.PostalAddress.Type + 58, // 141: signal.backup.Quote.QuotedAttachment.thumbnail:type_name -> signal.backup.MessageAttachment + 73, // 142: signal.backup.GroupChangeChatUpdate.Update.genericGroupUpdate:type_name -> signal.backup.GenericGroupUpdate + 74, // 143: signal.backup.GroupChangeChatUpdate.Update.groupCreationUpdate:type_name -> signal.backup.GroupCreationUpdate + 75, // 144: signal.backup.GroupChangeChatUpdate.Update.groupNameUpdate:type_name -> signal.backup.GroupNameUpdate + 76, // 145: signal.backup.GroupChangeChatUpdate.Update.groupAvatarUpdate:type_name -> signal.backup.GroupAvatarUpdate + 77, // 146: signal.backup.GroupChangeChatUpdate.Update.groupDescriptionUpdate:type_name -> signal.backup.GroupDescriptionUpdate + 78, // 147: signal.backup.GroupChangeChatUpdate.Update.groupMembershipAccessLevelChangeUpdate:type_name -> signal.backup.GroupMembershipAccessLevelChangeUpdate + 79, // 148: signal.backup.GroupChangeChatUpdate.Update.groupAttributesAccessLevelChangeUpdate:type_name -> signal.backup.GroupAttributesAccessLevelChangeUpdate + 80, // 149: signal.backup.GroupChangeChatUpdate.Update.groupAnnouncementOnlyChangeUpdate:type_name -> signal.backup.GroupAnnouncementOnlyChangeUpdate + 81, // 150: signal.backup.GroupChangeChatUpdate.Update.groupAdminStatusUpdate:type_name -> signal.backup.GroupAdminStatusUpdate + 82, // 151: signal.backup.GroupChangeChatUpdate.Update.groupMemberLeftUpdate:type_name -> signal.backup.GroupMemberLeftUpdate + 83, // 152: signal.backup.GroupChangeChatUpdate.Update.groupMemberRemovedUpdate:type_name -> signal.backup.GroupMemberRemovedUpdate + 84, // 153: signal.backup.GroupChangeChatUpdate.Update.selfInvitedToGroupUpdate:type_name -> signal.backup.SelfInvitedToGroupUpdate + 85, // 154: signal.backup.GroupChangeChatUpdate.Update.selfInvitedOtherUserToGroupUpdate:type_name -> signal.backup.SelfInvitedOtherUserToGroupUpdate + 86, // 155: signal.backup.GroupChangeChatUpdate.Update.groupUnknownInviteeUpdate:type_name -> signal.backup.GroupUnknownInviteeUpdate + 87, // 156: signal.backup.GroupChangeChatUpdate.Update.groupInvitationAcceptedUpdate:type_name -> signal.backup.GroupInvitationAcceptedUpdate + 88, // 157: signal.backup.GroupChangeChatUpdate.Update.groupInvitationDeclinedUpdate:type_name -> signal.backup.GroupInvitationDeclinedUpdate + 89, // 158: signal.backup.GroupChangeChatUpdate.Update.groupMemberJoinedUpdate:type_name -> signal.backup.GroupMemberJoinedUpdate + 90, // 159: signal.backup.GroupChangeChatUpdate.Update.groupMemberAddedUpdate:type_name -> signal.backup.GroupMemberAddedUpdate + 91, // 160: signal.backup.GroupChangeChatUpdate.Update.groupSelfInvitationRevokedUpdate:type_name -> signal.backup.GroupSelfInvitationRevokedUpdate + 92, // 161: signal.backup.GroupChangeChatUpdate.Update.groupInvitationRevokedUpdate:type_name -> signal.backup.GroupInvitationRevokedUpdate + 93, // 162: signal.backup.GroupChangeChatUpdate.Update.groupJoinRequestUpdate:type_name -> signal.backup.GroupJoinRequestUpdate + 94, // 163: signal.backup.GroupChangeChatUpdate.Update.groupJoinRequestApprovalUpdate:type_name -> signal.backup.GroupJoinRequestApprovalUpdate + 95, // 164: signal.backup.GroupChangeChatUpdate.Update.groupJoinRequestCanceledUpdate:type_name -> signal.backup.GroupJoinRequestCanceledUpdate + 97, // 165: signal.backup.GroupChangeChatUpdate.Update.groupInviteLinkResetUpdate:type_name -> signal.backup.GroupInviteLinkResetUpdate + 98, // 166: signal.backup.GroupChangeChatUpdate.Update.groupInviteLinkEnabledUpdate:type_name -> signal.backup.GroupInviteLinkEnabledUpdate + 99, // 167: signal.backup.GroupChangeChatUpdate.Update.groupInviteLinkAdminApprovalUpdate:type_name -> signal.backup.GroupInviteLinkAdminApprovalUpdate + 100, // 168: signal.backup.GroupChangeChatUpdate.Update.groupInviteLinkDisabledUpdate:type_name -> signal.backup.GroupInviteLinkDisabledUpdate + 101, // 169: signal.backup.GroupChangeChatUpdate.Update.groupMemberJoinedByLinkUpdate:type_name -> signal.backup.GroupMemberJoinedByLinkUpdate + 102, // 170: signal.backup.GroupChangeChatUpdate.Update.groupV2MigrationUpdate:type_name -> signal.backup.GroupV2MigrationUpdate + 103, // 171: signal.backup.GroupChangeChatUpdate.Update.groupV2MigrationSelfInvitedUpdate:type_name -> signal.backup.GroupV2MigrationSelfInvitedUpdate + 104, // 172: signal.backup.GroupChangeChatUpdate.Update.groupV2MigrationInvitedMembersUpdate:type_name -> signal.backup.GroupV2MigrationInvitedMembersUpdate + 105, // 173: signal.backup.GroupChangeChatUpdate.Update.groupV2MigrationDroppedMembersUpdate:type_name -> signal.backup.GroupV2MigrationDroppedMembersUpdate + 96, // 174: signal.backup.GroupChangeChatUpdate.Update.groupSequenceOfRequestsAndCancelsUpdate:type_name -> signal.backup.GroupSequenceOfRequestsAndCancelsUpdate + 106, // 175: signal.backup.GroupChangeChatUpdate.Update.groupExpirationTimerUpdate:type_name -> signal.backup.GroupExpirationTimerUpdate + 152, // 176: signal.backup.ChatStyle.CustomChatColor.gradient:type_name -> signal.backup.ChatStyle.Gradient + 177, // [177:177] is the sub-list for method output_type + 177, // [177:177] is the sub-list for method input_type + 177, // [177:177] is the sub-list for extension type_name + 177, // [177:177] is the sub-list for extension extendee + 0, // [0:177] is the sub-list for field type_name } func init() { file_backuppb_Backup_proto_init() } @@ -12895,8 +13132,12 @@ func file_backuppb_Backup_proto_init() { file_backuppb_Backup_proto_msgTypes[113].OneofWrappers = []any{} file_backuppb_Backup_proto_msgTypes[114].OneofWrappers = []any{} file_backuppb_Backup_proto_msgTypes[116].OneofWrappers = []any{} - file_backuppb_Backup_proto_msgTypes[117].OneofWrappers = []any{} - file_backuppb_Backup_proto_msgTypes[118].OneofWrappers = []any{ + file_backuppb_Backup_proto_msgTypes[117].OneofWrappers = []any{ + (*FilePointer_LocatorInfo_PlaintextHash)(nil), + (*FilePointer_LocatorInfo_EncryptedDigest)(nil), + } + file_backuppb_Backup_proto_msgTypes[118].OneofWrappers = []any{} + file_backuppb_Backup_proto_msgTypes[119].OneofWrappers = []any{ (*GroupChangeChatUpdate_Update_GenericGroupUpdate)(nil), (*GroupChangeChatUpdate_Update_GroupCreationUpdate)(nil), (*GroupChangeChatUpdate_Update_GroupNameUpdate)(nil), @@ -12932,8 +13173,8 @@ func file_backuppb_Backup_proto_init() { (*GroupChangeChatUpdate_Update_GroupSequenceOfRequestsAndCancelsUpdate)(nil), (*GroupChangeChatUpdate_Update_GroupExpirationTimerUpdate)(nil), } - file_backuppb_Backup_proto_msgTypes[119].OneofWrappers = []any{} - file_backuppb_Backup_proto_msgTypes[121].OneofWrappers = []any{ + file_backuppb_Backup_proto_msgTypes[120].OneofWrappers = []any{} + file_backuppb_Backup_proto_msgTypes[122].OneofWrappers = []any{ (*ChatStyle_CustomChatColor_Solid)(nil), (*ChatStyle_CustomChatColor_Gradient)(nil), } @@ -12943,7 +13184,7 @@ func file_backuppb_Backup_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: unsafe.Slice(unsafe.StringData(file_backuppb_Backup_proto_rawDesc), len(file_backuppb_Backup_proto_rawDesc)), NumEnums: 31, - NumMessages: 123, + NumMessages: 124, NumExtensions: 0, NumServices: 0, }, diff --git a/pkg/signalmeow/protobuf/backuppb/Backup.proto b/pkg/signalmeow/protobuf/backuppb/Backup.proto index 3840f93..0dd3e89 100644 --- a/pkg/signalmeow/protobuf/backuppb/Backup.proto +++ b/pkg/signalmeow/protobuf/backuppb/Backup.proto @@ -87,6 +87,9 @@ message AccountData { PhoneNumberSharingMode phoneNumberSharingMode = 17; ChatStyle defaultChatStyle = 18; repeated ChatStyle.CustomChatColor customChatColors = 19; + bool optimizeOnDeviceStorage = 20; + // See zkgroup for integer particular values. Unset if backups are not enabled. + optional uint64 backupTier = 21; } message SubscriberData { @@ -689,6 +692,7 @@ message MessageAttachment { message FilePointer { // References attachments in the backup (media) storage tier. + // DEPRECATED; use LocatorInfo instead if available. message BackupLocator { string mediaName = 1; // If present, the cdn number of the succesful upload. @@ -698,6 +702,7 @@ message FilePointer { bytes key = 3; bytes digest = 4; uint32 size = 5; + // Fallback in case backup tier upload failed. optional string transitCdnKey = 6; optional uint32 transitCdnNumber = 7; @@ -707,6 +712,7 @@ message FilePointer { // May be downloaded or not when the backup is generated; // primarily for free-tier users who cannot copy the // attachments to the backup (media) storage tier. + // DEPRECATED; use LocatorInfo instead if available. message AttachmentLocator { string cdnKey = 1; uint32 cdnNumber = 2; @@ -721,12 +727,14 @@ message FilePointer { // CDN keys or anything else that makes download attempts impossible. // This serves as a 'tombstone' so that the UX can show that an attachment // did exist, but for whatever reason it's not retrievable. + // DEPRECATED; use LocatorInfo instead if available. message InvalidAttachmentLocator { } // References attachments in a local encrypted backup. // Importers should first attempt to read the file from the local backup, // and on failure fallback to backup and transit cdn if possible. + // DEPRECATED; use LocatorInfo instead if available. message LocalLocator { string mediaName = 1; // Separate key used to encrypt this file for the local backup. @@ -742,7 +750,57 @@ message FilePointer { optional uint32 transitCdnNumber = 8; } + message LocatorInfo { + // Must be non-empty if transitCdnKey or plaintextHash are set/nonempty. + // Otherwise must be empty. + bytes key = 1; + + // From the sender of the attachment (incl. ourselves) + // Will be reserved once all clients start reading integrityCheck + bytes legacyDigest = 2; + + oneof integrityCheck { + // Set if file was at one point downloaded and its plaintextHash was calculated + bytes plaintextHash = 10; + + // Set if file has not been downloaded so its integrity has not been verified + // From the sender of the attachment + bytes encryptedDigest = 11; + } + + // NB: This is the plaintext size, and empty content attachments are legal, so this + // may be zero even if transitCdnKey or mediaName are set/nonempty. + uint32 size = 3; + + // Either both transit cdn key and number are set or neither should be set. + // Upload timestamp is optional but should only be set if key/number are set. + optional string transitCdnKey = 4; + optional uint32 transitCdnNumber = 5; + optional uint64 transitTierUploadTimestamp = 6; + + // If present, the cdn number of the succesful upload to media tier. + // If unset, may still have been uploaded, and clients + // can discover the cdn number via the list endpoint. + // Exporting clients should set this as long as their subscription + // has not rotated since last upload; even if currently free tier. + optional uint32 mediaTierCdnNumber = 7; + + // Nonempty any time the attachment was downloaded and its + // digest validated, whether free tier or paid subscription. + // Will be reserved once all clients start reading integrityCheck, + // when mediaName will be derived from the plaintextHash and encryption key + string legacyMediaName = 8; + + // Separate key used to encrypt this file for the local backup. + // Generally required for local backups. + // Missing field indicates attachment was not available locally + // when the backup was generated, but remote backup or transit + // info was available. + optional bytes localKey = 9; + } + // If unset, importers should consider it to be an InvalidAttachmentLocator without throwing an error. + // DEPRECATED; use locatorInfo instead. oneof locator { BackupLocator backupLocator = 1; AttachmentLocator attachmentLocator = 2; @@ -758,6 +816,7 @@ message FilePointer { optional uint32 height = 9; optional string caption = 10; optional string blurHash = 11; + LocatorInfo locatorInfo = 13; } message Quote { diff --git a/pkg/signalmeow/protobuf/update-protos.sh b/pkg/signalmeow/protobuf/update-protos.sh index c95420d..c3d85c0 100755 --- a/pkg/signalmeow/protobuf/update-protos.sh +++ b/pkg/signalmeow/protobuf/update-protos.sh @@ -1,8 +1,8 @@ #!/bin/bash set -euo pipefail -ANDROID_GIT_REVISION=${1:-23669c3c372284d42db486a218d9f29bef247abf} -DESKTOP_GIT_REVISION=${1:-010c38ae9bce84c676a9c464a04f7c26e7a2c9e0} +ANDROID_GIT_REVISION=${1:-4b9cac43a82b5b907de53696b93eaf521943d15c} +DESKTOP_GIT_REVISION=${1:-ffc34d5080b8b8aec1bbebf11a13227e224dffe0} update_proto() { case "$1" in From bd5cc56cfc01e2fef3bf6d66f66d405b94f76a8f Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Mon, 7 Jul 2025 15:35:45 +0300 Subject: [PATCH 365/580] signalmeow/web: make SendRequest nil-safe --- pkg/signalmeow/web/signalwebsocket.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/pkg/signalmeow/web/signalwebsocket.go b/pkg/signalmeow/web/signalwebsocket.go index c4030d6..ed60103 100644 --- a/pkg/signalmeow/web/signalwebsocket.go +++ b/pkg/signalmeow/web/signalwebsocket.go @@ -561,6 +561,9 @@ func (s *SignalWebsocket) SendRequest( ctx context.Context, request *signalpb.WebSocketRequestMessage, ) (*signalpb.WebSocketResponseMessage, error) { + if s == nil { + return nil, errors.New("websocket is nil") + } startTime := time.Now() return s.sendRequestInternal(ctx, request, startTime, 0) } From 23b2496ac950b49ffb4bb26fd6d6093a5042a49e Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Mon, 7 Jul 2025 15:36:06 +0300 Subject: [PATCH 366/580] handlematrix: move viewing chat handler to correct file --- pkg/connector/client.go | 33 --------------------------------- pkg/connector/handlematrix.go | 33 +++++++++++++++++++++++++++++++++ 2 files changed, 33 insertions(+), 33 deletions(-) diff --git a/pkg/connector/client.go b/pkg/connector/client.go index 5a0b740..925747e 100644 --- a/pkg/connector/client.go +++ b/pkg/connector/client.go @@ -339,36 +339,3 @@ func (s *SignalClient) IsLoggedIn() bool { } return s.Client.IsLoggedIn() } - -func (s *SignalClient) HandleMatrixViewingChat(ctx context.Context, msg *bridgev2.MatrixViewingChat) error { - if msg.Portal == nil || msg.Portal.OtherUserID == "" { - // Group chat changes are sent by Signal so no need to fetch them on view - return nil - } - - // Sync other user ghost info in DM rooms - ghost, err := s.Main.Bridge.GetExistingGhostByID(ctx, msg.Portal.OtherUserID) - if err != nil { - return fmt.Errorf("failed to get ghost for sync: %w", err) - } else if ghost == nil { - zerolog.Ctx(ctx).Warn(). - Str("other_user_id", string(msg.Portal.OtherUserID)). - Msg("No ghost found for other user in portal") - return nil - } - - meta := ghost.Metadata.(*signalid.GhostMetadata) - if meta.ProfileFetchedAt.Time.Add(5 * time.Minute).After(time.Now()) { - // Limit profile fetches to max one per 5 minutes - return nil - } - - // Reset, but don't save, portal last sync time for immediate sync now - meta.ProfileFetchedAt.Time = time.Time{} - info, err := s.GetUserInfoWithRefreshAfter(ctx, ghost, 5*time.Minute) - if err != nil { - return fmt.Errorf("failed to get user info: %w", err) - } - ghost.UpdateInfo(ctx, info) - return nil -} diff --git a/pkg/connector/handlematrix.go b/pkg/connector/handlematrix.go index 8137c84..09daaa2 100644 --- a/pkg/connector/handlematrix.go +++ b/pkg/connector/handlematrix.go @@ -562,3 +562,36 @@ func (s *SignalClient) HandleMatrixPowerLevels(ctx context.Context, msg *bridgev msg.Portal.Metadata.(*signalid.PortalMetadata).Revision = revision return true, nil } + +func (s *SignalClient) HandleMatrixViewingChat(ctx context.Context, msg *bridgev2.MatrixViewingChat) error { + if msg.Portal == nil || msg.Portal.OtherUserID == "" { + // Group chat changes are sent by Signal so no need to fetch them on view + return nil + } + + // Sync other user ghost info in DM rooms + ghost, err := s.Main.Bridge.GetExistingGhostByID(ctx, msg.Portal.OtherUserID) + if err != nil { + return fmt.Errorf("failed to get ghost for sync: %w", err) + } else if ghost == nil { + zerolog.Ctx(ctx).Warn(). + Str("other_user_id", string(msg.Portal.OtherUserID)). + Msg("No ghost found for other user in portal") + return nil + } + + meta := ghost.Metadata.(*signalid.GhostMetadata) + if meta.ProfileFetchedAt.Time.Add(5 * time.Minute).After(time.Now()) { + // Limit profile fetches to max one per 5 minutes + return nil + } + + // Reset, but don't save, portal last sync time for immediate sync now + meta.ProfileFetchedAt.Time = time.Time{} + info, err := s.GetUserInfoWithRefreshAfter(ctx, ghost, 5*time.Minute) + if err != nil { + return fmt.Errorf("failed to get user info: %w", err) + } + ghost.UpdateInfo(ctx, info) + return nil +} From 1e6f84962e4099bdb08b7abca22285d6065089bc Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Tue, 8 Jul 2025 13:28:25 +0300 Subject: [PATCH 367/580] chatsync: stop processing chats if queueing event fails --- pkg/connector/chatsync.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/pkg/connector/chatsync.go b/pkg/connector/chatsync.go index 5d982e7..5211270 100644 --- a/pkg/connector/chatsync.go +++ b/pkg/connector/chatsync.go @@ -147,7 +147,9 @@ func (s *SignalClient) syncChats(ctx context.Context) { } continue } - s.UserLogin.QueueRemoteEvent(resyncEvt) + if !s.UserLogin.QueueRemoteEvent(resyncEvt).Success { + return + } } s.UserLogin.Metadata.(*signalid.UserLoginMetadata).ChatsSynced = true err = s.UserLogin.Save(ctx) From 31164440c61d9fecf7fc2a77d13acce1fca81901 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Tue, 8 Jul 2025 19:12:33 +0300 Subject: [PATCH 368/580] signalmeow/receiving: don't send decryption errors for context cancellations --- pkg/signalmeow/receiving.go | 5 +++++ pkg/signalmeow/web/signalwebsocket.go | 3 +++ 2 files changed, 8 insertions(+) diff --git a/pkg/signalmeow/receiving.go b/pkg/signalmeow/receiving.go index 5b9f212..4656fd1 100644 --- a/pkg/signalmeow/receiving.go +++ b/pkg/signalmeow/receiving.go @@ -385,6 +385,11 @@ func (cli *Client) handleDecryptedResult( envelope *signalpb.Envelope, destinationServiceID libsignalgo.ServiceID, ) error { + if errors.Is(result.Err, context.Canceled) { + return result.Err + } else if ctx.Err() != nil { + return ctx.Err() + } log := zerolog.Ctx(ctx) if result.CiphertextHash != nil { defer func() { diff --git a/pkg/signalmeow/web/signalwebsocket.go b/pkg/signalmeow/web/signalwebsocket.go index ed60103..c4572d6 100644 --- a/pkg/signalmeow/web/signalwebsocket.go +++ b/pkg/signalmeow/web/signalwebsocket.go @@ -135,6 +135,9 @@ func (s *SignalWebsocket) pushStatus(ctx context.Context, status SignalWebsocket } func (s *SignalWebsocket) pushOutgoing(ctx context.Context, send SignalWebsocketSendMessage) error { + if ctx.Err() != nil { + return ctx.Err() + } s.closeLock.RLock() defer s.closeLock.RUnlock() if s.sendChannel == nil { From 7d5ba58d241e63096bd70b56c96cc0cc6a13f773 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Wed, 16 Jul 2025 11:44:44 +0300 Subject: [PATCH 369/580] Bump version to v0.8.5 --- CHANGELOG.md | 4 ++++ cmd/mautrix-signal/main.go | 2 +- go.mod | 16 ++++++++-------- go.sum | 28 ++++++++++++++-------------- 4 files changed, 27 insertions(+), 23 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f314ccf..220f3ab 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +# v0.8.5 (2025-07-16) + +* Updated libsignal to v0.76.1. + # v0.8.4 (2025-06-16) * Updated libsignal to v0.74.1. diff --git a/cmd/mautrix-signal/main.go b/cmd/mautrix-signal/main.go index 565e9bf..78f696e 100644 --- a/cmd/mautrix-signal/main.go +++ b/cmd/mautrix-signal/main.go @@ -38,7 +38,7 @@ var m = mxmain.BridgeMain{ Name: "mautrix-signal", URL: "https://github.com/mautrix/signal", Description: "A Matrix-Signal puppeting bridge.", - Version: "0.8.4", + Version: "0.8.5", Connector: &connector.SignalConnector{}, } diff --git a/go.mod b/go.mod index 54e1fd9..29aa21d 100644 --- a/go.mod +++ b/go.mod @@ -2,7 +2,7 @@ module go.mau.fi/mautrix-signal go 1.23.0 -toolchain go1.24.4 +toolchain go1.24.5 require ( github.com/coder/websocket v1.8.13 @@ -14,11 +14,11 @@ require ( github.com/stretchr/testify v1.10.0 github.com/tidwall/gjson v1.18.0 go.mau.fi/util v0.8.8 - golang.org/x/crypto v0.39.0 - golang.org/x/exp v0.0.0-20250606033433-dcc06ee1d476 - golang.org/x/net v0.41.0 + golang.org/x/crypto v0.40.0 + golang.org/x/exp v0.0.0-20250711185948-6ae5c78190dc + golang.org/x/net v0.42.0 google.golang.org/protobuf v1.36.6 - maunium.net/go/mautrix v0.24.2-0.20250617163829-26da46dbbf6e + maunium.net/go/mautrix v0.24.2 ) require ( @@ -41,9 +41,9 @@ require ( github.com/tidwall/sjson v1.2.5 // indirect github.com/yuin/goldmark v1.7.12 // indirect go.mau.fi/zeroconfig v0.1.3 // indirect - golang.org/x/sync v0.15.0 // indirect - golang.org/x/sys v0.33.0 // indirect - golang.org/x/text v0.26.0 // indirect + golang.org/x/sync v0.16.0 // indirect + golang.org/x/sys v0.34.0 // indirect + golang.org/x/text v0.27.0 // indirect gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect gopkg.in/natefinch/lumberjack.v2 v2.2.1 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect diff --git a/go.sum b/go.sum index b0dbd1c..1f8d1a9 100644 --- a/go.sum +++ b/go.sum @@ -73,21 +73,21 @@ go.mau.fi/util v0.8.8 h1:OnuEEc/sIJFhnq4kFggiImUpcmnmL/xpvQMRu5Fiy5c= go.mau.fi/util v0.8.8/go.mod h1:Y/kS3loxTEhy8Vill513EtPXr+CRDdae+Xj2BXXMy/c= go.mau.fi/zeroconfig v0.1.3 h1:As9wYDKmktjmNZW5i1vn8zvJlmGKHeVxHVIBMXsm4kM= go.mau.fi/zeroconfig v0.1.3/go.mod h1:NcSJkf180JT+1IId76PcMuLTNa1CzsFFZ0nBygIQM70= -golang.org/x/crypto v0.39.0 h1:SHs+kF4LP+f+p14esP5jAoDpHU8Gu/v9lFRK6IT5imM= -golang.org/x/crypto v0.39.0/go.mod h1:L+Xg3Wf6HoL4Bn4238Z6ft6KfEpN0tJGo53AAPC632U= -golang.org/x/exp v0.0.0-20250606033433-dcc06ee1d476 h1:bsqhLWFR6G6xiQcb+JoGqdKdRU6WzPWmK8E0jxTjzo4= -golang.org/x/exp v0.0.0-20250606033433-dcc06ee1d476/go.mod h1:3//PLf8L/X+8b4vuAfHzxeRUl04Adcb341+IGKfnqS8= -golang.org/x/net v0.41.0 h1:vBTly1HeNPEn3wtREYfy4GZ/NECgw2Cnl+nK6Nz3uvw= -golang.org/x/net v0.41.0/go.mod h1:B/K4NNqkfmg07DQYrbwvSluqCJOOXwUjeb/5lOisjbA= -golang.org/x/sync v0.15.0 h1:KWH3jNZsfyT6xfAfKiz6MRNmd46ByHDYaZ7KSkCtdW8= -golang.org/x/sync v0.15.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= +golang.org/x/crypto v0.40.0 h1:r4x+VvoG5Fm+eJcxMaY8CQM7Lb0l1lsmjGBQ6s8BfKM= +golang.org/x/crypto v0.40.0/go.mod h1:Qr1vMER5WyS2dfPHAlsOj01wgLbsyWtFn/aY+5+ZdxY= +golang.org/x/exp v0.0.0-20250711185948-6ae5c78190dc h1:TS73t7x3KarrNd5qAipmspBDS1rkMcgVG/fS1aRb4Rc= +golang.org/x/exp v0.0.0-20250711185948-6ae5c78190dc/go.mod h1:A+z0yzpGtvnG90cToK5n2tu8UJVP2XUATh+r+sfOOOc= +golang.org/x/net v0.42.0 h1:jzkYrhi3YQWD6MLBJcsklgQsoAcw89EcZbJw8Z614hs= +golang.org/x/net v0.42.0/go.mod h1:FF1RA5d3u7nAYA4z2TkclSCKh68eSXtiFwcWQpPXdt8= +golang.org/x/sync v0.16.0 h1:ycBJEhp9p4vXvUZNszeOq0kGTPghopOL8q0fq3vstxw= +golang.org/x/sync v0.16.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.33.0 h1:q3i8TbbEz+JRD9ywIRlyRAQbM0qF7hu24q3teo2hbuw= -golang.org/x/sys v0.33.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= -golang.org/x/text v0.26.0 h1:P42AVeLghgTYr4+xUnTRKDMqpar+PtX7KWuNQL21L8M= -golang.org/x/text v0.26.0/go.mod h1:QK15LZJUUQVJxhz7wXgxSy/CJaTFjd0G+YLonydOVQA= +golang.org/x/sys v0.34.0 h1:H5Y5sJ2L2JRdyv7ROF1he/lPdvFsd0mJHFw2ThKHxLA= +golang.org/x/sys v0.34.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= +golang.org/x/text v0.27.0 h1:4fGWRpyh641NLlecmyl4LOe6yDdfaYNrGb2zdfo4JV4= +golang.org/x/text v0.27.0/go.mod h1:1D28KMCvyooCX9hBiosv5Tz/+YLxj0j7XhWjpSUF7CU= google.golang.org/protobuf v1.36.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY= google.golang.org/protobuf v1.36.6/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= @@ -99,5 +99,5 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= maunium.net/go/mauflag v1.0.0 h1:YiaRc0tEI3toYtJMRIfjP+jklH45uDHtT80nUamyD4M= maunium.net/go/mauflag v1.0.0/go.mod h1:nLivPOpTpHnpzEh8jEdSL9UqO9+/KBJFmNRlwKfkPeA= -maunium.net/go/mautrix v0.24.2-0.20250617163829-26da46dbbf6e h1:Y8kbRpPcKMZn2gIjUFd15xzMB5GJ2bS6ZcOfvlx4KnE= -maunium.net/go/mautrix v0.24.2-0.20250617163829-26da46dbbf6e/go.mod h1:Xy6o+pXmbqmgWsUWh15EQ1eozjC+k/VT/7kloByv9PI= +maunium.net/go/mautrix v0.24.2 h1:+AVT5kbcA/QuT5svrJKp4ivwoUmz+RRplMp3DnfpheI= +maunium.net/go/mautrix v0.24.2/go.mod h1:1ut900w++eE9by9yqCR2dQdMqwsHwZG5L+1bKB1EvSA= From 9e6b701ad858fe46e4879753848c467c95c85432 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Thu, 17 Jul 2025 11:28:46 +0300 Subject: [PATCH 370/580] .github: update issue templates [skip ci] --- .github/ISSUE_TEMPLATE/bug.md | 10 ++++++---- .github/ISSUE_TEMPLATE/enhancement.md | 2 +- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/bug.md b/.github/ISSUE_TEMPLATE/bug.md index 18862a5..3703df9 100644 --- a/.github/ISSUE_TEMPLATE/bug.md +++ b/.github/ISSUE_TEMPLATE/bug.md @@ -1,14 +1,16 @@ --- name: Bug report about: If something is definitely wrong in the bridge (rather than just a setup issue), - file a bug report. Remember to include relevant logs. -labels: bug + file a bug report. Remember to include relevant logs. Asking in the Matrix room first + is strongly recommended. +type: Bug --- diff --git a/.github/ISSUE_TEMPLATE/enhancement.md b/.github/ISSUE_TEMPLATE/enhancement.md index 264e67f..a04fe58 100644 --- a/.github/ISSUE_TEMPLATE/enhancement.md +++ b/.github/ISSUE_TEMPLATE/enhancement.md @@ -1,6 +1,6 @@ --- name: Enhancement request about: Submit a feature request or other suggestion -labels: enhancement +type: Feature --- From 69d54526b4b63ce5c79cccf8baa277a21f90acf1 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Fri, 18 Jul 2025 15:24:16 +0300 Subject: [PATCH 371/580] capabilities: remove delete max age in note to self room --- pkg/connector/capabilities.go | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/pkg/connector/capabilities.go b/pkg/connector/capabilities.go index 072c6fa..f0f71ff 100644 --- a/pkg/connector/capabilities.go +++ b/pkg/connector/capabilities.go @@ -160,7 +160,8 @@ var signalCapsNoteToSelf *event.RoomFeatures func init() { signalCapsNoteToSelf = ptr.Clone(signalCaps) signalCapsNoteToSelf.EditMaxAge = nil - signalCapsNoteToSelf.ID = capID() + "+note_to_self" + signalCapsNoteToSelf.DeleteMaxAge = nil + signalCapsNoteToSelf.ID = capID() + "+note_to_self.2" } func (s *SignalClient) GetCapabilities(ctx context.Context, portal *bridgev2.Portal) *event.RoomFeatures { @@ -180,5 +181,5 @@ func (s *SignalConnector) GetCapabilities() *bridgev2.NetworkGeneralCapabilities } func (s *SignalConnector) GetBridgeInfoVersion() (info, capabilities int) { - return 1, 3 + return 1, 4 } From c245fa474f7437d0cb0b6b27b49af25271f2b787 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Fri, 18 Jul 2025 15:58:17 +0300 Subject: [PATCH 372/580] handlesignal: add support for delete for me --- pkg/connector/handlesignal.go | 142 +++++++++++++++++++++++++++ pkg/libsignalgo/groupsecretparams.go | 11 ++- pkg/signalmeow/events/message.go | 9 +- pkg/signalmeow/groups.go | 4 +- pkg/signalmeow/receiving.go | 9 +- pkg/signalmeow/store/backup_store.go | 2 +- pkg/signalmeow/types/identifer.go | 4 + 7 files changed, 174 insertions(+), 7 deletions(-) diff --git a/pkg/connector/handlesignal.go b/pkg/connector/handlesignal.go index 634c5ca..f77d87d 100644 --- a/pkg/connector/handlesignal.go +++ b/pkg/connector/handlesignal.go @@ -18,6 +18,7 @@ package connector import ( "context" + "encoding/base64" "fmt" "strings" "time" @@ -31,6 +32,7 @@ import ( "maunium.net/go/mautrix/bridgev2/simplevent" "maunium.net/go/mautrix/event" + "go.mau.fi/mautrix-signal/pkg/libsignalgo" "go.mau.fi/mautrix-signal/pkg/signalid" "go.mau.fi/mautrix-signal/pkg/signalmeow/events" signalpb "go.mau.fi/mautrix-signal/pkg/signalmeow/protobuf" @@ -47,6 +49,8 @@ func (s *SignalClient) handleSignalEvent(rawEvt events.SignalEvent) bool { return s.handleSignalReceipt(evt) case *events.ReadSelf: return s.handleSignalReadSelf(evt) + case *events.DeleteForMe: + return s.handleSignalDeleteForMe(evt) case *events.Call: return s.Main.Bridge.QueueRemoteEvent(s.UserLogin, s.wrapCallEvent(evt)).Success case *events.ContactList: @@ -469,6 +473,144 @@ func (s *SignalClient) handleSignalReadSelf(evt *events.ReadSelf) bool { return s.dispatchReceipts(s.Client.Store.ACI, signalpb.ReceiptMessage_READ, receipts) } +func (s *SignalClient) conversationIDToPortalKey(ctx context.Context, cid *signalpb.ConversationIdentifier) (networkid.PortalKey, bool) { + log := zerolog.Ctx(ctx) + switch ident := cid.GetIdentifier().(type) { + case *signalpb.ConversationIdentifier_ThreadServiceId: + serviceID, err := libsignalgo.ServiceIDFromString(ident.ThreadServiceId) + if err != nil { + log.Err(err).Str("chat_id", ident.ThreadServiceId).Msg("Failed to parse delete for me conversation ID") + return networkid.PortalKey{}, false + } + return s.makeDMPortalKey(serviceID), true + case *signalpb.ConversationIdentifier_ThreadGroupId: + if len(ident.ThreadGroupId) != libsignalgo.GroupIdentifierLength { + log.Error(). + Str("chat_id", base64.StdEncoding.EncodeToString(ident.ThreadGroupId)). + Msg("Invalid group ID length in delete for me conversation") + return networkid.PortalKey{}, false + } + return s.makePortalKey((*libsignalgo.GroupIdentifier)(ident.ThreadGroupId).String()), true + case *signalpb.ConversationIdentifier_ThreadE164: + log.Warn().Str("chat_id", ident.ThreadE164).Msg("Unsupported E164 conversation ID in delete for me") + return networkid.PortalKey{}, false + default: + log.Warn(). + Type("chat_id_type", ident). + Msg("Unsupported conversation ID protobuf type in delete for me") + return networkid.PortalKey{}, false + } +} + +func (s *SignalClient) addressableMessageToID(ctx context.Context, portalKey networkid.PortalKey, am *signalpb.AddressableMessage) networkid.MessageID { + log := zerolog.Ctx(ctx) + switch typedAuthor := am.GetAuthor().(type) { + case *signalpb.AddressableMessage_AuthorServiceId: + serviceID, err := libsignalgo.ServiceIDFromString(typedAuthor.AuthorServiceId) + if err != nil { + log.Err(err). + Object("portal_key", portalKey). + Str("author_service_id", typedAuthor.AuthorServiceId). + Msg("Failed to parse delete for me message author service ID") + return "" + } else if serviceID.Type != libsignalgo.ServiceIDTypeACI { + log.Warn(). + Object("portal_key", portalKey). + Str("author_service_id", typedAuthor.AuthorServiceId). + Msg("Dropping delete for me message with unsupported service ID type") + return "" + } + return signalid.MakeMessageID(serviceID.UUID, am.GetSentTimestamp()) + case *signalpb.AddressableMessage_AuthorE164: + log.Warn(). + Object("portal_key", portalKey). + Str("author_e164", typedAuthor.AuthorE164). + Msg("Dropping delete for me message with unsupported E164 author") + return "" + default: + log.Warn(). + Object("portal_key", portalKey). + Type("author_type", typedAuthor). + Msg("Dropping delete for me message with unrecognized author protobuf type") + return "" + } +} + +func (s *SignalClient) handleSignalDeleteForMe(evt *events.DeleteForMe) bool { + log := s.UserLogin.Log.With(). + Str("action", "handle signal delete for me"). + Logger() + ctx := log.WithContext(s.Main.Bridge.BackgroundCtx) + for _, conv := range evt.GetConversationDeletes() { + if !conv.GetIsFullDelete() { + // Non-full deletes might mean clearing chats? + continue + } + portalKey, ok := s.conversationIDToPortalKey(ctx, conv.GetConversation()) + if !ok { + continue + } + + res := s.UserLogin.QueueRemoteEvent(&simplevent.ChatDelete{ + EventMeta: simplevent.EventMeta{ + Type: bridgev2.RemoteEventChatDelete, + PortalKey: portalKey, + Timestamp: time.UnixMilli(int64(evt.Timestamp)), + StreamOrder: int64(evt.Timestamp), + }, + OnlyForMe: true, + }) + if !res.Success { + return false + } + } + for _, conv := range evt.GetLocalOnlyConversationDeletes() { + portalKey, ok := s.conversationIDToPortalKey(ctx, conv.GetConversation()) + if !ok { + continue + } + + res := s.UserLogin.QueueRemoteEvent(&simplevent.ChatDelete{ + EventMeta: simplevent.EventMeta{ + Type: bridgev2.RemoteEventChatDelete, + PortalKey: portalKey, + Timestamp: time.UnixMilli(int64(evt.Timestamp)), + StreamOrder: int64(evt.Timestamp), + }, + OnlyForMe: true, + }) + if !res.Success { + return false + } + } + for _, conv := range evt.GetMessageDeletes() { + portalKey, ok := s.conversationIDToPortalKey(ctx, conv.GetConversation()) + if !ok { + continue + } + for _, msg := range conv.GetMessages() { + msgID := s.addressableMessageToID(ctx, portalKey, msg) + if msgID == "" { + continue + } + res := s.UserLogin.QueueRemoteEvent(&simplevent.MessageRemove{ + EventMeta: simplevent.EventMeta{ + Type: bridgev2.RemoteEventMessageRemove, + PortalKey: portalKey, + Timestamp: time.UnixMilli(int64(evt.Timestamp)), + StreamOrder: int64(evt.Timestamp), + }, + OnlyForMe: true, + TargetMessage: msgID, + }) + if !res.Success { + return false + } + } + } + return true +} + func (s *SignalClient) handleSignalACIFound(evt *events.ACIFound) { log := s.UserLogin.Log.With(). Str("action", "handle aci found"). diff --git a/pkg/libsignalgo/groupsecretparams.go b/pkg/libsignalgo/groupsecretparams.go index c6189af..5ad11fd 100644 --- a/pkg/libsignalgo/groupsecretparams.go +++ b/pkg/libsignalgo/groupsecretparams.go @@ -23,6 +23,7 @@ package libsignalgo import "C" import ( "crypto/rand" + "encoding/base64" "fmt" "runtime" "unsafe" @@ -42,11 +43,19 @@ func GenerateRandomness() Randomness { } const GroupMasterKeyLength = C.SignalGROUP_MASTER_KEY_LEN +const GroupIdentifierLength = C.SignalGROUP_IDENTIFIER_LEN type GroupMasterKey [GroupMasterKeyLength]byte type GroupSecretParams [C.SignalGROUP_SECRET_PARAMS_LEN]byte type GroupPublicParams [C.SignalGROUP_PUBLIC_PARAMS_LEN]byte -type GroupIdentifier [C.SignalGROUP_IDENTIFIER_LEN]byte +type GroupIdentifier [GroupIdentifierLength]byte + +func (gid *GroupIdentifier) String() string { + if gid == nil { + return "" + } + return base64.StdEncoding.EncodeToString(gid[:]) +} type UUIDCiphertext [C.SignalUUID_CIPHERTEXT_LEN]byte type ProfileKeyCiphertext [C.SignalPROFILE_KEY_CIPHERTEXT_LEN]byte diff --git a/pkg/signalmeow/events/message.go b/pkg/signalmeow/events/message.go index 9b8e79d..8a13329 100644 --- a/pkg/signalmeow/events/message.go +++ b/pkg/signalmeow/events/message.go @@ -35,6 +35,7 @@ func (*ReadSelf) isSignalEvent() {} func (*Call) isSignalEvent() {} func (*ContactList) isSignalEvent() {} func (*ACIFound) isSignalEvent() {} +func (*DeleteForMe) isSignalEvent() {} func (*QueueEmpty) isSignalEvent() {} type MessageInfo struct { @@ -62,7 +63,8 @@ type Receipt struct { } type ReadSelf struct { - Messages []*signalpb.SyncMessage_Read + Timestamp uint64 + Messages []*signalpb.SyncMessage_Read } type Call struct { @@ -80,4 +82,9 @@ type ACIFound struct { ACI libsignalgo.ServiceID } +type DeleteForMe struct { + Timestamp uint64 + *signalpb.SyncMessage_DeleteForMe +} + type QueueEmpty struct{} diff --git a/pkg/signalmeow/groups.go b/pkg/signalmeow/groups.go index 35544f7..8c0a841 100644 --- a/pkg/signalmeow/groups.go +++ b/pkg/signalmeow/groups.go @@ -452,9 +452,7 @@ func groupIdentifierFromMasterKey(masterKey types.SerializedGroupMasterKey) (typ if err != nil { return "", err } - base64GroupIdentifier := base64.StdEncoding.EncodeToString(groupIdentifier[:]) - gid := types.GroupIdentifier(base64GroupIdentifier) - return gid, nil + return types.BytesToGroupIdentifier(groupIdentifier), nil } func decryptGroup(ctx context.Context, encryptedGroup *signalpb.Group, groupMasterKey types.SerializedGroupMasterKey) (*Group, error) { diff --git a/pkg/signalmeow/receiving.go b/pkg/signalmeow/receiving.go index 4656fd1..49ed0f3 100644 --- a/pkg/signalmeow/receiving.go +++ b/pkg/signalmeow/receiving.go @@ -631,7 +631,14 @@ func (cli *Client) handleDecryptedResult( } if content.SyncMessage.Read != nil { handlerSuccess = cli.handleEvent(&events.ReadSelf{ - Messages: content.SyncMessage.GetRead(), + Timestamp: envelope.GetTimestamp(), + Messages: content.SyncMessage.GetRead(), + }) + } + if content.SyncMessage.DeleteForMe != nil { + handlerSuccess = cli.handleEvent(&events.DeleteForMe{ + Timestamp: envelope.GetTimestamp(), + SyncMessage_DeleteForMe: content.SyncMessage.DeleteForMe, }) } diff --git a/pkg/signalmeow/store/backup_store.go b/pkg/signalmeow/store/backup_store.go index edcb658..4575b05 100644 --- a/pkg/signalmeow/store/backup_store.go +++ b/pkg/signalmeow/store/backup_store.go @@ -183,7 +183,7 @@ func (s *sqlStore) AddBackupRecipient(ctx context.Context, recipient *backuppb.R zerolog.Ctx(ctx).Err(err). Uint64("recipient_id", recipient.Id). Msg("Failed to get group identifier from master key") - } else if err = s.StoreMasterKey(ctx, types.GroupIdentifier(base64.StdEncoding.EncodeToString(gid[:])), groupMasterKey); err != nil { + } else if err = s.StoreMasterKey(ctx, types.BytesToGroupIdentifier(gid), groupMasterKey); err != nil { return fmt.Errorf("failed to save group master key for recipient %d: %w", recipient.Id, err) } } else { diff --git a/pkg/signalmeow/types/identifer.go b/pkg/signalmeow/types/identifer.go index 87ed647..f1c02dc 100644 --- a/pkg/signalmeow/types/identifer.go +++ b/pkg/signalmeow/types/identifer.go @@ -25,6 +25,10 @@ import ( type GroupIdentifier string +func BytesToGroupIdentifier(raw *libsignalgo.GroupIdentifier) GroupIdentifier { + return GroupIdentifier(raw.String()) +} + func (gid GroupIdentifier) String() string { return string(gid) } From 8201f9b1af45b9d89b91d551337ba1a2f3a26467 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Wed, 23 Jul 2025 11:17:36 +0300 Subject: [PATCH 373/580] libsignal: update to v0.76.7 --- pkg/libsignalgo/error.go | 2 +- pkg/libsignalgo/libsignal | 2 +- pkg/libsignalgo/libsignal-ffi.h | 35 +++++++++++++++++++++------------ pkg/libsignalgo/version.go | 2 +- 4 files changed, 25 insertions(+), 16 deletions(-) diff --git a/pkg/libsignalgo/error.go b/pkg/libsignalgo/error.go index 8b83a48..b0d79c8 100644 --- a/pkg/libsignalgo/error.go +++ b/pkg/libsignalgo/error.go @@ -92,7 +92,7 @@ func wrapError(signalError *C.SignalFfiError) error { func wrapSignalError(signalError *C.SignalFfiError, errorType C.uint32_t) error { var messageBytes *C.char - getMessageError := C.signal_error_get_message(signalError, &messageBytes) + getMessageError := C.signal_error_get_message(&messageBytes, signalError) if getMessageError != nil { // Ignore any errors from this, it will just end up being an empty string. C.signal_error_free(getMessageError) diff --git a/pkg/libsignalgo/libsignal b/pkg/libsignalgo/libsignal index 6dc0f85..9fc4534 160000 --- a/pkg/libsignalgo/libsignal +++ b/pkg/libsignalgo/libsignal @@ -1 +1 @@ -Subproject commit 6dc0f85b07d890fd02e727a0f8484a1f3f864f7e +Subproject commit 9fc4534b29fc488beeba082dd739aeae73032908 diff --git a/pkg/libsignalgo/libsignal-ffi.h b/pkg/libsignalgo/libsignal-ffi.h index 0288e34..d52782d 100644 --- a/pkg/libsignalgo/libsignal-ffi.h +++ b/pkg/libsignalgo/libsignal-ffi.h @@ -864,6 +864,11 @@ typedef struct { const SignalDecryptionErrorMessage *raw; } SignalConstPointerDecryptionErrorMessage; +/** + * Like [`std::panic::AssertUnwindSafe`], but FFI-compatible. + */ +typedef const SignalFfiError *SignalUnwindSafeArgSignalFfiError; + typedef struct { SignalFingerprint *raw; } SignalMutPointerFingerprint; @@ -1588,31 +1593,31 @@ SignalFfiError *signal_encrypt_message(SignalMutPointerCiphertextMessage *out, S void signal_error_free(SignalFfiError *err); -SignalFfiError *signal_error_get_address(const SignalFfiError *err, SignalMutPointerProtocolAddress *out); +SignalFfiError *signal_error_get_address(SignalMutPointerProtocolAddress *out, SignalUnwindSafeArgSignalFfiError err); -SignalFfiError *signal_error_get_invalid_protocol_address(const SignalFfiError *err, const char **name_out, uint32_t *device_id_out); +SignalFfiError *signal_error_get_invalid_protocol_address(const char **name_out, uint32_t *device_id_out, const SignalFfiError *err); -SignalFfiError *signal_error_get_message(const SignalFfiError *err, const char **out); +SignalFfiError *signal_error_get_message(const char **out, SignalUnwindSafeArgSignalFfiError err); -SignalFfiError *signal_error_get_our_fingerprint_version(const SignalFfiError *err, uint32_t *out); +SignalFfiError *signal_error_get_our_fingerprint_version(uint32_t *out, SignalUnwindSafeArgSignalFfiError err); -SignalFfiError *signal_error_get_rate_limit_challenge(const SignalFfiError *err, const char **out_token, SignalOwnedBuffer *out_options); +SignalFfiError *signal_error_get_rate_limit_challenge(const char **out_token, SignalOwnedBuffer *out_options, const SignalFfiError *err); -SignalFfiError *signal_error_get_registration_error_not_deliverable(const SignalFfiError *err, const char **out_reason, bool *out_permanent); +SignalFfiError *signal_error_get_registration_error_not_deliverable(const char **out_reason, bool *out_permanent, const SignalFfiError *err); -SignalFfiError *signal_error_get_registration_lock(const SignalFfiError *err, uint64_t *out_time_remaining_seconds, const char **out_svr2_username, const char **out_svr2_password); +SignalFfiError *signal_error_get_registration_lock(uint64_t *out_time_remaining_seconds, const char **out_svr2_username, const char **out_svr2_password, const SignalFfiError *err); -SignalFfiError *signal_error_get_retry_after_seconds(const SignalFfiError *err, uint32_t *out); +SignalFfiError *signal_error_get_retry_after_seconds(uint32_t *out, SignalUnwindSafeArgSignalFfiError err); -SignalFfiError *signal_error_get_their_fingerprint_version(const SignalFfiError *err, uint32_t *out); +SignalFfiError *signal_error_get_their_fingerprint_version(uint32_t *out, SignalUnwindSafeArgSignalFfiError err); -SignalFfiError *signal_error_get_tries_remaining(const SignalFfiError *err, uint32_t *out); +SignalFfiError *signal_error_get_tries_remaining(uint32_t *out, SignalUnwindSafeArgSignalFfiError err); uint32_t signal_error_get_type(const SignalFfiError *err); -SignalFfiError *signal_error_get_unknown_fields(const SignalFfiError *err, SignalStringArray *out); +SignalFfiError *signal_error_get_unknown_fields(SignalStringArray *out, SignalUnwindSafeArgSignalFfiError err); -SignalFfiError *signal_error_get_uuid(const SignalFfiError *err, uint8_t (*out)[16]); +SignalFfiError *signal_error_get_uuid(uint8_t (*out)[16], SignalUnwindSafeArgSignalFfiError err); SignalFfiError *signal_expiring_profile_key_credential_check_valid_contents(SignalBorrowedBuffer buffer); @@ -1998,6 +2003,8 @@ SignalFfiError *signal_privatekey_generate(SignalMutPointerPrivateKey *out); SignalFfiError *signal_privatekey_get_public_key(SignalMutPointerPublicKey *out, SignalConstPointerPrivateKey k); +SignalFfiError *signal_privatekey_hpke_open(SignalOwnedBuffer *out, SignalConstPointerPrivateKey sk, SignalBorrowedBuffer ciphertext, SignalBorrowedBuffer info, SignalBorrowedBuffer associated_data); + SignalFfiError *signal_privatekey_serialize(SignalOwnedBuffer *out, SignalConstPointerPrivateKey obj); SignalFfiError *signal_privatekey_sign(SignalOwnedBuffer *out, SignalConstPointerPrivateKey key, SignalBorrowedBuffer message); @@ -2042,6 +2049,8 @@ SignalFfiError *signal_publickey_equals(bool *out, SignalConstPointerPublicKey l SignalFfiError *signal_publickey_get_public_key_bytes(SignalOwnedBuffer *out, SignalConstPointerPublicKey obj); +SignalFfiError *signal_publickey_hpke_seal(SignalOwnedBuffer *out, SignalConstPointerPublicKey pk, SignalBorrowedBuffer plaintext, SignalBorrowedBuffer info, SignalBorrowedBuffer associated_data); + SignalFfiError *signal_publickey_serialize(SignalOwnedBuffer *out, SignalConstPointerPublicKey obj); SignalFfiError *signal_publickey_verify(bool *out, SignalConstPointerPublicKey key, SignalBorrowedBuffer message, SignalBorrowedBuffer signature); @@ -2118,7 +2127,7 @@ SignalFfiError *signal_registration_service_register_account(SignalCPromiseMutPo SignalFfiError *signal_registration_service_registration_session(SignalMutPointerRegistrationSession *out, SignalConstPointerRegistrationService service); -SignalFfiError *signal_registration_service_request_push_challenge(SignalCPromisebool *promise, SignalConstPointerTokioAsyncContext async_runtime, SignalConstPointerRegistrationService service, const char *push_token, const void *push_token_type); +SignalFfiError *signal_registration_service_request_push_challenge(SignalCPromisebool *promise, SignalConstPointerTokioAsyncContext async_runtime, SignalConstPointerRegistrationService service, const char *push_token); SignalFfiError *signal_registration_service_request_verification_code(SignalCPromisebool *promise, SignalConstPointerTokioAsyncContext async_runtime, SignalConstPointerRegistrationService service, const char *transport, const char *client, SignalBorrowedBytestringArray languages); diff --git a/pkg/libsignalgo/version.go b/pkg/libsignalgo/version.go index e9ce0db..90264fd 100644 --- a/pkg/libsignalgo/version.go +++ b/pkg/libsignalgo/version.go @@ -2,4 +2,4 @@ package libsignalgo -const Version = "v0.76.1" +const Version = "v0.76.7" From 0833cb544052a4455cf91e6c2199a15ee7300afd Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Wed, 23 Jul 2025 11:18:43 +0300 Subject: [PATCH 374/580] signalmeow: update protobufs --- pkg/signalmeow/protobuf/SignalService.pb.go | 15 ++++++++--- pkg/signalmeow/protobuf/SignalService.proto | 1 + pkg/signalmeow/protobuf/StorageService.pb.go | 13 ++++++++-- pkg/signalmeow/protobuf/StorageService.proto | 1 + pkg/signalmeow/protobuf/backuppb/Backup.pb.go | 26 ++++++++++++++++--- pkg/signalmeow/protobuf/backuppb/Backup.proto | 2 ++ pkg/signalmeow/protobuf/update-protos.sh | 4 +-- 7 files changed, 51 insertions(+), 11 deletions(-) diff --git a/pkg/signalmeow/protobuf/SignalService.pb.go b/pkg/signalmeow/protobuf/SignalService.pb.go index 46214d7..fd875ac 100644 --- a/pkg/signalmeow/protobuf/SignalService.pb.go +++ b/pkg/signalmeow/protobuf/SignalService.pb.go @@ -6660,6 +6660,7 @@ type SyncMessage_CallLinkUpdate struct { RootKey []byte `protobuf:"bytes,1,opt,name=rootKey" json:"rootKey,omitempty"` AdminPasskey []byte `protobuf:"bytes,2,opt,name=adminPasskey" json:"adminPasskey,omitempty"` Type *SyncMessage_CallLinkUpdate_Type `protobuf:"varint,3,opt,name=type,enum=signalservice.SyncMessage_CallLinkUpdate_Type" json:"type,omitempty"` // defaults to UPDATE + Epoch []byte `protobuf:"bytes,4,opt,name=epoch" json:"epoch,omitempty"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } @@ -6715,6 +6716,13 @@ func (x *SyncMessage_CallLinkUpdate) GetType() SyncMessage_CallLinkUpdate_Type { return SyncMessage_CallLinkUpdate_UPDATE } +func (x *SyncMessage_CallLinkUpdate) GetEpoch() []byte { + if x != nil { + return x.Epoch + } + return nil +} + type SyncMessage_CallLogEvent struct { state protoimpl.MessageState `protogen:"open.v1"` Type *SyncMessage_CallLogEvent_Type `protobuf:"varint,1,opt,name=type,enum=signalservice.SyncMessage_CallLogEvent_Type" json:"type,omitempty"` @@ -8082,7 +8090,7 @@ const file_SignalService_proto_rawDesc = "" + "\aDEFAULT\x10\x00\x12\f\n" + "\bVERIFIED\x10\x01\x12\x0e\n" + "\n" + - "UNVERIFIED\x10\x02J\x04\b\x01\x10\x02\"\xf1C\n" + + "UNVERIFIED\x10\x02J\x04\b\x01\x10\x02\"\x87D\n" + "\vSyncMessage\x123\n" + "\x04sent\x18\x01 \x01(\v2\x1f.signalservice.SyncMessage.SentR\x04sent\x12?\n" + "\bcontacts\x18\x02 \x01(\v2#.signalservice.SyncMessage.ContactsR\bcontacts\x12<\n" + @@ -8247,11 +8255,12 @@ const file_SignalService_proto_rawDesc = "" + "\fNOT_ACCEPTED\x10\x02\x12\n" + "\n" + "\x06DELETE\x10\x03\x12\f\n" + - "\bOBSERVED\x10\x04\x1a\xac\x01\n" + + "\bOBSERVED\x10\x04\x1a\xc2\x01\n" + "\x0eCallLinkUpdate\x12\x18\n" + "\arootKey\x18\x01 \x01(\fR\arootKey\x12\"\n" + "\fadminPasskey\x18\x02 \x01(\fR\fadminPasskey\x12B\n" + - "\x04type\x18\x03 \x01(\x0e2..signalservice.SyncMessage.CallLinkUpdate.TypeR\x04type\"\x18\n" + + "\x04type\x18\x03 \x01(\x0e2..signalservice.SyncMessage.CallLinkUpdate.TypeR\x04type\x12\x14\n" + + "\x05epoch\x18\x04 \x01(\fR\x05epoch\"\x18\n" + "\x04Type\x12\n" + "\n" + "\x06UPDATE\x10\x00\"\x04\b\x01\x10\x01\x1a\x94\x02\n" + diff --git a/pkg/signalmeow/protobuf/SignalService.proto b/pkg/signalmeow/protobuf/SignalService.proto index 51213ca..a1fa8f9 100644 --- a/pkg/signalmeow/protobuf/SignalService.proto +++ b/pkg/signalmeow/protobuf/SignalService.proto @@ -628,6 +628,7 @@ message SyncMessage { optional bytes rootKey = 1; optional bytes adminPasskey = 2; optional Type type = 3; // defaults to UPDATE + optional bytes epoch = 4; } message CallLogEvent { diff --git a/pkg/signalmeow/protobuf/StorageService.pb.go b/pkg/signalmeow/protobuf/StorageService.pb.go index c6ce93e..3bfa1c1 100644 --- a/pkg/signalmeow/protobuf/StorageService.pb.go +++ b/pkg/signalmeow/protobuf/StorageService.pb.go @@ -1962,6 +1962,7 @@ type CallLinkRecord struct { RootKey []byte `protobuf:"bytes,1,opt,name=rootKey,proto3" json:"rootKey,omitempty"` AdminPasskey []byte `protobuf:"bytes,2,opt,name=adminPasskey,proto3" json:"adminPasskey,omitempty"` DeletedAtTimestampMs uint64 `protobuf:"varint,3,opt,name=deletedAtTimestampMs,proto3" json:"deletedAtTimestampMs,omitempty"` + Epoch []byte `protobuf:"bytes,4,opt,name=epoch,proto3" json:"epoch,omitempty"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } @@ -2017,6 +2018,13 @@ func (x *CallLinkRecord) GetDeletedAtTimestampMs() uint64 { return 0 } +func (x *CallLinkRecord) GetEpoch() []byte { + if x != nil { + return x.Epoch + } + return nil +} + type Recipient struct { state protoimpl.MessageState `protogen:"open.v1"` // Types that are valid to be assigned to Identifier: @@ -3259,11 +3267,12 @@ const file_StorageService_proto_rawDesc = "" + "\x13recipientServiceIds\x18\x03 \x03(\tR\x13recipientServiceIds\x12.\n" + "\x12deletedAtTimestamp\x18\x04 \x01(\x04R\x12deletedAtTimestamp\x12$\n" + "\rallowsReplies\x18\x05 \x01(\bR\rallowsReplies\x12 \n" + - "\visBlockList\x18\x06 \x01(\bR\visBlockList\"\x82\x01\n" + + "\visBlockList\x18\x06 \x01(\bR\visBlockList\"\x98\x01\n" + "\x0eCallLinkRecord\x12\x18\n" + "\arootKey\x18\x01 \x01(\fR\arootKey\x12\"\n" + "\fadminPasskey\x18\x02 \x01(\fR\fadminPasskey\x122\n" + - "\x14deletedAtTimestampMs\x18\x03 \x01(\x04R\x14deletedAtTimestampMs\"\xe6\x01\n" + + "\x14deletedAtTimestampMs\x18\x03 \x01(\x04R\x14deletedAtTimestampMs\x12\x14\n" + + "\x05epoch\x18\x04 \x01(\fR\x05epoch\"\xe6\x01\n" + "\tRecipient\x12<\n" + "\acontact\x18\x01 \x01(\v2 .signalservice.Recipient.ContactH\x00R\acontact\x12&\n" + "\rlegacyGroupId\x18\x02 \x01(\fH\x00R\rlegacyGroupId\x12(\n" + diff --git a/pkg/signalmeow/protobuf/StorageService.proto b/pkg/signalmeow/protobuf/StorageService.proto index eaa1453..2229805 100644 --- a/pkg/signalmeow/protobuf/StorageService.proto +++ b/pkg/signalmeow/protobuf/StorageService.proto @@ -306,6 +306,7 @@ message CallLinkRecord { bytes rootKey = 1; bytes adminPasskey = 2; uint64 deletedAtTimestampMs = 3; + bytes epoch = 4; } message Recipient { diff --git a/pkg/signalmeow/protobuf/backuppb/Backup.pb.go b/pkg/signalmeow/protobuf/backuppb/Backup.pb.go index 06ebdea..cc4b279 100644 --- a/pkg/signalmeow/protobuf/backuppb/Backup.pb.go +++ b/pkg/signalmeow/protobuf/backuppb/Backup.pb.go @@ -1861,6 +1861,7 @@ type BackupInfo struct { MediaRootBackupKey []byte `protobuf:"bytes,3,opt,name=mediaRootBackupKey,proto3" json:"mediaRootBackupKey,omitempty"` // 32-byte random value generated when the backup is uploaded for the first time. CurrentAppVersion string `protobuf:"bytes,4,opt,name=currentAppVersion,proto3" json:"currentAppVersion,omitempty"` FirstAppVersion string `protobuf:"bytes,5,opt,name=firstAppVersion,proto3" json:"firstAppVersion,omitempty"` + DebugInfo []byte `protobuf:"bytes,6,opt,name=debugInfo,proto3" json:"debugInfo,omitempty"` // Client-specific data field for debug info during testing unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } @@ -1930,6 +1931,13 @@ func (x *BackupInfo) GetFirstAppVersion() string { return "" } +func (x *BackupInfo) GetDebugInfo() []byte { + if x != nil { + return x.DebugInfo + } + return nil +} + // Frames must follow in the following ordering rules: // // 1. There is exactly one AccountData and it is the first frame. @@ -2936,6 +2944,7 @@ type CallLink struct { Name string `protobuf:"bytes,3,opt,name=name,proto3" json:"name,omitempty"` Restrictions CallLink_Restrictions `protobuf:"varint,4,opt,name=restrictions,proto3,enum=signal.backup.CallLink_Restrictions" json:"restrictions,omitempty"` ExpirationMs uint64 `protobuf:"varint,5,opt,name=expirationMs,proto3" json:"expirationMs,omitempty"` + Epoch []byte `protobuf:"bytes,6,opt,name=epoch,proto3" json:"epoch,omitempty"` // May be absent/empty for older links unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } @@ -3005,6 +3014,13 @@ func (x *CallLink) GetExpirationMs() uint64 { return 0 } +func (x *CallLink) GetEpoch() []byte { + if x != nil { + return x.Epoch + } + return nil +} + type AdHocCall struct { state protoimpl.MessageState `protogen:"open.v1"` CallId uint64 `protobuf:"varint,1,opt,name=callId,proto3" json:"callId,omitempty"` @@ -11519,14 +11535,15 @@ var File_backuppb_Backup_proto protoreflect.FileDescriptor const file_backuppb_Backup_proto_rawDesc = "" + "\n" + - "\x15backuppb/Backup.proto\x12\rsignal.backup\"\xd2\x01\n" + + "\x15backuppb/Backup.proto\x12\rsignal.backup\"\xf0\x01\n" + "\n" + "BackupInfo\x12\x18\n" + "\aversion\x18\x01 \x01(\x04R\aversion\x12\"\n" + "\fbackupTimeMs\x18\x02 \x01(\x04R\fbackupTimeMs\x12.\n" + "\x12mediaRootBackupKey\x18\x03 \x01(\fR\x12mediaRootBackupKey\x12,\n" + "\x11currentAppVersion\x18\x04 \x01(\tR\x11currentAppVersion\x12(\n" + - "\x0ffirstAppVersion\x18\x05 \x01(\tR\x0ffirstAppVersion\"\xf2\x03\n" + + "\x0ffirstAppVersion\x18\x05 \x01(\tR\x0ffirstAppVersion\x12\x1c\n" + + "\tdebugInfo\x18\x06 \x01(\fR\tdebugInfo\"\xf2\x03\n" + "\x05Frame\x126\n" + "\aaccount\x18\x01 \x01(\v2\x1a.signal.backup.AccountDataH\x00R\aaccount\x128\n" + "\trecipient\x18\x02 \x01(\v2\x18.signal.backup.RecipientH\x00R\trecipient\x12)\n" + @@ -11763,13 +11780,14 @@ const file_backuppb_Backup_proto_rawDesc = "" + " \x01(\rR\x12expireTimerVersionB\x0e\n" + "\f_pinnedOrderB\x14\n" + "\x12_expirationTimerMsB\x0e\n" + - "\f_muteUntilMs\"\x8f\x02\n" + + "\f_muteUntilMs\"\xa5\x02\n" + "\bCallLink\x12\x18\n" + "\arootKey\x18\x01 \x01(\fR\arootKey\x12\x1f\n" + "\badminKey\x18\x02 \x01(\fH\x00R\badminKey\x88\x01\x01\x12\x12\n" + "\x04name\x18\x03 \x01(\tR\x04name\x12H\n" + "\frestrictions\x18\x04 \x01(\x0e2$.signal.backup.CallLink.RestrictionsR\frestrictions\x12\"\n" + - "\fexpirationMs\x18\x05 \x01(\x04R\fexpirationMs\"9\n" + + "\fexpirationMs\x18\x05 \x01(\x04R\fexpirationMs\x12\x14\n" + + "\x05epoch\x18\x06 \x01(\fR\x05epoch\"9\n" + "\fRestrictions\x12\v\n" + "\aUNKNOWN\x10\x00\x12\b\n" + "\x04NONE\x10\x01\x12\x12\n" + diff --git a/pkg/signalmeow/protobuf/backuppb/Backup.proto b/pkg/signalmeow/protobuf/backuppb/Backup.proto index 0dd3e89..f88c6ae 100644 --- a/pkg/signalmeow/protobuf/backuppb/Backup.proto +++ b/pkg/signalmeow/protobuf/backuppb/Backup.proto @@ -11,6 +11,7 @@ message BackupInfo { bytes mediaRootBackupKey = 3; // 32-byte random value generated when the backup is uploaded for the first time. string currentAppVersion = 4; string firstAppVersion = 5; + bytes debugInfo = 6; // Client-specific data field for debug info during testing } // Frames must follow in the following ordering rules: @@ -343,6 +344,7 @@ message CallLink { string name = 3; Restrictions restrictions = 4; uint64 expirationMs = 5; + bytes epoch = 6; // May be absent/empty for older links } message AdHocCall { diff --git a/pkg/signalmeow/protobuf/update-protos.sh b/pkg/signalmeow/protobuf/update-protos.sh index c3d85c0..21503c1 100755 --- a/pkg/signalmeow/protobuf/update-protos.sh +++ b/pkg/signalmeow/protobuf/update-protos.sh @@ -1,8 +1,8 @@ #!/bin/bash set -euo pipefail -ANDROID_GIT_REVISION=${1:-4b9cac43a82b5b907de53696b93eaf521943d15c} -DESKTOP_GIT_REVISION=${1:-ffc34d5080b8b8aec1bbebf11a13227e224dffe0} +ANDROID_GIT_REVISION=${1:-dbd79cd0a52d7d1594f70a4ba5a68c8fc3efa5e8} +DESKTOP_GIT_REVISION=${1:-07a05f3dd6f7fd07a1faebd8dd046d2b87da6c07} update_proto() { case "$1" in From 1f08ab883c3618c874dfc54d1d052b02faf356b3 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Mon, 28 Jul 2025 15:59:10 +0300 Subject: [PATCH 375/580] legacyprovision: switch to standard http mux --- cmd/mautrix-signal/legacyprovision.go | 3 +-- cmd/mautrix-signal/main.go | 14 ++++++-------- go.mod | 10 ++++------ go.sum | 20 ++++++++------------ 4 files changed, 19 insertions(+), 28 deletions(-) diff --git a/cmd/mautrix-signal/legacyprovision.go b/cmd/mautrix-signal/legacyprovision.go index 8bad469..6bd6882 100644 --- a/cmd/mautrix-signal/legacyprovision.go +++ b/cmd/mautrix-signal/legacyprovision.go @@ -25,7 +25,6 @@ import ( "sync" "sync/atomic" - "github.com/gorilla/mux" "github.com/rs/zerolog" "maunium.net/go/mautrix" "maunium.net/go/mautrix/bridgev2" @@ -215,7 +214,7 @@ func legacyResolveIdentifierOrStartChat(w http.ResponseWriter, r *http.Request, return } api := login.Client.(bridgev2.IdentifierResolvingNetworkAPI) - phonenum := mux.Vars(r)["phonenum"] + phonenum := r.PathValue("phonenum") resp, err := api.ResolveIdentifier(r.Context(), phonenum, create) if err != nil { zerolog.Ctx(r.Context()).Err(err).Msg("Failed to resolve identifier") diff --git a/cmd/mautrix-signal/main.go b/cmd/mautrix-signal/main.go index 78f696e..dc1a25a 100644 --- a/cmd/mautrix-signal/main.go +++ b/cmd/mautrix-signal/main.go @@ -17,8 +17,6 @@ package main import ( - "net/http" - "maunium.net/go/mautrix/bridgev2/bridgeconfig" "maunium.net/go/mautrix/bridgev2/matrix/mxmain" @@ -57,12 +55,12 @@ func main() { } m.PostStart = func() { if m.Matrix.Provisioning != nil { - m.Matrix.Provisioning.Router.HandleFunc("/v2/link/new", legacyProvLinkNew).Methods(http.MethodPost) - m.Matrix.Provisioning.Router.HandleFunc("/v2/link/wait/scan", legacyProvLinkWaitScan).Methods(http.MethodPost) - m.Matrix.Provisioning.Router.HandleFunc("/v2/link/wait/account", legacyProvLinkWaitAccount).Methods(http.MethodPost) - m.Matrix.Provisioning.Router.HandleFunc("/v2/logout", legacyProvLogout).Methods(http.MethodPost) - m.Matrix.Provisioning.Router.HandleFunc("/v2/resolve_identifier/{phonenum}", legacyProvResolveIdentifier).Methods(http.MethodGet) - m.Matrix.Provisioning.Router.HandleFunc("/v2/pm/{phonenum}", legacyProvPM).Methods(http.MethodPost) + m.Matrix.Provisioning.Router.HandleFunc("POST /v2/link/new", legacyProvLinkNew) + m.Matrix.Provisioning.Router.HandleFunc("POST /v2/link/wait/scan", legacyProvLinkWaitScan) + m.Matrix.Provisioning.Router.HandleFunc("POST /v2/link/wait/account", legacyProvLinkWaitAccount) + m.Matrix.Provisioning.Router.HandleFunc("POST /v2/logout", legacyProvLogout) + m.Matrix.Provisioning.Router.HandleFunc("GET /v2/resolve_identifier/{phonenum}", legacyProvResolveIdentifier) + m.Matrix.Provisioning.Router.HandleFunc("POST /v2/pm/{phonenum}", legacyProvPM) } } m.InitVersion(Tag, Commit, BuildTime) diff --git a/go.mod b/go.mod index 29aa21d..579302a 100644 --- a/go.mod +++ b/go.mod @@ -8,30 +8,28 @@ require ( github.com/coder/websocket v1.8.13 github.com/emersion/go-vcard v0.0.0-20241024213814-c9703dde27ff github.com/google/uuid v1.6.0 - github.com/gorilla/mux v1.8.0 github.com/mattn/go-pointer v0.0.1 github.com/rs/zerolog v1.34.0 github.com/stretchr/testify v1.10.0 github.com/tidwall/gjson v1.18.0 - go.mau.fi/util v0.8.8 + go.mau.fi/util v0.8.9-0.20250723171559-474867266038 golang.org/x/crypto v0.40.0 - golang.org/x/exp v0.0.0-20250711185948-6ae5c78190dc + golang.org/x/exp v0.0.0-20250718183923-645b1fa84792 golang.org/x/net v0.42.0 google.golang.org/protobuf v1.36.6 - maunium.net/go/mautrix v0.24.2 + maunium.net/go/mautrix v0.24.3-0.20250728125317-74ab3b118e10 ) require ( filippo.io/edwards25519 v1.1.0 // indirect github.com/coreos/go-systemd/v22 v22.5.0 // indirect github.com/davecgh/go-spew v1.1.1 // indirect - github.com/gorilla/websocket v1.5.0 // indirect github.com/kr/pretty v0.3.1 // indirect github.com/lib/pq v1.10.9 // indirect github.com/mattn/go-colorable v0.1.14 // indirect github.com/mattn/go-isatty v0.0.20 // indirect github.com/mattn/go-sqlite3 v1.14.28 // indirect - github.com/petermattis/goid v0.0.0-20250508124226-395b08cebbdb // indirect + github.com/petermattis/goid v0.0.0-20250721140440-ea1c0173183e // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/rogpeppe/go-internal v1.10.0 // indirect github.com/rs/xid v1.6.0 // indirect diff --git a/go.sum b/go.sum index 1f8d1a9..dda20d8 100644 --- a/go.sum +++ b/go.sum @@ -16,10 +16,6 @@ github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI= -github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= -github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc= -github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= @@ -40,8 +36,8 @@ github.com/mattn/go-pointer v0.0.1 h1:n+XhsuGeVO6MEAp7xyEukFINEa+Quek5psIR/ylA6o github.com/mattn/go-pointer v0.0.1/go.mod h1:2zXcozF6qYGgmsG+SeTZz3oAbFLdD3OWqnUbNvJZAlc= github.com/mattn/go-sqlite3 v1.14.28 h1:ThEiQrnbtumT+QMknw63Befp/ce/nUPgBPMlRFEum7A= github.com/mattn/go-sqlite3 v1.14.28/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y= -github.com/petermattis/goid v0.0.0-20250508124226-395b08cebbdb h1:3PrKuO92dUTMrQ9dx0YNejC6U/Si6jqKmyQ9vWjwqR4= -github.com/petermattis/goid v0.0.0-20250508124226-395b08cebbdb/go.mod h1:pxMtw7cyUw6B2bRH0ZBANSPg+AoSud1I1iyJHI69jH4= +github.com/petermattis/goid v0.0.0-20250721140440-ea1c0173183e h1:D0bJD+4O3G4izvrQUmzCL80zazlN7EwJ0PPDhpJWC/I= +github.com/petermattis/goid v0.0.0-20250721140440-ea1c0173183e/go.mod h1:pxMtw7cyUw6B2bRH0ZBANSPg+AoSud1I1iyJHI69jH4= github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= @@ -69,14 +65,14 @@ github.com/tidwall/sjson v1.2.5 h1:kLy8mja+1c9jlljvWTlSazM7cKDRfJuR/bOJhcY5NcY= github.com/tidwall/sjson v1.2.5/go.mod h1:Fvgq9kS/6ociJEDnK0Fk1cpYF4FIW6ZF7LAe+6jwd28= github.com/yuin/goldmark v1.7.12 h1:YwGP/rrea2/CnCtUHgjuolG/PnMxdQtPMO5PvaE2/nY= github.com/yuin/goldmark v1.7.12/go.mod h1:ip/1k0VRfGynBgxOz0yCqHrbZXhcjxyuS66Brc7iBKg= -go.mau.fi/util v0.8.8 h1:OnuEEc/sIJFhnq4kFggiImUpcmnmL/xpvQMRu5Fiy5c= -go.mau.fi/util v0.8.8/go.mod h1:Y/kS3loxTEhy8Vill513EtPXr+CRDdae+Xj2BXXMy/c= +go.mau.fi/util v0.8.9-0.20250723171559-474867266038 h1:RVL8TVaYc3LTBBopfjCNDtD+6eZks0O+qgXN/9hsz7k= +go.mau.fi/util v0.8.9-0.20250723171559-474867266038/go.mod h1:GZZp5f9r2MgEu4GDvtB0XxCF7i6Z7Z8fM0w9a5oZH3Y= go.mau.fi/zeroconfig v0.1.3 h1:As9wYDKmktjmNZW5i1vn8zvJlmGKHeVxHVIBMXsm4kM= go.mau.fi/zeroconfig v0.1.3/go.mod h1:NcSJkf180JT+1IId76PcMuLTNa1CzsFFZ0nBygIQM70= golang.org/x/crypto v0.40.0 h1:r4x+VvoG5Fm+eJcxMaY8CQM7Lb0l1lsmjGBQ6s8BfKM= golang.org/x/crypto v0.40.0/go.mod h1:Qr1vMER5WyS2dfPHAlsOj01wgLbsyWtFn/aY+5+ZdxY= -golang.org/x/exp v0.0.0-20250711185948-6ae5c78190dc h1:TS73t7x3KarrNd5qAipmspBDS1rkMcgVG/fS1aRb4Rc= -golang.org/x/exp v0.0.0-20250711185948-6ae5c78190dc/go.mod h1:A+z0yzpGtvnG90cToK5n2tu8UJVP2XUATh+r+sfOOOc= +golang.org/x/exp v0.0.0-20250718183923-645b1fa84792 h1:R9PFI6EUdfVKgwKjZef7QIwGcBKu86OEFpJ9nUEP2l4= +golang.org/x/exp v0.0.0-20250718183923-645b1fa84792/go.mod h1:A+z0yzpGtvnG90cToK5n2tu8UJVP2XUATh+r+sfOOOc= golang.org/x/net v0.42.0 h1:jzkYrhi3YQWD6MLBJcsklgQsoAcw89EcZbJw8Z614hs= golang.org/x/net v0.42.0/go.mod h1:FF1RA5d3u7nAYA4z2TkclSCKh68eSXtiFwcWQpPXdt8= golang.org/x/sync v0.16.0 h1:ycBJEhp9p4vXvUZNszeOq0kGTPghopOL8q0fq3vstxw= @@ -99,5 +95,5 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= maunium.net/go/mauflag v1.0.0 h1:YiaRc0tEI3toYtJMRIfjP+jklH45uDHtT80nUamyD4M= maunium.net/go/mauflag v1.0.0/go.mod h1:nLivPOpTpHnpzEh8jEdSL9UqO9+/KBJFmNRlwKfkPeA= -maunium.net/go/mautrix v0.24.2 h1:+AVT5kbcA/QuT5svrJKp4ivwoUmz+RRplMp3DnfpheI= -maunium.net/go/mautrix v0.24.2/go.mod h1:1ut900w++eE9by9yqCR2dQdMqwsHwZG5L+1bKB1EvSA= +maunium.net/go/mautrix v0.24.3-0.20250728125317-74ab3b118e10 h1:IMOGeYKTOzHNnBx1ksVCVCw3t6joQRqDOSI2Ou4Xr/U= +maunium.net/go/mautrix v0.24.3-0.20250728125317-74ab3b118e10/go.mod h1:KrE/TdIeAo6cfAUICmbaiZ18UgHimTOozAGOrioK9SU= From d4d9687ef242025350ceeb58015c038e67855510 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Mon, 28 Jul 2025 16:10:20 +0300 Subject: [PATCH 376/580] signalid/media: remove pointless use of bufio --- pkg/signalid/media.go | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/pkg/signalid/media.go b/pkg/signalid/media.go index 533463c..6190c89 100644 --- a/pkg/signalid/media.go +++ b/pkg/signalid/media.go @@ -17,7 +17,6 @@ package signalid import ( - "bufio" "bytes" "crypto/sha256" "encoding/binary" @@ -127,7 +126,7 @@ func ParseDirectMediaInfo(mediaID networkid.MediaID) (_ DirectMediaInfo, err err return nil, fmt.Errorf("empty media ID") } - buf := bufio.NewReader(bytes.NewBuffer(mediaID)) + buf := bytes.NewReader(mediaID) // type byte var mediaType directMediaType @@ -169,7 +168,7 @@ func ParseDirectMediaInfo(mediaID networkid.MediaID) (_ DirectMediaInfo, err err if err = binary.Read(buf, binary.BigEndian, &info.UserID); err != nil { return info, fmt.Errorf("failed to read user id: %w", err) - } else if binary.Read(buf, binary.BigEndian, &info.GroupID); err != nil { + } else if err = binary.Read(buf, binary.BigEndian, &info.GroupID); err != nil { return info, fmt.Errorf("failed to read group id: %w", err) } if groupAvatarPath, err := readByteSlice(buf, mediaIDLen); err != nil { @@ -215,7 +214,12 @@ func writeByteSlice(w io.Writer, b []byte) error { return err } -func readByteSlice(r *bufio.Reader, maxLength int) ([]byte, error) { +type byteReader interface { + io.ByteReader + io.Reader +} + +func readByteSlice(r byteReader, maxLength int) ([]byte, error) { length, err := binary.ReadUvarint(r) if err != nil { return nil, fmt.Errorf("reading uvarint failed: %w", err) From 7c89794bb29e98db446d738885b17695eb96e3ae Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Mon, 28 Jul 2025 15:59:44 +0300 Subject: [PATCH 377/580] msgconv,signalmeow: switch to using LocatorInfo in backups --- pkg/msgconv/from-signal-backup.go | 40 +++++++++++++++++++++---------- pkg/msgconv/from-signal.go | 23 ++++++++++++------ pkg/signalid/media.go | 6 ++--- pkg/signalmeow/provisioning.go | 2 +- 4 files changed, 47 insertions(+), 24 deletions(-) diff --git a/pkg/msgconv/from-signal-backup.go b/pkg/msgconv/from-signal-backup.go index d5532cd..e5cb316 100644 --- a/pkg/msgconv/from-signal-backup.go +++ b/pkg/msgconv/from-signal-backup.go @@ -34,7 +34,7 @@ func boolToInt(b bool) int { return 0 } -type AttachmentMap map[uuid.UUID]*backuppb.FilePointer_BackupLocator +type AttachmentMap map[uuid.UUID]*backuppb.FilePointer_LocatorInfo func BackupToDataMessage(ci *backuppb.ChatItem, attMap AttachmentMap) (*signalpb.DataMessage, []*backuppb.Reaction) { var dm signalpb.DataMessage @@ -186,7 +186,7 @@ func backupToSignalAttachment( fp *backuppb.FilePointer, flag backuppb.MessageAttachment_Flag, clientUUID uuid.UUID, - atts map[uuid.UUID]*backuppb.FilePointer_BackupLocator, + atts AttachmentMap, ) *signalpb.AttachmentPointer { sig := &signalpb.AttachmentPointer{ //IncrementalMacChunkSize: fp.IncrementalMacChunkSize, @@ -200,17 +200,31 @@ func backupToSignalAttachment( BlurHash: fp.BlurHash, ClientUuid: clientUUID[:], } - switch loc := fp.Locator.(type) { - case *backuppb.FilePointer_AttachmentLocator_: - sig.AttachmentIdentifier = &signalpb.AttachmentPointer_CdnKey{CdnKey: loc.AttachmentLocator.CdnKey} - sig.Key = loc.AttachmentLocator.Key - sig.Size = &loc.AttachmentLocator.Size - sig.Digest = loc.AttachmentLocator.Digest - sig.CdnNumber = &loc.AttachmentLocator.CdnNumber - case *backuppb.FilePointer_BackupLocator_: - atts[clientUUID] = loc.BackupLocator - case *backuppb.FilePointer_InvalidAttachmentLocator_: - atts[clientUUID] = nil + if fp.LocatorInfo != nil { + if fp.LocatorInfo.TransitCdnKey != nil { + sig.AttachmentIdentifier = &signalpb.AttachmentPointer_CdnKey{CdnKey: *fp.LocatorInfo.TransitCdnKey} + sig.Size = &fp.LocatorInfo.Size + sig.Digest = fp.LocatorInfo.GetEncryptedDigest() // Note: may be nil if plaintextHash is set instead + if sig.Digest == nil { + sig.Digest = fp.LocatorInfo.LegacyDigest + } + sig.CdnNumber = fp.LocatorInfo.TransitCdnNumber + } + sig.Key = fp.LocatorInfo.Key + atts[clientUUID] = fp.LocatorInfo + } else { + switch loc := fp.Locator.(type) { + case *backuppb.FilePointer_AttachmentLocator_: + sig.AttachmentIdentifier = &signalpb.AttachmentPointer_CdnKey{CdnKey: loc.AttachmentLocator.CdnKey} + sig.Key = loc.AttachmentLocator.Key + sig.Size = &loc.AttachmentLocator.Size + sig.Digest = loc.AttachmentLocator.Digest + sig.CdnNumber = &loc.AttachmentLocator.CdnNumber + case *backuppb.FilePointer_BackupLocator_: + //atts[clientUUID] = loc.BackupLocator + case *backuppb.FilePointer_InvalidAttachmentLocator_: + atts[clientUUID] = nil + } } return sig } diff --git a/pkg/msgconv/from-signal.go b/pkg/msgconv/from-signal.go index da5becb..73663f9 100644 --- a/pkg/msgconv/from-signal.go +++ b/pkg/msgconv/from-signal.go @@ -463,21 +463,28 @@ func (mc *MessageConverter) downloadSignalLongText(ctx context.Context, att *sig return &longBody, nil } -func (mc *MessageConverter) downloadAttachment(ctx context.Context, att *signalpb.AttachmentPointer, attMap AttachmentMap) ([]byte, error) { +func checkIfAttachmentExists(att *signalpb.AttachmentPointer, attMap AttachmentMap) error { if att.AttachmentIdentifier == nil { if len(att.GetClientUuid()) != 16 { - return nil, fmt.Errorf("no attachment identifier found") + return fmt.Errorf("no attachment identifier found") } target, ok := attMap[uuid.UUID(att.GetClientUuid())] if !ok { - return nil, fmt.Errorf("no attachment identifier and attachment not found in map") - } else if target == nil { - return nil, ErrAttachmentNotInBackup + return fmt.Errorf("no attachment identifier and attachment not found in map") + } else if target == nil || target.MediaTierCdnNumber == nil { + return ErrAttachmentNotInBackup } else { // TODO add support for downloading attachments from backup - return nil, ErrBackupNotSupported + return ErrBackupNotSupported } } + return nil +} + +func (mc *MessageConverter) downloadAttachment(ctx context.Context, att *signalpb.AttachmentPointer, attMap AttachmentMap) ([]byte, error) { + if err := checkIfAttachmentExists(att, attMap); err != nil { + return nil, err + } return signalmeow.DownloadAttachmentWithPointer(ctx, att) } @@ -491,7 +498,9 @@ func (mc *MessageConverter) reuploadAttachment(ctx context.Context, att *signalp }, } mimeType := att.GetContentType() - if mc.DirectMedia { + if err := checkIfAttachmentExists(att, attMap); err != nil { + return nil, err + } else if mc.DirectMedia { mediaID, err := signalid.DirectMediaAttachment{ CDNID: att.GetCdnId(), CDNKey: att.GetCdnKey(), diff --git a/pkg/signalid/media.go b/pkg/signalid/media.go index 6190c89..d060628 100644 --- a/pkg/signalid/media.go +++ b/pkg/signalid/media.go @@ -30,9 +30,9 @@ import ( type directMediaType byte const ( - directMediaTypeAttachment directMediaType = iota - directMediaTypeGroupAvatar - directMediaTypeProfileAvatar + directMediaTypeAttachment directMediaType = 0 + directMediaTypeGroupAvatar directMediaType = 1 + directMediaTypeProfileAvatar directMediaType = 2 ) type DirectMediaInfo interface { diff --git a/pkg/signalmeow/provisioning.go b/pkg/signalmeow/provisioning.go index 94a4176..07697d1 100644 --- a/pkg/signalmeow/provisioning.go +++ b/pkg/signalmeow/provisioning.go @@ -299,7 +299,7 @@ func startProvisioning(ctx context.Context, ws *websocket.Conn, provisioningCiph return "", fmt.Errorf("failed to unmarshal provisioning UUID: %w", err) } - linkCapabilities := []string{"backup3"} + linkCapabilities := []string{"backup4"} if !allowBackup { linkCapabilities = []string{} } From 47e4284fea419fdb99bd500e88762b5763170540 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Mon, 28 Jul 2025 16:17:55 +0300 Subject: [PATCH 378/580] msgconv,signalmeow: add support for plaintext attachment hashes in backup --- pkg/connector/directmedia.go | 5 ++++- pkg/msgconv/from-signal.go | 31 ++++++++++++++++++++++++------- pkg/signalid/media.go | 30 +++++++++++++++++++----------- pkg/signalmeow/attachments.go | 33 ++++++++++++++++++++++++--------- pkg/signalmeow/receiving.go | 2 +- 5 files changed, 72 insertions(+), 29 deletions(-) diff --git a/pkg/connector/directmedia.go b/pkg/connector/directmedia.go index 8507626..6f31e15 100644 --- a/pkg/connector/directmedia.go +++ b/pkg/connector/directmedia.go @@ -37,12 +37,15 @@ func (s *SignalConnector) Download(ctx context.Context, mediaID networkid.MediaI Uint32("cdn_number", info.CDNNumber). Int("key_len", len(info.Key)). Int("digest_len", len(info.Digest)). + Bool("plaintext_digest", info.PlaintextDigest). Uint32("size", info.Size). Msg("Direct downloading attachment") return &mediaproxy.GetMediaResponseCallback{ Callback: func(w io.Writer) (int64, error) { - data, err := signalmeow.DownloadAttachment(ctx, info.CDNID, info.CDNKey, info.CDNNumber, info.Key, info.Digest, info.Size) + data, err := signalmeow.DownloadAttachment( + ctx, info.CDNID, info.CDNKey, info.CDNNumber, info.Key, info.Digest, info.PlaintextDigest, info.Size, + ) if err != nil { log.Err(err).Msg("Direct download failed") return 0, err diff --git a/pkg/msgconv/from-signal.go b/pkg/msgconv/from-signal.go index 73663f9..18e8de4 100644 --- a/pkg/msgconv/from-signal.go +++ b/pkg/msgconv/from-signal.go @@ -485,7 +485,14 @@ func (mc *MessageConverter) downloadAttachment(ctx context.Context, att *signalp if err := checkIfAttachmentExists(att, attMap); err != nil { return nil, err } - return signalmeow.DownloadAttachmentWithPointer(ctx, att) + var plaintextHash []byte + if len(att.GetClientUuid()) == 16 { + target, ok := attMap[uuid.UUID(att.GetClientUuid())] + if ok { + plaintextHash = target.GetPlaintextHash() + } + } + return signalmeow.DownloadAttachmentWithPointer(ctx, att, plaintextHash) } func (mc *MessageConverter) reuploadAttachment(ctx context.Context, att *signalpb.AttachmentPointer, attMap AttachmentMap) (*bridgev2.ConvertedMessagePart, error) { @@ -501,13 +508,23 @@ func (mc *MessageConverter) reuploadAttachment(ctx context.Context, att *signalp if err := checkIfAttachmentExists(att, attMap); err != nil { return nil, err } else if mc.DirectMedia { + digest := att.Digest + var plaintextDigest bool + if digest == nil && len(att.GetClientUuid()) == 16 { + locatorInfo, ok := attMap[uuid.UUID(att.GetClientUuid())] + if ok { + digest = locatorInfo.GetPlaintextHash() + plaintextDigest = true + } + } mediaID, err := signalid.DirectMediaAttachment{ - CDNID: att.GetCdnId(), - CDNKey: att.GetCdnKey(), - CDNNumber: att.GetCdnNumber(), - Key: att.Key, - Digest: att.Digest, - Size: att.GetSize(), + CDNID: att.GetCdnId(), + CDNKey: att.GetCdnKey(), + CDNNumber: att.GetCdnNumber(), + Key: att.Key, + Digest: digest, + PlaintextDigest: plaintextDigest, + Size: att.GetSize(), }.AsMediaID() if err != nil { return nil, err diff --git a/pkg/signalid/media.go b/pkg/signalid/media.go index d060628..8c91b6a 100644 --- a/pkg/signalid/media.go +++ b/pkg/signalid/media.go @@ -30,9 +30,10 @@ import ( type directMediaType byte const ( - directMediaTypeAttachment directMediaType = 0 - directMediaTypeGroupAvatar directMediaType = 1 - directMediaTypeProfileAvatar directMediaType = 2 + directMediaTypeAttachment directMediaType = 0 + directMediaTypeGroupAvatar directMediaType = 1 + directMediaTypeProfileAvatar directMediaType = 2 + directMediaTypePlaintextDigestAttachment directMediaType = 3 ) type DirectMediaInfo interface { @@ -46,18 +47,24 @@ var ( ) type DirectMediaAttachment struct { - CDNID uint64 - CDNKey string - CDNNumber uint32 - Key []byte - Digest []byte - Size uint32 + CDNID uint64 + CDNKey string + CDNNumber uint32 + Key []byte + PlaintextDigest bool + Digest []byte + Size uint32 } func (m DirectMediaAttachment) AsMediaID() (mediaID networkid.MediaID, err error) { buf := &bytes.Buffer{} - if err = binary.Write(buf, binary.BigEndian, directMediaTypeAttachment); err != nil { + attType := directMediaTypeAttachment + if m.PlaintextDigest { + attType = directMediaTypePlaintextDigestAttachment + } + + if err = binary.Write(buf, binary.BigEndian, attType); err != nil { return } else if err = writeUvarint(buf, m.CDNID); err != nil { return @@ -135,8 +142,9 @@ func ParseDirectMediaInfo(mediaID networkid.MediaID) (_ DirectMediaInfo, err err } switch mediaType { - case directMediaTypeAttachment: + case directMediaTypeAttachment, directMediaTypePlaintextDigestAttachment: var info DirectMediaAttachment + info.PlaintextDigest = mediaType == directMediaTypePlaintextDigestAttachment if info.CDNID, err = binary.ReadUvarint(buf); err != nil { return info, fmt.Errorf("failed to read cdn id: %w", err) diff --git a/pkg/signalmeow/attachments.go b/pkg/signalmeow/attachments.go index 386d9cc..e321f57 100644 --- a/pkg/signalmeow/attachments.go +++ b/pkg/signalmeow/attachments.go @@ -59,11 +59,17 @@ var ErrInvalidMACForAttachment = errors.New("invalid MAC for attachment") var ErrInvalidDigestForAttachment = errors.New("invalid digest for attachment") var ErrAttachmentNotFound = errors.New("attachment not found on server") -func DownloadAttachmentWithPointer(ctx context.Context, a *signalpb.AttachmentPointer) ([]byte, error) { - return DownloadAttachment(ctx, a.GetCdnId(), a.GetCdnKey(), a.GetCdnNumber(), a.Key, a.Digest, a.GetSize()) +func DownloadAttachmentWithPointer(ctx context.Context, a *signalpb.AttachmentPointer, plaintextHash []byte) ([]byte, error) { + digest := a.GetDigest() + plaintextDigest := false + if digest == nil && plaintextHash != nil { + digest = plaintextHash + plaintextDigest = true + } + return DownloadAttachment(ctx, a.GetCdnId(), a.GetCdnKey(), a.GetCdnNumber(), a.Key, digest, plaintextDigest, a.GetSize()) } -func DownloadAttachment(ctx context.Context, cdnID uint64, cdnKey string, cdnNumber uint32, key, digest []byte, size uint32) ([]byte, error) { +func DownloadAttachment(ctx context.Context, cdnID uint64, cdnKey string, cdnNumber uint32, key, digest []byte, plaintextDigest bool, size uint32) ([]byte, error) { path := getAttachmentPath(cdnID, cdnKey) resp, err := web.GetAttachment(ctx, path, cdnNumber, nil) if err != nil { @@ -88,16 +94,18 @@ func DownloadAttachment(ctx context.Context, cdnID uint64, cdnKey string, cdnNum return nil, fmt.Errorf("unexpected status code %d", resp.StatusCode) } - return decryptAttachment(body, key, digest, size) + return decryptAttachment(body, key, digest, plaintextDigest, size) } const MACLength = 32 const IVLength = 16 -func decryptAttachment(body, key, digest []byte, size uint32) ([]byte, error) { - hash := sha256.Sum256(body) - if !hmac.Equal(hash[:], digest) { - return nil, ErrInvalidDigestForAttachment +func decryptAttachment(body, key, digest []byte, plaintextDigest bool, size uint32) ([]byte, error) { + if !plaintextDigest { + hash := sha256.Sum256(body) + if !hmac.Equal(hash[:], digest) { + return nil, ErrInvalidDigestForAttachment + } } l := len(body) - MACLength if !verifyMAC(key[MACLength:], body[:l], body[l:]) { @@ -111,7 +119,14 @@ func decryptAttachment(body, key, digest []byte, size uint32) ([]byte, error) { if len(decrypted) < int(size) { return nil, fmt.Errorf("decrypted attachment length %v < expected %v", len(decrypted), size) } - return decrypted[:size], nil + decrypted = decrypted[:size] + if plaintextDigest { + hash := sha256.Sum256(decrypted) + if !hmac.Equal(hash[:], digest) { + return nil, fmt.Errorf("%w (plaintext hash)", ErrInvalidDigestForAttachment) + } + } + return decrypted, nil } type attachmentV4UploadAttributes struct { diff --git a/pkg/signalmeow/receiving.go b/pkg/signalmeow/receiving.go index 49ed0f3..6c97a69 100644 --- a/pkg/signalmeow/receiving.go +++ b/pkg/signalmeow/receiving.go @@ -592,7 +592,7 @@ func (cli *Client) handleDecryptedResult( log.Debug().Msg("Recieved sync message contacts") blob := content.SyncMessage.Contacts.Blob if blob != nil { - contactsBytes, err := DownloadAttachmentWithPointer(ctx, blob) + contactsBytes, err := DownloadAttachmentWithPointer(ctx, blob, nil) if err != nil { log.Err(err).Msg("Contacts Sync DownloadAttachment error") } From fb5ff7dd74df79b17d12d7778d278b0e55c9cde3 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Mon, 28 Jul 2025 16:52:46 +0300 Subject: [PATCH 379/580] msgconv/from-signal: remove hack for gif flag --- pkg/msgconv/from-matrix.go | 2 +- pkg/msgconv/from-signal-backup.go | 2 +- pkg/msgconv/from-signal.go | 9 +-------- 3 files changed, 3 insertions(+), 10 deletions(-) diff --git a/pkg/msgconv/from-matrix.go b/pkg/msgconv/from-matrix.go index 36391f3..26bb492 100644 --- a/pkg/msgconv/from-matrix.go +++ b/pkg/msgconv/from-matrix.go @@ -192,7 +192,7 @@ func (mc *MessageConverter) convertFileToSignal(ctx context.Context, evt *event. att.Flags = proto.Uint32(uint32(signalpb.AttachmentPointer_VOICE_MESSAGE)) } if content.Info.MauGIF { - att.Flags = proto.Uint32(uint32(compatFlagGIF)) + att.Flags = proto.Uint32(uint32(signalpb.AttachmentPointer_GIF)) } att.ContentType = proto.String(mime) att.FileName = &fileName diff --git a/pkg/msgconv/from-signal-backup.go b/pkg/msgconv/from-signal-backup.go index e5cb316..5f7f12b 100644 --- a/pkg/msgconv/from-signal-backup.go +++ b/pkg/msgconv/from-signal-backup.go @@ -236,7 +236,7 @@ func backupToSignalAttachmentFlag(flag backuppb.MessageAttachment_Flag) signalpb case backuppb.MessageAttachment_BORDERLESS: return signalpb.AttachmentPointer_BORDERLESS case backuppb.MessageAttachment_GIF: - return compatFlagGIF + return signalpb.AttachmentPointer_GIF case backuppb.MessageAttachment_NONE: fallthrough default: diff --git a/pkg/msgconv/from-signal.go b/pkg/msgconv/from-signal.go index 18e8de4..815954a 100644 --- a/pkg/msgconv/from-signal.go +++ b/pkg/msgconv/from-signal.go @@ -76,13 +76,6 @@ func CanConvertSignal(dm *signalpb.DataMessage) bool { const ViewOnceDisappearTimer = 5 * time.Minute -// Why does signal have two different flags for gifs?? -// https://github.com/signalapp/Signal-Android/blob/v7.29.4/libsignal-service/src/main/protowire/SignalService.proto#L745 -// https://github.com/signalapp/Signal-Desktop/blob/v7.38.0-beta.1/protos/SignalService.proto#L740 -// https://github.com/signalapp/Signal-iOS/blob/7.42.0.545-beta/SignalServiceKit/protobuf/SignalService.proto#L756 -// Apparently the android one is a lie and doesn't work? -const compatFlagGIF = 8 - func (mc *MessageConverter) ToMatrix( ctx context.Context, client *signalmeow.Client, @@ -569,7 +562,7 @@ func (mc *MessageConverter) reuploadAttachment(ctx context.Context, att *signalp content.MsgType = event.MsgFile } var extra map[string]any - if att.GetFlags()&uint32(compatFlagGIF) != 0 { + if att.GetFlags()&uint32(signalpb.AttachmentPointer_GIF) != 0 { content.Info.MauGIF = true extra = map[string]any{ "info": map[string]any{ From d85a48abeb12d4a3accdee8af11bfa76626c2f2a Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Mon, 28 Jul 2025 17:34:59 +0300 Subject: [PATCH 380/580] dependencies: update mautrix-go --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 579302a..cff8080 100644 --- a/go.mod +++ b/go.mod @@ -17,7 +17,7 @@ require ( golang.org/x/exp v0.0.0-20250718183923-645b1fa84792 golang.org/x/net v0.42.0 google.golang.org/protobuf v1.36.6 - maunium.net/go/mautrix v0.24.3-0.20250728125317-74ab3b118e10 + maunium.net/go/mautrix v0.24.3-0.20250728143428-ae2c07fb863a ) require ( diff --git a/go.sum b/go.sum index dda20d8..e8d87ed 100644 --- a/go.sum +++ b/go.sum @@ -95,5 +95,5 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= maunium.net/go/mauflag v1.0.0 h1:YiaRc0tEI3toYtJMRIfjP+jklH45uDHtT80nUamyD4M= maunium.net/go/mauflag v1.0.0/go.mod h1:nLivPOpTpHnpzEh8jEdSL9UqO9+/KBJFmNRlwKfkPeA= -maunium.net/go/mautrix v0.24.3-0.20250728125317-74ab3b118e10 h1:IMOGeYKTOzHNnBx1ksVCVCw3t6joQRqDOSI2Ou4Xr/U= -maunium.net/go/mautrix v0.24.3-0.20250728125317-74ab3b118e10/go.mod h1:KrE/TdIeAo6cfAUICmbaiZ18UgHimTOozAGOrioK9SU= +maunium.net/go/mautrix v0.24.3-0.20250728143428-ae2c07fb863a h1:3lQKIbNLbHKxMLjwoChuCstvfJ8LT9+So4+QabIjKI8= +maunium.net/go/mautrix v0.24.3-0.20250728143428-ae2c07fb863a/go.mod h1:KrE/TdIeAo6cfAUICmbaiZ18UgHimTOozAGOrioK9SU= From 1350339213519b3c54542961262055fff2d6d4c7 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Mon, 28 Jul 2025 22:04:08 +0300 Subject: [PATCH 381/580] dependencies: update mautrix-go --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index cff8080..2bf4ecb 100644 --- a/go.mod +++ b/go.mod @@ -17,7 +17,7 @@ require ( golang.org/x/exp v0.0.0-20250718183923-645b1fa84792 golang.org/x/net v0.42.0 google.golang.org/protobuf v1.36.6 - maunium.net/go/mautrix v0.24.3-0.20250728143428-ae2c07fb863a + maunium.net/go/mautrix v0.24.3-0.20250728190343-2e7ff3fedd4c ) require ( diff --git a/go.sum b/go.sum index e8d87ed..9d298f2 100644 --- a/go.sum +++ b/go.sum @@ -95,5 +95,5 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= maunium.net/go/mauflag v1.0.0 h1:YiaRc0tEI3toYtJMRIfjP+jklH45uDHtT80nUamyD4M= maunium.net/go/mauflag v1.0.0/go.mod h1:nLivPOpTpHnpzEh8jEdSL9UqO9+/KBJFmNRlwKfkPeA= -maunium.net/go/mautrix v0.24.3-0.20250728143428-ae2c07fb863a h1:3lQKIbNLbHKxMLjwoChuCstvfJ8LT9+So4+QabIjKI8= -maunium.net/go/mautrix v0.24.3-0.20250728143428-ae2c07fb863a/go.mod h1:KrE/TdIeAo6cfAUICmbaiZ18UgHimTOozAGOrioK9SU= +maunium.net/go/mautrix v0.24.3-0.20250728190343-2e7ff3fedd4c h1:ciLyRuYMrqQK8Y0Rp06QcUz5YOnuieNlEbLg65ERLe8= +maunium.net/go/mautrix v0.24.3-0.20250728190343-2e7ff3fedd4c/go.mod h1:KrE/TdIeAo6cfAUICmbaiZ18UgHimTOozAGOrioK9SU= From 7704fcc6f03aa9d2b5db8937119ee9e6f1cd06f4 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Tue, 29 Jul 2025 16:19:32 +0300 Subject: [PATCH 382/580] dependencies: update mautrix-go --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 2bf4ecb..d174260 100644 --- a/go.mod +++ b/go.mod @@ -17,7 +17,7 @@ require ( golang.org/x/exp v0.0.0-20250718183923-645b1fa84792 golang.org/x/net v0.42.0 google.golang.org/protobuf v1.36.6 - maunium.net/go/mautrix v0.24.3-0.20250728190343-2e7ff3fedd4c + maunium.net/go/mautrix v0.24.3-0.20250729131536-26e66f293e6a ) require ( diff --git a/go.sum b/go.sum index 9d298f2..6f18389 100644 --- a/go.sum +++ b/go.sum @@ -95,5 +95,5 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= maunium.net/go/mauflag v1.0.0 h1:YiaRc0tEI3toYtJMRIfjP+jklH45uDHtT80nUamyD4M= maunium.net/go/mauflag v1.0.0/go.mod h1:nLivPOpTpHnpzEh8jEdSL9UqO9+/KBJFmNRlwKfkPeA= -maunium.net/go/mautrix v0.24.3-0.20250728190343-2e7ff3fedd4c h1:ciLyRuYMrqQK8Y0Rp06QcUz5YOnuieNlEbLg65ERLe8= -maunium.net/go/mautrix v0.24.3-0.20250728190343-2e7ff3fedd4c/go.mod h1:KrE/TdIeAo6cfAUICmbaiZ18UgHimTOozAGOrioK9SU= +maunium.net/go/mautrix v0.24.3-0.20250729131536-26e66f293e6a h1:+tnOE+D2F7wOQVY/SpBdssD9U45uvpfe2yYZ1FuXuIM= +maunium.net/go/mautrix v0.24.3-0.20250729131536-26e66f293e6a/go.mod h1:KrE/TdIeAo6cfAUICmbaiZ18UgHimTOozAGOrioK9SU= From 1636355668a583eec266e7f8774e75f33e1df9d9 Mon Sep 17 00:00:00 2001 From: "Skip R." Date: Wed, 30 Jul 2025 08:47:33 -0700 Subject: [PATCH 383/580] build: use `serviceid_clang.go` when building for arm64 windows (#606) --- pkg/libsignalgo/serviceid_clang.go | 2 +- pkg/libsignalgo/serviceid_gcc.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pkg/libsignalgo/serviceid_clang.go b/pkg/libsignalgo/serviceid_clang.go index 72c9ed3..89197b6 100644 --- a/pkg/libsignalgo/serviceid_clang.go +++ b/pkg/libsignalgo/serviceid_clang.go @@ -1,4 +1,4 @@ -//go:build darwin || android || ios +//go:build darwin || android || ios || (windows && arm64) package libsignalgo diff --git a/pkg/libsignalgo/serviceid_gcc.go b/pkg/libsignalgo/serviceid_gcc.go index b8dbbee..0feb627 100644 --- a/pkg/libsignalgo/serviceid_gcc.go +++ b/pkg/libsignalgo/serviceid_gcc.go @@ -1,4 +1,4 @@ -//go:build !(darwin || android || ios) +//go:build !(darwin || android || ios || (windows && arm64)) package libsignalgo From a17e60e3925464222b436a0c4cd618850f34e104 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Thu, 31 Jul 2025 14:25:09 +0300 Subject: [PATCH 384/580] dependencies: update mautrix-go --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index d174260..534e2c7 100644 --- a/go.mod +++ b/go.mod @@ -17,7 +17,7 @@ require ( golang.org/x/exp v0.0.0-20250718183923-645b1fa84792 golang.org/x/net v0.42.0 google.golang.org/protobuf v1.36.6 - maunium.net/go/mautrix v0.24.3-0.20250729131536-26e66f293e6a + maunium.net/go/mautrix v0.24.3-0.20250731110000-94f53c5853c6 ) require ( diff --git a/go.sum b/go.sum index 6f18389..c8a420f 100644 --- a/go.sum +++ b/go.sum @@ -95,5 +95,5 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= maunium.net/go/mauflag v1.0.0 h1:YiaRc0tEI3toYtJMRIfjP+jklH45uDHtT80nUamyD4M= maunium.net/go/mauflag v1.0.0/go.mod h1:nLivPOpTpHnpzEh8jEdSL9UqO9+/KBJFmNRlwKfkPeA= -maunium.net/go/mautrix v0.24.3-0.20250729131536-26e66f293e6a h1:+tnOE+D2F7wOQVY/SpBdssD9U45uvpfe2yYZ1FuXuIM= -maunium.net/go/mautrix v0.24.3-0.20250729131536-26e66f293e6a/go.mod h1:KrE/TdIeAo6cfAUICmbaiZ18UgHimTOozAGOrioK9SU= +maunium.net/go/mautrix v0.24.3-0.20250731110000-94f53c5853c6 h1:27wTzsIxqJ+xzqcGGSXfe3MGXHPgzmWHO2+lw7V8Tdk= +maunium.net/go/mautrix v0.24.3-0.20250731110000-94f53c5853c6/go.mod h1:KrE/TdIeAo6cfAUICmbaiZ18UgHimTOozAGOrioK9SU= From 456a69ff410345674c4ce1ca2e4b58203283bf97 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Fri, 1 Aug 2025 11:49:19 +0300 Subject: [PATCH 385/580] dependencies: update mautrix-go --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 534e2c7..9609350 100644 --- a/go.mod +++ b/go.mod @@ -17,7 +17,7 @@ require ( golang.org/x/exp v0.0.0-20250718183923-645b1fa84792 golang.org/x/net v0.42.0 google.golang.org/protobuf v1.36.6 - maunium.net/go/mautrix v0.24.3-0.20250731110000-94f53c5853c6 + maunium.net/go/mautrix v0.24.3-0.20250801084753-196164ed6749 ) require ( diff --git a/go.sum b/go.sum index c8a420f..33b1d29 100644 --- a/go.sum +++ b/go.sum @@ -95,5 +95,5 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= maunium.net/go/mauflag v1.0.0 h1:YiaRc0tEI3toYtJMRIfjP+jklH45uDHtT80nUamyD4M= maunium.net/go/mauflag v1.0.0/go.mod h1:nLivPOpTpHnpzEh8jEdSL9UqO9+/KBJFmNRlwKfkPeA= -maunium.net/go/mautrix v0.24.3-0.20250731110000-94f53c5853c6 h1:27wTzsIxqJ+xzqcGGSXfe3MGXHPgzmWHO2+lw7V8Tdk= -maunium.net/go/mautrix v0.24.3-0.20250731110000-94f53c5853c6/go.mod h1:KrE/TdIeAo6cfAUICmbaiZ18UgHimTOozAGOrioK9SU= +maunium.net/go/mautrix v0.24.3-0.20250801084753-196164ed6749 h1:eEIsN9CufSHs4SeRjUwIpJo3n8QaX0rfO2sEERjPkKY= +maunium.net/go/mautrix v0.24.3-0.20250801084753-196164ed6749/go.mod h1:KrE/TdIeAo6cfAUICmbaiZ18UgHimTOozAGOrioK9SU= From 80f2d2b87baa07ca83afd7ba2515f743263c5e9f Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Tue, 5 Aug 2025 10:45:52 +0300 Subject: [PATCH 386/580] signalmeow/contactdiscovery: update enclave ID --- pkg/signalmeow/contactdiscovery.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/signalmeow/contactdiscovery.go b/pkg/signalmeow/contactdiscovery.go index 2360457..07d9b49 100644 --- a/pkg/signalmeow/contactdiscovery.go +++ b/pkg/signalmeow/contactdiscovery.go @@ -40,7 +40,7 @@ import ( ) const ProdContactDiscoveryServer = "cdsi.signal.org" -const ProdContactDiscoveryMrenclave = "c6ff0682219217f7045624be472a077c0d4b06193fe71632eb0adb50051d5da1" +const ProdContactDiscoveryMrenclave = "ee9503070127120074612b6688e593b67e486b1541449f54d71e387484eb40a3" const ContactDiscoveryAuthTTL = 23 * time.Hour const rateLimitCloseCode = websocket.StatusCode(4008) From 31e390734bfca6f3d9c7bf692e1b4d0fb35b3765 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Tue, 12 Aug 2025 23:31:43 +0300 Subject: [PATCH 387/580] libsignal: update to v0.78.2 --- pkg/libsignalgo/libsignal | 2 +- pkg/libsignalgo/libsignal-ffi.h | 79 ++++++++++++++++++++++++++++- pkg/libsignalgo/messagebackupkey.go | 2 + pkg/libsignalgo/version.go | 2 +- 4 files changed, 81 insertions(+), 4 deletions(-) diff --git a/pkg/libsignalgo/libsignal b/pkg/libsignalgo/libsignal index 9fc4534..36916db 160000 --- a/pkg/libsignalgo/libsignal +++ b/pkg/libsignalgo/libsignal @@ -1 +1 @@ -Subproject commit 9fc4534b29fc488beeba082dd739aeae73032908 +Subproject commit 36916db152747b1a176527ceab4f826bf2d432fb diff --git a/pkg/libsignalgo/libsignal-ffi.h b/pkg/libsignalgo/libsignal-ffi.h index d52782d..0ed572f 100644 --- a/pkg/libsignalgo/libsignal-ffi.h +++ b/pkg/libsignalgo/libsignal-ffi.h @@ -23,6 +23,8 @@ SPDX-License-Identifier: AGPL-3.0-only #define SignalMEDIA_ID_LEN 15 +#define SignalBACKUP_FORWARD_SECRECY_TOKEN_LEN 32 + #define SignalMEDIA_ENCRYPTION_KEY_LEN (32 + 32) #define SignalBackupId_LEN 16 @@ -234,6 +236,7 @@ typedef enum { SignalErrorCodeSvrDataMissing = 160, SignalErrorCodeSvrRestoreFailed = 161, SignalErrorCodeSvrRotationMachineTooManySteps = 162, + SignalErrorCodeSvrRequestFailed = 163, SignalErrorCodeAppExpired = 170, SignalErrorCodeDeviceDeregistered = 171, SignalErrorCodeConnectionInvalidated = 172, @@ -276,6 +279,10 @@ typedef struct SignalAes256GcmSiv SignalAes256GcmSiv; typedef struct SignalAuthenticatedChatConnection SignalAuthenticatedChatConnection; +typedef struct SignalBackupRestoreResponse SignalBackupRestoreResponse; + +typedef struct SignalBackupStoreResponse SignalBackupStoreResponse; + typedef struct SignalBridgedStringMap SignalBridgedStringMap; typedef struct SignalCdsiLookup SignalCdsiLookup; @@ -612,6 +619,22 @@ typedef struct { SignalPrivateKey *raw; } SignalMutPointerPrivateKey; +typedef struct { + SignalBackupRestoreResponse *raw; +} SignalMutPointerBackupRestoreResponse; + +typedef struct { + const SignalBackupRestoreResponse *raw; +} SignalConstPointerBackupRestoreResponse; + +typedef struct { + SignalBackupStoreResponse *raw; +} SignalMutPointerBackupStoreResponse; + +typedef struct { + const SignalBackupStoreResponse *raw; +} SignalConstPointerBackupStoreResponse; + typedef struct { SignalBridgedStringMap *raw; } SignalMutPointerBridgedStringMap; @@ -1252,6 +1275,38 @@ typedef struct { SignalUnidentifiedSenderMessageContent *raw; } SignalMutPointerUnidentifiedSenderMessageContent; +typedef uint8_t SignalBackupKeyBytes[SignalBACKUP_KEY_LEN]; + +/** + * A C callback used to report the results of Rust futures. + * + * cbindgen will produce independent C types like `SignalCPromisei32` and + * `SignalCPromiseProtocolAddress`. + * + * This derives Copy because it behaves like a C type; nevertheless, a promise should still only be + * completed once. + */ +typedef struct { + void (*complete)(SignalFfiError *error, const SignalMutPointerBackupRestoreResponse *result, const void *context); + const void *context; + SignalCancellationId cancellation_id; +} SignalCPromiseMutPointerBackupRestoreResponse; + +/** + * A C callback used to report the results of Rust futures. + * + * cbindgen will produce independent C types like `SignalCPromisei32` and + * `SignalCPromiseProtocolAddress`. + * + * This derives Copy because it behaves like a C type; nevertheless, a promise should still only be + * completed once. + */ +typedef struct { + void (*complete)(SignalFfiError *error, const SignalMutPointerBackupStoreResponse *result, const void *context); + const void *context; + SignalCancellationId cancellation_id; +} SignalCPromiseMutPointerBackupStoreResponse; + typedef struct { SignalSenderCertificate *raw; } SignalMutPointerSenderCertificate; @@ -1451,6 +1506,20 @@ SignalFfiError *signal_backup_key_derive_media_id(uint8_t (*out)[SignalMEDIA_ID_ SignalFfiError *signal_backup_key_derive_thumbnail_transit_encryption_key(uint8_t (*out)[SignalMEDIA_ENCRYPTION_KEY_LEN], const uint8_t (*backup_key)[SignalBACKUP_KEY_LEN], const uint8_t (*media_id)[SignalMEDIA_ID_LEN]); +SignalFfiError *signal_backup_restore_response_destroy(SignalMutPointerBackupRestoreResponse p); + +SignalFfiError *signal_backup_restore_response_get_forward_secrecy_token(uint8_t (*out)[SignalBACKUP_FORWARD_SECRECY_TOKEN_LEN], SignalConstPointerBackupRestoreResponse response); + +SignalFfiError *signal_backup_restore_response_get_next_backup_secret_data(SignalOwnedBuffer *out, SignalConstPointerBackupRestoreResponse response); + +SignalFfiError *signal_backup_store_response_destroy(SignalMutPointerBackupStoreResponse p); + +SignalFfiError *signal_backup_store_response_get_forward_secrecy_token(uint8_t (*out)[SignalBACKUP_FORWARD_SECRECY_TOKEN_LEN], SignalConstPointerBackupStoreResponse response); + +SignalFfiError *signal_backup_store_response_get_next_backup_secret_data(SignalOwnedBuffer *out, SignalConstPointerBackupStoreResponse response); + +SignalFfiError *signal_backup_store_response_get_opaque_metadata(SignalOwnedBuffer *out, SignalConstPointerBackupStoreResponse response); + SignalFfiError *signal_bridged_string_map_clone(SignalMutPointerBridgedStringMap *new_obj, SignalConstPointerBridgedStringMap obj); SignalFfiError *signal_bridged_string_map_destroy(SignalMutPointerBridgedStringMap p); @@ -1843,9 +1912,9 @@ SignalFfiError *signal_lookup_request_set_token(SignalConstPointerLookupRequest SignalFfiError *signal_message_backup_key_destroy(SignalMutPointerMessageBackupKey p); -SignalFfiError *signal_message_backup_key_from_account_entropy_pool(SignalMutPointerMessageBackupKey *out, const char *account_entropy, const SignalServiceIdFixedWidthBinaryBytes *aci); +SignalFfiError *signal_message_backup_key_from_account_entropy_pool(SignalMutPointerMessageBackupKey *out, const char *account_entropy, const SignalServiceIdFixedWidthBinaryBytes *aci, const uint8_t (*forward_secrecy_token)[SignalBACKUP_FORWARD_SECRECY_TOKEN_LEN]); -SignalFfiError *signal_message_backup_key_from_backup_key_and_backup_id(SignalMutPointerMessageBackupKey *out, const uint8_t (*backup_key)[32], const uint8_t (*backup_id)[16]); +SignalFfiError *signal_message_backup_key_from_backup_key_and_backup_id(SignalMutPointerMessageBackupKey *out, const uint8_t (*backup_key)[32], const uint8_t (*backup_id)[16], const uint8_t (*forward_secrecy_token)[SignalBACKUP_FORWARD_SECRECY_TOKEN_LEN]); SignalFfiError *signal_message_backup_key_get_aes_key(uint8_t (*out)[32], SignalConstPointerMessageBackupKey key); @@ -2185,6 +2254,12 @@ SignalFfiError *signal_sealed_session_cipher_decrypt_to_usmc(SignalMutPointerUni SignalFfiError *signal_sealed_session_cipher_encrypt(SignalOwnedBuffer *out, SignalConstPointerProtocolAddress destination, SignalConstPointerUnidentifiedSenderMessageContent content, SignalConstPointerFfiIdentityKeyStoreStruct identity_key_store); +SignalFfiError *signal_secure_value_recovery_for_backups_create_new_backup_chain(SignalOwnedBuffer *out, uint8_t environment, const SignalBackupKeyBytes *backup_key); + +SignalFfiError *signal_secure_value_recovery_for_backups_restore_backup_from_server(SignalCPromiseMutPointerBackupRestoreResponse *promise, SignalConstPointerTokioAsyncContext async_runtime, const SignalBackupKeyBytes *backup_key, SignalBorrowedBuffer metadata, SignalConstPointerConnectionManager connection_manager, const char *username, const char *password); + +SignalFfiError *signal_secure_value_recovery_for_backups_store_backup(SignalCPromiseMutPointerBackupStoreResponse *promise, SignalConstPointerTokioAsyncContext async_runtime, const SignalBackupKeyBytes *backup_key, SignalBorrowedBuffer previous_secret_data, SignalConstPointerConnectionManager connection_manager, const char *username, const char *password); + SignalFfiError *signal_sender_certificate_clone(SignalMutPointerSenderCertificate *new_obj, SignalConstPointerSenderCertificate obj); SignalFfiError *signal_sender_certificate_deserialize(SignalMutPointerSenderCertificate *out, SignalBorrowedBuffer data); diff --git a/pkg/libsignalgo/messagebackupkey.go b/pkg/libsignalgo/messagebackupkey.go index 87f2b4f..65b4136 100644 --- a/pkg/libsignalgo/messagebackupkey.go +++ b/pkg/libsignalgo/messagebackupkey.go @@ -42,6 +42,7 @@ func MessageBackupKeyFromAccountEntropyPool(aep AccountEntropyPool, aci ServiceI &bk, C.CString(string(aep)), aci.CFixedBytes(), + nil, // TODO what's a forward secrecy token? ) runtime.KeepAlive(aep) if signalFfiError != nil { @@ -56,6 +57,7 @@ func MessageBackupKeyFromBackupKeyAndID(backupKey *BackupKey, backupID *BackupID &bk, (*[C.SignalBACKUP_KEY_LEN]C.uint8_t)(unsafe.Pointer(backupKey)), (*[BackupIDLength]C.uint8_t)(unsafe.Pointer(backupID)), + nil, // TODO what's a forward secrecy token? ) runtime.KeepAlive(backupKey) runtime.KeepAlive(backupID) diff --git a/pkg/libsignalgo/version.go b/pkg/libsignalgo/version.go index 90264fd..1db5dfc 100644 --- a/pkg/libsignalgo/version.go +++ b/pkg/libsignalgo/version.go @@ -2,4 +2,4 @@ package libsignalgo -const Version = "v0.76.7" +const Version = "v0.78.2" From 04fd88da5e00d3dd2a145e2581656ab54e52ba33 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Tue, 12 Aug 2025 23:32:31 +0300 Subject: [PATCH 388/580] changelog: update --- CHANGELOG.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 220f3ab..b81dfbd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,9 @@ +# v0.8.6 (unreleased) + +* Updated libsignal to v0.78.2. +* Added support for "delete to me" of chats and messages. +* Added support for latest Signal backup/transfer protocol. + # v0.8.5 (2025-07-16) * Updated libsignal to v0.76.1. From ee8a019a78f42133d4b7e15ae03afc5eca6f2bb6 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Sat, 16 Aug 2025 13:52:57 +0300 Subject: [PATCH 389/580] Bump version to v0.8.6 --- .github/workflows/go.yml | 8 +++---- .pre-commit-config.yaml | 4 ++-- CHANGELOG.md | 5 +++- cmd/mautrix-signal/main.go | 2 +- go.mod | 28 +++++++++++----------- go.sum | 48 +++++++++++++++++++------------------- 6 files changed, 49 insertions(+), 46 deletions(-) diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml index 6bbfaef..3913002 100644 --- a/.github/workflows/go.yml +++ b/.github/workflows/go.yml @@ -11,8 +11,8 @@ jobs: strategy: fail-fast: false matrix: - go-version: ["1.23", "1.24"] - name: Lint ${{ matrix.go-version == '1.24' && '(latest)' || '(old)' }} + go-version: ["1.24", "1.25"] + name: Lint ${{ matrix.go-version == '1.25' && '(latest)' || '(old)' }} steps: - uses: actions/checkout@v4 @@ -40,8 +40,8 @@ jobs: strategy: fail-fast: false matrix: - go-version: ["1.23", "1.24"] - name: Test ${{ matrix.go-version == '1.24' && '(latest)' || '(old)' }} + go-version: ["1.24", "1.25"] + name: Test ${{ matrix.go-version == '1.25' && '(latest)' || '(old)' }} steps: - uses: actions/checkout@v4 diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 1f3f910..f6b3302 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,6 +1,6 @@ repos: - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v5.0.0 + rev: v6.0.0 hooks: - id: trailing-whitespace exclude_types: [markdown] @@ -9,7 +9,7 @@ repos: - id: check-added-large-files - repo: https://github.com/tekwizely/pre-commit-golang - rev: v1.0.0-rc.1 + rev: v1.0.0-rc.2 hooks: - id: go-imports exclude: "pb\\.go$" diff --git a/CHANGELOG.md b/CHANGELOG.md index b81dfbd..3cf3475 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,8 @@ -# v0.8.6 (unreleased) +# v0.8.6 (2025-08-16) +* Deprecated legacy provisioning API. The `/_matrix/provision/v2` endpoints will + be deleted in the next release. +* Bumped minimum Go version to 1.24. * Updated libsignal to v0.78.2. * Added support for "delete to me" of chats and messages. * Added support for latest Signal backup/transfer protocol. diff --git a/cmd/mautrix-signal/main.go b/cmd/mautrix-signal/main.go index dc1a25a..d96283f 100644 --- a/cmd/mautrix-signal/main.go +++ b/cmd/mautrix-signal/main.go @@ -36,7 +36,7 @@ var m = mxmain.BridgeMain{ Name: "mautrix-signal", URL: "https://github.com/mautrix/signal", Description: "A Matrix-Signal puppeting bridge.", - Version: "0.8.5", + Version: "0.8.6", Connector: &connector.SignalConnector{}, } diff --git a/go.mod b/go.mod index 9609350..b66294a 100644 --- a/go.mod +++ b/go.mod @@ -1,8 +1,8 @@ module go.mau.fi/mautrix-signal -go 1.23.0 +go 1.24.0 -toolchain go1.24.5 +toolchain go1.25.0 require ( github.com/coder/websocket v1.8.13 @@ -12,12 +12,12 @@ require ( github.com/rs/zerolog v1.34.0 github.com/stretchr/testify v1.10.0 github.com/tidwall/gjson v1.18.0 - go.mau.fi/util v0.8.9-0.20250723171559-474867266038 - golang.org/x/crypto v0.40.0 - golang.org/x/exp v0.0.0-20250718183923-645b1fa84792 - golang.org/x/net v0.42.0 - google.golang.org/protobuf v1.36.6 - maunium.net/go/mautrix v0.24.3-0.20250801084753-196164ed6749 + go.mau.fi/util v0.9.0 + golang.org/x/crypto v0.41.0 + golang.org/x/exp v0.0.0-20250813145105-42675adae3e6 + golang.org/x/net v0.43.0 + google.golang.org/protobuf v1.36.7 + maunium.net/go/mautrix v0.25.0 ) require ( @@ -28,8 +28,8 @@ require ( github.com/lib/pq v1.10.9 // indirect github.com/mattn/go-colorable v0.1.14 // indirect github.com/mattn/go-isatty v0.0.20 // indirect - github.com/mattn/go-sqlite3 v1.14.28 // indirect - github.com/petermattis/goid v0.0.0-20250721140440-ea1c0173183e // indirect + github.com/mattn/go-sqlite3 v1.14.32 // indirect + github.com/petermattis/goid v0.0.0-20250813065127-a731cc31b4fe // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/rogpeppe/go-internal v1.10.0 // indirect github.com/rs/xid v1.6.0 // indirect @@ -37,11 +37,11 @@ require ( github.com/tidwall/match v1.1.1 // indirect github.com/tidwall/pretty v1.2.1 // indirect github.com/tidwall/sjson v1.2.5 // indirect - github.com/yuin/goldmark v1.7.12 // indirect - go.mau.fi/zeroconfig v0.1.3 // indirect + github.com/yuin/goldmark v1.7.13 // indirect + go.mau.fi/zeroconfig v0.2.0 // indirect golang.org/x/sync v0.16.0 // indirect - golang.org/x/sys v0.34.0 // indirect - golang.org/x/text v0.27.0 // indirect + golang.org/x/sys v0.35.0 // indirect + golang.org/x/text v0.28.0 // indirect gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect gopkg.in/natefinch/lumberjack.v2 v2.2.1 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect diff --git a/go.sum b/go.sum index 33b1d29..9fd93bc 100644 --- a/go.sum +++ b/go.sum @@ -34,10 +34,10 @@ github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWE github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mattn/go-pointer v0.0.1 h1:n+XhsuGeVO6MEAp7xyEukFINEa+Quek5psIR/ylA6o0= github.com/mattn/go-pointer v0.0.1/go.mod h1:2zXcozF6qYGgmsG+SeTZz3oAbFLdD3OWqnUbNvJZAlc= -github.com/mattn/go-sqlite3 v1.14.28 h1:ThEiQrnbtumT+QMknw63Befp/ce/nUPgBPMlRFEum7A= -github.com/mattn/go-sqlite3 v1.14.28/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y= -github.com/petermattis/goid v0.0.0-20250721140440-ea1c0173183e h1:D0bJD+4O3G4izvrQUmzCL80zazlN7EwJ0PPDhpJWC/I= -github.com/petermattis/goid v0.0.0-20250721140440-ea1c0173183e/go.mod h1:pxMtw7cyUw6B2bRH0ZBANSPg+AoSud1I1iyJHI69jH4= +github.com/mattn/go-sqlite3 v1.14.32 h1:JD12Ag3oLy1zQA+BNn74xRgaBbdhbNIDYvQUEuuErjs= +github.com/mattn/go-sqlite3 v1.14.32/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y= +github.com/petermattis/goid v0.0.0-20250813065127-a731cc31b4fe h1:vHpqOnPlnkba8iSxU4j/CvDSS9J4+F4473esQsYLGoE= +github.com/petermattis/goid v0.0.0-20250813065127-a731cc31b4fe/go.mod h1:pxMtw7cyUw6B2bRH0ZBANSPg+AoSud1I1iyJHI69jH4= github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= @@ -63,29 +63,29 @@ github.com/tidwall/pretty v1.2.1 h1:qjsOFOWWQl+N3RsoF5/ssm1pHmJJwhjlSbZ51I6wMl4= github.com/tidwall/pretty v1.2.1/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU= github.com/tidwall/sjson v1.2.5 h1:kLy8mja+1c9jlljvWTlSazM7cKDRfJuR/bOJhcY5NcY= github.com/tidwall/sjson v1.2.5/go.mod h1:Fvgq9kS/6ociJEDnK0Fk1cpYF4FIW6ZF7LAe+6jwd28= -github.com/yuin/goldmark v1.7.12 h1:YwGP/rrea2/CnCtUHgjuolG/PnMxdQtPMO5PvaE2/nY= -github.com/yuin/goldmark v1.7.12/go.mod h1:ip/1k0VRfGynBgxOz0yCqHrbZXhcjxyuS66Brc7iBKg= -go.mau.fi/util v0.8.9-0.20250723171559-474867266038 h1:RVL8TVaYc3LTBBopfjCNDtD+6eZks0O+qgXN/9hsz7k= -go.mau.fi/util v0.8.9-0.20250723171559-474867266038/go.mod h1:GZZp5f9r2MgEu4GDvtB0XxCF7i6Z7Z8fM0w9a5oZH3Y= -go.mau.fi/zeroconfig v0.1.3 h1:As9wYDKmktjmNZW5i1vn8zvJlmGKHeVxHVIBMXsm4kM= -go.mau.fi/zeroconfig v0.1.3/go.mod h1:NcSJkf180JT+1IId76PcMuLTNa1CzsFFZ0nBygIQM70= -golang.org/x/crypto v0.40.0 h1:r4x+VvoG5Fm+eJcxMaY8CQM7Lb0l1lsmjGBQ6s8BfKM= -golang.org/x/crypto v0.40.0/go.mod h1:Qr1vMER5WyS2dfPHAlsOj01wgLbsyWtFn/aY+5+ZdxY= -golang.org/x/exp v0.0.0-20250718183923-645b1fa84792 h1:R9PFI6EUdfVKgwKjZef7QIwGcBKu86OEFpJ9nUEP2l4= -golang.org/x/exp v0.0.0-20250718183923-645b1fa84792/go.mod h1:A+z0yzpGtvnG90cToK5n2tu8UJVP2XUATh+r+sfOOOc= -golang.org/x/net v0.42.0 h1:jzkYrhi3YQWD6MLBJcsklgQsoAcw89EcZbJw8Z614hs= -golang.org/x/net v0.42.0/go.mod h1:FF1RA5d3u7nAYA4z2TkclSCKh68eSXtiFwcWQpPXdt8= +github.com/yuin/goldmark v1.7.13 h1:GPddIs617DnBLFFVJFgpo1aBfe/4xcvMc3SB5t/D0pA= +github.com/yuin/goldmark v1.7.13/go.mod h1:ip/1k0VRfGynBgxOz0yCqHrbZXhcjxyuS66Brc7iBKg= +go.mau.fi/util v0.9.0 h1:ya3s3pX+Y8R2fgp0DbE7a0o3FwncoelDX5iyaeVE8ls= +go.mau.fi/util v0.9.0/go.mod h1:pdL3lg2aaeeHIreGXNnPwhJPXkXdc3ZxsI6le8hOWEA= +go.mau.fi/zeroconfig v0.2.0 h1:e/OGEERqVRRKlgaro7E6bh8xXiKFSXB3eNNIud7FUjU= +go.mau.fi/zeroconfig v0.2.0/go.mod h1:J0Vn0prHNOm493oZoQ84kq83ZaNCYZnq+noI1b1eN8w= +golang.org/x/crypto v0.41.0 h1:WKYxWedPGCTVVl5+WHSSrOBT0O8lx32+zxmHxijgXp4= +golang.org/x/crypto v0.41.0/go.mod h1:pO5AFd7FA68rFak7rOAGVuygIISepHftHnr8dr6+sUc= +golang.org/x/exp v0.0.0-20250813145105-42675adae3e6 h1:SbTAbRFnd5kjQXbczszQ0hdk3ctwYf3qBNH9jIsGclE= +golang.org/x/exp v0.0.0-20250813145105-42675adae3e6/go.mod h1:4QTo5u+SEIbbKW1RacMZq1YEfOBqeXa19JeshGi+zc4= +golang.org/x/net v0.43.0 h1:lat02VYK2j4aLzMzecihNvTlJNQUq316m2Mr9rnM6YE= +golang.org/x/net v0.43.0/go.mod h1:vhO1fvI4dGsIjh73sWfUVjj3N7CA9WkKJNQm2svM6Jg= golang.org/x/sync v0.16.0 h1:ycBJEhp9p4vXvUZNszeOq0kGTPghopOL8q0fq3vstxw= golang.org/x/sync v0.16.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.34.0 h1:H5Y5sJ2L2JRdyv7ROF1he/lPdvFsd0mJHFw2ThKHxLA= -golang.org/x/sys v0.34.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= -golang.org/x/text v0.27.0 h1:4fGWRpyh641NLlecmyl4LOe6yDdfaYNrGb2zdfo4JV4= -golang.org/x/text v0.27.0/go.mod h1:1D28KMCvyooCX9hBiosv5Tz/+YLxj0j7XhWjpSUF7CU= -google.golang.org/protobuf v1.36.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY= -google.golang.org/protobuf v1.36.6/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY= +golang.org/x/sys v0.35.0 h1:vz1N37gP5bs89s7He8XuIYXpyY0+QlsKmzipCbUtyxI= +golang.org/x/sys v0.35.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= +golang.org/x/text v0.28.0 h1:rhazDwis8INMIwQ4tpjLDzUhx6RlXqZNPEM0huQojng= +golang.org/x/text v0.28.0/go.mod h1:U8nCwOR8jO/marOQ0QbDiOngZVEBB7MAiitBuMjXiNU= +google.golang.org/protobuf v1.36.7 h1:IgrO7UwFQGJdRNXH/sQux4R1Dj1WAKcLElzeeRaXV2A= +google.golang.org/protobuf v1.36.7/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= @@ -95,5 +95,5 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= maunium.net/go/mauflag v1.0.0 h1:YiaRc0tEI3toYtJMRIfjP+jklH45uDHtT80nUamyD4M= maunium.net/go/mauflag v1.0.0/go.mod h1:nLivPOpTpHnpzEh8jEdSL9UqO9+/KBJFmNRlwKfkPeA= -maunium.net/go/mautrix v0.24.3-0.20250801084753-196164ed6749 h1:eEIsN9CufSHs4SeRjUwIpJo3n8QaX0rfO2sEERjPkKY= -maunium.net/go/mautrix v0.24.3-0.20250801084753-196164ed6749/go.mod h1:KrE/TdIeAo6cfAUICmbaiZ18UgHimTOozAGOrioK9SU= +maunium.net/go/mautrix v0.25.0 h1:dhYoXIXSxI9A+kEPwBceuRP0wcpho15dVLucUF8k2eE= +maunium.net/go/mautrix v0.25.0/go.mod h1:pDd6Ppg+1PbWrw/rg4ZQQfVYZICRGzH+DcliZ/BODvU= From 6900cc9d3d32a1b621bf49c6c814f86698a1a4e7 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Tue, 19 Aug 2025 12:32:38 +0300 Subject: [PATCH 390/580] signalmeow/keys: dispatch logged out event on prekey 422 error --- pkg/connector/handlesignal.go | 3 +++ pkg/signalmeow/events/message.go | 3 +++ pkg/signalmeow/keys.go | 2 ++ 3 files changed, 8 insertions(+) diff --git a/pkg/connector/handlesignal.go b/pkg/connector/handlesignal.go index f77d87d..803d481 100644 --- a/pkg/connector/handlesignal.go +++ b/pkg/connector/handlesignal.go @@ -30,6 +30,7 @@ import ( "maunium.net/go/mautrix/bridgev2/database" "maunium.net/go/mautrix/bridgev2/networkid" "maunium.net/go/mautrix/bridgev2/simplevent" + "maunium.net/go/mautrix/bridgev2/status" "maunium.net/go/mautrix/event" "go.mau.fi/mautrix-signal/pkg/libsignalgo" @@ -59,6 +60,8 @@ func (s *SignalClient) handleSignalEvent(rawEvt events.SignalEvent) bool { s.handleSignalACIFound(evt) case *events.QueueEmpty: s.queueEmptyWaiter.Set() + case *events.LoggedOut: + s.UserLogin.BridgeState.Send(status.BridgeState{StateEvent: status.StateBadCredentials, Message: evt.Error.Error()}) default: s.UserLogin.Log.Warn().Type("event_type", evt).Msg("Unrecognized signalmeow event type") } diff --git a/pkg/signalmeow/events/message.go b/pkg/signalmeow/events/message.go index 8a13329..cc7d62c 100644 --- a/pkg/signalmeow/events/message.go +++ b/pkg/signalmeow/events/message.go @@ -37,6 +37,7 @@ func (*ContactList) isSignalEvent() {} func (*ACIFound) isSignalEvent() {} func (*DeleteForMe) isSignalEvent() {} func (*QueueEmpty) isSignalEvent() {} +func (*LoggedOut) isSignalEvent() {} type MessageInfo struct { Sender uuid.UUID @@ -88,3 +89,5 @@ type DeleteForMe struct { } type QueueEmpty struct{} + +type LoggedOut struct{ Error error } diff --git a/pkg/signalmeow/keys.go b/pkg/signalmeow/keys.go index bc86789..a3f2690 100644 --- a/pkg/signalmeow/keys.go +++ b/pkg/signalmeow/keys.go @@ -30,6 +30,7 @@ import ( "github.com/rs/zerolog" "go.mau.fi/mautrix-signal/pkg/libsignalgo" + "go.mau.fi/mautrix-signal/pkg/signalmeow/events" "go.mau.fi/mautrix-signal/pkg/signalmeow/store" "go.mau.fi/mautrix-signal/pkg/signalmeow/web" ) @@ -630,6 +631,7 @@ func (cli *Client) keyCheckLoop(ctx context.Context) { if disconnectErr != nil { log.Err(disconnectErr).Msg("ClearKeysAndDisconnect error") } + cli.handleEvent(&events.LoggedOut{Error: err}) return } log.Err(err).Msg("Error checking and uploading new prekeys for PNI identity") From dcb4b0c99e80feada5a0582214d4ce90532d0b26 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Thu, 21 Aug 2025 17:13:50 +0300 Subject: [PATCH 391/580] msgconv/from-signal: don't use different logins for mention in split portals --- pkg/msgconv/msgconv.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pkg/msgconv/msgconv.go b/pkg/msgconv/msgconv.go index 01d46a6..86e7e2d 100644 --- a/pkg/msgconv/msgconv.go +++ b/pkg/msgconv/msgconv.go @@ -65,7 +65,8 @@ func NewMessageConverter(br *bridgev2.Bridge) *MessageConverter { Name: ghost.Name, } userLogin := br.GetCachedUserLoginByID(networkid.UserLoginID(uuid.String())) - if userLogin != nil { + portal := getPortal(ctx) + if userLogin != nil && (portal.Receiver == "" || portal.Receiver == userLogin.ID) { userInfo.MXID = userLogin.UserMXID // TODO find matrix user displayname? } From 2390b6e70f82fff66f05c28383d2a33cef33c652 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Fri, 22 Aug 2025 16:26:27 +0300 Subject: [PATCH 392/580] libsignal: update to v0.79.0 --- pkg/libsignalgo/libsignal | 2 +- pkg/libsignalgo/libsignal-ffi.h | 10 ++++------ pkg/libsignalgo/version.go | 2 +- 3 files changed, 6 insertions(+), 8 deletions(-) diff --git a/pkg/libsignalgo/libsignal b/pkg/libsignalgo/libsignal index 36916db..83690bd 160000 --- a/pkg/libsignalgo/libsignal +++ b/pkg/libsignalgo/libsignal @@ -1 +1 @@ -Subproject commit 36916db152747b1a176527ceab4f826bf2d432fb +Subproject commit 83690bdf1130c514e51d573ad0da7b3802aabb6e diff --git a/pkg/libsignalgo/libsignal-ffi.h b/pkg/libsignalgo/libsignal-ffi.h index 0ed572f..dc7fc18 100644 --- a/pkg/libsignalgo/libsignal-ffi.h +++ b/pkg/libsignalgo/libsignal-ffi.h @@ -1626,10 +1626,6 @@ SignalFfiError *signal_create_call_link_credential_request_issue_deterministic(S SignalFfiError *signal_create_call_link_credential_response_check_valid_contents(SignalBorrowedBuffer response_bytes); -SignalFfiError *signal_create_otp(const char **out, const char *username, SignalBorrowedBuffer secret); - -SignalFfiError *signal_create_otp_from_base64(const char **out, const char *username, const char *secret); - SignalFfiError *signal_decrypt_message(SignalOwnedBuffer *out, SignalConstPointerSignalMessage message, SignalConstPointerProtocolAddress protocol_address, SignalConstPointerFfiSessionStoreStruct session_store, SignalConstPointerFfiIdentityKeyStoreStruct identity_key_store); SignalFfiError *signal_decrypt_pre_key_message(SignalOwnedBuffer *out, SignalConstPointerPreKeySignalMessage message, SignalConstPointerProtocolAddress protocol_address, SignalConstPointerFfiSessionStoreStruct session_store, SignalConstPointerFfiIdentityKeyStoreStruct identity_key_store, SignalConstPointerFfiPreKeyStoreStruct prekey_store, SignalConstPointerFfiSignedPreKeyStoreStruct signed_prekey_store, SignalConstPointerFfiKyberPreKeyStoreStruct kyber_prekey_store, bool use_pq_ratchet); @@ -1792,7 +1788,7 @@ SignalFfiError *signal_group_send_token_check_valid_contents(SignalBorrowedBuffe SignalFfiError *signal_group_send_token_to_full_token(SignalOwnedBuffer *out, SignalBorrowedBuffer token, uint64_t expiration); -SignalFfiError *signal_hex_encode(char *output, size_t output_len, const uint8_t *input, size_t input_len); +SignalFfiError *signal_hex_encode(SignalBorrowedMutableBuffer output, SignalBorrowedBuffer input); SignalFfiError *signal_hkdf_derive(SignalBorrowedMutableBuffer output, SignalBorrowedBuffer ikm, SignalBorrowedBuffer label, SignalBorrowedBuffer salt); @@ -1842,7 +1838,7 @@ SignalFfiError *signal_key_transparency_distinguished(SignalCPromiseOwnedBufferO SignalFfiError *signal_key_transparency_e164_search_key(SignalOwnedBuffer *out, const char *e164); -SignalFfiError *signal_key_transparency_monitor(SignalCPromiseOwnedBufferOfc_uchar *promise, SignalConstPointerTokioAsyncContext async_runtime, uint8_t environment, SignalConstPointerUnauthenticatedChatConnection chat_connection, const SignalServiceIdFixedWidthBinaryBytes *aci, SignalConstPointerPublicKey aci_identity_key, const char *e164, SignalOptionalBorrowedSliceOfc_uchar unidentified_access_key, SignalOptionalBorrowedSliceOfc_uchar username_hash, SignalOptionalBorrowedSliceOfc_uchar account_data, SignalBorrowedBuffer last_distinguished_tree_head); +SignalFfiError *signal_key_transparency_monitor(SignalCPromiseOwnedBufferOfc_uchar *promise, SignalConstPointerTokioAsyncContext async_runtime, uint8_t environment, SignalConstPointerUnauthenticatedChatConnection chat_connection, const SignalServiceIdFixedWidthBinaryBytes *aci, SignalConstPointerPublicKey aci_identity_key, const char *e164, SignalOptionalBorrowedSliceOfc_uchar unidentified_access_key, SignalOptionalBorrowedSliceOfc_uchar username_hash, SignalOptionalBorrowedSliceOfc_uchar account_data, SignalBorrowedBuffer last_distinguished_tree_head, bool is_self_monitor); SignalFfiError *signal_key_transparency_search(SignalCPromiseOwnedBufferOfc_uchar *promise, SignalConstPointerTokioAsyncContext async_runtime, uint8_t environment, SignalConstPointerUnauthenticatedChatConnection chat_connection, const SignalServiceIdFixedWidthBinaryBytes *aci, SignalConstPointerPublicKey aci_identity_key, const char *e164, SignalOptionalBorrowedSliceOfc_uchar unidentified_access_key, SignalOptionalBorrowedSliceOfc_uchar username_hash, SignalOptionalBorrowedSliceOfc_uchar account_data, SignalBorrowedBuffer last_distinguished_tree_head); @@ -2256,6 +2252,8 @@ SignalFfiError *signal_sealed_session_cipher_encrypt(SignalOwnedBuffer *out, Sig SignalFfiError *signal_secure_value_recovery_for_backups_create_new_backup_chain(SignalOwnedBuffer *out, uint8_t environment, const SignalBackupKeyBytes *backup_key); +SignalFfiError *signal_secure_value_recovery_for_backups_remove_backup(SignalCPromisebool *promise, SignalConstPointerTokioAsyncContext async_runtime, SignalConstPointerConnectionManager connection_manager, const char *username, const char *password); + SignalFfiError *signal_secure_value_recovery_for_backups_restore_backup_from_server(SignalCPromiseMutPointerBackupRestoreResponse *promise, SignalConstPointerTokioAsyncContext async_runtime, const SignalBackupKeyBytes *backup_key, SignalBorrowedBuffer metadata, SignalConstPointerConnectionManager connection_manager, const char *username, const char *password); SignalFfiError *signal_secure_value_recovery_for_backups_store_backup(SignalCPromiseMutPointerBackupStoreResponse *promise, SignalConstPointerTokioAsyncContext async_runtime, const SignalBackupKeyBytes *backup_key, SignalBorrowedBuffer previous_secret_data, SignalConstPointerConnectionManager connection_manager, const char *username, const char *password); diff --git a/pkg/libsignalgo/version.go b/pkg/libsignalgo/version.go index 1db5dfc..04012e8 100644 --- a/pkg/libsignalgo/version.go +++ b/pkg/libsignalgo/version.go @@ -2,4 +2,4 @@ package libsignalgo -const Version = "v0.78.2" +const Version = "v0.79.0" From dff8052be315c5e1608b9b9934c32d54293da3f8 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Fri, 22 Aug 2025 16:28:48 +0300 Subject: [PATCH 393/580] signalmeow: update protobufs --- pkg/msgconv/from-signal-backup.go | 16 - pkg/signalmeow/protobuf/Provisioning.pb.go | 38 +- pkg/signalmeow/protobuf/Provisioning.proto | 60 +- pkg/signalmeow/protobuf/StorageService.pb.go | 10 +- pkg/signalmeow/protobuf/StorageService.proto | 2 +- pkg/signalmeow/protobuf/backuppb/Backup.pb.go | 813 ++++-------------- pkg/signalmeow/protobuf/backuppb/Backup.proto | 84 +- pkg/signalmeow/protobuf/update-protos.sh | 4 +- 8 files changed, 244 insertions(+), 783 deletions(-) diff --git a/pkg/msgconv/from-signal-backup.go b/pkg/msgconv/from-signal-backup.go index 5f7f12b..7e8d4e1 100644 --- a/pkg/msgconv/from-signal-backup.go +++ b/pkg/msgconv/from-signal-backup.go @@ -205,26 +205,10 @@ func backupToSignalAttachment( sig.AttachmentIdentifier = &signalpb.AttachmentPointer_CdnKey{CdnKey: *fp.LocatorInfo.TransitCdnKey} sig.Size = &fp.LocatorInfo.Size sig.Digest = fp.LocatorInfo.GetEncryptedDigest() // Note: may be nil if plaintextHash is set instead - if sig.Digest == nil { - sig.Digest = fp.LocatorInfo.LegacyDigest - } sig.CdnNumber = fp.LocatorInfo.TransitCdnNumber } sig.Key = fp.LocatorInfo.Key atts[clientUUID] = fp.LocatorInfo - } else { - switch loc := fp.Locator.(type) { - case *backuppb.FilePointer_AttachmentLocator_: - sig.AttachmentIdentifier = &signalpb.AttachmentPointer_CdnKey{CdnKey: loc.AttachmentLocator.CdnKey} - sig.Key = loc.AttachmentLocator.Key - sig.Size = &loc.AttachmentLocator.Size - sig.Digest = loc.AttachmentLocator.Digest - sig.CdnNumber = &loc.AttachmentLocator.CdnNumber - case *backuppb.FilePointer_BackupLocator_: - //atts[clientUUID] = loc.BackupLocator - case *backuppb.FilePointer_InvalidAttachmentLocator_: - atts[clientUUID] = nil - } } return sig } diff --git a/pkg/signalmeow/protobuf/Provisioning.pb.go b/pkg/signalmeow/protobuf/Provisioning.pb.go index e2fbf7c..9e75ec2 100644 --- a/pkg/signalmeow/protobuf/Provisioning.pb.go +++ b/pkg/signalmeow/protobuf/Provisioning.pb.go @@ -1,7 +1,6 @@ -//* -// Copyright (C) 2014-2016 Open Whisper Systems // -// Licensed according to the LICENSE file in this repository. +// Copyright 2020 Signal Messenger, LLC +// SPDX-License-Identifier: AGPL-3.0-only // Code generated by protoc-gen-go. DO NOT EDIT. // versions: @@ -85,9 +84,14 @@ func (ProvisioningVersion) EnumDescriptor() ([]byte, []int) { return file_Provisioning_proto_rawDescGZIP(), []int{0} } +// An opaque address sent by the server when clients first open a provisioning +// WebSocket type ProvisioningAddress struct { - state protoimpl.MessageState `protogen:"open.v1"` - Address *string `protobuf:"bytes,1,opt,name=address" json:"address,omitempty"` + state protoimpl.MessageState `protogen:"open.v1"` + // The opaque provisioning address for the active provisioning WebSocket + // session; clients should not attempt to interpret or modify the contents + // of the address string + Address *string `protobuf:"bytes,1,opt,name=address" json:"address,omitempty"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } @@ -195,10 +199,12 @@ type ProvisionMessage struct { ProfileKey []byte `protobuf:"bytes,6,opt,name=profileKey" json:"profileKey,omitempty"` ReadReceipts *bool `protobuf:"varint,7,opt,name=readReceipts" json:"readReceipts,omitempty"` ProvisioningVersion *uint32 `protobuf:"varint,9,opt,name=provisioningVersion" json:"provisioningVersion,omitempty"` - MasterKey []byte `protobuf:"bytes,13,opt,name=masterKey" json:"masterKey,omitempty"` + MasterKey []byte `protobuf:"bytes,13,opt,name=masterKey" json:"masterKey,omitempty"` // Deprecated, but required by linked devices EphemeralBackupKey []byte `protobuf:"bytes,14,opt,name=ephemeralBackupKey" json:"ephemeralBackupKey,omitempty"` // 32 bytes AccountEntropyPool *string `protobuf:"bytes,15,opt,name=accountEntropyPool" json:"accountEntropyPool,omitempty"` MediaRootBackupKey []byte `protobuf:"bytes,16,opt,name=mediaRootBackupKey" json:"mediaRootBackupKey,omitempty"` // 32-bytes + AciBinary []byte `protobuf:"bytes,17,opt,name=aciBinary" json:"aciBinary,omitempty"` // 16-byte UUID + PniBinary []byte `protobuf:"bytes,18,opt,name=pniBinary" json:"pniBinary,omitempty"` // 16-byte UUID unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } @@ -345,6 +351,20 @@ func (x *ProvisionMessage) GetMediaRootBackupKey() []byte { return nil } +func (x *ProvisionMessage) GetAciBinary() []byte { + if x != nil { + return x.AciBinary + } + return nil +} + +func (x *ProvisionMessage) GetPniBinary() []byte { + if x != nil { + return x.PniBinary + } + return nil +} + var File_Provisioning_proto protoreflect.FileDescriptor const file_Provisioning_proto_rawDesc = "" + @@ -354,7 +374,7 @@ const file_Provisioning_proto_rawDesc = "" + "\aaddress\x18\x01 \x01(\tR\aaddress\"E\n" + "\x11ProvisionEnvelope\x12\x1c\n" + "\tpublicKey\x18\x01 \x01(\fR\tpublicKey\x12\x12\n" + - "\x04body\x18\x02 \x01(\fR\x04body\"\x90\x05\n" + + "\x04body\x18\x02 \x01(\fR\x04body\"\xcc\x05\n" + "\x10ProvisionMessage\x122\n" + "\x14aciIdentityKeyPublic\x18\x01 \x01(\fR\x14aciIdentityKeyPublic\x124\n" + "\x15aciIdentityKeyPrivate\x18\x02 \x01(\fR\x15aciIdentityKeyPrivate\x122\n" + @@ -374,7 +394,9 @@ const file_Provisioning_proto_rawDesc = "" + "\tmasterKey\x18\r \x01(\fR\tmasterKey\x12.\n" + "\x12ephemeralBackupKey\x18\x0e \x01(\fR\x12ephemeralBackupKey\x12.\n" + "\x12accountEntropyPool\x18\x0f \x01(\tR\x12accountEntropyPool\x12.\n" + - "\x12mediaRootBackupKey\x18\x10 \x01(\fR\x12mediaRootBackupKey*G\n" + + "\x12mediaRootBackupKey\x18\x10 \x01(\fR\x12mediaRootBackupKey\x12\x1c\n" + + "\taciBinary\x18\x11 \x01(\fR\taciBinary\x12\x1c\n" + + "\tpniBinary\x18\x12 \x01(\fR\tpniBinary*G\n" + "\x13ProvisioningVersion\x12\v\n" + "\aINITIAL\x10\x00\x12\x12\n" + "\x0eTABLET_SUPPORT\x10\x01\x12\v\n" + diff --git a/pkg/signalmeow/protobuf/Provisioning.proto b/pkg/signalmeow/protobuf/Provisioning.proto index e18829a..2fde938 100644 --- a/pkg/signalmeow/protobuf/Provisioning.proto +++ b/pkg/signalmeow/protobuf/Provisioning.proto @@ -1,48 +1,56 @@ -/** - * Copyright (C) 2014-2016 Open Whisper Systems - * - * Licensed according to the LICENSE file in this repository. +/* + * Copyright 2020 Signal Messenger, LLC + * SPDX-License-Identifier: AGPL-3.0-only */ + syntax = "proto2"; package signalservice; -option java_package = "org.whispersystems.signalservice.internal.push"; +option java_package = "org.whispersystems.signalservice.internal.push"; option java_outer_classname = "ProvisioningProtos"; +// An opaque address sent by the server when clients first open a provisioning +// WebSocket message ProvisioningAddress { + + // The opaque provisioning address for the active provisioning WebSocket + // session; clients should not attempt to interpret or modify the contents + // of the address string optional string address = 1; } message ProvisionEnvelope { optional bytes publicKey = 1; - optional bytes body = 2; // Encrypted ProvisionMessage + optional bytes body = 2; // Encrypted ProvisionMessage } message ProvisionMessage { - optional bytes aciIdentityKeyPublic = 1; - optional bytes aciIdentityKeyPrivate = 2; - optional bytes pniIdentityKeyPublic = 11; - optional bytes pniIdentityKeyPrivate = 12; - optional string aci = 8; - optional string pni = 10; - optional string number = 3; - optional string provisioningCode = 4; - optional string userAgent = 5; - optional bytes profileKey = 6; - optional bool readReceipts = 7; - optional uint32 provisioningVersion = 9; - optional bytes masterKey = 13; - optional bytes ephemeralBackupKey = 14; // 32 bytes - optional string accountEntropyPool = 15; - optional bytes mediaRootBackupKey = 16; // 32-bytes - // NEXT ID: 17 + optional bytes aciIdentityKeyPublic = 1; + optional bytes aciIdentityKeyPrivate = 2; + optional bytes pniIdentityKeyPublic = 11; + optional bytes pniIdentityKeyPrivate = 12; + optional string aci = 8; + optional string pni = 10; + optional string number = 3; + optional string provisioningCode = 4; + optional string userAgent = 5; + optional bytes profileKey = 6; + optional bool readReceipts = 7; + optional uint32 provisioningVersion = 9; + optional bytes masterKey = 13; // Deprecated, but required by linked devices + optional bytes ephemeralBackupKey = 14; // 32 bytes + optional string accountEntropyPool = 15; + optional bytes mediaRootBackupKey = 16; // 32-bytes + optional bytes aciBinary = 17; // 16-byte UUID + optional bytes pniBinary = 18; // 16-byte UUID + // NEXT ID: 19 } enum ProvisioningVersion { option allow_alias = true; - INITIAL = 0; - TABLET_SUPPORT = 1; - CURRENT = 1; + INITIAL = 0; + TABLET_SUPPORT = 1; + CURRENT = 1; } diff --git a/pkg/signalmeow/protobuf/StorageService.pb.go b/pkg/signalmeow/protobuf/StorageService.pb.go index 3bfa1c1..33804f6 100644 --- a/pkg/signalmeow/protobuf/StorageService.pb.go +++ b/pkg/signalmeow/protobuf/StorageService.pb.go @@ -1962,7 +1962,7 @@ type CallLinkRecord struct { RootKey []byte `protobuf:"bytes,1,opt,name=rootKey,proto3" json:"rootKey,omitempty"` AdminPasskey []byte `protobuf:"bytes,2,opt,name=adminPasskey,proto3" json:"adminPasskey,omitempty"` DeletedAtTimestampMs uint64 `protobuf:"varint,3,opt,name=deletedAtTimestampMs,proto3" json:"deletedAtTimestampMs,omitempty"` - Epoch []byte `protobuf:"bytes,4,opt,name=epoch,proto3" json:"epoch,omitempty"` + Epoch []byte `protobuf:"bytes,4,opt,name=epoch,proto3,oneof" json:"epoch,omitempty"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } @@ -3267,12 +3267,13 @@ const file_StorageService_proto_rawDesc = "" + "\x13recipientServiceIds\x18\x03 \x03(\tR\x13recipientServiceIds\x12.\n" + "\x12deletedAtTimestamp\x18\x04 \x01(\x04R\x12deletedAtTimestamp\x12$\n" + "\rallowsReplies\x18\x05 \x01(\bR\rallowsReplies\x12 \n" + - "\visBlockList\x18\x06 \x01(\bR\visBlockList\"\x98\x01\n" + + "\visBlockList\x18\x06 \x01(\bR\visBlockList\"\xa7\x01\n" + "\x0eCallLinkRecord\x12\x18\n" + "\arootKey\x18\x01 \x01(\fR\arootKey\x12\"\n" + "\fadminPasskey\x18\x02 \x01(\fR\fadminPasskey\x122\n" + - "\x14deletedAtTimestampMs\x18\x03 \x01(\x04R\x14deletedAtTimestampMs\x12\x14\n" + - "\x05epoch\x18\x04 \x01(\fR\x05epoch\"\xe6\x01\n" + + "\x14deletedAtTimestampMs\x18\x03 \x01(\x04R\x14deletedAtTimestampMs\x12\x19\n" + + "\x05epoch\x18\x04 \x01(\fH\x00R\x05epoch\x88\x01\x01B\b\n" + + "\x06_epoch\"\xe6\x01\n" + "\tRecipient\x12<\n" + "\acontact\x18\x01 \x01(\v2 .signalservice.Recipient.ContactH\x00R\acontact\x12&\n" + "\rlegacyGroupId\x18\x02 \x01(\fH\x00R\rlegacyGroupId\x12(\n" + @@ -3467,6 +3468,7 @@ func file_StorageService_proto_init() { file_StorageService_proto_msgTypes[7].OneofWrappers = []any{} file_StorageService_proto_msgTypes[9].OneofWrappers = []any{} file_StorageService_proto_msgTypes[11].OneofWrappers = []any{} + file_StorageService_proto_msgTypes[13].OneofWrappers = []any{} file_StorageService_proto_msgTypes[14].OneofWrappers = []any{ (*Recipient_Contact_)(nil), (*Recipient_LegacyGroupId)(nil), diff --git a/pkg/signalmeow/protobuf/StorageService.proto b/pkg/signalmeow/protobuf/StorageService.proto index 2229805..4258fba 100644 --- a/pkg/signalmeow/protobuf/StorageService.proto +++ b/pkg/signalmeow/protobuf/StorageService.proto @@ -306,7 +306,7 @@ message CallLinkRecord { bytes rootKey = 1; bytes adminPasskey = 2; uint64 deletedAtTimestampMs = 3; - bytes epoch = 4; + optional bytes epoch = 4; } message Recipient { diff --git a/pkg/signalmeow/protobuf/backuppb/Backup.pb.go b/pkg/signalmeow/protobuf/backuppb/Backup.pb.go index cc4b279..3eaaed0 100644 --- a/pkg/signalmeow/protobuf/backuppb/Backup.pb.go +++ b/pkg/signalmeow/protobuf/backuppb/Backup.pb.go @@ -2944,7 +2944,7 @@ type CallLink struct { Name string `protobuf:"bytes,3,opt,name=name,proto3" json:"name,omitempty"` Restrictions CallLink_Restrictions `protobuf:"varint,4,opt,name=restrictions,proto3,enum=signal.backup.CallLink_Restrictions" json:"restrictions,omitempty"` ExpirationMs uint64 `protobuf:"varint,5,opt,name=expirationMs,proto3" json:"expirationMs,omitempty"` - Epoch []byte `protobuf:"bytes,6,opt,name=epoch,proto3" json:"epoch,omitempty"` // May be absent/empty for older links + Epoch []byte `protobuf:"bytes,6,opt,name=epoch,proto3,oneof" json:"epoch,omitempty"` // May be absent/empty for older links unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } @@ -4603,17 +4603,7 @@ func (x *MessageAttachment) GetClientUuid() []byte { } type FilePointer struct { - state protoimpl.MessageState `protogen:"open.v1"` - // If unset, importers should consider it to be an InvalidAttachmentLocator without throwing an error. - // DEPRECATED; use locatorInfo instead. - // - // Types that are valid to be assigned to Locator: - // - // *FilePointer_BackupLocator_ - // *FilePointer_AttachmentLocator_ - // *FilePointer_InvalidAttachmentLocator_ - // *FilePointer_LocalLocator_ - Locator isFilePointer_Locator `protobuf_oneof:"locator"` + state protoimpl.MessageState `protogen:"open.v1"` ContentType *string `protobuf:"bytes,4,opt,name=contentType,proto3,oneof" json:"contentType,omitempty"` IncrementalMac []byte `protobuf:"bytes,5,opt,name=incrementalMac,proto3,oneof" json:"incrementalMac,omitempty"` IncrementalMacChunkSize *uint32 `protobuf:"varint,6,opt,name=incrementalMacChunkSize,proto3,oneof" json:"incrementalMacChunkSize,omitempty"` @@ -4657,49 +4647,6 @@ func (*FilePointer) Descriptor() ([]byte, []int) { return file_backuppb_Backup_proto_rawDescGZIP(), []int{28} } -func (x *FilePointer) GetLocator() isFilePointer_Locator { - if x != nil { - return x.Locator - } - return nil -} - -func (x *FilePointer) GetBackupLocator() *FilePointer_BackupLocator { - if x != nil { - if x, ok := x.Locator.(*FilePointer_BackupLocator_); ok { - return x.BackupLocator - } - } - return nil -} - -func (x *FilePointer) GetAttachmentLocator() *FilePointer_AttachmentLocator { - if x != nil { - if x, ok := x.Locator.(*FilePointer_AttachmentLocator_); ok { - return x.AttachmentLocator - } - } - return nil -} - -func (x *FilePointer) GetInvalidAttachmentLocator() *FilePointer_InvalidAttachmentLocator { - if x != nil { - if x, ok := x.Locator.(*FilePointer_InvalidAttachmentLocator_); ok { - return x.InvalidAttachmentLocator - } - } - return nil -} - -func (x *FilePointer) GetLocalLocator() *FilePointer_LocalLocator { - if x != nil { - if x, ok := x.Locator.(*FilePointer_LocalLocator_); ok { - return x.LocalLocator - } - } - return nil -} - func (x *FilePointer) GetContentType() string { if x != nil && x.ContentType != nil { return *x.ContentType @@ -4763,34 +4710,6 @@ func (x *FilePointer) GetLocatorInfo() *FilePointer_LocatorInfo { return nil } -type isFilePointer_Locator interface { - isFilePointer_Locator() -} - -type FilePointer_BackupLocator_ struct { - BackupLocator *FilePointer_BackupLocator `protobuf:"bytes,1,opt,name=backupLocator,proto3,oneof"` -} - -type FilePointer_AttachmentLocator_ struct { - AttachmentLocator *FilePointer_AttachmentLocator `protobuf:"bytes,2,opt,name=attachmentLocator,proto3,oneof"` -} - -type FilePointer_InvalidAttachmentLocator_ struct { - InvalidAttachmentLocator *FilePointer_InvalidAttachmentLocator `protobuf:"bytes,3,opt,name=invalidAttachmentLocator,proto3,oneof"` -} - -type FilePointer_LocalLocator_ struct { - LocalLocator *FilePointer_LocalLocator `protobuf:"bytes,12,opt,name=localLocator,proto3,oneof"` -} - -func (*FilePointer_BackupLocator_) isFilePointer_Locator() {} - -func (*FilePointer_AttachmentLocator_) isFilePointer_Locator() {} - -func (*FilePointer_InvalidAttachmentLocator_) isFilePointer_Locator() {} - -func (*FilePointer_LocalLocator_) isFilePointer_Locator() {} - type Quote struct { state protoimpl.MessageState `protogen:"open.v1"` TargetSentTimestamp *uint64 `protobuf:"varint,1,opt,name=targetSentTimestamp,proto3,oneof" json:"targetSentTimestamp,omitempty"` // null if the target message could not be found at time of quote insert @@ -9074,6 +8993,7 @@ func (x *ChatItem_IncomingMessageDetails) GetSealedSender() bool { type ChatItem_OutgoingMessageDetails struct { state protoimpl.MessageState `protogen:"open.v1"` SendStatus []*SendStatus `protobuf:"bytes,1,rep,name=sendStatus,proto3" json:"sendStatus,omitempty"` + DateReceived uint64 `protobuf:"varint,2,opt,name=dateReceived,proto3" json:"dateReceived,omitempty"` // may be different from dateSent for sync messages unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } @@ -9115,6 +9035,13 @@ func (x *ChatItem_OutgoingMessageDetails) GetSendStatus() []*SendStatus { return nil } +func (x *ChatItem_OutgoingMessageDetails) GetDateReceived() uint64 { + if x != nil { + return x.DateReceived + } + return 0 +} + type ChatItem_DirectionlessMessageDetails struct { state protoimpl.MessageState `protogen:"open.v1"` unknownFields protoimpl.UnknownFields @@ -10085,351 +10012,11 @@ func (x *ContactAttachment_PostalAddress) GetCountry() string { return "" } -// References attachments in the backup (media) storage tier. -// DEPRECATED; use LocatorInfo instead if available. -type FilePointer_BackupLocator struct { - state protoimpl.MessageState `protogen:"open.v1"` - MediaName string `protobuf:"bytes,1,opt,name=mediaName,proto3" json:"mediaName,omitempty"` - // If present, the cdn number of the succesful upload. - // If empty/0, may still have been uploaded, and clients - // can discover the cdn number via the list endpoint. - CdnNumber *uint32 `protobuf:"varint,2,opt,name=cdnNumber,proto3,oneof" json:"cdnNumber,omitempty"` - Key []byte `protobuf:"bytes,3,opt,name=key,proto3" json:"key,omitempty"` - Digest []byte `protobuf:"bytes,4,opt,name=digest,proto3" json:"digest,omitempty"` - Size uint32 `protobuf:"varint,5,opt,name=size,proto3" json:"size,omitempty"` - // Fallback in case backup tier upload failed. - TransitCdnKey *string `protobuf:"bytes,6,opt,name=transitCdnKey,proto3,oneof" json:"transitCdnKey,omitempty"` - TransitCdnNumber *uint32 `protobuf:"varint,7,opt,name=transitCdnNumber,proto3,oneof" json:"transitCdnNumber,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache -} - -func (x *FilePointer_BackupLocator) Reset() { - *x = FilePointer_BackupLocator{} - mi := &file_backuppb_Backup_proto_msgTypes[113] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) -} - -func (x *FilePointer_BackupLocator) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*FilePointer_BackupLocator) ProtoMessage() {} - -func (x *FilePointer_BackupLocator) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[113] - if x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use FilePointer_BackupLocator.ProtoReflect.Descriptor instead. -func (*FilePointer_BackupLocator) Descriptor() ([]byte, []int) { - return file_backuppb_Backup_proto_rawDescGZIP(), []int{28, 0} -} - -func (x *FilePointer_BackupLocator) GetMediaName() string { - if x != nil { - return x.MediaName - } - return "" -} - -func (x *FilePointer_BackupLocator) GetCdnNumber() uint32 { - if x != nil && x.CdnNumber != nil { - return *x.CdnNumber - } - return 0 -} - -func (x *FilePointer_BackupLocator) GetKey() []byte { - if x != nil { - return x.Key - } - return nil -} - -func (x *FilePointer_BackupLocator) GetDigest() []byte { - if x != nil { - return x.Digest - } - return nil -} - -func (x *FilePointer_BackupLocator) GetSize() uint32 { - if x != nil { - return x.Size - } - return 0 -} - -func (x *FilePointer_BackupLocator) GetTransitCdnKey() string { - if x != nil && x.TransitCdnKey != nil { - return *x.TransitCdnKey - } - return "" -} - -func (x *FilePointer_BackupLocator) GetTransitCdnNumber() uint32 { - if x != nil && x.TransitCdnNumber != nil { - return *x.TransitCdnNumber - } - return 0 -} - -// References attachments in the transit storage tier. -// May be downloaded or not when the backup is generated; -// primarily for free-tier users who cannot copy the -// attachments to the backup (media) storage tier. -// DEPRECATED; use LocatorInfo instead if available. -type FilePointer_AttachmentLocator struct { - state protoimpl.MessageState `protogen:"open.v1"` - CdnKey string `protobuf:"bytes,1,opt,name=cdnKey,proto3" json:"cdnKey,omitempty"` - CdnNumber uint32 `protobuf:"varint,2,opt,name=cdnNumber,proto3" json:"cdnNumber,omitempty"` - UploadTimestamp *uint64 `protobuf:"varint,3,opt,name=uploadTimestamp,proto3,oneof" json:"uploadTimestamp,omitempty"` - Key []byte `protobuf:"bytes,4,opt,name=key,proto3" json:"key,omitempty"` - Digest []byte `protobuf:"bytes,5,opt,name=digest,proto3" json:"digest,omitempty"` - Size uint32 `protobuf:"varint,6,opt,name=size,proto3" json:"size,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache -} - -func (x *FilePointer_AttachmentLocator) Reset() { - *x = FilePointer_AttachmentLocator{} - mi := &file_backuppb_Backup_proto_msgTypes[114] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) -} - -func (x *FilePointer_AttachmentLocator) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*FilePointer_AttachmentLocator) ProtoMessage() {} - -func (x *FilePointer_AttachmentLocator) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[114] - if x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use FilePointer_AttachmentLocator.ProtoReflect.Descriptor instead. -func (*FilePointer_AttachmentLocator) Descriptor() ([]byte, []int) { - return file_backuppb_Backup_proto_rawDescGZIP(), []int{28, 1} -} - -func (x *FilePointer_AttachmentLocator) GetCdnKey() string { - if x != nil { - return x.CdnKey - } - return "" -} - -func (x *FilePointer_AttachmentLocator) GetCdnNumber() uint32 { - if x != nil { - return x.CdnNumber - } - return 0 -} - -func (x *FilePointer_AttachmentLocator) GetUploadTimestamp() uint64 { - if x != nil && x.UploadTimestamp != nil { - return *x.UploadTimestamp - } - return 0 -} - -func (x *FilePointer_AttachmentLocator) GetKey() []byte { - if x != nil { - return x.Key - } - return nil -} - -func (x *FilePointer_AttachmentLocator) GetDigest() []byte { - if x != nil { - return x.Digest - } - return nil -} - -func (x *FilePointer_AttachmentLocator) GetSize() uint32 { - if x != nil { - return x.Size - } - return 0 -} - -// References attachments that are invalid in such a way where download -// cannot be attempted. Could range from missing digests to missing -// CDN keys or anything else that makes download attempts impossible. -// This serves as a 'tombstone' so that the UX can show that an attachment -// did exist, but for whatever reason it's not retrievable. -// DEPRECATED; use LocatorInfo instead if available. -type FilePointer_InvalidAttachmentLocator struct { - state protoimpl.MessageState `protogen:"open.v1"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache -} - -func (x *FilePointer_InvalidAttachmentLocator) Reset() { - *x = FilePointer_InvalidAttachmentLocator{} - mi := &file_backuppb_Backup_proto_msgTypes[115] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) -} - -func (x *FilePointer_InvalidAttachmentLocator) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*FilePointer_InvalidAttachmentLocator) ProtoMessage() {} - -func (x *FilePointer_InvalidAttachmentLocator) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[115] - if x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use FilePointer_InvalidAttachmentLocator.ProtoReflect.Descriptor instead. -func (*FilePointer_InvalidAttachmentLocator) Descriptor() ([]byte, []int) { - return file_backuppb_Backup_proto_rawDescGZIP(), []int{28, 2} -} - -// References attachments in a local encrypted backup. -// Importers should first attempt to read the file from the local backup, -// and on failure fallback to backup and transit cdn if possible. -// DEPRECATED; use LocatorInfo instead if available. -type FilePointer_LocalLocator struct { - state protoimpl.MessageState `protogen:"open.v1"` - MediaName string `protobuf:"bytes,1,opt,name=mediaName,proto3" json:"mediaName,omitempty"` - // Separate key used to encrypt this file for the local backup. - // Generally required. Missing field indicates attachment was not - // available locally when the backup was generated, but remote - // backup or transit info was available. - LocalKey []byte `protobuf:"bytes,2,opt,name=localKey,proto3,oneof" json:"localKey,omitempty"` - RemoteKey []byte `protobuf:"bytes,3,opt,name=remoteKey,proto3" json:"remoteKey,omitempty"` - RemoteDigest []byte `protobuf:"bytes,4,opt,name=remoteDigest,proto3" json:"remoteDigest,omitempty"` - Size uint32 `protobuf:"varint,5,opt,name=size,proto3" json:"size,omitempty"` - BackupCdnNumber *uint32 `protobuf:"varint,6,opt,name=backupCdnNumber,proto3,oneof" json:"backupCdnNumber,omitempty"` - TransitCdnKey *string `protobuf:"bytes,7,opt,name=transitCdnKey,proto3,oneof" json:"transitCdnKey,omitempty"` - TransitCdnNumber *uint32 `protobuf:"varint,8,opt,name=transitCdnNumber,proto3,oneof" json:"transitCdnNumber,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache -} - -func (x *FilePointer_LocalLocator) Reset() { - *x = FilePointer_LocalLocator{} - mi := &file_backuppb_Backup_proto_msgTypes[116] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) -} - -func (x *FilePointer_LocalLocator) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*FilePointer_LocalLocator) ProtoMessage() {} - -func (x *FilePointer_LocalLocator) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[116] - if x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use FilePointer_LocalLocator.ProtoReflect.Descriptor instead. -func (*FilePointer_LocalLocator) Descriptor() ([]byte, []int) { - return file_backuppb_Backup_proto_rawDescGZIP(), []int{28, 3} -} - -func (x *FilePointer_LocalLocator) GetMediaName() string { - if x != nil { - return x.MediaName - } - return "" -} - -func (x *FilePointer_LocalLocator) GetLocalKey() []byte { - if x != nil { - return x.LocalKey - } - return nil -} - -func (x *FilePointer_LocalLocator) GetRemoteKey() []byte { - if x != nil { - return x.RemoteKey - } - return nil -} - -func (x *FilePointer_LocalLocator) GetRemoteDigest() []byte { - if x != nil { - return x.RemoteDigest - } - return nil -} - -func (x *FilePointer_LocalLocator) GetSize() uint32 { - if x != nil { - return x.Size - } - return 0 -} - -func (x *FilePointer_LocalLocator) GetBackupCdnNumber() uint32 { - if x != nil && x.BackupCdnNumber != nil { - return *x.BackupCdnNumber - } - return 0 -} - -func (x *FilePointer_LocalLocator) GetTransitCdnKey() string { - if x != nil && x.TransitCdnKey != nil { - return *x.TransitCdnKey - } - return "" -} - -func (x *FilePointer_LocalLocator) GetTransitCdnNumber() uint32 { - if x != nil && x.TransitCdnNumber != nil { - return *x.TransitCdnNumber - } - return 0 -} - type FilePointer_LocatorInfo struct { state protoimpl.MessageState `protogen:"open.v1"` // Must be non-empty if transitCdnKey or plaintextHash are set/nonempty. // Otherwise must be empty. Key []byte `protobuf:"bytes,1,opt,name=key,proto3" json:"key,omitempty"` - // From the sender of the attachment (incl. ourselves) - // Will be reserved once all clients start reading integrityCheck - LegacyDigest []byte `protobuf:"bytes,2,opt,name=legacyDigest,proto3" json:"legacyDigest,omitempty"` // Types that are valid to be assigned to IntegrityCheck: // // *FilePointer_LocatorInfo_PlaintextHash @@ -10449,11 +10036,6 @@ type FilePointer_LocatorInfo struct { // Exporting clients should set this as long as their subscription // has not rotated since last upload; even if currently free tier. MediaTierCdnNumber *uint32 `protobuf:"varint,7,opt,name=mediaTierCdnNumber,proto3,oneof" json:"mediaTierCdnNumber,omitempty"` - // Nonempty any time the attachment was downloaded and its - // digest validated, whether free tier or paid subscription. - // Will be reserved once all clients start reading integrityCheck, - // when mediaName will be derived from the plaintextHash and encryption key - LegacyMediaName string `protobuf:"bytes,8,opt,name=legacyMediaName,proto3" json:"legacyMediaName,omitempty"` // Separate key used to encrypt this file for the local backup. // Generally required for local backups. // Missing field indicates attachment was not available locally @@ -10466,7 +10048,7 @@ type FilePointer_LocatorInfo struct { func (x *FilePointer_LocatorInfo) Reset() { *x = FilePointer_LocatorInfo{} - mi := &file_backuppb_Backup_proto_msgTypes[117] + mi := &file_backuppb_Backup_proto_msgTypes[113] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -10478,7 +10060,7 @@ func (x *FilePointer_LocatorInfo) String() string { func (*FilePointer_LocatorInfo) ProtoMessage() {} func (x *FilePointer_LocatorInfo) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[117] + mi := &file_backuppb_Backup_proto_msgTypes[113] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -10491,7 +10073,7 @@ func (x *FilePointer_LocatorInfo) ProtoReflect() protoreflect.Message { // Deprecated: Use FilePointer_LocatorInfo.ProtoReflect.Descriptor instead. func (*FilePointer_LocatorInfo) Descriptor() ([]byte, []int) { - return file_backuppb_Backup_proto_rawDescGZIP(), []int{28, 4} + return file_backuppb_Backup_proto_rawDescGZIP(), []int{28, 0} } func (x *FilePointer_LocatorInfo) GetKey() []byte { @@ -10501,13 +10083,6 @@ func (x *FilePointer_LocatorInfo) GetKey() []byte { return nil } -func (x *FilePointer_LocatorInfo) GetLegacyDigest() []byte { - if x != nil { - return x.LegacyDigest - } - return nil -} - func (x *FilePointer_LocatorInfo) GetIntegrityCheck() isFilePointer_LocatorInfo_IntegrityCheck { if x != nil { return x.IntegrityCheck @@ -10568,13 +10143,6 @@ func (x *FilePointer_LocatorInfo) GetMediaTierCdnNumber() uint32 { return 0 } -func (x *FilePointer_LocatorInfo) GetLegacyMediaName() string { - if x != nil { - return x.LegacyMediaName - } - return "" -} - func (x *FilePointer_LocatorInfo) GetLocalKey() []byte { if x != nil { return x.LocalKey @@ -10612,7 +10180,7 @@ type Quote_QuotedAttachment struct { func (x *Quote_QuotedAttachment) Reset() { *x = Quote_QuotedAttachment{} - mi := &file_backuppb_Backup_proto_msgTypes[118] + mi := &file_backuppb_Backup_proto_msgTypes[114] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -10624,7 +10192,7 @@ func (x *Quote_QuotedAttachment) String() string { func (*Quote_QuotedAttachment) ProtoMessage() {} func (x *Quote_QuotedAttachment) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[118] + mi := &file_backuppb_Backup_proto_msgTypes[114] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -10708,7 +10276,7 @@ type GroupChangeChatUpdate_Update struct { func (x *GroupChangeChatUpdate_Update) Reset() { *x = GroupChangeChatUpdate_Update{} - mi := &file_backuppb_Backup_proto_msgTypes[119] + mi := &file_backuppb_Backup_proto_msgTypes[115] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -10720,7 +10288,7 @@ func (x *GroupChangeChatUpdate_Update) String() string { func (*GroupChangeChatUpdate_Update) ProtoMessage() {} func (x *GroupChangeChatUpdate_Update) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[119] + mi := &file_backuppb_Backup_proto_msgTypes[115] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -11294,7 +10862,7 @@ type GroupInvitationRevokedUpdate_Invitee struct { func (x *GroupInvitationRevokedUpdate_Invitee) Reset() { *x = GroupInvitationRevokedUpdate_Invitee{} - mi := &file_backuppb_Backup_proto_msgTypes[120] + mi := &file_backuppb_Backup_proto_msgTypes[116] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -11306,7 +10874,7 @@ func (x *GroupInvitationRevokedUpdate_Invitee) String() string { func (*GroupInvitationRevokedUpdate_Invitee) ProtoMessage() {} func (x *GroupInvitationRevokedUpdate_Invitee) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[120] + mi := &file_backuppb_Backup_proto_msgTypes[116] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -11354,7 +10922,7 @@ type ChatStyle_Gradient struct { func (x *ChatStyle_Gradient) Reset() { *x = ChatStyle_Gradient{} - mi := &file_backuppb_Backup_proto_msgTypes[121] + mi := &file_backuppb_Backup_proto_msgTypes[117] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -11366,7 +10934,7 @@ func (x *ChatStyle_Gradient) String() string { func (*ChatStyle_Gradient) ProtoMessage() {} func (x *ChatStyle_Gradient) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[121] + mi := &file_backuppb_Backup_proto_msgTypes[117] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -11419,7 +10987,7 @@ type ChatStyle_CustomChatColor struct { func (x *ChatStyle_CustomChatColor) Reset() { *x = ChatStyle_CustomChatColor{} - mi := &file_backuppb_Backup_proto_msgTypes[122] + mi := &file_backuppb_Backup_proto_msgTypes[118] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -11431,7 +10999,7 @@ func (x *ChatStyle_CustomChatColor) String() string { func (*ChatStyle_CustomChatColor) ProtoMessage() {} func (x *ChatStyle_CustomChatColor) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[122] + mi := &file_backuppb_Backup_proto_msgTypes[118] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -11503,7 +11071,7 @@ type ChatStyle_AutomaticBubbleColor struct { func (x *ChatStyle_AutomaticBubbleColor) Reset() { *x = ChatStyle_AutomaticBubbleColor{} - mi := &file_backuppb_Backup_proto_msgTypes[123] + mi := &file_backuppb_Backup_proto_msgTypes[119] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -11515,7 +11083,7 @@ func (x *ChatStyle_AutomaticBubbleColor) String() string { func (*ChatStyle_AutomaticBubbleColor) ProtoMessage() {} func (x *ChatStyle_AutomaticBubbleColor) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[123] + mi := &file_backuppb_Backup_proto_msgTypes[119] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -11780,19 +11348,20 @@ const file_backuppb_Backup_proto_rawDesc = "" + " \x01(\rR\x12expireTimerVersionB\x0e\n" + "\f_pinnedOrderB\x14\n" + "\x12_expirationTimerMsB\x0e\n" + - "\f_muteUntilMs\"\xa5\x02\n" + + "\f_muteUntilMs\"\xb4\x02\n" + "\bCallLink\x12\x18\n" + "\arootKey\x18\x01 \x01(\fR\arootKey\x12\x1f\n" + "\badminKey\x18\x02 \x01(\fH\x00R\badminKey\x88\x01\x01\x12\x12\n" + "\x04name\x18\x03 \x01(\tR\x04name\x12H\n" + "\frestrictions\x18\x04 \x01(\x0e2$.signal.backup.CallLink.RestrictionsR\frestrictions\x12\"\n" + - "\fexpirationMs\x18\x05 \x01(\x04R\fexpirationMs\x12\x14\n" + - "\x05epoch\x18\x06 \x01(\fR\x05epoch\"9\n" + + "\fexpirationMs\x18\x05 \x01(\x04R\fexpirationMs\x12\x19\n" + + "\x05epoch\x18\x06 \x01(\fH\x01R\x05epoch\x88\x01\x01\"9\n" + "\fRestrictions\x12\v\n" + "\aUNKNOWN\x10\x00\x12\b\n" + "\x04NONE\x10\x01\x12\x12\n" + "\x0eADMIN_APPROVAL\x10\x02B\v\n" + - "\t_adminKey\"\xca\x01\n" + + "\t_adminKeyB\b\n" + + "\x06_epoch\"\xca\x01\n" + "\tAdHocCall\x12\x16\n" + "\x06callId\x18\x01 \x01(\x04R\x06callId\x12 \n" + "\vrecipientId\x18\x02 \x01(\x04R\vrecipientId\x124\n" + @@ -11816,7 +11385,7 @@ const file_backuppb_Backup_proto_rawDesc = "" + "\tONLY_WITH\x10\x01\x12\x0e\n" + "\n" + "ALL_EXCEPT\x10\x02\x12\a\n" + - "\x03ALL\x10\x03\"\xa4\f\n" + + "\x03ALL\x10\x03\"\xc8\f\n" + "\bChatItem\x12\x16\n" + "\x06chatId\x18\x01 \x01(\x04R\x06chatId\x12\x1a\n" + "\bauthorId\x18\x02 \x01(\x04R\bauthorId\x12\x1a\n" + @@ -11843,11 +11412,12 @@ const file_backuppb_Backup_proto_rawDesc = "" + "\x0edateServerSent\x18\x02 \x01(\x04H\x00R\x0edateServerSent\x88\x01\x01\x12\x12\n" + "\x04read\x18\x03 \x01(\bR\x04read\x12\"\n" + "\fsealedSender\x18\x04 \x01(\bR\fsealedSenderB\x11\n" + - "\x0f_dateServerSent\x1aS\n" + + "\x0f_dateServerSent\x1aw\n" + "\x16OutgoingMessageDetails\x129\n" + "\n" + "sendStatus\x18\x01 \x03(\v2\x19.signal.backup.SendStatusR\n" + - "sendStatus\x1a\x1d\n" + + "sendStatus\x12\"\n" + + "\fdateReceived\x18\x02 \x01(\x04R\fdateReceived\x1a\x1d\n" + "\x1bDirectionlessMessageDetailsB\x14\n" + "\x12directionalDetailsB\x06\n" + "\x04itemB\x12\n" + @@ -12062,59 +11632,20 @@ const file_backuppb_Backup_proto_rawDesc = "" + "\n" + "BORDERLESS\x10\x02\x12\a\n" + "\x03GIF\x10\x03B\r\n" + - "\v_clientUuid\"\xc9\x12\n" + - "\vFilePointer\x12P\n" + - "\rbackupLocator\x18\x01 \x01(\v2(.signal.backup.FilePointer.BackupLocatorH\x00R\rbackupLocator\x12\\\n" + - "\x11attachmentLocator\x18\x02 \x01(\v2,.signal.backup.FilePointer.AttachmentLocatorH\x00R\x11attachmentLocator\x12q\n" + - "\x18invalidAttachmentLocator\x18\x03 \x01(\v23.signal.backup.FilePointer.InvalidAttachmentLocatorH\x00R\x18invalidAttachmentLocator\x12M\n" + - "\flocalLocator\x18\f \x01(\v2'.signal.backup.FilePointer.LocalLocatorH\x00R\flocalLocator\x12%\n" + - "\vcontentType\x18\x04 \x01(\tH\x01R\vcontentType\x88\x01\x01\x12+\n" + - "\x0eincrementalMac\x18\x05 \x01(\fH\x02R\x0eincrementalMac\x88\x01\x01\x12=\n" + - "\x17incrementalMacChunkSize\x18\x06 \x01(\rH\x03R\x17incrementalMacChunkSize\x88\x01\x01\x12\x1f\n" + - "\bfileName\x18\a \x01(\tH\x04R\bfileName\x88\x01\x01\x12\x19\n" + - "\x05width\x18\b \x01(\rH\x05R\x05width\x88\x01\x01\x12\x1b\n" + - "\x06height\x18\t \x01(\rH\x06R\x06height\x88\x01\x01\x12\x1d\n" + + "\v_clientUuid\"\x9e\b\n" + + "\vFilePointer\x12%\n" + + "\vcontentType\x18\x04 \x01(\tH\x00R\vcontentType\x88\x01\x01\x12+\n" + + "\x0eincrementalMac\x18\x05 \x01(\fH\x01R\x0eincrementalMac\x88\x01\x01\x12=\n" + + "\x17incrementalMacChunkSize\x18\x06 \x01(\rH\x02R\x17incrementalMacChunkSize\x88\x01\x01\x12\x1f\n" + + "\bfileName\x18\a \x01(\tH\x03R\bfileName\x88\x01\x01\x12\x19\n" + + "\x05width\x18\b \x01(\rH\x04R\x05width\x88\x01\x01\x12\x1b\n" + + "\x06height\x18\t \x01(\rH\x05R\x06height\x88\x01\x01\x12\x1d\n" + "\acaption\x18\n" + - " \x01(\tH\aR\acaption\x88\x01\x01\x12\x1f\n" + - "\bblurHash\x18\v \x01(\tH\bR\bblurHash\x88\x01\x01\x12H\n" + - "\vlocatorInfo\x18\r \x01(\v2&.signal.backup.FilePointer.LocatorInfoR\vlocatorInfo\x1a\x9f\x02\n" + - "\rBackupLocator\x12\x1c\n" + - "\tmediaName\x18\x01 \x01(\tR\tmediaName\x12!\n" + - "\tcdnNumber\x18\x02 \x01(\rH\x00R\tcdnNumber\x88\x01\x01\x12\x10\n" + - "\x03key\x18\x03 \x01(\fR\x03key\x12\x16\n" + - "\x06digest\x18\x04 \x01(\fR\x06digest\x12\x12\n" + - "\x04size\x18\x05 \x01(\rR\x04size\x12)\n" + - "\rtransitCdnKey\x18\x06 \x01(\tH\x01R\rtransitCdnKey\x88\x01\x01\x12/\n" + - "\x10transitCdnNumber\x18\a \x01(\rH\x02R\x10transitCdnNumber\x88\x01\x01B\f\n" + - "\n" + - "_cdnNumberB\x10\n" + - "\x0e_transitCdnKeyB\x13\n" + - "\x11_transitCdnNumber\x1a\xca\x01\n" + - "\x11AttachmentLocator\x12\x16\n" + - "\x06cdnKey\x18\x01 \x01(\tR\x06cdnKey\x12\x1c\n" + - "\tcdnNumber\x18\x02 \x01(\rR\tcdnNumber\x12-\n" + - "\x0fuploadTimestamp\x18\x03 \x01(\x04H\x00R\x0fuploadTimestamp\x88\x01\x01\x12\x10\n" + - "\x03key\x18\x04 \x01(\fR\x03key\x12\x16\n" + - "\x06digest\x18\x05 \x01(\fR\x06digest\x12\x12\n" + - "\x04size\x18\x06 \x01(\rR\x04sizeB\x12\n" + - "\x10_uploadTimestamp\x1a\x1a\n" + - "\x18InvalidAttachmentLocator\x1a\xf6\x02\n" + - "\fLocalLocator\x12\x1c\n" + - "\tmediaName\x18\x01 \x01(\tR\tmediaName\x12\x1f\n" + - "\blocalKey\x18\x02 \x01(\fH\x00R\blocalKey\x88\x01\x01\x12\x1c\n" + - "\tremoteKey\x18\x03 \x01(\fR\tremoteKey\x12\"\n" + - "\fremoteDigest\x18\x04 \x01(\fR\fremoteDigest\x12\x12\n" + - "\x04size\x18\x05 \x01(\rR\x04size\x12-\n" + - "\x0fbackupCdnNumber\x18\x06 \x01(\rH\x01R\x0fbackupCdnNumber\x88\x01\x01\x12)\n" + - "\rtransitCdnKey\x18\a \x01(\tH\x02R\rtransitCdnKey\x88\x01\x01\x12/\n" + - "\x10transitCdnNumber\x18\b \x01(\rH\x03R\x10transitCdnNumber\x88\x01\x01B\v\n" + - "\t_localKeyB\x12\n" + - "\x10_backupCdnNumberB\x10\n" + - "\x0e_transitCdnKeyB\x13\n" + - "\x11_transitCdnNumber\x1a\xc8\x04\n" + + " \x01(\tH\x06R\acaption\x88\x01\x01\x12\x1f\n" + + "\bblurHash\x18\v \x01(\tH\aR\bblurHash\x88\x01\x01\x12H\n" + + "\vlocatorInfo\x18\r \x01(\v2&.signal.backup.FilePointer.LocatorInfoR\vlocatorInfo\x1a\x86\x04\n" + "\vLocatorInfo\x12\x10\n" + - "\x03key\x18\x01 \x01(\fR\x03key\x12\"\n" + - "\flegacyDigest\x18\x02 \x01(\fR\flegacyDigest\x12&\n" + + "\x03key\x18\x01 \x01(\fR\x03key\x12&\n" + "\rplaintextHash\x18\n" + " \x01(\fH\x00R\rplaintextHash\x12*\n" + "\x0fencryptedDigest\x18\v \x01(\fH\x00R\x0fencryptedDigest\x12\x12\n" + @@ -12122,16 +11653,14 @@ const file_backuppb_Backup_proto_rawDesc = "" + "\rtransitCdnKey\x18\x04 \x01(\tH\x01R\rtransitCdnKey\x88\x01\x01\x12/\n" + "\x10transitCdnNumber\x18\x05 \x01(\rH\x02R\x10transitCdnNumber\x88\x01\x01\x12C\n" + "\x1atransitTierUploadTimestamp\x18\x06 \x01(\x04H\x03R\x1atransitTierUploadTimestamp\x88\x01\x01\x123\n" + - "\x12mediaTierCdnNumber\x18\a \x01(\rH\x04R\x12mediaTierCdnNumber\x88\x01\x01\x12(\n" + - "\x0flegacyMediaName\x18\b \x01(\tR\x0flegacyMediaName\x12\x1f\n" + + "\x12mediaTierCdnNumber\x18\a \x01(\rH\x04R\x12mediaTierCdnNumber\x88\x01\x01\x12\x1f\n" + "\blocalKey\x18\t \x01(\fH\x05R\blocalKey\x88\x01\x01B\x10\n" + "\x0eintegrityCheckB\x10\n" + "\x0e_transitCdnKeyB\x13\n" + "\x11_transitCdnNumberB\x1d\n" + "\x1b_transitTierUploadTimestampB\x15\n" + "\x13_mediaTierCdnNumberB\v\n" + - "\t_localKeyB\t\n" + - "\alocatorB\x0e\n" + + "\t_localKeyJ\x04\b\x02\x10\x03J\x04\b\b\x10\tB\x0e\n" + "\f_contentTypeB\x11\n" + "\x0f_incrementalMacB\x1a\n" + "\x18_incrementalMacChunkSizeB\v\n" + @@ -12140,7 +11669,7 @@ const file_backuppb_Backup_proto_rawDesc = "" + "\a_heightB\n" + "\n" + "\b_captionB\v\n" + - "\t_blurHash\"\xae\x04\n" + + "\t_blurHashJ\x04\b\x01\x10\x02J\x04\b\x02\x10\x03J\x04\b\x03\x10\x04J\x04\b\f\x10\r\"\xae\x04\n" + "\x05Quote\x125\n" + "\x13targetSentTimestamp\x18\x01 \x01(\x04H\x00R\x13targetSentTimestamp\x88\x01\x01\x12\x1a\n" + "\bauthorId\x18\x02 \x01(\x04R\bauthorId\x12,\n" + @@ -12659,7 +12188,7 @@ func file_backuppb_Backup_proto_rawDescGZIP() []byte { } var file_backuppb_Backup_proto_enumTypes = make([]protoimpl.EnumInfo, 31) -var file_backuppb_Backup_proto_msgTypes = make([]protoimpl.MessageInfo, 124) +var file_backuppb_Backup_proto_msgTypes = make([]protoimpl.MessageInfo, 120) var file_backuppb_Backup_proto_goTypes = []any{ (AvatarColor)(0), // 0: signal.backup.AvatarColor (GroupV2AccessLevel)(0), // 1: signal.backup.GroupV2AccessLevel @@ -12805,17 +12334,13 @@ var file_backuppb_Backup_proto_goTypes = []any{ (*ContactAttachment_Phone)(nil), // 141: signal.backup.ContactAttachment.Phone (*ContactAttachment_Email)(nil), // 142: signal.backup.ContactAttachment.Email (*ContactAttachment_PostalAddress)(nil), // 143: signal.backup.ContactAttachment.PostalAddress - (*FilePointer_BackupLocator)(nil), // 144: signal.backup.FilePointer.BackupLocator - (*FilePointer_AttachmentLocator)(nil), // 145: signal.backup.FilePointer.AttachmentLocator - (*FilePointer_InvalidAttachmentLocator)(nil), // 146: signal.backup.FilePointer.InvalidAttachmentLocator - (*FilePointer_LocalLocator)(nil), // 147: signal.backup.FilePointer.LocalLocator - (*FilePointer_LocatorInfo)(nil), // 148: signal.backup.FilePointer.LocatorInfo - (*Quote_QuotedAttachment)(nil), // 149: signal.backup.Quote.QuotedAttachment - (*GroupChangeChatUpdate_Update)(nil), // 150: signal.backup.GroupChangeChatUpdate.Update - (*GroupInvitationRevokedUpdate_Invitee)(nil), // 151: signal.backup.GroupInvitationRevokedUpdate.Invitee - (*ChatStyle_Gradient)(nil), // 152: signal.backup.ChatStyle.Gradient - (*ChatStyle_CustomChatColor)(nil), // 153: signal.backup.ChatStyle.CustomChatColor - (*ChatStyle_AutomaticBubbleColor)(nil), // 154: signal.backup.ChatStyle.AutomaticBubbleColor + (*FilePointer_LocatorInfo)(nil), // 144: signal.backup.FilePointer.LocatorInfo + (*Quote_QuotedAttachment)(nil), // 145: signal.backup.Quote.QuotedAttachment + (*GroupChangeChatUpdate_Update)(nil), // 146: signal.backup.GroupChangeChatUpdate.Update + (*GroupInvitationRevokedUpdate_Invitee)(nil), // 147: signal.backup.GroupInvitationRevokedUpdate.Invitee + (*ChatStyle_Gradient)(nil), // 148: signal.backup.ChatStyle.Gradient + (*ChatStyle_CustomChatColor)(nil), // 149: signal.backup.ChatStyle.CustomChatColor + (*ChatStyle_AutomaticBubbleColor)(nil), // 150: signal.backup.ChatStyle.AutomaticBubbleColor } var file_backuppb_Backup_proto_depIdxs = []int32{ 33, // 0: signal.backup.Frame.account:type_name -> signal.backup.AccountData @@ -12897,109 +12422,105 @@ var file_backuppb_Backup_proto_depIdxs = []int32{ 59, // 76: signal.backup.LinkPreview.image:type_name -> signal.backup.FilePointer 59, // 77: signal.backup.MessageAttachment.pointer:type_name -> signal.backup.FilePointer 19, // 78: signal.backup.MessageAttachment.flag:type_name -> signal.backup.MessageAttachment.Flag - 144, // 79: signal.backup.FilePointer.backupLocator:type_name -> signal.backup.FilePointer.BackupLocator - 145, // 80: signal.backup.FilePointer.attachmentLocator:type_name -> signal.backup.FilePointer.AttachmentLocator - 146, // 81: signal.backup.FilePointer.invalidAttachmentLocator:type_name -> signal.backup.FilePointer.InvalidAttachmentLocator - 147, // 82: signal.backup.FilePointer.localLocator:type_name -> signal.backup.FilePointer.LocalLocator - 148, // 83: signal.backup.FilePointer.locatorInfo:type_name -> signal.backup.FilePointer.LocatorInfo - 46, // 84: signal.backup.Quote.text:type_name -> signal.backup.Text - 149, // 85: signal.backup.Quote.attachments:type_name -> signal.backup.Quote.QuotedAttachment - 20, // 86: signal.backup.Quote.type:type_name -> signal.backup.Quote.Type - 21, // 87: signal.backup.BodyRange.style:type_name -> signal.backup.BodyRange.Style - 66, // 88: signal.backup.ChatUpdateMessage.simpleUpdate:type_name -> signal.backup.SimpleChatUpdate - 72, // 89: signal.backup.ChatUpdateMessage.groupChange:type_name -> signal.backup.GroupChangeChatUpdate - 67, // 90: signal.backup.ChatUpdateMessage.expirationTimerChange:type_name -> signal.backup.ExpirationTimerChatUpdate - 68, // 91: signal.backup.ChatUpdateMessage.profileChange:type_name -> signal.backup.ProfileChangeChatUpdate - 70, // 92: signal.backup.ChatUpdateMessage.threadMerge:type_name -> signal.backup.ThreadMergeChatUpdate - 71, // 93: signal.backup.ChatUpdateMessage.sessionSwitchover:type_name -> signal.backup.SessionSwitchoverChatUpdate - 64, // 94: signal.backup.ChatUpdateMessage.individualCall:type_name -> signal.backup.IndividualCall - 65, // 95: signal.backup.ChatUpdateMessage.groupCall:type_name -> signal.backup.GroupCall - 69, // 96: signal.backup.ChatUpdateMessage.learnedProfileChange:type_name -> signal.backup.LearnedProfileChatUpdate - 22, // 97: signal.backup.IndividualCall.type:type_name -> signal.backup.IndividualCall.Type - 23, // 98: signal.backup.IndividualCall.direction:type_name -> signal.backup.IndividualCall.Direction - 24, // 99: signal.backup.IndividualCall.state:type_name -> signal.backup.IndividualCall.State - 25, // 100: signal.backup.GroupCall.state:type_name -> signal.backup.GroupCall.State - 26, // 101: signal.backup.SimpleChatUpdate.type:type_name -> signal.backup.SimpleChatUpdate.Type - 150, // 102: signal.backup.GroupChangeChatUpdate.updates:type_name -> signal.backup.GroupChangeChatUpdate.Update - 1, // 103: signal.backup.GroupMembershipAccessLevelChangeUpdate.accessLevel:type_name -> signal.backup.GroupV2AccessLevel - 1, // 104: signal.backup.GroupAttributesAccessLevelChangeUpdate.accessLevel:type_name -> signal.backup.GroupV2AccessLevel - 151, // 105: signal.backup.GroupInvitationRevokedUpdate.invitees:type_name -> signal.backup.GroupInvitationRevokedUpdate.Invitee - 27, // 106: signal.backup.ChatStyle.wallpaperPreset:type_name -> signal.backup.ChatStyle.WallpaperPreset - 59, // 107: signal.backup.ChatStyle.wallpaperPhoto:type_name -> signal.backup.FilePointer - 154, // 108: signal.backup.ChatStyle.autoBubbleColor:type_name -> signal.backup.ChatStyle.AutomaticBubbleColor - 28, // 109: signal.backup.ChatStyle.bubbleColorPreset:type_name -> signal.backup.ChatStyle.BubbleColorPreset - 29, // 110: signal.backup.NotificationProfile.scheduleDaysEnabled:type_name -> signal.backup.NotificationProfile.DayOfWeek - 30, // 111: signal.backup.ChatFolder.folderType:type_name -> signal.backup.ChatFolder.FolderType - 3, // 112: signal.backup.AccountData.UsernameLink.color:type_name -> signal.backup.AccountData.UsernameLink.Color - 2, // 113: signal.backup.AccountData.AccountSettings.phoneNumberSharingMode:type_name -> signal.backup.AccountData.PhoneNumberSharingMode - 108, // 114: signal.backup.AccountData.AccountSettings.defaultChatStyle:type_name -> signal.backup.ChatStyle - 153, // 115: signal.backup.AccountData.AccountSettings.customChatColors:type_name -> signal.backup.ChatStyle.CustomChatColor - 119, // 116: signal.backup.Group.GroupSnapshot.title:type_name -> signal.backup.Group.GroupAttributeBlob - 119, // 117: signal.backup.Group.GroupSnapshot.description:type_name -> signal.backup.Group.GroupAttributeBlob - 119, // 118: signal.backup.Group.GroupSnapshot.disappearingMessagesTimer:type_name -> signal.backup.Group.GroupAttributeBlob - 124, // 119: signal.backup.Group.GroupSnapshot.accessControl:type_name -> signal.backup.Group.AccessControl - 120, // 120: signal.backup.Group.GroupSnapshot.members:type_name -> signal.backup.Group.Member - 121, // 121: signal.backup.Group.GroupSnapshot.membersPendingProfileKey:type_name -> signal.backup.Group.MemberPendingProfileKey - 122, // 122: signal.backup.Group.GroupSnapshot.membersPendingAdminApproval:type_name -> signal.backup.Group.MemberPendingAdminApproval - 123, // 123: signal.backup.Group.GroupSnapshot.members_banned:type_name -> signal.backup.Group.MemberBanned - 7, // 124: signal.backup.Group.Member.role:type_name -> signal.backup.Group.Member.Role - 120, // 125: signal.backup.Group.MemberPendingProfileKey.member:type_name -> signal.backup.Group.Member - 8, // 126: signal.backup.Group.AccessControl.attributes:type_name -> signal.backup.Group.AccessControl.AccessRequired - 8, // 127: signal.backup.Group.AccessControl.members:type_name -> signal.backup.Group.AccessControl.AccessRequired - 8, // 128: signal.backup.Group.AccessControl.addFromInviteLink:type_name -> signal.backup.Group.AccessControl.AccessRequired - 45, // 129: signal.backup.ChatItem.OutgoingMessageDetails.sendStatus:type_name -> signal.backup.SendStatus - 12, // 130: signal.backup.SendStatus.Failed.reason:type_name -> signal.backup.SendStatus.Failed.FailureReason - 46, // 131: signal.backup.DirectStoryReplyMessage.TextReply.text:type_name -> signal.backup.Text - 59, // 132: signal.backup.DirectStoryReplyMessage.TextReply.longText:type_name -> signal.backup.FilePointer - 139, // 133: signal.backup.PaymentNotification.TransactionDetails.transaction:type_name -> signal.backup.PaymentNotification.TransactionDetails.Transaction - 138, // 134: signal.backup.PaymentNotification.TransactionDetails.failedTransaction:type_name -> signal.backup.PaymentNotification.TransactionDetails.FailedTransaction - 13, // 135: signal.backup.PaymentNotification.TransactionDetails.FailedTransaction.reason:type_name -> signal.backup.PaymentNotification.TransactionDetails.FailedTransaction.FailureReason - 14, // 136: signal.backup.PaymentNotification.TransactionDetails.Transaction.status:type_name -> signal.backup.PaymentNotification.TransactionDetails.Transaction.Status - 137, // 137: signal.backup.PaymentNotification.TransactionDetails.Transaction.mobileCoinIdentification:type_name -> signal.backup.PaymentNotification.TransactionDetails.MobileCoinTxoIdentification - 16, // 138: signal.backup.ContactAttachment.Phone.type:type_name -> signal.backup.ContactAttachment.Phone.Type - 17, // 139: signal.backup.ContactAttachment.Email.type:type_name -> signal.backup.ContactAttachment.Email.Type - 18, // 140: signal.backup.ContactAttachment.PostalAddress.type:type_name -> signal.backup.ContactAttachment.PostalAddress.Type - 58, // 141: signal.backup.Quote.QuotedAttachment.thumbnail:type_name -> signal.backup.MessageAttachment - 73, // 142: signal.backup.GroupChangeChatUpdate.Update.genericGroupUpdate:type_name -> signal.backup.GenericGroupUpdate - 74, // 143: signal.backup.GroupChangeChatUpdate.Update.groupCreationUpdate:type_name -> signal.backup.GroupCreationUpdate - 75, // 144: signal.backup.GroupChangeChatUpdate.Update.groupNameUpdate:type_name -> signal.backup.GroupNameUpdate - 76, // 145: signal.backup.GroupChangeChatUpdate.Update.groupAvatarUpdate:type_name -> signal.backup.GroupAvatarUpdate - 77, // 146: signal.backup.GroupChangeChatUpdate.Update.groupDescriptionUpdate:type_name -> signal.backup.GroupDescriptionUpdate - 78, // 147: signal.backup.GroupChangeChatUpdate.Update.groupMembershipAccessLevelChangeUpdate:type_name -> signal.backup.GroupMembershipAccessLevelChangeUpdate - 79, // 148: signal.backup.GroupChangeChatUpdate.Update.groupAttributesAccessLevelChangeUpdate:type_name -> signal.backup.GroupAttributesAccessLevelChangeUpdate - 80, // 149: signal.backup.GroupChangeChatUpdate.Update.groupAnnouncementOnlyChangeUpdate:type_name -> signal.backup.GroupAnnouncementOnlyChangeUpdate - 81, // 150: signal.backup.GroupChangeChatUpdate.Update.groupAdminStatusUpdate:type_name -> signal.backup.GroupAdminStatusUpdate - 82, // 151: signal.backup.GroupChangeChatUpdate.Update.groupMemberLeftUpdate:type_name -> signal.backup.GroupMemberLeftUpdate - 83, // 152: signal.backup.GroupChangeChatUpdate.Update.groupMemberRemovedUpdate:type_name -> signal.backup.GroupMemberRemovedUpdate - 84, // 153: signal.backup.GroupChangeChatUpdate.Update.selfInvitedToGroupUpdate:type_name -> signal.backup.SelfInvitedToGroupUpdate - 85, // 154: signal.backup.GroupChangeChatUpdate.Update.selfInvitedOtherUserToGroupUpdate:type_name -> signal.backup.SelfInvitedOtherUserToGroupUpdate - 86, // 155: signal.backup.GroupChangeChatUpdate.Update.groupUnknownInviteeUpdate:type_name -> signal.backup.GroupUnknownInviteeUpdate - 87, // 156: signal.backup.GroupChangeChatUpdate.Update.groupInvitationAcceptedUpdate:type_name -> signal.backup.GroupInvitationAcceptedUpdate - 88, // 157: signal.backup.GroupChangeChatUpdate.Update.groupInvitationDeclinedUpdate:type_name -> signal.backup.GroupInvitationDeclinedUpdate - 89, // 158: signal.backup.GroupChangeChatUpdate.Update.groupMemberJoinedUpdate:type_name -> signal.backup.GroupMemberJoinedUpdate - 90, // 159: signal.backup.GroupChangeChatUpdate.Update.groupMemberAddedUpdate:type_name -> signal.backup.GroupMemberAddedUpdate - 91, // 160: signal.backup.GroupChangeChatUpdate.Update.groupSelfInvitationRevokedUpdate:type_name -> signal.backup.GroupSelfInvitationRevokedUpdate - 92, // 161: signal.backup.GroupChangeChatUpdate.Update.groupInvitationRevokedUpdate:type_name -> signal.backup.GroupInvitationRevokedUpdate - 93, // 162: signal.backup.GroupChangeChatUpdate.Update.groupJoinRequestUpdate:type_name -> signal.backup.GroupJoinRequestUpdate - 94, // 163: signal.backup.GroupChangeChatUpdate.Update.groupJoinRequestApprovalUpdate:type_name -> signal.backup.GroupJoinRequestApprovalUpdate - 95, // 164: signal.backup.GroupChangeChatUpdate.Update.groupJoinRequestCanceledUpdate:type_name -> signal.backup.GroupJoinRequestCanceledUpdate - 97, // 165: signal.backup.GroupChangeChatUpdate.Update.groupInviteLinkResetUpdate:type_name -> signal.backup.GroupInviteLinkResetUpdate - 98, // 166: signal.backup.GroupChangeChatUpdate.Update.groupInviteLinkEnabledUpdate:type_name -> signal.backup.GroupInviteLinkEnabledUpdate - 99, // 167: signal.backup.GroupChangeChatUpdate.Update.groupInviteLinkAdminApprovalUpdate:type_name -> signal.backup.GroupInviteLinkAdminApprovalUpdate - 100, // 168: signal.backup.GroupChangeChatUpdate.Update.groupInviteLinkDisabledUpdate:type_name -> signal.backup.GroupInviteLinkDisabledUpdate - 101, // 169: signal.backup.GroupChangeChatUpdate.Update.groupMemberJoinedByLinkUpdate:type_name -> signal.backup.GroupMemberJoinedByLinkUpdate - 102, // 170: signal.backup.GroupChangeChatUpdate.Update.groupV2MigrationUpdate:type_name -> signal.backup.GroupV2MigrationUpdate - 103, // 171: signal.backup.GroupChangeChatUpdate.Update.groupV2MigrationSelfInvitedUpdate:type_name -> signal.backup.GroupV2MigrationSelfInvitedUpdate - 104, // 172: signal.backup.GroupChangeChatUpdate.Update.groupV2MigrationInvitedMembersUpdate:type_name -> signal.backup.GroupV2MigrationInvitedMembersUpdate - 105, // 173: signal.backup.GroupChangeChatUpdate.Update.groupV2MigrationDroppedMembersUpdate:type_name -> signal.backup.GroupV2MigrationDroppedMembersUpdate - 96, // 174: signal.backup.GroupChangeChatUpdate.Update.groupSequenceOfRequestsAndCancelsUpdate:type_name -> signal.backup.GroupSequenceOfRequestsAndCancelsUpdate - 106, // 175: signal.backup.GroupChangeChatUpdate.Update.groupExpirationTimerUpdate:type_name -> signal.backup.GroupExpirationTimerUpdate - 152, // 176: signal.backup.ChatStyle.CustomChatColor.gradient:type_name -> signal.backup.ChatStyle.Gradient - 177, // [177:177] is the sub-list for method output_type - 177, // [177:177] is the sub-list for method input_type - 177, // [177:177] is the sub-list for extension type_name - 177, // [177:177] is the sub-list for extension extendee - 0, // [0:177] is the sub-list for field type_name + 144, // 79: signal.backup.FilePointer.locatorInfo:type_name -> signal.backup.FilePointer.LocatorInfo + 46, // 80: signal.backup.Quote.text:type_name -> signal.backup.Text + 145, // 81: signal.backup.Quote.attachments:type_name -> signal.backup.Quote.QuotedAttachment + 20, // 82: signal.backup.Quote.type:type_name -> signal.backup.Quote.Type + 21, // 83: signal.backup.BodyRange.style:type_name -> signal.backup.BodyRange.Style + 66, // 84: signal.backup.ChatUpdateMessage.simpleUpdate:type_name -> signal.backup.SimpleChatUpdate + 72, // 85: signal.backup.ChatUpdateMessage.groupChange:type_name -> signal.backup.GroupChangeChatUpdate + 67, // 86: signal.backup.ChatUpdateMessage.expirationTimerChange:type_name -> signal.backup.ExpirationTimerChatUpdate + 68, // 87: signal.backup.ChatUpdateMessage.profileChange:type_name -> signal.backup.ProfileChangeChatUpdate + 70, // 88: signal.backup.ChatUpdateMessage.threadMerge:type_name -> signal.backup.ThreadMergeChatUpdate + 71, // 89: signal.backup.ChatUpdateMessage.sessionSwitchover:type_name -> signal.backup.SessionSwitchoverChatUpdate + 64, // 90: signal.backup.ChatUpdateMessage.individualCall:type_name -> signal.backup.IndividualCall + 65, // 91: signal.backup.ChatUpdateMessage.groupCall:type_name -> signal.backup.GroupCall + 69, // 92: signal.backup.ChatUpdateMessage.learnedProfileChange:type_name -> signal.backup.LearnedProfileChatUpdate + 22, // 93: signal.backup.IndividualCall.type:type_name -> signal.backup.IndividualCall.Type + 23, // 94: signal.backup.IndividualCall.direction:type_name -> signal.backup.IndividualCall.Direction + 24, // 95: signal.backup.IndividualCall.state:type_name -> signal.backup.IndividualCall.State + 25, // 96: signal.backup.GroupCall.state:type_name -> signal.backup.GroupCall.State + 26, // 97: signal.backup.SimpleChatUpdate.type:type_name -> signal.backup.SimpleChatUpdate.Type + 146, // 98: signal.backup.GroupChangeChatUpdate.updates:type_name -> signal.backup.GroupChangeChatUpdate.Update + 1, // 99: signal.backup.GroupMembershipAccessLevelChangeUpdate.accessLevel:type_name -> signal.backup.GroupV2AccessLevel + 1, // 100: signal.backup.GroupAttributesAccessLevelChangeUpdate.accessLevel:type_name -> signal.backup.GroupV2AccessLevel + 147, // 101: signal.backup.GroupInvitationRevokedUpdate.invitees:type_name -> signal.backup.GroupInvitationRevokedUpdate.Invitee + 27, // 102: signal.backup.ChatStyle.wallpaperPreset:type_name -> signal.backup.ChatStyle.WallpaperPreset + 59, // 103: signal.backup.ChatStyle.wallpaperPhoto:type_name -> signal.backup.FilePointer + 150, // 104: signal.backup.ChatStyle.autoBubbleColor:type_name -> signal.backup.ChatStyle.AutomaticBubbleColor + 28, // 105: signal.backup.ChatStyle.bubbleColorPreset:type_name -> signal.backup.ChatStyle.BubbleColorPreset + 29, // 106: signal.backup.NotificationProfile.scheduleDaysEnabled:type_name -> signal.backup.NotificationProfile.DayOfWeek + 30, // 107: signal.backup.ChatFolder.folderType:type_name -> signal.backup.ChatFolder.FolderType + 3, // 108: signal.backup.AccountData.UsernameLink.color:type_name -> signal.backup.AccountData.UsernameLink.Color + 2, // 109: signal.backup.AccountData.AccountSettings.phoneNumberSharingMode:type_name -> signal.backup.AccountData.PhoneNumberSharingMode + 108, // 110: signal.backup.AccountData.AccountSettings.defaultChatStyle:type_name -> signal.backup.ChatStyle + 149, // 111: signal.backup.AccountData.AccountSettings.customChatColors:type_name -> signal.backup.ChatStyle.CustomChatColor + 119, // 112: signal.backup.Group.GroupSnapshot.title:type_name -> signal.backup.Group.GroupAttributeBlob + 119, // 113: signal.backup.Group.GroupSnapshot.description:type_name -> signal.backup.Group.GroupAttributeBlob + 119, // 114: signal.backup.Group.GroupSnapshot.disappearingMessagesTimer:type_name -> signal.backup.Group.GroupAttributeBlob + 124, // 115: signal.backup.Group.GroupSnapshot.accessControl:type_name -> signal.backup.Group.AccessControl + 120, // 116: signal.backup.Group.GroupSnapshot.members:type_name -> signal.backup.Group.Member + 121, // 117: signal.backup.Group.GroupSnapshot.membersPendingProfileKey:type_name -> signal.backup.Group.MemberPendingProfileKey + 122, // 118: signal.backup.Group.GroupSnapshot.membersPendingAdminApproval:type_name -> signal.backup.Group.MemberPendingAdminApproval + 123, // 119: signal.backup.Group.GroupSnapshot.members_banned:type_name -> signal.backup.Group.MemberBanned + 7, // 120: signal.backup.Group.Member.role:type_name -> signal.backup.Group.Member.Role + 120, // 121: signal.backup.Group.MemberPendingProfileKey.member:type_name -> signal.backup.Group.Member + 8, // 122: signal.backup.Group.AccessControl.attributes:type_name -> signal.backup.Group.AccessControl.AccessRequired + 8, // 123: signal.backup.Group.AccessControl.members:type_name -> signal.backup.Group.AccessControl.AccessRequired + 8, // 124: signal.backup.Group.AccessControl.addFromInviteLink:type_name -> signal.backup.Group.AccessControl.AccessRequired + 45, // 125: signal.backup.ChatItem.OutgoingMessageDetails.sendStatus:type_name -> signal.backup.SendStatus + 12, // 126: signal.backup.SendStatus.Failed.reason:type_name -> signal.backup.SendStatus.Failed.FailureReason + 46, // 127: signal.backup.DirectStoryReplyMessage.TextReply.text:type_name -> signal.backup.Text + 59, // 128: signal.backup.DirectStoryReplyMessage.TextReply.longText:type_name -> signal.backup.FilePointer + 139, // 129: signal.backup.PaymentNotification.TransactionDetails.transaction:type_name -> signal.backup.PaymentNotification.TransactionDetails.Transaction + 138, // 130: signal.backup.PaymentNotification.TransactionDetails.failedTransaction:type_name -> signal.backup.PaymentNotification.TransactionDetails.FailedTransaction + 13, // 131: signal.backup.PaymentNotification.TransactionDetails.FailedTransaction.reason:type_name -> signal.backup.PaymentNotification.TransactionDetails.FailedTransaction.FailureReason + 14, // 132: signal.backup.PaymentNotification.TransactionDetails.Transaction.status:type_name -> signal.backup.PaymentNotification.TransactionDetails.Transaction.Status + 137, // 133: signal.backup.PaymentNotification.TransactionDetails.Transaction.mobileCoinIdentification:type_name -> signal.backup.PaymentNotification.TransactionDetails.MobileCoinTxoIdentification + 16, // 134: signal.backup.ContactAttachment.Phone.type:type_name -> signal.backup.ContactAttachment.Phone.Type + 17, // 135: signal.backup.ContactAttachment.Email.type:type_name -> signal.backup.ContactAttachment.Email.Type + 18, // 136: signal.backup.ContactAttachment.PostalAddress.type:type_name -> signal.backup.ContactAttachment.PostalAddress.Type + 58, // 137: signal.backup.Quote.QuotedAttachment.thumbnail:type_name -> signal.backup.MessageAttachment + 73, // 138: signal.backup.GroupChangeChatUpdate.Update.genericGroupUpdate:type_name -> signal.backup.GenericGroupUpdate + 74, // 139: signal.backup.GroupChangeChatUpdate.Update.groupCreationUpdate:type_name -> signal.backup.GroupCreationUpdate + 75, // 140: signal.backup.GroupChangeChatUpdate.Update.groupNameUpdate:type_name -> signal.backup.GroupNameUpdate + 76, // 141: signal.backup.GroupChangeChatUpdate.Update.groupAvatarUpdate:type_name -> signal.backup.GroupAvatarUpdate + 77, // 142: signal.backup.GroupChangeChatUpdate.Update.groupDescriptionUpdate:type_name -> signal.backup.GroupDescriptionUpdate + 78, // 143: signal.backup.GroupChangeChatUpdate.Update.groupMembershipAccessLevelChangeUpdate:type_name -> signal.backup.GroupMembershipAccessLevelChangeUpdate + 79, // 144: signal.backup.GroupChangeChatUpdate.Update.groupAttributesAccessLevelChangeUpdate:type_name -> signal.backup.GroupAttributesAccessLevelChangeUpdate + 80, // 145: signal.backup.GroupChangeChatUpdate.Update.groupAnnouncementOnlyChangeUpdate:type_name -> signal.backup.GroupAnnouncementOnlyChangeUpdate + 81, // 146: signal.backup.GroupChangeChatUpdate.Update.groupAdminStatusUpdate:type_name -> signal.backup.GroupAdminStatusUpdate + 82, // 147: signal.backup.GroupChangeChatUpdate.Update.groupMemberLeftUpdate:type_name -> signal.backup.GroupMemberLeftUpdate + 83, // 148: signal.backup.GroupChangeChatUpdate.Update.groupMemberRemovedUpdate:type_name -> signal.backup.GroupMemberRemovedUpdate + 84, // 149: signal.backup.GroupChangeChatUpdate.Update.selfInvitedToGroupUpdate:type_name -> signal.backup.SelfInvitedToGroupUpdate + 85, // 150: signal.backup.GroupChangeChatUpdate.Update.selfInvitedOtherUserToGroupUpdate:type_name -> signal.backup.SelfInvitedOtherUserToGroupUpdate + 86, // 151: signal.backup.GroupChangeChatUpdate.Update.groupUnknownInviteeUpdate:type_name -> signal.backup.GroupUnknownInviteeUpdate + 87, // 152: signal.backup.GroupChangeChatUpdate.Update.groupInvitationAcceptedUpdate:type_name -> signal.backup.GroupInvitationAcceptedUpdate + 88, // 153: signal.backup.GroupChangeChatUpdate.Update.groupInvitationDeclinedUpdate:type_name -> signal.backup.GroupInvitationDeclinedUpdate + 89, // 154: signal.backup.GroupChangeChatUpdate.Update.groupMemberJoinedUpdate:type_name -> signal.backup.GroupMemberJoinedUpdate + 90, // 155: signal.backup.GroupChangeChatUpdate.Update.groupMemberAddedUpdate:type_name -> signal.backup.GroupMemberAddedUpdate + 91, // 156: signal.backup.GroupChangeChatUpdate.Update.groupSelfInvitationRevokedUpdate:type_name -> signal.backup.GroupSelfInvitationRevokedUpdate + 92, // 157: signal.backup.GroupChangeChatUpdate.Update.groupInvitationRevokedUpdate:type_name -> signal.backup.GroupInvitationRevokedUpdate + 93, // 158: signal.backup.GroupChangeChatUpdate.Update.groupJoinRequestUpdate:type_name -> signal.backup.GroupJoinRequestUpdate + 94, // 159: signal.backup.GroupChangeChatUpdate.Update.groupJoinRequestApprovalUpdate:type_name -> signal.backup.GroupJoinRequestApprovalUpdate + 95, // 160: signal.backup.GroupChangeChatUpdate.Update.groupJoinRequestCanceledUpdate:type_name -> signal.backup.GroupJoinRequestCanceledUpdate + 97, // 161: signal.backup.GroupChangeChatUpdate.Update.groupInviteLinkResetUpdate:type_name -> signal.backup.GroupInviteLinkResetUpdate + 98, // 162: signal.backup.GroupChangeChatUpdate.Update.groupInviteLinkEnabledUpdate:type_name -> signal.backup.GroupInviteLinkEnabledUpdate + 99, // 163: signal.backup.GroupChangeChatUpdate.Update.groupInviteLinkAdminApprovalUpdate:type_name -> signal.backup.GroupInviteLinkAdminApprovalUpdate + 100, // 164: signal.backup.GroupChangeChatUpdate.Update.groupInviteLinkDisabledUpdate:type_name -> signal.backup.GroupInviteLinkDisabledUpdate + 101, // 165: signal.backup.GroupChangeChatUpdate.Update.groupMemberJoinedByLinkUpdate:type_name -> signal.backup.GroupMemberJoinedByLinkUpdate + 102, // 166: signal.backup.GroupChangeChatUpdate.Update.groupV2MigrationUpdate:type_name -> signal.backup.GroupV2MigrationUpdate + 103, // 167: signal.backup.GroupChangeChatUpdate.Update.groupV2MigrationSelfInvitedUpdate:type_name -> signal.backup.GroupV2MigrationSelfInvitedUpdate + 104, // 168: signal.backup.GroupChangeChatUpdate.Update.groupV2MigrationInvitedMembersUpdate:type_name -> signal.backup.GroupV2MigrationInvitedMembersUpdate + 105, // 169: signal.backup.GroupChangeChatUpdate.Update.groupV2MigrationDroppedMembersUpdate:type_name -> signal.backup.GroupV2MigrationDroppedMembersUpdate + 96, // 170: signal.backup.GroupChangeChatUpdate.Update.groupSequenceOfRequestsAndCancelsUpdate:type_name -> signal.backup.GroupSequenceOfRequestsAndCancelsUpdate + 106, // 171: signal.backup.GroupChangeChatUpdate.Update.groupExpirationTimerUpdate:type_name -> signal.backup.GroupExpirationTimerUpdate + 148, // 172: signal.backup.ChatStyle.CustomChatColor.gradient:type_name -> signal.backup.ChatStyle.Gradient + 173, // [173:173] is the sub-list for method output_type + 173, // [173:173] is the sub-list for method input_type + 173, // [173:173] is the sub-list for extension type_name + 173, // [173:173] is the sub-list for extension extendee + 0, // [0:173] is the sub-list for field type_name } func init() { file_backuppb_Backup_proto_init() } @@ -13071,12 +12592,7 @@ func file_backuppb_Backup_proto_init() { file_backuppb_Backup_proto_msgTypes[25].OneofWrappers = []any{} file_backuppb_Backup_proto_msgTypes[26].OneofWrappers = []any{} file_backuppb_Backup_proto_msgTypes[27].OneofWrappers = []any{} - file_backuppb_Backup_proto_msgTypes[28].OneofWrappers = []any{ - (*FilePointer_BackupLocator_)(nil), - (*FilePointer_AttachmentLocator_)(nil), - (*FilePointer_InvalidAttachmentLocator_)(nil), - (*FilePointer_LocalLocator_)(nil), - } + file_backuppb_Backup_proto_msgTypes[28].OneofWrappers = []any{} file_backuppb_Backup_proto_msgTypes[29].OneofWrappers = []any{} file_backuppb_Backup_proto_msgTypes[30].OneofWrappers = []any{ (*BodyRange_MentionAci)(nil), @@ -13147,15 +12663,12 @@ func file_backuppb_Backup_proto_init() { (*PaymentNotification_TransactionDetails_FailedTransaction_)(nil), } file_backuppb_Backup_proto_msgTypes[108].OneofWrappers = []any{} - file_backuppb_Backup_proto_msgTypes[113].OneofWrappers = []any{} - file_backuppb_Backup_proto_msgTypes[114].OneofWrappers = []any{} - file_backuppb_Backup_proto_msgTypes[116].OneofWrappers = []any{} - file_backuppb_Backup_proto_msgTypes[117].OneofWrappers = []any{ + file_backuppb_Backup_proto_msgTypes[113].OneofWrappers = []any{ (*FilePointer_LocatorInfo_PlaintextHash)(nil), (*FilePointer_LocatorInfo_EncryptedDigest)(nil), } - file_backuppb_Backup_proto_msgTypes[118].OneofWrappers = []any{} - file_backuppb_Backup_proto_msgTypes[119].OneofWrappers = []any{ + file_backuppb_Backup_proto_msgTypes[114].OneofWrappers = []any{} + file_backuppb_Backup_proto_msgTypes[115].OneofWrappers = []any{ (*GroupChangeChatUpdate_Update_GenericGroupUpdate)(nil), (*GroupChangeChatUpdate_Update_GroupCreationUpdate)(nil), (*GroupChangeChatUpdate_Update_GroupNameUpdate)(nil), @@ -13191,8 +12704,8 @@ func file_backuppb_Backup_proto_init() { (*GroupChangeChatUpdate_Update_GroupSequenceOfRequestsAndCancelsUpdate)(nil), (*GroupChangeChatUpdate_Update_GroupExpirationTimerUpdate)(nil), } - file_backuppb_Backup_proto_msgTypes[120].OneofWrappers = []any{} - file_backuppb_Backup_proto_msgTypes[122].OneofWrappers = []any{ + file_backuppb_Backup_proto_msgTypes[116].OneofWrappers = []any{} + file_backuppb_Backup_proto_msgTypes[118].OneofWrappers = []any{ (*ChatStyle_CustomChatColor_Solid)(nil), (*ChatStyle_CustomChatColor_Gradient)(nil), } @@ -13202,7 +12715,7 @@ func file_backuppb_Backup_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: unsafe.Slice(unsafe.StringData(file_backuppb_Backup_proto_rawDesc), len(file_backuppb_Backup_proto_rawDesc)), NumEnums: 31, - NumMessages: 124, + NumMessages: 120, NumExtensions: 0, NumServices: 0, }, diff --git a/pkg/signalmeow/protobuf/backuppb/Backup.proto b/pkg/signalmeow/protobuf/backuppb/Backup.proto index f88c6ae..464301d 100644 --- a/pkg/signalmeow/protobuf/backuppb/Backup.proto +++ b/pkg/signalmeow/protobuf/backuppb/Backup.proto @@ -344,7 +344,7 @@ message CallLink { string name = 3; Restrictions restrictions = 4; uint64 expirationMs = 5; - bytes epoch = 6; // May be absent/empty for older links + optional bytes epoch = 6; // May be absent/empty for older links } message AdHocCall { @@ -396,6 +396,7 @@ message ChatItem { message OutgoingMessageDetails { repeated SendStatus sendStatus = 1; + uint64 dateReceived = 2; // may be different from dateSent for sync messages } message DirectionlessMessageDetails { @@ -693,73 +694,12 @@ message MessageAttachment { } message FilePointer { - // References attachments in the backup (media) storage tier. - // DEPRECATED; use LocatorInfo instead if available. - message BackupLocator { - string mediaName = 1; - // If present, the cdn number of the succesful upload. - // If empty/0, may still have been uploaded, and clients - // can discover the cdn number via the list endpoint. - optional uint32 cdnNumber = 2; - bytes key = 3; - bytes digest = 4; - uint32 size = 5; - - // Fallback in case backup tier upload failed. - optional string transitCdnKey = 6; - optional uint32 transitCdnNumber = 7; - } - - // References attachments in the transit storage tier. - // May be downloaded or not when the backup is generated; - // primarily for free-tier users who cannot copy the - // attachments to the backup (media) storage tier. - // DEPRECATED; use LocatorInfo instead if available. - message AttachmentLocator { - string cdnKey = 1; - uint32 cdnNumber = 2; - optional uint64 uploadTimestamp = 3; - bytes key = 4; - bytes digest = 5; - uint32 size = 6; - } - - // References attachments that are invalid in such a way where download - // cannot be attempted. Could range from missing digests to missing - // CDN keys or anything else that makes download attempts impossible. - // This serves as a 'tombstone' so that the UX can show that an attachment - // did exist, but for whatever reason it's not retrievable. - // DEPRECATED; use LocatorInfo instead if available. - message InvalidAttachmentLocator { - } - - // References attachments in a local encrypted backup. - // Importers should first attempt to read the file from the local backup, - // and on failure fallback to backup and transit cdn if possible. - // DEPRECATED; use LocatorInfo instead if available. - message LocalLocator { - string mediaName = 1; - // Separate key used to encrypt this file for the local backup. - // Generally required. Missing field indicates attachment was not - // available locally when the backup was generated, but remote - // backup or transit info was available. - optional bytes localKey = 2; - bytes remoteKey = 3; - bytes remoteDigest = 4; - uint32 size = 5; - optional uint32 backupCdnNumber = 6; - optional string transitCdnKey = 7; - optional uint32 transitCdnNumber = 8; - } - message LocatorInfo { // Must be non-empty if transitCdnKey or plaintextHash are set/nonempty. // Otherwise must be empty. bytes key = 1; - // From the sender of the attachment (incl. ourselves) - // Will be reserved once all clients start reading integrityCheck - bytes legacyDigest = 2; + reserved /*legacyDigest*/ 2; oneof integrityCheck { // Set if file was at one point downloaded and its plaintextHash was calculated @@ -787,11 +727,7 @@ message FilePointer { // has not rotated since last upload; even if currently free tier. optional uint32 mediaTierCdnNumber = 7; - // Nonempty any time the attachment was downloaded and its - // digest validated, whether free tier or paid subscription. - // Will be reserved once all clients start reading integrityCheck, - // when mediaName will be derived from the plaintextHash and encryption key - string legacyMediaName = 8; + reserved /*legacyMediaName*/ 8; // Separate key used to encrypt this file for the local backup. // Generally required for local backups. @@ -801,14 +737,10 @@ message FilePointer { optional bytes localKey = 9; } - // If unset, importers should consider it to be an InvalidAttachmentLocator without throwing an error. - // DEPRECATED; use locatorInfo instead. - oneof locator { - BackupLocator backupLocator = 1; - AttachmentLocator attachmentLocator = 2; - InvalidAttachmentLocator invalidAttachmentLocator = 3; - LocalLocator localLocator = 12; - } + reserved /*backupLocator*/ 1; + reserved /*attachmentLocator*/ 2; + reserved /*invalidAttachmentLocator*/ 3; + reserved /*localLocator*/ 12; optional string contentType = 4; optional bytes incrementalMac = 5; diff --git a/pkg/signalmeow/protobuf/update-protos.sh b/pkg/signalmeow/protobuf/update-protos.sh index 21503c1..bcdd71b 100755 --- a/pkg/signalmeow/protobuf/update-protos.sh +++ b/pkg/signalmeow/protobuf/update-protos.sh @@ -1,8 +1,8 @@ #!/bin/bash set -euo pipefail -ANDROID_GIT_REVISION=${1:-dbd79cd0a52d7d1594f70a4ba5a68c8fc3efa5e8} -DESKTOP_GIT_REVISION=${1:-07a05f3dd6f7fd07a1faebd8dd046d2b87da6c07} +ANDROID_GIT_REVISION=${1:-62fdf3d1aa9f637729ae67b55aadcc24f38f0117} +DESKTOP_GIT_REVISION=${1:-203a1cc5e3f9c1533a58caff72e13aa6eaeeddc7} update_proto() { case "$1" in From 8ee190a1e72baf682f1ad9e112873e105c53cb27 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Tue, 26 Aug 2025 17:23:55 +0300 Subject: [PATCH 394/580] all: enable mautrix-go's new disappearing message features --- go.mod | 2 +- go.sum | 4 +-- pkg/connector/capabilities.go | 32 +++++++++++-------- pkg/connector/chatinfo.go | 14 ++++++++ pkg/connector/client.go | 17 ++-------- pkg/connector/groupinfo.go | 5 +-- pkg/connector/handlematrix.go | 12 +++++++ pkg/connector/handlesignal.go | 8 ++++- pkg/msgconv/from-matrix.go | 6 +++- pkg/msgconv/from-signal.go | 60 +++++++++++++++++------------------ 10 files changed, 94 insertions(+), 66 deletions(-) diff --git a/go.mod b/go.mod index b66294a..940c9b0 100644 --- a/go.mod +++ b/go.mod @@ -17,7 +17,7 @@ require ( golang.org/x/exp v0.0.0-20250813145105-42675adae3e6 golang.org/x/net v0.43.0 google.golang.org/protobuf v1.36.7 - maunium.net/go/mautrix v0.25.0 + maunium.net/go/mautrix v0.25.1-0.20250826140716-0345a5356de1 ) require ( diff --git a/go.sum b/go.sum index 9fd93bc..c053158 100644 --- a/go.sum +++ b/go.sum @@ -95,5 +95,5 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= maunium.net/go/mauflag v1.0.0 h1:YiaRc0tEI3toYtJMRIfjP+jklH45uDHtT80nUamyD4M= maunium.net/go/mauflag v1.0.0/go.mod h1:nLivPOpTpHnpzEh8jEdSL9UqO9+/KBJFmNRlwKfkPeA= -maunium.net/go/mautrix v0.25.0 h1:dhYoXIXSxI9A+kEPwBceuRP0wcpho15dVLucUF8k2eE= -maunium.net/go/mautrix v0.25.0/go.mod h1:pDd6Ppg+1PbWrw/rg4ZQQfVYZICRGzH+DcliZ/BODvU= +maunium.net/go/mautrix v0.25.1-0.20250826140716-0345a5356de1 h1:8U8dwv4dxhMLrtqjf9LoDuQ6daGj9qdw1/62HIvK2cY= +maunium.net/go/mautrix v0.25.1-0.20250826140716-0345a5356de1/go.mod h1:pDd6Ppg+1PbWrw/rg4ZQQfVYZICRGzH+DcliZ/BODvU= diff --git a/pkg/connector/capabilities.go b/pkg/connector/capabilities.go index f0f71ff..144bda5 100644 --- a/pkg/connector/capabilities.go +++ b/pkg/connector/capabilities.go @@ -37,7 +37,7 @@ func supportedIfFFmpeg() event.CapabilitySupportLevel { } func capID() string { - base := "fi.mau.signal.capabilities.2025_01_16" + base := "fi.mau.signal.capabilities.2025_08_25" if ffmpeg.Supported() { return base + "+ffmpeg" } @@ -136,17 +136,21 @@ var signalCaps = &event.RoomFeatures{ MaxSize: MaxFileSize, }, }, - MaxTextLength: MaxTextLength, // TODO support arbitrary sized text messages with files - LocationMessage: event.CapLevelPartialSupport, - Poll: event.CapLevelRejected, - Thread: event.CapLevelUnsupported, - Reply: event.CapLevelFullySupported, - Edit: event.CapLevelFullySupported, - EditMaxCount: 10, - EditMaxAge: ptr.Ptr(jsontime.S(24 * time.Hour)), - Delete: event.CapLevelFullySupported, - DeleteForMe: false, - DeleteMaxAge: ptr.Ptr(jsontime.S(24 * time.Hour)), + MaxTextLength: MaxTextLength, // TODO support arbitrary sized text messages with files + LocationMessage: event.CapLevelPartialSupport, + Poll: event.CapLevelRejected, + Thread: event.CapLevelUnsupported, + Reply: event.CapLevelFullySupported, + Edit: event.CapLevelFullySupported, + EditMaxCount: 10, + EditMaxAge: ptr.Ptr(jsontime.S(24 * time.Hour)), + Delete: event.CapLevelFullySupported, + DeleteForMe: false, + DeleteMaxAge: ptr.Ptr(jsontime.S(24 * time.Hour)), + DisappearingTimer: &event.DisappearingTimerCapability{ + Types: []event.DisappearingType{event.DisappearingTypeAfterRead}, + }, + Reaction: event.CapLevelFullySupported, ReactionCount: 1, AllowedReactions: nil, @@ -161,7 +165,7 @@ func init() { signalCapsNoteToSelf = ptr.Clone(signalCaps) signalCapsNoteToSelf.EditMaxAge = nil signalCapsNoteToSelf.DeleteMaxAge = nil - signalCapsNoteToSelf.ID = capID() + "+note_to_self.2" + signalCapsNoteToSelf.ID = capID() + "+note_to_self" } func (s *SignalClient) GetCapabilities(ctx context.Context, portal *bridgev2.Portal) *event.RoomFeatures { @@ -181,5 +185,5 @@ func (s *SignalConnector) GetCapabilities() *bridgev2.NetworkGeneralCapabilities } func (s *SignalConnector) GetBridgeInfoVersion() (info, capabilities int) { - return 1, 4 + return 1, 5 } diff --git a/pkg/connector/chatinfo.go b/pkg/connector/chatinfo.go index 1937318..d4d1013 100644 --- a/pkg/connector/chatinfo.go +++ b/pkg/connector/chatinfo.go @@ -40,6 +40,12 @@ import ( "go.mau.fi/mautrix-signal/pkg/signalmeow/types" ) +var ( + _ bridgev2.IdentifierResolvingNetworkAPI = (*SignalClient)(nil) + _ bridgev2.GroupCreatingNetworkAPI = (*SignalClient)(nil) + _ bridgev2.ContactListingNetworkAPI = (*SignalClient)(nil) +) + const PrivateChatTopic = "Signal private chat" const NoteToSelfName = "Signal Note to Self" @@ -278,6 +284,14 @@ func (s *SignalClient) makeCreateDMResponse(ctx context.Context, recipient *type PowerLevel: &moderatorPL, }, }, + PowerLevels: &bridgev2.PowerLevelOverrides{ + Events: map[event.Type]int{ + event.StateRoomName: 0, + event.StateTopic: 0, + event.StateRoomAvatar: 0, + event.StateBeeperDisappearingTimer: 0, + }, + }, } if s.Main.Config.NumberInTopic && recipient.E164 != "" { topic = fmt.Sprintf("%s with %s", PrivateChatTopic, recipient.E164) diff --git a/pkg/connector/client.go b/pkg/connector/client.go index 925747e..27cea14 100644 --- a/pkg/connector/client.go +++ b/pkg/connector/client.go @@ -42,21 +42,8 @@ type SignalClient struct { } var ( - _ bridgev2.NetworkAPI = (*SignalClient)(nil) - _ bridgev2.EditHandlingNetworkAPI = (*SignalClient)(nil) - _ bridgev2.ReactionHandlingNetworkAPI = (*SignalClient)(nil) - _ bridgev2.RedactionHandlingNetworkAPI = (*SignalClient)(nil) - _ bridgev2.ReadReceiptHandlingNetworkAPI = (*SignalClient)(nil) - _ bridgev2.ReadReceiptHandlingNetworkAPI = (*SignalClient)(nil) - _ bridgev2.TypingHandlingNetworkAPI = (*SignalClient)(nil) - _ bridgev2.IdentifierResolvingNetworkAPI = (*SignalClient)(nil) - _ bridgev2.GroupCreatingNetworkAPI = (*SignalClient)(nil) - _ bridgev2.ContactListingNetworkAPI = (*SignalClient)(nil) - _ bridgev2.RoomNameHandlingNetworkAPI = (*SignalClient)(nil) - _ bridgev2.RoomAvatarHandlingNetworkAPI = (*SignalClient)(nil) - _ bridgev2.RoomTopicHandlingNetworkAPI = (*SignalClient)(nil) - _ bridgev2.BackgroundSyncingNetworkAPI = (*SignalClient)(nil) - _ bridgev2.ChatViewingNetworkAPI = (*SignalClient)(nil) + _ bridgev2.NetworkAPI = (*SignalClient)(nil) + _ bridgev2.BackgroundSyncingNetworkAPI = (*SignalClient)(nil) ) var pushCfg = &bridgev2.PushConfig{ diff --git a/pkg/connector/groupinfo.go b/pkg/connector/groupinfo.go index dfd4faf..3b5fbcd 100644 --- a/pkg/connector/groupinfo.go +++ b/pkg/connector/groupinfo.go @@ -66,6 +66,7 @@ func applyAttributesAccess(plc *bridgev2.PowerLevelOverrides, attributeAccess si plc.Events[event.StateRoomName] = attributePL plc.Events[event.StateRoomAvatar] = attributePL plc.Events[event.StateTopic] = attributePL + plc.Events[event.StateBeeperDisappearingTimer] = attributePL } func applyMembersAccess(plc *bridgev2.PowerLevelOverrides, memberAccess signalmeow.AccessControl) { @@ -170,7 +171,7 @@ func (s *SignalClient) getGroupInfo(ctx context.Context, groupID types.GroupIden Topic: &groupInfo.Description, Avatar: avatar, Disappear: &database.DisappearingSetting{ - Type: database.DisappearingTypeAfterRead, + Type: event.DisappearingTypeAfterRead, Timer: time.Duration(groupInfo.DisappearingMessagesDuration) * time.Second, }, Members: members, @@ -245,7 +246,7 @@ func (s *SignalClient) groupChangeToChatInfoChange(ctx context.Context, groupID } if groupChange.ModifyDisappearingMessagesDuration != nil { ic.ChatInfo.Disappear = &database.DisappearingSetting{ - Type: database.DisappearingTypeAfterRead, + Type: event.DisappearingTypeAfterRead, Timer: time.Duration(*groupChange.ModifyDisappearingMessagesDuration) * time.Second, } } diff --git a/pkg/connector/handlematrix.go b/pkg/connector/handlematrix.go index 09daaa2..af5cb55 100644 --- a/pkg/connector/handlematrix.go +++ b/pkg/connector/handlematrix.go @@ -39,6 +39,18 @@ import ( signalpb "go.mau.fi/mautrix-signal/pkg/signalmeow/protobuf" ) +var ( + _ bridgev2.EditHandlingNetworkAPI = (*SignalClient)(nil) + _ bridgev2.ReactionHandlingNetworkAPI = (*SignalClient)(nil) + _ bridgev2.RedactionHandlingNetworkAPI = (*SignalClient)(nil) + _ bridgev2.ReadReceiptHandlingNetworkAPI = (*SignalClient)(nil) + _ bridgev2.TypingHandlingNetworkAPI = (*SignalClient)(nil) + _ bridgev2.RoomNameHandlingNetworkAPI = (*SignalClient)(nil) + _ bridgev2.RoomAvatarHandlingNetworkAPI = (*SignalClient)(nil) + _ bridgev2.RoomTopicHandlingNetworkAPI = (*SignalClient)(nil) + _ bridgev2.ChatViewingNetworkAPI = (*SignalClient)(nil) +) + func (s *SignalClient) sendMessage(ctx context.Context, portalID networkid.PortalID, content *signalpb.Content) error { userID, groupID, err := signalid.ParsePortalID(portalID) if err != nil { diff --git a/pkg/connector/handlesignal.go b/pkg/connector/handlesignal.go index 803d481..fe11f88 100644 --- a/pkg/connector/handlesignal.go +++ b/pkg/connector/handlesignal.go @@ -331,7 +331,13 @@ func (evt *Bv2ChatEvent) ConvertMessage(ctx context.Context, portal *bridgev2.Po if converted.Disappear.Type != "" { evtTS := evt.GetTimestamp() if !dataMsg.GetIsViewOnce() { - portal.UpdateDisappearingSetting(ctx, converted.Disappear, nil, evtTS, true, true) + portal.UpdateDisappearingSetting(ctx, converted.Disappear, bridgev2.UpdateDisappearingSettingOpts{ + Sender: intent, + Timestamp: evtTS, + Implicit: true, + Save: true, + SendNotice: true, + }) } if evt.Info.Sender == evt.s.Client.Store.ACI { converted.Disappear.DisappearAt = evtTS.Add(converted.Disappear.Timer) diff --git a/pkg/msgconv/from-matrix.go b/pkg/msgconv/from-matrix.go index 26bb492..9af4dc5 100644 --- a/pkg/msgconv/from-matrix.go +++ b/pkg/msgconv/from-matrix.go @@ -71,8 +71,12 @@ func (mc *MessageConverter) ToSignal( } } } - if portal.Disappear.Timer > 0 { + if content.BeeperDisappearingTimer != nil { + dm.ExpireTimer = proto.Uint32(uint32(content.BeeperDisappearingTimer.Timer.Seconds())) + } else if portal.Disappear.Timer > 0 { dm.ExpireTimer = proto.Uint32(uint32(portal.Disappear.Timer.Seconds())) + } + if dm.ExpireTimer != nil && *dm.ExpireTimer != 0 { timerVersion := portal.Metadata.(*signalid.PortalMetadata).ExpirationTimerVersion if timerVersion > 0 { dm.ExpireTimerVersion = &timerVersion diff --git a/pkg/msgconv/from-signal.go b/pkg/msgconv/from-signal.go index 815954a..b4f1b56 100644 --- a/pkg/msgconv/from-signal.go +++ b/pkg/msgconv/from-signal.go @@ -93,12 +93,12 @@ func (mc *MessageConverter) ToMatrix( Parts: make([]*bridgev2.ConvertedMessagePart, 0, calculateLength(dm)), } if dm.GetFlags()&uint32(signalpb.DataMessage_EXPIRATION_TIMER_UPDATE) != 0 { - cm.Parts = append(cm.Parts, mc.ConvertDisappearingTimerChangeToMatrix(ctx, dm.GetExpireTimer(), dm.ExpireTimerVersion, true)) + cm.Parts = append(cm.Parts, mc.ConvertDisappearingTimerChangeToMatrix(ctx, dm.GetExpireTimer(), dm.ExpireTimerVersion, time.UnixMilli(int64(dm.GetTimestamp())))) // Don't allow any other parts in a disappearing timer change message return cm } if dm.GetExpireTimer() > 0 { - cm.Disappear.Type = database.DisappearingTypeAfterRead + cm.Disappear.Type = event.DisappearingTypeAfterRead cm.Disappear.Timer = time.Duration(dm.GetExpireTimer()) * time.Second } if dm.Sticker != nil { @@ -140,7 +140,7 @@ func (mc *MessageConverter) ToMatrix( }) } if dm.GetIsViewOnce() && mc.DisappearViewOnce && (cm.Disappear.Timer == 0 || cm.Disappear.Timer > ViewOnceDisappearTimer) { - cm.Disappear.Type = database.DisappearingTypeAfterRead + cm.Disappear.Type = event.DisappearingTypeAfterRead cm.Disappear.Timer = ViewOnceDisappearTimer cm.Parts = append(cm.Parts, &bridgev2.ConvertedMessagePart{ Type: event.EventMessage, @@ -170,38 +170,38 @@ func (mc *MessageConverter) ToMatrix( return cm } -func (mc *MessageConverter) ConvertDisappearingTimerChangeToMatrix(ctx context.Context, timer uint32, timerVersion *uint32, updatePortal bool) *bridgev2.ConvertedMessagePart { +func (mc *MessageConverter) ConvertDisappearingTimerChangeToMatrix(ctx context.Context, timer uint32, timerVersion *uint32, ts time.Time) *bridgev2.ConvertedMessagePart { part := &bridgev2.ConvertedMessagePart{ Type: event.EventMessage, Content: bridgev2.DisappearingMessageNotice(time.Duration(timer)*time.Second, false), } - if updatePortal { - portal := getPortal(ctx) - portalMeta := portal.Metadata.(*signalid.PortalMetadata) - if timerVersion != nil && portalMeta.ExpirationTimerVersion > *timerVersion { - zerolog.Ctx(ctx).Warn(). - Uint32("current_version", portalMeta.ExpirationTimerVersion). - Uint32("new_version", *timerVersion). - Msg("Ignoring outdated disappearing timer change") - part.Content.Body += " (change ignored)" - return part - } - portal.Disappear.Timer = time.Duration(timer) * time.Second - if timer == 0 { - portal.Disappear.Type = "" - } else { - portal.Disappear.Type = database.DisappearingTypeAfterRead - } - if timerVersion != nil { - portalMeta.ExpirationTimerVersion = *timerVersion - } else { - portalMeta.ExpirationTimerVersion = 1 - } - err := portal.Save(ctx) - if err != nil { - zerolog.Ctx(ctx).Err(err).Msg("Failed to update portal disappearing timer in database") - } + portal := getPortal(ctx) + portalMeta := portal.Metadata.(*signalid.PortalMetadata) + if timerVersion != nil && portalMeta.ExpirationTimerVersion > *timerVersion { + zerolog.Ctx(ctx).Warn(). + Uint32("current_version", portalMeta.ExpirationTimerVersion). + Uint32("new_version", *timerVersion). + Msg("Ignoring outdated disappearing timer change") + part.Content.Body += " (change ignored)" + return part } + setting := database.DisappearingSetting{ + Timer: time.Duration(timer) * time.Second, + Type: event.DisappearingTypeAfterRead, + } + if timer == 0 { + portal.Disappear.Type = "" + } + if timerVersion != nil { + portalMeta.ExpirationTimerVersion = *timerVersion + } else { + portalMeta.ExpirationTimerVersion = 1 + } + portal.UpdateDisappearingSetting(ctx, setting, bridgev2.UpdateDisappearingSettingOpts{ + Sender: getIntent(ctx), + Timestamp: ts, + Save: true, + }) return part } From 9e31917222f506bd8cf313d01f9048dd913634aa Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Fri, 29 Aug 2025 12:12:00 +0300 Subject: [PATCH 395/580] signalmeow: update capability flags --- pkg/signalmeow/provisioning.go | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/pkg/signalmeow/provisioning.go b/pkg/signalmeow/provisioning.go index 07697d1..8957018 100644 --- a/pkg/signalmeow/provisioning.go +++ b/pkg/signalmeow/provisioning.go @@ -359,9 +359,8 @@ func continueProvisioning(ctx context.Context, ws *websocket.Conn, provisioningC } var signalCapabilities = map[string]any{ - "deleteSync": true, - "versionedExpirationTimer": true, - "ssre2": true, + "attachmentBackfill": true, + "sqpr": true, } var signalCapabilitiesBody = exerrors.Must(json.Marshal(signalCapabilities)) From 676ad03905abe733f7e496fc72939e7784de75aa Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Fri, 29 Aug 2025 16:10:41 +0300 Subject: [PATCH 396/580] handlematrix: add support for changing disappearing timer --- pkg/connector/handlematrix.go | 56 +++++++++++++++++++++++++++++------ 1 file changed, 47 insertions(+), 9 deletions(-) diff --git a/pkg/connector/handlematrix.go b/pkg/connector/handlematrix.go index af5cb55..977e22f 100644 --- a/pkg/connector/handlematrix.go +++ b/pkg/connector/handlematrix.go @@ -26,6 +26,7 @@ import ( "github.com/google/uuid" "github.com/rs/zerolog" + "go.mau.fi/util/ptr" "go.mau.fi/util/variationselector" "google.golang.org/protobuf/proto" "maunium.net/go/mautrix/bridgev2" @@ -40,15 +41,16 @@ import ( ) var ( - _ bridgev2.EditHandlingNetworkAPI = (*SignalClient)(nil) - _ bridgev2.ReactionHandlingNetworkAPI = (*SignalClient)(nil) - _ bridgev2.RedactionHandlingNetworkAPI = (*SignalClient)(nil) - _ bridgev2.ReadReceiptHandlingNetworkAPI = (*SignalClient)(nil) - _ bridgev2.TypingHandlingNetworkAPI = (*SignalClient)(nil) - _ bridgev2.RoomNameHandlingNetworkAPI = (*SignalClient)(nil) - _ bridgev2.RoomAvatarHandlingNetworkAPI = (*SignalClient)(nil) - _ bridgev2.RoomTopicHandlingNetworkAPI = (*SignalClient)(nil) - _ bridgev2.ChatViewingNetworkAPI = (*SignalClient)(nil) + _ bridgev2.EditHandlingNetworkAPI = (*SignalClient)(nil) + _ bridgev2.ReactionHandlingNetworkAPI = (*SignalClient)(nil) + _ bridgev2.RedactionHandlingNetworkAPI = (*SignalClient)(nil) + _ bridgev2.ReadReceiptHandlingNetworkAPI = (*SignalClient)(nil) + _ bridgev2.TypingHandlingNetworkAPI = (*SignalClient)(nil) + _ bridgev2.RoomNameHandlingNetworkAPI = (*SignalClient)(nil) + _ bridgev2.RoomAvatarHandlingNetworkAPI = (*SignalClient)(nil) + _ bridgev2.RoomTopicHandlingNetworkAPI = (*SignalClient)(nil) + _ bridgev2.ChatViewingNetworkAPI = (*SignalClient)(nil) + _ bridgev2.DisappearTimerChangingNetworkAPI = (*SignalClient)(nil) ) func (s *SignalClient) sendMessage(ctx context.Context, portalID networkid.PortalID, content *signalpb.Content) error { @@ -607,3 +609,39 @@ func (s *SignalClient) HandleMatrixViewingChat(ctx context.Context, msg *bridgev ghost.UpdateInfo(ctx, info) return nil } + +func (s *SignalClient) HandleMatrixDisappearingTimer(ctx context.Context, msg *bridgev2.MatrixDisappearingTimer) (bool, error) { + if msg.Content.Type != event.DisappearingTypeAfterRead && msg.Content.Timer.Duration != 0 { + return false, fmt.Errorf("unsupported disappearing timer type: %s", msg.Content.Type) + } + userID, groupID, err := signalid.ParsePortalID(msg.Portal.ID) + if err != nil { + return false, err + } + newSetting := database.DisappearingSetting{ + Type: event.DisappearingTypeAfterRead, + Timer: msg.Content.Timer.Duration, + } + if newSetting.Timer == 0 { + newSetting.Type = event.DisappearingTypeNone + } + if groupID != "" { + return s.handleMatrixRoomMeta(ctx, msg.Portal, &signalmeow.GroupChange{ + ModifyDisappearingMessagesDuration: ptr.Ptr(uint32(msg.Content.Timer.Seconds())), + }, func() { + msg.Portal.Disappear = newSetting + }) + } else { + res := s.Client.SendMessage(ctx, userID, &signalpb.Content{ + DataMessage: &signalpb.DataMessage{ + Flags: ptr.Ptr(uint32(signalpb.DataMessage_EXPIRATION_TIMER_UPDATE)), + ExpireTimer: ptr.Ptr(uint32(msg.Content.Timer.Seconds())), + }, + }) + if !res.WasSuccessful { + return false, res.Error + } + msg.Portal.Disappear = newSetting + return true, nil + } +} From f80af12c9b8e28c2974d897f89efbce255a9b82e Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Mon, 1 Sep 2025 16:40:35 +0300 Subject: [PATCH 397/580] signalmeow/store: save signal-specific nicknames --- pkg/connector/config.go | 2 ++ pkg/connector/example-config.yaml | 1 + pkg/signalmeow/storageservice.go | 4 ++++ pkg/signalmeow/store/recipient_store.go | 7 ++++++- pkg/signalmeow/store/upgrades/00-latest.sql | 3 ++- pkg/signalmeow/store/upgrades/22-recipient-nickname.sql | 2 ++ pkg/signalmeow/types/contact.go | 1 + 7 files changed, 18 insertions(+), 2 deletions(-) create mode 100644 pkg/signalmeow/store/upgrades/22-recipient-nickname.sql diff --git a/pkg/connector/config.go b/pkg/connector/config.go index 1f583c5..e210b65 100644 --- a/pkg/connector/config.go +++ b/pkg/connector/config.go @@ -47,6 +47,7 @@ type SignalConfig struct { type DisplaynameParams struct { ProfileName string ContactName string + Nickname string Username string PhoneNumber string UUID string @@ -60,6 +61,7 @@ func (c *SignalConfig) FormatDisplayname(contact *types.Recipient) string { err := c.displaynameTemplate.Execute(&nameBuf, &DisplaynameParams{ ProfileName: contact.Profile.Name, ContactName: contact.ContactName, + Nickname: contact.Nickname, Username: "", PhoneNumber: contact.E164, UUID: contact.ACI.String(), diff --git a/pkg/connector/example-config.yaml b/pkg/connector/example-config.yaml index 8c0a61e..e9ff6b4 100644 --- a/pkg/connector/example-config.yaml +++ b/pkg/connector/example-config.yaml @@ -1,6 +1,7 @@ # Displayname template for Signal users. # {{.ProfileName}} - The Signal profile name set by the user. # {{.ContactName}} - The name for the user from your phone's contact list. This is not safe on multi-user instances. +# {{.Nickname}} - The nickname set for the user in the native Signal app. This is not safe on multi-user instances. # {{.PhoneNumber}} - The phone number of the user. # {{.UUID}} - The UUID of the Signal user. # {{.AboutEmoji}} - The emoji set by the user in their profile. diff --git a/pkg/signalmeow/storageservice.go b/pkg/signalmeow/storageservice.go index 26d52ff..38a17d9 100644 --- a/pkg/signalmeow/storageservice.go +++ b/pkg/signalmeow/storageservice.go @@ -88,6 +88,10 @@ func (cli *Client) processStorageInTxn(ctx context.Context, update *StorageUpdat changed = true recipient.ContactName = strings.TrimSpace(fmt.Sprintf("%s %s", contact.SystemGivenName, contact.SystemFamilyName)) } + if contact.Nickname != nil { + changed = true + recipient.Nickname = strings.TrimSpace(fmt.Sprintf("%s %s", contact.Nickname.Given, contact.Nickname.Family)) + } if contact.E164 != "" { changed = changed || recipient.E164 != contact.E164 recipient.E164 = contact.E164 diff --git a/pkg/signalmeow/store/recipient_store.go b/pkg/signalmeow/store/recipient_store.go index 03608a2..9e2bb8e 100644 --- a/pkg/signalmeow/store/recipient_store.go +++ b/pkg/signalmeow/store/recipient_store.go @@ -55,6 +55,7 @@ const ( e164_number, contact_name, contact_avatar_hash, + nickname, profile_key, profile_name, profile_about, @@ -79,6 +80,7 @@ const ( e164_number, contact_name, contact_avatar_hash, + nickname, profile_key, profile_name, profile_about, @@ -87,12 +89,13 @@ const ( profile_fetched_at, needs_pni_signature ) - VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13) + VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14) ON CONFLICT (account_id, aci_uuid) DO UPDATE SET pni_uuid = excluded.pni_uuid, e164_number = excluded.e164_number, contact_name = excluded.contact_name, contact_avatar_hash = excluded.contact_avatar_hash, + nickname = excluded.nickname, profile_key = excluded.profile_key, profile_name = excluded.profile_name, profile_about = excluded.profile_about, @@ -128,6 +131,7 @@ func scanRecipient(row dbutil.Scannable) (*types.Recipient, error) { &recipient.E164, &recipient.ContactName, &recipient.ContactAvatar.Hash, + &recipient.Nickname, &profileKey, &recipient.Profile.Name, &recipient.Profile.About, @@ -329,6 +333,7 @@ func (s *sqlStore) StoreRecipient(ctx context.Context, recipient *types.Recipien recipient.E164, recipient.ContactName, recipient.ContactAvatar.Hash, + recipient.Nickname, recipient.Profile.Key.Slice(), recipient.Profile.Name, recipient.Profile.About, diff --git a/pkg/signalmeow/store/upgrades/00-latest.sql b/pkg/signalmeow/store/upgrades/00-latest.sql index cb7e693..2c550c9 100644 --- a/pkg/signalmeow/store/upgrades/00-latest.sql +++ b/pkg/signalmeow/store/upgrades/00-latest.sql @@ -1,4 +1,4 @@ --- v0 -> v21 (compatible with v13+): Latest revision +-- v0 -> v22 (compatible with v13+): Latest revision CREATE TABLE signalmeow_device ( aci_uuid TEXT PRIMARY KEY, @@ -109,6 +109,7 @@ CREATE TABLE signalmeow_recipients ( e164_number TEXT NOT NULL DEFAULT '', contact_name TEXT NOT NULL DEFAULT '', contact_avatar_hash TEXT NOT NULL DEFAULT '', + nickname TEXT NOT NULL DEFAULT '', profile_key bytea, profile_name TEXT NOT NULL DEFAULT '', profile_about TEXT NOT NULL DEFAULT '', diff --git a/pkg/signalmeow/store/upgrades/22-recipient-nickname.sql b/pkg/signalmeow/store/upgrades/22-recipient-nickname.sql new file mode 100644 index 0000000..437cb33 --- /dev/null +++ b/pkg/signalmeow/store/upgrades/22-recipient-nickname.sql @@ -0,0 +1,2 @@ +-- v22 (compatible with v13+): Store Signal-specific nickname of contacts +ALTER TABLE signalmeow_recipients ADD COLUMN nickname TEXT NOT NULL DEFAULT ''; diff --git a/pkg/signalmeow/types/contact.go b/pkg/signalmeow/types/contact.go index fea6fa5..53852aa 100644 --- a/pkg/signalmeow/types/contact.go +++ b/pkg/signalmeow/types/contact.go @@ -51,6 +51,7 @@ type Recipient struct { E164 string ContactName string ContactAvatar ContactAvatar + Nickname string Profile Profile NeedsPNISignature bool From c71d417ccc8691b8bdfdbad8d208a6ab83790d62 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Mon, 1 Sep 2025 16:48:30 +0300 Subject: [PATCH 398/580] signalmeow/storageservice: send contact list event on storage sync --- pkg/connector/handlesignal.go | 13 ++++++++----- pkg/signalmeow/events/message.go | 1 + pkg/signalmeow/storageservice.go | 15 ++++++++++++++- 3 files changed, 23 insertions(+), 6 deletions(-) diff --git a/pkg/connector/handlesignal.go b/pkg/connector/handlesignal.go index fe11f88..d60acc0 100644 --- a/pkg/connector/handlesignal.go +++ b/pkg/connector/handlesignal.go @@ -651,12 +651,15 @@ func (s *SignalClient) handleSignalContactList(evt *events.ContactList) { if contact.ACI == uuid.Nil { continue } - fullContact, err := s.Client.ContactByACI(ctx, contact.ACI) - if err != nil { - log.Err(err).Msg("Failed to get full contact info from store") - continue + if !evt.IsFromDB { + fullContact, err := s.Client.ContactByACI(ctx, contact.ACI) + if err != nil { + log.Err(err).Msg("Failed to get full contact info from store") + continue + } + fullContact.ContactAvatar = contact.ContactAvatar + contact = fullContact } - fullContact.ContactAvatar = contact.ContactAvatar ghost, err := s.Main.Bridge.GetGhostByID(ctx, signalid.MakeUserID(contact.ACI)) if err != nil { log.Err(err).Msg("Failed to get ghost to update contact info") diff --git a/pkg/signalmeow/events/message.go b/pkg/signalmeow/events/message.go index cc7d62c..0642c33 100644 --- a/pkg/signalmeow/events/message.go +++ b/pkg/signalmeow/events/message.go @@ -76,6 +76,7 @@ type Call struct { type ContactList struct { Contacts []*types.Recipient + IsFromDB bool } type ACIFound struct { diff --git a/pkg/signalmeow/storageservice.go b/pkg/signalmeow/storageservice.go index 38a17d9..06b0283 100644 --- a/pkg/signalmeow/storageservice.go +++ b/pkg/signalmeow/storageservice.go @@ -35,6 +35,7 @@ import ( "google.golang.org/protobuf/proto" "go.mau.fi/mautrix-signal/pkg/libsignalgo" + "go.mau.fi/mautrix-signal/pkg/signalmeow/events" signalpb "go.mau.fi/mautrix-signal/pkg/signalmeow/protobuf" "go.mau.fi/mautrix-signal/pkg/signalmeow/types" "go.mau.fi/mautrix-signal/pkg/signalmeow/web" @@ -59,6 +60,7 @@ func (cli *Client) SyncStorage(ctx context.Context) { func (cli *Client) processStorageInTxn(ctx context.Context, update *StorageUpdate) error { log := zerolog.Ctx(ctx) + var changedContacts []*types.Recipient for _, record := range update.NewRecords { switch data := record.StorageRecord.GetRecord().(type) { case *signalpb.StorageRecord_Contact: @@ -74,7 +76,8 @@ func (cli *Client) processStorageInTxn(ctx context.Context, update *StorageUpdat continue } contact := data.Contact - _, err := cli.Store.RecipientStore.LoadAndUpdateRecipient(ctx, aci, pni, func(recipient *types.Recipient) (changed bool, err error) { + topLevelChanged := false + recipient, err := cli.Store.RecipientStore.LoadAndUpdateRecipient(ctx, aci, pni, func(recipient *types.Recipient) (changed bool, err error) { if len(contact.ProfileKey) == libsignalgo.ProfileKeyLength { newProfileKey := libsignalgo.ProfileKey(contact.ProfileKey) changed = changed || recipient.Profile.Key != newProfileKey @@ -96,11 +99,15 @@ func (cli *Client) processStorageInTxn(ctx context.Context, update *StorageUpdat changed = changed || recipient.E164 != contact.E164 recipient.E164 = contact.E164 } + topLevelChanged = changed return }) if err != nil { return fmt.Errorf("failed to update contact %s/%s: %w", aci, pni, err) } + if topLevelChanged { + changedContacts = append(changedContacts, recipient) + } case *signalpb.StorageRecord_GroupV2: if len(data.GroupV2.MasterKey) != libsignalgo.GroupMasterKeyLength { log.Warn().Msg("Invalid group master key length") @@ -126,6 +133,12 @@ func (cli *Client) processStorageInTxn(ctx context.Context, update *StorageUpdat log.Warn().Type("type", data).Str("item_id", record.StorageID).Msg("Unknown storage record type") } } + if len(changedContacts) > 0 { + go cli.handleEvent(&events.ContactList{ + Contacts: changedContacts, + IsFromDB: true, + }) + } return nil } From 06ac834ac32db08118b437923ef87c97fb43ba41 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Mon, 1 Sep 2025 17:06:25 +0300 Subject: [PATCH 399/580] config: parse displayname template at config parse time --- pkg/connector/config.go | 18 ++++++++++++++++++ pkg/connector/connector.go | 7 ------- 2 files changed, 18 insertions(+), 7 deletions(-) diff --git a/pkg/connector/config.go b/pkg/connector/config.go index e210b65..4e42186 100644 --- a/pkg/connector/config.go +++ b/pkg/connector/config.go @@ -22,6 +22,8 @@ import ( "text/template" up "go.mau.fi/util/configupgrade" + "gopkg.in/yaml.v3" + "maunium.net/go/mautrix/id" "go.mau.fi/mautrix-signal/pkg/signalmeow/types" @@ -44,6 +46,22 @@ type SignalConfig struct { displaynameTemplate *template.Template `yaml:"-"` } +type umConfig SignalConfig + +func (c *SignalConfig) UnmarshalYAML(node *yaml.Node) error { + err := node.Decode((*umConfig)(c)) + if err != nil { + return err + } + return c.PostProcess() +} + +func (c *SignalConfig) PostProcess() error { + var err error + c.displaynameTemplate, err = template.New("displayname").Parse(c.DisplaynameTemplate) + return err +} + type DisplaynameParams struct { ProfileName string ContactName string diff --git a/pkg/connector/connector.go b/pkg/connector/connector.go index 00032b8..e81ef7a 100644 --- a/pkg/connector/connector.go +++ b/pkg/connector/connector.go @@ -20,7 +20,6 @@ import ( "context" "fmt" "strconv" - "text/template" "time" "github.com/google/uuid" @@ -59,12 +58,6 @@ func (s *SignalConnector) GetName() bridgev2.BridgeName { } func (s *SignalConnector) Init(bridge *bridgev2.Bridge) { - var err error - s.Config.displaynameTemplate, err = template.New("displayname").Parse(s.Config.DisplaynameTemplate) - if err != nil { - // TODO return error or do this later? - panic(err) - } s.Store = store.NewStore(bridge.DB.Database, dbutil.ZeroLogger(bridge.Log.With().Str("db_section", "signalmeow").Logger())) s.Bridge = bridge s.MsgConv = msgconv.NewMessageConverter(bridge) From ffd170f0f11d3565302875a39bce5f66827f5174 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Thu, 4 Sep 2025 12:13:58 +0200 Subject: [PATCH 400/580] startchat: add support for creating groups (#607) --- go.mod | 4 +- go.sum | 4 +- pkg/connector/capabilities.go | 48 +++++++++++----- pkg/connector/chatinfo.go | 105 +++++++++++++++++++++++++++++++++- pkg/connector/groupinfo.go | 9 ++- pkg/connector/handlematrix.go | 3 +- pkg/signalmeow/attachments.go | 22 +++---- pkg/signalmeow/groups.go | 52 +++++++++-------- pkg/signalmeow/profile.go | 5 +- 9 files changed, 189 insertions(+), 63 deletions(-) diff --git a/go.mod b/go.mod index 940c9b0..bf104b0 100644 --- a/go.mod +++ b/go.mod @@ -17,7 +17,8 @@ require ( golang.org/x/exp v0.0.0-20250813145105-42675adae3e6 golang.org/x/net v0.43.0 google.golang.org/protobuf v1.36.7 - maunium.net/go/mautrix v0.25.1-0.20250826140716-0345a5356de1 + gopkg.in/yaml.v3 v3.0.1 + maunium.net/go/mautrix v0.25.1-0.20250902152424-709f48f2b370 ) require ( @@ -44,6 +45,5 @@ require ( golang.org/x/text v0.28.0 // indirect gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect gopkg.in/natefinch/lumberjack.v2 v2.2.1 // indirect - gopkg.in/yaml.v3 v3.0.1 // indirect maunium.net/go/mauflag v1.0.0 // indirect ) diff --git a/go.sum b/go.sum index c053158..e4402d2 100644 --- a/go.sum +++ b/go.sum @@ -95,5 +95,5 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= maunium.net/go/mauflag v1.0.0 h1:YiaRc0tEI3toYtJMRIfjP+jklH45uDHtT80nUamyD4M= maunium.net/go/mauflag v1.0.0/go.mod h1:nLivPOpTpHnpzEh8jEdSL9UqO9+/KBJFmNRlwKfkPeA= -maunium.net/go/mautrix v0.25.1-0.20250826140716-0345a5356de1 h1:8U8dwv4dxhMLrtqjf9LoDuQ6daGj9qdw1/62HIvK2cY= -maunium.net/go/mautrix v0.25.1-0.20250826140716-0345a5356de1/go.mod h1:pDd6Ppg+1PbWrw/rg4ZQQfVYZICRGzH+DcliZ/BODvU= +maunium.net/go/mautrix v0.25.1-0.20250902152424-709f48f2b370 h1:1rz6V3P38i2qSJKEe0QBXozfI/9yaM/zWrZPDrtKVYQ= +maunium.net/go/mautrix v0.25.1-0.20250902152424-709f48f2b370/go.mod h1:pDd6Ppg+1PbWrw/rg4ZQQfVYZICRGzH+DcliZ/BODvU= diff --git a/pkg/connector/capabilities.go b/pkg/connector/capabilities.go index 144bda5..129c75c 100644 --- a/pkg/connector/capabilities.go +++ b/pkg/connector/capabilities.go @@ -136,20 +136,18 @@ var signalCaps = &event.RoomFeatures{ MaxSize: MaxFileSize, }, }, - MaxTextLength: MaxTextLength, // TODO support arbitrary sized text messages with files - LocationMessage: event.CapLevelPartialSupport, - Poll: event.CapLevelRejected, - Thread: event.CapLevelUnsupported, - Reply: event.CapLevelFullySupported, - Edit: event.CapLevelFullySupported, - EditMaxCount: 10, - EditMaxAge: ptr.Ptr(jsontime.S(24 * time.Hour)), - Delete: event.CapLevelFullySupported, - DeleteForMe: false, - DeleteMaxAge: ptr.Ptr(jsontime.S(24 * time.Hour)), - DisappearingTimer: &event.DisappearingTimerCapability{ - Types: []event.DisappearingType{event.DisappearingTypeAfterRead}, - }, + MaxTextLength: MaxTextLength, // TODO support arbitrary sized text messages with files + LocationMessage: event.CapLevelPartialSupport, + Poll: event.CapLevelRejected, + Thread: event.CapLevelUnsupported, + Reply: event.CapLevelFullySupported, + Edit: event.CapLevelFullySupported, + EditMaxCount: 10, + EditMaxAge: ptr.Ptr(jsontime.S(24 * time.Hour)), + Delete: event.CapLevelFullySupported, + DeleteForMe: false, + DeleteMaxAge: ptr.Ptr(jsontime.S(24 * time.Hour)), + DisappearingTimer: signalDisappearingCap, Reaction: event.CapLevelFullySupported, ReactionCount: 1, @@ -159,6 +157,10 @@ var signalCaps = &event.RoomFeatures{ TypingNotifications: true, } +var signalDisappearingCap = &event.DisappearingTimerCapability{ + Types: []event.DisappearingType{event.DisappearingTypeAfterRead}, +} + var signalCapsNoteToSelf *event.RoomFeatures func init() { @@ -178,6 +180,24 @@ func (s *SignalClient) GetCapabilities(ctx context.Context, portal *bridgev2.Por var signalGeneralCaps = &bridgev2.NetworkGeneralCapabilities{ DisappearingMessages: true, AggressiveUpdateInfo: true, + Provisioning: bridgev2.ProvisioningCapabilities{ + ResolveIdentifier: bridgev2.ResolveIdentifierCapabilities{ + CreateDM: true, + LookupPhone: true, + LookupUsername: false, // TODO implement + ContactList: true, + }, + GroupCreation: map[string]bridgev2.GroupTypeCapabilities{ + "group": { + TypeDescription: "a group chat", + + Name: bridgev2.GroupFieldCapability{Allowed: true, Required: true, MaxLength: 32}, + Avatar: bridgev2.GroupFieldCapability{Allowed: true}, + Disappear: bridgev2.GroupFieldCapability{Allowed: true, DisappearSettings: signalDisappearingCap}, + Participants: bridgev2.GroupFieldCapability{Allowed: true}, + }, + }, + }, } func (s *SignalConnector) GetCapabilities() *bridgev2.NetworkGeneralCapabilities { diff --git a/pkg/connector/chatinfo.go b/pkg/connector/chatinfo.go index d4d1013..4b72ad0 100644 --- a/pkg/connector/chatinfo.go +++ b/pkg/connector/chatinfo.go @@ -32,6 +32,7 @@ import ( "maunium.net/go/mautrix/bridgev2/database" "maunium.net/go/mautrix/bridgev2/networkid" "maunium.net/go/mautrix/event" + "maunium.net/go/mautrix/id" "go.mau.fi/mautrix-signal/pkg/libsignalgo" "go.mau.fi/mautrix-signal/pkg/signalid" @@ -236,9 +237,107 @@ func (s *SignalClient) ResolveIdentifier(ctx context.Context, number string, cre } } -func (s *SignalClient) CreateGroup(ctx context.Context, name string, users ...networkid.UserID) (*bridgev2.CreateChatResponse, error) { - //TODO implement me - return nil, fmt.Errorf("not implemented") +func (s *SignalClient) CreateGroup(ctx context.Context, params *bridgev2.GroupCreateParams) (*bridgev2.CreateChatResponse, error) { + group := &signalmeow.Group{ + Title: ptr.Val(params.Name).Name, + Members: make([]*signalmeow.GroupMember, len(params.Participants)+1), + Description: ptr.Val(params.Topic).Topic, + AnnouncementsOnly: false, + DisappearingMessagesDuration: uint32(ptr.Val(params.Disappear).Timer.Seconds()), + AccessControl: &signalmeow.GroupAccessControl{ + Members: signalmeow.AccessControl_MEMBER, + AddFromInviteLink: signalmeow.AccessControl_UNSATISFIABLE, + Attributes: signalmeow.AccessControl_ADMINISTRATOR, + }, + } + var pl *event.PowerLevelsEventContent + // TODO actually get PLs + if pl != nil { + if pl.EventsDefault > pl.UsersDefault { + group.AnnouncementsOnly = true + } + if pl.Invite() > pl.UsersDefault { + group.AccessControl.Members = signalmeow.AccessControl_ADMINISTRATOR + } + if pl.GetEventLevel(event.StateRoomName) <= pl.UsersDefault { + group.AccessControl.Attributes = signalmeow.AccessControl_MEMBER + } + } + group.Members[0] = &signalmeow.GroupMember{ + ACI: s.Client.Store.ACI, + Role: signalmeow.GroupMember_ADMINISTRATOR, + } + for i, member := range params.Participants { + userID, err := signalid.ParseUserID(member) + if err != nil { + return nil, fmt.Errorf("invalid user ID %q: %w", member, err) + } + group.Members[i+1] = &signalmeow.GroupMember{ + ACI: userID, + Role: signalmeow.GroupMember_DEFAULT, // TODO set proper role from power levels + } + } + _, err := signalmeow.PrepareGroupCreation(group) + if err != nil { + return nil, fmt.Errorf("failed to prepare group creation: %w", err) + } + var avatarBytes []byte + var avatarMXC id.ContentURIString + if params.Avatar != nil { + avatarMXC = params.Avatar.URL + avatarBytes, err = s.Main.Bridge.Bot.DownloadMedia(ctx, params.Avatar.URL, params.Avatar.MSC3414File) + if err != nil { + return nil, fmt.Errorf("failed to download avatar: %w", err) + } + group.AvatarPath, err = s.Client.UploadGroupAvatar(ctx, avatarBytes, group.GroupIdentifier) + if err != nil { + return nil, fmt.Errorf("failed to upload avatar: %w", err) + } + } + portal, err := s.Main.Bridge.GetPortalByKey(ctx, s.makePortalKey(string(group.GroupIdentifier))) + if err != nil { + return nil, fmt.Errorf("failed to get portal: %w", err) + } + if params.RoomID != "" { + err = portal.UpdateMatrixRoomID(ctx, params.RoomID, bridgev2.UpdateMatrixRoomIDParams{SyncDBMetadata: func() { + portal.Name = group.Title + portal.NameSet = true + portal.Topic = group.Description + portal.TopicSet = true + portal.AvatarHash = sha256.Sum256(avatarBytes) + portal.AvatarSet = true + portal.AvatarMXC = avatarMXC + portal.AvatarID = makeAvatarPathID(group.AvatarPath) + if group.DisappearingMessagesDuration > 0 { + portal.Disappear = database.DisappearingSetting{ + Type: event.DisappearingTypeAfterRead, + Timer: time.Duration(group.DisappearingMessagesDuration) * time.Second, + } + } + }}) + if err != nil { + return nil, fmt.Errorf("failed to set portal room ID: %w", err) + } + } + resp, err := s.Client.CreateGroup(ctx, group, avatarBytes) + if err != nil { + return nil, fmt.Errorf("failed to create group: %w", err) + } + if params.RoomID != "" { + // UpdateMatrixRoomID could do this for us if we passed ChatInfoSource to it, + // but we only want to do it after the group is successfully created + portal.UpdateBridgeInfo(ctx) + portal.UpdateCapabilities(ctx, s.UserLogin, true) + } + wrappedInfo, err := s.wrapGroupInfo(ctx, resp, nil) + if err != nil { + return nil, fmt.Errorf("failed to wrap group info for sync: %w", err) + } + return &bridgev2.CreateChatResponse{ + PortalKey: portal.PortalKey, + Portal: portal, + PortalInfo: wrappedInfo, + }, nil } func (s *SignalClient) GetContactList(ctx context.Context) ([]*bridgev2.ResolveIdentifierResponse, error) { diff --git a/pkg/connector/groupinfo.go b/pkg/connector/groupinfo.go index 3b5fbcd..857031f 100644 --- a/pkg/connector/groupinfo.go +++ b/pkg/connector/groupinfo.go @@ -101,6 +101,10 @@ func (s *SignalClient) getGroupInfo(ctx context.Context, groupID types.GroupIden if err != nil { return nil, fmt.Errorf("failed to retrieve group by id: %w", err) } + return s.wrapGroupInfo(ctx, groupInfo, backupChat) +} + +func (s *SignalClient) wrapGroupInfo(ctx context.Context, groupInfo *signalmeow.Group, backupChat *store.BackupChat) (*bridgev2.ChatInfo, error) { members := &bridgev2.ChatMemberList{ IsFull: true, MemberMap: make(map[networkid.UserID]bridgev2.ChatMember, len(groupInfo.Members)+len(groupInfo.PendingMembers)+len(groupInfo.RequestingMembers)+len(groupInfo.BannedMembers)), @@ -156,13 +160,14 @@ func (s *SignalClient) getGroupInfo(ctx context.Context, groupID types.GroupIden } } if backupChat == nil { + var err error // TODO allow using backup chat for data too instead of asking server? - backupChat, err = s.Client.Store.BackupStore.GetBackupChatByGroupID(ctx, groupID) + backupChat, err = s.Client.Store.BackupStore.GetBackupChatByGroupID(ctx, groupInfo.GroupIdentifier) if err != nil { zerolog.Ctx(ctx).Warn().Err(err).Msg("Failed to get backup chat for group") } } - avatar, err := s.makeGroupAvatar(ctx, groupID, &groupInfo.AvatarPath, groupInfo.GroupMasterKey) + avatar, err := s.makeGroupAvatar(ctx, groupInfo.GroupIdentifier, &groupInfo.AvatarPath, groupInfo.GroupMasterKey) if err != nil { return nil, fmt.Errorf("failed to make group avatar: %w", err) } diff --git a/pkg/connector/handlematrix.go b/pkg/connector/handlematrix.go index 977e22f..614795a 100644 --- a/pkg/connector/handlematrix.go +++ b/pkg/connector/handlematrix.go @@ -365,11 +365,10 @@ func (s *SignalClient) HandleMatrixRoomAvatar(ctx context.Context, msg *bridgev2 return false, fmt.Errorf("failed to download avatar: %w", err) } avatarHash = sha256.Sum256(data) - avatarPathPtr, err := s.Client.UploadGroupAvatar(ctx, data, groupID) + avatarPath, err = s.Client.UploadGroupAvatar(ctx, data, groupID) if err != nil { return false, fmt.Errorf("failed to reupload avatar: %w", err) } - avatarPath = *avatarPathPtr } return s.handleMatrixRoomMeta(ctx, msg.Portal, &signalmeow.GroupChange{ ModifyAvatar: &avatarPath, diff --git a/pkg/signalmeow/attachments.go b/pkg/signalmeow/attachments.go index e321f57..ea03c21 100644 --- a/pkg/signalmeow/attachments.go +++ b/pkg/signalmeow/attachments.go @@ -280,28 +280,28 @@ func (cli *Client) uploadAttachmentTUS( return nil } -func (cli *Client) UploadGroupAvatar(ctx context.Context, avatarBytes []byte, gid types.GroupIdentifier) (*string, error) { +func (cli *Client) UploadGroupAvatar(ctx context.Context, avatarBytes []byte, gid types.GroupIdentifier) (string, error) { log := zerolog.Ctx(ctx) groupMasterKey, err := cli.Store.GroupStore.MasterKeyFromGroupIdentifier(ctx, gid) if err != nil { log.Err(err).Msg("Could not get master key from group id") - return nil, err + return "", err } groupAuth, err := cli.GetAuthorizationForToday(ctx, masterKeyToBytes(groupMasterKey)) if err != nil { log.Err(err).Msg("Failed to get Authorization for today") - return nil, err + return "", err } groupSecretParams, err := libsignalgo.DeriveGroupSecretParamsFromMasterKey(masterKeyToBytes(groupMasterKey)) if err != nil { log.Err(err).Msg("Could not get groupSecretParams from master key") - return nil, err + return "", err } attributeBlob := signalpb.GroupAttributeBlob{Content: &signalpb.GroupAttributeBlob_Avatar{Avatar: avatarBytes}} encryptedAvatar, err := encryptBlobIntoGroupProperty(groupSecretParams, &attributeBlob) if err != nil { log.Err(err).Msg("Could not encrypt avatar into Group Property") - return nil, err + return "", err } // Get upload form from Signal server @@ -310,18 +310,18 @@ func (cli *Client) UploadGroupAvatar(ctx context.Context, avatarBytes []byte, gi resp, err := web.SendHTTPRequest(ctx, http.MethodGet, formPath, opts) if err != nil { log.Err(err).Msg("Error sending request fetching avatar upload form") - return nil, err + return "", err } body, err := io.ReadAll(resp.Body) if err != nil { log.Err(err).Msg("Error decoding response body fetching upload attributes") - return nil, err + return "", err } uploadForm := signalpb.AvatarUploadAttributes{} err = proto.Unmarshal(body, &uploadForm) if err != nil { log.Err(err).Msg("failed to unmarshal group avatar upload form") - return nil, err + return "", err } requestBody := &bytes.Buffer{} w := multipart.NewWriter(requestBody) @@ -345,14 +345,14 @@ func (cli *Client) UploadGroupAvatar(ctx context.Context, avatarBytes []byte, gi }) if err != nil { log.Err(err).Msg("Error sending request uploading attachment") - return nil, err + return "", err } if resp.StatusCode < 200 || resp.StatusCode >= 300 { log.Error().Int("status_code", resp.StatusCode).Msg("Error uploading attachment") - return nil, fmt.Errorf("error uploading attachment: %s", resp.Status) + return "", fmt.Errorf("error uploading attachment: %s", resp.Status) } - return &uploadForm.Key, nil + return uploadForm.Key, nil } func verifyMAC(key, body, mac []byte) bool { diff --git a/pkg/signalmeow/groups.go b/pkg/signalmeow/groups.go index 8c0a841..865de3f 100644 --- a/pkg/signalmeow/groups.go +++ b/pkg/signalmeow/groups.go @@ -18,7 +18,6 @@ package signalmeow import ( "context" - "crypto/rand" "encoding/base64" "encoding/hex" "encoding/json" @@ -32,6 +31,8 @@ import ( "github.com/google/uuid" "github.com/rs/zerolog" + "go.mau.fi/util/ptr" + "go.mau.fi/util/random" "google.golang.org/protobuf/proto" "go.mau.fi/mautrix-signal/pkg/libsignalgo" @@ -1558,10 +1559,7 @@ func (cli *Client) UpdateGroup(ctx context.Context, groupChange *GroupChange, gi log.Err(err).Msg("Failed to retrieve Group") } if group.InviteLinkPassword == nil && groupChange.ModifyAddFromInviteLinkAccess != nil && groupChange.ModifyInviteLinkPassword != nil { - inviteLinkPasswordBytes := make([]byte, 16) - rand.Read(inviteLinkPasswordBytes) - inviteLinkPassword := InviteLinkPasswordFromBytes(inviteLinkPasswordBytes) - groupChange.ModifyInviteLinkPassword = &inviteLinkPassword + groupChange.ModifyInviteLinkPassword = ptr.Ptr(GenerateInviteLinkPassword()) } groupChange.Revision = group.Revision + 1 for attempt := 0; attempt < 5; attempt++ { @@ -1644,9 +1642,7 @@ func (cli *Client) EncryptGroup(ctx context.Context, decryptedGroup *Group, grou AddFromInviteLink: signalpb.AccessControl_AccessRequired(decryptedGroup.AccessControl.AddFromInviteLink), } if decryptedGroup.AccessControl.AddFromInviteLink != AccessControl_UNSATISFIABLE { - inviteLinkPasswordBytes := make([]byte, 16) - rand.Read(inviteLinkPasswordBytes) - encryptedGroup.InviteLinkPassword = inviteLinkPasswordBytes + encryptedGroup.InviteLinkPassword = random.Bytes(16) } } for _, member := range decryptedGroup.Members { @@ -1671,41 +1667,52 @@ func (cli *Client) EncryptGroup(ctx context.Context, decryptedGroup *Group, grou return encryptedGroup, nil } +func PrepareGroupCreation(decryptedGroup *Group) (libsignalgo.GroupMasterKey, error) { + var masterKeyBytes libsignalgo.GroupMasterKey + if decryptedGroup.GroupMasterKey == "" { + masterKeyBytes = libsignalgo.GroupMasterKey(random.Bytes(32)) + decryptedGroup.GroupMasterKey = masterKeyFromBytes(masterKeyBytes) + } else { + masterKeyBytes = masterKeyToBytes(decryptedGroup.GroupMasterKey) + } + if decryptedGroup.GroupIdentifier == "" { + var err error + decryptedGroup.GroupIdentifier, err = groupIdentifierFromMasterKey(decryptedGroup.GroupMasterKey) + if err != nil { + return masterKeyBytes, err + } + } + return masterKeyBytes, nil +} + func (cli *Client) createGroupOnServer(ctx context.Context, decryptedGroup *Group, avatarBytes []byte) (*Group, error) { log := zerolog.Ctx(ctx).With().Str("action", "CreateGroupOnServer").Logger() - masterKeyByteArray := make([]byte, 32) - rand.Read(masterKeyByteArray) - masterKeyBytes := libsignalgo.GroupMasterKey(masterKeyByteArray) - groupMasterKey := masterKeyFromBytes(masterKeyBytes) - groupId, err := groupIdentifierFromMasterKey(groupMasterKey) + masterKeyBytes, err := PrepareGroupCreation(decryptedGroup) if err != nil { - log.Err(err).Msg("Couldn't get gid from masterkey") return nil, err } - err = cli.Store.GroupStore.StoreMasterKey(ctx, groupId, groupMasterKey) + err = cli.Store.GroupStore.StoreMasterKey(ctx, decryptedGroup.GroupIdentifier, decryptedGroup.GroupMasterKey) if err != nil { return nil, fmt.Errorf("StoreMasterKey error: %w", err) } - log.Debug().Msg(string(groupMasterKey)) groupSecretParams, err := libsignalgo.DeriveGroupSecretParamsFromMasterKey(masterKeyBytes) if err != nil { log.Err(err).Msg("DeriveGroupSecretParamsFromMasterKey error") return nil, err } if len(avatarBytes) > 0 { - avatarPath, err := cli.UploadGroupAvatar(ctx, avatarBytes, groupId) + avatarPath, err := cli.UploadGroupAvatar(ctx, avatarBytes, decryptedGroup.GroupIdentifier) if err != nil { log.Err(err).Msg("Failed to upload group avatar") return nil, err } - decryptedGroup.AvatarPath = *avatarPath + decryptedGroup.AvatarPath = avatarPath } encryptedGroup, err := cli.EncryptGroup(ctx, decryptedGroup, groupSecretParams) if err != nil { log.Err(err).Msg("Failed to encrypt group") return nil, err } - log.Debug().Stringer("groupID", groupId) groupAuth, err := cli.GetAuthorizationForToday(ctx, masterKeyBytes) if err != nil { log.Err(err).Msg("Failed to get Authorization for today") @@ -1744,18 +1751,15 @@ func (cli *Client) createGroupOnServer(ctx context.Context, decryptedGroup *Grou case http.StatusBadRequest: return nil, fmt.Errorf("failed to put new group: bad request") } - group, err := cli.fetchGroupWithMasterKey(ctx, groupMasterKey) + group, err := cli.fetchGroupWithMasterKey(ctx, decryptedGroup.GroupMasterKey) if err != nil { return nil, fmt.Errorf("failed to get new group: %w", err) } - log.Debug().Stringer("group id", group.GroupIdentifier).Msg("new group created") return group, nil } func GenerateInviteLinkPassword() types.SerializedInviteLinkPassword { - inviteLinkPasswordBytes := make([]byte, 16) - rand.Read(inviteLinkPasswordBytes) - return InviteLinkPasswordFromBytes(inviteLinkPasswordBytes) + return InviteLinkPasswordFromBytes(random.Bytes(16)) } func (cli *Client) CreateGroup(ctx context.Context, decryptedGroup *Group, avatarBytes []byte) (*Group, error) { diff --git a/pkg/signalmeow/profile.go b/pkg/signalmeow/profile.go index 3aa88ff..81f1ed8 100644 --- a/pkg/signalmeow/profile.go +++ b/pkg/signalmeow/profile.go @@ -21,7 +21,6 @@ import ( "context" "crypto/aes" "crypto/cipher" - "crypto/rand" "encoding/base64" "encoding/hex" "encoding/json" @@ -35,6 +34,7 @@ import ( "github.com/google/uuid" "github.com/rs/zerolog" + "go.mau.fi/util/random" "go.mau.fi/mautrix-signal/pkg/libsignalgo" "go.mau.fi/mautrix-signal/pkg/signalmeow/types" @@ -338,8 +338,7 @@ func encryptString(key libsignalgo.ProfileKey, plaintext string, paddedLength in return nil, errors.New("plaintext longer than paddedLength") } padded := append([]byte(plaintext), make([]byte, paddedLength-inputLength)...) - nonce := make([]byte, NONCE_LENGTH) - rand.Read(nonce) + nonce := random.Bytes(NONCE_LENGTH) keyBytes := key[:] ciphertext, err := AesgcmEncrypt(keyBytes, nonce, padded) if err != nil { From b2c6eaf6f9fa900858aa045de8a05086b05e1915 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Tue, 9 Sep 2025 16:00:27 +0300 Subject: [PATCH 401/580] msgconv/from-signal: don't bridge redundant disappear timer changes --- pkg/msgconv/from-signal.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pkg/msgconv/from-signal.go b/pkg/msgconv/from-signal.go index b4f1b56..41ad2ec 100644 --- a/pkg/msgconv/from-signal.go +++ b/pkg/msgconv/from-signal.go @@ -190,8 +190,9 @@ func (mc *MessageConverter) ConvertDisappearingTimerChangeToMatrix(ctx context.C Type: event.DisappearingTypeAfterRead, } if timer == 0 { - portal.Disappear.Type = "" + setting.Type = "" } + part.DontBridge = setting == portal.Disappear if timerVersion != nil { portalMeta.ExpirationTimerVersion = *timerVersion } else { From e3ecc7c0b201546b39521945f427b9f3ae5fde69 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Tue, 9 Sep 2025 16:27:03 +0300 Subject: [PATCH 402/580] msgconv/from-signal: add action message metadata to disappearing notices --- go.mod | 2 +- go.sum | 4 ++-- pkg/msgconv/from-signal.go | 26 +++++++++++++++++--------- 3 files changed, 20 insertions(+), 12 deletions(-) diff --git a/go.mod b/go.mod index bf104b0..00b8bdc 100644 --- a/go.mod +++ b/go.mod @@ -18,7 +18,7 @@ require ( golang.org/x/net v0.43.0 google.golang.org/protobuf v1.36.7 gopkg.in/yaml.v3 v3.0.1 - maunium.net/go/mautrix v0.25.1-0.20250902152424-709f48f2b370 + maunium.net/go/mautrix v0.25.1-0.20250909132418-41bbe4ace4c7 ) require ( diff --git a/go.sum b/go.sum index e4402d2..390cf40 100644 --- a/go.sum +++ b/go.sum @@ -95,5 +95,5 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= maunium.net/go/mauflag v1.0.0 h1:YiaRc0tEI3toYtJMRIfjP+jklH45uDHtT80nUamyD4M= maunium.net/go/mauflag v1.0.0/go.mod h1:nLivPOpTpHnpzEh8jEdSL9UqO9+/KBJFmNRlwKfkPeA= -maunium.net/go/mautrix v0.25.1-0.20250902152424-709f48f2b370 h1:1rz6V3P38i2qSJKEe0QBXozfI/9yaM/zWrZPDrtKVYQ= -maunium.net/go/mautrix v0.25.1-0.20250902152424-709f48f2b370/go.mod h1:pDd6Ppg+1PbWrw/rg4ZQQfVYZICRGzH+DcliZ/BODvU= +maunium.net/go/mautrix v0.25.1-0.20250909132418-41bbe4ace4c7 h1:TywnMUPZakwE9oU1jPC8pVZk3q5dP66LkyOQ5Z+e7cI= +maunium.net/go/mautrix v0.25.1-0.20250909132418-41bbe4ace4c7/go.mod h1:pDd6Ppg+1PbWrw/rg4ZQQfVYZICRGzH+DcliZ/BODvU= diff --git a/pkg/msgconv/from-signal.go b/pkg/msgconv/from-signal.go index 41ad2ec..1606245 100644 --- a/pkg/msgconv/from-signal.go +++ b/pkg/msgconv/from-signal.go @@ -171,11 +171,27 @@ func (mc *MessageConverter) ToMatrix( } func (mc *MessageConverter) ConvertDisappearingTimerChangeToMatrix(ctx context.Context, timer uint32, timerVersion *uint32, ts time.Time) *bridgev2.ConvertedMessagePart { + portal := getPortal(ctx) + setting := database.DisappearingSetting{ + Timer: time.Duration(timer) * time.Second, + Type: event.DisappearingTypeAfterRead, + } + if timer == 0 { + setting.Type = "" + } part := &bridgev2.ConvertedMessagePart{ Type: event.EventMessage, Content: bridgev2.DisappearingMessageNotice(time.Duration(timer)*time.Second, false), + Extra: map[string]any{ + "com.beeper.action_message": map[string]any{ + "type": "disappearing_timer", + "timer": setting.Timer.Milliseconds(), + "timer_type": setting.Type, + "implicit": false, + }, + }, + DontBridge: setting == portal.Disappear, } - portal := getPortal(ctx) portalMeta := portal.Metadata.(*signalid.PortalMetadata) if timerVersion != nil && portalMeta.ExpirationTimerVersion > *timerVersion { zerolog.Ctx(ctx).Warn(). @@ -185,14 +201,6 @@ func (mc *MessageConverter) ConvertDisappearingTimerChangeToMatrix(ctx context.C part.Content.Body += " (change ignored)" return part } - setting := database.DisappearingSetting{ - Timer: time.Duration(timer) * time.Second, - Type: event.DisappearingTypeAfterRead, - } - if timer == 0 { - setting.Type = "" - } - part.DontBridge = setting == portal.Disappear if timerVersion != nil { portalMeta.ExpirationTimerVersion = *timerVersion } else { From 09846af725e3580f3c7f1008acd10d315ad3e7f3 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Fri, 12 Sep 2025 13:38:50 +0300 Subject: [PATCH 403/580] legacy{migrate,provision}: delete Except keep start chat endpoints --- cmd/mautrix-signal/legacymigrate.go | 49 ------ cmd/mautrix-signal/legacymigrate.sql | 181 ---------------------- cmd/mautrix-signal/legacyprovision.go | 211 -------------------------- cmd/mautrix-signal/main.go | 17 --- go.mod | 2 +- go.sum | 4 +- 6 files changed, 3 insertions(+), 461 deletions(-) delete mode 100644 cmd/mautrix-signal/legacymigrate.go delete mode 100644 cmd/mautrix-signal/legacymigrate.sql diff --git a/cmd/mautrix-signal/legacymigrate.go b/cmd/mautrix-signal/legacymigrate.go deleted file mode 100644 index 377b5af..0000000 --- a/cmd/mautrix-signal/legacymigrate.go +++ /dev/null @@ -1,49 +0,0 @@ -// mautrix-signal - A Matrix-Signal puppeting bridge. -// Copyright (C) 2024 Tulir Asokan -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see . - -package main - -import ( - _ "embed" - - up "go.mau.fi/util/configupgrade" - - "maunium.net/go/mautrix/bridgev2/bridgeconfig" -) - -const legacyMigrateRenameTables = ` -ALTER TABLE portal RENAME TO portal_old; -ALTER TABLE puppet RENAME TO puppet_old; -ALTER TABLE "user" RENAME TO user_old; -ALTER TABLE user_portal RENAME TO user_portal_old; -ALTER TABLE message RENAME TO message_old; -ALTER TABLE reaction RENAME TO reaction_old; -ALTER TABLE disappearing_message RENAME TO disappearing_message_old; -` - -//go:embed legacymigrate.sql -var legacyMigrateCopyData string - -func migrateLegacyConfig(helper up.Helper) { - helper.Set(up.Str, "mautrix.bridge.e2ee", "encryption", "pickle_key") - bridgeconfig.CopyToOtherLocation(helper, up.Str, []string{"bridge", "displayname_template"}, []string{"network", "displayname_template"}) - bridgeconfig.CopyToOtherLocation(helper, up.Str, []string{"bridge", "note_to_self_avatar"}, []string{"network", "note_to_self_avatar"}) - bridgeconfig.CopyToOtherLocation(helper, up.Str, []string{"bridge", "location_format"}, []string{"network", "location_format"}) - bridgeconfig.CopyToOtherLocation(helper, up.Bool, []string{"bridge", "use_contact_avatars"}, []string{"network", "use_contact_avatars"}) - bridgeconfig.CopyToOtherLocation(helper, up.Bool, []string{"bridge", "use_outdated_profiles"}, []string{"network", "use_outdated_profiles"}) - bridgeconfig.CopyToOtherLocation(helper, up.Bool, []string{"bridge", "number_in_topic"}, []string{"network", "number_in_topic"}) - bridgeconfig.CopyToOtherLocation(helper, up.Str, []string{"signal", "device_name"}, []string{"network", "device_name"}) -} diff --git a/cmd/mautrix-signal/legacymigrate.sql b/cmd/mautrix-signal/legacymigrate.sql deleted file mode 100644 index cbf06e3..0000000 --- a/cmd/mautrix-signal/legacymigrate.sql +++ /dev/null @@ -1,181 +0,0 @@ -INSERT INTO "user" (bridge_id, mxid, management_room, access_token) -SELECT '', mxid, management_room, NULL -FROM user_old; - -INSERT INTO user_login (bridge_id, user_mxid, id, remote_name, space_room, metadata) -SELECT - '', - mxid, - cast(uuid AS TEXT), - phone, -- remote_name - space_room, - CAST( - '{"phone":"' || phone || '"}' - -- only: postgres - AS jsonb - -- only: sqlite (line commented) --- AS text - ) -FROM user_old WHERE uuid IS NOT NULL AND phone IS NOT NULL; - -INSERT INTO portal ( - bridge_id, id, receiver, mxid, parent_id, parent_receiver, relay_bridge_id, relay_login_id, other_user_id, - name, topic, avatar_id, avatar_hash, avatar_mxc, - name_set, avatar_set, topic_set, name_is_custom, in_space, - room_type, disappear_type, disappear_timer, metadata -) -SELECT - '', -- bridge_id - chat_id, -- id - CASE - WHEN receiver='00000000-0000-0000-0000-000000000000' THEN '' - ELSE CAST(receiver AS TEXT) - END, -- receiver - mxid, - NULL, -- parent_id - '', -- parent_receiver - CASE WHEN portal_old.relay_user_id<>'' THEN '' END, -- relay_bridge_id - CASE WHEN portal_old.relay_user_id<>'' THEN (SELECT id FROM user_login WHERE user_mxid=portal_old.relay_user_id) END, -- relay_login_id - CASE WHEN LENGTH(chat_id)=44 THEN NULL ELSE chat_id END, -- other_user_id - name, - topic, - CASE - WHEN avatar_path='notetoself' THEN avatar_url - WHEN avatar_path<>'' THEN ('path:' || avatar_path) - WHEN avatar_hash<>'' THEN ('hash:' || avatar_hash) - ELSE '' - END, -- avatar_id - avatar_hash, -- avatar_hash - avatar_url, -- avatar_mxc - name_set, - avatar_set, - topic_set, - CASE WHEN LENGTH(chat_id)=44 THEN true ELSE false END, -- name_is_custom - false, -- in_space - CASE WHEN LENGTH(chat_id)=44 THEN '' ELSE 'dm' END, -- room_type - CASE WHEN expiration_time<>0 THEN 'after_read' END, - CASE WHEN expiration_time<>0 THEN expiration_time * 1000000000 END, - CAST( - '{"revision":' || revision || '}' - -- only: postgres - AS jsonb - -- only: sqlite (line commented) --- AS text - ) -- metadata -FROM portal_old; - -INSERT INTO ghost ( - bridge_id, id, name, avatar_id, avatar_hash, avatar_mxc, - name_set, avatar_set, contact_info_set, - is_bot, identifiers, metadata -) -SELECT - '', -- bridge_id - cast(uuid AS TEXT), -- id - name, - CASE - WHEN avatar_path<>'' THEN ('path:' || avatar_path) - WHEN avatar_hash<>'' THEN ('hash:' || avatar_hash) - ELSE '' - END, -- avatar_id - avatar_hash, -- avatar_hash - avatar_url, -- avatar_mxc - name_set, - avatar_set, - contact_info_set, - false, -- is_bot - '[]', -- identifiers - CAST( - CASE - WHEN profile_fetched_at IS NOT NULL THEN ('{"profile_fetched_at":' || profile_fetched_at || '}') - ELSE '{}' - END - -- only: postgres - AS jsonb - -- only: sqlite (line commented) --- AS text - ) -- metadata -FROM puppet_old; - -INSERT INTO message ( - bridge_id, id, part_id, mxid, room_id, room_receiver, - sender_id, sender_mxid, timestamp, edit_count, metadata -) -SELECT - '', -- bridge_id - cast(sender AS TEXT) || '|' || timestamp, -- id - CASE WHEN part_index=0 THEN '' ELSE CAST(part_index AS TEXT) END, -- part_id - mxid, - signal_chat_id, -- room_id - CASE - WHEN signal_receiver='00000000-0000-0000-0000-000000000000' THEN '' - ELSE cast(signal_receiver AS TEXT) - END, -- room_receiver - cast(sender AS TEXT), -- sender_id - '', -- sender_mxid - timestamp * 1000000, - 0, -- edit_count - '{}' -- metadata -FROM message_old; - -INSERT INTO disappearing_message ( - bridge_id, mx_room, mxid, type, timer, disappear_at -) -SELECT - '', -- bridge_id - room_id, -- mx_room - mxid, - 'after_read', -- type - expiration_seconds * 1000000000, -- timer - CASE WHEN expiration_ts IS NOT NULL THEN expiration_ts * 1000000000 END -- disappear_at -FROM disappearing_message_old -WHERE expiration_ts < 9000000000 - AND room_id IN (SELECT mxid FROM portal WHERE mxid IS NOT NULL); - -INSERT INTO reaction ( - bridge_id, message_id, message_part_id, sender_id, emoji_id, emoji, - room_id, room_receiver, mxid, timestamp, metadata -) -SELECT - '', -- bridge_id - cast(msg_author AS TEXT) || '|' || msg_timestamp, -- message_id - '', -- message_part_id - cast(author AS TEXT), -- sender_id - '', -- emoji_id - emoji, - signal_chat_id, -- room_id - CASE - WHEN signal_receiver='00000000-0000-0000-0000-000000000000' THEN '' - ELSE cast(signal_receiver AS TEXT) - END, -- room_receiver - mxid, - msg_timestamp * 1000000, -- timestamp (actual reaction timestamp not available) - '{}' -- metadata -FROM reaction_old; - -INSERT INTO user_portal ( - bridge_id, user_mxid, login_id, portal_id, portal_receiver, in_space, preferred, last_read -) -SELECT - '', -- bridge_id - user_mxid, - cast(user_old.uuid AS TEXT), -- login_id - portal_chat_id, -- portal_id - CASE - WHEN portal_receiver='00000000-0000-0000-0000-000000000000' THEN '' - ELSE cast(portal_receiver AS TEXT) - END, -- portal_receiver - in_space, - false, -- preferred - CASE WHEN last_read_ts = 0 THEN NULL ELSE last_read_ts * 1000000 END -- last_read -FROM user_portal_old -LEFT JOIN user_old ON user_old.mxid = user_portal_old.user_mxid -WHERE user_old.uuid IS NOT NULL; - -DROP TABLE disappearing_message_old; -DROP TABLE reaction_old; -DROP TABLE user_portal_old; -DROP TABLE message_old; -DROP TABLE puppet_old; -DROP TABLE portal_old; -DROP TABLE user_old; diff --git a/cmd/mautrix-signal/legacyprovision.go b/cmd/mautrix-signal/legacyprovision.go index 6bd6882..c9061ac 100644 --- a/cmd/mautrix-signal/legacyprovision.go +++ b/cmd/mautrix-signal/legacyprovision.go @@ -17,197 +17,16 @@ package main import ( - "context" "encoding/json" "fmt" "net/http" - "strconv" - "sync" - "sync/atomic" "github.com/rs/zerolog" "maunium.net/go/mautrix" "maunium.net/go/mautrix/bridgev2" - "maunium.net/go/mautrix/bridgev2/status" "maunium.net/go/mautrix/id" - - "go.mau.fi/mautrix-signal/pkg/connector" ) -var legacyProvisionHandleID atomic.Uint32 -var loginSessions = make(map[uint32]*legacyLoginProcess) -var loginSessionsLock sync.Mutex - -type legacyLoginProcess struct { - ID uint32 - Login bridgev2.LoginProcess - User *bridgev2.User -} - -func (llp *legacyLoginProcess) Delete() { - loginSessionsLock.Lock() - delete(loginSessions, llp.ID) - loginSessionsLock.Unlock() -} - -func legacyProvLinkNew(w http.ResponseWriter, r *http.Request) { - handleID := legacyProvisionHandleID.Add(1) - user := m.Matrix.Provisioning.GetUser(r) - defLogin := user.GetDefaultLogin() - if defLogin != nil && defLogin.Client != nil && defLogin.Client.IsLoggedIn() { - JSONResponse(w, http.StatusConflict, &Error{ - Error: "Already logged in", - ErrCode: "FI.MAU.ALREADY_LOGGED_IN", - }) - return - } - log := zerolog.Ctx(r.Context()) - login, err := m.Connector.CreateLogin(r.Context(), user, "qr") - if err != nil { - log.Err(err).Msg("Failed to create login") - JSONResponse(w, http.StatusInternalServerError, &Error{ - Error: "Internal error starting login", - ErrCode: "M_UNKNOWN", - }) - return - } - firstStep, err := login.Start(r.Context()) - if err != nil { - log.Err(err).Msg("Failed to start login") - JSONResponse(w, http.StatusInternalServerError, &Error{ - Error: "Internal error starting login", - ErrCode: "M_UNKNOWN", - }) - return - } else if firstStep.StepID != connector.LoginStepQR || firstStep.Type != bridgev2.LoginStepTypeDisplayAndWait || firstStep.DisplayAndWaitParams.Type != bridgev2.LoginDisplayTypeQR { - log.Error().Any("first_step", firstStep).Msg("Unexpected first step") - JSONResponse(w, http.StatusInternalServerError, &Error{ - Error: "Unexpected first login step", - ErrCode: "M_UNKNOWN", - }) - return - } - loginSessionsLock.Lock() - loginSessions[handleID] = &legacyLoginProcess{ - ID: handleID, - Login: login, - User: user, - } - loginSessionsLock.Unlock() - JSONResponse(w, http.StatusOK, Response{ - Success: true, - Status: "provisioning_url_received", - SessionID: strconv.Itoa(int(handleID)), - URI: firstStep.DisplayAndWaitParams.Data, - }) -} - -func getLoginProcess(w http.ResponseWriter, r *http.Request) *legacyLoginProcess { - var body LinkWaitForAccountRequest - err := json.NewDecoder(r.Body).Decode(&body) - if err != nil { - JSONResponse(w, http.StatusBadRequest, Error{ - Success: false, - Error: "Error decoding JSON body", - ErrCode: mautrix.MBadJSON.ErrCode, - }) - return nil - } - sessionID, err := strconv.Atoi(body.SessionID) - if err != nil { - JSONResponse(w, http.StatusBadRequest, Error{ - Success: false, - Error: "Error decoding session ID in JSON body", - ErrCode: mautrix.MBadJSON.ErrCode, - }) - return nil - } - process, ok := loginSessions[uint32(sessionID)] - user := m.Matrix.Provisioning.GetUser(r) - if !ok || process.User != user { - JSONResponse(w, http.StatusNotFound, Error{ - Success: false, - Error: "No session found", - ErrCode: mautrix.MNotFound.ErrCode, - }) - return nil - } - return process -} - -func legacyProvLinkWaitScan(w http.ResponseWriter, r *http.Request) { - login := getLoginProcess(w, r) - if login == nil { - return - } - res, err := login.Login.(bridgev2.LoginProcessDisplayAndWait).Wait(r.Context()) - if err != nil { - zerolog.Ctx(r.Context()).Err(err).Msg("Failed to log in") - JSONResponse(w, http.StatusInternalServerError, Error{ - Error: "Failed to log in", - ErrCode: "M_UNKNOWN", - }) - login.Delete() - return - } else if res.StepID != connector.LoginStepProcess { - zerolog.Ctx(r.Context()).Error().Any("first_step", res).Msg("Unexpected login step") - JSONResponse(w, http.StatusInternalServerError, Error{ - Error: "Unexpected login step", - ErrCode: "M_UNKNOWN", - }) - login.Delete() - return - } - JSONResponse(w, http.StatusOK, Response{ - Success: true, - Status: "provisioning_data_received", - }) -} - -func legacyProvLinkWaitAccount(w http.ResponseWriter, r *http.Request) { - login := getLoginProcess(w, r) - if login == nil { - return - } - res, err := login.Login.(bridgev2.LoginProcessDisplayAndWait).Wait(r.Context()) - if err != nil { - zerolog.Ctx(r.Context()).Err(err).Msg("Failed to log in") - JSONResponse(w, http.StatusInternalServerError, Error{ - Error: "Failed to log in", - ErrCode: "M_UNKNOWN", - }) - } else if res.StepID != connector.LoginStepComplete || res.Type != bridgev2.LoginStepTypeComplete { - zerolog.Ctx(r.Context()).Error().Any("first_step", res).Msg("Unexpected login step") - JSONResponse(w, http.StatusInternalServerError, Error{ - Error: "Unexpected login step", - ErrCode: "M_UNKNOWN", - }) - } else { - JSONResponse(w, http.StatusOK, Response{ - Success: true, - Status: "prekeys_registered", - UUID: string(res.CompleteParams.UserLogin.ID), - Number: res.CompleteParams.UserLogin.RemoteName, - }) - go handleLoginComplete(context.WithoutCancel(r.Context()), login.User, res.CompleteParams.UserLogin) - } - login.Delete() -} - -func handleLoginComplete(ctx context.Context, user *bridgev2.User, newLogin *bridgev2.UserLogin) { - allLogins := user.GetCachedUserLogins() - for _, login := range allLogins { - if login.ID != newLogin.ID { - login.Delete(ctx, status.BridgeState{StateEvent: status.StateLoggedOut, Reason: "LOGIN_OVERRIDDEN"}, bridgev2.DeleteOpts{}) - } - } -} - -func legacyProvLogout(w http.ResponseWriter, r *http.Request) { - // No-op for backwards compatibility - JSONResponse(w, http.StatusOK, nil) -} - func legacyResolveIdentifierOrStartChat(w http.ResponseWriter, r *http.Request, create bool) { login := m.Matrix.Provisioning.GetLoginForRequest(w, r) if login == nil { @@ -305,31 +124,10 @@ type Response struct { Success bool `json:"success"` Status string `json:"status"` - // For response in LinkNew - SessionID string `json:"session_id,omitempty"` - URI string `json:"uri,omitempty"` - - // For response in LinkWaitForAccount - UUID string `json:"uuid,omitempty"` - Number string `json:"number,omitempty"` - // For response in ResolveIdentifier *ResolveIdentifierResponse } -type WhoAmIResponse struct { - Permissions int `json:"permissions"` - MXID string `json:"mxid"` - Signal *WhoAmIResponseSignal `json:"signal,omitempty"` -} - -type WhoAmIResponseSignal struct { - Number string `json:"number"` - UUID string `json:"uuid"` - Name string `json:"name"` - Ok bool `json:"ok"` -} - type ResolveIdentifierResponse struct { RoomID id.RoomID `json:"room_id"` ChatID ResolveIdentifierResponseChatID `json:"chat_id"` @@ -347,12 +145,3 @@ type ResolveIdentifierResponseOtherUser struct { DisplayName string `json:"displayname"` AvatarURL id.ContentURI `json:"avatar_url"` } - -type LinkWaitForScanRequest struct { - SessionID string `json:"session_id"` -} - -type LinkWaitForAccountRequest struct { - SessionID string `json:"session_id"` - DeviceName string `json:"device_name"` // TODO this seems to not be used anywhere -} diff --git a/cmd/mautrix-signal/main.go b/cmd/mautrix-signal/main.go index d96283f..16093b5 100644 --- a/cmd/mautrix-signal/main.go +++ b/cmd/mautrix-signal/main.go @@ -17,11 +17,9 @@ package main import ( - "maunium.net/go/mautrix/bridgev2/bridgeconfig" "maunium.net/go/mautrix/bridgev2/matrix/mxmain" "go.mau.fi/mautrix-signal/pkg/connector" - "go.mau.fi/mautrix-signal/pkg/signalmeow" ) // Information to find out exactly which commit the bridge was built from. @@ -42,23 +40,8 @@ var m = mxmain.BridgeMain{ } func main() { - bridgeconfig.HackyMigrateLegacyNetworkConfig = migrateLegacyConfig - m.PostInit = func() { - signalmeow.SetLogger(m.Log.With().Str("component", "signalmeow").Logger()) - m.CheckLegacyDB( - 20, - "v0.5.1", - "v0.7.0", - m.LegacyMigrateSimple(legacyMigrateRenameTables, legacyMigrateCopyData, 21), - true, - ) - } m.PostStart = func() { if m.Matrix.Provisioning != nil { - m.Matrix.Provisioning.Router.HandleFunc("POST /v2/link/new", legacyProvLinkNew) - m.Matrix.Provisioning.Router.HandleFunc("POST /v2/link/wait/scan", legacyProvLinkWaitScan) - m.Matrix.Provisioning.Router.HandleFunc("POST /v2/link/wait/account", legacyProvLinkWaitAccount) - m.Matrix.Provisioning.Router.HandleFunc("POST /v2/logout", legacyProvLogout) m.Matrix.Provisioning.Router.HandleFunc("GET /v2/resolve_identifier/{phonenum}", legacyProvResolveIdentifier) m.Matrix.Provisioning.Router.HandleFunc("POST /v2/pm/{phonenum}", legacyProvPM) } diff --git a/go.mod b/go.mod index 00b8bdc..7136fa1 100644 --- a/go.mod +++ b/go.mod @@ -18,7 +18,7 @@ require ( golang.org/x/net v0.43.0 google.golang.org/protobuf v1.36.7 gopkg.in/yaml.v3 v3.0.1 - maunium.net/go/mautrix v0.25.1-0.20250909132418-41bbe4ace4c7 + maunium.net/go/mautrix v0.25.1-0.20250911181014-4603a344ce1d ) require ( diff --git a/go.sum b/go.sum index 390cf40..345ff89 100644 --- a/go.sum +++ b/go.sum @@ -95,5 +95,5 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= maunium.net/go/mauflag v1.0.0 h1:YiaRc0tEI3toYtJMRIfjP+jklH45uDHtT80nUamyD4M= maunium.net/go/mauflag v1.0.0/go.mod h1:nLivPOpTpHnpzEh8jEdSL9UqO9+/KBJFmNRlwKfkPeA= -maunium.net/go/mautrix v0.25.1-0.20250909132418-41bbe4ace4c7 h1:TywnMUPZakwE9oU1jPC8pVZk3q5dP66LkyOQ5Z+e7cI= -maunium.net/go/mautrix v0.25.1-0.20250909132418-41bbe4ace4c7/go.mod h1:pDd6Ppg+1PbWrw/rg4ZQQfVYZICRGzH+DcliZ/BODvU= +maunium.net/go/mautrix v0.25.1-0.20250911181014-4603a344ce1d h1:jKAn+2wwFC3aLdgE7IBSxhVjB4JisBOz2oCLzj928+c= +maunium.net/go/mautrix v0.25.1-0.20250911181014-4603a344ce1d/go.mod h1:pDd6Ppg+1PbWrw/rg4ZQQfVYZICRGzH+DcliZ/BODvU= From 7a81e7bcf5c7e44b0f9b0204bce4fc04fbda9cde Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Fri, 12 Sep 2025 13:57:26 +0300 Subject: [PATCH 404/580] libsignal: update to v0.80.3 --- pkg/libsignalgo/libsignal | 2 +- pkg/libsignalgo/libsignal-ffi.h | 24 +++++++++++++++++++++++- pkg/libsignalgo/sendercertificate.go | 15 ++++++++++++--- pkg/libsignalgo/version.go | 2 +- 4 files changed, 37 insertions(+), 6 deletions(-) diff --git a/pkg/libsignalgo/libsignal b/pkg/libsignalgo/libsignal index 83690bd..43a23ef 160000 --- a/pkg/libsignalgo/libsignal +++ b/pkg/libsignalgo/libsignal @@ -1 +1 @@ -Subproject commit 83690bdf1130c514e51d573ad0da7b3802aabb6e +Subproject commit 43a23efa1118ac32a1434ab317025adfa2b91e4a diff --git a/pkg/libsignalgo/libsignal-ffi.h b/pkg/libsignalgo/libsignal-ffi.h index dc7fc18..ead3cb4 100644 --- a/pkg/libsignalgo/libsignal-ffi.h +++ b/pkg/libsignalgo/libsignal-ffi.h @@ -1323,6 +1323,11 @@ typedef struct { const SignalServerCertificate *raw; } SignalConstPointerServerCertificate; +typedef struct { + const SignalConstPointerPublicKey *base; + size_t length; +} SignalBorrowedSliceOfConstPointerPublicKey; + typedef struct { SignalSenderKeyDistributionMessage *raw; } SignalMutPointerSenderKeyDistributionMessage; @@ -1378,6 +1383,21 @@ typedef struct { SignalCancellationId cancellation_id; } SignalCPromiseMutPointerUnauthenticatedChatConnection; +/** + * A C callback used to report the results of Rust futures. + * + * cbindgen will produce independent C types like `SignalCPromisei32` and + * `SignalCPromiseProtocolAddress`. + * + * This derives Copy because it behaves like a C type; nevertheless, a promise should still only be + * completed once. + */ +typedef struct { + void (*complete)(SignalFfiError *error, const SignalOptionalUuid *result, const void *context); + const void *context; + SignalCancellationId cancellation_id; +} SignalCPromiseOptionalUuid; + typedef struct { SignalValidatingMac *raw; } SignalMutPointerValidatingMac; @@ -2284,7 +2304,7 @@ SignalFfiError *signal_sender_certificate_get_signature(SignalOwnedBuffer *out, SignalFfiError *signal_sender_certificate_new(SignalMutPointerSenderCertificate *out, const char *sender_uuid, const char *sender_e164, uint32_t sender_device_id, SignalConstPointerPublicKey sender_key, uint64_t expiration, SignalConstPointerServerCertificate signer_cert, SignalConstPointerPrivateKey signer_key); -SignalFfiError *signal_sender_certificate_validate(bool *out, SignalConstPointerSenderCertificate cert, SignalConstPointerPublicKey key, uint64_t time); +SignalFfiError *signal_sender_certificate_validate(bool *out, SignalConstPointerSenderCertificate cert, SignalBorrowedSliceOfConstPointerPublicKey trust_roots, uint64_t time); SignalFfiError *signal_sender_key_distribution_message_clone(SignalMutPointerSenderKeyDistributionMessage *new_obj, SignalConstPointerSenderKeyDistributionMessage obj); @@ -2488,6 +2508,8 @@ SignalFfiError *signal_unauthenticated_chat_connection_info(SignalMutPointerChat SignalFfiError *signal_unauthenticated_chat_connection_init_listener(SignalConstPointerUnauthenticatedChatConnection chat, SignalConstPointerFfiChatListenerStruct listener); +SignalFfiError *signal_unauthenticated_chat_connection_look_up_username_hash(SignalCPromiseOptionalUuid *promise, SignalConstPointerTokioAsyncContext async_runtime, SignalConstPointerUnauthenticatedChatConnection chat, SignalBorrowedBuffer hash); + SignalFfiError *signal_unauthenticated_chat_connection_send(SignalCPromiseFfiChatResponse *promise, SignalConstPointerTokioAsyncContext async_runtime, SignalConstPointerUnauthenticatedChatConnection chat, SignalConstPointerHttpRequest http_request, uint32_t timeout_millis); SignalFfiError *signal_unidentified_sender_message_content_deserialize(SignalMutPointerUnidentifiedSenderMessageContent *out, SignalBorrowedBuffer data); diff --git a/pkg/libsignalgo/sendercertificate.go b/pkg/libsignalgo/sendercertificate.go index 1d7422f..47cf958 100644 --- a/pkg/libsignalgo/sendercertificate.go +++ b/pkg/libsignalgo/sendercertificate.go @@ -24,6 +24,7 @@ import "C" import ( "runtime" "time" + "unsafe" "github.com/google/uuid" ) @@ -186,16 +187,24 @@ func (sc *SenderCertificate) GetKey() (*PublicKey, error) { return wrapPublicKey(key.raw), nil } -func (sc *SenderCertificate) Validate(trustRoot *PublicKey, ts time.Time) (bool, error) { +func (sc *SenderCertificate) Validate(trustRoots []*PublicKey, ts time.Time) (bool, error) { var valid C.bool + constRoots := make([]C.SignalConstPointerPublicKey, len(trustRoots)) + for i, root := range trustRoots { + constRoots[i] = root.constPtr() + } signalFfiError := C.signal_sender_certificate_validate( &valid, sc.constPtr(), - trustRoot.constPtr(), + // TODO this might not be correct + C.SignalBorrowedSliceOfConstPointerPublicKey{ + base: unsafe.SliceData(constRoots), + length: C.size_t(len(constRoots)), + }, C.uint64_t(ts.UnixMilli()), ) runtime.KeepAlive(sc) - runtime.KeepAlive(trustRoot) + runtime.KeepAlive(constRoots) if signalFfiError != nil { return false, wrapError(signalFfiError) } diff --git a/pkg/libsignalgo/version.go b/pkg/libsignalgo/version.go index 04012e8..334f82a 100644 --- a/pkg/libsignalgo/version.go +++ b/pkg/libsignalgo/version.go @@ -2,4 +2,4 @@ package libsignalgo -const Version = "v0.79.0" +const Version = "v0.80.3" From 0d77884ce4459ac7e56de3895ca34087580eec78 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Fri, 12 Sep 2025 14:03:08 +0300 Subject: [PATCH 405/580] changelog: update --- CHANGELOG.md | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3cf3475..0b0e5b4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,19 @@ +# v0.8.7 (unreleased) + +* Removed legacy provisioning API and database legacy migration. + Upgrading directly from versions prior to v0.7.0 is not supported. + * If you've been using the bridge since before v0.7.0 and have prevented the + bridge from writing to the config, you must either update the config + manually or allow the bridge to update it for you **before** upgrading to + this release (i.e. run v0.8.6 once with config writing allowed). +* Updated libsignal to v0.80.3. +* Added support for `com.beeper.disappearing_timer` state event, which stores + the disappearing setting of chats and allows changing the setting from Matrix. +* Added support for nicknames in displayname templates. + * Like contact list names, nicknames are not safe to use on multi-user instances. +* Added support for creating Signal groups. +* Fixed certain types of logouts not being detected properly. + # v0.8.6 (2025-08-16) * Deprecated legacy provisioning API. The `/_matrix/provision/v2` endpoints will From 6d218d8853a54a69a859f19bb4f2edb9e4a6ebcf Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Tue, 16 Sep 2025 15:05:20 +0300 Subject: [PATCH 406/580] Bump version to v0.8.7 --- CHANGELOG.md | 2 +- cmd/mautrix-signal/main.go | 2 +- go.mod | 26 ++++++++++----------- go.sum | 48 +++++++++++++++++++------------------- 4 files changed, 39 insertions(+), 39 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0b0e5b4..b548abd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,4 @@ -# v0.8.7 (unreleased) +# v0.8.7 (2025-09-16) * Removed legacy provisioning API and database legacy migration. Upgrading directly from versions prior to v0.7.0 is not supported. diff --git a/cmd/mautrix-signal/main.go b/cmd/mautrix-signal/main.go index 16093b5..01e3793 100644 --- a/cmd/mautrix-signal/main.go +++ b/cmd/mautrix-signal/main.go @@ -34,7 +34,7 @@ var m = mxmain.BridgeMain{ Name: "mautrix-signal", URL: "https://github.com/mautrix/signal", Description: "A Matrix-Signal puppeting bridge.", - Version: "0.8.6", + Version: "0.8.7", Connector: &connector.SignalConnector{}, } diff --git a/go.mod b/go.mod index 7136fa1..503059c 100644 --- a/go.mod +++ b/go.mod @@ -2,23 +2,23 @@ module go.mau.fi/mautrix-signal go 1.24.0 -toolchain go1.25.0 +toolchain go1.25.1 require ( - github.com/coder/websocket v1.8.13 + github.com/coder/websocket v1.8.14 github.com/emersion/go-vcard v0.0.0-20241024213814-c9703dde27ff github.com/google/uuid v1.6.0 github.com/mattn/go-pointer v0.0.1 github.com/rs/zerolog v1.34.0 - github.com/stretchr/testify v1.10.0 + github.com/stretchr/testify v1.11.1 github.com/tidwall/gjson v1.18.0 - go.mau.fi/util v0.9.0 - golang.org/x/crypto v0.41.0 - golang.org/x/exp v0.0.0-20250813145105-42675adae3e6 - golang.org/x/net v0.43.0 - google.golang.org/protobuf v1.36.7 + go.mau.fi/util v0.9.1 + golang.org/x/crypto v0.42.0 + golang.org/x/exp v0.0.0-20250911091902-df9299821621 + golang.org/x/net v0.44.0 + google.golang.org/protobuf v1.36.9 gopkg.in/yaml.v3 v3.0.1 - maunium.net/go/mautrix v0.25.1-0.20250911181014-4603a344ce1d + maunium.net/go/mautrix v0.25.1 ) require ( @@ -30,7 +30,7 @@ require ( github.com/mattn/go-colorable v0.1.14 // indirect github.com/mattn/go-isatty v0.0.20 // indirect github.com/mattn/go-sqlite3 v1.14.32 // indirect - github.com/petermattis/goid v0.0.0-20250813065127-a731cc31b4fe // indirect + github.com/petermattis/goid v0.0.0-20250904145737-900bdf8bb490 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/rogpeppe/go-internal v1.10.0 // indirect github.com/rs/xid v1.6.0 // indirect @@ -40,9 +40,9 @@ require ( github.com/tidwall/sjson v1.2.5 // indirect github.com/yuin/goldmark v1.7.13 // indirect go.mau.fi/zeroconfig v0.2.0 // indirect - golang.org/x/sync v0.16.0 // indirect - golang.org/x/sys v0.35.0 // indirect - golang.org/x/text v0.28.0 // indirect + golang.org/x/sync v0.17.0 // indirect + golang.org/x/sys v0.36.0 // indirect + golang.org/x/text v0.29.0 // indirect gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect gopkg.in/natefinch/lumberjack.v2 v2.2.1 // indirect maunium.net/go/mauflag v1.0.0 // indirect diff --git a/go.sum b/go.sum index 345ff89..d410473 100644 --- a/go.sum +++ b/go.sum @@ -2,8 +2,8 @@ filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA= filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4= github.com/DATA-DOG/go-sqlmock v1.5.2 h1:OcvFkGmslmlZibjAjaHm3L//6LiuBgolP7OputlJIzU= github.com/DATA-DOG/go-sqlmock v1.5.2/go.mod h1:88MAG/4G7SMwSE3CeA0ZKzrT5CiOU3OJ+JlNzwDqpNU= -github.com/coder/websocket v1.8.13 h1:f3QZdXy7uGVz+4uCJy2nTZyM0yTBj8yANEHhqlXZ9FE= -github.com/coder/websocket v1.8.13/go.mod h1:LNVeNrXQZfe5qhS9ALED3uA+l5pPqvwXg3CKoDBB2gs= +github.com/coder/websocket v1.8.14 h1:9L0p0iKiNOibykf283eHkKUHHrpG7f65OE3BhhO7v9g= +github.com/coder/websocket v1.8.14/go.mod h1:NX3SzP+inril6yawo5CQXx8+fk145lPDC6pumgx0mVg= github.com/coreos/go-systemd/v22 v22.5.0 h1:RrqgGjYQKalulkV8NGVIfkXQf6YYmOyiJKk8iXXhfZs= github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= @@ -36,8 +36,8 @@ github.com/mattn/go-pointer v0.0.1 h1:n+XhsuGeVO6MEAp7xyEukFINEa+Quek5psIR/ylA6o github.com/mattn/go-pointer v0.0.1/go.mod h1:2zXcozF6qYGgmsG+SeTZz3oAbFLdD3OWqnUbNvJZAlc= github.com/mattn/go-sqlite3 v1.14.32 h1:JD12Ag3oLy1zQA+BNn74xRgaBbdhbNIDYvQUEuuErjs= github.com/mattn/go-sqlite3 v1.14.32/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y= -github.com/petermattis/goid v0.0.0-20250813065127-a731cc31b4fe h1:vHpqOnPlnkba8iSxU4j/CvDSS9J4+F4473esQsYLGoE= -github.com/petermattis/goid v0.0.0-20250813065127-a731cc31b4fe/go.mod h1:pxMtw7cyUw6B2bRH0ZBANSPg+AoSud1I1iyJHI69jH4= +github.com/petermattis/goid v0.0.0-20250904145737-900bdf8bb490 h1:QTvNkZ5ylY0PGgA+Lih+GdboMLY/G9SEGLMEGVjTVA4= +github.com/petermattis/goid v0.0.0-20250904145737-900bdf8bb490/go.mod h1:pxMtw7cyUw6B2bRH0ZBANSPg+AoSud1I1iyJHI69jH4= github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= @@ -51,8 +51,8 @@ github.com/rs/zerolog v1.34.0 h1:k43nTLIwcTVQAncfCw4KZ2VY6ukYoZaBPNOE8txlOeY= github.com/rs/zerolog v1.34.0/go.mod h1:bJsvje4Z08ROH4Nhs5iH600c3IkWhwp44iRc54W6wYQ= github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e h1:MRM5ITcdelLK2j1vwZ3Je0FKVCfqOLp5zO6trqMLYs0= github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e/go.mod h1:XV66xRDqSt+GTGFMVlhk3ULuV0y9ZmzeVGR4mloJI3M= -github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= -github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= +github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= github.com/tidwall/gjson v1.14.2/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= github.com/tidwall/gjson v1.18.0 h1:FIDeeyB800efLX89e5a8Y0BNH+LOngJyGrIWxG2FKQY= github.com/tidwall/gjson v1.18.0/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= @@ -65,27 +65,27 @@ github.com/tidwall/sjson v1.2.5 h1:kLy8mja+1c9jlljvWTlSazM7cKDRfJuR/bOJhcY5NcY= github.com/tidwall/sjson v1.2.5/go.mod h1:Fvgq9kS/6ociJEDnK0Fk1cpYF4FIW6ZF7LAe+6jwd28= github.com/yuin/goldmark v1.7.13 h1:GPddIs617DnBLFFVJFgpo1aBfe/4xcvMc3SB5t/D0pA= github.com/yuin/goldmark v1.7.13/go.mod h1:ip/1k0VRfGynBgxOz0yCqHrbZXhcjxyuS66Brc7iBKg= -go.mau.fi/util v0.9.0 h1:ya3s3pX+Y8R2fgp0DbE7a0o3FwncoelDX5iyaeVE8ls= -go.mau.fi/util v0.9.0/go.mod h1:pdL3lg2aaeeHIreGXNnPwhJPXkXdc3ZxsI6le8hOWEA= +go.mau.fi/util v0.9.1 h1:A+XKHRsjKkFi2qOm4RriR1HqY2hoOXNS3WFHaC89r2Y= +go.mau.fi/util v0.9.1/go.mod h1:M0bM9SyaOWJniaHs9hxEzz91r5ql6gYq6o1q5O1SsjQ= go.mau.fi/zeroconfig v0.2.0 h1:e/OGEERqVRRKlgaro7E6bh8xXiKFSXB3eNNIud7FUjU= go.mau.fi/zeroconfig v0.2.0/go.mod h1:J0Vn0prHNOm493oZoQ84kq83ZaNCYZnq+noI1b1eN8w= -golang.org/x/crypto v0.41.0 h1:WKYxWedPGCTVVl5+WHSSrOBT0O8lx32+zxmHxijgXp4= -golang.org/x/crypto v0.41.0/go.mod h1:pO5AFd7FA68rFak7rOAGVuygIISepHftHnr8dr6+sUc= -golang.org/x/exp v0.0.0-20250813145105-42675adae3e6 h1:SbTAbRFnd5kjQXbczszQ0hdk3ctwYf3qBNH9jIsGclE= -golang.org/x/exp v0.0.0-20250813145105-42675adae3e6/go.mod h1:4QTo5u+SEIbbKW1RacMZq1YEfOBqeXa19JeshGi+zc4= -golang.org/x/net v0.43.0 h1:lat02VYK2j4aLzMzecihNvTlJNQUq316m2Mr9rnM6YE= -golang.org/x/net v0.43.0/go.mod h1:vhO1fvI4dGsIjh73sWfUVjj3N7CA9WkKJNQm2svM6Jg= -golang.org/x/sync v0.16.0 h1:ycBJEhp9p4vXvUZNszeOq0kGTPghopOL8q0fq3vstxw= -golang.org/x/sync v0.16.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= +golang.org/x/crypto v0.42.0 h1:chiH31gIWm57EkTXpwnqf8qeuMUi0yekh6mT2AvFlqI= +golang.org/x/crypto v0.42.0/go.mod h1:4+rDnOTJhQCx2q7/j6rAN5XDw8kPjeaXEUR2eL94ix8= +golang.org/x/exp v0.0.0-20250911091902-df9299821621 h1:2id6c1/gto0kaHYyrixvknJ8tUK/Qs5IsmBtrc+FtgU= +golang.org/x/exp v0.0.0-20250911091902-df9299821621/go.mod h1:TwQYMMnGpvZyc+JpB/UAuTNIsVJifOlSkrZkhcvpVUk= +golang.org/x/net v0.44.0 h1:evd8IRDyfNBMBTTY5XRF1vaZlD+EmWx6x8PkhR04H/I= +golang.org/x/net v0.44.0/go.mod h1:ECOoLqd5U3Lhyeyo/QDCEVQ4sNgYsqvCZ722XogGieY= +golang.org/x/sync v0.17.0 h1:l60nONMj9l5drqw6jlhIELNv9I0A4OFgRsG9k2oT9Ug= +golang.org/x/sync v0.17.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.35.0 h1:vz1N37gP5bs89s7He8XuIYXpyY0+QlsKmzipCbUtyxI= -golang.org/x/sys v0.35.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= -golang.org/x/text v0.28.0 h1:rhazDwis8INMIwQ4tpjLDzUhx6RlXqZNPEM0huQojng= -golang.org/x/text v0.28.0/go.mod h1:U8nCwOR8jO/marOQ0QbDiOngZVEBB7MAiitBuMjXiNU= -google.golang.org/protobuf v1.36.7 h1:IgrO7UwFQGJdRNXH/sQux4R1Dj1WAKcLElzeeRaXV2A= -google.golang.org/protobuf v1.36.7/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY= +golang.org/x/sys v0.36.0 h1:KVRy2GtZBrk1cBYA7MKu5bEZFxQk4NIDV6RLVcC8o0k= +golang.org/x/sys v0.36.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= +golang.org/x/text v0.29.0 h1:1neNs90w9YzJ9BocxfsQNHKuAT4pkghyXc4nhZ6sJvk= +golang.org/x/text v0.29.0/go.mod h1:7MhJOA9CD2qZyOKYazxdYMF85OwPdEr9jTtBpO7ydH4= +google.golang.org/protobuf v1.36.9 h1:w2gp2mA27hUeUzj9Ex9FBjsBm40zfaDtEWow293U7Iw= +google.golang.org/protobuf v1.36.9/go.mod h1:fuxRtAxBytpl4zzqUh6/eyUujkJdNiuEkXntxiD/uRU= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= @@ -95,5 +95,5 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= maunium.net/go/mauflag v1.0.0 h1:YiaRc0tEI3toYtJMRIfjP+jklH45uDHtT80nUamyD4M= maunium.net/go/mauflag v1.0.0/go.mod h1:nLivPOpTpHnpzEh8jEdSL9UqO9+/KBJFmNRlwKfkPeA= -maunium.net/go/mautrix v0.25.1-0.20250911181014-4603a344ce1d h1:jKAn+2wwFC3aLdgE7IBSxhVjB4JisBOz2oCLzj928+c= -maunium.net/go/mautrix v0.25.1-0.20250911181014-4603a344ce1d/go.mod h1:pDd6Ppg+1PbWrw/rg4ZQQfVYZICRGzH+DcliZ/BODvU= +maunium.net/go/mautrix v0.25.1 h1:+xe3eXtQNcDPU/HoWzvSOA5YX57iqlYI1TXf/fM0KWs= +maunium.net/go/mautrix v0.25.1/go.mod h1:iSueLJ/2fBaNrsTObGqi1j0cl/loxrtAjmjay1scYD8= From 979bf338020869102103977d4c73747aef03930e Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Wed, 17 Sep 2025 12:50:59 +0300 Subject: [PATCH 407/580] handlematrix: fix changing disappearing timer --- pkg/connector/handlematrix.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/pkg/connector/handlematrix.go b/pkg/connector/handlematrix.go index 614795a..4443fad 100644 --- a/pkg/connector/handlematrix.go +++ b/pkg/connector/handlematrix.go @@ -631,8 +631,10 @@ func (s *SignalClient) HandleMatrixDisappearingTimer(ctx context.Context, msg *b msg.Portal.Disappear = newSetting }) } else { + ts := getTimestampForEvent(msg.InputTransactionID, msg.Event, msg.OrigSender) res := s.Client.SendMessage(ctx, userID, &signalpb.Content{ DataMessage: &signalpb.DataMessage{ + Timestamp: ptr.Ptr(ts), Flags: ptr.Ptr(uint32(signalpb.DataMessage_EXPIRATION_TIMER_UPDATE)), ExpireTimer: ptr.Ptr(uint32(msg.Content.Timer.Seconds())), }, From 96b1aae14ece3a5d8fc84c25f003316da09906f1 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Wed, 17 Sep 2025 15:04:27 +0300 Subject: [PATCH 408/580] msgconv/from-signal: ignore disappearing timers in backfill --- pkg/msgconv/from-signal.go | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/pkg/msgconv/from-signal.go b/pkg/msgconv/from-signal.go index 1606245..277e2a5 100644 --- a/pkg/msgconv/from-signal.go +++ b/pkg/msgconv/from-signal.go @@ -93,7 +93,9 @@ func (mc *MessageConverter) ToMatrix( Parts: make([]*bridgev2.ConvertedMessagePart, 0, calculateLength(dm)), } if dm.GetFlags()&uint32(signalpb.DataMessage_EXPIRATION_TIMER_UPDATE) != 0 { - cm.Parts = append(cm.Parts, mc.ConvertDisappearingTimerChangeToMatrix(ctx, dm.GetExpireTimer(), dm.ExpireTimerVersion, time.UnixMilli(int64(dm.GetTimestamp())))) + cm.Parts = append(cm.Parts, mc.ConvertDisappearingTimerChangeToMatrix( + ctx, dm.GetExpireTimer(), dm.ExpireTimerVersion, time.UnixMilli(int64(dm.GetTimestamp())), attMap != nil, + )) // Don't allow any other parts in a disappearing timer change message return cm } @@ -170,7 +172,9 @@ func (mc *MessageConverter) ToMatrix( return cm } -func (mc *MessageConverter) ConvertDisappearingTimerChangeToMatrix(ctx context.Context, timer uint32, timerVersion *uint32, ts time.Time) *bridgev2.ConvertedMessagePart { +func (mc *MessageConverter) ConvertDisappearingTimerChangeToMatrix( + ctx context.Context, timer uint32, timerVersion *uint32, ts time.Time, isBackfill bool, +) *bridgev2.ConvertedMessagePart { portal := getPortal(ctx) setting := database.DisappearingSetting{ Timer: time.Duration(timer) * time.Second, @@ -188,10 +192,14 @@ func (mc *MessageConverter) ConvertDisappearingTimerChangeToMatrix(ctx context.C "timer": setting.Timer.Milliseconds(), "timer_type": setting.Type, "implicit": false, + "backfill": isBackfill, }, }, DontBridge: setting == portal.Disappear, } + if isBackfill { + return part + } portalMeta := portal.Metadata.(*signalid.PortalMetadata) if timerVersion != nil && portalMeta.ExpirationTimerVersion > *timerVersion { zerolog.Ctx(ctx).Warn(). From 88b2378fd9ca7538c900fd831464274c5bff9805 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Wed, 17 Sep 2025 15:04:37 +0300 Subject: [PATCH 409/580] signalmeow: remove unused data message wrapper functions --- pkg/signalmeow/sending.go | 26 -------------------------- 1 file changed, 26 deletions(-) diff --git a/pkg/signalmeow/sending.go b/pkg/signalmeow/sending.go index 69545d9..5c3612e 100644 --- a/pkg/signalmeow/sending.go +++ b/pkg/signalmeow/sending.go @@ -531,32 +531,6 @@ func ReadReceptMessageForTimestamps(timestamps []uint64) *signalpb.Content { } } -func DataMessageForReaction(reaction string, targetMessageSender uuid.UUID, targetMessageTimestamp uint64, removing bool) *signalpb.Content { - timestamp := currentMessageTimestamp() - dm := &signalpb.DataMessage{ - Timestamp: ×tamp, - RequiredProtocolVersion: proto.Uint32(uint32(signalpb.DataMessage_REACTIONS)), - Reaction: &signalpb.DataMessage_Reaction{ - Emoji: proto.String(reaction), - Remove: proto.Bool(removing), - TargetAuthorAci: proto.String(targetMessageSender.String()), - TargetSentTimestamp: proto.Uint64(targetMessageTimestamp), - }, - } - return wrapDataMessageInContent(dm) -} - -func DataMessageForDelete(targetMessageTimestamp uint64) *signalpb.Content { - timestamp := currentMessageTimestamp() - dm := &signalpb.DataMessage{ - Timestamp: ×tamp, - Delete: &signalpb.DataMessage_Delete{ - TargetSentTimestamp: proto.Uint64(targetMessageTimestamp), - }, - } - return wrapDataMessageInContent(dm) -} - func wrapDataMessageInContent(dm *signalpb.DataMessage) *signalpb.Content { return &signalpb.Content{ DataMessage: dm, From 250975a622459f2c949eff3ad315fad8a52ff90c Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Fri, 19 Sep 2025 14:32:26 +0300 Subject: [PATCH 410/580] capabilities: enable implicit read receipts --- go.mod | 2 +- go.sum | 4 ++-- pkg/connector/capabilities.go | 1 + 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 503059c..d31d7ec 100644 --- a/go.mod +++ b/go.mod @@ -18,7 +18,7 @@ require ( golang.org/x/net v0.44.0 google.golang.org/protobuf v1.36.9 gopkg.in/yaml.v3 v3.0.1 - maunium.net/go/mautrix v0.25.1 + maunium.net/go/mautrix v0.25.2-0.20250919113047-b760023dcaa3 ) require ( diff --git a/go.sum b/go.sum index d410473..a0e7676 100644 --- a/go.sum +++ b/go.sum @@ -95,5 +95,5 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= maunium.net/go/mauflag v1.0.0 h1:YiaRc0tEI3toYtJMRIfjP+jklH45uDHtT80nUamyD4M= maunium.net/go/mauflag v1.0.0/go.mod h1:nLivPOpTpHnpzEh8jEdSL9UqO9+/KBJFmNRlwKfkPeA= -maunium.net/go/mautrix v0.25.1 h1:+xe3eXtQNcDPU/HoWzvSOA5YX57iqlYI1TXf/fM0KWs= -maunium.net/go/mautrix v0.25.1/go.mod h1:iSueLJ/2fBaNrsTObGqi1j0cl/loxrtAjmjay1scYD8= +maunium.net/go/mautrix v0.25.2-0.20250919113047-b760023dcaa3 h1:MU7lyDtxVAsd1Mh+WGJOFD5PsGLRRl3Xv67zizxLkgc= +maunium.net/go/mautrix v0.25.2-0.20250919113047-b760023dcaa3/go.mod h1:iSueLJ/2fBaNrsTObGqi1j0cl/loxrtAjmjay1scYD8= diff --git a/pkg/connector/capabilities.go b/pkg/connector/capabilities.go index 129c75c..329a81d 100644 --- a/pkg/connector/capabilities.go +++ b/pkg/connector/capabilities.go @@ -180,6 +180,7 @@ func (s *SignalClient) GetCapabilities(ctx context.Context, portal *bridgev2.Por var signalGeneralCaps = &bridgev2.NetworkGeneralCapabilities{ DisappearingMessages: true, AggressiveUpdateInfo: true, + ImplicitReadReceipts: true, Provisioning: bridgev2.ProvisioningCapabilities{ ResolveIdentifier: bridgev2.ResolveIdentifierCapabilities{ CreateDM: true, From 546230ec40ccc44758ad22fc34882bda3644c327 Mon Sep 17 00:00:00 2001 From: Adam Van Ymeren Date: Thu, 25 Sep 2025 12:31:18 -0700 Subject: [PATCH 411/580] handlematrix: resync portals upon viewieng if they haven't synced in the last 24h (#608) Co-authored-by: Tulir Asokan --- pkg/connector/chatinfo.go | 2 ++ pkg/connector/groupinfo.go | 9 +++++- pkg/connector/handlematrix.go | 55 +++++++++++++++++++++-------------- pkg/signalid/dbmeta.go | 2 ++ 4 files changed, 45 insertions(+), 23 deletions(-) diff --git a/pkg/connector/chatinfo.go b/pkg/connector/chatinfo.go index 4b72ad0..18ffb36 100644 --- a/pkg/connector/chatinfo.go +++ b/pkg/connector/chatinfo.go @@ -438,6 +438,8 @@ func (s *SignalClient) makeCreateDMResponse(ctx context.Context, recipient *type Type: ptr.Ptr(database.RoomTypeDM), CanBackfill: backupChat != nil, + + ExtraUpdates: updatePortalSyncMeta, }, } } diff --git a/pkg/connector/groupinfo.go b/pkg/connector/groupinfo.go index 857031f..6baa3d6 100644 --- a/pkg/connector/groupinfo.go +++ b/pkg/connector/groupinfo.go @@ -23,6 +23,7 @@ import ( "github.com/google/uuid" "github.com/rs/zerolog" + "go.mau.fi/util/jsontime" "go.mau.fi/util/ptr" "maunium.net/go/mautrix/bridgev2" "maunium.net/go/mautrix/bridgev2/database" @@ -182,11 +183,17 @@ func (s *SignalClient) wrapGroupInfo(ctx context.Context, groupInfo *signalmeow. Members: members, Type: ptr.Ptr(database.RoomTypeDefault), JoinRule: &event.JoinRulesEventContent{JoinRule: joinRule}, - ExtraUpdates: makeRevisionUpdater(groupInfo.Revision), + ExtraUpdates: bridgev2.MergeExtraUpdaters(makeRevisionUpdater(groupInfo.Revision), updatePortalSyncMeta), CanBackfill: backupChat != nil, }, nil } +func updatePortalSyncMeta(ctx context.Context, portal *bridgev2.Portal) bool { + meta := portal.Metadata.(*signalid.PortalMetadata) + meta.LastSync = jsontime.UnixNow() + return true +} + func (s *SignalClient) makeGroupAvatar(ctx context.Context, groupID types.GroupIdentifier, path *string, groupMasterKey types.SerializedGroupMasterKey) (*bridgev2.Avatar, error) { if path == nil { return nil, nil diff --git a/pkg/connector/handlematrix.go b/pkg/connector/handlematrix.go index 4443fad..1a10773 100644 --- a/pkg/connector/handlematrix.go +++ b/pkg/connector/handlematrix.go @@ -32,6 +32,7 @@ import ( "maunium.net/go/mautrix/bridgev2" "maunium.net/go/mautrix/bridgev2/database" "maunium.net/go/mautrix/bridgev2/networkid" + "maunium.net/go/mautrix/bridgev2/simplevent" "maunium.net/go/mautrix/event" "go.mau.fi/mautrix-signal/pkg/libsignalgo" @@ -577,35 +578,45 @@ func (s *SignalClient) HandleMatrixPowerLevels(ctx context.Context, msg *bridgev } func (s *SignalClient) HandleMatrixViewingChat(ctx context.Context, msg *bridgev2.MatrixViewingChat) error { - if msg.Portal == nil || msg.Portal.OtherUserID == "" { - // Group chat changes are sent by Signal so no need to fetch them on view + if msg.Portal == nil { return nil } - // Sync other user ghost info in DM rooms - ghost, err := s.Main.Bridge.GetExistingGhostByID(ctx, msg.Portal.OtherUserID) - if err != nil { - return fmt.Errorf("failed to get ghost for sync: %w", err) - } else if ghost == nil { - zerolog.Ctx(ctx).Warn(). - Str("other_user_id", string(msg.Portal.OtherUserID)). - Msg("No ghost found for other user in portal") - return nil + // Sync the other users ghost in DMs + if msg.Portal.OtherUserID != "" { + ghost, err := s.Main.Bridge.GetExistingGhostByID(ctx, msg.Portal.OtherUserID) + if err != nil { + return fmt.Errorf("failed to get ghost for sync: %w", err) + } else if ghost == nil { + zerolog.Ctx(ctx).Warn(). + Str("other_user_id", string(msg.Portal.OtherUserID)). + Msg("No ghost found for other user in portal") + } else { + meta := ghost.Metadata.(*signalid.GhostMetadata) + if meta.ProfileFetchedAt.Time.Add(5 * time.Minute).Before(time.Now()) { + // Reset, but don't save, portal last sync time for immediate sync now + meta.ProfileFetchedAt.Time = time.Time{} + info, err := s.GetUserInfoWithRefreshAfter(ctx, ghost, 5*time.Minute) + if err != nil { + return fmt.Errorf("failed to get user info: %w", err) + } + ghost.UpdateInfo(ctx, info) + } + } } - meta := ghost.Metadata.(*signalid.GhostMetadata) - if meta.ProfileFetchedAt.Time.Add(5 * time.Minute).After(time.Now()) { - // Limit profile fetches to max one per 5 minutes - return nil + // always resync the portal if its stale + portalMeta := msg.Portal.Metadata.(*signalid.PortalMetadata) + if portalMeta.LastSync.Add(24 * time.Hour).Before(time.Now()) { + s.UserLogin.QueueRemoteEvent(&simplevent.ChatResync{ + EventMeta: simplevent.EventMeta{ + Type: bridgev2.RemoteEventChatResync, + PortalKey: msg.Portal.PortalKey, + }, + GetChatInfoFunc: s.GetChatInfo, + }) } - // Reset, but don't save, portal last sync time for immediate sync now - meta.ProfileFetchedAt.Time = time.Time{} - info, err := s.GetUserInfoWithRefreshAfter(ctx, ghost, 5*time.Minute) - if err != nil { - return fmt.Errorf("failed to get user info: %w", err) - } - ghost.UpdateInfo(ctx, info) return nil } diff --git a/pkg/signalid/dbmeta.go b/pkg/signalid/dbmeta.go index 76ee217..72112a8 100644 --- a/pkg/signalid/dbmeta.go +++ b/pkg/signalid/dbmeta.go @@ -23,6 +23,8 @@ import ( type PortalMetadata struct { Revision uint32 `json:"revision,omitempty"` ExpirationTimerVersion uint32 `json:"expiration_timer_version,omitempty"` + // Lazy resync tracking + LastSync jsontime.Unix `json:"last_sync,omitempty"` } type MessageMetadata struct { From 7459cb38b3fdb8c2f2ddb64929bc05737f67ad50 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Thu, 25 Sep 2025 23:59:08 +0300 Subject: [PATCH 412/580] dependencies: update mautrix-go --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index d31d7ec..9ead914 100644 --- a/go.mod +++ b/go.mod @@ -18,7 +18,7 @@ require ( golang.org/x/net v0.44.0 google.golang.org/protobuf v1.36.9 gopkg.in/yaml.v3 v3.0.1 - maunium.net/go/mautrix v0.25.2-0.20250919113047-b760023dcaa3 + maunium.net/go/mautrix v0.25.2-0.20250924172949-cf29b07f32ce ) require ( diff --git a/go.sum b/go.sum index a0e7676..1e05243 100644 --- a/go.sum +++ b/go.sum @@ -95,5 +95,5 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= maunium.net/go/mauflag v1.0.0 h1:YiaRc0tEI3toYtJMRIfjP+jklH45uDHtT80nUamyD4M= maunium.net/go/mauflag v1.0.0/go.mod h1:nLivPOpTpHnpzEh8jEdSL9UqO9+/KBJFmNRlwKfkPeA= -maunium.net/go/mautrix v0.25.2-0.20250919113047-b760023dcaa3 h1:MU7lyDtxVAsd1Mh+WGJOFD5PsGLRRl3Xv67zizxLkgc= -maunium.net/go/mautrix v0.25.2-0.20250919113047-b760023dcaa3/go.mod h1:iSueLJ/2fBaNrsTObGqi1j0cl/loxrtAjmjay1scYD8= +maunium.net/go/mautrix v0.25.2-0.20250924172949-cf29b07f32ce h1:sRBScG2xa66ERjgrX+7D//HorAhmNHwxB2Kzltg+aUg= +maunium.net/go/mautrix v0.25.2-0.20250924172949-cf29b07f32ce/go.mod h1:iSueLJ/2fBaNrsTObGqi1j0cl/loxrtAjmjay1scYD8= From 0fb7252230e78a424410132dd9b5d8f22e2b9aee Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Fri, 26 Sep 2025 19:56:40 +0300 Subject: [PATCH 413/580] libsignalgo: add docker version of update-ffi.sh [skip cd] --- pkg/libsignalgo/update-ffi-docker-inner.sh | 11 +++++++++++ pkg/libsignalgo/update-ffi-docker.sh | 9 +++++++++ 2 files changed, 20 insertions(+) create mode 100755 pkg/libsignalgo/update-ffi-docker-inner.sh create mode 100755 pkg/libsignalgo/update-ffi-docker.sh diff --git a/pkg/libsignalgo/update-ffi-docker-inner.sh b/pkg/libsignalgo/update-ffi-docker-inner.sh new file mode 100755 index 0000000..7641701 --- /dev/null +++ b/pkg/libsignalgo/update-ffi-docker-inner.sh @@ -0,0 +1,11 @@ +#!/bin/sh +cd /data +export RUSTFLAGS="-Ctarget-feature=-crt-static" RUSTC_WRAPPER="" +apk add --no-cache git make cmake protoc musl-dev g++ clang-dev cbindgen +cd libsignal +cargo build -p libsignal-ffi --release +cbindgen --profile release rust/bridge/ffi -o libsignal-ffi.h +cd .. +mv libsignal/target/release/libsignal_ffi.a . +mv libsignal/libsignal-ffi.h . +chown 1000:1000 libsignal_ffi.a libsignal-ffi.h version.go diff --git a/pkg/libsignalgo/update-ffi-docker.sh b/pkg/libsignalgo/update-ffi-docker.sh new file mode 100755 index 0000000..5fb6dda --- /dev/null +++ b/pkg/libsignalgo/update-ffi-docker.sh @@ -0,0 +1,9 @@ +#!/bin/bash +docker run --rm -itv $(pwd):/data rust:1-alpine /data/update-ffi-docker-inner.sh + +echo "// Generated by update-ffi.sh; DO NOT EDIT." > version.go +echo >> version.go +echo "package libsignalgo" >> version.go +echo >> version.go +cd libsignal +echo "const Version = \"$(git describe --tags --always)\"" >> ../version.go From 01d1472750150a53440551f0c0503dfbf31b323a Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Tue, 30 Sep 2025 15:36:25 +0300 Subject: [PATCH 414/580] libsignal: update to v0.82.0 --- pkg/libsignalgo/libsignal | 2 +- pkg/libsignalgo/libsignal-ffi.h | 2 +- pkg/libsignalgo/version.go | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/pkg/libsignalgo/libsignal b/pkg/libsignalgo/libsignal index 43a23ef..42ff946 160000 --- a/pkg/libsignalgo/libsignal +++ b/pkg/libsignalgo/libsignal @@ -1 +1 @@ -Subproject commit 43a23efa1118ac32a1434ab317025adfa2b91e4a +Subproject commit 42ff946228be177c33c147359178455b411d3628 diff --git a/pkg/libsignalgo/libsignal-ffi.h b/pkg/libsignalgo/libsignal-ffi.h index ead3cb4..0111718 100644 --- a/pkg/libsignalgo/libsignal-ffi.h +++ b/pkg/libsignalgo/libsignal-ffi.h @@ -866,7 +866,7 @@ typedef struct { typedef int (*SignalStoreKyberPreKey)(void *store_ctx, uint32_t id, SignalConstPointerKyberPreKeyRecord record); -typedef int (*SignalMarkKyberPreKeyUsed)(void *store_ctx, uint32_t id); +typedef int (*SignalMarkKyberPreKeyUsed)(void *store_ctx, uint32_t id, uint32_t signed_prekey_id, SignalConstPointerPublicKey base_key); typedef struct { void *ctx; diff --git a/pkg/libsignalgo/version.go b/pkg/libsignalgo/version.go index 334f82a..b137e61 100644 --- a/pkg/libsignalgo/version.go +++ b/pkg/libsignalgo/version.go @@ -2,4 +2,4 @@ package libsignalgo -const Version = "v0.80.3" +const Version = "v0.82.0" From 527cd4ec0be42dd2d57a0af50556dc1573da3583 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Tue, 30 Sep 2025 16:14:13 +0300 Subject: [PATCH 415/580] signalmeow/groups: update to v2 api --- pkg/signalmeow/groups.go | 83 ++++++++++++++++++++++------------------ 1 file changed, 46 insertions(+), 37 deletions(-) diff --git a/pkg/signalmeow/groups.go b/pkg/signalmeow/groups.go index 865de3f..de6e054 100644 --- a/pkg/signalmeow/groups.go +++ b/pkg/signalmeow/groups.go @@ -192,7 +192,7 @@ type GroupChange struct { ModifyInviteLinkPassword *types.SerializedInviteLinkPassword } -func (groupChange *GroupChange) isEmptpy() bool { +func (groupChange *GroupChange) isEmpty() bool { return len(groupChange.AddMembers) == 0 && len(groupChange.DeleteMembers) == 0 && len(groupChange.ModifyMemberRoles) == 0 && @@ -638,6 +638,7 @@ func (cli *Client) fetchGroupByID(ctx context.Context, gid types.GroupIdentifier } return cli.fetchGroupWithMasterKey(ctx, groupMasterKey) } + func (cli *Client) fetchGroupWithMasterKey(ctx context.Context, groupMasterKey types.SerializedGroupMasterKey) (*Group, error) { masterKeyBytes := masterKeyToBytes(groupMasterKey) groupAuth, err := cli.GetAuthorizationForToday(ctx, masterKeyBytes) @@ -650,24 +651,28 @@ func (cli *Client) fetchGroupWithMasterKey(ctx context.Context, groupMasterKey t ContentType: web.ContentTypeProtobuf, Host: web.StorageHostname, } - response, err := web.SendHTTPRequest(ctx, http.MethodGet, "/v1/groups", opts) + response, err := web.SendHTTPRequest(ctx, http.MethodGet, "/v2/groups", opts) if err != nil { return nil, err } if response.StatusCode != 200 { return nil, fmt.Errorf("fetchGroupByID SendHTTPRequest bad status: %d", response.StatusCode) } - var encryptedGroup signalpb.Group + return cli.parseGroupResponse(ctx, response, groupMasterKey) +} + +func (cli *Client) parseGroupResponse(ctx context.Context, response *http.Response, masterKey types.SerializedGroupMasterKey) (*Group, error) { + var groupResponse signalpb.GroupResponse groupBytes, err := io.ReadAll(response.Body) if err != nil { return nil, err } - err = proto.Unmarshal(groupBytes, &encryptedGroup) + err = proto.Unmarshal(groupBytes, &groupResponse) if err != nil { return nil, fmt.Errorf("failed to unmarshal group: %w", err) } - group, err := decryptGroup(ctx, &encryptedGroup, groupMasterKey) + group, err := decryptGroup(ctx, groupResponse.Group, masterKey) if err != nil { return nil, fmt.Errorf("failed to decrypt group: %w", err) } @@ -1196,7 +1201,7 @@ func decryptRequestingMember(ctx context.Context, requestingMember *signalpb.Req }, nil } -func (cli *Client) EncryptAndSignGroupChange(ctx context.Context, decryptedGroupChange *GroupChange, gid types.GroupIdentifier) (*signalpb.GroupChange, error) { +func (cli *Client) EncryptAndSignGroupChange(ctx context.Context, decryptedGroupChange *GroupChange) (*signalpb.GroupChangeResponse, error) { log := zerolog.Ctx(ctx).With().Str("action", "EncryptGroupChange").Logger() groupMasterKey := decryptedGroupChange.GroupMasterKey masterKeyBytes := masterKeyToBytes(groupMasterKey) @@ -1479,7 +1484,7 @@ func (e RespError) Error() string { return e.Err } -func (cli *Client) patchGroup(ctx context.Context, groupChange *signalpb.GroupChange_Actions, groupMasterKey types.SerializedGroupMasterKey, groupLinkPassword []byte) (*signalpb.GroupChange, error) { +func (cli *Client) patchGroup(ctx context.Context, groupChange *signalpb.GroupChange_Actions, groupMasterKey types.SerializedGroupMasterKey, groupLinkPassword []byte) (*signalpb.GroupChangeResponse, error) { log := zerolog.Ctx(ctx).With().Str("action", "patchGroup").Logger() groupAuth, err := cli.GetAuthorizationForToday(ctx, masterKeyToBytes(groupMasterKey)) if err != nil { @@ -1488,9 +1493,9 @@ func (cli *Client) patchGroup(ctx context.Context, groupChange *signalpb.GroupCh } var path string if groupLinkPassword == nil { - path = "/v1/groups/" + path = "/v2/groups/" } else { - path = fmt.Sprintf("/v1/groups/?inviteLinkPassword=%s", base64.StdEncoding.EncodeToString(groupLinkPassword)) + path = fmt.Sprintf("/v2/groups/?inviteLinkPassword=%s", base64.StdEncoding.EncodeToString(groupLinkPassword)) } requestBody, err := proto.Marshal(groupChange) if err != nil { @@ -1535,70 +1540,78 @@ func (cli *Client) patchGroup(ctx context.Context, groupChange *signalpb.GroupCh if err != nil { return nil, fmt.Errorf("failed to read storage manifest response: %w", err) } - signedGroupChange := signalpb.GroupChange{} - err = proto.Unmarshal(body, &signedGroupChange) + var changeResp signalpb.GroupChangeResponse + err = proto.Unmarshal(body, &changeResp) if err != nil { return nil, fmt.Errorf("failed to unmarshal signed groupChange: %w", err) } - return &signedGroupChange, nil + return &changeResp, nil } func (cli *Client) UpdateGroup(ctx context.Context, groupChange *GroupChange, gid types.GroupIdentifier) (uint32, error) { log := zerolog.Ctx(ctx).With().Str("action", "UpdateGroup").Logger() groupMasterKey, err := cli.Store.GroupStore.MasterKeyFromGroupIdentifier(ctx, gid) if err != nil { - log.Err(err).Msg("Could not get master key from group id") - return 0, err + return 0, fmt.Errorf("failed to get master key for group: %w", err) } groupChange.GroupMasterKey = groupMasterKey masterKeyBytes := masterKeyToBytes(groupMasterKey) var refetchedAddMemberCredentials bool - var signedGroupChange *signalpb.GroupChange + var signedGroupChange *signalpb.GroupChangeResponse group, err := cli.RetrieveGroupByID(ctx, gid, 0) if err != nil { - log.Err(err).Msg("Failed to retrieve Group") + return 0, fmt.Errorf("failed to fetch group info to update: %w", err) } if group.InviteLinkPassword == nil && groupChange.ModifyAddFromInviteLinkAccess != nil && groupChange.ModifyInviteLinkPassword != nil { groupChange.ModifyInviteLinkPassword = ptr.Ptr(GenerateInviteLinkPassword()) } groupChange.Revision = group.Revision + 1 - for attempt := 0; attempt < 5; attempt++ { - signedGroupChange, err = cli.EncryptAndSignGroupChange(ctx, groupChange, gid) - if errors.Is(err, GroupPatchNotAcceptedError) { - log.Warn().Str("Error applying GroupChange, retrying...", err.Error()) + for attempt := 0; ; attempt++ { + signedGroupChange, err = cli.EncryptAndSignGroupChange(ctx, groupChange) + if err == nil { + break + } else if attempt >= 5 { + return 0, fmt.Errorf("failed to encrypt and sign group change after multiple retries: %w", err) + } else if errors.Is(err, GroupPatchNotAcceptedError) { + log.Err(err).Msg("Failed to apply group change, retrying...") if len(groupChange.AddMembers) > 0 && !refetchedAddMemberCredentials { refetchedAddMemberCredentials = true // change = refetchAddMemberCredentials(change); TODO } else { - return 0, fmt.Errorf("Group Change Failed: %w", err) + return 0, fmt.Errorf("failed to update group: %w", err) } } else if errors.Is(err, ConflictError) { delete(cli.GroupCache.groups, gid) delete(cli.GroupCache.lastFetched, gid) delete(cli.GroupCache.activeCalls, gid) group, err = cli.RetrieveGroupByID(ctx, gid, 0) + if err != nil { + return 0, fmt.Errorf("failed to fetch group after conflict: %w", err) + } groupChange.resolveConflict(group) - if groupChange.isEmptpy() { + if groupChange.isEmpty() { log.Debug().Msg("Change is empty after conflict resolution") } groupChange.Revision = group.Revision + 1 } else { - break + return 0, fmt.Errorf("unknown error encrypting and signing group change: %w", err) } } delete(cli.GroupCache.groups, gid) delete(cli.GroupCache.lastFetched, gid) delete(cli.GroupCache.activeCalls, gid) - if err != nil { - log.Err(err).Msg("couldn't patch group on server") - return 0, err + if signedGroupChange == nil { + return 0, fmt.Errorf("no signed group change returned: %w", err) } - groupChangeBytes, err := proto.Marshal(signedGroupChange) + groupChangeBytes, err := proto.Marshal(signedGroupChange.GroupChange) if err != nil { - log.Err(err).Msg("Error marshalling signed GroupChange") - return 0, err + return 0, fmt.Errorf("failed to marshal signed group change: %w", err) + } + groupContext := &signalpb.GroupContextV2{ + Revision: &groupChange.Revision, + GroupChange: groupChangeBytes, + MasterKey: masterKeyBytes[:], } - groupContext := &signalpb.GroupContextV2{Revision: &groupChange.Revision, GroupChange: groupChangeBytes, MasterKey: masterKeyBytes[:]} _, err = cli.SendGroupUpdate(ctx, group, groupContext, groupChange) if err != nil { log.Err(err).Msg("Error sending GroupChange to group members") @@ -1718,7 +1731,7 @@ func (cli *Client) createGroupOnServer(ctx context.Context, decryptedGroup *Grou log.Err(err).Msg("Failed to get Authorization for today") return nil, err } - path := "/v1/groups/" + path := "/v2/groups/" requestBody, err := proto.Marshal(encryptedGroup) if err != nil { log.Err(err).Msg("Failed to marshal request") @@ -1751,11 +1764,7 @@ func (cli *Client) createGroupOnServer(ctx context.Context, decryptedGroup *Grou case http.StatusBadRequest: return nil, fmt.Errorf("failed to put new group: bad request") } - group, err := cli.fetchGroupWithMasterKey(ctx, decryptedGroup.GroupMasterKey) - if err != nil { - return nil, fmt.Errorf("failed to get new group: %w", err) - } - return group, nil + return cli.parseGroupResponse(ctx, resp, decryptedGroup.GroupMasterKey) } func GenerateInviteLinkPassword() types.SerializedInviteLinkPassword { @@ -1801,7 +1810,7 @@ func (cli *Client) GetGroupHistoryPage(ctx context.Context, gid types.GroupIdent Host: web.StorageHostname, } // highest known epoch seems to always be 5, but that may change in the future. includeLastState is always false - path := fmt.Sprintf("/v1/groups/logs/%d?maxSupportedChangeEpoch=%d&includeFirstState=%t&includeLastState=false", fromRevision, 5, includeFirstState) + path := fmt.Sprintf("/v2/groups/logs/%d?maxSupportedChangeEpoch=%d&includeFirstState=%t&includeLastState=false", fromRevision, 5, includeFirstState) response, err := web.SendHTTPRequest(ctx, http.MethodGet, path, opts) if err != nil { return nil, err From 4843285488d5b2c6b422dd3eec2da068e9b092ff Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Tue, 30 Sep 2025 16:56:37 +0300 Subject: [PATCH 416/580] dependencies: update mautrix-go --- go.mod | 4 ++-- go.sum | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/go.mod b/go.mod index 9ead914..3366ff4 100644 --- a/go.mod +++ b/go.mod @@ -12,13 +12,13 @@ require ( github.com/rs/zerolog v1.34.0 github.com/stretchr/testify v1.11.1 github.com/tidwall/gjson v1.18.0 - go.mau.fi/util v0.9.1 + go.mau.fi/util v0.9.2-0.20250928173307-c0b5f4ee5899 golang.org/x/crypto v0.42.0 golang.org/x/exp v0.0.0-20250911091902-df9299821621 golang.org/x/net v0.44.0 google.golang.org/protobuf v1.36.9 gopkg.in/yaml.v3 v3.0.1 - maunium.net/go/mautrix v0.25.2-0.20250924172949-cf29b07f32ce + maunium.net/go/mautrix v0.25.2-0.20250930123525-329da10584ba ) require ( diff --git a/go.sum b/go.sum index 1e05243..6e3dcca 100644 --- a/go.sum +++ b/go.sum @@ -65,8 +65,8 @@ github.com/tidwall/sjson v1.2.5 h1:kLy8mja+1c9jlljvWTlSazM7cKDRfJuR/bOJhcY5NcY= github.com/tidwall/sjson v1.2.5/go.mod h1:Fvgq9kS/6ociJEDnK0Fk1cpYF4FIW6ZF7LAe+6jwd28= github.com/yuin/goldmark v1.7.13 h1:GPddIs617DnBLFFVJFgpo1aBfe/4xcvMc3SB5t/D0pA= github.com/yuin/goldmark v1.7.13/go.mod h1:ip/1k0VRfGynBgxOz0yCqHrbZXhcjxyuS66Brc7iBKg= -go.mau.fi/util v0.9.1 h1:A+XKHRsjKkFi2qOm4RriR1HqY2hoOXNS3WFHaC89r2Y= -go.mau.fi/util v0.9.1/go.mod h1:M0bM9SyaOWJniaHs9hxEzz91r5ql6gYq6o1q5O1SsjQ= +go.mau.fi/util v0.9.2-0.20250928173307-c0b5f4ee5899 h1:GoPWdX45WrJG/NC+/6u4km9X9UvrzqGGG78z4VlXI7o= +go.mau.fi/util v0.9.2-0.20250928173307-c0b5f4ee5899/go.mod h1:M0bM9SyaOWJniaHs9hxEzz91r5ql6gYq6o1q5O1SsjQ= go.mau.fi/zeroconfig v0.2.0 h1:e/OGEERqVRRKlgaro7E6bh8xXiKFSXB3eNNIud7FUjU= go.mau.fi/zeroconfig v0.2.0/go.mod h1:J0Vn0prHNOm493oZoQ84kq83ZaNCYZnq+noI1b1eN8w= golang.org/x/crypto v0.42.0 h1:chiH31gIWm57EkTXpwnqf8qeuMUi0yekh6mT2AvFlqI= @@ -95,5 +95,5 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= maunium.net/go/mauflag v1.0.0 h1:YiaRc0tEI3toYtJMRIfjP+jklH45uDHtT80nUamyD4M= maunium.net/go/mauflag v1.0.0/go.mod h1:nLivPOpTpHnpzEh8jEdSL9UqO9+/KBJFmNRlwKfkPeA= -maunium.net/go/mautrix v0.25.2-0.20250924172949-cf29b07f32ce h1:sRBScG2xa66ERjgrX+7D//HorAhmNHwxB2Kzltg+aUg= -maunium.net/go/mautrix v0.25.2-0.20250924172949-cf29b07f32ce/go.mod h1:iSueLJ/2fBaNrsTObGqi1j0cl/loxrtAjmjay1scYD8= +maunium.net/go/mautrix v0.25.2-0.20250930123525-329da10584ba h1:IDm8LrL7PJCPqcKeGgBRTCMotz9DCRA1Ru6RWRVAfCQ= +maunium.net/go/mautrix v0.25.2-0.20250930123525-329da10584ba/go.mod h1:nDkJOInK+FbqroUE7j0M1W0PAmAV+03YZYJKWqpx1/0= From 031ef4d2ddc824b73bf3665959b3cbf4968e7c6b Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Wed, 1 Oct 2025 13:12:51 +0300 Subject: [PATCH 417/580] libsignalgo: add zlib to ldflags --- pkg/libsignalgo/cflags.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/libsignalgo/cflags.go b/pkg/libsignalgo/cflags.go index b86e973..12c1e0c 100644 --- a/pkg/libsignalgo/cflags.go +++ b/pkg/libsignalgo/cflags.go @@ -1,6 +1,6 @@ package libsignalgo /* -#cgo LDFLAGS: -lsignal_ffi -ldl -lm +#cgo LDFLAGS: -lsignal_ffi -ldl -lm -lz */ import "C" From a0e596496ceee20282aefa2fcec2fd35d58b2c7b Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Wed, 1 Oct 2025 14:49:22 +0300 Subject: [PATCH 418/580] groupinfo: add exclude from timeline flag for group resyncs --- go.mod | 4 ++-- go.sum | 8 ++++---- pkg/connector/groupinfo.go | 3 +++ 3 files changed, 9 insertions(+), 6 deletions(-) diff --git a/go.mod b/go.mod index 3366ff4..bfd23cc 100644 --- a/go.mod +++ b/go.mod @@ -12,13 +12,13 @@ require ( github.com/rs/zerolog v1.34.0 github.com/stretchr/testify v1.11.1 github.com/tidwall/gjson v1.18.0 - go.mau.fi/util v0.9.2-0.20250928173307-c0b5f4ee5899 + go.mau.fi/util v0.9.2-0.20251001114608-d99877b9cc10 golang.org/x/crypto v0.42.0 golang.org/x/exp v0.0.0-20250911091902-df9299821621 golang.org/x/net v0.44.0 google.golang.org/protobuf v1.36.9 gopkg.in/yaml.v3 v3.0.1 - maunium.net/go/mautrix v0.25.2-0.20250930123525-329da10584ba + maunium.net/go/mautrix v0.25.2-0.20251001115535-dd778ae0cdaf ) require ( diff --git a/go.sum b/go.sum index 6e3dcca..7cc4a8a 100644 --- a/go.sum +++ b/go.sum @@ -65,8 +65,8 @@ github.com/tidwall/sjson v1.2.5 h1:kLy8mja+1c9jlljvWTlSazM7cKDRfJuR/bOJhcY5NcY= github.com/tidwall/sjson v1.2.5/go.mod h1:Fvgq9kS/6ociJEDnK0Fk1cpYF4FIW6ZF7LAe+6jwd28= github.com/yuin/goldmark v1.7.13 h1:GPddIs617DnBLFFVJFgpo1aBfe/4xcvMc3SB5t/D0pA= github.com/yuin/goldmark v1.7.13/go.mod h1:ip/1k0VRfGynBgxOz0yCqHrbZXhcjxyuS66Brc7iBKg= -go.mau.fi/util v0.9.2-0.20250928173307-c0b5f4ee5899 h1:GoPWdX45WrJG/NC+/6u4km9X9UvrzqGGG78z4VlXI7o= -go.mau.fi/util v0.9.2-0.20250928173307-c0b5f4ee5899/go.mod h1:M0bM9SyaOWJniaHs9hxEzz91r5ql6gYq6o1q5O1SsjQ= +go.mau.fi/util v0.9.2-0.20251001114608-d99877b9cc10 h1:EvX/di02gOriKN0xGDJuQ5mgiNdAF4LJc8moffI7Svo= +go.mau.fi/util v0.9.2-0.20251001114608-d99877b9cc10/go.mod h1:M0bM9SyaOWJniaHs9hxEzz91r5ql6gYq6o1q5O1SsjQ= go.mau.fi/zeroconfig v0.2.0 h1:e/OGEERqVRRKlgaro7E6bh8xXiKFSXB3eNNIud7FUjU= go.mau.fi/zeroconfig v0.2.0/go.mod h1:J0Vn0prHNOm493oZoQ84kq83ZaNCYZnq+noI1b1eN8w= golang.org/x/crypto v0.42.0 h1:chiH31gIWm57EkTXpwnqf8qeuMUi0yekh6mT2AvFlqI= @@ -95,5 +95,5 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= maunium.net/go/mauflag v1.0.0 h1:YiaRc0tEI3toYtJMRIfjP+jklH45uDHtT80nUamyD4M= maunium.net/go/mauflag v1.0.0/go.mod h1:nLivPOpTpHnpzEh8jEdSL9UqO9+/KBJFmNRlwKfkPeA= -maunium.net/go/mautrix v0.25.2-0.20250930123525-329da10584ba h1:IDm8LrL7PJCPqcKeGgBRTCMotz9DCRA1Ru6RWRVAfCQ= -maunium.net/go/mautrix v0.25.2-0.20250930123525-329da10584ba/go.mod h1:nDkJOInK+FbqroUE7j0M1W0PAmAV+03YZYJKWqpx1/0= +maunium.net/go/mautrix v0.25.2-0.20251001115535-dd778ae0cdaf h1:prmIYgiziW4A8H2v/TliQ7fis8uTWblabxyPIeLFlNg= +maunium.net/go/mautrix v0.25.2-0.20251001115535-dd778ae0cdaf/go.mod h1:eWXuX2UAGye4AU7i/8Fv2L2Nh7L9kZtuv3R0O0n1KaM= diff --git a/pkg/connector/groupinfo.go b/pkg/connector/groupinfo.go index 6baa3d6..56256c5 100644 --- a/pkg/connector/groupinfo.go +++ b/pkg/connector/groupinfo.go @@ -114,6 +114,7 @@ func (s *SignalClient) wrapGroupInfo(ctx context.Context, groupInfo *signalmeow. event.StatePowerLevels: moderatorPL, }, }, + ExcludeChangesFromTimeline: true, } applyAnnouncementsOnly(members.PowerLevels, groupInfo.AnnouncementsOnly) joinRule := event.JoinRuleInvite @@ -185,6 +186,8 @@ func (s *SignalClient) wrapGroupInfo(ctx context.Context, groupInfo *signalmeow. JoinRule: &event.JoinRulesEventContent{JoinRule: joinRule}, ExtraUpdates: bridgev2.MergeExtraUpdaters(makeRevisionUpdater(groupInfo.Revision), updatePortalSyncMeta), CanBackfill: backupChat != nil, + + ExcludeChangesFromTimeline: true, }, nil } From 89638a95ab355f3fe5f91fbf2358965f3f8a4cb9 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Sun, 5 Oct 2025 00:28:12 +0300 Subject: [PATCH 419/580] signalmeow/provisioning: fix typo in capability name --- pkg/signalmeow/provisioning.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/signalmeow/provisioning.go b/pkg/signalmeow/provisioning.go index 8957018..d0aeb59 100644 --- a/pkg/signalmeow/provisioning.go +++ b/pkg/signalmeow/provisioning.go @@ -360,7 +360,7 @@ func continueProvisioning(ctx context.Context, ws *websocket.Conn, provisioningC var signalCapabilities = map[string]any{ "attachmentBackfill": true, - "sqpr": true, + "spqr": true, } var signalCapabilitiesBody = exerrors.Must(json.Marshal(signalCapabilities)) From 40a0d8525c3282e608fa3d1f92f13817aa101de8 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Sun, 5 Oct 2025 00:47:57 +0300 Subject: [PATCH 420/580] libsignal: update to v0.83.0 --- pkg/libsignalgo/libsignal | 2 +- pkg/libsignalgo/libsignal-ffi.h | 24 ++++-------------------- pkg/libsignalgo/prekey.go | 1 - pkg/libsignalgo/prekeybundle.go | 1 - pkg/libsignalgo/version.go | 2 +- 5 files changed, 6 insertions(+), 24 deletions(-) diff --git a/pkg/libsignalgo/libsignal b/pkg/libsignalgo/libsignal index 42ff946..eb7e0e7 160000 --- a/pkg/libsignalgo/libsignal +++ b/pkg/libsignalgo/libsignal @@ -1 +1 @@ -Subproject commit 42ff946228be177c33c147359178455b411d3628 +Subproject commit eb7e0e7d18c76b29a0de706ed8932730f68b677e diff --git a/pkg/libsignalgo/libsignal-ffi.h b/pkg/libsignalgo/libsignal-ffi.h index 0111718..5f503ad 100644 --- a/pkg/libsignalgo/libsignal-ffi.h +++ b/pkg/libsignalgo/libsignal-ffi.h @@ -1606,7 +1606,7 @@ SignalFfiError *signal_connection_manager_clear_proxy(SignalConstPointerConnecti SignalFfiError *signal_connection_manager_destroy(SignalMutPointerConnectionManager p); -SignalFfiError *signal_connection_manager_new(SignalMutPointerConnectionManager *out, uint8_t environment, const char *user_agent, SignalMutPointerBridgedStringMap remote_config); +SignalFfiError *signal_connection_manager_new(SignalMutPointerConnectionManager *out, uint8_t environment, const char *user_agent, SignalMutPointerBridgedStringMap remote_config, uint8_t build_variant); SignalFfiError *signal_connection_manager_on_network_change(SignalConstPointerConnectionManager connection_manager); @@ -1616,7 +1616,7 @@ SignalFfiError *signal_connection_manager_set_invalid_proxy(SignalConstPointerCo SignalFfiError *signal_connection_manager_set_proxy(SignalConstPointerConnectionManager connection_manager, SignalConstPointerConnectionProxyConfig proxy); -SignalFfiError *signal_connection_manager_set_remote_config(SignalConstPointerConnectionManager connection_manager, SignalMutPointerBridgedStringMap remote_config); +SignalFfiError *signal_connection_manager_set_remote_config(SignalConstPointerConnectionManager connection_manager, SignalMutPointerBridgedStringMap remote_config, uint8_t build_variant); SignalFfiError *signal_connection_proxy_config_clone(SignalMutPointerConnectionProxyConfig *new_obj, SignalConstPointerConnectionProxyConfig obj); @@ -1648,7 +1648,7 @@ SignalFfiError *signal_create_call_link_credential_response_check_valid_contents SignalFfiError *signal_decrypt_message(SignalOwnedBuffer *out, SignalConstPointerSignalMessage message, SignalConstPointerProtocolAddress protocol_address, SignalConstPointerFfiSessionStoreStruct session_store, SignalConstPointerFfiIdentityKeyStoreStruct identity_key_store); -SignalFfiError *signal_decrypt_pre_key_message(SignalOwnedBuffer *out, SignalConstPointerPreKeySignalMessage message, SignalConstPointerProtocolAddress protocol_address, SignalConstPointerFfiSessionStoreStruct session_store, SignalConstPointerFfiIdentityKeyStoreStruct identity_key_store, SignalConstPointerFfiPreKeyStoreStruct prekey_store, SignalConstPointerFfiSignedPreKeyStoreStruct signed_prekey_store, SignalConstPointerFfiKyberPreKeyStoreStruct kyber_prekey_store, bool use_pq_ratchet); +SignalFfiError *signal_decrypt_pre_key_message(SignalOwnedBuffer *out, SignalConstPointerPreKeySignalMessage message, SignalConstPointerProtocolAddress protocol_address, SignalConstPointerFfiSessionStoreStruct session_store, SignalConstPointerFfiIdentityKeyStoreStruct identity_key_store, SignalConstPointerFfiPreKeyStoreStruct prekey_store, SignalConstPointerFfiSignedPreKeyStoreStruct signed_prekey_store, SignalConstPointerFfiKyberPreKeyStoreStruct kyber_prekey_store); SignalFfiError *signal_decryption_error_message_clone(SignalMutPointerDecryptionErrorMessage *new_obj, SignalConstPointerDecryptionErrorMessage obj); @@ -1966,9 +1966,7 @@ SignalFfiError *signal_message_new(SignalMutPointerSignalMessage *out, uint8_t m SignalFfiError *signal_message_verify_mac(bool *out, SignalConstPointerSignalMessage msg, SignalConstPointerPublicKey sender_identity_key, SignalConstPointerPublicKey receiver_identity_key, SignalBorrowedBuffer mac_key); -#if defined(SIGNAL_MEDIA_SUPPORTED) SignalFfiError *signal_mp4_sanitizer_sanitize(SignalMutPointerSanitizedMetadata *out, SignalConstPointerFfiInputStreamStruct input, uint64_t len); -#endif SignalFfiError *signal_online_backup_validator_add_frame(SignalMutPointerOnlineBackupValidator backup, SignalBorrowedBuffer frame); @@ -2094,7 +2092,7 @@ SignalFfiError *signal_privatekey_serialize(SignalOwnedBuffer *out, SignalConstP SignalFfiError *signal_privatekey_sign(SignalOwnedBuffer *out, SignalConstPointerPrivateKey key, SignalBorrowedBuffer message); -SignalFfiError *signal_process_prekey_bundle(SignalConstPointerPreKeyBundle bundle, SignalConstPointerProtocolAddress protocol_address, SignalConstPointerFfiSessionStoreStruct session_store, SignalConstPointerFfiIdentityKeyStoreStruct identity_key_store, uint64_t now, bool use_pq_ratchet); +SignalFfiError *signal_process_prekey_bundle(SignalConstPointerPreKeyBundle bundle, SignalConstPointerProtocolAddress protocol_address, SignalConstPointerFfiSessionStoreStruct session_store, SignalConstPointerFfiIdentityKeyStoreStruct identity_key_store, uint64_t now); SignalFfiError *signal_process_sender_key_distribution_message(SignalConstPointerProtocolAddress sender, SignalConstPointerSenderKeyDistributionMessage sender_key_distribution_message, SignalConstPointerFfiSenderKeyStoreStruct store); @@ -2242,25 +2240,15 @@ SignalFfiError *signal_registration_session_get_requested_information(SignalOwne SignalFfiError *signal_registration_session_get_verified(bool *out, SignalConstPointerRegistrationSession session); -#if defined(SIGNAL_MEDIA_SUPPORTED) SignalFfiError *signal_sanitized_metadata_clone(SignalMutPointerSanitizedMetadata *new_obj, SignalConstPointerSanitizedMetadata obj); -#endif -#if defined(SIGNAL_MEDIA_SUPPORTED) SignalFfiError *signal_sanitized_metadata_destroy(SignalMutPointerSanitizedMetadata p); -#endif -#if defined(SIGNAL_MEDIA_SUPPORTED) SignalFfiError *signal_sanitized_metadata_get_data_len(uint64_t *out, SignalConstPointerSanitizedMetadata sanitized); -#endif -#if defined(SIGNAL_MEDIA_SUPPORTED) SignalFfiError *signal_sanitized_metadata_get_data_offset(uint64_t *out, SignalConstPointerSanitizedMetadata sanitized); -#endif -#if defined(SIGNAL_MEDIA_SUPPORTED) SignalFfiError *signal_sanitized_metadata_get_metadata(SignalOwnedBuffer *out, SignalConstPointerSanitizedMetadata sanitized); -#endif SignalFfiError *signal_sealed_sender_multi_recipient_encrypt(SignalOwnedBuffer *out, SignalBorrowedSliceOfConstPointerProtocolAddress recipients, SignalBorrowedSliceOfConstPointerSessionRecord recipient_sessions, SignalBorrowedBuffer excluded_recipients, SignalConstPointerUnidentifiedSenderMessageContent content, SignalConstPointerFfiIdentityKeyStoreStruct identity_key_store); @@ -2466,9 +2454,7 @@ SignalFfiError *signal_sgx_client_state_established_send(SignalOwnedBuffer *out, SignalFfiError *signal_sgx_client_state_initial_request(SignalOwnedBuffer *out, SignalConstPointerSgxClientState obj); -#if defined(SIGNAL_MEDIA_SUPPORTED) SignalFfiError *signal_signal_media_check_available(void); -#endif SignalFfiError *signal_signed_pre_key_record_clone(SignalMutPointerSignedPreKeyRecord *new_obj, SignalConstPointerSignedPreKeyRecord obj); @@ -2556,8 +2542,6 @@ SignalFfiError *signal_validating_mac_initialize(SignalMutPointerValidatingMac * SignalFfiError *signal_validating_mac_update(int32_t *out, SignalMutPointerValidatingMac mac, SignalBorrowedBuffer bytes, uint32_t offset, uint32_t length); -#if defined(SIGNAL_MEDIA_SUPPORTED) SignalFfiError *signal_webp_sanitizer_sanitize(SignalConstPointerFfiSyncInputStreamStruct input); -#endif #endif /* SIGNAL_FFI_H_ */ diff --git a/pkg/libsignalgo/prekey.go b/pkg/libsignalgo/prekey.go index 7713c76..4d01f89 100644 --- a/pkg/libsignalgo/prekey.go +++ b/pkg/libsignalgo/prekey.go @@ -39,7 +39,6 @@ func DecryptPreKey(ctx context.Context, preKeyMessage *PreKeyMessage, fromAddres callbackCtx.wrapPreKeyStore(preKeyStore), callbackCtx.wrapSignedPreKeyStore(signedPreKeyStore), callbackCtx.wrapKyberPreKeyStore(kyberPreKeyStore), - false, // no pq ratchets yet ) runtime.KeepAlive(preKeyMessage) runtime.KeepAlive(fromAddress) diff --git a/pkg/libsignalgo/prekeybundle.go b/pkg/libsignalgo/prekeybundle.go index 7d8536e..4cd5547 100644 --- a/pkg/libsignalgo/prekeybundle.go +++ b/pkg/libsignalgo/prekeybundle.go @@ -37,7 +37,6 @@ func ProcessPreKeyBundle(ctx context.Context, bundle *PreKeyBundle, forAddress * callbackCtx.wrapSessionStore(sessionStore), callbackCtx.wrapIdentityKeyStore(identityStore), now, - false, // no pq ratchets yet ) runtime.KeepAlive(bundle) runtime.KeepAlive(forAddress) diff --git a/pkg/libsignalgo/version.go b/pkg/libsignalgo/version.go index b137e61..82b7589 100644 --- a/pkg/libsignalgo/version.go +++ b/pkg/libsignalgo/version.go @@ -2,4 +2,4 @@ package libsignalgo -const Version = "v0.82.0" +const Version = "v0.83.0" From 58203bf921e2d7866880e3946a62065b27e230ce Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Fri, 10 Oct 2025 17:15:51 +0300 Subject: [PATCH 421/580] signalmeow/provisioning: update link capabilities --- pkg/signalmeow/provisioning.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/signalmeow/provisioning.go b/pkg/signalmeow/provisioning.go index d0aeb59..8e87738 100644 --- a/pkg/signalmeow/provisioning.go +++ b/pkg/signalmeow/provisioning.go @@ -299,7 +299,7 @@ func startProvisioning(ctx context.Context, ws *websocket.Conn, provisioningCiph return "", fmt.Errorf("failed to unmarshal provisioning UUID: %w", err) } - linkCapabilities := []string{"backup4"} + linkCapabilities := []string{"backup4", "backup5"} if !allowBackup { linkCapabilities = []string{} } From aaa4f1f00fecc8150e961ca2536077a65f2f1503 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Fri, 10 Oct 2025 18:41:37 +0300 Subject: [PATCH 422/580] libsignal: update to v0.84.0 --- pkg/libsignalgo/identitykey.go | 7 +++---- pkg/libsignalgo/libsignal | 2 +- pkg/libsignalgo/libsignal-ffi.h | 28 ++++++++++++++++++++++++---- pkg/libsignalgo/version.go | 2 +- 4 files changed, 29 insertions(+), 10 deletions(-) diff --git a/pkg/libsignalgo/identitykey.go b/pkg/libsignalgo/identitykey.go index 7877d22..f35d116 100644 --- a/pkg/libsignalgo/identitykey.go +++ b/pkg/libsignalgo/identitykey.go @@ -114,14 +114,13 @@ func GenerateIdentityKeyPair() (*IdentityKeyPair, error) { } func DeserializeIdentityKeyPair(bytes []byte) (*IdentityKeyPair, error) { - var privateKey C.SignalMutPointerPrivateKey - var publicKey C.SignalMutPointerPublicKey - signalFfiError := C.signal_identitykeypair_deserialize(&privateKey, &publicKey, BytesToBuffer(bytes)) + var keys C.SignalPairOfMutPointerPublicKeyMutPointerPrivateKey + signalFfiError := C.signal_identitykeypair_deserialize(&keys, BytesToBuffer(bytes)) runtime.KeepAlive(bytes) if signalFfiError != nil { return nil, wrapError(signalFfiError) } - return &IdentityKeyPair{publicKey: wrapPublicKey(publicKey.raw), privateKey: wrapPrivateKey(privateKey.raw)}, nil + return &IdentityKeyPair{publicKey: wrapPublicKey(keys.first.raw), privateKey: wrapPrivateKey(keys.second.raw)}, nil } func NewIdentityKeyPair(publicKey *PublicKey, privateKey *PrivateKey) (*IdentityKeyPair, error) { diff --git a/pkg/libsignalgo/libsignal b/pkg/libsignalgo/libsignal index eb7e0e7..c02859f 160000 --- a/pkg/libsignalgo/libsignal +++ b/pkg/libsignalgo/libsignal @@ -1 +1 @@ -Subproject commit eb7e0e7d18c76b29a0de706ed8932730f68b677e +Subproject commit c02859f57552477680fb7928c3c3426193040313 diff --git a/pkg/libsignalgo/libsignal-ffi.h b/pkg/libsignalgo/libsignal-ffi.h index 5f503ad..a516a23 100644 --- a/pkg/libsignalgo/libsignal-ffi.h +++ b/pkg/libsignalgo/libsignal-ffi.h @@ -892,6 +892,21 @@ typedef struct { */ typedef const SignalFfiError *SignalUnwindSafeArgSignalFfiError; +typedef struct { + const char *first; + uint32_t second; +} SignalPairOfc_charu32; + +typedef struct { + const char *first; + SignalOwnedBuffer second; +} SignalPairOfc_charOwnedBufferOfc_uchar; + +typedef struct { + const char *first; + bool second; +} SignalPairOfc_charbool; + typedef struct { SignalFingerprint *raw; } SignalMutPointerFingerprint; @@ -973,6 +988,11 @@ typedef struct { SignalHttpRequest *raw; } SignalMutPointerHttpRequest; +typedef struct { + SignalMutPointerPublicKey first; + SignalMutPointerPrivateKey second; +} SignalPairOfMutPointerPublicKeyMutPointerPrivateKey; + typedef struct { const SignalPrivateKey *raw; } SignalConstPointerPrivateKey; @@ -1680,15 +1700,15 @@ void signal_error_free(SignalFfiError *err); SignalFfiError *signal_error_get_address(SignalMutPointerProtocolAddress *out, SignalUnwindSafeArgSignalFfiError err); -SignalFfiError *signal_error_get_invalid_protocol_address(const char **name_out, uint32_t *device_id_out, const SignalFfiError *err); +SignalFfiError *signal_error_get_invalid_protocol_address(SignalPairOfc_charu32 *out, SignalUnwindSafeArgSignalFfiError err); SignalFfiError *signal_error_get_message(const char **out, SignalUnwindSafeArgSignalFfiError err); SignalFfiError *signal_error_get_our_fingerprint_version(uint32_t *out, SignalUnwindSafeArgSignalFfiError err); -SignalFfiError *signal_error_get_rate_limit_challenge(const char **out_token, SignalOwnedBuffer *out_options, const SignalFfiError *err); +SignalFfiError *signal_error_get_rate_limit_challenge(SignalPairOfc_charOwnedBufferOfc_uchar *out, SignalUnwindSafeArgSignalFfiError err); -SignalFfiError *signal_error_get_registration_error_not_deliverable(const char **out_reason, bool *out_permanent, const SignalFfiError *err); +SignalFfiError *signal_error_get_registration_error_not_deliverable(SignalPairOfc_charbool *out, SignalUnwindSafeArgSignalFfiError err); SignalFfiError *signal_error_get_registration_lock(uint64_t *out_time_remaining_seconds, const char **out_svr2_username, const char **out_svr2_password, const SignalFfiError *err); @@ -1834,7 +1854,7 @@ SignalFfiError *signal_http_request_new_without_body(SignalMutPointerHttpRequest SignalFfiError *signal_identitykey_verify_alternate_identity(bool *out, SignalConstPointerPublicKey public_key, SignalConstPointerPublicKey other_identity, SignalBorrowedBuffer signature); -SignalFfiError *signal_identitykeypair_deserialize(SignalMutPointerPrivateKey *private_key, SignalMutPointerPublicKey *public_key, SignalBorrowedBuffer input); +SignalFfiError *signal_identitykeypair_deserialize(SignalPairOfMutPointerPublicKeyMutPointerPrivateKey *out, SignalBorrowedBuffer input); SignalFfiError *signal_identitykeypair_serialize(SignalOwnedBuffer *out, SignalConstPointerPublicKey public_key, SignalConstPointerPrivateKey private_key); diff --git a/pkg/libsignalgo/version.go b/pkg/libsignalgo/version.go index 82b7589..b859d49 100644 --- a/pkg/libsignalgo/version.go +++ b/pkg/libsignalgo/version.go @@ -2,4 +2,4 @@ package libsignalgo -const Version = "v0.83.0" +const Version = "v0.84.0" From 7e0f1601d2841aaf945352d1ef9883030731ad56 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Fri, 10 Oct 2025 18:46:50 +0300 Subject: [PATCH 423/580] changelog: update --- CHANGELOG.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index b548abd..23bab3b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,9 @@ +# v25.10 (unreleased) + +* Switched to calendar versioning. +* Updated libsignal to v0.84.0. +* Fixed backfill creating incorrect disappearing timer change notices. + # v0.8.7 (2025-09-16) * Removed legacy provisioning API and database legacy migration. From 4889eae088d3f74031b23c8f69d67b566c2eb690 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Tue, 14 Oct 2025 00:20:43 +0300 Subject: [PATCH 424/580] chatinfo: add support for PNIs in group creation --- go.mod | 2 +- go.sum | 4 ++-- pkg/connector/chatinfo.go | 23 +++++++++++++++++------ 3 files changed, 20 insertions(+), 9 deletions(-) diff --git a/go.mod b/go.mod index bfd23cc..1dcea92 100644 --- a/go.mod +++ b/go.mod @@ -18,7 +18,7 @@ require ( golang.org/x/net v0.44.0 google.golang.org/protobuf v1.36.9 gopkg.in/yaml.v3 v3.0.1 - maunium.net/go/mautrix v0.25.2-0.20251001115535-dd778ae0cdaf + maunium.net/go/mautrix v0.25.2-0.20251013212004-097813c9b29b ) require ( diff --git a/go.sum b/go.sum index 7cc4a8a..eaf756c 100644 --- a/go.sum +++ b/go.sum @@ -95,5 +95,5 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= maunium.net/go/mauflag v1.0.0 h1:YiaRc0tEI3toYtJMRIfjP+jklH45uDHtT80nUamyD4M= maunium.net/go/mauflag v1.0.0/go.mod h1:nLivPOpTpHnpzEh8jEdSL9UqO9+/KBJFmNRlwKfkPeA= -maunium.net/go/mautrix v0.25.2-0.20251001115535-dd778ae0cdaf h1:prmIYgiziW4A8H2v/TliQ7fis8uTWblabxyPIeLFlNg= -maunium.net/go/mautrix v0.25.2-0.20251001115535-dd778ae0cdaf/go.mod h1:eWXuX2UAGye4AU7i/8Fv2L2Nh7L9kZtuv3R0O0n1KaM= +maunium.net/go/mautrix v0.25.2-0.20251013212004-097813c9b29b h1:cRR925ki45mwOA5lb6tjWYxV8YAG00/anpTRH2SJfvA= +maunium.net/go/mautrix v0.25.2-0.20251013212004-097813c9b29b/go.mod h1:eWXuX2UAGye4AU7i/8Fv2L2Nh7L9kZtuv3R0O0n1KaM= diff --git a/pkg/connector/chatinfo.go b/pkg/connector/chatinfo.go index 18ffb36..55dcf9e 100644 --- a/pkg/connector/chatinfo.go +++ b/pkg/connector/chatinfo.go @@ -240,7 +240,7 @@ func (s *SignalClient) ResolveIdentifier(ctx context.Context, number string, cre func (s *SignalClient) CreateGroup(ctx context.Context, params *bridgev2.GroupCreateParams) (*bridgev2.CreateChatResponse, error) { group := &signalmeow.Group{ Title: ptr.Val(params.Name).Name, - Members: make([]*signalmeow.GroupMember, len(params.Participants)+1), + Members: make([]*signalmeow.GroupMember, 1, len(params.Participants)+1), Description: ptr.Val(params.Topic).Topic, AnnouncementsOnly: false, DisappearingMessagesDuration: uint32(ptr.Val(params.Disappear).Timer.Seconds()), @@ -267,14 +267,25 @@ func (s *SignalClient) CreateGroup(ctx context.Context, params *bridgev2.GroupCr ACI: s.Client.Store.ACI, Role: signalmeow.GroupMember_ADMINISTRATOR, } - for i, member := range params.Participants { - userID, err := signalid.ParseUserID(member) + currentTS := uint64(time.Now().UnixMilli()) + for _, member := range params.Participants { + userID, err := signalid.ParseUserIDAsServiceID(member) if err != nil { return nil, fmt.Errorf("invalid user ID %q: %w", member, err) } - group.Members[i+1] = &signalmeow.GroupMember{ - ACI: userID, - Role: signalmeow.GroupMember_DEFAULT, // TODO set proper role from power levels + if userID.Type == libsignalgo.ServiceIDTypeACI { + group.Members = append(group.Members, &signalmeow.GroupMember{ + ACI: userID.UUID, + Role: signalmeow.GroupMember_DEFAULT, // TODO set proper role from power levels + }) + } else if userID.Type == libsignalgo.ServiceIDTypePNI { + // TODO check if this is correct + group.PendingMembers = append(group.PendingMembers, &signalmeow.PendingMember{ + ServiceID: userID, + Role: signalmeow.GroupMember_DEFAULT, + AddedByUserID: s.Client.Store.ACI, + Timestamp: currentTS, + }) } } _, err := signalmeow.PrepareGroupCreation(group) From 422291c80452ddbbf6760db66977220797b078e5 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Thu, 16 Oct 2025 12:05:32 +0200 Subject: [PATCH 425/580] Bump version to v25.10 --- CHANGELOG.md | 2 +- cmd/mautrix-signal/main.go | 3 ++- go.mod | 18 +++++++++--------- go.sum | 36 ++++++++++++++++++------------------ 4 files changed, 30 insertions(+), 29 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 23bab3b..9135702 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,4 @@ -# v25.10 (unreleased) +# v25.10 * Switched to calendar versioning. * Updated libsignal to v0.84.0. diff --git a/cmd/mautrix-signal/main.go b/cmd/mautrix-signal/main.go index 01e3793..73a2921 100644 --- a/cmd/mautrix-signal/main.go +++ b/cmd/mautrix-signal/main.go @@ -34,7 +34,8 @@ var m = mxmain.BridgeMain{ Name: "mautrix-signal", URL: "https://github.com/mautrix/signal", Description: "A Matrix-Signal puppeting bridge.", - Version: "0.8.7", + Version: "25.10", + SemCalVer: true, Connector: &connector.SignalConnector{}, } diff --git a/go.mod b/go.mod index 1dcea92..d57b356 100644 --- a/go.mod +++ b/go.mod @@ -2,7 +2,7 @@ module go.mau.fi/mautrix-signal go 1.24.0 -toolchain go1.25.1 +toolchain go1.25.3 require ( github.com/coder/websocket v1.8.14 @@ -12,13 +12,13 @@ require ( github.com/rs/zerolog v1.34.0 github.com/stretchr/testify v1.11.1 github.com/tidwall/gjson v1.18.0 - go.mau.fi/util v0.9.2-0.20251001114608-d99877b9cc10 - golang.org/x/crypto v0.42.0 - golang.org/x/exp v0.0.0-20250911091902-df9299821621 - golang.org/x/net v0.44.0 - google.golang.org/protobuf v1.36.9 + go.mau.fi/util v0.9.2 + golang.org/x/crypto v0.43.0 + golang.org/x/exp v0.0.0-20251009144603-d2f985daa21b + golang.org/x/net v0.46.0 + google.golang.org/protobuf v1.36.10 gopkg.in/yaml.v3 v3.0.1 - maunium.net/go/mautrix v0.25.2-0.20251013212004-097813c9b29b + maunium.net/go/mautrix v0.25.2 ) require ( @@ -41,8 +41,8 @@ require ( github.com/yuin/goldmark v1.7.13 // indirect go.mau.fi/zeroconfig v0.2.0 // indirect golang.org/x/sync v0.17.0 // indirect - golang.org/x/sys v0.36.0 // indirect - golang.org/x/text v0.29.0 // indirect + golang.org/x/sys v0.37.0 // indirect + golang.org/x/text v0.30.0 // indirect gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect gopkg.in/natefinch/lumberjack.v2 v2.2.1 // indirect maunium.net/go/mauflag v1.0.0 // indirect diff --git a/go.sum b/go.sum index eaf756c..da6cc5e 100644 --- a/go.sum +++ b/go.sum @@ -12,8 +12,8 @@ github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs github.com/emersion/go-vcard v0.0.0-20241024213814-c9703dde27ff h1:4N8wnS3f1hNHSmFD5zgFkWCyA4L1kCDkImPAtK7D6tg= github.com/emersion/go-vcard v0.0.0-20241024213814-c9703dde27ff/go.mod h1:HMJKR5wlh/ziNp+sHEDV2ltblO4JD2+IdDOWtGcQBTM= github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= -github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= -github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= +github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= @@ -65,27 +65,27 @@ github.com/tidwall/sjson v1.2.5 h1:kLy8mja+1c9jlljvWTlSazM7cKDRfJuR/bOJhcY5NcY= github.com/tidwall/sjson v1.2.5/go.mod h1:Fvgq9kS/6ociJEDnK0Fk1cpYF4FIW6ZF7LAe+6jwd28= github.com/yuin/goldmark v1.7.13 h1:GPddIs617DnBLFFVJFgpo1aBfe/4xcvMc3SB5t/D0pA= github.com/yuin/goldmark v1.7.13/go.mod h1:ip/1k0VRfGynBgxOz0yCqHrbZXhcjxyuS66Brc7iBKg= -go.mau.fi/util v0.9.2-0.20251001114608-d99877b9cc10 h1:EvX/di02gOriKN0xGDJuQ5mgiNdAF4LJc8moffI7Svo= -go.mau.fi/util v0.9.2-0.20251001114608-d99877b9cc10/go.mod h1:M0bM9SyaOWJniaHs9hxEzz91r5ql6gYq6o1q5O1SsjQ= +go.mau.fi/util v0.9.2 h1:+S4Z03iCsGqU2WY8X2gySFsFjaLlUHFRDVCYvVwynKM= +go.mau.fi/util v0.9.2/go.mod h1:055elBBCJSdhRsmub7ci9hXZPgGr1U6dYg44cSgRgoU= go.mau.fi/zeroconfig v0.2.0 h1:e/OGEERqVRRKlgaro7E6bh8xXiKFSXB3eNNIud7FUjU= go.mau.fi/zeroconfig v0.2.0/go.mod h1:J0Vn0prHNOm493oZoQ84kq83ZaNCYZnq+noI1b1eN8w= -golang.org/x/crypto v0.42.0 h1:chiH31gIWm57EkTXpwnqf8qeuMUi0yekh6mT2AvFlqI= -golang.org/x/crypto v0.42.0/go.mod h1:4+rDnOTJhQCx2q7/j6rAN5XDw8kPjeaXEUR2eL94ix8= -golang.org/x/exp v0.0.0-20250911091902-df9299821621 h1:2id6c1/gto0kaHYyrixvknJ8tUK/Qs5IsmBtrc+FtgU= -golang.org/x/exp v0.0.0-20250911091902-df9299821621/go.mod h1:TwQYMMnGpvZyc+JpB/UAuTNIsVJifOlSkrZkhcvpVUk= -golang.org/x/net v0.44.0 h1:evd8IRDyfNBMBTTY5XRF1vaZlD+EmWx6x8PkhR04H/I= -golang.org/x/net v0.44.0/go.mod h1:ECOoLqd5U3Lhyeyo/QDCEVQ4sNgYsqvCZ722XogGieY= +golang.org/x/crypto v0.43.0 h1:dduJYIi3A3KOfdGOHX8AVZ/jGiyPa3IbBozJ5kNuE04= +golang.org/x/crypto v0.43.0/go.mod h1:BFbav4mRNlXJL4wNeejLpWxB7wMbc79PdRGhWKncxR0= +golang.org/x/exp v0.0.0-20251009144603-d2f985daa21b h1:18qgiDvlvH7kk8Ioa8Ov+K6xCi0GMvmGfGW0sgd/SYA= +golang.org/x/exp v0.0.0-20251009144603-d2f985daa21b/go.mod h1:j/pmGrbnkbPtQfxEe5D0VQhZC6qKbfKifgD0oM7sR70= +golang.org/x/net v0.46.0 h1:giFlY12I07fugqwPuWJi68oOnpfqFnJIJzaIIm2JVV4= +golang.org/x/net v0.46.0/go.mod h1:Q9BGdFy1y4nkUwiLvT5qtyhAnEHgnQ/zd8PfU6nc210= golang.org/x/sync v0.17.0 h1:l60nONMj9l5drqw6jlhIELNv9I0A4OFgRsG9k2oT9Ug= golang.org/x/sync v0.17.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.36.0 h1:KVRy2GtZBrk1cBYA7MKu5bEZFxQk4NIDV6RLVcC8o0k= -golang.org/x/sys v0.36.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= -golang.org/x/text v0.29.0 h1:1neNs90w9YzJ9BocxfsQNHKuAT4pkghyXc4nhZ6sJvk= -golang.org/x/text v0.29.0/go.mod h1:7MhJOA9CD2qZyOKYazxdYMF85OwPdEr9jTtBpO7ydH4= -google.golang.org/protobuf v1.36.9 h1:w2gp2mA27hUeUzj9Ex9FBjsBm40zfaDtEWow293U7Iw= -google.golang.org/protobuf v1.36.9/go.mod h1:fuxRtAxBytpl4zzqUh6/eyUujkJdNiuEkXntxiD/uRU= +golang.org/x/sys v0.37.0 h1:fdNQudmxPjkdUTPnLn5mdQv7Zwvbvpaxqs831goi9kQ= +golang.org/x/sys v0.37.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= +golang.org/x/text v0.30.0 h1:yznKA/E9zq54KzlzBEAWn1NXSQ8DIp/NYMy88xJjl4k= +golang.org/x/text v0.30.0/go.mod h1:yDdHFIX9t+tORqspjENWgzaCVXgk0yYnYuSZ8UzzBVM= +google.golang.org/protobuf v1.36.10 h1:AYd7cD/uASjIL6Q9LiTjz8JLcrh/88q5UObnmY3aOOE= +google.golang.org/protobuf v1.36.10/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= @@ -95,5 +95,5 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= maunium.net/go/mauflag v1.0.0 h1:YiaRc0tEI3toYtJMRIfjP+jklH45uDHtT80nUamyD4M= maunium.net/go/mauflag v1.0.0/go.mod h1:nLivPOpTpHnpzEh8jEdSL9UqO9+/KBJFmNRlwKfkPeA= -maunium.net/go/mautrix v0.25.2-0.20251013212004-097813c9b29b h1:cRR925ki45mwOA5lb6tjWYxV8YAG00/anpTRH2SJfvA= -maunium.net/go/mautrix v0.25.2-0.20251013212004-097813c9b29b/go.mod h1:eWXuX2UAGye4AU7i/8Fv2L2Nh7L9kZtuv3R0O0n1KaM= +maunium.net/go/mautrix v0.25.2 h1:CUG23zp754yGOTMh9Q4mVSENS9FyweE/G+6ZsPDMCUU= +maunium.net/go/mautrix v0.25.2/go.mod h1:EWgYyp2iFZP7pnSm+rufHlO8YVnA2KnoNBDpwekiAwI= From 11e0e970675a5ead29047518f1fa038365476bfc Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Mon, 20 Oct 2025 11:22:33 +0300 Subject: [PATCH 426/580] client: use transient disconnect for all network errors --- go.mod | 2 +- go.sum | 4 ++-- pkg/connector/client.go | 17 ++++++++--------- 3 files changed, 11 insertions(+), 12 deletions(-) diff --git a/go.mod b/go.mod index d57b356..0613f9b 100644 --- a/go.mod +++ b/go.mod @@ -18,7 +18,7 @@ require ( golang.org/x/net v0.46.0 google.golang.org/protobuf v1.36.10 gopkg.in/yaml.v3 v3.0.1 - maunium.net/go/mautrix v0.25.2 + maunium.net/go/mautrix v0.25.3-0.20251020084845-56b182f85d04 ) require ( diff --git a/go.sum b/go.sum index da6cc5e..560e1b9 100644 --- a/go.sum +++ b/go.sum @@ -95,5 +95,5 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= maunium.net/go/mauflag v1.0.0 h1:YiaRc0tEI3toYtJMRIfjP+jklH45uDHtT80nUamyD4M= maunium.net/go/mauflag v1.0.0/go.mod h1:nLivPOpTpHnpzEh8jEdSL9UqO9+/KBJFmNRlwKfkPeA= -maunium.net/go/mautrix v0.25.2 h1:CUG23zp754yGOTMh9Q4mVSENS9FyweE/G+6ZsPDMCUU= -maunium.net/go/mautrix v0.25.2/go.mod h1:EWgYyp2iFZP7pnSm+rufHlO8YVnA2KnoNBDpwekiAwI= +maunium.net/go/mautrix v0.25.3-0.20251020084845-56b182f85d04 h1:OPcp3Bh6PyF282Siq7/d84XZHaNSm74N9VINAeYEQys= +maunium.net/go/mautrix v0.25.3-0.20251020084845-56b182f85d04/go.mod h1:EWgYyp2iFZP7pnSm+rufHlO8YVnA2KnoNBDpwekiAwI= diff --git a/pkg/connector/client.go b/pkg/connector/client.go index 27cea14..8da1723 100644 --- a/pkg/connector/client.go +++ b/pkg/connector/client.go @@ -189,7 +189,7 @@ func (s *SignalClient) bridgeStateLoop(statusChan <-chan signalmeow.SignalConnec case signalmeow.SignalConnectionEventError: s.UserLogin.Log.Debug().Msg("Sending UnknownError BridgeState") - s.UserLogin.BridgeState.Send(status.BridgeState{StateEvent: status.StateUnknownError, Error: "unknown-websocket-error", Message: err.Error()}) + s.UserLogin.BridgeState.Send(status.BridgeState{StateEvent: status.StateTransientDisconnect, Error: "unknown-websocket-error", Message: err.Error()}) case signalmeow.SignalConnectionCleanShutdown: if s.Client.IsLoggedIn() { @@ -303,15 +303,14 @@ func (s *SignalClient) tryConnect(ctx context.Context, retryCount int, doSync bo ch, err := s.Client.StartReceiveLoops(ctx) if err != nil { zerolog.Ctx(ctx).Err(err).Msg("Failed to start receive loops") - if retryCount < 6 { - s.UserLogin.BridgeState.Send(status.BridgeState{StateEvent: status.StateTransientDisconnect, Error: "unknown-websocket-error", Message: err.Error()}) - retryInSeconds := 2 << retryCount - zerolog.Ctx(ctx).Debug().Int("retry_in_seconds", retryInSeconds).Msg("Sleeping and retrying connection") - time.Sleep(time.Duration(retryInSeconds) * time.Second) - s.tryConnect(ctx, retryCount+1, doSync) - } else { - s.UserLogin.BridgeState.Send(status.BridgeState{StateEvent: status.StateUnknownError, Error: "unknown-websocket-error", Message: err.Error()}) + s.UserLogin.BridgeState.Send(status.BridgeState{StateEvent: status.StateTransientDisconnect, Error: "unknown-websocket-error", Message: err.Error()}) + retryInSeconds := 2 << retryCount + if retryInSeconds > 150 { + retryInSeconds = 150 } + zerolog.Ctx(ctx).Debug().Int("retry_in_seconds", retryInSeconds).Msg("Sleeping and retrying connection") + time.Sleep(time.Duration(retryInSeconds) * time.Second) + s.tryConnect(ctx, retryCount+1, doSync) } else { go s.bridgeStateLoop(ch) if doSync { From 08d70602e195719e6a5d9c8943d13d56c4d3c21b Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Mon, 20 Oct 2025 11:52:14 +0300 Subject: [PATCH 427/580] signalmeow/web: split non-retrying errors into different type --- pkg/connector/client.go | 10 +++++++--- pkg/signalmeow/receiving.go | 11 +++++++++++ pkg/signalmeow/web/signalwebsocket.go | 4 +++- 3 files changed, 21 insertions(+), 4 deletions(-) diff --git a/pkg/connector/client.go b/pkg/connector/client.go index 8da1723..0ff578f 100644 --- a/pkg/connector/client.go +++ b/pkg/connector/client.go @@ -188,9 +188,13 @@ func (s *SignalClient) bridgeStateLoop(statusChan <-chan signalmeow.SignalConnec } case signalmeow.SignalConnectionEventError: - s.UserLogin.Log.Debug().Msg("Sending UnknownError BridgeState") + s.UserLogin.Log.Debug().Msg("Sending TransientDisconnect BridgeState") s.UserLogin.BridgeState.Send(status.BridgeState{StateEvent: status.StateTransientDisconnect, Error: "unknown-websocket-error", Message: err.Error()}) + case signalmeow.SignalConnectionEventFatalError: + s.UserLogin.Log.Debug().Msg("Sending UnknownError BridgeState") + s.UserLogin.BridgeState.Send(status.BridgeState{StateEvent: status.StateUnknownError, Error: "unknown-websocket-error", Message: err.Error()}) + case signalmeow.SignalConnectionCleanShutdown: if s.Client.IsLoggedIn() { s.UserLogin.Log.Debug().Msg("Clean Shutdown - sending no BridgeState") @@ -233,7 +237,7 @@ func (s *SignalClient) ConnectBackground(ctx context.Context, _ *bridgev2.Connec case web.SignalWebsocketConnectionEventLoggedOut: log.Err(status.Err).Msg("Authed websocket logged out") return fmt.Errorf("authed websocket logged out: %w", status.Err) - case web.SignalWebsocketConnectionEventError: + case web.SignalWebsocketConnectionEventError, web.SignalWebsocketConnectionEventFatalError: log.Err(status.Err).Msg("Authed websocket error") return fmt.Errorf("authed websocket errored: %w", status.Err) case web.SignalWebsocketConnectionEventCleanShutdown: @@ -247,7 +251,7 @@ func (s *SignalClient) ConnectBackground(ctx context.Context, _ *bridgev2.Connec log.Err(status.Err).Msg("Unauthed websocket disconnected") case web.SignalWebsocketConnectionEventLoggedOut: log.Err(status.Err).Msg("Unauthed websocket logged out") - case web.SignalWebsocketConnectionEventError: + case web.SignalWebsocketConnectionEventError, web.SignalWebsocketConnectionEventFatalError: log.Err(status.Err).Msg("Unauthed websocket error") case web.SignalWebsocketConnectionEventCleanShutdown: log.Info().Msg("Unauthed websocket clean shutdown") diff --git a/pkg/signalmeow/receiving.go b/pkg/signalmeow/receiving.go index 6c97a69..d630386 100644 --- a/pkg/signalmeow/receiving.go +++ b/pkg/signalmeow/receiving.go @@ -46,6 +46,7 @@ const ( SignalConnectionEventDisconnected SignalConnectionEventLoggedOut SignalConnectionEventError + SignalConnectionEventFatalError SignalConnectionCleanShutdown ) @@ -56,6 +57,7 @@ var signalConnectionEventNames = map[SignalConnectionEvent]string{ SignalConnectionEventDisconnected: "SignalConnectionEventDisconnected", SignalConnectionEventLoggedOut: "SignalConnectionEventLoggedOut", SignalConnectionEventError: "SignalConnectionEventError", + SignalConnectionEventFatalError: "SignalConnectionEventFatalError", SignalConnectionCleanShutdown: "SignalConnectionCleanShutdown", } @@ -164,6 +166,8 @@ func (cli *Client) StartReceiveLoops(ctx context.Context) (chan SignalConnection //StopReceiveLoops(d) case web.SignalWebsocketConnectionEventError: log.Err(status.Err).Msg("Authed websocket error") + case web.SignalWebsocketConnectionEventFatalError: + log.Err(status.Err).Msg("Authed websocket fatal error") case web.SignalWebsocketConnectionEventCleanShutdown: log.Info().Msg("Authed websocket clean shutdown") } @@ -192,6 +196,8 @@ func (cli *Client) StartReceiveLoops(ctx context.Context) (chan SignalConnection log.Err(status.Err).Msg("Unauthed websocket logged out ** THIS SHOULD BE IMPOSSIBLE **") case web.SignalWebsocketConnectionEventError: log.Err(status.Err).Msg("Unauthed websocket error") + case web.SignalWebsocketConnectionEventFatalError: + log.Err(status.Err).Msg("Unauthed websocket fatal error") case web.SignalWebsocketConnectionEventCleanShutdown: log.Info().Msg("Unauthed websocket clean shutdown") } @@ -221,6 +227,11 @@ func (cli *Client) StartReceiveLoops(ctx context.Context) (chan SignalConnection Event: SignalConnectionEventError, Err: currentStatus.Err, } + } else if currentStatus.Event == web.SignalWebsocketConnectionEventFatalError { + statusToSend = SignalConnectionStatus{ + Event: SignalConnectionEventFatalError, + Err: currentStatus.Err, + } } else if currentStatus.Event == web.SignalWebsocketConnectionEventCleanShutdown { statusToSend = SignalConnectionStatus{ Event: SignalConnectionCleanShutdown, diff --git a/pkg/signalmeow/web/signalwebsocket.go b/pkg/signalmeow/web/signalwebsocket.go index c4572d6..ca09208 100644 --- a/pkg/signalmeow/web/signalwebsocket.go +++ b/pkg/signalmeow/web/signalwebsocket.go @@ -73,6 +73,7 @@ const ( SignalWebsocketConnectionEventDisconnected SignalWebsocketConnectionEventLoggedOut SignalWebsocketConnectionEventError + SignalWebsocketConnectionEventFatalError SignalWebsocketConnectionEventCleanShutdown ) @@ -83,6 +84,7 @@ var signalWebsocketConnectionEventNames = map[SignalWebsocketConnectionEvent]str SignalWebsocketConnectionEventDisconnected: "SignalWebsocketConnectionEventDisconnected", SignalWebsocketConnectionEventLoggedOut: "SignalWebsocketConnectionEventLoggedOut", SignalWebsocketConnectionEventError: "SignalWebsocketConnectionEventError", + SignalWebsocketConnectionEventFatalError: "SignalWebsocketConnectionEventFatalError", SignalWebsocketConnectionEventCleanShutdown: "SignalWebsocketConnectionEventCleanShutdown", } @@ -275,7 +277,7 @@ func (s *SignalWebsocket) connectLoop( return // NOT RETRYING, KILLING THE CONNECTION LOOP } else if resp.StatusCode > 0 && resp.StatusCode < 500 { // Unexpected status code - s.pushStatus(ctx, SignalWebsocketConnectionEventError, fmt.Errorf("unexpected status opening websocket: %v", resp.Status)) + s.pushStatus(ctx, SignalWebsocketConnectionEventFatalError, fmt.Errorf("unexpected status opening websocket: %v", resp.Status)) return // NOT RETRYING, KILLING THE CONNECTION LOOP } else { // Something is very wrong From 865642be07e1c987a7e2e7ce608c5e0d7179ac11 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Mon, 20 Oct 2025 12:36:42 +0300 Subject: [PATCH 428/580] docker: use gitlab dependency proxy for CI builds --- Dockerfile.ci | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Dockerfile.ci b/Dockerfile.ci index dc554ab..7d34502 100644 --- a/Dockerfile.ci +++ b/Dockerfile.ci @@ -1,4 +1,6 @@ -FROM alpine:3.22 +ARG DOCKER_HUB="docker.io" + +FROM ${DOCKER_HUB}/alpine:3.22 ENV UID=1337 \ GID=1337 From d63cf0106bc47a9ff2a6202b782481a14dce3999 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Wed, 22 Oct 2025 21:49:59 +0300 Subject: [PATCH 429/580] all: add support for PNI ghosts to bridge invites/bans (#612) --- go.mod | 2 +- go.sum | 4 +- pkg/connector/chatinfo.go | 75 ++++++++---- pkg/connector/groupinfo.go | 219 ++++++++++++++++------------------ pkg/connector/handlematrix.go | 75 ++++++++---- pkg/connector/id.go | 19 +++ pkg/signalid/ids.go | 33 ++++- pkg/signalmeow/groups.go | 15 +-- 8 files changed, 261 insertions(+), 181 deletions(-) diff --git a/go.mod b/go.mod index 0613f9b..2fabdcc 100644 --- a/go.mod +++ b/go.mod @@ -18,7 +18,7 @@ require ( golang.org/x/net v0.46.0 google.golang.org/protobuf v1.36.10 gopkg.in/yaml.v3 v3.0.1 - maunium.net/go/mautrix v0.25.3-0.20251020084845-56b182f85d04 + maunium.net/go/mautrix v0.25.3-0.20251022182546-33d8d658fe98 ) require ( diff --git a/go.sum b/go.sum index 560e1b9..b7850bf 100644 --- a/go.sum +++ b/go.sum @@ -95,5 +95,5 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= maunium.net/go/mauflag v1.0.0 h1:YiaRc0tEI3toYtJMRIfjP+jklH45uDHtT80nUamyD4M= maunium.net/go/mauflag v1.0.0/go.mod h1:nLivPOpTpHnpzEh8jEdSL9UqO9+/KBJFmNRlwKfkPeA= -maunium.net/go/mautrix v0.25.3-0.20251020084845-56b182f85d04 h1:OPcp3Bh6PyF282Siq7/d84XZHaNSm74N9VINAeYEQys= -maunium.net/go/mautrix v0.25.3-0.20251020084845-56b182f85d04/go.mod h1:EWgYyp2iFZP7pnSm+rufHlO8YVnA2KnoNBDpwekiAwI= +maunium.net/go/mautrix v0.25.3-0.20251022182546-33d8d658fe98 h1:0cTTVYsfTyXaoqFYz4MoHfMv+zps+Gh3dbQtDn4mtHo= +maunium.net/go/mautrix v0.25.3-0.20251022182546-33d8d658fe98/go.mod h1:EWgYyp2iFZP7pnSm+rufHlO8YVnA2KnoNBDpwekiAwI= diff --git a/pkg/connector/chatinfo.go b/pkg/connector/chatinfo.go index 55dcf9e..88cf3e2 100644 --- a/pkg/connector/chatinfo.go +++ b/pkg/connector/chatinfo.go @@ -45,13 +45,16 @@ var ( _ bridgev2.IdentifierResolvingNetworkAPI = (*SignalClient)(nil) _ bridgev2.GroupCreatingNetworkAPI = (*SignalClient)(nil) _ bridgev2.ContactListingNetworkAPI = (*SignalClient)(nil) + _ bridgev2.GhostDMCreatingNetworkAPI = (*SignalClient)(nil) ) +var _ bridgev2.IdentifierValidatingNetwork = (*SignalConnector)(nil) + const PrivateChatTopic = "Signal private chat" const NoteToSelfName = "Signal Note to Self" func (s *SignalClient) GetUserInfoWithRefreshAfter(ctx context.Context, ghost *bridgev2.Ghost, refreshAfter time.Duration) (*bridgev2.UserInfo, error) { - userID, err := signalid.ParseUserID(ghost.ID) + userID, err := signalid.ParseUserIDAsServiceID(ghost.ID) if err != nil { return nil, err } @@ -59,12 +62,17 @@ func (s *SignalClient) GetUserInfoWithRefreshAfter(ctx context.Context, ghost *b // Don't do unnecessary fetches in background mode return nil, nil } - contact, err := s.Client.ContactByACIWithRefreshAfter(ctx, userID, refreshAfter) + var contact *types.Recipient + if userID.Type == libsignalgo.ServiceIDTypePNI { + contact, err = s.Client.Store.RecipientStore.LoadAndUpdateRecipient(ctx, uuid.Nil, userID.UUID, nil) + } else { + contact, err = s.Client.ContactByACIWithRefreshAfter(ctx, userID.UUID, refreshAfter) + } if err != nil { return nil, err } meta := ghost.Metadata.(*signalid.GhostMetadata) - if !s.Main.Config.UseOutdatedProfiles && meta.ProfileFetchedAt.After(contact.Profile.FetchedAt) { + if userID.Type != libsignalgo.ServiceIDTypePNI && (!s.Main.Config.UseOutdatedProfiles && meta.ProfileFetchedAt.After(contact.Profile.FetchedAt)) { return nil, nil } return s.contactToUserInfo(ctx, contact) @@ -157,18 +165,41 @@ func (s *SignalClient) contactToUserInfo(ctx context.Context, contact *types.Rec return ui, nil } -var _ bridgev2.IdentifierValidatingNetwork = (*SignalConnector)(nil) - func (s *SignalConnector) ValidateUserID(id networkid.UserID) bool { _, err := signalid.ParseUserIDAsServiceID(id) return err == nil } -func (s *SignalClient) ResolveIdentifier(ctx context.Context, number string, createChat bool) (*bridgev2.ResolveIdentifierResponse, error) { +func (s *SignalClient) CreateChatWithGhost(ctx context.Context, ghost *bridgev2.Ghost) (*bridgev2.CreateChatResponse, error) { + parsedID, err := signalid.ParseUserIDAsServiceID(ghost.ID) + if err != nil { + return nil, err + } + resp, err := s.ResolveIdentifier(ctx, parsedID.String(), true) + if err != nil { + return nil, err + } else if resp == nil { + return nil, nil + } + resultID, err := signalid.ParseUserIDAsServiceID(resp.UserID) + if err != nil { + return nil, fmt.Errorf("failed to parse result user ID: %w", err) + } + if parsedID.Type == libsignalgo.ServiceIDTypePNI { + if resultID.Type == libsignalgo.ServiceIDTypeACI && !resultID.IsEmpty() { + resp.Chat.DMRedirectedTo = resp.UserID + } else { + resp.Chat.DMRedirectedTo = bridgev2.SpecialValueDMRedirectedToBot + } + } + return resp.Chat, nil +} + +func (s *SignalClient) ResolveIdentifier(ctx context.Context, number string, _ bool) (*bridgev2.ResolveIdentifierResponse, error) { var aci, pni uuid.UUID var e164Number uint64 var recipient *types.Recipient - serviceID, err := libsignalgo.ServiceIDFromString(number) + serviceID, err := signalid.ParseUserIDAsServiceID(networkid.UserID(number)) if err != nil { number, err = bridgev2.CleanPhoneNumber(number) if err != nil { @@ -216,25 +247,23 @@ func (s *SignalClient) ResolveIdentifier(ctx context.Context, number string, cre return nil, fmt.Errorf("failed to convert contact: %w", err) } - // createChat is a no-op: chats don't need to be created, and we always return chat info + var userID networkid.UserID if aci != uuid.Nil { - ghost, err := s.Main.Bridge.GetGhostByID(ctx, signalid.MakeUserID(aci)) - if err != nil { - return nil, fmt.Errorf("failed to get ghost: %w", err) - } - return &bridgev2.ResolveIdentifierResponse{ - UserID: signalid.MakeUserID(aci), - UserInfo: userInfo, - Ghost: ghost, - Chat: s.makeCreateDMResponse(ctx, recipient, nil), - }, nil + userID = signalid.MakeUserID(aci) } else { - return &bridgev2.ResolveIdentifierResponse{ - UserID: signalid.MakeUserIDFromServiceID(libsignalgo.NewPNIServiceID(pni)), - UserInfo: userInfo, - Chat: s.makeCreateDMResponse(ctx, recipient, nil), - }, nil + userID = signalid.MakeUserIDFromServiceID(libsignalgo.NewPNIServiceID(pni)) } + // createChat is a no-op: chats don't need to be created, and we always return chat info + resp := &bridgev2.ResolveIdentifierResponse{ + UserID: userID, + UserInfo: userInfo, + Chat: s.makeCreateDMResponse(ctx, recipient, nil), + } + resp.Ghost, err = s.Main.Bridge.GetGhostByID(ctx, resp.UserID) + if err != nil { + return nil, fmt.Errorf("failed to get ghost: %w", err) + } + return resp, nil } func (s *SignalClient) CreateGroup(ctx context.Context, params *bridgev2.GroupCreateParams) (*bridgev2.CreateChatResponse, error) { diff --git a/pkg/connector/groupinfo.go b/pkg/connector/groupinfo.go index 56256c5..a025fa4 100644 --- a/pkg/connector/groupinfo.go +++ b/pkg/connector/groupinfo.go @@ -123,43 +123,30 @@ func (s *SignalClient) wrapGroupInfo(ctx context.Context, groupInfo *signalmeow. applyMembersAccess(members.PowerLevels, groupInfo.AccessControl.Members) joinRule = inviteLinkToJoinRule(groupInfo.AccessControl.AddFromInviteLink) } - for _, member := range groupInfo.Members { - evtSender := s.makeEventSender(member.ACI) - members.MemberMap[evtSender.Sender] = bridgev2.ChatMember{ - EventSender: evtSender, - PowerLevel: roleToPL(member.Role), - Membership: event.MembershipJoin, - } + for _, member := range groupInfo.RequestingMembers { + members.MemberMap.Set(bridgev2.ChatMember{ + EventSender: s.makeEventSender(member.ACI), + Membership: event.MembershipKnock, + }) } for _, member := range groupInfo.PendingMembers { - aci := s.maybeResolvePNItoACI(ctx, &member.ServiceID) - if aci == nil { - continue - } - evtSender := s.makeEventSender(*aci) - members.MemberMap[evtSender.Sender] = bridgev2.ChatMember{ - EventSender: evtSender, - PowerLevel: roleToPL(member.Role), - Membership: event.MembershipInvite, - } + s.addChatMemberWithACIQuery(ctx, members.MemberMap, member.ServiceID, bridgev2.ChatMember{ + PowerLevel: roleToPL(member.Role), + Membership: event.MembershipInvite, + MemberSender: s.makeEventSender(member.AddedByUserID), + }) } - for _, member := range groupInfo.RequestingMembers { - evtSender := s.makeEventSender(member.ACI) - members.MemberMap[evtSender.Sender] = bridgev2.ChatMember{ - EventSender: evtSender, - Membership: event.MembershipKnock, - } + for _, member := range groupInfo.Members { + members.MemberMap.Set(bridgev2.ChatMember{ + EventSender: s.makeEventSender(member.ACI), + PowerLevel: roleToPL(member.Role), + Membership: event.MembershipJoin, + }) } for _, member := range groupInfo.BannedMembers { - aci := s.maybeResolvePNItoACI(ctx, &member.ServiceID) - if aci == nil { - continue - } - evtSender := s.makeEventSender(*aci) - members.MemberMap[evtSender.Sender] = bridgev2.ChatMember{ - EventSender: evtSender, - Membership: event.MembershipBan, - } + s.addChatMemberWithACIQuery(ctx, members.MemberMap, member.ServiceID, bridgev2.ChatMember{ + Membership: event.MembershipBan, + }) } if backupChat == nil { var err error @@ -191,6 +178,10 @@ func (s *SignalClient) wrapGroupInfo(ctx context.Context, groupInfo *signalmeow. }, nil } +func addMemberToMap(mc map[networkid.UserID]bridgev2.ChatMember, member bridgev2.ChatMember) { + mc[member.EventSender.Sender] = member +} + func updatePortalSyncMeta(ctx context.Context, portal *bridgev2.Portal) bool { meta := portal.Metadata.(*signalid.PortalMetadata) meta.LastSync = jsontime.UnixNow() @@ -286,131 +277,127 @@ func (s *SignalClient) groupChangeToChatInfoChange(ctx context.Context, groupID JoinRule: inviteLinkToJoinRule(*groupChange.ModifyAddFromInviteLinkAccess), } } - var mc []bridgev2.ChatMember - for _, member := range groupChange.AddMembers { - mc = append(mc, bridgev2.ChatMember{ - EventSender: s.makeEventSender(member.ACI), - PowerLevel: roleToPL(member.Role), - Membership: event.MembershipJoin, - }) - } - for _, member := range groupChange.ModifyMemberRoles { - mc = append(mc, bridgev2.ChatMember{ - EventSender: s.makeEventSender(member.ACI), - PowerLevel: roleToPL(member.Role), - Membership: event.MembershipJoin, - }) - } - bannedMembers := make(map[libsignalgo.ServiceID]bool) - for _, member := range groupChange.AddBannedMembers { - aci := s.maybeResolvePNItoACI(ctx, &member.ServiceID) - if aci == nil { - continue - } - bannedMembers[member.ServiceID] = true - mc = append(mc, bridgev2.ChatMember{ - EventSender: s.makeEventSender(*aci), - Membership: event.MembershipBan, - }) - } - for _, memberACI := range groupChange.DeleteMembers { - if bannedMembers[libsignalgo.NewACIServiceID(*memberACI)] { - continue - } - mc = append(mc, bridgev2.ChatMember{ - EventSender: s.makeEventSender(*memberACI), - Membership: event.MembershipLeave, - PrevMembership: event.MembershipJoin, - }) - } + mc := make(bridgev2.ChatMemberMap) for _, member := range groupChange.AddPendingMembers { - aci := s.maybeResolvePNItoACI(ctx, &member.ServiceID) - if aci == nil { - continue - } - mc = append(mc, bridgev2.ChatMember{ - EventSender: s.makeEventSender(*aci), - PowerLevel: roleToPL(member.Role), - Membership: event.MembershipInvite, - }) - } - for _, memberServiceID := range groupChange.DeletePendingMembers { - if bannedMembers[*memberServiceID] { - continue - } - aci := s.maybeResolvePNItoACI(ctx, memberServiceID) - if aci == nil { - continue - } - mc = append(mc, bridgev2.ChatMember{ - EventSender: s.makeEventSender(*aci), - Membership: event.MembershipLeave, - PrevMembership: event.MembershipInvite, + s.addChatMemberWithACIQuery(ctx, mc, member.ServiceID, bridgev2.ChatMember{ + PowerLevel: roleToPL(member.Role), + Membership: event.MembershipInvite, + PrevMembership: event.MembershipLeave, + MemberSender: s.makeEventSender(member.AddedByUserID), }) } for _, member := range groupChange.AddRequestingMembers { - mc = append(mc, bridgev2.ChatMember{ + mc.Set(bridgev2.ChatMember{ EventSender: s.makeEventSender(member.ACI), Membership: event.MembershipKnock, }) } + for _, memberServiceID := range groupChange.DeletePendingMembers { + s.addChatMemberWithACIQuery(ctx, mc, *memberServiceID, bridgev2.ChatMember{ + Membership: event.MembershipLeave, + PrevMembership: event.MembershipInvite, + }) + } for _, memberACI := range groupChange.DeleteRequestingMembers { - if bannedMembers[libsignalgo.NewACIServiceID(*memberACI)] { - continue - } - mc = append(mc, bridgev2.ChatMember{ + mc.Set(bridgev2.ChatMember{ EventSender: s.makeEventSender(*memberACI), Membership: event.MembershipLeave, PrevMembership: event.MembershipKnock, }) } + for _, memberACI := range groupChange.DeleteMembers { + mc.Set(bridgev2.ChatMember{ + EventSender: s.makeEventSender(*memberACI), + Membership: event.MembershipLeave, + PrevMembership: event.MembershipJoin, + }) + } for _, memberServiceID := range groupChange.DeleteBannedMembers { - aci := s.maybeResolvePNItoACI(ctx, memberServiceID) - if aci == nil { - continue - } - mc = append(mc, bridgev2.ChatMember{ - EventSender: s.makeEventSender(*aci), + s.addChatMemberWithACIQuery(ctx, mc, *memberServiceID, bridgev2.ChatMember{ Membership: event.MembershipLeave, PrevMembership: event.MembershipBan, }) } + for _, member := range groupChange.AddBannedMembers { + s.addChatMemberWithACIQuery(ctx, mc, member.ServiceID, bridgev2.ChatMember{ + Membership: event.MembershipBan, + }) + } for _, member := range groupChange.PromotePendingMembers { - mc = append(mc, bridgev2.ChatMember{ + mc.Set(bridgev2.ChatMember{ EventSender: s.makeEventSender(member.ACI), Membership: event.MembershipJoin, PrevMembership: event.MembershipInvite, }) } for _, member := range groupChange.PromotePendingPniAciMembers { - mc = append(mc, bridgev2.ChatMember{ - EventSender: s.makeEventSender(member.ACI), - Membership: event.MembershipJoin, + mc.Set(bridgev2.ChatMember{ + EventSender: s.makeEventSender(member.ACI), + Membership: event.MembershipJoin, + }) + mc.Set(bridgev2.ChatMember{ + EventSender: s.makePNIEventSender(member.PNI), + Membership: event.MembershipLeave, PrevMembership: event.MembershipInvite, + MemberEventExtra: map[string]any{ + "com.beeper.exclude_from_timeline": true, + }, }) } for _, member := range groupChange.PromoteRequestingMembers { - mc = append(mc, bridgev2.ChatMember{ + mc.Set(bridgev2.ChatMember{ EventSender: s.makeEventSender(member.ACI), Membership: event.MembershipJoin, PrevMembership: event.MembershipKnock, }) } + for _, member := range groupChange.AddMembers { + mc.Set(bridgev2.ChatMember{ + EventSender: s.makeEventSender(member.ACI), + PowerLevel: roleToPL(member.Role), + Membership: event.MembershipJoin, + }) + } + for _, member := range groupChange.ModifyMemberRoles { + mc.Set(bridgev2.ChatMember{ + EventSender: s.makeEventSender(member.ACI), + PowerLevel: roleToPL(member.Role), + Membership: event.MembershipJoin, + }) + } if len(mc) > 0 || pls != nil { - ic.MemberChanges = &bridgev2.ChatMemberList{Members: mc, PowerLevels: pls} + ic.MemberChanges = &bridgev2.ChatMemberList{MemberMap: mc, PowerLevels: pls} } return ic, nil } -func (s *SignalClient) maybeResolvePNItoACI(ctx context.Context, serviceID *libsignalgo.ServiceID) *uuid.UUID { - if serviceID.Type == libsignalgo.ServiceIDTypeACI { - return &serviceID.UUID +func (s *SignalClient) addChatMemberWithACIQuery( + ctx context.Context, mc bridgev2.ChatMemberMap, serviceID libsignalgo.ServiceID, member bridgev2.ChatMember, +) { + member.EventSender = s.makeEventSenderFromServiceID(serviceID) + mc.Set(member) + if aci := s.tryResolvePNItoLoggedInACI(ctx, serviceID); aci != nil { + member.EventSender = s.makeEventSender(*aci) + mc.Add(member) } - device, err := s.Client.Store.DeviceStore.DeviceByPNI(ctx, serviceID.UUID) - if err != nil || device == nil { +} + +func (s *SignalClient) tryResolvePNItoLoggedInACI(ctx context.Context, serviceID libsignalgo.ServiceID) *uuid.UUID { + if serviceID.Type != libsignalgo.ServiceIDTypePNI { return nil + } else if serviceID.UUID == s.Client.Store.PNI { + return &s.Client.Store.ACI + } else if s.Main.Bridge.Config.SplitPortals { + // When split portals is enabled, we don't care about anyone else's logins + return nil + } else if device, err := s.Client.Store.DeviceStore.DeviceByPNI(ctx, serviceID.UUID); err != nil { + zerolog.Ctx(ctx).Err(err).Msg("Failed to get ACI for PNI") + return nil + } else if device == nil { + return nil + } else { + return &device.ACI } - return &device.ACI } func (s *SignalClient) catchUpGroup(ctx context.Context, portal *bridgev2.Portal, fromRevision, toRevision uint32, ts uint64) { @@ -443,8 +430,8 @@ func (s *SignalClient) catchUpGroup(ctx context.Context, portal *bridgev2.Portal chatInfoChange, err := s.groupChangeToChatInfoChange(ctx, types.GroupIdentifier(portal.ID), gc.GroupChange.Revision, gc.GroupChange) if err != nil { log.Err(err).Msg("Failed to convert group info") - } else if gc.GroupChange.SourceServiceID.Type == libsignalgo.ServiceIDTypeACI { - portal.ProcessChatInfoChange(ctx, s.makeEventSender(gc.GroupChange.SourceServiceID.UUID), s.UserLogin, chatInfoChange, time.UnixMilli(int64(ts))) + } else { + portal.ProcessChatInfoChange(ctx, s.makeEventSenderFromServiceID(gc.GroupChange.SourceServiceID), s.UserLogin, chatInfoChange, time.UnixMilli(int64(ts))) } if gc.GroupChange.Revision == toRevision { break diff --git a/pkg/connector/handlematrix.go b/pkg/connector/handlematrix.go index 1a10773..dec5341 100644 --- a/pkg/connector/handlematrix.go +++ b/pkg/connector/handlematrix.go @@ -387,7 +387,7 @@ func (s *SignalClient) HandleMatrixRoomTopic(ctx context.Context, msg *bridgev2. func (s *SignalClient) HandleMatrixMembership(ctx context.Context, msg *bridgev2.MatrixMembershipChange) (bool, error) { var targetIntent bridgev2.MatrixAPI - var targetSignalID uuid.UUID + var targetSignalID libsignalgo.ServiceID var err error if msg.Portal.RoomType == database.RoomTypeDM { //TODO: this probably needs to revert some changes and clean up the portal on leaves @@ -434,21 +434,35 @@ func (s *SignalClient) HandleMatrixMembership(ctx context.Context, msg *bridgev2 } switch msg.Type { case bridgev2.AcceptInvite: + if targetSignalID.Type != libsignalgo.ServiceIDTypeACI { + return false, fmt.Errorf("can't accept invite for non-ACI service ID") + } gc.PromotePendingMembers = []*signalmeow.PromotePendingMember{{ - ACI: targetSignalID, + ACI: targetSignalID.UUID, }} case bridgev2.RevokeInvite, bridgev2.RejectInvite: - deletePendingMember := libsignalgo.NewACIServiceID(targetSignalID) - gc.DeletePendingMembers = []*libsignalgo.ServiceID{&deletePendingMember} + gc.DeletePendingMembers = []*libsignalgo.ServiceID{&targetSignalID} case bridgev2.Leave, bridgev2.Kick: - gc.DeleteMembers = []*uuid.UUID{&targetSignalID} + if targetSignalID.Type != libsignalgo.ServiceIDTypeACI { + return false, fmt.Errorf("can't kick non-ACI service ID") + } + gc.DeleteMembers = []*uuid.UUID{&targetSignalID.UUID} case bridgev2.Invite: - gc.AddMembers = []*signalmeow.AddMember{{ - GroupMember: signalmeow.GroupMember{ - ACI: targetSignalID, - Role: role, - }, - }} + if targetSignalID.Type == libsignalgo.ServiceIDTypeACI { + gc.AddMembers = []*signalmeow.AddMember{{ + GroupMember: signalmeow.GroupMember{ + ACI: targetSignalID.UUID, + Role: role, + }, + }} + } else { + gc.AddPendingMembers = []*signalmeow.PendingMember{{ + ServiceID: targetSignalID, + Role: role, + AddedByUserID: s.Client.Store.ACI, + Timestamp: uint64(msg.Event.Timestamp), + }} + } // TODO: joining and knocking requires a way to obtain the invite link // because the joining/knocking member doesn't have the GroupMasterKey yet // case bridgev2.Join: @@ -465,29 +479,39 @@ func (s *SignalClient) HandleMatrixMembership(ctx context.Context, msg *bridgev2 // Timestamp: uint64(time.Now().UnixMilli()), // }} case bridgev2.AcceptKnock: + if targetSignalID.Type != libsignalgo.ServiceIDTypeACI { + return false, fmt.Errorf("can't accept knock from non-ACI service ID") + } gc.PromoteRequestingMembers = []*signalmeow.RoleMember{{ - ACI: targetSignalID, + ACI: targetSignalID.UUID, Role: role, }} case bridgev2.RetractKnock, bridgev2.RejectKnock: - gc.DeleteRequestingMembers = []*uuid.UUID{&targetSignalID} + if targetSignalID.Type != libsignalgo.ServiceIDTypeACI { + return false, fmt.Errorf("can't reject knock from non-ACI service ID") + } + gc.DeleteRequestingMembers = []*uuid.UUID{&targetSignalID.UUID} case bridgev2.BanKnocked, bridgev2.BanInvited, bridgev2.BanJoined, bridgev2.BanLeft: gc.AddBannedMembers = []*signalmeow.BannedMember{{ - ServiceID: libsignalgo.NewACIServiceID(targetSignalID), + ServiceID: targetSignalID, Timestamp: uint64(time.Now().UnixMilli()), }} switch msg.Type { case bridgev2.BanJoined: - gc.DeleteMembers = []*uuid.UUID{&targetSignalID} + if targetSignalID.Type != libsignalgo.ServiceIDTypeACI { + return false, fmt.Errorf("can't ban joined non-ACI service ID") + } + gc.DeleteMembers = []*uuid.UUID{&targetSignalID.UUID} case bridgev2.BanInvited: - deletePendingMember := libsignalgo.NewACIServiceID(targetSignalID) - gc.DeletePendingMembers = []*libsignalgo.ServiceID{&deletePendingMember} + gc.DeletePendingMembers = []*libsignalgo.ServiceID{&targetSignalID} case bridgev2.BanKnocked: - gc.DeleteRequestingMembers = []*uuid.UUID{&targetSignalID} + if targetSignalID.Type != libsignalgo.ServiceIDTypeACI { + return false, fmt.Errorf("can't ban knocked non-ACI service ID") + } + gc.DeleteRequestingMembers = []*uuid.UUID{&targetSignalID.UUID} } case bridgev2.Unban: - unbanUser := libsignalgo.NewACIServiceID(targetSignalID) - gc.DeleteBannedMembers = []*libsignalgo.ServiceID{&unbanUser} + gc.DeleteBannedMembers = []*libsignalgo.ServiceID{&targetSignalID} default: log.Debug().Msg("unsupported membership change") return false, nil @@ -501,7 +525,7 @@ func (s *SignalClient) HandleMatrixMembership(ctx context.Context, msg *bridgev2 if err != nil { return false, err } - if msg.Type == bridgev2.Invite { + if msg.Type == bridgev2.Invite && targetSignalID.Type != libsignalgo.ServiceIDTypePNI { err = targetIntent.EnsureJoined(ctx, msg.Portal.MXID) if err != nil { return false, err @@ -540,18 +564,17 @@ func (s *SignalClient) HandleMatrixPowerLevels(ctx context.Context, msg *bridgev if msg.Portal.RoomType == database.RoomTypeDM { return false, nil } - log := zerolog.Ctx(ctx) gc := &signalmeow.GroupChange{} for _, plc := range msg.Users { if !hasAdminChanged(&plc.SinglePowerLevelChange) { continue } - aci, err := signalid.ParseGhostOrUserLoginID(plc.Target) - if err != nil { - log.Err(err).Msg("Couldn't parse user id") + serviceID, err := signalid.ParseGhostOrUserLoginID(plc.Target) + if err != nil || serviceID.Type != libsignalgo.ServiceIDTypeACI { + continue } gc.ModifyMemberRoles = append(gc.ModifyMemberRoles, &signalmeow.RoleMember{ - ACI: aci, + ACI: serviceID.UUID, Role: plToRole(plc.NewLevel), }) } diff --git a/pkg/connector/id.go b/pkg/connector/id.go index 16cb7dc..4c3f123 100644 --- a/pkg/connector/id.go +++ b/pkg/connector/id.go @@ -17,6 +17,8 @@ package connector import ( + "fmt" + "github.com/google/uuid" "maunium.net/go/mautrix/bridgev2" "maunium.net/go/mautrix/bridgev2/networkid" @@ -48,3 +50,20 @@ func (s *SignalClient) makeEventSender(sender uuid.UUID) bridgev2.EventSender { Sender: signalid.MakeUserID(sender), } } + +func (s *SignalClient) makePNIEventSender(sender uuid.UUID) bridgev2.EventSender { + return bridgev2.EventSender{ + Sender: signalid.MakeUserIDFromServiceID(libsignalgo.NewPNIServiceID(sender)), + } +} + +func (s *SignalClient) makeEventSenderFromServiceID(serviceID libsignalgo.ServiceID) bridgev2.EventSender { + switch serviceID.Type { + case libsignalgo.ServiceIDTypeACI: + return s.makeEventSender(serviceID.UUID) + case libsignalgo.ServiceIDTypePNI: + return s.makePNIEventSender(serviceID.UUID) + default: + panic(fmt.Errorf("invalid service ID type %d", serviceID.Type)) + } +} diff --git a/pkg/signalid/ids.go b/pkg/signalid/ids.go index 79ba90f..daa9200 100644 --- a/pkg/signalid/ids.go +++ b/pkg/signalid/ids.go @@ -48,19 +48,33 @@ func ParseUserLoginID(userLoginID networkid.UserLoginID) (uuid.UUID, error) { return userID, nil } -func ParseGhostOrUserLoginID(ghostOrUserLogin bridgev2.GhostOrUserLogin) (uuid.UUID, error) { +func toServiceID(id uuid.UUID, err error) (libsignalgo.ServiceID, error) { + if err != nil { + return libsignalgo.ServiceID{}, err + } + return libsignalgo.NewACIServiceID(id), nil +} + +func ParseGhostOrUserLoginID(ghostOrUserLogin bridgev2.GhostOrUserLogin) (libsignalgo.ServiceID, error) { switch ghostOrUserLogin := ghostOrUserLogin.(type) { case *bridgev2.UserLogin: - return ParseUserLoginID(ghostOrUserLogin.ID) + return toServiceID(ParseUserLoginID(ghostOrUserLogin.ID)) case *bridgev2.Ghost: - return ParseUserID(ghostOrUserLogin.ID) + return ParseUserIDAsServiceID(ghostOrUserLogin.ID) default: - return uuid.Nil, fmt.Errorf("cannot parse ID: unknown type: %T", ghostOrUserLogin) + return libsignalgo.ServiceID{}, fmt.Errorf("cannot parse ID: unknown type: %T", ghostOrUserLogin) } } +const pniUserIDPrefix = "pni_" +const pniServiceIDPrefix = "PNI:" + func ParseUserIDAsServiceID(userID networkid.UserID) (libsignalgo.ServiceID, error) { - return libsignalgo.ServiceIDFromString(string(userID)) + userIDStr := string(userID) + if strings.HasPrefix(userIDStr, pniUserIDPrefix) { + userIDStr = pniServiceIDPrefix + userIDStr[len(pniUserIDPrefix):] + } + return libsignalgo.ServiceIDFromString(userIDStr) } func ParsePortalID(portalID networkid.PortalID) (userID libsignalgo.ServiceID, groupID types.GroupIdentifier, err error) { @@ -103,7 +117,14 @@ func MakeUserID(user uuid.UUID) networkid.UserID { } func MakeUserIDFromServiceID(user libsignalgo.ServiceID) networkid.UserID { - return networkid.UserID(user.String()) + switch user.Type { + case libsignalgo.ServiceIDTypeACI: + return MakeUserID(user.UUID) + case libsignalgo.ServiceIDTypePNI: + return networkid.UserID(pniUserIDPrefix + user.UUID.String()) + default: + panic(fmt.Errorf("invalid service ID type %d", user.Type)) + } } func MakeUserLoginID(user uuid.UUID) networkid.UserLoginID { diff --git a/pkg/signalmeow/groups.go b/pkg/signalmeow/groups.go index de6e054..d938e10 100644 --- a/pkg/signalmeow/groups.go +++ b/pkg/signalmeow/groups.go @@ -831,9 +831,6 @@ func (cli *Client) decryptGroupChange(ctx context.Context, encryptedGroupChange log.Err(err).Msg("Couldn't decrypt source serviceID") return nil, err } - if sourceServiceID.Type != libsignalgo.ServiceIDTypeACI { - return nil, fmt.Errorf("wrong serviceid kind: expected aci, got pni") - } decryptedGroupChange := &GroupChange{ GroupMasterKey: groupMasterKey, Revision: encryptedActions.Revision, @@ -891,7 +888,7 @@ func (cli *Client) decryptGroupChange(ctx context.Context, encryptedGroupChange return nil, err } if serviceID.Type != libsignalgo.ServiceIDTypeACI { - return nil, fmt.Errorf("Wrong ServiceID kind: expected ACI, got PNI") + return nil, fmt.Errorf("wrong ServiceID kind for delete member: expected ACI, got PNI") } decryptedGroupChange.DeleteMembers = append(decryptedGroupChange.DeleteMembers, &serviceID.UUID) } @@ -904,7 +901,7 @@ func (cli *Client) decryptGroupChange(ctx context.Context, encryptedGroupChange return nil, err } if serviceID.Type != libsignalgo.ServiceIDTypeACI { - return nil, fmt.Errorf("Wrong ServiceID kind: expected ACI, got PNI") + return nil, fmt.Errorf("wrong ServiceID kind for modify member: expected ACI, got PNI") } decryptedGroupChange.ModifyMemberRoles = append(decryptedGroupChange.ModifyMemberRoles, &RoleMember{ ACI: serviceID.UUID, @@ -992,7 +989,7 @@ func (cli *Client) decryptGroupChange(ctx context.Context, encryptedGroupChange return nil, err } if pniServiceID.Type != libsignalgo.ServiceIDTypePNI { - return nil, fmt.Errorf("Wrong ServiceID kind: expected PNI, got ACI") + return nil, fmt.Errorf("wrong ServiceID kind for promote pending pni->aci: expected PNI, got ACI") } decryptedGroupChange.PromotePendingPniAciMembers = append(decryptedGroupChange.PromotePendingPniAciMembers, &PromotePendingPniAciMember{ ACI: *aci, @@ -1147,7 +1144,7 @@ func decryptPKeyAndIDorPresentation(ctx context.Context, userID []byte, profileK return nil, nil, err } if serviceID.Type == libsignalgo.ServiceIDTypePNI { - return nil, nil, fmt.Errorf("wrong serviceid kind, expected ACI, got PNI") + return nil, nil, fmt.Errorf("wrong serviceid kind for profile key: expected ACI, got PNI") } return &serviceID.UUID, profileKey, nil @@ -1808,6 +1805,10 @@ func (cli *Client) GetGroupHistoryPage(ctx context.Context, gid types.GroupIdent Password: &groupAuth.Password, ContentType: web.ContentTypeProtobuf, Host: web.StorageHostname, + Headers: map[string]string{ + // TODO actually cache the data and provide real expiry timestamp + "Cached-Send-Endorsements": "0", + }, } // highest known epoch seems to always be 5, but that may change in the future. includeLastState is always false path := fmt.Sprintf("/v2/groups/logs/%d?maxSupportedChangeEpoch=%d&includeFirstState=%t&includeLastState=false", fromRevision, 5, includeFirstState) From 41311f917cd2a6ea0d606ada4318eae310b4808a Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Wed, 22 Oct 2025 21:50:24 +0300 Subject: [PATCH 430/580] signalmeow/sending: don't clear needs PNI signature flag for typing/receipts --- pkg/signalmeow/sending.go | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/pkg/signalmeow/sending.go b/pkg/signalmeow/sending.go index 5c3612e..d5f7076 100644 --- a/pkg/signalmeow/sending.go +++ b/pkg/signalmeow/sending.go @@ -690,8 +690,9 @@ func (cli *Client) SendMessage(ctx context.Context, recipientID libsignalgo.Serv } else if recipientID.Type == libsignalgo.ServiceIDTypePNI { pni = recipientID.UUID } + isTypingOrReceipt := content.TypingMessage != nil || content.ReceiptMessage != nil recipientData, err := cli.Store.RecipientStore.LoadAndUpdateRecipient(ctx, aci, pni, func(recipientData *types.Recipient) (changed bool, err error) { - if recipientID.Type == libsignalgo.ServiceIDTypeACI && recipientData.NeedsPNISignature { + if recipientID.Type == libsignalgo.ServiceIDTypeACI && recipientData.NeedsPNISignature && !isTypingOrReceipt { needsPNISignature = true zerolog.Ctx(ctx).Debug(). Stringer("recipient", recipientID). @@ -713,7 +714,7 @@ func (cli *Client) SendMessage(ctx context.Context, recipientID libsignalgo.Serv zerolog.Ctx(ctx).Err(err).Msg("Failed to get message recipient data") } // Treat needs PNI signature as "this is a message request" and don't send receipts/typing - if needsPNISignature && (content.TypingMessage != nil || content.ReceiptMessage != nil) { + if needsPNISignature && isTypingOrReceipt { zerolog.Ctx(ctx).Debug().Msg("Not sending typing/receipt message to recipient as needs PNI signature flag is set") res := SuccessfulSendResult{Recipient: recipientID} if content.GetReceiptMessage().GetType() == signalpb.ReceiptMessage_READ { From 9beafc1c2f83e7bc4b763c9a35a7cb9942c1a6a6 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Wed, 22 Oct 2025 22:00:54 +0300 Subject: [PATCH 431/580] signalmeow/sending: fix typing/receipts being sent to PNI --- pkg/signalmeow/sending.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkg/signalmeow/sending.go b/pkg/signalmeow/sending.go index d5f7076..c1b2016 100644 --- a/pkg/signalmeow/sending.go +++ b/pkg/signalmeow/sending.go @@ -692,8 +692,8 @@ func (cli *Client) SendMessage(ctx context.Context, recipientID libsignalgo.Serv } isTypingOrReceipt := content.TypingMessage != nil || content.ReceiptMessage != nil recipientData, err := cli.Store.RecipientStore.LoadAndUpdateRecipient(ctx, aci, pni, func(recipientData *types.Recipient) (changed bool, err error) { - if recipientID.Type == libsignalgo.ServiceIDTypeACI && recipientData.NeedsPNISignature && !isTypingOrReceipt { - needsPNISignature = true + needsPNISignature = recipientID.Type == libsignalgo.ServiceIDTypeACI && recipientData.NeedsPNISignature + if needsPNISignature && !isTypingOrReceipt { zerolog.Ctx(ctx).Debug(). Stringer("recipient", recipientID). Msg("Including PNI identity in message") From 69208e85683b6e680428b00aca4527fd93fe6231 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Thu, 23 Oct 2025 15:14:38 +0300 Subject: [PATCH 432/580] dependencies: update mautrix-go --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 2fabdcc..5fc3a9a 100644 --- a/go.mod +++ b/go.mod @@ -18,7 +18,7 @@ require ( golang.org/x/net v0.46.0 google.golang.org/protobuf v1.36.10 gopkg.in/yaml.v3 v3.0.1 - maunium.net/go/mautrix v0.25.3-0.20251022182546-33d8d658fe98 + maunium.net/go/mautrix v0.25.3-0.20251023124911-1be49d53e4f3 ) require ( diff --git a/go.sum b/go.sum index b7850bf..f48dcac 100644 --- a/go.sum +++ b/go.sum @@ -95,5 +95,5 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= maunium.net/go/mauflag v1.0.0 h1:YiaRc0tEI3toYtJMRIfjP+jklH45uDHtT80nUamyD4M= maunium.net/go/mauflag v1.0.0/go.mod h1:nLivPOpTpHnpzEh8jEdSL9UqO9+/KBJFmNRlwKfkPeA= -maunium.net/go/mautrix v0.25.3-0.20251022182546-33d8d658fe98 h1:0cTTVYsfTyXaoqFYz4MoHfMv+zps+Gh3dbQtDn4mtHo= -maunium.net/go/mautrix v0.25.3-0.20251022182546-33d8d658fe98/go.mod h1:EWgYyp2iFZP7pnSm+rufHlO8YVnA2KnoNBDpwekiAwI= +maunium.net/go/mautrix v0.25.3-0.20251023124911-1be49d53e4f3 h1:C+inXVPJspCtjiLIP64npDR01o5Fs9bE9lg3jr0PzS4= +maunium.net/go/mautrix v0.25.3-0.20251023124911-1be49d53e4f3/go.mod h1:EWgYyp2iFZP7pnSm+rufHlO8YVnA2KnoNBDpwekiAwI= From 5f3e2527025ea7707b1994ebbb72359978b57b60 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Thu, 23 Oct 2025 15:20:59 +0300 Subject: [PATCH 433/580] changelog: update --- CHANGELOG.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9135702..4e38aa4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,9 @@ +# v25.11 (unreleased) + +* Added support for bridging invite state in groups for phone number invites. +* Fixed PNI signature not being sent when replying to message requests. +* Fixed unnecessary repeating error notices when Signal is down. + # v25.10 * Switched to calendar versioning. From 0ededf479433f708cb7a60f4f072cc3552b7ad7b Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Fri, 24 Oct 2025 08:51:17 -0700 Subject: [PATCH 434/580] build.sh: fail if prior steps fail (#609) --- build.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/build.sh b/build.sh index 2b51084..3ec20a6 100755 --- a/build.sh +++ b/build.sh @@ -1,4 +1,5 @@ #!/bin/sh +set -e ./build-rust.sh cp -f pkg/libsignalgo/libsignal/target/release/libsignal_ffi.a . LIBRARY_PATH=.:$LIBRARY_PATH ./build-go.sh From afa38f4f9fc373f40ca8965e2ebc0a44880fe0ff Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Mon, 27 Oct 2025 18:07:14 +0200 Subject: [PATCH 435/580] msgconv/from-signal: match sticker size with native desktop --- pkg/msgconv/from-signal.go | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/pkg/msgconv/from-signal.go b/pkg/msgconv/from-signal.go index 277e2a5..ac3fe65 100644 --- a/pkg/msgconv/from-signal.go +++ b/pkg/msgconv/from-signal.go @@ -441,10 +441,11 @@ func (mc *MessageConverter) convertStickerToMatrix(ctx context.Context, sticker }, } } - // Signal stickers are 512x512, so tell Matrix clients to render them as 256x256 + // Signal stickers are 512x512, so tell Matrix clients to render them as 200x200 to match Signal + // https://github.com/signalapp/Signal-Desktop/blob/v7.77.0-beta.1/ts/components/conversation/Message.dom.tsx#L135 if converted.Content.Info.Width == 512 && converted.Content.Info.Height == 512 { - converted.Content.Info.Width = 256 - converted.Content.Info.Height = 256 + converted.Content.Info.Width = 200 + converted.Content.Info.Height = 200 } converted.Content.Body = sticker.GetEmoji() converted.Type = event.EventSticker From b3973632e5e27b6fa0cb083e9772663b084155ba Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Mon, 27 Oct 2025 19:03:38 +0200 Subject: [PATCH 436/580] capabilities: advertise supported state events and member actions Closes #614 Closes #613 --- go.mod | 2 +- go.sum | 4 ++-- pkg/connector/capabilities.go | 29 ++++++++++++++++++++++++++--- 3 files changed, 29 insertions(+), 6 deletions(-) diff --git a/go.mod b/go.mod index 5fc3a9a..313f1ed 100644 --- a/go.mod +++ b/go.mod @@ -18,7 +18,7 @@ require ( golang.org/x/net v0.46.0 google.golang.org/protobuf v1.36.10 gopkg.in/yaml.v3 v3.0.1 - maunium.net/go/mautrix v0.25.3-0.20251023124911-1be49d53e4f3 + maunium.net/go/mautrix v0.25.3-0.20251027163910-adc035b6a555 ) require ( diff --git a/go.sum b/go.sum index f48dcac..95c60ff 100644 --- a/go.sum +++ b/go.sum @@ -95,5 +95,5 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= maunium.net/go/mauflag v1.0.0 h1:YiaRc0tEI3toYtJMRIfjP+jklH45uDHtT80nUamyD4M= maunium.net/go/mauflag v1.0.0/go.mod h1:nLivPOpTpHnpzEh8jEdSL9UqO9+/KBJFmNRlwKfkPeA= -maunium.net/go/mautrix v0.25.3-0.20251023124911-1be49d53e4f3 h1:C+inXVPJspCtjiLIP64npDR01o5Fs9bE9lg3jr0PzS4= -maunium.net/go/mautrix v0.25.3-0.20251023124911-1be49d53e4f3/go.mod h1:EWgYyp2iFZP7pnSm+rufHlO8YVnA2KnoNBDpwekiAwI= +maunium.net/go/mautrix v0.25.3-0.20251027163910-adc035b6a555 h1:6D/kRJyT+5+RRnJErNNglVwDMYU6EwQN0bRYqcdkfZw= +maunium.net/go/mautrix v0.25.3-0.20251027163910-adc035b6a555/go.mod h1:EWgYyp2iFZP7pnSm+rufHlO8YVnA2KnoNBDpwekiAwI= diff --git a/pkg/connector/capabilities.go b/pkg/connector/capabilities.go index 329a81d..b9cb632 100644 --- a/pkg/connector/capabilities.go +++ b/pkg/connector/capabilities.go @@ -25,6 +25,7 @@ import ( "go.mau.fi/util/ptr" "maunium.net/go/mautrix/bridgev2" + "maunium.net/go/mautrix/bridgev2/database" "maunium.net/go/mautrix/bridgev2/networkid" "maunium.net/go/mautrix/event" ) @@ -37,7 +38,7 @@ func supportedIfFFmpeg() event.CapabilitySupportLevel { } func capID() string { - base := "fi.mau.signal.capabilities.2025_08_25" + base := "fi.mau.signal.capabilities.2025_10_27" if ffmpeg.Supported() { return base + "+ffmpeg" } @@ -136,6 +137,19 @@ var signalCaps = &event.RoomFeatures{ MaxSize: MaxFileSize, }, }, + State: event.StateFeatureMap{ + event.StateRoomName.Type: {Level: event.CapLevelFullySupported}, + event.StateRoomAvatar.Type: {Level: event.CapLevelFullySupported}, + event.StateTopic.Type: {Level: event.CapLevelFullySupported}, + event.StateBeeperDisappearingTimer.Type: {Level: event.CapLevelFullySupported}, + }, + MemberActions: event.MemberFeatureMap{ + event.MemberActionInvite: event.CapLevelFullySupported, + event.MemberActionRevokeInvite: event.CapLevelFullySupported, + event.MemberActionLeave: event.CapLevelFullySupported, + event.MemberActionBan: event.CapLevelFullySupported, + event.MemberActionKick: event.CapLevelFullySupported, + }, MaxTextLength: MaxTextLength, // TODO support arbitrary sized text messages with files LocationMessage: event.CapLevelPartialSupport, Poll: event.CapLevelRejected, @@ -162,9 +176,16 @@ var signalDisappearingCap = &event.DisappearingTimerCapability{ } var signalCapsNoteToSelf *event.RoomFeatures +var signalCapsDM *event.RoomFeatures func init() { - signalCapsNoteToSelf = ptr.Clone(signalCaps) + signalCapsDM = ptr.Clone(signalCaps) + signalCapsDM.ID = capID() + "+dm" + signalCapsDM.MemberActions = nil + signalCapsDM.State = event.StateFeatureMap{ + event.StateBeeperDisappearingTimer.Type: {Level: event.CapLevelFullySupported}, + } + signalCapsNoteToSelf = ptr.Clone(signalCapsDM) signalCapsNoteToSelf.EditMaxAge = nil signalCapsNoteToSelf.DeleteMaxAge = nil signalCapsNoteToSelf.ID = capID() + "+note_to_self" @@ -173,6 +194,8 @@ func init() { func (s *SignalClient) GetCapabilities(ctx context.Context, portal *bridgev2.Portal) *event.RoomFeatures { if portal.Receiver == s.UserLogin.ID && portal.ID == networkid.PortalID(s.UserLogin.ID) { return signalCapsNoteToSelf + } else if portal.RoomType == database.RoomTypeDM { + return signalCapsDM } return signalCaps } @@ -206,5 +229,5 @@ func (s *SignalConnector) GetCapabilities() *bridgev2.NetworkGeneralCapabilities } func (s *SignalConnector) GetBridgeInfoVersion() (info, capabilities int) { - return 1, 5 + return 1, 6 } From dab89843b0ca14c0851f0b5032d38c3b29252755 Mon Sep 17 00:00:00 2001 From: Nick Mills-Barrett Date: Tue, 28 Oct 2025 12:40:17 +0000 Subject: [PATCH 437/580] handlematrix: return error when handling unsupported membership changes --- pkg/connector/handlematrix.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/pkg/connector/handlematrix.go b/pkg/connector/handlematrix.go index dec5341..65e7b7c 100644 --- a/pkg/connector/handlematrix.go +++ b/pkg/connector/handlematrix.go @@ -513,8 +513,7 @@ func (s *SignalClient) HandleMatrixMembership(ctx context.Context, msg *bridgev2 case bridgev2.Unban: gc.DeleteBannedMembers = []*libsignalgo.ServiceID{&targetSignalID} default: - log.Debug().Msg("unsupported membership change") - return false, nil + return false, fmt.Errorf("unsupported membership change: %s -> %s", msg.Type.From, msg.Type.To) } _, groupID, err := signalid.ParsePortalID(msg.Portal.ID) if err != nil || groupID == "" { From 6e49c340768e8f8521cf9ab4ea2e94e6fed3e1f3 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Tue, 28 Oct 2025 15:08:34 +0200 Subject: [PATCH 438/580] dependencies: update mautrix-go --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 313f1ed..f61bdd1 100644 --- a/go.mod +++ b/go.mod @@ -18,7 +18,7 @@ require ( golang.org/x/net v0.46.0 google.golang.org/protobuf v1.36.10 gopkg.in/yaml.v3 v3.0.1 - maunium.net/go/mautrix v0.25.3-0.20251027163910-adc035b6a555 + maunium.net/go/mautrix v0.25.3-0.20251028130646-bea28c1381cd ) require ( diff --git a/go.sum b/go.sum index 95c60ff..fa344cc 100644 --- a/go.sum +++ b/go.sum @@ -95,5 +95,5 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= maunium.net/go/mauflag v1.0.0 h1:YiaRc0tEI3toYtJMRIfjP+jklH45uDHtT80nUamyD4M= maunium.net/go/mauflag v1.0.0/go.mod h1:nLivPOpTpHnpzEh8jEdSL9UqO9+/KBJFmNRlwKfkPeA= -maunium.net/go/mautrix v0.25.3-0.20251027163910-adc035b6a555 h1:6D/kRJyT+5+RRnJErNNglVwDMYU6EwQN0bRYqcdkfZw= -maunium.net/go/mautrix v0.25.3-0.20251027163910-adc035b6a555/go.mod h1:EWgYyp2iFZP7pnSm+rufHlO8YVnA2KnoNBDpwekiAwI= +maunium.net/go/mautrix v0.25.3-0.20251028130646-bea28c1381cd h1:4OfgnwTd71vgHGc+kBwhWsb92ePZVvsDbyTLJiy+PKU= +maunium.net/go/mautrix v0.25.3-0.20251028130646-bea28c1381cd/go.mod h1:EWgYyp2iFZP7pnSm+rufHlO8YVnA2KnoNBDpwekiAwI= From 6f840544e180794d5aa8e4d57cce0cdcaaca5fad Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Wed, 29 Oct 2025 14:10:25 +0200 Subject: [PATCH 439/580] signalmeow: update protobufs --- .../protobuf/ContactDiscovery.pb.go | 2 +- pkg/signalmeow/protobuf/DeviceName.pb.go | 2 +- pkg/signalmeow/protobuf/Groups.pb.go | 2 +- pkg/signalmeow/protobuf/Provisioning.pb.go | 2 +- pkg/signalmeow/protobuf/SignalService.pb.go | 735 ++++++---- pkg/signalmeow/protobuf/SignalService.proto | 24 +- .../protobuf/StickerResources.pb.go | 2 +- pkg/signalmeow/protobuf/StorageService.pb.go | 2 +- .../protobuf/UnidentifiedDelivery.pb.go | 2 +- .../protobuf/WebSocketResources.pb.go | 2 +- pkg/signalmeow/protobuf/backuppb/Backup.pb.go | 1304 ++++++++++------- pkg/signalmeow/protobuf/backuppb/Backup.proto | 27 + pkg/signalmeow/protobuf/update-protos.sh | 7 +- 13 files changed, 1339 insertions(+), 774 deletions(-) diff --git a/pkg/signalmeow/protobuf/ContactDiscovery.pb.go b/pkg/signalmeow/protobuf/ContactDiscovery.pb.go index 97ac6b4..5523a0e 100644 --- a/pkg/signalmeow/protobuf/ContactDiscovery.pb.go +++ b/pkg/signalmeow/protobuf/ContactDiscovery.pb.go @@ -1,6 +1,6 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.36.6 +// protoc-gen-go v1.36.10 // protoc v3.21.12 // source: ContactDiscovery.proto diff --git a/pkg/signalmeow/protobuf/DeviceName.pb.go b/pkg/signalmeow/protobuf/DeviceName.pb.go index e83e374..144428d 100644 --- a/pkg/signalmeow/protobuf/DeviceName.pb.go +++ b/pkg/signalmeow/protobuf/DeviceName.pb.go @@ -1,6 +1,6 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.36.6 +// protoc-gen-go v1.36.10 // protoc v3.21.12 // source: DeviceName.proto diff --git a/pkg/signalmeow/protobuf/Groups.pb.go b/pkg/signalmeow/protobuf/Groups.pb.go index 7178760..3e5cc7a 100644 --- a/pkg/signalmeow/protobuf/Groups.pb.go +++ b/pkg/signalmeow/protobuf/Groups.pb.go @@ -5,7 +5,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.36.6 +// protoc-gen-go v1.36.10 // protoc v3.21.12 // source: Groups.proto diff --git a/pkg/signalmeow/protobuf/Provisioning.pb.go b/pkg/signalmeow/protobuf/Provisioning.pb.go index 9e75ec2..d2f0a4d 100644 --- a/pkg/signalmeow/protobuf/Provisioning.pb.go +++ b/pkg/signalmeow/protobuf/Provisioning.pb.go @@ -4,7 +4,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.36.6 +// protoc-gen-go v1.36.10 // protoc v3.21.12 // source: Provisioning.proto diff --git a/pkg/signalmeow/protobuf/SignalService.pb.go b/pkg/signalmeow/protobuf/SignalService.pb.go index fd875ac..ae5bd18 100644 --- a/pkg/signalmeow/protobuf/SignalService.pb.go +++ b/pkg/signalmeow/protobuf/SignalService.pb.go @@ -4,7 +4,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.36.6 +// protoc-gen-go v1.36.10 // protoc v3.21.12 // source: SignalService.proto @@ -346,6 +346,7 @@ const ( DataMessage_CDN_SELECTOR_ATTACHMENTS DataMessage_ProtocolVersion = 5 DataMessage_MENTIONS DataMessage_ProtocolVersion = 6 DataMessage_PAYMENTS DataMessage_ProtocolVersion = 7 + DataMessage_POLLS DataMessage_ProtocolVersion = 8 DataMessage_CURRENT DataMessage_ProtocolVersion = 7 ) @@ -360,6 +361,7 @@ var ( 5: "CDN_SELECTOR_ATTACHMENTS", 6: "MENTIONS", 7: "PAYMENTS", + 8: "POLLS", // Duplicate value: 7: "CURRENT", } DataMessage_ProtocolVersion_value = map[string]int32{ @@ -371,6 +373,7 @@ var ( "CDN_SELECTOR_ATTACHMENTS": 5, "MENTIONS": 6, "PAYMENTS": 7, + "POLLS": 8, "CURRENT": 7, } ) @@ -473,6 +476,7 @@ type DataMessage_Quote_Type int32 const ( DataMessage_Quote_NORMAL DataMessage_Quote_Type = 0 DataMessage_Quote_GIFT_BADGE DataMessage_Quote_Type = 1 + DataMessage_Quote_POLL DataMessage_Quote_Type = 2 ) // Enum value maps for DataMessage_Quote_Type. @@ -480,10 +484,12 @@ var ( DataMessage_Quote_Type_name = map[int32]string{ 0: "NORMAL", 1: "GIFT_BADGE", + 2: "POLL", } DataMessage_Quote_Type_value = map[string]int32{ "NORMAL": 0, "GIFT_BADGE": 1, + "POLL": 2, } ) @@ -2126,7 +2132,10 @@ type DataMessage struct { GroupCallUpdate *DataMessage_GroupCallUpdate `protobuf:"bytes,19,opt,name=groupCallUpdate" json:"groupCallUpdate,omitempty"` Payment *DataMessage_Payment `protobuf:"bytes,20,opt,name=payment" json:"payment,omitempty"` StoryContext *DataMessage_StoryContext `protobuf:"bytes,21,opt,name=storyContext" json:"storyContext,omitempty"` - GiftBadge *DataMessage_GiftBadge `protobuf:"bytes,22,opt,name=giftBadge" json:"giftBadge,omitempty"` // NEXT ID: 24 + GiftBadge *DataMessage_GiftBadge `protobuf:"bytes,22,opt,name=giftBadge" json:"giftBadge,omitempty"` + PollCreate *DataMessage_PollCreate `protobuf:"bytes,24,opt,name=pollCreate" json:"pollCreate,omitempty"` + PollTerminate *DataMessage_PollTerminate `protobuf:"bytes,25,opt,name=pollTerminate" json:"pollTerminate,omitempty"` + PollVote *DataMessage_PollVote `protobuf:"bytes,26,opt,name=pollVote" json:"pollVote,omitempty"` // NEXT ID: 27 unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } @@ -2308,6 +2317,27 @@ func (x *DataMessage) GetGiftBadge() *DataMessage_GiftBadge { return nil } +func (x *DataMessage) GetPollCreate() *DataMessage_PollCreate { + if x != nil { + return x.PollCreate + } + return nil +} + +func (x *DataMessage) GetPollTerminate() *DataMessage_PollTerminate { + if x != nil { + return x.PollTerminate + } + return nil +} + +func (x *DataMessage) GetPollVote() *DataMessage_PollVote { + if x != nil { + return x.PollVote + } + return nil +} + type NullMessage struct { state protoimpl.MessageState `protogen:"open.v1"` Padding []byte `protobuf:"bytes,1,opt,name=padding" json:"padding,omitempty"` @@ -4843,6 +4873,178 @@ func (x *DataMessage_GiftBadge) GetReceiptCredentialPresentation() []byte { return nil } +type DataMessage_PollCreate struct { + state protoimpl.MessageState `protogen:"open.v1"` + Question *string `protobuf:"bytes,1,opt,name=question" json:"question,omitempty"` + AllowMultiple *bool `protobuf:"varint,2,opt,name=allowMultiple" json:"allowMultiple,omitempty"` + Options []string `protobuf:"bytes,3,rep,name=options" json:"options,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *DataMessage_PollCreate) Reset() { + *x = DataMessage_PollCreate{} + mi := &file_SignalService_proto_msgTypes[37] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *DataMessage_PollCreate) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*DataMessage_PollCreate) ProtoMessage() {} + +func (x *DataMessage_PollCreate) ProtoReflect() protoreflect.Message { + mi := &file_SignalService_proto_msgTypes[37] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use DataMessage_PollCreate.ProtoReflect.Descriptor instead. +func (*DataMessage_PollCreate) Descriptor() ([]byte, []int) { + return file_SignalService_proto_rawDescGZIP(), []int{3, 9} +} + +func (x *DataMessage_PollCreate) GetQuestion() string { + if x != nil && x.Question != nil { + return *x.Question + } + return "" +} + +func (x *DataMessage_PollCreate) GetAllowMultiple() bool { + if x != nil && x.AllowMultiple != nil { + return *x.AllowMultiple + } + return false +} + +func (x *DataMessage_PollCreate) GetOptions() []string { + if x != nil { + return x.Options + } + return nil +} + +type DataMessage_PollTerminate struct { + state protoimpl.MessageState `protogen:"open.v1"` + TargetSentTimestamp *uint64 `protobuf:"varint,1,opt,name=targetSentTimestamp" json:"targetSentTimestamp,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *DataMessage_PollTerminate) Reset() { + *x = DataMessage_PollTerminate{} + mi := &file_SignalService_proto_msgTypes[38] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *DataMessage_PollTerminate) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*DataMessage_PollTerminate) ProtoMessage() {} + +func (x *DataMessage_PollTerminate) ProtoReflect() protoreflect.Message { + mi := &file_SignalService_proto_msgTypes[38] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use DataMessage_PollTerminate.ProtoReflect.Descriptor instead. +func (*DataMessage_PollTerminate) Descriptor() ([]byte, []int) { + return file_SignalService_proto_rawDescGZIP(), []int{3, 10} +} + +func (x *DataMessage_PollTerminate) GetTargetSentTimestamp() uint64 { + if x != nil && x.TargetSentTimestamp != nil { + return *x.TargetSentTimestamp + } + return 0 +} + +type DataMessage_PollVote struct { + state protoimpl.MessageState `protogen:"open.v1"` + TargetAuthorAciBinary []byte `protobuf:"bytes,1,opt,name=targetAuthorAciBinary" json:"targetAuthorAciBinary,omitempty"` + TargetSentTimestamp *uint64 `protobuf:"varint,2,opt,name=targetSentTimestamp" json:"targetSentTimestamp,omitempty"` + OptionIndexes []uint32 `protobuf:"varint,3,rep,name=optionIndexes" json:"optionIndexes,omitempty"` // must be in the range [0, options.length) from the PollCreate + VoteCount *uint32 `protobuf:"varint,4,opt,name=voteCount" json:"voteCount,omitempty"` // increment this by 1 each time you vote on a given poll + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *DataMessage_PollVote) Reset() { + *x = DataMessage_PollVote{} + mi := &file_SignalService_proto_msgTypes[39] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *DataMessage_PollVote) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*DataMessage_PollVote) ProtoMessage() {} + +func (x *DataMessage_PollVote) ProtoReflect() protoreflect.Message { + mi := &file_SignalService_proto_msgTypes[39] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use DataMessage_PollVote.ProtoReflect.Descriptor instead. +func (*DataMessage_PollVote) Descriptor() ([]byte, []int) { + return file_SignalService_proto_rawDescGZIP(), []int{3, 11} +} + +func (x *DataMessage_PollVote) GetTargetAuthorAciBinary() []byte { + if x != nil { + return x.TargetAuthorAciBinary + } + return nil +} + +func (x *DataMessage_PollVote) GetTargetSentTimestamp() uint64 { + if x != nil && x.TargetSentTimestamp != nil { + return *x.TargetSentTimestamp + } + return 0 +} + +func (x *DataMessage_PollVote) GetOptionIndexes() []uint32 { + if x != nil { + return x.OptionIndexes + } + return nil +} + +func (x *DataMessage_PollVote) GetVoteCount() uint32 { + if x != nil && x.VoteCount != nil { + return *x.VoteCount + } + return 0 +} + type DataMessage_Payment_Amount struct { state protoimpl.MessageState `protogen:"open.v1"` // Types that are valid to be assigned to Amount: @@ -4855,7 +5057,7 @@ type DataMessage_Payment_Amount struct { func (x *DataMessage_Payment_Amount) Reset() { *x = DataMessage_Payment_Amount{} - mi := &file_SignalService_proto_msgTypes[37] + mi := &file_SignalService_proto_msgTypes[40] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4867,7 +5069,7 @@ func (x *DataMessage_Payment_Amount) String() string { func (*DataMessage_Payment_Amount) ProtoMessage() {} func (x *DataMessage_Payment_Amount) ProtoReflect() protoreflect.Message { - mi := &file_SignalService_proto_msgTypes[37] + mi := &file_SignalService_proto_msgTypes[40] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4923,7 +5125,7 @@ type DataMessage_Payment_Notification struct { func (x *DataMessage_Payment_Notification) Reset() { *x = DataMessage_Payment_Notification{} - mi := &file_SignalService_proto_msgTypes[38] + mi := &file_SignalService_proto_msgTypes[41] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4935,7 +5137,7 @@ func (x *DataMessage_Payment_Notification) String() string { func (*DataMessage_Payment_Notification) ProtoMessage() {} func (x *DataMessage_Payment_Notification) ProtoReflect() protoreflect.Message { - mi := &file_SignalService_proto_msgTypes[38] + mi := &file_SignalService_proto_msgTypes[41] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4994,7 +5196,7 @@ type DataMessage_Payment_Activation struct { func (x *DataMessage_Payment_Activation) Reset() { *x = DataMessage_Payment_Activation{} - mi := &file_SignalService_proto_msgTypes[39] + mi := &file_SignalService_proto_msgTypes[42] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5006,7 +5208,7 @@ func (x *DataMessage_Payment_Activation) String() string { func (*DataMessage_Payment_Activation) ProtoMessage() {} func (x *DataMessage_Payment_Activation) ProtoReflect() protoreflect.Message { - mi := &file_SignalService_proto_msgTypes[39] + mi := &file_SignalService_proto_msgTypes[42] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5038,7 +5240,7 @@ type DataMessage_Payment_Amount_MobileCoin struct { func (x *DataMessage_Payment_Amount_MobileCoin) Reset() { *x = DataMessage_Payment_Amount_MobileCoin{} - mi := &file_SignalService_proto_msgTypes[40] + mi := &file_SignalService_proto_msgTypes[43] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5050,7 +5252,7 @@ func (x *DataMessage_Payment_Amount_MobileCoin) String() string { func (*DataMessage_Payment_Amount_MobileCoin) ProtoMessage() {} func (x *DataMessage_Payment_Amount_MobileCoin) ProtoReflect() protoreflect.Message { - mi := &file_SignalService_proto_msgTypes[40] + mi := &file_SignalService_proto_msgTypes[43] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5082,7 +5284,7 @@ type DataMessage_Payment_Notification_MobileCoin struct { func (x *DataMessage_Payment_Notification_MobileCoin) Reset() { *x = DataMessage_Payment_Notification_MobileCoin{} - mi := &file_SignalService_proto_msgTypes[41] + mi := &file_SignalService_proto_msgTypes[44] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5094,7 +5296,7 @@ func (x *DataMessage_Payment_Notification_MobileCoin) String() string { func (*DataMessage_Payment_Notification_MobileCoin) ProtoMessage() {} func (x *DataMessage_Payment_Notification_MobileCoin) ProtoReflect() protoreflect.Message { - mi := &file_SignalService_proto_msgTypes[41] + mi := &file_SignalService_proto_msgTypes[44] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5128,7 +5330,7 @@ type DataMessage_Quote_QuotedAttachment struct { func (x *DataMessage_Quote_QuotedAttachment) Reset() { *x = DataMessage_Quote_QuotedAttachment{} - mi := &file_SignalService_proto_msgTypes[42] + mi := &file_SignalService_proto_msgTypes[45] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5140,7 +5342,7 @@ func (x *DataMessage_Quote_QuotedAttachment) String() string { func (*DataMessage_Quote_QuotedAttachment) ProtoMessage() {} func (x *DataMessage_Quote_QuotedAttachment) ProtoReflect() protoreflect.Message { - mi := &file_SignalService_proto_msgTypes[42] + mi := &file_SignalService_proto_msgTypes[45] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5191,7 +5393,7 @@ type DataMessage_Contact_Name struct { func (x *DataMessage_Contact_Name) Reset() { *x = DataMessage_Contact_Name{} - mi := &file_SignalService_proto_msgTypes[43] + mi := &file_SignalService_proto_msgTypes[46] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5203,7 +5405,7 @@ func (x *DataMessage_Contact_Name) String() string { func (*DataMessage_Contact_Name) ProtoMessage() {} func (x *DataMessage_Contact_Name) ProtoReflect() protoreflect.Message { - mi := &file_SignalService_proto_msgTypes[43] + mi := &file_SignalService_proto_msgTypes[46] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5272,7 +5474,7 @@ type DataMessage_Contact_Phone struct { func (x *DataMessage_Contact_Phone) Reset() { *x = DataMessage_Contact_Phone{} - mi := &file_SignalService_proto_msgTypes[44] + mi := &file_SignalService_proto_msgTypes[47] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5284,7 +5486,7 @@ func (x *DataMessage_Contact_Phone) String() string { func (*DataMessage_Contact_Phone) ProtoMessage() {} func (x *DataMessage_Contact_Phone) ProtoReflect() protoreflect.Message { - mi := &file_SignalService_proto_msgTypes[44] + mi := &file_SignalService_proto_msgTypes[47] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5332,7 +5534,7 @@ type DataMessage_Contact_Email struct { func (x *DataMessage_Contact_Email) Reset() { *x = DataMessage_Contact_Email{} - mi := &file_SignalService_proto_msgTypes[45] + mi := &file_SignalService_proto_msgTypes[48] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5344,7 +5546,7 @@ func (x *DataMessage_Contact_Email) String() string { func (*DataMessage_Contact_Email) ProtoMessage() {} func (x *DataMessage_Contact_Email) ProtoReflect() protoreflect.Message { - mi := &file_SignalService_proto_msgTypes[45] + mi := &file_SignalService_proto_msgTypes[48] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5398,7 +5600,7 @@ type DataMessage_Contact_PostalAddress struct { func (x *DataMessage_Contact_PostalAddress) Reset() { *x = DataMessage_Contact_PostalAddress{} - mi := &file_SignalService_proto_msgTypes[46] + mi := &file_SignalService_proto_msgTypes[49] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5410,7 +5612,7 @@ func (x *DataMessage_Contact_PostalAddress) String() string { func (*DataMessage_Contact_PostalAddress) ProtoMessage() {} func (x *DataMessage_Contact_PostalAddress) ProtoReflect() protoreflect.Message { - mi := &file_SignalService_proto_msgTypes[46] + mi := &file_SignalService_proto_msgTypes[49] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5499,7 +5701,7 @@ type DataMessage_Contact_Avatar struct { func (x *DataMessage_Contact_Avatar) Reset() { *x = DataMessage_Contact_Avatar{} - mi := &file_SignalService_proto_msgTypes[47] + mi := &file_SignalService_proto_msgTypes[50] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5511,7 +5713,7 @@ func (x *DataMessage_Contact_Avatar) String() string { func (*DataMessage_Contact_Avatar) ProtoMessage() {} func (x *DataMessage_Contact_Avatar) ProtoReflect() protoreflect.Message { - mi := &file_SignalService_proto_msgTypes[47] + mi := &file_SignalService_proto_msgTypes[50] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5554,7 +5756,7 @@ type TextAttachment_Gradient struct { func (x *TextAttachment_Gradient) Reset() { *x = TextAttachment_Gradient{} - mi := &file_SignalService_proto_msgTypes[48] + mi := &file_SignalService_proto_msgTypes[51] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5566,7 +5768,7 @@ func (x *TextAttachment_Gradient) String() string { func (*TextAttachment_Gradient) ProtoMessage() {} func (x *TextAttachment_Gradient) ProtoReflect() protoreflect.Message { - mi := &file_SignalService_proto_msgTypes[48] + mi := &file_SignalService_proto_msgTypes[51] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5640,7 +5842,7 @@ const ( func (x *SyncMessage_Sent) Reset() { *x = SyncMessage_Sent{} - mi := &file_SignalService_proto_msgTypes[49] + mi := &file_SignalService_proto_msgTypes[52] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5652,7 +5854,7 @@ func (x *SyncMessage_Sent) String() string { func (*SyncMessage_Sent) ProtoMessage() {} func (x *SyncMessage_Sent) ProtoReflect() protoreflect.Message { - mi := &file_SignalService_proto_msgTypes[49] + mi := &file_SignalService_proto_msgTypes[52] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5753,7 +5955,7 @@ const ( func (x *SyncMessage_Contacts) Reset() { *x = SyncMessage_Contacts{} - mi := &file_SignalService_proto_msgTypes[50] + mi := &file_SignalService_proto_msgTypes[53] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5765,7 +5967,7 @@ func (x *SyncMessage_Contacts) String() string { func (*SyncMessage_Contacts) ProtoMessage() {} func (x *SyncMessage_Contacts) ProtoReflect() protoreflect.Message { - mi := &file_SignalService_proto_msgTypes[50] + mi := &file_SignalService_proto_msgTypes[53] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5806,7 +6008,7 @@ type SyncMessage_Blocked struct { func (x *SyncMessage_Blocked) Reset() { *x = SyncMessage_Blocked{} - mi := &file_SignalService_proto_msgTypes[51] + mi := &file_SignalService_proto_msgTypes[54] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5818,7 +6020,7 @@ func (x *SyncMessage_Blocked) String() string { func (*SyncMessage_Blocked) ProtoMessage() {} func (x *SyncMessage_Blocked) ProtoReflect() protoreflect.Message { - mi := &file_SignalService_proto_msgTypes[51] + mi := &file_SignalService_proto_msgTypes[54] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5864,7 +6066,7 @@ type SyncMessage_Request struct { func (x *SyncMessage_Request) Reset() { *x = SyncMessage_Request{} - mi := &file_SignalService_proto_msgTypes[52] + mi := &file_SignalService_proto_msgTypes[55] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5876,7 +6078,7 @@ func (x *SyncMessage_Request) String() string { func (*SyncMessage_Request) ProtoMessage() {} func (x *SyncMessage_Request) ProtoReflect() protoreflect.Message { - mi := &file_SignalService_proto_msgTypes[52] + mi := &file_SignalService_proto_msgTypes[55] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5909,7 +6111,7 @@ type SyncMessage_Read struct { func (x *SyncMessage_Read) Reset() { *x = SyncMessage_Read{} - mi := &file_SignalService_proto_msgTypes[53] + mi := &file_SignalService_proto_msgTypes[56] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5921,7 +6123,7 @@ func (x *SyncMessage_Read) String() string { func (*SyncMessage_Read) ProtoMessage() {} func (x *SyncMessage_Read) ProtoReflect() protoreflect.Message { - mi := &file_SignalService_proto_msgTypes[53] + mi := &file_SignalService_proto_msgTypes[56] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5961,7 +6163,7 @@ type SyncMessage_Viewed struct { func (x *SyncMessage_Viewed) Reset() { *x = SyncMessage_Viewed{} - mi := &file_SignalService_proto_msgTypes[54] + mi := &file_SignalService_proto_msgTypes[57] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5973,7 +6175,7 @@ func (x *SyncMessage_Viewed) String() string { func (*SyncMessage_Viewed) ProtoMessage() {} func (x *SyncMessage_Viewed) ProtoReflect() protoreflect.Message { - mi := &file_SignalService_proto_msgTypes[54] + mi := &file_SignalService_proto_msgTypes[57] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6016,7 +6218,7 @@ type SyncMessage_Configuration struct { func (x *SyncMessage_Configuration) Reset() { *x = SyncMessage_Configuration{} - mi := &file_SignalService_proto_msgTypes[55] + mi := &file_SignalService_proto_msgTypes[58] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6028,7 +6230,7 @@ func (x *SyncMessage_Configuration) String() string { func (*SyncMessage_Configuration) ProtoMessage() {} func (x *SyncMessage_Configuration) ProtoReflect() protoreflect.Message { - mi := &file_SignalService_proto_msgTypes[55] + mi := &file_SignalService_proto_msgTypes[58] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6090,7 +6292,7 @@ type SyncMessage_StickerPackOperation struct { func (x *SyncMessage_StickerPackOperation) Reset() { *x = SyncMessage_StickerPackOperation{} - mi := &file_SignalService_proto_msgTypes[56] + mi := &file_SignalService_proto_msgTypes[59] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6102,7 +6304,7 @@ func (x *SyncMessage_StickerPackOperation) String() string { func (*SyncMessage_StickerPackOperation) ProtoMessage() {} func (x *SyncMessage_StickerPackOperation) ProtoReflect() protoreflect.Message { - mi := &file_SignalService_proto_msgTypes[56] + mi := &file_SignalService_proto_msgTypes[59] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6149,7 +6351,7 @@ type SyncMessage_ViewOnceOpen struct { func (x *SyncMessage_ViewOnceOpen) Reset() { *x = SyncMessage_ViewOnceOpen{} - mi := &file_SignalService_proto_msgTypes[57] + mi := &file_SignalService_proto_msgTypes[60] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6161,7 +6363,7 @@ func (x *SyncMessage_ViewOnceOpen) String() string { func (*SyncMessage_ViewOnceOpen) ProtoMessage() {} func (x *SyncMessage_ViewOnceOpen) ProtoReflect() protoreflect.Message { - mi := &file_SignalService_proto_msgTypes[57] + mi := &file_SignalService_proto_msgTypes[60] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6200,7 +6402,7 @@ type SyncMessage_FetchLatest struct { func (x *SyncMessage_FetchLatest) Reset() { *x = SyncMessage_FetchLatest{} - mi := &file_SignalService_proto_msgTypes[58] + mi := &file_SignalService_proto_msgTypes[61] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6212,7 +6414,7 @@ func (x *SyncMessage_FetchLatest) String() string { func (*SyncMessage_FetchLatest) ProtoMessage() {} func (x *SyncMessage_FetchLatest) ProtoReflect() protoreflect.Message { - mi := &file_SignalService_proto_msgTypes[58] + mi := &file_SignalService_proto_msgTypes[61] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6246,7 +6448,7 @@ type SyncMessage_Keys struct { func (x *SyncMessage_Keys) Reset() { *x = SyncMessage_Keys{} - mi := &file_SignalService_proto_msgTypes[59] + mi := &file_SignalService_proto_msgTypes[62] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6258,7 +6460,7 @@ func (x *SyncMessage_Keys) String() string { func (*SyncMessage_Keys) ProtoMessage() {} func (x *SyncMessage_Keys) ProtoReflect() protoreflect.Message { - mi := &file_SignalService_proto_msgTypes[59] + mi := &file_SignalService_proto_msgTypes[62] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6305,7 +6507,7 @@ type SyncMessage_PniIdentity struct { func (x *SyncMessage_PniIdentity) Reset() { *x = SyncMessage_PniIdentity{} - mi := &file_SignalService_proto_msgTypes[60] + mi := &file_SignalService_proto_msgTypes[63] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6317,7 +6519,7 @@ func (x *SyncMessage_PniIdentity) String() string { func (*SyncMessage_PniIdentity) ProtoMessage() {} func (x *SyncMessage_PniIdentity) ProtoReflect() protoreflect.Message { - mi := &file_SignalService_proto_msgTypes[60] + mi := &file_SignalService_proto_msgTypes[63] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6358,7 +6560,7 @@ type SyncMessage_MessageRequestResponse struct { func (x *SyncMessage_MessageRequestResponse) Reset() { *x = SyncMessage_MessageRequestResponse{} - mi := &file_SignalService_proto_msgTypes[61] + mi := &file_SignalService_proto_msgTypes[64] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6370,7 +6572,7 @@ func (x *SyncMessage_MessageRequestResponse) String() string { func (*SyncMessage_MessageRequestResponse) ProtoMessage() {} func (x *SyncMessage_MessageRequestResponse) ProtoReflect() protoreflect.Message { - mi := &file_SignalService_proto_msgTypes[61] + mi := &file_SignalService_proto_msgTypes[64] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6421,7 +6623,7 @@ type SyncMessage_OutgoingPayment struct { func (x *SyncMessage_OutgoingPayment) Reset() { *x = SyncMessage_OutgoingPayment{} - mi := &file_SignalService_proto_msgTypes[62] + mi := &file_SignalService_proto_msgTypes[65] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6433,7 +6635,7 @@ func (x *SyncMessage_OutgoingPayment) String() string { func (*SyncMessage_OutgoingPayment) ProtoMessage() {} func (x *SyncMessage_OutgoingPayment) ProtoReflect() protoreflect.Message { - mi := &file_SignalService_proto_msgTypes[62] + mi := &file_SignalService_proto_msgTypes[65] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6503,7 +6705,7 @@ type SyncMessage_PniChangeNumber struct { func (x *SyncMessage_PniChangeNumber) Reset() { *x = SyncMessage_PniChangeNumber{} - mi := &file_SignalService_proto_msgTypes[63] + mi := &file_SignalService_proto_msgTypes[66] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6515,7 +6717,7 @@ func (x *SyncMessage_PniChangeNumber) String() string { func (*SyncMessage_PniChangeNumber) ProtoMessage() {} func (x *SyncMessage_PniChangeNumber) ProtoReflect() protoreflect.Message { - mi := &file_SignalService_proto_msgTypes[63] + mi := &file_SignalService_proto_msgTypes[66] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6585,7 +6787,7 @@ type SyncMessage_CallEvent struct { func (x *SyncMessage_CallEvent) Reset() { *x = SyncMessage_CallEvent{} - mi := &file_SignalService_proto_msgTypes[64] + mi := &file_SignalService_proto_msgTypes[67] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6597,7 +6799,7 @@ func (x *SyncMessage_CallEvent) String() string { func (*SyncMessage_CallEvent) ProtoMessage() {} func (x *SyncMessage_CallEvent) ProtoReflect() protoreflect.Message { - mi := &file_SignalService_proto_msgTypes[64] + mi := &file_SignalService_proto_msgTypes[67] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6667,7 +6869,7 @@ type SyncMessage_CallLinkUpdate struct { func (x *SyncMessage_CallLinkUpdate) Reset() { *x = SyncMessage_CallLinkUpdate{} - mi := &file_SignalService_proto_msgTypes[65] + mi := &file_SignalService_proto_msgTypes[68] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6679,7 +6881,7 @@ func (x *SyncMessage_CallLinkUpdate) String() string { func (*SyncMessage_CallLinkUpdate) ProtoMessage() {} func (x *SyncMessage_CallLinkUpdate) ProtoReflect() protoreflect.Message { - mi := &file_SignalService_proto_msgTypes[65] + mi := &file_SignalService_proto_msgTypes[68] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6740,7 +6942,7 @@ type SyncMessage_CallLogEvent struct { func (x *SyncMessage_CallLogEvent) Reset() { *x = SyncMessage_CallLogEvent{} - mi := &file_SignalService_proto_msgTypes[66] + mi := &file_SignalService_proto_msgTypes[69] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6752,7 +6954,7 @@ func (x *SyncMessage_CallLogEvent) String() string { func (*SyncMessage_CallLogEvent) ProtoMessage() {} func (x *SyncMessage_CallLogEvent) ProtoReflect() protoreflect.Message { - mi := &file_SignalService_proto_msgTypes[66] + mi := &file_SignalService_proto_msgTypes[69] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6808,7 +7010,7 @@ type SyncMessage_DeleteForMe struct { func (x *SyncMessage_DeleteForMe) Reset() { *x = SyncMessage_DeleteForMe{} - mi := &file_SignalService_proto_msgTypes[67] + mi := &file_SignalService_proto_msgTypes[70] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6820,7 +7022,7 @@ func (x *SyncMessage_DeleteForMe) String() string { func (*SyncMessage_DeleteForMe) ProtoMessage() {} func (x *SyncMessage_DeleteForMe) ProtoReflect() protoreflect.Message { - mi := &file_SignalService_proto_msgTypes[67] + mi := &file_SignalService_proto_msgTypes[70] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6873,7 +7075,7 @@ type SyncMessage_DeviceNameChange struct { func (x *SyncMessage_DeviceNameChange) Reset() { *x = SyncMessage_DeviceNameChange{} - mi := &file_SignalService_proto_msgTypes[68] + mi := &file_SignalService_proto_msgTypes[71] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6885,7 +7087,7 @@ func (x *SyncMessage_DeviceNameChange) String() string { func (*SyncMessage_DeviceNameChange) ProtoMessage() {} func (x *SyncMessage_DeviceNameChange) ProtoReflect() protoreflect.Message { - mi := &file_SignalService_proto_msgTypes[68] + mi := &file_SignalService_proto_msgTypes[71] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6918,7 +7120,7 @@ type SyncMessage_AttachmentBackfillRequest struct { func (x *SyncMessage_AttachmentBackfillRequest) Reset() { *x = SyncMessage_AttachmentBackfillRequest{} - mi := &file_SignalService_proto_msgTypes[69] + mi := &file_SignalService_proto_msgTypes[72] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6930,7 +7132,7 @@ func (x *SyncMessage_AttachmentBackfillRequest) String() string { func (*SyncMessage_AttachmentBackfillRequest) ProtoMessage() {} func (x *SyncMessage_AttachmentBackfillRequest) ProtoReflect() protoreflect.Message { - mi := &file_SignalService_proto_msgTypes[69] + mi := &file_SignalService_proto_msgTypes[72] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6975,7 +7177,7 @@ type SyncMessage_AttachmentBackfillResponse struct { func (x *SyncMessage_AttachmentBackfillResponse) Reset() { *x = SyncMessage_AttachmentBackfillResponse{} - mi := &file_SignalService_proto_msgTypes[70] + mi := &file_SignalService_proto_msgTypes[73] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6987,7 +7189,7 @@ func (x *SyncMessage_AttachmentBackfillResponse) String() string { func (*SyncMessage_AttachmentBackfillResponse) ProtoMessage() {} func (x *SyncMessage_AttachmentBackfillResponse) ProtoReflect() protoreflect.Message { - mi := &file_SignalService_proto_msgTypes[70] + mi := &file_SignalService_proto_msgTypes[73] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7071,7 +7273,7 @@ type SyncMessage_Sent_UnidentifiedDeliveryStatus struct { func (x *SyncMessage_Sent_UnidentifiedDeliveryStatus) Reset() { *x = SyncMessage_Sent_UnidentifiedDeliveryStatus{} - mi := &file_SignalService_proto_msgTypes[71] + mi := &file_SignalService_proto_msgTypes[74] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7083,7 +7285,7 @@ func (x *SyncMessage_Sent_UnidentifiedDeliveryStatus) String() string { func (*SyncMessage_Sent_UnidentifiedDeliveryStatus) ProtoMessage() {} func (x *SyncMessage_Sent_UnidentifiedDeliveryStatus) ProtoReflect() protoreflect.Message { - mi := &file_SignalService_proto_msgTypes[71] + mi := &file_SignalService_proto_msgTypes[74] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7131,7 +7333,7 @@ type SyncMessage_Sent_StoryMessageRecipient struct { func (x *SyncMessage_Sent_StoryMessageRecipient) Reset() { *x = SyncMessage_Sent_StoryMessageRecipient{} - mi := &file_SignalService_proto_msgTypes[72] + mi := &file_SignalService_proto_msgTypes[75] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7143,7 +7345,7 @@ func (x *SyncMessage_Sent_StoryMessageRecipient) String() string { func (*SyncMessage_Sent_StoryMessageRecipient) ProtoMessage() {} func (x *SyncMessage_Sent_StoryMessageRecipient) ProtoReflect() protoreflect.Message { - mi := &file_SignalService_proto_msgTypes[72] + mi := &file_SignalService_proto_msgTypes[75] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7196,7 +7398,7 @@ type SyncMessage_OutgoingPayment_MobileCoin struct { func (x *SyncMessage_OutgoingPayment_MobileCoin) Reset() { *x = SyncMessage_OutgoingPayment_MobileCoin{} - mi := &file_SignalService_proto_msgTypes[73] + mi := &file_SignalService_proto_msgTypes[76] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7208,7 +7410,7 @@ func (x *SyncMessage_OutgoingPayment_MobileCoin) String() string { func (*SyncMessage_OutgoingPayment_MobileCoin) ProtoMessage() {} func (x *SyncMessage_OutgoingPayment_MobileCoin) ProtoReflect() protoreflect.Message { - mi := &file_SignalService_proto_msgTypes[73] + mi := &file_SignalService_proto_msgTypes[76] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7290,7 +7492,7 @@ type SyncMessage_DeleteForMe_MessageDeletes struct { func (x *SyncMessage_DeleteForMe_MessageDeletes) Reset() { *x = SyncMessage_DeleteForMe_MessageDeletes{} - mi := &file_SignalService_proto_msgTypes[74] + mi := &file_SignalService_proto_msgTypes[77] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7302,7 +7504,7 @@ func (x *SyncMessage_DeleteForMe_MessageDeletes) String() string { func (*SyncMessage_DeleteForMe_MessageDeletes) ProtoMessage() {} func (x *SyncMessage_DeleteForMe_MessageDeletes) ProtoReflect() protoreflect.Message { - mi := &file_SignalService_proto_msgTypes[74] + mi := &file_SignalService_proto_msgTypes[77] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7348,7 +7550,7 @@ type SyncMessage_DeleteForMe_AttachmentDelete struct { func (x *SyncMessage_DeleteForMe_AttachmentDelete) Reset() { *x = SyncMessage_DeleteForMe_AttachmentDelete{} - mi := &file_SignalService_proto_msgTypes[75] + mi := &file_SignalService_proto_msgTypes[78] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7360,7 +7562,7 @@ func (x *SyncMessage_DeleteForMe_AttachmentDelete) String() string { func (*SyncMessage_DeleteForMe_AttachmentDelete) ProtoMessage() {} func (x *SyncMessage_DeleteForMe_AttachmentDelete) ProtoReflect() protoreflect.Message { - mi := &file_SignalService_proto_msgTypes[75] + mi := &file_SignalService_proto_msgTypes[78] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7423,7 +7625,7 @@ type SyncMessage_DeleteForMe_ConversationDelete struct { func (x *SyncMessage_DeleteForMe_ConversationDelete) Reset() { *x = SyncMessage_DeleteForMe_ConversationDelete{} - mi := &file_SignalService_proto_msgTypes[76] + mi := &file_SignalService_proto_msgTypes[79] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7435,7 +7637,7 @@ func (x *SyncMessage_DeleteForMe_ConversationDelete) String() string { func (*SyncMessage_DeleteForMe_ConversationDelete) ProtoMessage() {} func (x *SyncMessage_DeleteForMe_ConversationDelete) ProtoReflect() protoreflect.Message { - mi := &file_SignalService_proto_msgTypes[76] + mi := &file_SignalService_proto_msgTypes[79] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7488,7 +7690,7 @@ type SyncMessage_DeleteForMe_LocalOnlyConversationDelete struct { func (x *SyncMessage_DeleteForMe_LocalOnlyConversationDelete) Reset() { *x = SyncMessage_DeleteForMe_LocalOnlyConversationDelete{} - mi := &file_SignalService_proto_msgTypes[77] + mi := &file_SignalService_proto_msgTypes[80] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7500,7 +7702,7 @@ func (x *SyncMessage_DeleteForMe_LocalOnlyConversationDelete) String() string { func (*SyncMessage_DeleteForMe_LocalOnlyConversationDelete) ProtoMessage() {} func (x *SyncMessage_DeleteForMe_LocalOnlyConversationDelete) ProtoReflect() protoreflect.Message { - mi := &file_SignalService_proto_msgTypes[77] + mi := &file_SignalService_proto_msgTypes[80] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7536,7 +7738,7 @@ type SyncMessage_AttachmentBackfillResponse_AttachmentData struct { func (x *SyncMessage_AttachmentBackfillResponse_AttachmentData) Reset() { *x = SyncMessage_AttachmentBackfillResponse_AttachmentData{} - mi := &file_SignalService_proto_msgTypes[78] + mi := &file_SignalService_proto_msgTypes[81] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7548,7 +7750,7 @@ func (x *SyncMessage_AttachmentBackfillResponse_AttachmentData) String() string func (*SyncMessage_AttachmentBackfillResponse_AttachmentData) ProtoMessage() {} func (x *SyncMessage_AttachmentBackfillResponse_AttachmentData) ProtoReflect() protoreflect.Message { - mi := &file_SignalService_proto_msgTypes[78] + mi := &file_SignalService_proto_msgTypes[81] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7617,7 +7819,7 @@ type SyncMessage_AttachmentBackfillResponse_AttachmentDataList struct { func (x *SyncMessage_AttachmentBackfillResponse_AttachmentDataList) Reset() { *x = SyncMessage_AttachmentBackfillResponse_AttachmentDataList{} - mi := &file_SignalService_proto_msgTypes[79] + mi := &file_SignalService_proto_msgTypes[82] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7629,7 +7831,7 @@ func (x *SyncMessage_AttachmentBackfillResponse_AttachmentDataList) String() str func (*SyncMessage_AttachmentBackfillResponse_AttachmentDataList) ProtoMessage() {} func (x *SyncMessage_AttachmentBackfillResponse_AttachmentDataList) ProtoReflect() protoreflect.Message { - mi := &file_SignalService_proto_msgTypes[79] + mi := &file_SignalService_proto_msgTypes[82] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7669,7 +7871,7 @@ type ContactDetails_Avatar struct { func (x *ContactDetails_Avatar) Reset() { *x = ContactDetails_Avatar{} - mi := &file_SignalService_proto_msgTypes[80] + mi := &file_SignalService_proto_msgTypes[83] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7681,7 +7883,7 @@ func (x *ContactDetails_Avatar) String() string { func (*ContactDetails_Avatar) ProtoMessage() {} func (x *ContactDetails_Avatar) ProtoReflect() protoreflect.Message { - mi := &file_SignalService_proto_msgTypes[80] + mi := &file_SignalService_proto_msgTypes[83] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7721,7 +7923,7 @@ type PaymentAddress_MobileCoin struct { func (x *PaymentAddress_MobileCoin) Reset() { *x = PaymentAddress_MobileCoin{} - mi := &file_SignalService_proto_msgTypes[81] + mi := &file_SignalService_proto_msgTypes[84] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7733,7 +7935,7 @@ func (x *PaymentAddress_MobileCoin) String() string { func (*PaymentAddress_MobileCoin) ProtoMessage() {} func (x *PaymentAddress_MobileCoin) ProtoReflect() protoreflect.Message { - mi := &file_SignalService_proto_msgTypes[81] + mi := &file_SignalService_proto_msgTypes[84] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7848,7 +8050,7 @@ const file_SignalService_proto_rawDesc = "" + "\aurgency\x18\x02 \x01(\x0e2).signalservice.CallMessage.Opaque.UrgencyR\aurgency\"0\n" + "\aUrgency\x12\r\n" + "\tDROPPABLE\x10\x00\x12\x16\n" + - "\x12HANDLE_IMMEDIATELY\x10\x01J\x04\b\x04\x10\x05J\x04\b\x06\x10\aJ\x04\b\b\x10\t\"\xf7\"\n" + + "\x12HANDLE_IMMEDIATELY\x10\x01J\x04\b\x04\x10\x05J\x04\b\x06\x10\aJ\x04\b\b\x10\t\"\xca'\n" + "\vDataMessage\x12\x12\n" + "\x04body\x18\x01 \x01(\tR\x04body\x12B\n" + "\vattachments\x18\x02 \x03(\v2 .signalservice.AttachmentPointerR\vattachments\x127\n" + @@ -7877,7 +8079,12 @@ const file_SignalService_proto_rawDesc = "" + "\x0fgroupCallUpdate\x18\x13 \x01(\v2*.signalservice.DataMessage.GroupCallUpdateR\x0fgroupCallUpdate\x12<\n" + "\apayment\x18\x14 \x01(\v2\".signalservice.DataMessage.PaymentR\apayment\x12K\n" + "\fstoryContext\x18\x15 \x01(\v2'.signalservice.DataMessage.StoryContextR\fstoryContext\x12B\n" + - "\tgiftBadge\x18\x16 \x01(\v2$.signalservice.DataMessage.GiftBadgeR\tgiftBadge\x1a\x9a\x05\n" + + "\tgiftBadge\x18\x16 \x01(\v2$.signalservice.DataMessage.GiftBadgeR\tgiftBadge\x12E\n" + + "\n" + + "pollCreate\x18\x18 \x01(\v2%.signalservice.DataMessage.PollCreateR\n" + + "pollCreate\x12N\n" + + "\rpollTerminate\x18\x19 \x01(\v2(.signalservice.DataMessage.PollTerminateR\rpollTerminate\x12?\n" + + "\bpollVote\x18\x1a \x01(\v2#.signalservice.DataMessage.PollVoteR\bpollVote\x1a\x9a\x05\n" + "\aPayment\x12U\n" + "\fnotification\x18\x01 \x01(\v2/.signalservice.DataMessage.Payment.NotificationH\x00R\fnotification\x12O\n" + "\n" + @@ -7906,7 +8113,7 @@ const file_SignalService_proto_rawDesc = "" + "\x04Type\x12\v\n" + "\aREQUEST\x10\x00\x12\r\n" + "\tACTIVATED\x10\x01B\x06\n" + - "\x04ItemJ\x06\b\xea\a\x10\xeb\aJ\x06\b\xeb\a\x10\xec\a\x1a\xd0\x03\n" + + "\x04ItemJ\x06\b\xea\a\x10\xeb\aJ\x06\b\xeb\a\x10\xec\a\x1a\xda\x03\n" + "\x05Quote\x12\x0e\n" + "\x02id\x18\x01 \x01(\x04R\x02id\x12\x1c\n" + "\tauthorAci\x18\x05 \x01(\tR\tauthorAci\x12\x12\n" + @@ -7919,12 +8126,13 @@ const file_SignalService_proto_rawDesc = "" + "\x10QuotedAttachment\x12 \n" + "\vcontentType\x18\x01 \x01(\tR\vcontentType\x12\x1a\n" + "\bfileName\x18\x02 \x01(\tR\bfileName\x12>\n" + - "\tthumbnail\x18\x03 \x01(\v2 .signalservice.AttachmentPointerR\tthumbnail\"\"\n" + + "\tthumbnail\x18\x03 \x01(\v2 .signalservice.AttachmentPointerR\tthumbnail\",\n" + "\x04Type\x12\n" + "\n" + "\x06NORMAL\x10\x00\x12\x0e\n" + "\n" + - "GIFT_BADGE\x10\x01J\x04\b\x02\x10\x03\x1a\xbf\n" + + "GIFT_BADGE\x10\x01\x12\b\n" + + "\x04POLL\x10\x02J\x04\b\x02\x10\x03\x1a\xbf\n" + "\n" + "\aContact\x12;\n" + "\x04name\x18\x01 \x01(\v2'.signalservice.DataMessage.Contact.NameR\x04name\x12@\n" + @@ -8003,12 +8211,24 @@ const file_SignalService_proto_rawDesc = "" + "\tauthorAci\x18\x01 \x01(\tR\tauthorAci\x12$\n" + "\rsentTimestamp\x18\x02 \x01(\x04R\rsentTimestamp\x1aQ\n" + "\tGiftBadge\x12D\n" + - "\x1dreceiptCredentialPresentation\x18\x01 \x01(\fR\x1dreceiptCredentialPresentation\"Z\n" + + "\x1dreceiptCredentialPresentation\x18\x01 \x01(\fR\x1dreceiptCredentialPresentation\x1ah\n" + + "\n" + + "PollCreate\x12\x1a\n" + + "\bquestion\x18\x01 \x01(\tR\bquestion\x12$\n" + + "\rallowMultiple\x18\x02 \x01(\bR\rallowMultiple\x12\x18\n" + + "\aoptions\x18\x03 \x03(\tR\aoptions\x1aA\n" + + "\rPollTerminate\x120\n" + + "\x13targetSentTimestamp\x18\x01 \x01(\x04R\x13targetSentTimestamp\x1a\xb6\x01\n" + + "\bPollVote\x124\n" + + "\x15targetAuthorAciBinary\x18\x01 \x01(\fR\x15targetAuthorAciBinary\x120\n" + + "\x13targetSentTimestamp\x18\x02 \x01(\x04R\x13targetSentTimestamp\x12$\n" + + "\roptionIndexes\x18\x03 \x03(\rR\roptionIndexes\x12\x1c\n" + + "\tvoteCount\x18\x04 \x01(\rR\tvoteCount\"Z\n" + "\x05Flags\x12\x0f\n" + "\vEND_SESSION\x10\x01\x12\x1b\n" + "\x17EXPIRATION_TIMER_UPDATE\x10\x02\x12\x16\n" + "\x12PROFILE_KEY_UPDATE\x10\x04\x12\v\n" + - "\aFORWARD\x10\b\"\xb0\x01\n" + + "\aFORWARD\x10\b\"\xbb\x01\n" + "\x0fProtocolVersion\x12\v\n" + "\aINITIAL\x10\x00\x12\x12\n" + "\x0eMESSAGE_TIMERS\x10\x01\x12\r\n" + @@ -8017,7 +8237,8 @@ const file_SignalService_proto_rawDesc = "" + "\tREACTIONS\x10\x04\x12\x1c\n" + "\x18CDN_SELECTOR_ATTACHMENTS\x10\x05\x12\f\n" + "\bMENTIONS\x10\x06\x12\f\n" + - "\bPAYMENTS\x10\a\x12\v\n" + + "\bPAYMENTS\x10\a\x12\t\n" + + "\x05POLLS\x10\b\x12\v\n" + "\aCURRENT\x10\a\x1a\x02\x10\x01J\x04\b\x03\x10\x04\"'\n" + "\vNullMessage\x12\x18\n" + "\apadding\x18\x01 \x01(\fR\apadding\"\x92\x01\n" + @@ -8434,7 +8655,7 @@ func file_SignalService_proto_rawDescGZIP() []byte { } var file_SignalService_proto_enumTypes = make([]protoimpl.EnumInfo, 28) -var file_SignalService_proto_msgTypes = make([]protoimpl.MessageInfo, 82) +var file_SignalService_proto_msgTypes = make([]protoimpl.MessageInfo, 85) var file_SignalService_proto_goTypes = []any{ (Envelope_Type)(0), // 0: signalservice.Envelope.Type (CallMessage_Offer_Type)(0), // 1: signalservice.CallMessage.Offer.Type @@ -8501,51 +8722,54 @@ var file_SignalService_proto_goTypes = []any{ (*DataMessage_GroupCallUpdate)(nil), // 62: signalservice.DataMessage.GroupCallUpdate (*DataMessage_StoryContext)(nil), // 63: signalservice.DataMessage.StoryContext (*DataMessage_GiftBadge)(nil), // 64: signalservice.DataMessage.GiftBadge - (*DataMessage_Payment_Amount)(nil), // 65: signalservice.DataMessage.Payment.Amount - (*DataMessage_Payment_Notification)(nil), // 66: signalservice.DataMessage.Payment.Notification - (*DataMessage_Payment_Activation)(nil), // 67: signalservice.DataMessage.Payment.Activation - (*DataMessage_Payment_Amount_MobileCoin)(nil), // 68: signalservice.DataMessage.Payment.Amount.MobileCoin - (*DataMessage_Payment_Notification_MobileCoin)(nil), // 69: signalservice.DataMessage.Payment.Notification.MobileCoin - (*DataMessage_Quote_QuotedAttachment)(nil), // 70: signalservice.DataMessage.Quote.QuotedAttachment - (*DataMessage_Contact_Name)(nil), // 71: signalservice.DataMessage.Contact.Name - (*DataMessage_Contact_Phone)(nil), // 72: signalservice.DataMessage.Contact.Phone - (*DataMessage_Contact_Email)(nil), // 73: signalservice.DataMessage.Contact.Email - (*DataMessage_Contact_PostalAddress)(nil), // 74: signalservice.DataMessage.Contact.PostalAddress - (*DataMessage_Contact_Avatar)(nil), // 75: signalservice.DataMessage.Contact.Avatar - (*TextAttachment_Gradient)(nil), // 76: signalservice.TextAttachment.Gradient - (*SyncMessage_Sent)(nil), // 77: signalservice.SyncMessage.Sent - (*SyncMessage_Contacts)(nil), // 78: signalservice.SyncMessage.Contacts - (*SyncMessage_Blocked)(nil), // 79: signalservice.SyncMessage.Blocked - (*SyncMessage_Request)(nil), // 80: signalservice.SyncMessage.Request - (*SyncMessage_Read)(nil), // 81: signalservice.SyncMessage.Read - (*SyncMessage_Viewed)(nil), // 82: signalservice.SyncMessage.Viewed - (*SyncMessage_Configuration)(nil), // 83: signalservice.SyncMessage.Configuration - (*SyncMessage_StickerPackOperation)(nil), // 84: signalservice.SyncMessage.StickerPackOperation - (*SyncMessage_ViewOnceOpen)(nil), // 85: signalservice.SyncMessage.ViewOnceOpen - (*SyncMessage_FetchLatest)(nil), // 86: signalservice.SyncMessage.FetchLatest - (*SyncMessage_Keys)(nil), // 87: signalservice.SyncMessage.Keys - (*SyncMessage_PniIdentity)(nil), // 88: signalservice.SyncMessage.PniIdentity - (*SyncMessage_MessageRequestResponse)(nil), // 89: signalservice.SyncMessage.MessageRequestResponse - (*SyncMessage_OutgoingPayment)(nil), // 90: signalservice.SyncMessage.OutgoingPayment - (*SyncMessage_PniChangeNumber)(nil), // 91: signalservice.SyncMessage.PniChangeNumber - (*SyncMessage_CallEvent)(nil), // 92: signalservice.SyncMessage.CallEvent - (*SyncMessage_CallLinkUpdate)(nil), // 93: signalservice.SyncMessage.CallLinkUpdate - (*SyncMessage_CallLogEvent)(nil), // 94: signalservice.SyncMessage.CallLogEvent - (*SyncMessage_DeleteForMe)(nil), // 95: signalservice.SyncMessage.DeleteForMe - (*SyncMessage_DeviceNameChange)(nil), // 96: signalservice.SyncMessage.DeviceNameChange - (*SyncMessage_AttachmentBackfillRequest)(nil), // 97: signalservice.SyncMessage.AttachmentBackfillRequest - (*SyncMessage_AttachmentBackfillResponse)(nil), // 98: signalservice.SyncMessage.AttachmentBackfillResponse - (*SyncMessage_Sent_UnidentifiedDeliveryStatus)(nil), // 99: signalservice.SyncMessage.Sent.UnidentifiedDeliveryStatus - (*SyncMessage_Sent_StoryMessageRecipient)(nil), // 100: signalservice.SyncMessage.Sent.StoryMessageRecipient - (*SyncMessage_OutgoingPayment_MobileCoin)(nil), // 101: signalservice.SyncMessage.OutgoingPayment.MobileCoin - (*SyncMessage_DeleteForMe_MessageDeletes)(nil), // 102: signalservice.SyncMessage.DeleteForMe.MessageDeletes - (*SyncMessage_DeleteForMe_AttachmentDelete)(nil), // 103: signalservice.SyncMessage.DeleteForMe.AttachmentDelete - (*SyncMessage_DeleteForMe_ConversationDelete)(nil), // 104: signalservice.SyncMessage.DeleteForMe.ConversationDelete - (*SyncMessage_DeleteForMe_LocalOnlyConversationDelete)(nil), // 105: signalservice.SyncMessage.DeleteForMe.LocalOnlyConversationDelete - (*SyncMessage_AttachmentBackfillResponse_AttachmentData)(nil), // 106: signalservice.SyncMessage.AttachmentBackfillResponse.AttachmentData - (*SyncMessage_AttachmentBackfillResponse_AttachmentDataList)(nil), // 107: signalservice.SyncMessage.AttachmentBackfillResponse.AttachmentDataList - (*ContactDetails_Avatar)(nil), // 108: signalservice.ContactDetails.Avatar - (*PaymentAddress_MobileCoin)(nil), // 109: signalservice.PaymentAddress.MobileCoin + (*DataMessage_PollCreate)(nil), // 65: signalservice.DataMessage.PollCreate + (*DataMessage_PollTerminate)(nil), // 66: signalservice.DataMessage.PollTerminate + (*DataMessage_PollVote)(nil), // 67: signalservice.DataMessage.PollVote + (*DataMessage_Payment_Amount)(nil), // 68: signalservice.DataMessage.Payment.Amount + (*DataMessage_Payment_Notification)(nil), // 69: signalservice.DataMessage.Payment.Notification + (*DataMessage_Payment_Activation)(nil), // 70: signalservice.DataMessage.Payment.Activation + (*DataMessage_Payment_Amount_MobileCoin)(nil), // 71: signalservice.DataMessage.Payment.Amount.MobileCoin + (*DataMessage_Payment_Notification_MobileCoin)(nil), // 72: signalservice.DataMessage.Payment.Notification.MobileCoin + (*DataMessage_Quote_QuotedAttachment)(nil), // 73: signalservice.DataMessage.Quote.QuotedAttachment + (*DataMessage_Contact_Name)(nil), // 74: signalservice.DataMessage.Contact.Name + (*DataMessage_Contact_Phone)(nil), // 75: signalservice.DataMessage.Contact.Phone + (*DataMessage_Contact_Email)(nil), // 76: signalservice.DataMessage.Contact.Email + (*DataMessage_Contact_PostalAddress)(nil), // 77: signalservice.DataMessage.Contact.PostalAddress + (*DataMessage_Contact_Avatar)(nil), // 78: signalservice.DataMessage.Contact.Avatar + (*TextAttachment_Gradient)(nil), // 79: signalservice.TextAttachment.Gradient + (*SyncMessage_Sent)(nil), // 80: signalservice.SyncMessage.Sent + (*SyncMessage_Contacts)(nil), // 81: signalservice.SyncMessage.Contacts + (*SyncMessage_Blocked)(nil), // 82: signalservice.SyncMessage.Blocked + (*SyncMessage_Request)(nil), // 83: signalservice.SyncMessage.Request + (*SyncMessage_Read)(nil), // 84: signalservice.SyncMessage.Read + (*SyncMessage_Viewed)(nil), // 85: signalservice.SyncMessage.Viewed + (*SyncMessage_Configuration)(nil), // 86: signalservice.SyncMessage.Configuration + (*SyncMessage_StickerPackOperation)(nil), // 87: signalservice.SyncMessage.StickerPackOperation + (*SyncMessage_ViewOnceOpen)(nil), // 88: signalservice.SyncMessage.ViewOnceOpen + (*SyncMessage_FetchLatest)(nil), // 89: signalservice.SyncMessage.FetchLatest + (*SyncMessage_Keys)(nil), // 90: signalservice.SyncMessage.Keys + (*SyncMessage_PniIdentity)(nil), // 91: signalservice.SyncMessage.PniIdentity + (*SyncMessage_MessageRequestResponse)(nil), // 92: signalservice.SyncMessage.MessageRequestResponse + (*SyncMessage_OutgoingPayment)(nil), // 93: signalservice.SyncMessage.OutgoingPayment + (*SyncMessage_PniChangeNumber)(nil), // 94: signalservice.SyncMessage.PniChangeNumber + (*SyncMessage_CallEvent)(nil), // 95: signalservice.SyncMessage.CallEvent + (*SyncMessage_CallLinkUpdate)(nil), // 96: signalservice.SyncMessage.CallLinkUpdate + (*SyncMessage_CallLogEvent)(nil), // 97: signalservice.SyncMessage.CallLogEvent + (*SyncMessage_DeleteForMe)(nil), // 98: signalservice.SyncMessage.DeleteForMe + (*SyncMessage_DeviceNameChange)(nil), // 99: signalservice.SyncMessage.DeviceNameChange + (*SyncMessage_AttachmentBackfillRequest)(nil), // 100: signalservice.SyncMessage.AttachmentBackfillRequest + (*SyncMessage_AttachmentBackfillResponse)(nil), // 101: signalservice.SyncMessage.AttachmentBackfillResponse + (*SyncMessage_Sent_UnidentifiedDeliveryStatus)(nil), // 102: signalservice.SyncMessage.Sent.UnidentifiedDeliveryStatus + (*SyncMessage_Sent_StoryMessageRecipient)(nil), // 103: signalservice.SyncMessage.Sent.StoryMessageRecipient + (*SyncMessage_OutgoingPayment_MobileCoin)(nil), // 104: signalservice.SyncMessage.OutgoingPayment.MobileCoin + (*SyncMessage_DeleteForMe_MessageDeletes)(nil), // 105: signalservice.SyncMessage.DeleteForMe.MessageDeletes + (*SyncMessage_DeleteForMe_AttachmentDelete)(nil), // 106: signalservice.SyncMessage.DeleteForMe.AttachmentDelete + (*SyncMessage_DeleteForMe_ConversationDelete)(nil), // 107: signalservice.SyncMessage.DeleteForMe.ConversationDelete + (*SyncMessage_DeleteForMe_LocalOnlyConversationDelete)(nil), // 108: signalservice.SyncMessage.DeleteForMe.LocalOnlyConversationDelete + (*SyncMessage_AttachmentBackfillResponse_AttachmentData)(nil), // 109: signalservice.SyncMessage.AttachmentBackfillResponse.AttachmentData + (*SyncMessage_AttachmentBackfillResponse_AttachmentDataList)(nil), // 110: signalservice.SyncMessage.AttachmentBackfillResponse.AttachmentDataList + (*ContactDetails_Avatar)(nil), // 111: signalservice.ContactDetails.Avatar + (*PaymentAddress_MobileCoin)(nil), // 112: signalservice.PaymentAddress.MobileCoin } var file_SignalService_proto_depIdxs = []int32{ 0, // 0: signalservice.Envelope.type:type_name -> signalservice.Envelope.Type @@ -8577,108 +8801,111 @@ var file_SignalService_proto_depIdxs = []int32{ 56, // 26: signalservice.DataMessage.payment:type_name -> signalservice.DataMessage.Payment 63, // 27: signalservice.DataMessage.storyContext:type_name -> signalservice.DataMessage.StoryContext 64, // 28: signalservice.DataMessage.giftBadge:type_name -> signalservice.DataMessage.GiftBadge - 11, // 29: signalservice.ReceiptMessage.type:type_name -> signalservice.ReceiptMessage.Type - 12, // 30: signalservice.TypingMessage.action:type_name -> signalservice.TypingMessage.Action - 41, // 31: signalservice.StoryMessage.group:type_name -> signalservice.GroupContextV2 - 40, // 32: signalservice.StoryMessage.fileAttachment:type_name -> signalservice.AttachmentPointer - 37, // 33: signalservice.StoryMessage.textAttachment:type_name -> signalservice.TextAttachment - 47, // 34: signalservice.StoryMessage.bodyRanges:type_name -> signalservice.BodyRange - 40, // 35: signalservice.Preview.image:type_name -> signalservice.AttachmentPointer - 13, // 36: signalservice.TextAttachment.textStyle:type_name -> signalservice.TextAttachment.Style - 36, // 37: signalservice.TextAttachment.preview:type_name -> signalservice.Preview - 76, // 38: signalservice.TextAttachment.gradient:type_name -> signalservice.TextAttachment.Gradient - 14, // 39: signalservice.Verified.state:type_name -> signalservice.Verified.State - 77, // 40: signalservice.SyncMessage.sent:type_name -> signalservice.SyncMessage.Sent - 78, // 41: signalservice.SyncMessage.contacts:type_name -> signalservice.SyncMessage.Contacts - 80, // 42: signalservice.SyncMessage.request:type_name -> signalservice.SyncMessage.Request - 81, // 43: signalservice.SyncMessage.read:type_name -> signalservice.SyncMessage.Read - 79, // 44: signalservice.SyncMessage.blocked:type_name -> signalservice.SyncMessage.Blocked - 38, // 45: signalservice.SyncMessage.verified:type_name -> signalservice.Verified - 83, // 46: signalservice.SyncMessage.configuration:type_name -> signalservice.SyncMessage.Configuration - 84, // 47: signalservice.SyncMessage.stickerPackOperation:type_name -> signalservice.SyncMessage.StickerPackOperation - 85, // 48: signalservice.SyncMessage.viewOnceOpen:type_name -> signalservice.SyncMessage.ViewOnceOpen - 86, // 49: signalservice.SyncMessage.fetchLatest:type_name -> signalservice.SyncMessage.FetchLatest - 87, // 50: signalservice.SyncMessage.keys:type_name -> signalservice.SyncMessage.Keys - 89, // 51: signalservice.SyncMessage.messageRequestResponse:type_name -> signalservice.SyncMessage.MessageRequestResponse - 90, // 52: signalservice.SyncMessage.outgoingPayment:type_name -> signalservice.SyncMessage.OutgoingPayment - 82, // 53: signalservice.SyncMessage.viewed:type_name -> signalservice.SyncMessage.Viewed - 91, // 54: signalservice.SyncMessage.pniChangeNumber:type_name -> signalservice.SyncMessage.PniChangeNumber - 92, // 55: signalservice.SyncMessage.callEvent:type_name -> signalservice.SyncMessage.CallEvent - 93, // 56: signalservice.SyncMessage.callLinkUpdate:type_name -> signalservice.SyncMessage.CallLinkUpdate - 94, // 57: signalservice.SyncMessage.callLogEvent:type_name -> signalservice.SyncMessage.CallLogEvent - 95, // 58: signalservice.SyncMessage.deleteForMe:type_name -> signalservice.SyncMessage.DeleteForMe - 96, // 59: signalservice.SyncMessage.deviceNameChange:type_name -> signalservice.SyncMessage.DeviceNameChange - 97, // 60: signalservice.SyncMessage.attachmentBackfillRequest:type_name -> signalservice.SyncMessage.AttachmentBackfillRequest - 98, // 61: signalservice.SyncMessage.attachmentBackfillResponse:type_name -> signalservice.SyncMessage.AttachmentBackfillResponse - 108, // 62: signalservice.ContactDetails.avatar:type_name -> signalservice.ContactDetails.Avatar - 109, // 63: signalservice.PaymentAddress.mobileCoin:type_name -> signalservice.PaymentAddress.MobileCoin - 31, // 64: signalservice.EditMessage.dataMessage:type_name -> signalservice.DataMessage - 27, // 65: signalservice.BodyRange.style:type_name -> signalservice.BodyRange.Style - 1, // 66: signalservice.CallMessage.Offer.type:type_name -> signalservice.CallMessage.Offer.Type - 2, // 67: signalservice.CallMessage.Hangup.type:type_name -> signalservice.CallMessage.Hangup.Type - 3, // 68: signalservice.CallMessage.Opaque.urgency:type_name -> signalservice.CallMessage.Opaque.Urgency - 66, // 69: signalservice.DataMessage.Payment.notification:type_name -> signalservice.DataMessage.Payment.Notification - 67, // 70: signalservice.DataMessage.Payment.activation:type_name -> signalservice.DataMessage.Payment.Activation - 70, // 71: signalservice.DataMessage.Quote.attachments:type_name -> signalservice.DataMessage.Quote.QuotedAttachment - 47, // 72: signalservice.DataMessage.Quote.bodyRanges:type_name -> signalservice.BodyRange - 7, // 73: signalservice.DataMessage.Quote.type:type_name -> signalservice.DataMessage.Quote.Type - 71, // 74: signalservice.DataMessage.Contact.name:type_name -> signalservice.DataMessage.Contact.Name - 72, // 75: signalservice.DataMessage.Contact.number:type_name -> signalservice.DataMessage.Contact.Phone - 73, // 76: signalservice.DataMessage.Contact.email:type_name -> signalservice.DataMessage.Contact.Email - 74, // 77: signalservice.DataMessage.Contact.address:type_name -> signalservice.DataMessage.Contact.PostalAddress - 75, // 78: signalservice.DataMessage.Contact.avatar:type_name -> signalservice.DataMessage.Contact.Avatar - 40, // 79: signalservice.DataMessage.Sticker.data:type_name -> signalservice.AttachmentPointer - 68, // 80: signalservice.DataMessage.Payment.Amount.mobileCoin:type_name -> signalservice.DataMessage.Payment.Amount.MobileCoin - 69, // 81: signalservice.DataMessage.Payment.Notification.mobileCoin:type_name -> signalservice.DataMessage.Payment.Notification.MobileCoin - 6, // 82: signalservice.DataMessage.Payment.Activation.type:type_name -> signalservice.DataMessage.Payment.Activation.Type - 40, // 83: signalservice.DataMessage.Quote.QuotedAttachment.thumbnail:type_name -> signalservice.AttachmentPointer - 8, // 84: signalservice.DataMessage.Contact.Phone.type:type_name -> signalservice.DataMessage.Contact.Phone.Type - 9, // 85: signalservice.DataMessage.Contact.Email.type:type_name -> signalservice.DataMessage.Contact.Email.Type - 10, // 86: signalservice.DataMessage.Contact.PostalAddress.type:type_name -> signalservice.DataMessage.Contact.PostalAddress.Type - 40, // 87: signalservice.DataMessage.Contact.Avatar.avatar:type_name -> signalservice.AttachmentPointer - 31, // 88: signalservice.SyncMessage.Sent.message:type_name -> signalservice.DataMessage - 99, // 89: signalservice.SyncMessage.Sent.unidentifiedStatus:type_name -> signalservice.SyncMessage.Sent.UnidentifiedDeliveryStatus - 35, // 90: signalservice.SyncMessage.Sent.storyMessage:type_name -> signalservice.StoryMessage - 100, // 91: signalservice.SyncMessage.Sent.storyMessageRecipients:type_name -> signalservice.SyncMessage.Sent.StoryMessageRecipient - 46, // 92: signalservice.SyncMessage.Sent.editMessage:type_name -> signalservice.EditMessage - 40, // 93: signalservice.SyncMessage.Contacts.blob:type_name -> signalservice.AttachmentPointer - 15, // 94: signalservice.SyncMessage.Request.type:type_name -> signalservice.SyncMessage.Request.Type - 16, // 95: signalservice.SyncMessage.StickerPackOperation.type:type_name -> signalservice.SyncMessage.StickerPackOperation.Type - 17, // 96: signalservice.SyncMessage.FetchLatest.type:type_name -> signalservice.SyncMessage.FetchLatest.Type - 18, // 97: signalservice.SyncMessage.MessageRequestResponse.type:type_name -> signalservice.SyncMessage.MessageRequestResponse.Type - 101, // 98: signalservice.SyncMessage.OutgoingPayment.mobileCoin:type_name -> signalservice.SyncMessage.OutgoingPayment.MobileCoin - 19, // 99: signalservice.SyncMessage.CallEvent.type:type_name -> signalservice.SyncMessage.CallEvent.Type - 20, // 100: signalservice.SyncMessage.CallEvent.direction:type_name -> signalservice.SyncMessage.CallEvent.Direction - 21, // 101: signalservice.SyncMessage.CallEvent.event:type_name -> signalservice.SyncMessage.CallEvent.Event - 22, // 102: signalservice.SyncMessage.CallLinkUpdate.type:type_name -> signalservice.SyncMessage.CallLinkUpdate.Type - 23, // 103: signalservice.SyncMessage.CallLogEvent.type:type_name -> signalservice.SyncMessage.CallLogEvent.Type - 102, // 104: signalservice.SyncMessage.DeleteForMe.messageDeletes:type_name -> signalservice.SyncMessage.DeleteForMe.MessageDeletes - 104, // 105: signalservice.SyncMessage.DeleteForMe.conversationDeletes:type_name -> signalservice.SyncMessage.DeleteForMe.ConversationDelete - 105, // 106: signalservice.SyncMessage.DeleteForMe.localOnlyConversationDeletes:type_name -> signalservice.SyncMessage.DeleteForMe.LocalOnlyConversationDelete - 103, // 107: signalservice.SyncMessage.DeleteForMe.attachmentDeletes:type_name -> signalservice.SyncMessage.DeleteForMe.AttachmentDelete - 48, // 108: signalservice.SyncMessage.AttachmentBackfillRequest.targetMessage:type_name -> signalservice.AddressableMessage - 49, // 109: signalservice.SyncMessage.AttachmentBackfillRequest.targetConversation:type_name -> signalservice.ConversationIdentifier - 48, // 110: signalservice.SyncMessage.AttachmentBackfillResponse.targetMessage:type_name -> signalservice.AddressableMessage - 49, // 111: signalservice.SyncMessage.AttachmentBackfillResponse.targetConversation:type_name -> signalservice.ConversationIdentifier - 107, // 112: signalservice.SyncMessage.AttachmentBackfillResponse.attachments:type_name -> signalservice.SyncMessage.AttachmentBackfillResponse.AttachmentDataList - 24, // 113: signalservice.SyncMessage.AttachmentBackfillResponse.error:type_name -> signalservice.SyncMessage.AttachmentBackfillResponse.Error - 49, // 114: signalservice.SyncMessage.DeleteForMe.MessageDeletes.conversation:type_name -> signalservice.ConversationIdentifier - 48, // 115: signalservice.SyncMessage.DeleteForMe.MessageDeletes.messages:type_name -> signalservice.AddressableMessage - 49, // 116: signalservice.SyncMessage.DeleteForMe.AttachmentDelete.conversation:type_name -> signalservice.ConversationIdentifier - 48, // 117: signalservice.SyncMessage.DeleteForMe.AttachmentDelete.targetMessage:type_name -> signalservice.AddressableMessage - 49, // 118: signalservice.SyncMessage.DeleteForMe.ConversationDelete.conversation:type_name -> signalservice.ConversationIdentifier - 48, // 119: signalservice.SyncMessage.DeleteForMe.ConversationDelete.mostRecentMessages:type_name -> signalservice.AddressableMessage - 48, // 120: signalservice.SyncMessage.DeleteForMe.ConversationDelete.mostRecentNonExpiringMessages:type_name -> signalservice.AddressableMessage - 49, // 121: signalservice.SyncMessage.DeleteForMe.LocalOnlyConversationDelete.conversation:type_name -> signalservice.ConversationIdentifier - 40, // 122: signalservice.SyncMessage.AttachmentBackfillResponse.AttachmentData.attachment:type_name -> signalservice.AttachmentPointer - 25, // 123: signalservice.SyncMessage.AttachmentBackfillResponse.AttachmentData.status:type_name -> signalservice.SyncMessage.AttachmentBackfillResponse.AttachmentData.Status - 106, // 124: signalservice.SyncMessage.AttachmentBackfillResponse.AttachmentDataList.attachments:type_name -> signalservice.SyncMessage.AttachmentBackfillResponse.AttachmentData - 106, // 125: signalservice.SyncMessage.AttachmentBackfillResponse.AttachmentDataList.longText:type_name -> signalservice.SyncMessage.AttachmentBackfillResponse.AttachmentData - 126, // [126:126] is the sub-list for method output_type - 126, // [126:126] is the sub-list for method input_type - 126, // [126:126] is the sub-list for extension type_name - 126, // [126:126] is the sub-list for extension extendee - 0, // [0:126] is the sub-list for field type_name + 65, // 29: signalservice.DataMessage.pollCreate:type_name -> signalservice.DataMessage.PollCreate + 66, // 30: signalservice.DataMessage.pollTerminate:type_name -> signalservice.DataMessage.PollTerminate + 67, // 31: signalservice.DataMessage.pollVote:type_name -> signalservice.DataMessage.PollVote + 11, // 32: signalservice.ReceiptMessage.type:type_name -> signalservice.ReceiptMessage.Type + 12, // 33: signalservice.TypingMessage.action:type_name -> signalservice.TypingMessage.Action + 41, // 34: signalservice.StoryMessage.group:type_name -> signalservice.GroupContextV2 + 40, // 35: signalservice.StoryMessage.fileAttachment:type_name -> signalservice.AttachmentPointer + 37, // 36: signalservice.StoryMessage.textAttachment:type_name -> signalservice.TextAttachment + 47, // 37: signalservice.StoryMessage.bodyRanges:type_name -> signalservice.BodyRange + 40, // 38: signalservice.Preview.image:type_name -> signalservice.AttachmentPointer + 13, // 39: signalservice.TextAttachment.textStyle:type_name -> signalservice.TextAttachment.Style + 36, // 40: signalservice.TextAttachment.preview:type_name -> signalservice.Preview + 79, // 41: signalservice.TextAttachment.gradient:type_name -> signalservice.TextAttachment.Gradient + 14, // 42: signalservice.Verified.state:type_name -> signalservice.Verified.State + 80, // 43: signalservice.SyncMessage.sent:type_name -> signalservice.SyncMessage.Sent + 81, // 44: signalservice.SyncMessage.contacts:type_name -> signalservice.SyncMessage.Contacts + 83, // 45: signalservice.SyncMessage.request:type_name -> signalservice.SyncMessage.Request + 84, // 46: signalservice.SyncMessage.read:type_name -> signalservice.SyncMessage.Read + 82, // 47: signalservice.SyncMessage.blocked:type_name -> signalservice.SyncMessage.Blocked + 38, // 48: signalservice.SyncMessage.verified:type_name -> signalservice.Verified + 86, // 49: signalservice.SyncMessage.configuration:type_name -> signalservice.SyncMessage.Configuration + 87, // 50: signalservice.SyncMessage.stickerPackOperation:type_name -> signalservice.SyncMessage.StickerPackOperation + 88, // 51: signalservice.SyncMessage.viewOnceOpen:type_name -> signalservice.SyncMessage.ViewOnceOpen + 89, // 52: signalservice.SyncMessage.fetchLatest:type_name -> signalservice.SyncMessage.FetchLatest + 90, // 53: signalservice.SyncMessage.keys:type_name -> signalservice.SyncMessage.Keys + 92, // 54: signalservice.SyncMessage.messageRequestResponse:type_name -> signalservice.SyncMessage.MessageRequestResponse + 93, // 55: signalservice.SyncMessage.outgoingPayment:type_name -> signalservice.SyncMessage.OutgoingPayment + 85, // 56: signalservice.SyncMessage.viewed:type_name -> signalservice.SyncMessage.Viewed + 94, // 57: signalservice.SyncMessage.pniChangeNumber:type_name -> signalservice.SyncMessage.PniChangeNumber + 95, // 58: signalservice.SyncMessage.callEvent:type_name -> signalservice.SyncMessage.CallEvent + 96, // 59: signalservice.SyncMessage.callLinkUpdate:type_name -> signalservice.SyncMessage.CallLinkUpdate + 97, // 60: signalservice.SyncMessage.callLogEvent:type_name -> signalservice.SyncMessage.CallLogEvent + 98, // 61: signalservice.SyncMessage.deleteForMe:type_name -> signalservice.SyncMessage.DeleteForMe + 99, // 62: signalservice.SyncMessage.deviceNameChange:type_name -> signalservice.SyncMessage.DeviceNameChange + 100, // 63: signalservice.SyncMessage.attachmentBackfillRequest:type_name -> signalservice.SyncMessage.AttachmentBackfillRequest + 101, // 64: signalservice.SyncMessage.attachmentBackfillResponse:type_name -> signalservice.SyncMessage.AttachmentBackfillResponse + 111, // 65: signalservice.ContactDetails.avatar:type_name -> signalservice.ContactDetails.Avatar + 112, // 66: signalservice.PaymentAddress.mobileCoin:type_name -> signalservice.PaymentAddress.MobileCoin + 31, // 67: signalservice.EditMessage.dataMessage:type_name -> signalservice.DataMessage + 27, // 68: signalservice.BodyRange.style:type_name -> signalservice.BodyRange.Style + 1, // 69: signalservice.CallMessage.Offer.type:type_name -> signalservice.CallMessage.Offer.Type + 2, // 70: signalservice.CallMessage.Hangup.type:type_name -> signalservice.CallMessage.Hangup.Type + 3, // 71: signalservice.CallMessage.Opaque.urgency:type_name -> signalservice.CallMessage.Opaque.Urgency + 69, // 72: signalservice.DataMessage.Payment.notification:type_name -> signalservice.DataMessage.Payment.Notification + 70, // 73: signalservice.DataMessage.Payment.activation:type_name -> signalservice.DataMessage.Payment.Activation + 73, // 74: signalservice.DataMessage.Quote.attachments:type_name -> signalservice.DataMessage.Quote.QuotedAttachment + 47, // 75: signalservice.DataMessage.Quote.bodyRanges:type_name -> signalservice.BodyRange + 7, // 76: signalservice.DataMessage.Quote.type:type_name -> signalservice.DataMessage.Quote.Type + 74, // 77: signalservice.DataMessage.Contact.name:type_name -> signalservice.DataMessage.Contact.Name + 75, // 78: signalservice.DataMessage.Contact.number:type_name -> signalservice.DataMessage.Contact.Phone + 76, // 79: signalservice.DataMessage.Contact.email:type_name -> signalservice.DataMessage.Contact.Email + 77, // 80: signalservice.DataMessage.Contact.address:type_name -> signalservice.DataMessage.Contact.PostalAddress + 78, // 81: signalservice.DataMessage.Contact.avatar:type_name -> signalservice.DataMessage.Contact.Avatar + 40, // 82: signalservice.DataMessage.Sticker.data:type_name -> signalservice.AttachmentPointer + 71, // 83: signalservice.DataMessage.Payment.Amount.mobileCoin:type_name -> signalservice.DataMessage.Payment.Amount.MobileCoin + 72, // 84: signalservice.DataMessage.Payment.Notification.mobileCoin:type_name -> signalservice.DataMessage.Payment.Notification.MobileCoin + 6, // 85: signalservice.DataMessage.Payment.Activation.type:type_name -> signalservice.DataMessage.Payment.Activation.Type + 40, // 86: signalservice.DataMessage.Quote.QuotedAttachment.thumbnail:type_name -> signalservice.AttachmentPointer + 8, // 87: signalservice.DataMessage.Contact.Phone.type:type_name -> signalservice.DataMessage.Contact.Phone.Type + 9, // 88: signalservice.DataMessage.Contact.Email.type:type_name -> signalservice.DataMessage.Contact.Email.Type + 10, // 89: signalservice.DataMessage.Contact.PostalAddress.type:type_name -> signalservice.DataMessage.Contact.PostalAddress.Type + 40, // 90: signalservice.DataMessage.Contact.Avatar.avatar:type_name -> signalservice.AttachmentPointer + 31, // 91: signalservice.SyncMessage.Sent.message:type_name -> signalservice.DataMessage + 102, // 92: signalservice.SyncMessage.Sent.unidentifiedStatus:type_name -> signalservice.SyncMessage.Sent.UnidentifiedDeliveryStatus + 35, // 93: signalservice.SyncMessage.Sent.storyMessage:type_name -> signalservice.StoryMessage + 103, // 94: signalservice.SyncMessage.Sent.storyMessageRecipients:type_name -> signalservice.SyncMessage.Sent.StoryMessageRecipient + 46, // 95: signalservice.SyncMessage.Sent.editMessage:type_name -> signalservice.EditMessage + 40, // 96: signalservice.SyncMessage.Contacts.blob:type_name -> signalservice.AttachmentPointer + 15, // 97: signalservice.SyncMessage.Request.type:type_name -> signalservice.SyncMessage.Request.Type + 16, // 98: signalservice.SyncMessage.StickerPackOperation.type:type_name -> signalservice.SyncMessage.StickerPackOperation.Type + 17, // 99: signalservice.SyncMessage.FetchLatest.type:type_name -> signalservice.SyncMessage.FetchLatest.Type + 18, // 100: signalservice.SyncMessage.MessageRequestResponse.type:type_name -> signalservice.SyncMessage.MessageRequestResponse.Type + 104, // 101: signalservice.SyncMessage.OutgoingPayment.mobileCoin:type_name -> signalservice.SyncMessage.OutgoingPayment.MobileCoin + 19, // 102: signalservice.SyncMessage.CallEvent.type:type_name -> signalservice.SyncMessage.CallEvent.Type + 20, // 103: signalservice.SyncMessage.CallEvent.direction:type_name -> signalservice.SyncMessage.CallEvent.Direction + 21, // 104: signalservice.SyncMessage.CallEvent.event:type_name -> signalservice.SyncMessage.CallEvent.Event + 22, // 105: signalservice.SyncMessage.CallLinkUpdate.type:type_name -> signalservice.SyncMessage.CallLinkUpdate.Type + 23, // 106: signalservice.SyncMessage.CallLogEvent.type:type_name -> signalservice.SyncMessage.CallLogEvent.Type + 105, // 107: signalservice.SyncMessage.DeleteForMe.messageDeletes:type_name -> signalservice.SyncMessage.DeleteForMe.MessageDeletes + 107, // 108: signalservice.SyncMessage.DeleteForMe.conversationDeletes:type_name -> signalservice.SyncMessage.DeleteForMe.ConversationDelete + 108, // 109: signalservice.SyncMessage.DeleteForMe.localOnlyConversationDeletes:type_name -> signalservice.SyncMessage.DeleteForMe.LocalOnlyConversationDelete + 106, // 110: signalservice.SyncMessage.DeleteForMe.attachmentDeletes:type_name -> signalservice.SyncMessage.DeleteForMe.AttachmentDelete + 48, // 111: signalservice.SyncMessage.AttachmentBackfillRequest.targetMessage:type_name -> signalservice.AddressableMessage + 49, // 112: signalservice.SyncMessage.AttachmentBackfillRequest.targetConversation:type_name -> signalservice.ConversationIdentifier + 48, // 113: signalservice.SyncMessage.AttachmentBackfillResponse.targetMessage:type_name -> signalservice.AddressableMessage + 49, // 114: signalservice.SyncMessage.AttachmentBackfillResponse.targetConversation:type_name -> signalservice.ConversationIdentifier + 110, // 115: signalservice.SyncMessage.AttachmentBackfillResponse.attachments:type_name -> signalservice.SyncMessage.AttachmentBackfillResponse.AttachmentDataList + 24, // 116: signalservice.SyncMessage.AttachmentBackfillResponse.error:type_name -> signalservice.SyncMessage.AttachmentBackfillResponse.Error + 49, // 117: signalservice.SyncMessage.DeleteForMe.MessageDeletes.conversation:type_name -> signalservice.ConversationIdentifier + 48, // 118: signalservice.SyncMessage.DeleteForMe.MessageDeletes.messages:type_name -> signalservice.AddressableMessage + 49, // 119: signalservice.SyncMessage.DeleteForMe.AttachmentDelete.conversation:type_name -> signalservice.ConversationIdentifier + 48, // 120: signalservice.SyncMessage.DeleteForMe.AttachmentDelete.targetMessage:type_name -> signalservice.AddressableMessage + 49, // 121: signalservice.SyncMessage.DeleteForMe.ConversationDelete.conversation:type_name -> signalservice.ConversationIdentifier + 48, // 122: signalservice.SyncMessage.DeleteForMe.ConversationDelete.mostRecentMessages:type_name -> signalservice.AddressableMessage + 48, // 123: signalservice.SyncMessage.DeleteForMe.ConversationDelete.mostRecentNonExpiringMessages:type_name -> signalservice.AddressableMessage + 49, // 124: signalservice.SyncMessage.DeleteForMe.LocalOnlyConversationDelete.conversation:type_name -> signalservice.ConversationIdentifier + 40, // 125: signalservice.SyncMessage.AttachmentBackfillResponse.AttachmentData.attachment:type_name -> signalservice.AttachmentPointer + 25, // 126: signalservice.SyncMessage.AttachmentBackfillResponse.AttachmentData.status:type_name -> signalservice.SyncMessage.AttachmentBackfillResponse.AttachmentData.Status + 109, // 127: signalservice.SyncMessage.AttachmentBackfillResponse.AttachmentDataList.attachments:type_name -> signalservice.SyncMessage.AttachmentBackfillResponse.AttachmentData + 109, // 128: signalservice.SyncMessage.AttachmentBackfillResponse.AttachmentDataList.longText:type_name -> signalservice.SyncMessage.AttachmentBackfillResponse.AttachmentData + 129, // [129:129] is the sub-list for method output_type + 129, // [129:129] is the sub-list for method input_type + 129, // [129:129] is the sub-list for extension type_name + 129, // [129:129] is the sub-list for extension extendee + 0, // [0:129] is the sub-list for field type_name } func init() { file_SignalService_proto_init() } @@ -8718,20 +8945,20 @@ func file_SignalService_proto_init() { (*DataMessage_Payment_Notification_)(nil), (*DataMessage_Payment_Activation_)(nil), } - file_SignalService_proto_msgTypes[37].OneofWrappers = []any{ + file_SignalService_proto_msgTypes[40].OneofWrappers = []any{ (*DataMessage_Payment_Amount_MobileCoin_)(nil), } - file_SignalService_proto_msgTypes[38].OneofWrappers = []any{ + file_SignalService_proto_msgTypes[41].OneofWrappers = []any{ (*DataMessage_Payment_Notification_MobileCoin_)(nil), } - file_SignalService_proto_msgTypes[62].OneofWrappers = []any{ + file_SignalService_proto_msgTypes[65].OneofWrappers = []any{ (*SyncMessage_OutgoingPayment_MobileCoin_)(nil), } - file_SignalService_proto_msgTypes[70].OneofWrappers = []any{ + file_SignalService_proto_msgTypes[73].OneofWrappers = []any{ (*SyncMessage_AttachmentBackfillResponse_Attachments)(nil), (*SyncMessage_AttachmentBackfillResponse_Error_)(nil), } - file_SignalService_proto_msgTypes[78].OneofWrappers = []any{ + file_SignalService_proto_msgTypes[81].OneofWrappers = []any{ (*SyncMessage_AttachmentBackfillResponse_AttachmentData_Attachment)(nil), (*SyncMessage_AttachmentBackfillResponse_AttachmentData_Status_)(nil), } @@ -8741,7 +8968,7 @@ func file_SignalService_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: unsafe.Slice(unsafe.StringData(file_SignalService_proto_rawDesc), len(file_SignalService_proto_rawDesc)), NumEnums: 28, - NumMessages: 82, + NumMessages: 85, NumExtensions: 0, NumServices: 0, }, diff --git a/pkg/signalmeow/protobuf/SignalService.proto b/pkg/signalmeow/protobuf/SignalService.proto index a1fa8f9..249c4eb 100644 --- a/pkg/signalmeow/protobuf/SignalService.proto +++ b/pkg/signalmeow/protobuf/SignalService.proto @@ -177,6 +177,7 @@ message DataMessage { enum Type { NORMAL = 0; GIFT_BADGE = 1; + POLL = 2; } message QuotedAttachment { @@ -302,6 +303,7 @@ message DataMessage { CDN_SELECTOR_ATTACHMENTS = 5; MENTIONS = 6; PAYMENTS = 7; + POLLS = 8; CURRENT = 7; } @@ -309,6 +311,23 @@ message DataMessage { optional bytes receiptCredentialPresentation = 1; } + message PollCreate { + optional string question = 1; + optional bool allowMultiple = 2; + repeated string options = 3; + } + + message PollTerminate { + optional uint64 targetSentTimestamp = 1; + } + + message PollVote { + optional bytes targetAuthorAciBinary = 1; + optional uint64 targetSentTimestamp = 2; + repeated uint32 optionIndexes = 3; // must be in the range [0, options.length) from the PollCreate + optional uint32 voteCount = 4; // increment this by 1 each time you vote on a given poll + } + optional string body = 1; repeated AttachmentPointer attachments = 2; reserved /*groupV1*/ 3; @@ -331,7 +350,10 @@ message DataMessage { optional Payment payment = 20; optional StoryContext storyContext = 21; optional GiftBadge giftBadge = 22; - // NEXT ID: 24 + optional PollCreate pollCreate = 24; + optional PollTerminate pollTerminate = 25; + optional PollVote pollVote = 26; + // NEXT ID: 27 } message NullMessage { diff --git a/pkg/signalmeow/protobuf/StickerResources.pb.go b/pkg/signalmeow/protobuf/StickerResources.pb.go index b1969bc..52905c6 100644 --- a/pkg/signalmeow/protobuf/StickerResources.pb.go +++ b/pkg/signalmeow/protobuf/StickerResources.pb.go @@ -5,7 +5,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.36.6 +// protoc-gen-go v1.36.10 // protoc v3.21.12 // source: StickerResources.proto diff --git a/pkg/signalmeow/protobuf/StorageService.pb.go b/pkg/signalmeow/protobuf/StorageService.pb.go index 33804f6..1294a3f 100644 --- a/pkg/signalmeow/protobuf/StorageService.pb.go +++ b/pkg/signalmeow/protobuf/StorageService.pb.go @@ -5,7 +5,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.36.6 +// protoc-gen-go v1.36.10 // protoc v3.21.12 // source: StorageService.proto diff --git a/pkg/signalmeow/protobuf/UnidentifiedDelivery.pb.go b/pkg/signalmeow/protobuf/UnidentifiedDelivery.pb.go index bb5b256..d512960 100644 --- a/pkg/signalmeow/protobuf/UnidentifiedDelivery.pb.go +++ b/pkg/signalmeow/protobuf/UnidentifiedDelivery.pb.go @@ -1,6 +1,6 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.36.6 +// protoc-gen-go v1.36.10 // protoc v3.21.12 // source: UnidentifiedDelivery.proto diff --git a/pkg/signalmeow/protobuf/WebSocketResources.pb.go b/pkg/signalmeow/protobuf/WebSocketResources.pb.go index ff48cda..ef45ba0 100644 --- a/pkg/signalmeow/protobuf/WebSocketResources.pb.go +++ b/pkg/signalmeow/protobuf/WebSocketResources.pb.go @@ -5,7 +5,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.36.6 +// protoc-gen-go v1.36.10 // protoc v3.21.12 // source: WebSocketResources.proto diff --git a/pkg/signalmeow/protobuf/backuppb/Backup.pb.go b/pkg/signalmeow/protobuf/backuppb/Backup.pb.go index 3eaaed0..86e176a 100644 --- a/pkg/signalmeow/protobuf/backuppb/Backup.pb.go +++ b/pkg/signalmeow/protobuf/backuppb/Backup.pb.go @@ -1,6 +1,6 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.36.6 +// protoc-gen-go v1.36.10 // protoc v3.21.12 // source: backuppb/Backup.proto @@ -1098,6 +1098,7 @@ const ( Quote_NORMAL Quote_Type = 1 Quote_GIFT_BADGE Quote_Type = 2 Quote_VIEW_ONCE Quote_Type = 3 + Quote_POLL Quote_Type = 4 ) // Enum value maps for Quote_Type. @@ -1107,12 +1108,14 @@ var ( 1: "NORMAL", 2: "GIFT_BADGE", 3: "VIEW_ONCE", + 4: "POLL", } Quote_Type_value = map[string]int32{ "UNKNOWN": 0, "NORMAL": 1, "GIFT_BADGE": 2, "VIEW_ONCE": 3, + "POLL": 4, } ) @@ -1247,7 +1250,7 @@ func (x IndividualCall_Type) Number() protoreflect.EnumNumber { // Deprecated: Use IndividualCall_Type.Descriptor instead. func (IndividualCall_Type) EnumDescriptor() ([]byte, []int) { - return file_backuppb_Backup_proto_rawDescGZIP(), []int{33, 0} + return file_backuppb_Backup_proto_rawDescGZIP(), []int{34, 0} } type IndividualCall_Direction int32 @@ -1296,7 +1299,7 @@ func (x IndividualCall_Direction) Number() protoreflect.EnumNumber { // Deprecated: Use IndividualCall_Direction.Descriptor instead. func (IndividualCall_Direction) EnumDescriptor() ([]byte, []int) { - return file_backuppb_Backup_proto_rawDescGZIP(), []int{33, 1} + return file_backuppb_Backup_proto_rawDescGZIP(), []int{34, 1} } type IndividualCall_State int32 @@ -1355,7 +1358,7 @@ func (x IndividualCall_State) Number() protoreflect.EnumNumber { // Deprecated: Use IndividualCall_State.Descriptor instead. func (IndividualCall_State) EnumDescriptor() ([]byte, []int) { - return file_backuppb_Backup_proto_rawDescGZIP(), []int{33, 2} + return file_backuppb_Backup_proto_rawDescGZIP(), []int{34, 2} } type GroupCall_State int32 @@ -1431,7 +1434,7 @@ func (x GroupCall_State) Number() protoreflect.EnumNumber { // Deprecated: Use GroupCall_State.Descriptor instead. func (GroupCall_State) EnumDescriptor() ([]byte, []int) { - return file_backuppb_Backup_proto_rawDescGZIP(), []int{34, 0} + return file_backuppb_Backup_proto_rawDescGZIP(), []int{35, 0} } type SimpleChatUpdate_Type int32 @@ -1522,7 +1525,7 @@ func (x SimpleChatUpdate_Type) Number() protoreflect.EnumNumber { // Deprecated: Use SimpleChatUpdate_Type.Descriptor instead. func (SimpleChatUpdate_Type) EnumDescriptor() ([]byte, []int) { - return file_backuppb_Backup_proto_rawDescGZIP(), []int{35, 0} + return file_backuppb_Backup_proto_rawDescGZIP(), []int{36, 0} } type ChatStyle_WallpaperPreset int32 @@ -1628,7 +1631,7 @@ func (x ChatStyle_WallpaperPreset) Number() protoreflect.EnumNumber { // Deprecated: Use ChatStyle_WallpaperPreset.Descriptor instead. func (ChatStyle_WallpaperPreset) EnumDescriptor() ([]byte, []int) { - return file_backuppb_Backup_proto_rawDescGZIP(), []int{77, 0} + return file_backuppb_Backup_proto_rawDescGZIP(), []int{79, 0} } type ChatStyle_BubbleColorPreset int32 @@ -1737,7 +1740,7 @@ func (x ChatStyle_BubbleColorPreset) Number() protoreflect.EnumNumber { // Deprecated: Use ChatStyle_BubbleColorPreset.Descriptor instead. func (ChatStyle_BubbleColorPreset) EnumDescriptor() ([]byte, []int) { - return file_backuppb_Backup_proto_rawDescGZIP(), []int{77, 1} + return file_backuppb_Backup_proto_rawDescGZIP(), []int{79, 1} } type NotificationProfile_DayOfWeek int32 @@ -1801,7 +1804,7 @@ func (x NotificationProfile_DayOfWeek) Number() protoreflect.EnumNumber { // Deprecated: Use NotificationProfile_DayOfWeek.Descriptor instead. func (NotificationProfile_DayOfWeek) EnumDescriptor() ([]byte, []int) { - return file_backuppb_Backup_proto_rawDescGZIP(), []int{78, 0} + return file_backuppb_Backup_proto_rawDescGZIP(), []int{80, 0} } // Represents the default "All chats" folder record vs all other custom folders @@ -1851,7 +1854,7 @@ func (x ChatFolder_FolderType) Number() protoreflect.EnumNumber { // Deprecated: Use ChatFolder_FolderType.Descriptor instead. func (ChatFolder_FolderType) EnumDescriptor() ([]byte, []int) { - return file_backuppb_Backup_proto_rawDescGZIP(), []int{79, 0} + return file_backuppb_Backup_proto_rawDescGZIP(), []int{81, 0} } type BackupInfo struct { @@ -3282,6 +3285,7 @@ type ChatItem struct { // *ChatItem_GiftBadge // *ChatItem_ViewOnceMessage // *ChatItem_DirectStoryReplyMessage + // *ChatItem_Poll Item isChatItem_Item `protobuf_oneof:"item"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache @@ -3488,6 +3492,15 @@ func (x *ChatItem) GetDirectStoryReplyMessage() *DirectStoryReplyMessage { return nil } +func (x *ChatItem) GetPoll() *Poll { + if x != nil { + if x, ok := x.Item.(*ChatItem_Poll); ok { + return x.Poll + } + } + return nil +} + type isChatItem_DirectionalDetails interface { isChatItem_DirectionalDetails() } @@ -3550,6 +3563,10 @@ type ChatItem_DirectStoryReplyMessage struct { DirectStoryReplyMessage *DirectStoryReplyMessage `protobuf:"bytes,19,opt,name=directStoryReplyMessage,proto3,oneof"` // group story reply messages are not backed up } +type ChatItem_Poll struct { + Poll *Poll `protobuf:"bytes,20,opt,name=poll,proto3,oneof"` +} + func (*ChatItem_StandardMessage) isChatItem_Item() {} func (*ChatItem_ContactMessage) isChatItem_Item() {} @@ -3568,6 +3585,8 @@ func (*ChatItem_ViewOnceMessage) isChatItem_Item() {} func (*ChatItem_DirectStoryReplyMessage) isChatItem_Item() {} +func (*ChatItem_Poll) isChatItem_Item() {} + type SendStatus struct { state protoimpl.MessageState `protogen:"open.v1"` RecipientId uint64 `protobuf:"varint,1,opt,name=recipientId,proto3" json:"recipientId,omitempty"` @@ -4958,6 +4977,74 @@ func (x *Reaction) GetSortOrder() uint64 { return 0 } +type Poll struct { + state protoimpl.MessageState `protogen:"open.v1"` + Question string `protobuf:"bytes,1,opt,name=question,proto3" json:"question,omitempty"` // Between 1-100 characters + AllowMultiple bool `protobuf:"varint,2,opt,name=allowMultiple,proto3" json:"allowMultiple,omitempty"` + Options []*Poll_PollOption `protobuf:"bytes,3,rep,name=options,proto3" json:"options,omitempty"` // At least two + HasEnded bool `protobuf:"varint,4,opt,name=hasEnded,proto3" json:"hasEnded,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *Poll) Reset() { + *x = Poll{} + mi := &file_backuppb_Backup_proto_msgTypes[32] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *Poll) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Poll) ProtoMessage() {} + +func (x *Poll) ProtoReflect() protoreflect.Message { + mi := &file_backuppb_Backup_proto_msgTypes[32] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Poll.ProtoReflect.Descriptor instead. +func (*Poll) Descriptor() ([]byte, []int) { + return file_backuppb_Backup_proto_rawDescGZIP(), []int{32} +} + +func (x *Poll) GetQuestion() string { + if x != nil { + return x.Question + } + return "" +} + +func (x *Poll) GetAllowMultiple() bool { + if x != nil { + return x.AllowMultiple + } + return false +} + +func (x *Poll) GetOptions() []*Poll_PollOption { + if x != nil { + return x.Options + } + return nil +} + +func (x *Poll) GetHasEnded() bool { + if x != nil { + return x.HasEnded + } + return false +} + type ChatUpdateMessage struct { state protoimpl.MessageState `protogen:"open.v1"` // If unset, importers should ignore the update message without throwing an error. @@ -4973,6 +5060,7 @@ type ChatUpdateMessage struct { // *ChatUpdateMessage_IndividualCall // *ChatUpdateMessage_GroupCall // *ChatUpdateMessage_LearnedProfileChange + // *ChatUpdateMessage_PollTerminate Update isChatUpdateMessage_Update `protobuf_oneof:"update"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache @@ -4980,7 +5068,7 @@ type ChatUpdateMessage struct { func (x *ChatUpdateMessage) Reset() { *x = ChatUpdateMessage{} - mi := &file_backuppb_Backup_proto_msgTypes[32] + mi := &file_backuppb_Backup_proto_msgTypes[33] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4992,7 +5080,7 @@ func (x *ChatUpdateMessage) String() string { func (*ChatUpdateMessage) ProtoMessage() {} func (x *ChatUpdateMessage) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[32] + mi := &file_backuppb_Backup_proto_msgTypes[33] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5005,7 +5093,7 @@ func (x *ChatUpdateMessage) ProtoReflect() protoreflect.Message { // Deprecated: Use ChatUpdateMessage.ProtoReflect.Descriptor instead. func (*ChatUpdateMessage) Descriptor() ([]byte, []int) { - return file_backuppb_Backup_proto_rawDescGZIP(), []int{32} + return file_backuppb_Backup_proto_rawDescGZIP(), []int{33} } func (x *ChatUpdateMessage) GetUpdate() isChatUpdateMessage_Update { @@ -5096,6 +5184,15 @@ func (x *ChatUpdateMessage) GetLearnedProfileChange() *LearnedProfileChatUpdate return nil } +func (x *ChatUpdateMessage) GetPollTerminate() *PollTerminateUpdate { + if x != nil { + if x, ok := x.Update.(*ChatUpdateMessage_PollTerminate); ok { + return x.PollTerminate + } + } + return nil +} + type isChatUpdateMessage_Update interface { isChatUpdateMessage_Update() } @@ -5136,6 +5233,10 @@ type ChatUpdateMessage_LearnedProfileChange struct { LearnedProfileChange *LearnedProfileChatUpdate `protobuf:"bytes,9,opt,name=learnedProfileChange,proto3,oneof"` } +type ChatUpdateMessage_PollTerminate struct { + PollTerminate *PollTerminateUpdate `protobuf:"bytes,10,opt,name=pollTerminate,proto3,oneof"` +} + func (*ChatUpdateMessage_SimpleUpdate) isChatUpdateMessage_Update() {} func (*ChatUpdateMessage_GroupChange) isChatUpdateMessage_Update() {} @@ -5154,6 +5255,8 @@ func (*ChatUpdateMessage_GroupCall) isChatUpdateMessage_Update() {} func (*ChatUpdateMessage_LearnedProfileChange) isChatUpdateMessage_Update() {} +func (*ChatUpdateMessage_PollTerminate) isChatUpdateMessage_Update() {} + type IndividualCall struct { state protoimpl.MessageState `protogen:"open.v1"` CallId *uint64 `protobuf:"varint,1,opt,name=callId,proto3,oneof" json:"callId,omitempty"` @@ -5168,7 +5271,7 @@ type IndividualCall struct { func (x *IndividualCall) Reset() { *x = IndividualCall{} - mi := &file_backuppb_Backup_proto_msgTypes[33] + mi := &file_backuppb_Backup_proto_msgTypes[34] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5180,7 +5283,7 @@ func (x *IndividualCall) String() string { func (*IndividualCall) ProtoMessage() {} func (x *IndividualCall) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[33] + mi := &file_backuppb_Backup_proto_msgTypes[34] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5193,7 +5296,7 @@ func (x *IndividualCall) ProtoReflect() protoreflect.Message { // Deprecated: Use IndividualCall.ProtoReflect.Descriptor instead. func (*IndividualCall) Descriptor() ([]byte, []int) { - return file_backuppb_Backup_proto_rawDescGZIP(), []int{33} + return file_backuppb_Backup_proto_rawDescGZIP(), []int{34} } func (x *IndividualCall) GetCallId() uint64 { @@ -5253,7 +5356,7 @@ type GroupCall struct { func (x *GroupCall) Reset() { *x = GroupCall{} - mi := &file_backuppb_Backup_proto_msgTypes[34] + mi := &file_backuppb_Backup_proto_msgTypes[35] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5265,7 +5368,7 @@ func (x *GroupCall) String() string { func (*GroupCall) ProtoMessage() {} func (x *GroupCall) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[34] + mi := &file_backuppb_Backup_proto_msgTypes[35] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5278,7 +5381,7 @@ func (x *GroupCall) ProtoReflect() protoreflect.Message { // Deprecated: Use GroupCall.ProtoReflect.Descriptor instead. func (*GroupCall) Descriptor() ([]byte, []int) { - return file_backuppb_Backup_proto_rawDescGZIP(), []int{34} + return file_backuppb_Backup_proto_rawDescGZIP(), []int{35} } func (x *GroupCall) GetCallId() uint64 { @@ -5339,7 +5442,7 @@ type SimpleChatUpdate struct { func (x *SimpleChatUpdate) Reset() { *x = SimpleChatUpdate{} - mi := &file_backuppb_Backup_proto_msgTypes[35] + mi := &file_backuppb_Backup_proto_msgTypes[36] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5351,7 +5454,7 @@ func (x *SimpleChatUpdate) String() string { func (*SimpleChatUpdate) ProtoMessage() {} func (x *SimpleChatUpdate) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[35] + mi := &file_backuppb_Backup_proto_msgTypes[36] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5364,7 +5467,7 @@ func (x *SimpleChatUpdate) ProtoReflect() protoreflect.Message { // Deprecated: Use SimpleChatUpdate.ProtoReflect.Descriptor instead. func (*SimpleChatUpdate) Descriptor() ([]byte, []int) { - return file_backuppb_Backup_proto_rawDescGZIP(), []int{35} + return file_backuppb_Backup_proto_rawDescGZIP(), []int{36} } func (x *SimpleChatUpdate) GetType() SimpleChatUpdate_Type { @@ -5385,7 +5488,7 @@ type ExpirationTimerChatUpdate struct { func (x *ExpirationTimerChatUpdate) Reset() { *x = ExpirationTimerChatUpdate{} - mi := &file_backuppb_Backup_proto_msgTypes[36] + mi := &file_backuppb_Backup_proto_msgTypes[37] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5397,7 +5500,7 @@ func (x *ExpirationTimerChatUpdate) String() string { func (*ExpirationTimerChatUpdate) ProtoMessage() {} func (x *ExpirationTimerChatUpdate) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[36] + mi := &file_backuppb_Backup_proto_msgTypes[37] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5410,7 +5513,7 @@ func (x *ExpirationTimerChatUpdate) ProtoReflect() protoreflect.Message { // Deprecated: Use ExpirationTimerChatUpdate.ProtoReflect.Descriptor instead. func (*ExpirationTimerChatUpdate) Descriptor() ([]byte, []int) { - return file_backuppb_Backup_proto_rawDescGZIP(), []int{36} + return file_backuppb_Backup_proto_rawDescGZIP(), []int{37} } func (x *ExpirationTimerChatUpdate) GetExpiresInMs() uint64 { @@ -5430,7 +5533,7 @@ type ProfileChangeChatUpdate struct { func (x *ProfileChangeChatUpdate) Reset() { *x = ProfileChangeChatUpdate{} - mi := &file_backuppb_Backup_proto_msgTypes[37] + mi := &file_backuppb_Backup_proto_msgTypes[38] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5442,7 +5545,7 @@ func (x *ProfileChangeChatUpdate) String() string { func (*ProfileChangeChatUpdate) ProtoMessage() {} func (x *ProfileChangeChatUpdate) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[37] + mi := &file_backuppb_Backup_proto_msgTypes[38] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5455,7 +5558,7 @@ func (x *ProfileChangeChatUpdate) ProtoReflect() protoreflect.Message { // Deprecated: Use ProfileChangeChatUpdate.ProtoReflect.Descriptor instead. func (*ProfileChangeChatUpdate) Descriptor() ([]byte, []int) { - return file_backuppb_Backup_proto_rawDescGZIP(), []int{37} + return file_backuppb_Backup_proto_rawDescGZIP(), []int{38} } func (x *ProfileChangeChatUpdate) GetPreviousName() string { @@ -5487,7 +5590,7 @@ type LearnedProfileChatUpdate struct { func (x *LearnedProfileChatUpdate) Reset() { *x = LearnedProfileChatUpdate{} - mi := &file_backuppb_Backup_proto_msgTypes[38] + mi := &file_backuppb_Backup_proto_msgTypes[39] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5499,7 +5602,7 @@ func (x *LearnedProfileChatUpdate) String() string { func (*LearnedProfileChatUpdate) ProtoMessage() {} func (x *LearnedProfileChatUpdate) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[38] + mi := &file_backuppb_Backup_proto_msgTypes[39] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5512,7 +5615,7 @@ func (x *LearnedProfileChatUpdate) ProtoReflect() protoreflect.Message { // Deprecated: Use LearnedProfileChatUpdate.ProtoReflect.Descriptor instead. func (*LearnedProfileChatUpdate) Descriptor() ([]byte, []int) { - return file_backuppb_Backup_proto_rawDescGZIP(), []int{38} + return file_backuppb_Backup_proto_rawDescGZIP(), []int{39} } func (x *LearnedProfileChatUpdate) GetPreviousName() isLearnedProfileChatUpdate_PreviousName { @@ -5565,7 +5668,7 @@ type ThreadMergeChatUpdate struct { func (x *ThreadMergeChatUpdate) Reset() { *x = ThreadMergeChatUpdate{} - mi := &file_backuppb_Backup_proto_msgTypes[39] + mi := &file_backuppb_Backup_proto_msgTypes[40] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5577,7 +5680,7 @@ func (x *ThreadMergeChatUpdate) String() string { func (*ThreadMergeChatUpdate) ProtoMessage() {} func (x *ThreadMergeChatUpdate) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[39] + mi := &file_backuppb_Backup_proto_msgTypes[40] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5590,7 +5693,7 @@ func (x *ThreadMergeChatUpdate) ProtoReflect() protoreflect.Message { // Deprecated: Use ThreadMergeChatUpdate.ProtoReflect.Descriptor instead. func (*ThreadMergeChatUpdate) Descriptor() ([]byte, []int) { - return file_backuppb_Backup_proto_rawDescGZIP(), []int{39} + return file_backuppb_Backup_proto_rawDescGZIP(), []int{40} } func (x *ThreadMergeChatUpdate) GetPreviousE164() uint64 { @@ -5609,7 +5712,7 @@ type SessionSwitchoverChatUpdate struct { func (x *SessionSwitchoverChatUpdate) Reset() { *x = SessionSwitchoverChatUpdate{} - mi := &file_backuppb_Backup_proto_msgTypes[40] + mi := &file_backuppb_Backup_proto_msgTypes[41] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5621,7 +5724,7 @@ func (x *SessionSwitchoverChatUpdate) String() string { func (*SessionSwitchoverChatUpdate) ProtoMessage() {} func (x *SessionSwitchoverChatUpdate) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[40] + mi := &file_backuppb_Backup_proto_msgTypes[41] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5634,7 +5737,7 @@ func (x *SessionSwitchoverChatUpdate) ProtoReflect() protoreflect.Message { // Deprecated: Use SessionSwitchoverChatUpdate.ProtoReflect.Descriptor instead. func (*SessionSwitchoverChatUpdate) Descriptor() ([]byte, []int) { - return file_backuppb_Backup_proto_rawDescGZIP(), []int{40} + return file_backuppb_Backup_proto_rawDescGZIP(), []int{41} } func (x *SessionSwitchoverChatUpdate) GetE164() uint64 { @@ -5655,7 +5758,7 @@ type GroupChangeChatUpdate struct { func (x *GroupChangeChatUpdate) Reset() { *x = GroupChangeChatUpdate{} - mi := &file_backuppb_Backup_proto_msgTypes[41] + mi := &file_backuppb_Backup_proto_msgTypes[42] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5667,7 +5770,7 @@ func (x *GroupChangeChatUpdate) String() string { func (*GroupChangeChatUpdate) ProtoMessage() {} func (x *GroupChangeChatUpdate) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[41] + mi := &file_backuppb_Backup_proto_msgTypes[42] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5680,7 +5783,7 @@ func (x *GroupChangeChatUpdate) ProtoReflect() protoreflect.Message { // Deprecated: Use GroupChangeChatUpdate.ProtoReflect.Descriptor instead. func (*GroupChangeChatUpdate) Descriptor() ([]byte, []int) { - return file_backuppb_Backup_proto_rawDescGZIP(), []int{41} + return file_backuppb_Backup_proto_rawDescGZIP(), []int{42} } func (x *GroupChangeChatUpdate) GetUpdates() []*GroupChangeChatUpdate_Update { @@ -5699,7 +5802,7 @@ type GenericGroupUpdate struct { func (x *GenericGroupUpdate) Reset() { *x = GenericGroupUpdate{} - mi := &file_backuppb_Backup_proto_msgTypes[42] + mi := &file_backuppb_Backup_proto_msgTypes[43] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5711,7 +5814,7 @@ func (x *GenericGroupUpdate) String() string { func (*GenericGroupUpdate) ProtoMessage() {} func (x *GenericGroupUpdate) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[42] + mi := &file_backuppb_Backup_proto_msgTypes[43] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5724,7 +5827,7 @@ func (x *GenericGroupUpdate) ProtoReflect() protoreflect.Message { // Deprecated: Use GenericGroupUpdate.ProtoReflect.Descriptor instead. func (*GenericGroupUpdate) Descriptor() ([]byte, []int) { - return file_backuppb_Backup_proto_rawDescGZIP(), []int{42} + return file_backuppb_Backup_proto_rawDescGZIP(), []int{43} } func (x *GenericGroupUpdate) GetUpdaterAci() []byte { @@ -5743,7 +5846,7 @@ type GroupCreationUpdate struct { func (x *GroupCreationUpdate) Reset() { *x = GroupCreationUpdate{} - mi := &file_backuppb_Backup_proto_msgTypes[43] + mi := &file_backuppb_Backup_proto_msgTypes[44] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5755,7 +5858,7 @@ func (x *GroupCreationUpdate) String() string { func (*GroupCreationUpdate) ProtoMessage() {} func (x *GroupCreationUpdate) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[43] + mi := &file_backuppb_Backup_proto_msgTypes[44] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5768,7 +5871,7 @@ func (x *GroupCreationUpdate) ProtoReflect() protoreflect.Message { // Deprecated: Use GroupCreationUpdate.ProtoReflect.Descriptor instead. func (*GroupCreationUpdate) Descriptor() ([]byte, []int) { - return file_backuppb_Backup_proto_rawDescGZIP(), []int{43} + return file_backuppb_Backup_proto_rawDescGZIP(), []int{44} } func (x *GroupCreationUpdate) GetUpdaterAci() []byte { @@ -5789,7 +5892,7 @@ type GroupNameUpdate struct { func (x *GroupNameUpdate) Reset() { *x = GroupNameUpdate{} - mi := &file_backuppb_Backup_proto_msgTypes[44] + mi := &file_backuppb_Backup_proto_msgTypes[45] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5801,7 +5904,7 @@ func (x *GroupNameUpdate) String() string { func (*GroupNameUpdate) ProtoMessage() {} func (x *GroupNameUpdate) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[44] + mi := &file_backuppb_Backup_proto_msgTypes[45] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5814,7 +5917,7 @@ func (x *GroupNameUpdate) ProtoReflect() protoreflect.Message { // Deprecated: Use GroupNameUpdate.ProtoReflect.Descriptor instead. func (*GroupNameUpdate) Descriptor() ([]byte, []int) { - return file_backuppb_Backup_proto_rawDescGZIP(), []int{44} + return file_backuppb_Backup_proto_rawDescGZIP(), []int{45} } func (x *GroupNameUpdate) GetUpdaterAci() []byte { @@ -5841,7 +5944,7 @@ type GroupAvatarUpdate struct { func (x *GroupAvatarUpdate) Reset() { *x = GroupAvatarUpdate{} - mi := &file_backuppb_Backup_proto_msgTypes[45] + mi := &file_backuppb_Backup_proto_msgTypes[46] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5853,7 +5956,7 @@ func (x *GroupAvatarUpdate) String() string { func (*GroupAvatarUpdate) ProtoMessage() {} func (x *GroupAvatarUpdate) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[45] + mi := &file_backuppb_Backup_proto_msgTypes[46] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5866,7 +5969,7 @@ func (x *GroupAvatarUpdate) ProtoReflect() protoreflect.Message { // Deprecated: Use GroupAvatarUpdate.ProtoReflect.Descriptor instead. func (*GroupAvatarUpdate) Descriptor() ([]byte, []int) { - return file_backuppb_Backup_proto_rawDescGZIP(), []int{45} + return file_backuppb_Backup_proto_rawDescGZIP(), []int{46} } func (x *GroupAvatarUpdate) GetUpdaterAci() []byte { @@ -5894,7 +5997,7 @@ type GroupDescriptionUpdate struct { func (x *GroupDescriptionUpdate) Reset() { *x = GroupDescriptionUpdate{} - mi := &file_backuppb_Backup_proto_msgTypes[46] + mi := &file_backuppb_Backup_proto_msgTypes[47] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5906,7 +6009,7 @@ func (x *GroupDescriptionUpdate) String() string { func (*GroupDescriptionUpdate) ProtoMessage() {} func (x *GroupDescriptionUpdate) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[46] + mi := &file_backuppb_Backup_proto_msgTypes[47] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5919,7 +6022,7 @@ func (x *GroupDescriptionUpdate) ProtoReflect() protoreflect.Message { // Deprecated: Use GroupDescriptionUpdate.ProtoReflect.Descriptor instead. func (*GroupDescriptionUpdate) Descriptor() ([]byte, []int) { - return file_backuppb_Backup_proto_rawDescGZIP(), []int{46} + return file_backuppb_Backup_proto_rawDescGZIP(), []int{47} } func (x *GroupDescriptionUpdate) GetUpdaterAci() []byte { @@ -5946,7 +6049,7 @@ type GroupMembershipAccessLevelChangeUpdate struct { func (x *GroupMembershipAccessLevelChangeUpdate) Reset() { *x = GroupMembershipAccessLevelChangeUpdate{} - mi := &file_backuppb_Backup_proto_msgTypes[47] + mi := &file_backuppb_Backup_proto_msgTypes[48] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5958,7 +6061,7 @@ func (x *GroupMembershipAccessLevelChangeUpdate) String() string { func (*GroupMembershipAccessLevelChangeUpdate) ProtoMessage() {} func (x *GroupMembershipAccessLevelChangeUpdate) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[47] + mi := &file_backuppb_Backup_proto_msgTypes[48] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5971,7 +6074,7 @@ func (x *GroupMembershipAccessLevelChangeUpdate) ProtoReflect() protoreflect.Mes // Deprecated: Use GroupMembershipAccessLevelChangeUpdate.ProtoReflect.Descriptor instead. func (*GroupMembershipAccessLevelChangeUpdate) Descriptor() ([]byte, []int) { - return file_backuppb_Backup_proto_rawDescGZIP(), []int{47} + return file_backuppb_Backup_proto_rawDescGZIP(), []int{48} } func (x *GroupMembershipAccessLevelChangeUpdate) GetUpdaterAci() []byte { @@ -5998,7 +6101,7 @@ type GroupAttributesAccessLevelChangeUpdate struct { func (x *GroupAttributesAccessLevelChangeUpdate) Reset() { *x = GroupAttributesAccessLevelChangeUpdate{} - mi := &file_backuppb_Backup_proto_msgTypes[48] + mi := &file_backuppb_Backup_proto_msgTypes[49] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6010,7 +6113,7 @@ func (x *GroupAttributesAccessLevelChangeUpdate) String() string { func (*GroupAttributesAccessLevelChangeUpdate) ProtoMessage() {} func (x *GroupAttributesAccessLevelChangeUpdate) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[48] + mi := &file_backuppb_Backup_proto_msgTypes[49] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6023,7 +6126,7 @@ func (x *GroupAttributesAccessLevelChangeUpdate) ProtoReflect() protoreflect.Mes // Deprecated: Use GroupAttributesAccessLevelChangeUpdate.ProtoReflect.Descriptor instead. func (*GroupAttributesAccessLevelChangeUpdate) Descriptor() ([]byte, []int) { - return file_backuppb_Backup_proto_rawDescGZIP(), []int{48} + return file_backuppb_Backup_proto_rawDescGZIP(), []int{49} } func (x *GroupAttributesAccessLevelChangeUpdate) GetUpdaterAci() []byte { @@ -6050,7 +6153,7 @@ type GroupAnnouncementOnlyChangeUpdate struct { func (x *GroupAnnouncementOnlyChangeUpdate) Reset() { *x = GroupAnnouncementOnlyChangeUpdate{} - mi := &file_backuppb_Backup_proto_msgTypes[49] + mi := &file_backuppb_Backup_proto_msgTypes[50] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6062,7 +6165,7 @@ func (x *GroupAnnouncementOnlyChangeUpdate) String() string { func (*GroupAnnouncementOnlyChangeUpdate) ProtoMessage() {} func (x *GroupAnnouncementOnlyChangeUpdate) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[49] + mi := &file_backuppb_Backup_proto_msgTypes[50] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6075,7 +6178,7 @@ func (x *GroupAnnouncementOnlyChangeUpdate) ProtoReflect() protoreflect.Message // Deprecated: Use GroupAnnouncementOnlyChangeUpdate.ProtoReflect.Descriptor instead. func (*GroupAnnouncementOnlyChangeUpdate) Descriptor() ([]byte, []int) { - return file_backuppb_Backup_proto_rawDescGZIP(), []int{49} + return file_backuppb_Backup_proto_rawDescGZIP(), []int{50} } func (x *GroupAnnouncementOnlyChangeUpdate) GetUpdaterAci() []byte { @@ -6104,7 +6207,7 @@ type GroupAdminStatusUpdate struct { func (x *GroupAdminStatusUpdate) Reset() { *x = GroupAdminStatusUpdate{} - mi := &file_backuppb_Backup_proto_msgTypes[50] + mi := &file_backuppb_Backup_proto_msgTypes[51] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6116,7 +6219,7 @@ func (x *GroupAdminStatusUpdate) String() string { func (*GroupAdminStatusUpdate) ProtoMessage() {} func (x *GroupAdminStatusUpdate) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[50] + mi := &file_backuppb_Backup_proto_msgTypes[51] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6129,7 +6232,7 @@ func (x *GroupAdminStatusUpdate) ProtoReflect() protoreflect.Message { // Deprecated: Use GroupAdminStatusUpdate.ProtoReflect.Descriptor instead. func (*GroupAdminStatusUpdate) Descriptor() ([]byte, []int) { - return file_backuppb_Backup_proto_rawDescGZIP(), []int{50} + return file_backuppb_Backup_proto_rawDescGZIP(), []int{51} } func (x *GroupAdminStatusUpdate) GetUpdaterAci() []byte { @@ -6162,7 +6265,7 @@ type GroupMemberLeftUpdate struct { func (x *GroupMemberLeftUpdate) Reset() { *x = GroupMemberLeftUpdate{} - mi := &file_backuppb_Backup_proto_msgTypes[51] + mi := &file_backuppb_Backup_proto_msgTypes[52] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6174,7 +6277,7 @@ func (x *GroupMemberLeftUpdate) String() string { func (*GroupMemberLeftUpdate) ProtoMessage() {} func (x *GroupMemberLeftUpdate) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[51] + mi := &file_backuppb_Backup_proto_msgTypes[52] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6187,7 +6290,7 @@ func (x *GroupMemberLeftUpdate) ProtoReflect() protoreflect.Message { // Deprecated: Use GroupMemberLeftUpdate.ProtoReflect.Descriptor instead. func (*GroupMemberLeftUpdate) Descriptor() ([]byte, []int) { - return file_backuppb_Backup_proto_rawDescGZIP(), []int{51} + return file_backuppb_Backup_proto_rawDescGZIP(), []int{52} } func (x *GroupMemberLeftUpdate) GetAci() []byte { @@ -6207,7 +6310,7 @@ type GroupMemberRemovedUpdate struct { func (x *GroupMemberRemovedUpdate) Reset() { *x = GroupMemberRemovedUpdate{} - mi := &file_backuppb_Backup_proto_msgTypes[52] + mi := &file_backuppb_Backup_proto_msgTypes[53] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6219,7 +6322,7 @@ func (x *GroupMemberRemovedUpdate) String() string { func (*GroupMemberRemovedUpdate) ProtoMessage() {} func (x *GroupMemberRemovedUpdate) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[52] + mi := &file_backuppb_Backup_proto_msgTypes[53] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6232,7 +6335,7 @@ func (x *GroupMemberRemovedUpdate) ProtoReflect() protoreflect.Message { // Deprecated: Use GroupMemberRemovedUpdate.ProtoReflect.Descriptor instead. func (*GroupMemberRemovedUpdate) Descriptor() ([]byte, []int) { - return file_backuppb_Backup_proto_rawDescGZIP(), []int{52} + return file_backuppb_Backup_proto_rawDescGZIP(), []int{53} } func (x *GroupMemberRemovedUpdate) GetRemoverAci() []byte { @@ -6258,7 +6361,7 @@ type SelfInvitedToGroupUpdate struct { func (x *SelfInvitedToGroupUpdate) Reset() { *x = SelfInvitedToGroupUpdate{} - mi := &file_backuppb_Backup_proto_msgTypes[53] + mi := &file_backuppb_Backup_proto_msgTypes[54] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6270,7 +6373,7 @@ func (x *SelfInvitedToGroupUpdate) String() string { func (*SelfInvitedToGroupUpdate) ProtoMessage() {} func (x *SelfInvitedToGroupUpdate) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[53] + mi := &file_backuppb_Backup_proto_msgTypes[54] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6283,7 +6386,7 @@ func (x *SelfInvitedToGroupUpdate) ProtoReflect() protoreflect.Message { // Deprecated: Use SelfInvitedToGroupUpdate.ProtoReflect.Descriptor instead. func (*SelfInvitedToGroupUpdate) Descriptor() ([]byte, []int) { - return file_backuppb_Backup_proto_rawDescGZIP(), []int{53} + return file_backuppb_Backup_proto_rawDescGZIP(), []int{54} } func (x *SelfInvitedToGroupUpdate) GetInviterAci() []byte { @@ -6303,7 +6406,7 @@ type SelfInvitedOtherUserToGroupUpdate struct { func (x *SelfInvitedOtherUserToGroupUpdate) Reset() { *x = SelfInvitedOtherUserToGroupUpdate{} - mi := &file_backuppb_Backup_proto_msgTypes[54] + mi := &file_backuppb_Backup_proto_msgTypes[55] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6315,7 +6418,7 @@ func (x *SelfInvitedOtherUserToGroupUpdate) String() string { func (*SelfInvitedOtherUserToGroupUpdate) ProtoMessage() {} func (x *SelfInvitedOtherUserToGroupUpdate) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[54] + mi := &file_backuppb_Backup_proto_msgTypes[55] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6328,7 +6431,7 @@ func (x *SelfInvitedOtherUserToGroupUpdate) ProtoReflect() protoreflect.Message // Deprecated: Use SelfInvitedOtherUserToGroupUpdate.ProtoReflect.Descriptor instead. func (*SelfInvitedOtherUserToGroupUpdate) Descriptor() ([]byte, []int) { - return file_backuppb_Backup_proto_rawDescGZIP(), []int{54} + return file_backuppb_Backup_proto_rawDescGZIP(), []int{55} } func (x *SelfInvitedOtherUserToGroupUpdate) GetInviteeServiceId() []byte { @@ -6349,7 +6452,7 @@ type GroupUnknownInviteeUpdate struct { func (x *GroupUnknownInviteeUpdate) Reset() { *x = GroupUnknownInviteeUpdate{} - mi := &file_backuppb_Backup_proto_msgTypes[55] + mi := &file_backuppb_Backup_proto_msgTypes[56] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6361,7 +6464,7 @@ func (x *GroupUnknownInviteeUpdate) String() string { func (*GroupUnknownInviteeUpdate) ProtoMessage() {} func (x *GroupUnknownInviteeUpdate) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[55] + mi := &file_backuppb_Backup_proto_msgTypes[56] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6374,7 +6477,7 @@ func (x *GroupUnknownInviteeUpdate) ProtoReflect() protoreflect.Message { // Deprecated: Use GroupUnknownInviteeUpdate.ProtoReflect.Descriptor instead. func (*GroupUnknownInviteeUpdate) Descriptor() ([]byte, []int) { - return file_backuppb_Backup_proto_rawDescGZIP(), []int{55} + return file_backuppb_Backup_proto_rawDescGZIP(), []int{56} } func (x *GroupUnknownInviteeUpdate) GetInviterAci() []byte { @@ -6401,7 +6504,7 @@ type GroupInvitationAcceptedUpdate struct { func (x *GroupInvitationAcceptedUpdate) Reset() { *x = GroupInvitationAcceptedUpdate{} - mi := &file_backuppb_Backup_proto_msgTypes[56] + mi := &file_backuppb_Backup_proto_msgTypes[57] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6413,7 +6516,7 @@ func (x *GroupInvitationAcceptedUpdate) String() string { func (*GroupInvitationAcceptedUpdate) ProtoMessage() {} func (x *GroupInvitationAcceptedUpdate) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[56] + mi := &file_backuppb_Backup_proto_msgTypes[57] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6426,7 +6529,7 @@ func (x *GroupInvitationAcceptedUpdate) ProtoReflect() protoreflect.Message { // Deprecated: Use GroupInvitationAcceptedUpdate.ProtoReflect.Descriptor instead. func (*GroupInvitationAcceptedUpdate) Descriptor() ([]byte, []int) { - return file_backuppb_Backup_proto_rawDescGZIP(), []int{56} + return file_backuppb_Backup_proto_rawDescGZIP(), []int{57} } func (x *GroupInvitationAcceptedUpdate) GetInviterAci() []byte { @@ -6454,7 +6557,7 @@ type GroupInvitationDeclinedUpdate struct { func (x *GroupInvitationDeclinedUpdate) Reset() { *x = GroupInvitationDeclinedUpdate{} - mi := &file_backuppb_Backup_proto_msgTypes[57] + mi := &file_backuppb_Backup_proto_msgTypes[58] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6466,7 +6569,7 @@ func (x *GroupInvitationDeclinedUpdate) String() string { func (*GroupInvitationDeclinedUpdate) ProtoMessage() {} func (x *GroupInvitationDeclinedUpdate) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[57] + mi := &file_backuppb_Backup_proto_msgTypes[58] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6479,7 +6582,7 @@ func (x *GroupInvitationDeclinedUpdate) ProtoReflect() protoreflect.Message { // Deprecated: Use GroupInvitationDeclinedUpdate.ProtoReflect.Descriptor instead. func (*GroupInvitationDeclinedUpdate) Descriptor() ([]byte, []int) { - return file_backuppb_Backup_proto_rawDescGZIP(), []int{57} + return file_backuppb_Backup_proto_rawDescGZIP(), []int{58} } func (x *GroupInvitationDeclinedUpdate) GetInviterAci() []byte { @@ -6505,7 +6608,7 @@ type GroupMemberJoinedUpdate struct { func (x *GroupMemberJoinedUpdate) Reset() { *x = GroupMemberJoinedUpdate{} - mi := &file_backuppb_Backup_proto_msgTypes[58] + mi := &file_backuppb_Backup_proto_msgTypes[59] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6517,7 +6620,7 @@ func (x *GroupMemberJoinedUpdate) String() string { func (*GroupMemberJoinedUpdate) ProtoMessage() {} func (x *GroupMemberJoinedUpdate) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[58] + mi := &file_backuppb_Backup_proto_msgTypes[59] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6530,7 +6633,7 @@ func (x *GroupMemberJoinedUpdate) ProtoReflect() protoreflect.Message { // Deprecated: Use GroupMemberJoinedUpdate.ProtoReflect.Descriptor instead. func (*GroupMemberJoinedUpdate) Descriptor() ([]byte, []int) { - return file_backuppb_Backup_proto_rawDescGZIP(), []int{58} + return file_backuppb_Backup_proto_rawDescGZIP(), []int{59} } func (x *GroupMemberJoinedUpdate) GetNewMemberAci() []byte { @@ -6553,7 +6656,7 @@ type GroupMemberAddedUpdate struct { func (x *GroupMemberAddedUpdate) Reset() { *x = GroupMemberAddedUpdate{} - mi := &file_backuppb_Backup_proto_msgTypes[59] + mi := &file_backuppb_Backup_proto_msgTypes[60] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6565,7 +6668,7 @@ func (x *GroupMemberAddedUpdate) String() string { func (*GroupMemberAddedUpdate) ProtoMessage() {} func (x *GroupMemberAddedUpdate) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[59] + mi := &file_backuppb_Backup_proto_msgTypes[60] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6578,7 +6681,7 @@ func (x *GroupMemberAddedUpdate) ProtoReflect() protoreflect.Message { // Deprecated: Use GroupMemberAddedUpdate.ProtoReflect.Descriptor instead. func (*GroupMemberAddedUpdate) Descriptor() ([]byte, []int) { - return file_backuppb_Backup_proto_rawDescGZIP(), []int{59} + return file_backuppb_Backup_proto_rawDescGZIP(), []int{60} } func (x *GroupMemberAddedUpdate) GetUpdaterAci() []byte { @@ -6619,7 +6722,7 @@ type GroupSelfInvitationRevokedUpdate struct { func (x *GroupSelfInvitationRevokedUpdate) Reset() { *x = GroupSelfInvitationRevokedUpdate{} - mi := &file_backuppb_Backup_proto_msgTypes[60] + mi := &file_backuppb_Backup_proto_msgTypes[61] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6631,7 +6734,7 @@ func (x *GroupSelfInvitationRevokedUpdate) String() string { func (*GroupSelfInvitationRevokedUpdate) ProtoMessage() {} func (x *GroupSelfInvitationRevokedUpdate) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[60] + mi := &file_backuppb_Backup_proto_msgTypes[61] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6644,7 +6747,7 @@ func (x *GroupSelfInvitationRevokedUpdate) ProtoReflect() protoreflect.Message { // Deprecated: Use GroupSelfInvitationRevokedUpdate.ProtoReflect.Descriptor instead. func (*GroupSelfInvitationRevokedUpdate) Descriptor() ([]byte, []int) { - return file_backuppb_Backup_proto_rawDescGZIP(), []int{60} + return file_backuppb_Backup_proto_rawDescGZIP(), []int{61} } func (x *GroupSelfInvitationRevokedUpdate) GetRevokerAci() []byte { @@ -6670,7 +6773,7 @@ type GroupInvitationRevokedUpdate struct { func (x *GroupInvitationRevokedUpdate) Reset() { *x = GroupInvitationRevokedUpdate{} - mi := &file_backuppb_Backup_proto_msgTypes[61] + mi := &file_backuppb_Backup_proto_msgTypes[62] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6682,7 +6785,7 @@ func (x *GroupInvitationRevokedUpdate) String() string { func (*GroupInvitationRevokedUpdate) ProtoMessage() {} func (x *GroupInvitationRevokedUpdate) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[61] + mi := &file_backuppb_Backup_proto_msgTypes[62] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6695,7 +6798,7 @@ func (x *GroupInvitationRevokedUpdate) ProtoReflect() protoreflect.Message { // Deprecated: Use GroupInvitationRevokedUpdate.ProtoReflect.Descriptor instead. func (*GroupInvitationRevokedUpdate) Descriptor() ([]byte, []int) { - return file_backuppb_Backup_proto_rawDescGZIP(), []int{61} + return file_backuppb_Backup_proto_rawDescGZIP(), []int{62} } func (x *GroupInvitationRevokedUpdate) GetUpdaterAci() []byte { @@ -6721,7 +6824,7 @@ type GroupJoinRequestUpdate struct { func (x *GroupJoinRequestUpdate) Reset() { *x = GroupJoinRequestUpdate{} - mi := &file_backuppb_Backup_proto_msgTypes[62] + mi := &file_backuppb_Backup_proto_msgTypes[63] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6733,7 +6836,7 @@ func (x *GroupJoinRequestUpdate) String() string { func (*GroupJoinRequestUpdate) ProtoMessage() {} func (x *GroupJoinRequestUpdate) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[62] + mi := &file_backuppb_Backup_proto_msgTypes[63] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6746,7 +6849,7 @@ func (x *GroupJoinRequestUpdate) ProtoReflect() protoreflect.Message { // Deprecated: Use GroupJoinRequestUpdate.ProtoReflect.Descriptor instead. func (*GroupJoinRequestUpdate) Descriptor() ([]byte, []int) { - return file_backuppb_Backup_proto_rawDescGZIP(), []int{62} + return file_backuppb_Backup_proto_rawDescGZIP(), []int{63} } func (x *GroupJoinRequestUpdate) GetRequestorAci() []byte { @@ -6768,7 +6871,7 @@ type GroupJoinRequestApprovalUpdate struct { func (x *GroupJoinRequestApprovalUpdate) Reset() { *x = GroupJoinRequestApprovalUpdate{} - mi := &file_backuppb_Backup_proto_msgTypes[63] + mi := &file_backuppb_Backup_proto_msgTypes[64] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6780,7 +6883,7 @@ func (x *GroupJoinRequestApprovalUpdate) String() string { func (*GroupJoinRequestApprovalUpdate) ProtoMessage() {} func (x *GroupJoinRequestApprovalUpdate) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[63] + mi := &file_backuppb_Backup_proto_msgTypes[64] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6793,7 +6896,7 @@ func (x *GroupJoinRequestApprovalUpdate) ProtoReflect() protoreflect.Message { // Deprecated: Use GroupJoinRequestApprovalUpdate.ProtoReflect.Descriptor instead. func (*GroupJoinRequestApprovalUpdate) Descriptor() ([]byte, []int) { - return file_backuppb_Backup_proto_rawDescGZIP(), []int{63} + return file_backuppb_Backup_proto_rawDescGZIP(), []int{64} } func (x *GroupJoinRequestApprovalUpdate) GetRequestorAci() []byte { @@ -6826,7 +6929,7 @@ type GroupJoinRequestCanceledUpdate struct { func (x *GroupJoinRequestCanceledUpdate) Reset() { *x = GroupJoinRequestCanceledUpdate{} - mi := &file_backuppb_Backup_proto_msgTypes[64] + mi := &file_backuppb_Backup_proto_msgTypes[65] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6838,7 +6941,7 @@ func (x *GroupJoinRequestCanceledUpdate) String() string { func (*GroupJoinRequestCanceledUpdate) ProtoMessage() {} func (x *GroupJoinRequestCanceledUpdate) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[64] + mi := &file_backuppb_Backup_proto_msgTypes[65] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6851,7 +6954,7 @@ func (x *GroupJoinRequestCanceledUpdate) ProtoReflect() protoreflect.Message { // Deprecated: Use GroupJoinRequestCanceledUpdate.ProtoReflect.Descriptor instead. func (*GroupJoinRequestCanceledUpdate) Descriptor() ([]byte, []int) { - return file_backuppb_Backup_proto_rawDescGZIP(), []int{64} + return file_backuppb_Backup_proto_rawDescGZIP(), []int{65} } func (x *GroupJoinRequestCanceledUpdate) GetRequestorAci() []byte { @@ -6877,7 +6980,7 @@ type GroupSequenceOfRequestsAndCancelsUpdate struct { func (x *GroupSequenceOfRequestsAndCancelsUpdate) Reset() { *x = GroupSequenceOfRequestsAndCancelsUpdate{} - mi := &file_backuppb_Backup_proto_msgTypes[65] + mi := &file_backuppb_Backup_proto_msgTypes[66] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6889,7 +6992,7 @@ func (x *GroupSequenceOfRequestsAndCancelsUpdate) String() string { func (*GroupSequenceOfRequestsAndCancelsUpdate) ProtoMessage() {} func (x *GroupSequenceOfRequestsAndCancelsUpdate) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[65] + mi := &file_backuppb_Backup_proto_msgTypes[66] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6902,7 +7005,7 @@ func (x *GroupSequenceOfRequestsAndCancelsUpdate) ProtoReflect() protoreflect.Me // Deprecated: Use GroupSequenceOfRequestsAndCancelsUpdate.ProtoReflect.Descriptor instead. func (*GroupSequenceOfRequestsAndCancelsUpdate) Descriptor() ([]byte, []int) { - return file_backuppb_Backup_proto_rawDescGZIP(), []int{65} + return file_backuppb_Backup_proto_rawDescGZIP(), []int{66} } func (x *GroupSequenceOfRequestsAndCancelsUpdate) GetRequestorAci() []byte { @@ -6928,7 +7031,7 @@ type GroupInviteLinkResetUpdate struct { func (x *GroupInviteLinkResetUpdate) Reset() { *x = GroupInviteLinkResetUpdate{} - mi := &file_backuppb_Backup_proto_msgTypes[66] + mi := &file_backuppb_Backup_proto_msgTypes[67] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6940,7 +7043,7 @@ func (x *GroupInviteLinkResetUpdate) String() string { func (*GroupInviteLinkResetUpdate) ProtoMessage() {} func (x *GroupInviteLinkResetUpdate) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[66] + mi := &file_backuppb_Backup_proto_msgTypes[67] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6953,7 +7056,7 @@ func (x *GroupInviteLinkResetUpdate) ProtoReflect() protoreflect.Message { // Deprecated: Use GroupInviteLinkResetUpdate.ProtoReflect.Descriptor instead. func (*GroupInviteLinkResetUpdate) Descriptor() ([]byte, []int) { - return file_backuppb_Backup_proto_rawDescGZIP(), []int{66} + return file_backuppb_Backup_proto_rawDescGZIP(), []int{67} } func (x *GroupInviteLinkResetUpdate) GetUpdaterAci() []byte { @@ -6973,7 +7076,7 @@ type GroupInviteLinkEnabledUpdate struct { func (x *GroupInviteLinkEnabledUpdate) Reset() { *x = GroupInviteLinkEnabledUpdate{} - mi := &file_backuppb_Backup_proto_msgTypes[67] + mi := &file_backuppb_Backup_proto_msgTypes[68] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6985,7 +7088,7 @@ func (x *GroupInviteLinkEnabledUpdate) String() string { func (*GroupInviteLinkEnabledUpdate) ProtoMessage() {} func (x *GroupInviteLinkEnabledUpdate) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[67] + mi := &file_backuppb_Backup_proto_msgTypes[68] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6998,7 +7101,7 @@ func (x *GroupInviteLinkEnabledUpdate) ProtoReflect() protoreflect.Message { // Deprecated: Use GroupInviteLinkEnabledUpdate.ProtoReflect.Descriptor instead. func (*GroupInviteLinkEnabledUpdate) Descriptor() ([]byte, []int) { - return file_backuppb_Backup_proto_rawDescGZIP(), []int{67} + return file_backuppb_Backup_proto_rawDescGZIP(), []int{68} } func (x *GroupInviteLinkEnabledUpdate) GetUpdaterAci() []byte { @@ -7025,7 +7128,7 @@ type GroupInviteLinkAdminApprovalUpdate struct { func (x *GroupInviteLinkAdminApprovalUpdate) Reset() { *x = GroupInviteLinkAdminApprovalUpdate{} - mi := &file_backuppb_Backup_proto_msgTypes[68] + mi := &file_backuppb_Backup_proto_msgTypes[69] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7037,7 +7140,7 @@ func (x *GroupInviteLinkAdminApprovalUpdate) String() string { func (*GroupInviteLinkAdminApprovalUpdate) ProtoMessage() {} func (x *GroupInviteLinkAdminApprovalUpdate) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[68] + mi := &file_backuppb_Backup_proto_msgTypes[69] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7050,7 +7153,7 @@ func (x *GroupInviteLinkAdminApprovalUpdate) ProtoReflect() protoreflect.Message // Deprecated: Use GroupInviteLinkAdminApprovalUpdate.ProtoReflect.Descriptor instead. func (*GroupInviteLinkAdminApprovalUpdate) Descriptor() ([]byte, []int) { - return file_backuppb_Backup_proto_rawDescGZIP(), []int{68} + return file_backuppb_Backup_proto_rawDescGZIP(), []int{69} } func (x *GroupInviteLinkAdminApprovalUpdate) GetUpdaterAci() []byte { @@ -7076,7 +7179,7 @@ type GroupInviteLinkDisabledUpdate struct { func (x *GroupInviteLinkDisabledUpdate) Reset() { *x = GroupInviteLinkDisabledUpdate{} - mi := &file_backuppb_Backup_proto_msgTypes[69] + mi := &file_backuppb_Backup_proto_msgTypes[70] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7088,7 +7191,7 @@ func (x *GroupInviteLinkDisabledUpdate) String() string { func (*GroupInviteLinkDisabledUpdate) ProtoMessage() {} func (x *GroupInviteLinkDisabledUpdate) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[69] + mi := &file_backuppb_Backup_proto_msgTypes[70] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7101,7 +7204,7 @@ func (x *GroupInviteLinkDisabledUpdate) ProtoReflect() protoreflect.Message { // Deprecated: Use GroupInviteLinkDisabledUpdate.ProtoReflect.Descriptor instead. func (*GroupInviteLinkDisabledUpdate) Descriptor() ([]byte, []int) { - return file_backuppb_Backup_proto_rawDescGZIP(), []int{69} + return file_backuppb_Backup_proto_rawDescGZIP(), []int{70} } func (x *GroupInviteLinkDisabledUpdate) GetUpdaterAci() []byte { @@ -7120,7 +7223,7 @@ type GroupMemberJoinedByLinkUpdate struct { func (x *GroupMemberJoinedByLinkUpdate) Reset() { *x = GroupMemberJoinedByLinkUpdate{} - mi := &file_backuppb_Backup_proto_msgTypes[70] + mi := &file_backuppb_Backup_proto_msgTypes[71] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7132,7 +7235,7 @@ func (x *GroupMemberJoinedByLinkUpdate) String() string { func (*GroupMemberJoinedByLinkUpdate) ProtoMessage() {} func (x *GroupMemberJoinedByLinkUpdate) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[70] + mi := &file_backuppb_Backup_proto_msgTypes[71] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7145,7 +7248,7 @@ func (x *GroupMemberJoinedByLinkUpdate) ProtoReflect() protoreflect.Message { // Deprecated: Use GroupMemberJoinedByLinkUpdate.ProtoReflect.Descriptor instead. func (*GroupMemberJoinedByLinkUpdate) Descriptor() ([]byte, []int) { - return file_backuppb_Backup_proto_rawDescGZIP(), []int{70} + return file_backuppb_Backup_proto_rawDescGZIP(), []int{71} } func (x *GroupMemberJoinedByLinkUpdate) GetNewMemberAci() []byte { @@ -7164,7 +7267,7 @@ type GroupV2MigrationUpdate struct { func (x *GroupV2MigrationUpdate) Reset() { *x = GroupV2MigrationUpdate{} - mi := &file_backuppb_Backup_proto_msgTypes[71] + mi := &file_backuppb_Backup_proto_msgTypes[72] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7176,7 +7279,7 @@ func (x *GroupV2MigrationUpdate) String() string { func (*GroupV2MigrationUpdate) ProtoMessage() {} func (x *GroupV2MigrationUpdate) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[71] + mi := &file_backuppb_Backup_proto_msgTypes[72] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7189,7 +7292,7 @@ func (x *GroupV2MigrationUpdate) ProtoReflect() protoreflect.Message { // Deprecated: Use GroupV2MigrationUpdate.ProtoReflect.Descriptor instead. func (*GroupV2MigrationUpdate) Descriptor() ([]byte, []int) { - return file_backuppb_Backup_proto_rawDescGZIP(), []int{71} + return file_backuppb_Backup_proto_rawDescGZIP(), []int{72} } // Another user migrated gv1->gv2 but was unable to add @@ -7202,7 +7305,7 @@ type GroupV2MigrationSelfInvitedUpdate struct { func (x *GroupV2MigrationSelfInvitedUpdate) Reset() { *x = GroupV2MigrationSelfInvitedUpdate{} - mi := &file_backuppb_Backup_proto_msgTypes[72] + mi := &file_backuppb_Backup_proto_msgTypes[73] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7214,7 +7317,7 @@ func (x *GroupV2MigrationSelfInvitedUpdate) String() string { func (*GroupV2MigrationSelfInvitedUpdate) ProtoMessage() {} func (x *GroupV2MigrationSelfInvitedUpdate) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[72] + mi := &file_backuppb_Backup_proto_msgTypes[73] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7227,7 +7330,7 @@ func (x *GroupV2MigrationSelfInvitedUpdate) ProtoReflect() protoreflect.Message // Deprecated: Use GroupV2MigrationSelfInvitedUpdate.ProtoReflect.Descriptor instead. func (*GroupV2MigrationSelfInvitedUpdate) Descriptor() ([]byte, []int) { - return file_backuppb_Backup_proto_rawDescGZIP(), []int{72} + return file_backuppb_Backup_proto_rawDescGZIP(), []int{73} } // The local user migrated gv1->gv2 but was unable to @@ -7242,7 +7345,7 @@ type GroupV2MigrationInvitedMembersUpdate struct { func (x *GroupV2MigrationInvitedMembersUpdate) Reset() { *x = GroupV2MigrationInvitedMembersUpdate{} - mi := &file_backuppb_Backup_proto_msgTypes[73] + mi := &file_backuppb_Backup_proto_msgTypes[74] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7254,7 +7357,7 @@ func (x *GroupV2MigrationInvitedMembersUpdate) String() string { func (*GroupV2MigrationInvitedMembersUpdate) ProtoMessage() {} func (x *GroupV2MigrationInvitedMembersUpdate) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[73] + mi := &file_backuppb_Backup_proto_msgTypes[74] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7267,7 +7370,7 @@ func (x *GroupV2MigrationInvitedMembersUpdate) ProtoReflect() protoreflect.Messa // Deprecated: Use GroupV2MigrationInvitedMembersUpdate.ProtoReflect.Descriptor instead. func (*GroupV2MigrationInvitedMembersUpdate) Descriptor() ([]byte, []int) { - return file_backuppb_Backup_proto_rawDescGZIP(), []int{73} + return file_backuppb_Backup_proto_rawDescGZIP(), []int{74} } func (x *GroupV2MigrationInvitedMembersUpdate) GetInvitedMembersCount() uint32 { @@ -7289,7 +7392,7 @@ type GroupV2MigrationDroppedMembersUpdate struct { func (x *GroupV2MigrationDroppedMembersUpdate) Reset() { *x = GroupV2MigrationDroppedMembersUpdate{} - mi := &file_backuppb_Backup_proto_msgTypes[74] + mi := &file_backuppb_Backup_proto_msgTypes[75] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7301,7 +7404,7 @@ func (x *GroupV2MigrationDroppedMembersUpdate) String() string { func (*GroupV2MigrationDroppedMembersUpdate) ProtoMessage() {} func (x *GroupV2MigrationDroppedMembersUpdate) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[74] + mi := &file_backuppb_Backup_proto_msgTypes[75] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7314,7 +7417,7 @@ func (x *GroupV2MigrationDroppedMembersUpdate) ProtoReflect() protoreflect.Messa // Deprecated: Use GroupV2MigrationDroppedMembersUpdate.ProtoReflect.Descriptor instead. func (*GroupV2MigrationDroppedMembersUpdate) Descriptor() ([]byte, []int) { - return file_backuppb_Backup_proto_rawDescGZIP(), []int{74} + return file_backuppb_Backup_proto_rawDescGZIP(), []int{75} } func (x *GroupV2MigrationDroppedMembersUpdate) GetDroppedMembersCount() uint32 { @@ -7335,7 +7438,7 @@ type GroupExpirationTimerUpdate struct { func (x *GroupExpirationTimerUpdate) Reset() { *x = GroupExpirationTimerUpdate{} - mi := &file_backuppb_Backup_proto_msgTypes[75] + mi := &file_backuppb_Backup_proto_msgTypes[76] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7347,7 +7450,7 @@ func (x *GroupExpirationTimerUpdate) String() string { func (*GroupExpirationTimerUpdate) ProtoMessage() {} func (x *GroupExpirationTimerUpdate) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[75] + mi := &file_backuppb_Backup_proto_msgTypes[76] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7360,7 +7463,7 @@ func (x *GroupExpirationTimerUpdate) ProtoReflect() protoreflect.Message { // Deprecated: Use GroupExpirationTimerUpdate.ProtoReflect.Descriptor instead. func (*GroupExpirationTimerUpdate) Descriptor() ([]byte, []int) { - return file_backuppb_Backup_proto_rawDescGZIP(), []int{75} + return file_backuppb_Backup_proto_rawDescGZIP(), []int{76} } func (x *GroupExpirationTimerUpdate) GetExpiresInMs() uint64 { @@ -7377,6 +7480,58 @@ func (x *GroupExpirationTimerUpdate) GetUpdaterAci() []byte { return nil } +type PollTerminateUpdate struct { + state protoimpl.MessageState `protogen:"open.v1"` + TargetSentTimestamp uint64 `protobuf:"varint,1,opt,name=targetSentTimestamp,proto3" json:"targetSentTimestamp,omitempty"` + Question string `protobuf:"bytes,2,opt,name=question,proto3" json:"question,omitempty"` // Between 1-100 characters + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *PollTerminateUpdate) Reset() { + *x = PollTerminateUpdate{} + mi := &file_backuppb_Backup_proto_msgTypes[77] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *PollTerminateUpdate) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*PollTerminateUpdate) ProtoMessage() {} + +func (x *PollTerminateUpdate) ProtoReflect() protoreflect.Message { + mi := &file_backuppb_Backup_proto_msgTypes[77] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use PollTerminateUpdate.ProtoReflect.Descriptor instead. +func (*PollTerminateUpdate) Descriptor() ([]byte, []int) { + return file_backuppb_Backup_proto_rawDescGZIP(), []int{77} +} + +func (x *PollTerminateUpdate) GetTargetSentTimestamp() uint64 { + if x != nil { + return x.TargetSentTimestamp + } + return 0 +} + +func (x *PollTerminateUpdate) GetQuestion() string { + if x != nil { + return x.Question + } + return "" +} + type StickerPack struct { state protoimpl.MessageState `protogen:"open.v1"` PackId []byte `protobuf:"bytes,1,opt,name=packId,proto3" json:"packId,omitempty"` @@ -7387,7 +7542,7 @@ type StickerPack struct { func (x *StickerPack) Reset() { *x = StickerPack{} - mi := &file_backuppb_Backup_proto_msgTypes[76] + mi := &file_backuppb_Backup_proto_msgTypes[78] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7399,7 +7554,7 @@ func (x *StickerPack) String() string { func (*StickerPack) ProtoMessage() {} func (x *StickerPack) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[76] + mi := &file_backuppb_Backup_proto_msgTypes[78] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7412,7 +7567,7 @@ func (x *StickerPack) ProtoReflect() protoreflect.Message { // Deprecated: Use StickerPack.ProtoReflect.Descriptor instead. func (*StickerPack) Descriptor() ([]byte, []int) { - return file_backuppb_Backup_proto_rawDescGZIP(), []int{76} + return file_backuppb_Backup_proto_rawDescGZIP(), []int{78} } func (x *StickerPack) GetPackId() []byte { @@ -7453,7 +7608,7 @@ type ChatStyle struct { func (x *ChatStyle) Reset() { *x = ChatStyle{} - mi := &file_backuppb_Backup_proto_msgTypes[77] + mi := &file_backuppb_Backup_proto_msgTypes[79] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7465,7 +7620,7 @@ func (x *ChatStyle) String() string { func (*ChatStyle) ProtoMessage() {} func (x *ChatStyle) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[77] + mi := &file_backuppb_Backup_proto_msgTypes[79] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7478,7 +7633,7 @@ func (x *ChatStyle) ProtoReflect() protoreflect.Message { // Deprecated: Use ChatStyle.ProtoReflect.Descriptor instead. func (*ChatStyle) Descriptor() ([]byte, []int) { - return file_backuppb_Backup_proto_rawDescGZIP(), []int{77} + return file_backuppb_Backup_proto_rawDescGZIP(), []int{79} } func (x *ChatStyle) GetWallpaper() isChatStyle_Wallpaper { @@ -7610,7 +7765,7 @@ type NotificationProfile struct { func (x *NotificationProfile) Reset() { *x = NotificationProfile{} - mi := &file_backuppb_Backup_proto_msgTypes[78] + mi := &file_backuppb_Backup_proto_msgTypes[80] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7622,7 +7777,7 @@ func (x *NotificationProfile) String() string { func (*NotificationProfile) ProtoMessage() {} func (x *NotificationProfile) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[78] + mi := &file_backuppb_Backup_proto_msgTypes[80] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7635,7 +7790,7 @@ func (x *NotificationProfile) ProtoReflect() protoreflect.Message { // Deprecated: Use NotificationProfile.ProtoReflect.Descriptor instead. func (*NotificationProfile) Descriptor() ([]byte, []int) { - return file_backuppb_Backup_proto_rawDescGZIP(), []int{78} + return file_backuppb_Backup_proto_rawDescGZIP(), []int{80} } func (x *NotificationProfile) GetName() string { @@ -7741,7 +7896,7 @@ type ChatFolder struct { func (x *ChatFolder) Reset() { *x = ChatFolder{} - mi := &file_backuppb_Backup_proto_msgTypes[79] + mi := &file_backuppb_Backup_proto_msgTypes[81] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7753,7 +7908,7 @@ func (x *ChatFolder) String() string { func (*ChatFolder) ProtoMessage() {} func (x *ChatFolder) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[79] + mi := &file_backuppb_Backup_proto_msgTypes[81] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7766,7 +7921,7 @@ func (x *ChatFolder) ProtoReflect() protoreflect.Message { // Deprecated: Use ChatFolder.ProtoReflect.Descriptor instead. func (*ChatFolder) Descriptor() ([]byte, []int) { - return file_backuppb_Backup_proto_rawDescGZIP(), []int{79} + return file_backuppb_Backup_proto_rawDescGZIP(), []int{81} } func (x *ChatFolder) GetName() string { @@ -7843,7 +7998,7 @@ type AccountData_UsernameLink struct { func (x *AccountData_UsernameLink) Reset() { *x = AccountData_UsernameLink{} - mi := &file_backuppb_Backup_proto_msgTypes[80] + mi := &file_backuppb_Backup_proto_msgTypes[82] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7855,7 +8010,7 @@ func (x *AccountData_UsernameLink) String() string { func (*AccountData_UsernameLink) ProtoMessage() {} func (x *AccountData_UsernameLink) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[80] + mi := &file_backuppb_Backup_proto_msgTypes[82] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7922,7 +8077,7 @@ type AccountData_AccountSettings struct { func (x *AccountData_AccountSettings) Reset() { *x = AccountData_AccountSettings{} - mi := &file_backuppb_Backup_proto_msgTypes[81] + mi := &file_backuppb_Backup_proto_msgTypes[83] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7934,7 +8089,7 @@ func (x *AccountData_AccountSettings) String() string { func (*AccountData_AccountSettings) ProtoMessage() {} func (x *AccountData_AccountSettings) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[81] + mi := &file_backuppb_Backup_proto_msgTypes[83] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8108,7 +8263,7 @@ type AccountData_SubscriberData struct { func (x *AccountData_SubscriberData) Reset() { *x = AccountData_SubscriberData{} - mi := &file_backuppb_Backup_proto_msgTypes[82] + mi := &file_backuppb_Backup_proto_msgTypes[84] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8120,7 +8275,7 @@ func (x *AccountData_SubscriberData) String() string { func (*AccountData_SubscriberData) ProtoMessage() {} func (x *AccountData_SubscriberData) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[82] + mi := &file_backuppb_Backup_proto_msgTypes[84] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8173,7 +8328,7 @@ type AccountData_IAPSubscriberData struct { func (x *AccountData_IAPSubscriberData) Reset() { *x = AccountData_IAPSubscriberData{} - mi := &file_backuppb_Backup_proto_msgTypes[83] + mi := &file_backuppb_Backup_proto_msgTypes[85] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8185,7 +8340,7 @@ func (x *AccountData_IAPSubscriberData) String() string { func (*AccountData_IAPSubscriberData) ProtoMessage() {} func (x *AccountData_IAPSubscriberData) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[83] + mi := &file_backuppb_Backup_proto_msgTypes[85] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8261,7 +8416,7 @@ type Contact_Registered struct { func (x *Contact_Registered) Reset() { *x = Contact_Registered{} - mi := &file_backuppb_Backup_proto_msgTypes[84] + mi := &file_backuppb_Backup_proto_msgTypes[86] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8273,7 +8428,7 @@ func (x *Contact_Registered) String() string { func (*Contact_Registered) ProtoMessage() {} func (x *Contact_Registered) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[84] + mi := &file_backuppb_Backup_proto_msgTypes[86] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8298,7 +8453,7 @@ type Contact_NotRegistered struct { func (x *Contact_NotRegistered) Reset() { *x = Contact_NotRegistered{} - mi := &file_backuppb_Backup_proto_msgTypes[85] + mi := &file_backuppb_Backup_proto_msgTypes[87] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8310,7 +8465,7 @@ func (x *Contact_NotRegistered) String() string { func (*Contact_NotRegistered) ProtoMessage() {} func (x *Contact_NotRegistered) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[85] + mi := &file_backuppb_Backup_proto_msgTypes[87] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8343,7 +8498,7 @@ type Contact_Name struct { func (x *Contact_Name) Reset() { *x = Contact_Name{} - mi := &file_backuppb_Backup_proto_msgTypes[86] + mi := &file_backuppb_Backup_proto_msgTypes[88] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8355,7 +8510,7 @@ func (x *Contact_Name) String() string { func (*Contact_Name) ProtoMessage() {} func (x *Contact_Name) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[86] + mi := &file_backuppb_Backup_proto_msgTypes[88] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8410,7 +8565,7 @@ type Group_GroupSnapshot struct { func (x *Group_GroupSnapshot) Reset() { *x = Group_GroupSnapshot{} - mi := &file_backuppb_Backup_proto_msgTypes[87] + mi := &file_backuppb_Backup_proto_msgTypes[89] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8422,7 +8577,7 @@ func (x *Group_GroupSnapshot) String() string { func (*Group_GroupSnapshot) ProtoMessage() {} func (x *Group_GroupSnapshot) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[87] + mi := &file_backuppb_Backup_proto_msgTypes[89] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8539,7 +8694,7 @@ type Group_GroupAttributeBlob struct { func (x *Group_GroupAttributeBlob) Reset() { *x = Group_GroupAttributeBlob{} - mi := &file_backuppb_Backup_proto_msgTypes[88] + mi := &file_backuppb_Backup_proto_msgTypes[90] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8551,7 +8706,7 @@ func (x *Group_GroupAttributeBlob) String() string { func (*Group_GroupAttributeBlob) ProtoMessage() {} func (x *Group_GroupAttributeBlob) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[88] + mi := &file_backuppb_Backup_proto_msgTypes[90] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8649,7 +8804,7 @@ type Group_Member struct { func (x *Group_Member) Reset() { *x = Group_Member{} - mi := &file_backuppb_Backup_proto_msgTypes[89] + mi := &file_backuppb_Backup_proto_msgTypes[91] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8661,7 +8816,7 @@ func (x *Group_Member) String() string { func (*Group_Member) ProtoMessage() {} func (x *Group_Member) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[89] + mi := &file_backuppb_Backup_proto_msgTypes[91] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8709,7 +8864,7 @@ type Group_MemberPendingProfileKey struct { func (x *Group_MemberPendingProfileKey) Reset() { *x = Group_MemberPendingProfileKey{} - mi := &file_backuppb_Backup_proto_msgTypes[90] + mi := &file_backuppb_Backup_proto_msgTypes[92] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8721,7 +8876,7 @@ func (x *Group_MemberPendingProfileKey) String() string { func (*Group_MemberPendingProfileKey) ProtoMessage() {} func (x *Group_MemberPendingProfileKey) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[90] + mi := &file_backuppb_Backup_proto_msgTypes[92] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8768,7 +8923,7 @@ type Group_MemberPendingAdminApproval struct { func (x *Group_MemberPendingAdminApproval) Reset() { *x = Group_MemberPendingAdminApproval{} - mi := &file_backuppb_Backup_proto_msgTypes[91] + mi := &file_backuppb_Backup_proto_msgTypes[93] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8780,7 +8935,7 @@ func (x *Group_MemberPendingAdminApproval) String() string { func (*Group_MemberPendingAdminApproval) ProtoMessage() {} func (x *Group_MemberPendingAdminApproval) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[91] + mi := &file_backuppb_Backup_proto_msgTypes[93] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8820,7 +8975,7 @@ type Group_MemberBanned struct { func (x *Group_MemberBanned) Reset() { *x = Group_MemberBanned{} - mi := &file_backuppb_Backup_proto_msgTypes[92] + mi := &file_backuppb_Backup_proto_msgTypes[94] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8832,7 +8987,7 @@ func (x *Group_MemberBanned) String() string { func (*Group_MemberBanned) ProtoMessage() {} func (x *Group_MemberBanned) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[92] + mi := &file_backuppb_Backup_proto_msgTypes[94] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8873,7 +9028,7 @@ type Group_AccessControl struct { func (x *Group_AccessControl) Reset() { *x = Group_AccessControl{} - mi := &file_backuppb_Backup_proto_msgTypes[93] + mi := &file_backuppb_Backup_proto_msgTypes[95] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8885,7 +9040,7 @@ func (x *Group_AccessControl) String() string { func (*Group_AccessControl) ProtoMessage() {} func (x *Group_AccessControl) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[93] + mi := &file_backuppb_Backup_proto_msgTypes[95] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8934,7 +9089,7 @@ type ChatItem_IncomingMessageDetails struct { func (x *ChatItem_IncomingMessageDetails) Reset() { *x = ChatItem_IncomingMessageDetails{} - mi := &file_backuppb_Backup_proto_msgTypes[94] + mi := &file_backuppb_Backup_proto_msgTypes[96] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8946,7 +9101,7 @@ func (x *ChatItem_IncomingMessageDetails) String() string { func (*ChatItem_IncomingMessageDetails) ProtoMessage() {} func (x *ChatItem_IncomingMessageDetails) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[94] + mi := &file_backuppb_Backup_proto_msgTypes[96] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9000,7 +9155,7 @@ type ChatItem_OutgoingMessageDetails struct { func (x *ChatItem_OutgoingMessageDetails) Reset() { *x = ChatItem_OutgoingMessageDetails{} - mi := &file_backuppb_Backup_proto_msgTypes[95] + mi := &file_backuppb_Backup_proto_msgTypes[97] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9012,7 +9167,7 @@ func (x *ChatItem_OutgoingMessageDetails) String() string { func (*ChatItem_OutgoingMessageDetails) ProtoMessage() {} func (x *ChatItem_OutgoingMessageDetails) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[95] + mi := &file_backuppb_Backup_proto_msgTypes[97] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9050,7 +9205,7 @@ type ChatItem_DirectionlessMessageDetails struct { func (x *ChatItem_DirectionlessMessageDetails) Reset() { *x = ChatItem_DirectionlessMessageDetails{} - mi := &file_backuppb_Backup_proto_msgTypes[96] + mi := &file_backuppb_Backup_proto_msgTypes[98] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9062,7 +9217,7 @@ func (x *ChatItem_DirectionlessMessageDetails) String() string { func (*ChatItem_DirectionlessMessageDetails) ProtoMessage() {} func (x *ChatItem_DirectionlessMessageDetails) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[96] + mi := &file_backuppb_Backup_proto_msgTypes[98] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9086,7 +9241,7 @@ type SendStatus_Pending struct { func (x *SendStatus_Pending) Reset() { *x = SendStatus_Pending{} - mi := &file_backuppb_Backup_proto_msgTypes[97] + mi := &file_backuppb_Backup_proto_msgTypes[99] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9098,7 +9253,7 @@ func (x *SendStatus_Pending) String() string { func (*SendStatus_Pending) ProtoMessage() {} func (x *SendStatus_Pending) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[97] + mi := &file_backuppb_Backup_proto_msgTypes[99] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9123,7 +9278,7 @@ type SendStatus_Sent struct { func (x *SendStatus_Sent) Reset() { *x = SendStatus_Sent{} - mi := &file_backuppb_Backup_proto_msgTypes[98] + mi := &file_backuppb_Backup_proto_msgTypes[100] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9135,7 +9290,7 @@ func (x *SendStatus_Sent) String() string { func (*SendStatus_Sent) ProtoMessage() {} func (x *SendStatus_Sent) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[98] + mi := &file_backuppb_Backup_proto_msgTypes[100] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9167,7 +9322,7 @@ type SendStatus_Delivered struct { func (x *SendStatus_Delivered) Reset() { *x = SendStatus_Delivered{} - mi := &file_backuppb_Backup_proto_msgTypes[99] + mi := &file_backuppb_Backup_proto_msgTypes[101] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9179,7 +9334,7 @@ func (x *SendStatus_Delivered) String() string { func (*SendStatus_Delivered) ProtoMessage() {} func (x *SendStatus_Delivered) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[99] + mi := &file_backuppb_Backup_proto_msgTypes[101] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9211,7 +9366,7 @@ type SendStatus_Read struct { func (x *SendStatus_Read) Reset() { *x = SendStatus_Read{} - mi := &file_backuppb_Backup_proto_msgTypes[100] + mi := &file_backuppb_Backup_proto_msgTypes[102] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9223,7 +9378,7 @@ func (x *SendStatus_Read) String() string { func (*SendStatus_Read) ProtoMessage() {} func (x *SendStatus_Read) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[100] + mi := &file_backuppb_Backup_proto_msgTypes[102] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9255,7 +9410,7 @@ type SendStatus_Viewed struct { func (x *SendStatus_Viewed) Reset() { *x = SendStatus_Viewed{} - mi := &file_backuppb_Backup_proto_msgTypes[101] + mi := &file_backuppb_Backup_proto_msgTypes[103] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9267,7 +9422,7 @@ func (x *SendStatus_Viewed) String() string { func (*SendStatus_Viewed) ProtoMessage() {} func (x *SendStatus_Viewed) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[101] + mi := &file_backuppb_Backup_proto_msgTypes[103] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9299,7 +9454,7 @@ type SendStatus_Skipped struct { func (x *SendStatus_Skipped) Reset() { *x = SendStatus_Skipped{} - mi := &file_backuppb_Backup_proto_msgTypes[102] + mi := &file_backuppb_Backup_proto_msgTypes[104] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9311,7 +9466,7 @@ func (x *SendStatus_Skipped) String() string { func (*SendStatus_Skipped) ProtoMessage() {} func (x *SendStatus_Skipped) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[102] + mi := &file_backuppb_Backup_proto_msgTypes[104] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9336,7 +9491,7 @@ type SendStatus_Failed struct { func (x *SendStatus_Failed) Reset() { *x = SendStatus_Failed{} - mi := &file_backuppb_Backup_proto_msgTypes[103] + mi := &file_backuppb_Backup_proto_msgTypes[105] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9348,7 +9503,7 @@ func (x *SendStatus_Failed) String() string { func (*SendStatus_Failed) ProtoMessage() {} func (x *SendStatus_Failed) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[103] + mi := &file_backuppb_Backup_proto_msgTypes[105] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9381,7 +9536,7 @@ type DirectStoryReplyMessage_TextReply struct { func (x *DirectStoryReplyMessage_TextReply) Reset() { *x = DirectStoryReplyMessage_TextReply{} - mi := &file_backuppb_Backup_proto_msgTypes[104] + mi := &file_backuppb_Backup_proto_msgTypes[106] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9393,7 +9548,7 @@ func (x *DirectStoryReplyMessage_TextReply) String() string { func (*DirectStoryReplyMessage_TextReply) ProtoMessage() {} func (x *DirectStoryReplyMessage_TextReply) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[104] + mi := &file_backuppb_Backup_proto_msgTypes[106] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9438,7 +9593,7 @@ type PaymentNotification_TransactionDetails struct { func (x *PaymentNotification_TransactionDetails) Reset() { *x = PaymentNotification_TransactionDetails{} - mi := &file_backuppb_Backup_proto_msgTypes[105] + mi := &file_backuppb_Backup_proto_msgTypes[107] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9450,7 +9605,7 @@ func (x *PaymentNotification_TransactionDetails) String() string { func (*PaymentNotification_TransactionDetails) ProtoMessage() {} func (x *PaymentNotification_TransactionDetails) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[105] + mi := &file_backuppb_Backup_proto_msgTypes[107] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9519,7 +9674,7 @@ type PaymentNotification_TransactionDetails_MobileCoinTxoIdentification struct { func (x *PaymentNotification_TransactionDetails_MobileCoinTxoIdentification) Reset() { *x = PaymentNotification_TransactionDetails_MobileCoinTxoIdentification{} - mi := &file_backuppb_Backup_proto_msgTypes[106] + mi := &file_backuppb_Backup_proto_msgTypes[108] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9531,7 +9686,7 @@ func (x *PaymentNotification_TransactionDetails_MobileCoinTxoIdentification) Str func (*PaymentNotification_TransactionDetails_MobileCoinTxoIdentification) ProtoMessage() {} func (x *PaymentNotification_TransactionDetails_MobileCoinTxoIdentification) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[106] + mi := &file_backuppb_Backup_proto_msgTypes[108] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9570,7 +9725,7 @@ type PaymentNotification_TransactionDetails_FailedTransaction struct { func (x *PaymentNotification_TransactionDetails_FailedTransaction) Reset() { *x = PaymentNotification_TransactionDetails_FailedTransaction{} - mi := &file_backuppb_Backup_proto_msgTypes[107] + mi := &file_backuppb_Backup_proto_msgTypes[109] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9582,7 +9737,7 @@ func (x *PaymentNotification_TransactionDetails_FailedTransaction) String() stri func (*PaymentNotification_TransactionDetails_FailedTransaction) ProtoMessage() {} func (x *PaymentNotification_TransactionDetails_FailedTransaction) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[107] + mi := &file_backuppb_Backup_proto_msgTypes[109] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9623,7 +9778,7 @@ type PaymentNotification_TransactionDetails_Transaction struct { func (x *PaymentNotification_TransactionDetails_Transaction) Reset() { *x = PaymentNotification_TransactionDetails_Transaction{} - mi := &file_backuppb_Backup_proto_msgTypes[108] + mi := &file_backuppb_Backup_proto_msgTypes[110] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9635,7 +9790,7 @@ func (x *PaymentNotification_TransactionDetails_Transaction) String() string { func (*PaymentNotification_TransactionDetails_Transaction) ProtoMessage() {} func (x *PaymentNotification_TransactionDetails_Transaction) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[108] + mi := &file_backuppb_Backup_proto_msgTypes[110] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9714,7 +9869,7 @@ type ContactAttachment_Name struct { func (x *ContactAttachment_Name) Reset() { *x = ContactAttachment_Name{} - mi := &file_backuppb_Backup_proto_msgTypes[109] + mi := &file_backuppb_Backup_proto_msgTypes[111] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9726,7 +9881,7 @@ func (x *ContactAttachment_Name) String() string { func (*ContactAttachment_Name) ProtoMessage() {} func (x *ContactAttachment_Name) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[109] + mi := &file_backuppb_Backup_proto_msgTypes[111] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9795,7 +9950,7 @@ type ContactAttachment_Phone struct { func (x *ContactAttachment_Phone) Reset() { *x = ContactAttachment_Phone{} - mi := &file_backuppb_Backup_proto_msgTypes[110] + mi := &file_backuppb_Backup_proto_msgTypes[112] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9807,7 +9962,7 @@ func (x *ContactAttachment_Phone) String() string { func (*ContactAttachment_Phone) ProtoMessage() {} func (x *ContactAttachment_Phone) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[110] + mi := &file_backuppb_Backup_proto_msgTypes[112] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9855,7 +10010,7 @@ type ContactAttachment_Email struct { func (x *ContactAttachment_Email) Reset() { *x = ContactAttachment_Email{} - mi := &file_backuppb_Backup_proto_msgTypes[111] + mi := &file_backuppb_Backup_proto_msgTypes[113] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9867,7 +10022,7 @@ func (x *ContactAttachment_Email) String() string { func (*ContactAttachment_Email) ProtoMessage() {} func (x *ContactAttachment_Email) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[111] + mi := &file_backuppb_Backup_proto_msgTypes[113] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9921,7 +10076,7 @@ type ContactAttachment_PostalAddress struct { func (x *ContactAttachment_PostalAddress) Reset() { *x = ContactAttachment_PostalAddress{} - mi := &file_backuppb_Backup_proto_msgTypes[112] + mi := &file_backuppb_Backup_proto_msgTypes[114] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9933,7 +10088,7 @@ func (x *ContactAttachment_PostalAddress) String() string { func (*ContactAttachment_PostalAddress) ProtoMessage() {} func (x *ContactAttachment_PostalAddress) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[112] + mi := &file_backuppb_Backup_proto_msgTypes[114] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -10048,7 +10203,7 @@ type FilePointer_LocatorInfo struct { func (x *FilePointer_LocatorInfo) Reset() { *x = FilePointer_LocatorInfo{} - mi := &file_backuppb_Backup_proto_msgTypes[113] + mi := &file_backuppb_Backup_proto_msgTypes[115] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -10060,7 +10215,7 @@ func (x *FilePointer_LocatorInfo) String() string { func (*FilePointer_LocatorInfo) ProtoMessage() {} func (x *FilePointer_LocatorInfo) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[113] + mi := &file_backuppb_Backup_proto_msgTypes[115] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -10180,7 +10335,7 @@ type Quote_QuotedAttachment struct { func (x *Quote_QuotedAttachment) Reset() { *x = Quote_QuotedAttachment{} - mi := &file_backuppb_Backup_proto_msgTypes[114] + mi := &file_backuppb_Backup_proto_msgTypes[116] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -10192,7 +10347,7 @@ func (x *Quote_QuotedAttachment) String() string { func (*Quote_QuotedAttachment) ProtoMessage() {} func (x *Quote_QuotedAttachment) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[114] + mi := &file_backuppb_Backup_proto_msgTypes[116] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -10229,6 +10384,110 @@ func (x *Quote_QuotedAttachment) GetThumbnail() *MessageAttachment { return nil } +type Poll_PollOption struct { + state protoimpl.MessageState `protogen:"open.v1"` + Option string `protobuf:"bytes,1,opt,name=option,proto3" json:"option,omitempty"` // Between 1-100 characters + Votes []*Poll_PollOption_PollVote `protobuf:"bytes,2,rep,name=votes,proto3" json:"votes,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *Poll_PollOption) Reset() { + *x = Poll_PollOption{} + mi := &file_backuppb_Backup_proto_msgTypes[117] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *Poll_PollOption) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Poll_PollOption) ProtoMessage() {} + +func (x *Poll_PollOption) ProtoReflect() protoreflect.Message { + mi := &file_backuppb_Backup_proto_msgTypes[117] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Poll_PollOption.ProtoReflect.Descriptor instead. +func (*Poll_PollOption) Descriptor() ([]byte, []int) { + return file_backuppb_Backup_proto_rawDescGZIP(), []int{32, 0} +} + +func (x *Poll_PollOption) GetOption() string { + if x != nil { + return x.Option + } + return "" +} + +func (x *Poll_PollOption) GetVotes() []*Poll_PollOption_PollVote { + if x != nil { + return x.Votes + } + return nil +} + +type Poll_PollOption_PollVote struct { + state protoimpl.MessageState `protogen:"open.v1"` + VoterId uint64 `protobuf:"varint,1,opt,name=voterId,proto3" json:"voterId,omitempty"` // A direct reference to Recipient proto id. Must be self or contact. + VoteCount uint32 `protobuf:"varint,2,opt,name=voteCount,proto3" json:"voteCount,omitempty"` // Tracks how many times you voted. + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *Poll_PollOption_PollVote) Reset() { + *x = Poll_PollOption_PollVote{} + mi := &file_backuppb_Backup_proto_msgTypes[118] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *Poll_PollOption_PollVote) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Poll_PollOption_PollVote) ProtoMessage() {} + +func (x *Poll_PollOption_PollVote) ProtoReflect() protoreflect.Message { + mi := &file_backuppb_Backup_proto_msgTypes[118] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Poll_PollOption_PollVote.ProtoReflect.Descriptor instead. +func (*Poll_PollOption_PollVote) Descriptor() ([]byte, []int) { + return file_backuppb_Backup_proto_rawDescGZIP(), []int{32, 0, 0} +} + +func (x *Poll_PollOption_PollVote) GetVoterId() uint64 { + if x != nil { + return x.VoterId + } + return 0 +} + +func (x *Poll_PollOption_PollVote) GetVoteCount() uint32 { + if x != nil { + return x.VoteCount + } + return 0 +} + type GroupChangeChatUpdate_Update struct { state protoimpl.MessageState `protogen:"open.v1"` // If unset, importers should consider it to be a GenericGroupUpdate with unset updaterAci @@ -10276,7 +10535,7 @@ type GroupChangeChatUpdate_Update struct { func (x *GroupChangeChatUpdate_Update) Reset() { *x = GroupChangeChatUpdate_Update{} - mi := &file_backuppb_Backup_proto_msgTypes[115] + mi := &file_backuppb_Backup_proto_msgTypes[119] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -10288,7 +10547,7 @@ func (x *GroupChangeChatUpdate_Update) String() string { func (*GroupChangeChatUpdate_Update) ProtoMessage() {} func (x *GroupChangeChatUpdate_Update) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[115] + mi := &file_backuppb_Backup_proto_msgTypes[119] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -10301,7 +10560,7 @@ func (x *GroupChangeChatUpdate_Update) ProtoReflect() protoreflect.Message { // Deprecated: Use GroupChangeChatUpdate_Update.ProtoReflect.Descriptor instead. func (*GroupChangeChatUpdate_Update) Descriptor() ([]byte, []int) { - return file_backuppb_Backup_proto_rawDescGZIP(), []int{41, 0} + return file_backuppb_Backup_proto_rawDescGZIP(), []int{42, 0} } func (x *GroupChangeChatUpdate_Update) GetUpdate() isGroupChangeChatUpdate_Update_Update { @@ -10862,7 +11121,7 @@ type GroupInvitationRevokedUpdate_Invitee struct { func (x *GroupInvitationRevokedUpdate_Invitee) Reset() { *x = GroupInvitationRevokedUpdate_Invitee{} - mi := &file_backuppb_Backup_proto_msgTypes[116] + mi := &file_backuppb_Backup_proto_msgTypes[120] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -10874,7 +11133,7 @@ func (x *GroupInvitationRevokedUpdate_Invitee) String() string { func (*GroupInvitationRevokedUpdate_Invitee) ProtoMessage() {} func (x *GroupInvitationRevokedUpdate_Invitee) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[116] + mi := &file_backuppb_Backup_proto_msgTypes[120] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -10887,7 +11146,7 @@ func (x *GroupInvitationRevokedUpdate_Invitee) ProtoReflect() protoreflect.Messa // Deprecated: Use GroupInvitationRevokedUpdate_Invitee.ProtoReflect.Descriptor instead. func (*GroupInvitationRevokedUpdate_Invitee) Descriptor() ([]byte, []int) { - return file_backuppb_Backup_proto_rawDescGZIP(), []int{61, 0} + return file_backuppb_Backup_proto_rawDescGZIP(), []int{62, 0} } func (x *GroupInvitationRevokedUpdate_Invitee) GetInviterAci() []byte { @@ -10922,7 +11181,7 @@ type ChatStyle_Gradient struct { func (x *ChatStyle_Gradient) Reset() { *x = ChatStyle_Gradient{} - mi := &file_backuppb_Backup_proto_msgTypes[117] + mi := &file_backuppb_Backup_proto_msgTypes[121] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -10934,7 +11193,7 @@ func (x *ChatStyle_Gradient) String() string { func (*ChatStyle_Gradient) ProtoMessage() {} func (x *ChatStyle_Gradient) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[117] + mi := &file_backuppb_Backup_proto_msgTypes[121] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -10947,7 +11206,7 @@ func (x *ChatStyle_Gradient) ProtoReflect() protoreflect.Message { // Deprecated: Use ChatStyle_Gradient.ProtoReflect.Descriptor instead. func (*ChatStyle_Gradient) Descriptor() ([]byte, []int) { - return file_backuppb_Backup_proto_rawDescGZIP(), []int{77, 0} + return file_backuppb_Backup_proto_rawDescGZIP(), []int{79, 0} } func (x *ChatStyle_Gradient) GetAngle() uint32 { @@ -10987,7 +11246,7 @@ type ChatStyle_CustomChatColor struct { func (x *ChatStyle_CustomChatColor) Reset() { *x = ChatStyle_CustomChatColor{} - mi := &file_backuppb_Backup_proto_msgTypes[118] + mi := &file_backuppb_Backup_proto_msgTypes[122] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -10999,7 +11258,7 @@ func (x *ChatStyle_CustomChatColor) String() string { func (*ChatStyle_CustomChatColor) ProtoMessage() {} func (x *ChatStyle_CustomChatColor) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[118] + mi := &file_backuppb_Backup_proto_msgTypes[122] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -11012,7 +11271,7 @@ func (x *ChatStyle_CustomChatColor) ProtoReflect() protoreflect.Message { // Deprecated: Use ChatStyle_CustomChatColor.ProtoReflect.Descriptor instead. func (*ChatStyle_CustomChatColor) Descriptor() ([]byte, []int) { - return file_backuppb_Backup_proto_rawDescGZIP(), []int{77, 1} + return file_backuppb_Backup_proto_rawDescGZIP(), []int{79, 1} } func (x *ChatStyle_CustomChatColor) GetId() uint64 { @@ -11071,7 +11330,7 @@ type ChatStyle_AutomaticBubbleColor struct { func (x *ChatStyle_AutomaticBubbleColor) Reset() { *x = ChatStyle_AutomaticBubbleColor{} - mi := &file_backuppb_Backup_proto_msgTypes[119] + mi := &file_backuppb_Backup_proto_msgTypes[123] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -11083,7 +11342,7 @@ func (x *ChatStyle_AutomaticBubbleColor) String() string { func (*ChatStyle_AutomaticBubbleColor) ProtoMessage() {} func (x *ChatStyle_AutomaticBubbleColor) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[119] + mi := &file_backuppb_Backup_proto_msgTypes[123] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -11096,7 +11355,7 @@ func (x *ChatStyle_AutomaticBubbleColor) ProtoReflect() protoreflect.Message { // Deprecated: Use ChatStyle_AutomaticBubbleColor.ProtoReflect.Descriptor instead. func (*ChatStyle_AutomaticBubbleColor) Descriptor() ([]byte, []int) { - return file_backuppb_Backup_proto_rawDescGZIP(), []int{77, 2} + return file_backuppb_Backup_proto_rawDescGZIP(), []int{79, 2} } var File_backuppb_Backup_proto protoreflect.FileDescriptor @@ -11385,7 +11644,7 @@ const file_backuppb_Backup_proto_rawDesc = "" + "\tONLY_WITH\x10\x01\x12\x0e\n" + "\n" + "ALL_EXCEPT\x10\x02\x12\a\n" + - "\x03ALL\x10\x03\"\xc8\f\n" + + "\x03ALL\x10\x03\"\xf3\f\n" + "\bChatItem\x12\x16\n" + "\x06chatId\x18\x01 \x01(\x04R\x06chatId\x12\x1a\n" + "\bauthorId\x18\x02 \x01(\x04R\bauthorId\x12\x1a\n" + @@ -11406,7 +11665,8 @@ const file_backuppb_Backup_proto_rawDesc = "" + "\x13paymentNotification\x18\x10 \x01(\v2\".signal.backup.PaymentNotificationH\x01R\x13paymentNotification\x128\n" + "\tgiftBadge\x18\x11 \x01(\v2\x18.signal.backup.GiftBadgeH\x01R\tgiftBadge\x12J\n" + "\x0fviewOnceMessage\x18\x12 \x01(\v2\x1e.signal.backup.ViewOnceMessageH\x01R\x0fviewOnceMessage\x12b\n" + - "\x17directStoryReplyMessage\x18\x13 \x01(\v2&.signal.backup.DirectStoryReplyMessageH\x01R\x17directStoryReplyMessage\x1a\xb4\x01\n" + + "\x17directStoryReplyMessage\x18\x13 \x01(\v2&.signal.backup.DirectStoryReplyMessageH\x01R\x17directStoryReplyMessage\x12)\n" + + "\x04poll\x18\x14 \x01(\v2\x13.signal.backup.PollH\x01R\x04poll\x1a\xb4\x01\n" + "\x16IncomingMessageDetails\x12\"\n" + "\fdateReceived\x18\x01 \x01(\x04R\fdateReceived\x12+\n" + "\x0edateServerSent\x18\x02 \x01(\x04H\x00R\x0edateServerSent\x88\x01\x01\x12\x12\n" + @@ -11669,7 +11929,7 @@ const file_backuppb_Backup_proto_rawDesc = "" + "\a_heightB\n" + "\n" + "\b_captionB\v\n" + - "\t_blurHashJ\x04\b\x01\x10\x02J\x04\b\x02\x10\x03J\x04\b\x03\x10\x04J\x04\b\f\x10\r\"\xae\x04\n" + + "\t_blurHashJ\x04\b\x01\x10\x02J\x04\b\x02\x10\x03J\x04\b\x03\x10\x04J\x04\b\f\x10\r\"\xb8\x04\n" + "\x05Quote\x125\n" + "\x13targetSentTimestamp\x18\x01 \x01(\x04H\x00R\x13targetSentTimestamp\x88\x01\x01\x12\x1a\n" + "\bauthorId\x18\x02 \x01(\x04R\bauthorId\x12,\n" + @@ -11683,14 +11943,15 @@ const file_backuppb_Backup_proto_rawDesc = "" + "\f_contentTypeB\v\n" + "\t_fileNameB\f\n" + "\n" + - "_thumbnail\">\n" + + "_thumbnail\"H\n" + "\x04Type\x12\v\n" + "\aUNKNOWN\x10\x00\x12\n" + "\n" + "\x06NORMAL\x10\x01\x12\x0e\n" + "\n" + "GIFT_BADGE\x10\x02\x12\r\n" + - "\tVIEW_ONCE\x10\x03B\x16\n" + + "\tVIEW_ONCE\x10\x03\x12\b\n" + + "\x04POLL\x10\x04B\x16\n" + "\x14_targetSentTimestampB\a\n" + "\x05_text\"\xfe\x01\n" + "\tBodyRange\x12\x14\n" + @@ -11713,7 +11974,19 @@ const file_backuppb_Backup_proto_rawDesc = "" + "\x05emoji\x18\x01 \x01(\tR\x05emoji\x12\x1a\n" + "\bauthorId\x18\x02 \x01(\x04R\bauthorId\x12$\n" + "\rsentTimestamp\x18\x03 \x01(\x04R\rsentTimestamp\x12\x1c\n" + - "\tsortOrder\x18\x04 \x01(\x04R\tsortOrder\"\xe8\x05\n" + + "\tsortOrder\x18\x04 \x01(\x04R\tsortOrder\"\xc8\x02\n" + + "\x04Poll\x12\x1a\n" + + "\bquestion\x18\x01 \x01(\tR\bquestion\x12$\n" + + "\rallowMultiple\x18\x02 \x01(\bR\rallowMultiple\x128\n" + + "\aoptions\x18\x03 \x03(\v2\x1e.signal.backup.Poll.PollOptionR\aoptions\x12\x1a\n" + + "\bhasEnded\x18\x04 \x01(\bR\bhasEnded\x1a\xa7\x01\n" + + "\n" + + "PollOption\x12\x16\n" + + "\x06option\x18\x01 \x01(\tR\x06option\x12=\n" + + "\x05votes\x18\x02 \x03(\v2'.signal.backup.Poll.PollOption.PollVoteR\x05votes\x1aB\n" + + "\bPollVote\x12\x18\n" + + "\avoterId\x18\x01 \x01(\x04R\avoterId\x12\x1c\n" + + "\tvoteCount\x18\x02 \x01(\rR\tvoteCount\"\xb4\x06\n" + "\x11ChatUpdateMessage\x12E\n" + "\fsimpleUpdate\x18\x01 \x01(\v2\x1f.signal.backup.SimpleChatUpdateH\x00R\fsimpleUpdate\x12H\n" + "\vgroupChange\x18\x02 \x01(\v2$.signal.backup.GroupChangeChatUpdateH\x00R\vgroupChange\x12`\n" + @@ -11723,7 +11996,9 @@ const file_backuppb_Backup_proto_rawDesc = "" + "\x11sessionSwitchover\x18\x06 \x01(\v2*.signal.backup.SessionSwitchoverChatUpdateH\x00R\x11sessionSwitchover\x12G\n" + "\x0eindividualCall\x18\a \x01(\v2\x1d.signal.backup.IndividualCallH\x00R\x0eindividualCall\x128\n" + "\tgroupCall\x18\b \x01(\v2\x18.signal.backup.GroupCallH\x00R\tgroupCall\x12]\n" + - "\x14learnedProfileChange\x18\t \x01(\v2'.signal.backup.LearnedProfileChatUpdateH\x00R\x14learnedProfileChangeB\b\n" + + "\x14learnedProfileChange\x18\t \x01(\v2'.signal.backup.LearnedProfileChatUpdateH\x00R\x14learnedProfileChange\x12J\n" + + "\rpollTerminate\x18\n" + + " \x01(\v2\".signal.backup.PollTerminateUpdateH\x00R\rpollTerminateB\b\n" + "\x06update\"\x9d\x04\n" + "\x0eIndividualCall\x12\x1b\n" + "\x06callId\x18\x01 \x01(\x04H\x00R\x06callId\x88\x01\x01\x126\n" + @@ -12028,7 +12303,10 @@ const file_backuppb_Backup_proto_rawDesc = "" + "\n" + "updaterAci\x18\x02 \x01(\fH\x00R\n" + "updaterAci\x88\x01\x01B\r\n" + - "\v_updaterAci\"?\n" + + "\v_updaterAci\"c\n" + + "\x13PollTerminateUpdate\x120\n" + + "\x13targetSentTimestamp\x18\x01 \x01(\x04R\x13targetSentTimestamp\x12\x1a\n" + + "\bquestion\x18\x02 \x01(\tR\bquestion\"?\n" + "\vStickerPack\x12\x16\n" + "\x06packId\x18\x01 \x01(\fR\x06packId\x12\x18\n" + "\apackKey\x18\x02 \x01(\fR\apackKey\"\x80\r\n" + @@ -12188,7 +12466,7 @@ func file_backuppb_Backup_proto_rawDescGZIP() []byte { } var file_backuppb_Backup_proto_enumTypes = make([]protoimpl.EnumInfo, 31) -var file_backuppb_Backup_proto_msgTypes = make([]protoimpl.MessageInfo, 120) +var file_backuppb_Backup_proto_msgTypes = make([]protoimpl.MessageInfo, 124) var file_backuppb_Backup_proto_goTypes = []any{ (AvatarColor)(0), // 0: signal.backup.AvatarColor (GroupV2AccessLevel)(0), // 1: signal.backup.GroupV2AccessLevel @@ -12253,108 +12531,112 @@ var file_backuppb_Backup_proto_goTypes = []any{ (*Quote)(nil), // 60: signal.backup.Quote (*BodyRange)(nil), // 61: signal.backup.BodyRange (*Reaction)(nil), // 62: signal.backup.Reaction - (*ChatUpdateMessage)(nil), // 63: signal.backup.ChatUpdateMessage - (*IndividualCall)(nil), // 64: signal.backup.IndividualCall - (*GroupCall)(nil), // 65: signal.backup.GroupCall - (*SimpleChatUpdate)(nil), // 66: signal.backup.SimpleChatUpdate - (*ExpirationTimerChatUpdate)(nil), // 67: signal.backup.ExpirationTimerChatUpdate - (*ProfileChangeChatUpdate)(nil), // 68: signal.backup.ProfileChangeChatUpdate - (*LearnedProfileChatUpdate)(nil), // 69: signal.backup.LearnedProfileChatUpdate - (*ThreadMergeChatUpdate)(nil), // 70: signal.backup.ThreadMergeChatUpdate - (*SessionSwitchoverChatUpdate)(nil), // 71: signal.backup.SessionSwitchoverChatUpdate - (*GroupChangeChatUpdate)(nil), // 72: signal.backup.GroupChangeChatUpdate - (*GenericGroupUpdate)(nil), // 73: signal.backup.GenericGroupUpdate - (*GroupCreationUpdate)(nil), // 74: signal.backup.GroupCreationUpdate - (*GroupNameUpdate)(nil), // 75: signal.backup.GroupNameUpdate - (*GroupAvatarUpdate)(nil), // 76: signal.backup.GroupAvatarUpdate - (*GroupDescriptionUpdate)(nil), // 77: signal.backup.GroupDescriptionUpdate - (*GroupMembershipAccessLevelChangeUpdate)(nil), // 78: signal.backup.GroupMembershipAccessLevelChangeUpdate - (*GroupAttributesAccessLevelChangeUpdate)(nil), // 79: signal.backup.GroupAttributesAccessLevelChangeUpdate - (*GroupAnnouncementOnlyChangeUpdate)(nil), // 80: signal.backup.GroupAnnouncementOnlyChangeUpdate - (*GroupAdminStatusUpdate)(nil), // 81: signal.backup.GroupAdminStatusUpdate - (*GroupMemberLeftUpdate)(nil), // 82: signal.backup.GroupMemberLeftUpdate - (*GroupMemberRemovedUpdate)(nil), // 83: signal.backup.GroupMemberRemovedUpdate - (*SelfInvitedToGroupUpdate)(nil), // 84: signal.backup.SelfInvitedToGroupUpdate - (*SelfInvitedOtherUserToGroupUpdate)(nil), // 85: signal.backup.SelfInvitedOtherUserToGroupUpdate - (*GroupUnknownInviteeUpdate)(nil), // 86: signal.backup.GroupUnknownInviteeUpdate - (*GroupInvitationAcceptedUpdate)(nil), // 87: signal.backup.GroupInvitationAcceptedUpdate - (*GroupInvitationDeclinedUpdate)(nil), // 88: signal.backup.GroupInvitationDeclinedUpdate - (*GroupMemberJoinedUpdate)(nil), // 89: signal.backup.GroupMemberJoinedUpdate - (*GroupMemberAddedUpdate)(nil), // 90: signal.backup.GroupMemberAddedUpdate - (*GroupSelfInvitationRevokedUpdate)(nil), // 91: signal.backup.GroupSelfInvitationRevokedUpdate - (*GroupInvitationRevokedUpdate)(nil), // 92: signal.backup.GroupInvitationRevokedUpdate - (*GroupJoinRequestUpdate)(nil), // 93: signal.backup.GroupJoinRequestUpdate - (*GroupJoinRequestApprovalUpdate)(nil), // 94: signal.backup.GroupJoinRequestApprovalUpdate - (*GroupJoinRequestCanceledUpdate)(nil), // 95: signal.backup.GroupJoinRequestCanceledUpdate - (*GroupSequenceOfRequestsAndCancelsUpdate)(nil), // 96: signal.backup.GroupSequenceOfRequestsAndCancelsUpdate - (*GroupInviteLinkResetUpdate)(nil), // 97: signal.backup.GroupInviteLinkResetUpdate - (*GroupInviteLinkEnabledUpdate)(nil), // 98: signal.backup.GroupInviteLinkEnabledUpdate - (*GroupInviteLinkAdminApprovalUpdate)(nil), // 99: signal.backup.GroupInviteLinkAdminApprovalUpdate - (*GroupInviteLinkDisabledUpdate)(nil), // 100: signal.backup.GroupInviteLinkDisabledUpdate - (*GroupMemberJoinedByLinkUpdate)(nil), // 101: signal.backup.GroupMemberJoinedByLinkUpdate - (*GroupV2MigrationUpdate)(nil), // 102: signal.backup.GroupV2MigrationUpdate - (*GroupV2MigrationSelfInvitedUpdate)(nil), // 103: signal.backup.GroupV2MigrationSelfInvitedUpdate - (*GroupV2MigrationInvitedMembersUpdate)(nil), // 104: signal.backup.GroupV2MigrationInvitedMembersUpdate - (*GroupV2MigrationDroppedMembersUpdate)(nil), // 105: signal.backup.GroupV2MigrationDroppedMembersUpdate - (*GroupExpirationTimerUpdate)(nil), // 106: signal.backup.GroupExpirationTimerUpdate - (*StickerPack)(nil), // 107: signal.backup.StickerPack - (*ChatStyle)(nil), // 108: signal.backup.ChatStyle - (*NotificationProfile)(nil), // 109: signal.backup.NotificationProfile - (*ChatFolder)(nil), // 110: signal.backup.ChatFolder - (*AccountData_UsernameLink)(nil), // 111: signal.backup.AccountData.UsernameLink - (*AccountData_AccountSettings)(nil), // 112: signal.backup.AccountData.AccountSettings - (*AccountData_SubscriberData)(nil), // 113: signal.backup.AccountData.SubscriberData - (*AccountData_IAPSubscriberData)(nil), // 114: signal.backup.AccountData.IAPSubscriberData - (*Contact_Registered)(nil), // 115: signal.backup.Contact.Registered - (*Contact_NotRegistered)(nil), // 116: signal.backup.Contact.NotRegistered - (*Contact_Name)(nil), // 117: signal.backup.Contact.Name - (*Group_GroupSnapshot)(nil), // 118: signal.backup.Group.GroupSnapshot - (*Group_GroupAttributeBlob)(nil), // 119: signal.backup.Group.GroupAttributeBlob - (*Group_Member)(nil), // 120: signal.backup.Group.Member - (*Group_MemberPendingProfileKey)(nil), // 121: signal.backup.Group.MemberPendingProfileKey - (*Group_MemberPendingAdminApproval)(nil), // 122: signal.backup.Group.MemberPendingAdminApproval - (*Group_MemberBanned)(nil), // 123: signal.backup.Group.MemberBanned - (*Group_AccessControl)(nil), // 124: signal.backup.Group.AccessControl - (*ChatItem_IncomingMessageDetails)(nil), // 125: signal.backup.ChatItem.IncomingMessageDetails - (*ChatItem_OutgoingMessageDetails)(nil), // 126: signal.backup.ChatItem.OutgoingMessageDetails - (*ChatItem_DirectionlessMessageDetails)(nil), // 127: signal.backup.ChatItem.DirectionlessMessageDetails - (*SendStatus_Pending)(nil), // 128: signal.backup.SendStatus.Pending - (*SendStatus_Sent)(nil), // 129: signal.backup.SendStatus.Sent - (*SendStatus_Delivered)(nil), // 130: signal.backup.SendStatus.Delivered - (*SendStatus_Read)(nil), // 131: signal.backup.SendStatus.Read - (*SendStatus_Viewed)(nil), // 132: signal.backup.SendStatus.Viewed - (*SendStatus_Skipped)(nil), // 133: signal.backup.SendStatus.Skipped - (*SendStatus_Failed)(nil), // 134: signal.backup.SendStatus.Failed - (*DirectStoryReplyMessage_TextReply)(nil), // 135: signal.backup.DirectStoryReplyMessage.TextReply - (*PaymentNotification_TransactionDetails)(nil), // 136: signal.backup.PaymentNotification.TransactionDetails - (*PaymentNotification_TransactionDetails_MobileCoinTxoIdentification)(nil), // 137: signal.backup.PaymentNotification.TransactionDetails.MobileCoinTxoIdentification - (*PaymentNotification_TransactionDetails_FailedTransaction)(nil), // 138: signal.backup.PaymentNotification.TransactionDetails.FailedTransaction - (*PaymentNotification_TransactionDetails_Transaction)(nil), // 139: signal.backup.PaymentNotification.TransactionDetails.Transaction - (*ContactAttachment_Name)(nil), // 140: signal.backup.ContactAttachment.Name - (*ContactAttachment_Phone)(nil), // 141: signal.backup.ContactAttachment.Phone - (*ContactAttachment_Email)(nil), // 142: signal.backup.ContactAttachment.Email - (*ContactAttachment_PostalAddress)(nil), // 143: signal.backup.ContactAttachment.PostalAddress - (*FilePointer_LocatorInfo)(nil), // 144: signal.backup.FilePointer.LocatorInfo - (*Quote_QuotedAttachment)(nil), // 145: signal.backup.Quote.QuotedAttachment - (*GroupChangeChatUpdate_Update)(nil), // 146: signal.backup.GroupChangeChatUpdate.Update - (*GroupInvitationRevokedUpdate_Invitee)(nil), // 147: signal.backup.GroupInvitationRevokedUpdate.Invitee - (*ChatStyle_Gradient)(nil), // 148: signal.backup.ChatStyle.Gradient - (*ChatStyle_CustomChatColor)(nil), // 149: signal.backup.ChatStyle.CustomChatColor - (*ChatStyle_AutomaticBubbleColor)(nil), // 150: signal.backup.ChatStyle.AutomaticBubbleColor + (*Poll)(nil), // 63: signal.backup.Poll + (*ChatUpdateMessage)(nil), // 64: signal.backup.ChatUpdateMessage + (*IndividualCall)(nil), // 65: signal.backup.IndividualCall + (*GroupCall)(nil), // 66: signal.backup.GroupCall + (*SimpleChatUpdate)(nil), // 67: signal.backup.SimpleChatUpdate + (*ExpirationTimerChatUpdate)(nil), // 68: signal.backup.ExpirationTimerChatUpdate + (*ProfileChangeChatUpdate)(nil), // 69: signal.backup.ProfileChangeChatUpdate + (*LearnedProfileChatUpdate)(nil), // 70: signal.backup.LearnedProfileChatUpdate + (*ThreadMergeChatUpdate)(nil), // 71: signal.backup.ThreadMergeChatUpdate + (*SessionSwitchoverChatUpdate)(nil), // 72: signal.backup.SessionSwitchoverChatUpdate + (*GroupChangeChatUpdate)(nil), // 73: signal.backup.GroupChangeChatUpdate + (*GenericGroupUpdate)(nil), // 74: signal.backup.GenericGroupUpdate + (*GroupCreationUpdate)(nil), // 75: signal.backup.GroupCreationUpdate + (*GroupNameUpdate)(nil), // 76: signal.backup.GroupNameUpdate + (*GroupAvatarUpdate)(nil), // 77: signal.backup.GroupAvatarUpdate + (*GroupDescriptionUpdate)(nil), // 78: signal.backup.GroupDescriptionUpdate + (*GroupMembershipAccessLevelChangeUpdate)(nil), // 79: signal.backup.GroupMembershipAccessLevelChangeUpdate + (*GroupAttributesAccessLevelChangeUpdate)(nil), // 80: signal.backup.GroupAttributesAccessLevelChangeUpdate + (*GroupAnnouncementOnlyChangeUpdate)(nil), // 81: signal.backup.GroupAnnouncementOnlyChangeUpdate + (*GroupAdminStatusUpdate)(nil), // 82: signal.backup.GroupAdminStatusUpdate + (*GroupMemberLeftUpdate)(nil), // 83: signal.backup.GroupMemberLeftUpdate + (*GroupMemberRemovedUpdate)(nil), // 84: signal.backup.GroupMemberRemovedUpdate + (*SelfInvitedToGroupUpdate)(nil), // 85: signal.backup.SelfInvitedToGroupUpdate + (*SelfInvitedOtherUserToGroupUpdate)(nil), // 86: signal.backup.SelfInvitedOtherUserToGroupUpdate + (*GroupUnknownInviteeUpdate)(nil), // 87: signal.backup.GroupUnknownInviteeUpdate + (*GroupInvitationAcceptedUpdate)(nil), // 88: signal.backup.GroupInvitationAcceptedUpdate + (*GroupInvitationDeclinedUpdate)(nil), // 89: signal.backup.GroupInvitationDeclinedUpdate + (*GroupMemberJoinedUpdate)(nil), // 90: signal.backup.GroupMemberJoinedUpdate + (*GroupMemberAddedUpdate)(nil), // 91: signal.backup.GroupMemberAddedUpdate + (*GroupSelfInvitationRevokedUpdate)(nil), // 92: signal.backup.GroupSelfInvitationRevokedUpdate + (*GroupInvitationRevokedUpdate)(nil), // 93: signal.backup.GroupInvitationRevokedUpdate + (*GroupJoinRequestUpdate)(nil), // 94: signal.backup.GroupJoinRequestUpdate + (*GroupJoinRequestApprovalUpdate)(nil), // 95: signal.backup.GroupJoinRequestApprovalUpdate + (*GroupJoinRequestCanceledUpdate)(nil), // 96: signal.backup.GroupJoinRequestCanceledUpdate + (*GroupSequenceOfRequestsAndCancelsUpdate)(nil), // 97: signal.backup.GroupSequenceOfRequestsAndCancelsUpdate + (*GroupInviteLinkResetUpdate)(nil), // 98: signal.backup.GroupInviteLinkResetUpdate + (*GroupInviteLinkEnabledUpdate)(nil), // 99: signal.backup.GroupInviteLinkEnabledUpdate + (*GroupInviteLinkAdminApprovalUpdate)(nil), // 100: signal.backup.GroupInviteLinkAdminApprovalUpdate + (*GroupInviteLinkDisabledUpdate)(nil), // 101: signal.backup.GroupInviteLinkDisabledUpdate + (*GroupMemberJoinedByLinkUpdate)(nil), // 102: signal.backup.GroupMemberJoinedByLinkUpdate + (*GroupV2MigrationUpdate)(nil), // 103: signal.backup.GroupV2MigrationUpdate + (*GroupV2MigrationSelfInvitedUpdate)(nil), // 104: signal.backup.GroupV2MigrationSelfInvitedUpdate + (*GroupV2MigrationInvitedMembersUpdate)(nil), // 105: signal.backup.GroupV2MigrationInvitedMembersUpdate + (*GroupV2MigrationDroppedMembersUpdate)(nil), // 106: signal.backup.GroupV2MigrationDroppedMembersUpdate + (*GroupExpirationTimerUpdate)(nil), // 107: signal.backup.GroupExpirationTimerUpdate + (*PollTerminateUpdate)(nil), // 108: signal.backup.PollTerminateUpdate + (*StickerPack)(nil), // 109: signal.backup.StickerPack + (*ChatStyle)(nil), // 110: signal.backup.ChatStyle + (*NotificationProfile)(nil), // 111: signal.backup.NotificationProfile + (*ChatFolder)(nil), // 112: signal.backup.ChatFolder + (*AccountData_UsernameLink)(nil), // 113: signal.backup.AccountData.UsernameLink + (*AccountData_AccountSettings)(nil), // 114: signal.backup.AccountData.AccountSettings + (*AccountData_SubscriberData)(nil), // 115: signal.backup.AccountData.SubscriberData + (*AccountData_IAPSubscriberData)(nil), // 116: signal.backup.AccountData.IAPSubscriberData + (*Contact_Registered)(nil), // 117: signal.backup.Contact.Registered + (*Contact_NotRegistered)(nil), // 118: signal.backup.Contact.NotRegistered + (*Contact_Name)(nil), // 119: signal.backup.Contact.Name + (*Group_GroupSnapshot)(nil), // 120: signal.backup.Group.GroupSnapshot + (*Group_GroupAttributeBlob)(nil), // 121: signal.backup.Group.GroupAttributeBlob + (*Group_Member)(nil), // 122: signal.backup.Group.Member + (*Group_MemberPendingProfileKey)(nil), // 123: signal.backup.Group.MemberPendingProfileKey + (*Group_MemberPendingAdminApproval)(nil), // 124: signal.backup.Group.MemberPendingAdminApproval + (*Group_MemberBanned)(nil), // 125: signal.backup.Group.MemberBanned + (*Group_AccessControl)(nil), // 126: signal.backup.Group.AccessControl + (*ChatItem_IncomingMessageDetails)(nil), // 127: signal.backup.ChatItem.IncomingMessageDetails + (*ChatItem_OutgoingMessageDetails)(nil), // 128: signal.backup.ChatItem.OutgoingMessageDetails + (*ChatItem_DirectionlessMessageDetails)(nil), // 129: signal.backup.ChatItem.DirectionlessMessageDetails + (*SendStatus_Pending)(nil), // 130: signal.backup.SendStatus.Pending + (*SendStatus_Sent)(nil), // 131: signal.backup.SendStatus.Sent + (*SendStatus_Delivered)(nil), // 132: signal.backup.SendStatus.Delivered + (*SendStatus_Read)(nil), // 133: signal.backup.SendStatus.Read + (*SendStatus_Viewed)(nil), // 134: signal.backup.SendStatus.Viewed + (*SendStatus_Skipped)(nil), // 135: signal.backup.SendStatus.Skipped + (*SendStatus_Failed)(nil), // 136: signal.backup.SendStatus.Failed + (*DirectStoryReplyMessage_TextReply)(nil), // 137: signal.backup.DirectStoryReplyMessage.TextReply + (*PaymentNotification_TransactionDetails)(nil), // 138: signal.backup.PaymentNotification.TransactionDetails + (*PaymentNotification_TransactionDetails_MobileCoinTxoIdentification)(nil), // 139: signal.backup.PaymentNotification.TransactionDetails.MobileCoinTxoIdentification + (*PaymentNotification_TransactionDetails_FailedTransaction)(nil), // 140: signal.backup.PaymentNotification.TransactionDetails.FailedTransaction + (*PaymentNotification_TransactionDetails_Transaction)(nil), // 141: signal.backup.PaymentNotification.TransactionDetails.Transaction + (*ContactAttachment_Name)(nil), // 142: signal.backup.ContactAttachment.Name + (*ContactAttachment_Phone)(nil), // 143: signal.backup.ContactAttachment.Phone + (*ContactAttachment_Email)(nil), // 144: signal.backup.ContactAttachment.Email + (*ContactAttachment_PostalAddress)(nil), // 145: signal.backup.ContactAttachment.PostalAddress + (*FilePointer_LocatorInfo)(nil), // 146: signal.backup.FilePointer.LocatorInfo + (*Quote_QuotedAttachment)(nil), // 147: signal.backup.Quote.QuotedAttachment + (*Poll_PollOption)(nil), // 148: signal.backup.Poll.PollOption + (*Poll_PollOption_PollVote)(nil), // 149: signal.backup.Poll.PollOption.PollVote + (*GroupChangeChatUpdate_Update)(nil), // 150: signal.backup.GroupChangeChatUpdate.Update + (*GroupInvitationRevokedUpdate_Invitee)(nil), // 151: signal.backup.GroupInvitationRevokedUpdate.Invitee + (*ChatStyle_Gradient)(nil), // 152: signal.backup.ChatStyle.Gradient + (*ChatStyle_CustomChatColor)(nil), // 153: signal.backup.ChatStyle.CustomChatColor + (*ChatStyle_AutomaticBubbleColor)(nil), // 154: signal.backup.ChatStyle.AutomaticBubbleColor } var file_backuppb_Backup_proto_depIdxs = []int32{ 33, // 0: signal.backup.Frame.account:type_name -> signal.backup.AccountData 34, // 1: signal.backup.Frame.recipient:type_name -> signal.backup.Recipient 39, // 2: signal.backup.Frame.chat:type_name -> signal.backup.Chat 44, // 3: signal.backup.Frame.chatItem:type_name -> signal.backup.ChatItem - 107, // 4: signal.backup.Frame.stickerPack:type_name -> signal.backup.StickerPack + 109, // 4: signal.backup.Frame.stickerPack:type_name -> signal.backup.StickerPack 41, // 5: signal.backup.Frame.adHocCall:type_name -> signal.backup.AdHocCall - 109, // 6: signal.backup.Frame.notificationProfile:type_name -> signal.backup.NotificationProfile - 110, // 7: signal.backup.Frame.chatFolder:type_name -> signal.backup.ChatFolder - 111, // 8: signal.backup.AccountData.usernameLink:type_name -> signal.backup.AccountData.UsernameLink - 113, // 9: signal.backup.AccountData.donationSubscriberData:type_name -> signal.backup.AccountData.SubscriberData - 112, // 10: signal.backup.AccountData.accountSettings:type_name -> signal.backup.AccountData.AccountSettings - 114, // 11: signal.backup.AccountData.backupsSubscriberData:type_name -> signal.backup.AccountData.IAPSubscriberData + 111, // 6: signal.backup.Frame.notificationProfile:type_name -> signal.backup.NotificationProfile + 112, // 7: signal.backup.Frame.chatFolder:type_name -> signal.backup.ChatFolder + 113, // 8: signal.backup.AccountData.usernameLink:type_name -> signal.backup.AccountData.UsernameLink + 115, // 9: signal.backup.AccountData.donationSubscriberData:type_name -> signal.backup.AccountData.SubscriberData + 114, // 10: signal.backup.AccountData.accountSettings:type_name -> signal.backup.AccountData.AccountSettings + 116, // 11: signal.backup.AccountData.backupsSubscriberData:type_name -> signal.backup.AccountData.IAPSubscriberData 35, // 12: signal.backup.Recipient.contact:type_name -> signal.backup.Contact 36, // 13: signal.backup.Recipient.group:type_name -> signal.backup.Group 42, // 14: signal.backup.Recipient.distributionList:type_name -> signal.backup.DistributionListItem @@ -12362,165 +12644,169 @@ var file_backuppb_Backup_proto_depIdxs = []int32{ 38, // 16: signal.backup.Recipient.releaseNotes:type_name -> signal.backup.ReleaseNotes 40, // 17: signal.backup.Recipient.callLink:type_name -> signal.backup.CallLink 5, // 18: signal.backup.Contact.visibility:type_name -> signal.backup.Contact.Visibility - 115, // 19: signal.backup.Contact.registered:type_name -> signal.backup.Contact.Registered - 116, // 20: signal.backup.Contact.notRegistered:type_name -> signal.backup.Contact.NotRegistered + 117, // 19: signal.backup.Contact.registered:type_name -> signal.backup.Contact.Registered + 118, // 20: signal.backup.Contact.notRegistered:type_name -> signal.backup.Contact.NotRegistered 4, // 21: signal.backup.Contact.identityState:type_name -> signal.backup.Contact.IdentityState - 117, // 22: signal.backup.Contact.nickname:type_name -> signal.backup.Contact.Name + 119, // 22: signal.backup.Contact.nickname:type_name -> signal.backup.Contact.Name 0, // 23: signal.backup.Contact.avatarColor:type_name -> signal.backup.AvatarColor 6, // 24: signal.backup.Group.storySendMode:type_name -> signal.backup.Group.StorySendMode - 118, // 25: signal.backup.Group.snapshot:type_name -> signal.backup.Group.GroupSnapshot + 120, // 25: signal.backup.Group.snapshot:type_name -> signal.backup.Group.GroupSnapshot 0, // 26: signal.backup.Group.avatarColor:type_name -> signal.backup.AvatarColor 0, // 27: signal.backup.Self.avatarColor:type_name -> signal.backup.AvatarColor - 108, // 28: signal.backup.Chat.style:type_name -> signal.backup.ChatStyle + 110, // 28: signal.backup.Chat.style:type_name -> signal.backup.ChatStyle 9, // 29: signal.backup.CallLink.restrictions:type_name -> signal.backup.CallLink.Restrictions 10, // 30: signal.backup.AdHocCall.state:type_name -> signal.backup.AdHocCall.State 43, // 31: signal.backup.DistributionListItem.distributionList:type_name -> signal.backup.DistributionList 11, // 32: signal.backup.DistributionList.privacyMode:type_name -> signal.backup.DistributionList.PrivacyMode 44, // 33: signal.backup.ChatItem.revisions:type_name -> signal.backup.ChatItem - 125, // 34: signal.backup.ChatItem.incoming:type_name -> signal.backup.ChatItem.IncomingMessageDetails - 126, // 35: signal.backup.ChatItem.outgoing:type_name -> signal.backup.ChatItem.OutgoingMessageDetails - 127, // 36: signal.backup.ChatItem.directionless:type_name -> signal.backup.ChatItem.DirectionlessMessageDetails + 127, // 34: signal.backup.ChatItem.incoming:type_name -> signal.backup.ChatItem.IncomingMessageDetails + 128, // 35: signal.backup.ChatItem.outgoing:type_name -> signal.backup.ChatItem.OutgoingMessageDetails + 129, // 36: signal.backup.ChatItem.directionless:type_name -> signal.backup.ChatItem.DirectionlessMessageDetails 47, // 37: signal.backup.ChatItem.standardMessage:type_name -> signal.backup.StandardMessage 48, // 38: signal.backup.ChatItem.contactMessage:type_name -> signal.backup.ContactMessage 54, // 39: signal.backup.ChatItem.stickerMessage:type_name -> signal.backup.StickerMessage 55, // 40: signal.backup.ChatItem.remoteDeletedMessage:type_name -> signal.backup.RemoteDeletedMessage - 63, // 41: signal.backup.ChatItem.updateMessage:type_name -> signal.backup.ChatUpdateMessage + 64, // 41: signal.backup.ChatItem.updateMessage:type_name -> signal.backup.ChatUpdateMessage 50, // 42: signal.backup.ChatItem.paymentNotification:type_name -> signal.backup.PaymentNotification 51, // 43: signal.backup.ChatItem.giftBadge:type_name -> signal.backup.GiftBadge 52, // 44: signal.backup.ChatItem.viewOnceMessage:type_name -> signal.backup.ViewOnceMessage 49, // 45: signal.backup.ChatItem.directStoryReplyMessage:type_name -> signal.backup.DirectStoryReplyMessage - 128, // 46: signal.backup.SendStatus.pending:type_name -> signal.backup.SendStatus.Pending - 129, // 47: signal.backup.SendStatus.sent:type_name -> signal.backup.SendStatus.Sent - 130, // 48: signal.backup.SendStatus.delivered:type_name -> signal.backup.SendStatus.Delivered - 131, // 49: signal.backup.SendStatus.read:type_name -> signal.backup.SendStatus.Read - 132, // 50: signal.backup.SendStatus.viewed:type_name -> signal.backup.SendStatus.Viewed - 133, // 51: signal.backup.SendStatus.skipped:type_name -> signal.backup.SendStatus.Skipped - 134, // 52: signal.backup.SendStatus.failed:type_name -> signal.backup.SendStatus.Failed - 61, // 53: signal.backup.Text.bodyRanges:type_name -> signal.backup.BodyRange - 60, // 54: signal.backup.StandardMessage.quote:type_name -> signal.backup.Quote - 46, // 55: signal.backup.StandardMessage.text:type_name -> signal.backup.Text - 58, // 56: signal.backup.StandardMessage.attachments:type_name -> signal.backup.MessageAttachment - 57, // 57: signal.backup.StandardMessage.linkPreview:type_name -> signal.backup.LinkPreview - 59, // 58: signal.backup.StandardMessage.longText:type_name -> signal.backup.FilePointer - 62, // 59: signal.backup.StandardMessage.reactions:type_name -> signal.backup.Reaction - 53, // 60: signal.backup.ContactMessage.contact:type_name -> signal.backup.ContactAttachment - 62, // 61: signal.backup.ContactMessage.reactions:type_name -> signal.backup.Reaction - 135, // 62: signal.backup.DirectStoryReplyMessage.textReply:type_name -> signal.backup.DirectStoryReplyMessage.TextReply - 62, // 63: signal.backup.DirectStoryReplyMessage.reactions:type_name -> signal.backup.Reaction - 136, // 64: signal.backup.PaymentNotification.transactionDetails:type_name -> signal.backup.PaymentNotification.TransactionDetails - 15, // 65: signal.backup.GiftBadge.state:type_name -> signal.backup.GiftBadge.State - 58, // 66: signal.backup.ViewOnceMessage.attachment:type_name -> signal.backup.MessageAttachment - 62, // 67: signal.backup.ViewOnceMessage.reactions:type_name -> signal.backup.Reaction - 140, // 68: signal.backup.ContactAttachment.name:type_name -> signal.backup.ContactAttachment.Name - 141, // 69: signal.backup.ContactAttachment.number:type_name -> signal.backup.ContactAttachment.Phone - 142, // 70: signal.backup.ContactAttachment.email:type_name -> signal.backup.ContactAttachment.Email - 143, // 71: signal.backup.ContactAttachment.address:type_name -> signal.backup.ContactAttachment.PostalAddress - 59, // 72: signal.backup.ContactAttachment.avatar:type_name -> signal.backup.FilePointer - 56, // 73: signal.backup.StickerMessage.sticker:type_name -> signal.backup.Sticker - 62, // 74: signal.backup.StickerMessage.reactions:type_name -> signal.backup.Reaction - 59, // 75: signal.backup.Sticker.data:type_name -> signal.backup.FilePointer - 59, // 76: signal.backup.LinkPreview.image:type_name -> signal.backup.FilePointer - 59, // 77: signal.backup.MessageAttachment.pointer:type_name -> signal.backup.FilePointer - 19, // 78: signal.backup.MessageAttachment.flag:type_name -> signal.backup.MessageAttachment.Flag - 144, // 79: signal.backup.FilePointer.locatorInfo:type_name -> signal.backup.FilePointer.LocatorInfo - 46, // 80: signal.backup.Quote.text:type_name -> signal.backup.Text - 145, // 81: signal.backup.Quote.attachments:type_name -> signal.backup.Quote.QuotedAttachment - 20, // 82: signal.backup.Quote.type:type_name -> signal.backup.Quote.Type - 21, // 83: signal.backup.BodyRange.style:type_name -> signal.backup.BodyRange.Style - 66, // 84: signal.backup.ChatUpdateMessage.simpleUpdate:type_name -> signal.backup.SimpleChatUpdate - 72, // 85: signal.backup.ChatUpdateMessage.groupChange:type_name -> signal.backup.GroupChangeChatUpdate - 67, // 86: signal.backup.ChatUpdateMessage.expirationTimerChange:type_name -> signal.backup.ExpirationTimerChatUpdate - 68, // 87: signal.backup.ChatUpdateMessage.profileChange:type_name -> signal.backup.ProfileChangeChatUpdate - 70, // 88: signal.backup.ChatUpdateMessage.threadMerge:type_name -> signal.backup.ThreadMergeChatUpdate - 71, // 89: signal.backup.ChatUpdateMessage.sessionSwitchover:type_name -> signal.backup.SessionSwitchoverChatUpdate - 64, // 90: signal.backup.ChatUpdateMessage.individualCall:type_name -> signal.backup.IndividualCall - 65, // 91: signal.backup.ChatUpdateMessage.groupCall:type_name -> signal.backup.GroupCall - 69, // 92: signal.backup.ChatUpdateMessage.learnedProfileChange:type_name -> signal.backup.LearnedProfileChatUpdate - 22, // 93: signal.backup.IndividualCall.type:type_name -> signal.backup.IndividualCall.Type - 23, // 94: signal.backup.IndividualCall.direction:type_name -> signal.backup.IndividualCall.Direction - 24, // 95: signal.backup.IndividualCall.state:type_name -> signal.backup.IndividualCall.State - 25, // 96: signal.backup.GroupCall.state:type_name -> signal.backup.GroupCall.State - 26, // 97: signal.backup.SimpleChatUpdate.type:type_name -> signal.backup.SimpleChatUpdate.Type - 146, // 98: signal.backup.GroupChangeChatUpdate.updates:type_name -> signal.backup.GroupChangeChatUpdate.Update - 1, // 99: signal.backup.GroupMembershipAccessLevelChangeUpdate.accessLevel:type_name -> signal.backup.GroupV2AccessLevel - 1, // 100: signal.backup.GroupAttributesAccessLevelChangeUpdate.accessLevel:type_name -> signal.backup.GroupV2AccessLevel - 147, // 101: signal.backup.GroupInvitationRevokedUpdate.invitees:type_name -> signal.backup.GroupInvitationRevokedUpdate.Invitee - 27, // 102: signal.backup.ChatStyle.wallpaperPreset:type_name -> signal.backup.ChatStyle.WallpaperPreset - 59, // 103: signal.backup.ChatStyle.wallpaperPhoto:type_name -> signal.backup.FilePointer - 150, // 104: signal.backup.ChatStyle.autoBubbleColor:type_name -> signal.backup.ChatStyle.AutomaticBubbleColor - 28, // 105: signal.backup.ChatStyle.bubbleColorPreset:type_name -> signal.backup.ChatStyle.BubbleColorPreset - 29, // 106: signal.backup.NotificationProfile.scheduleDaysEnabled:type_name -> signal.backup.NotificationProfile.DayOfWeek - 30, // 107: signal.backup.ChatFolder.folderType:type_name -> signal.backup.ChatFolder.FolderType - 3, // 108: signal.backup.AccountData.UsernameLink.color:type_name -> signal.backup.AccountData.UsernameLink.Color - 2, // 109: signal.backup.AccountData.AccountSettings.phoneNumberSharingMode:type_name -> signal.backup.AccountData.PhoneNumberSharingMode - 108, // 110: signal.backup.AccountData.AccountSettings.defaultChatStyle:type_name -> signal.backup.ChatStyle - 149, // 111: signal.backup.AccountData.AccountSettings.customChatColors:type_name -> signal.backup.ChatStyle.CustomChatColor - 119, // 112: signal.backup.Group.GroupSnapshot.title:type_name -> signal.backup.Group.GroupAttributeBlob - 119, // 113: signal.backup.Group.GroupSnapshot.description:type_name -> signal.backup.Group.GroupAttributeBlob - 119, // 114: signal.backup.Group.GroupSnapshot.disappearingMessagesTimer:type_name -> signal.backup.Group.GroupAttributeBlob - 124, // 115: signal.backup.Group.GroupSnapshot.accessControl:type_name -> signal.backup.Group.AccessControl - 120, // 116: signal.backup.Group.GroupSnapshot.members:type_name -> signal.backup.Group.Member - 121, // 117: signal.backup.Group.GroupSnapshot.membersPendingProfileKey:type_name -> signal.backup.Group.MemberPendingProfileKey - 122, // 118: signal.backup.Group.GroupSnapshot.membersPendingAdminApproval:type_name -> signal.backup.Group.MemberPendingAdminApproval - 123, // 119: signal.backup.Group.GroupSnapshot.members_banned:type_name -> signal.backup.Group.MemberBanned - 7, // 120: signal.backup.Group.Member.role:type_name -> signal.backup.Group.Member.Role - 120, // 121: signal.backup.Group.MemberPendingProfileKey.member:type_name -> signal.backup.Group.Member - 8, // 122: signal.backup.Group.AccessControl.attributes:type_name -> signal.backup.Group.AccessControl.AccessRequired - 8, // 123: signal.backup.Group.AccessControl.members:type_name -> signal.backup.Group.AccessControl.AccessRequired - 8, // 124: signal.backup.Group.AccessControl.addFromInviteLink:type_name -> signal.backup.Group.AccessControl.AccessRequired - 45, // 125: signal.backup.ChatItem.OutgoingMessageDetails.sendStatus:type_name -> signal.backup.SendStatus - 12, // 126: signal.backup.SendStatus.Failed.reason:type_name -> signal.backup.SendStatus.Failed.FailureReason - 46, // 127: signal.backup.DirectStoryReplyMessage.TextReply.text:type_name -> signal.backup.Text - 59, // 128: signal.backup.DirectStoryReplyMessage.TextReply.longText:type_name -> signal.backup.FilePointer - 139, // 129: signal.backup.PaymentNotification.TransactionDetails.transaction:type_name -> signal.backup.PaymentNotification.TransactionDetails.Transaction - 138, // 130: signal.backup.PaymentNotification.TransactionDetails.failedTransaction:type_name -> signal.backup.PaymentNotification.TransactionDetails.FailedTransaction - 13, // 131: signal.backup.PaymentNotification.TransactionDetails.FailedTransaction.reason:type_name -> signal.backup.PaymentNotification.TransactionDetails.FailedTransaction.FailureReason - 14, // 132: signal.backup.PaymentNotification.TransactionDetails.Transaction.status:type_name -> signal.backup.PaymentNotification.TransactionDetails.Transaction.Status - 137, // 133: signal.backup.PaymentNotification.TransactionDetails.Transaction.mobileCoinIdentification:type_name -> signal.backup.PaymentNotification.TransactionDetails.MobileCoinTxoIdentification - 16, // 134: signal.backup.ContactAttachment.Phone.type:type_name -> signal.backup.ContactAttachment.Phone.Type - 17, // 135: signal.backup.ContactAttachment.Email.type:type_name -> signal.backup.ContactAttachment.Email.Type - 18, // 136: signal.backup.ContactAttachment.PostalAddress.type:type_name -> signal.backup.ContactAttachment.PostalAddress.Type - 58, // 137: signal.backup.Quote.QuotedAttachment.thumbnail:type_name -> signal.backup.MessageAttachment - 73, // 138: signal.backup.GroupChangeChatUpdate.Update.genericGroupUpdate:type_name -> signal.backup.GenericGroupUpdate - 74, // 139: signal.backup.GroupChangeChatUpdate.Update.groupCreationUpdate:type_name -> signal.backup.GroupCreationUpdate - 75, // 140: signal.backup.GroupChangeChatUpdate.Update.groupNameUpdate:type_name -> signal.backup.GroupNameUpdate - 76, // 141: signal.backup.GroupChangeChatUpdate.Update.groupAvatarUpdate:type_name -> signal.backup.GroupAvatarUpdate - 77, // 142: signal.backup.GroupChangeChatUpdate.Update.groupDescriptionUpdate:type_name -> signal.backup.GroupDescriptionUpdate - 78, // 143: signal.backup.GroupChangeChatUpdate.Update.groupMembershipAccessLevelChangeUpdate:type_name -> signal.backup.GroupMembershipAccessLevelChangeUpdate - 79, // 144: signal.backup.GroupChangeChatUpdate.Update.groupAttributesAccessLevelChangeUpdate:type_name -> signal.backup.GroupAttributesAccessLevelChangeUpdate - 80, // 145: signal.backup.GroupChangeChatUpdate.Update.groupAnnouncementOnlyChangeUpdate:type_name -> signal.backup.GroupAnnouncementOnlyChangeUpdate - 81, // 146: signal.backup.GroupChangeChatUpdate.Update.groupAdminStatusUpdate:type_name -> signal.backup.GroupAdminStatusUpdate - 82, // 147: signal.backup.GroupChangeChatUpdate.Update.groupMemberLeftUpdate:type_name -> signal.backup.GroupMemberLeftUpdate - 83, // 148: signal.backup.GroupChangeChatUpdate.Update.groupMemberRemovedUpdate:type_name -> signal.backup.GroupMemberRemovedUpdate - 84, // 149: signal.backup.GroupChangeChatUpdate.Update.selfInvitedToGroupUpdate:type_name -> signal.backup.SelfInvitedToGroupUpdate - 85, // 150: signal.backup.GroupChangeChatUpdate.Update.selfInvitedOtherUserToGroupUpdate:type_name -> signal.backup.SelfInvitedOtherUserToGroupUpdate - 86, // 151: signal.backup.GroupChangeChatUpdate.Update.groupUnknownInviteeUpdate:type_name -> signal.backup.GroupUnknownInviteeUpdate - 87, // 152: signal.backup.GroupChangeChatUpdate.Update.groupInvitationAcceptedUpdate:type_name -> signal.backup.GroupInvitationAcceptedUpdate - 88, // 153: signal.backup.GroupChangeChatUpdate.Update.groupInvitationDeclinedUpdate:type_name -> signal.backup.GroupInvitationDeclinedUpdate - 89, // 154: signal.backup.GroupChangeChatUpdate.Update.groupMemberJoinedUpdate:type_name -> signal.backup.GroupMemberJoinedUpdate - 90, // 155: signal.backup.GroupChangeChatUpdate.Update.groupMemberAddedUpdate:type_name -> signal.backup.GroupMemberAddedUpdate - 91, // 156: signal.backup.GroupChangeChatUpdate.Update.groupSelfInvitationRevokedUpdate:type_name -> signal.backup.GroupSelfInvitationRevokedUpdate - 92, // 157: signal.backup.GroupChangeChatUpdate.Update.groupInvitationRevokedUpdate:type_name -> signal.backup.GroupInvitationRevokedUpdate - 93, // 158: signal.backup.GroupChangeChatUpdate.Update.groupJoinRequestUpdate:type_name -> signal.backup.GroupJoinRequestUpdate - 94, // 159: signal.backup.GroupChangeChatUpdate.Update.groupJoinRequestApprovalUpdate:type_name -> signal.backup.GroupJoinRequestApprovalUpdate - 95, // 160: signal.backup.GroupChangeChatUpdate.Update.groupJoinRequestCanceledUpdate:type_name -> signal.backup.GroupJoinRequestCanceledUpdate - 97, // 161: signal.backup.GroupChangeChatUpdate.Update.groupInviteLinkResetUpdate:type_name -> signal.backup.GroupInviteLinkResetUpdate - 98, // 162: signal.backup.GroupChangeChatUpdate.Update.groupInviteLinkEnabledUpdate:type_name -> signal.backup.GroupInviteLinkEnabledUpdate - 99, // 163: signal.backup.GroupChangeChatUpdate.Update.groupInviteLinkAdminApprovalUpdate:type_name -> signal.backup.GroupInviteLinkAdminApprovalUpdate - 100, // 164: signal.backup.GroupChangeChatUpdate.Update.groupInviteLinkDisabledUpdate:type_name -> signal.backup.GroupInviteLinkDisabledUpdate - 101, // 165: signal.backup.GroupChangeChatUpdate.Update.groupMemberJoinedByLinkUpdate:type_name -> signal.backup.GroupMemberJoinedByLinkUpdate - 102, // 166: signal.backup.GroupChangeChatUpdate.Update.groupV2MigrationUpdate:type_name -> signal.backup.GroupV2MigrationUpdate - 103, // 167: signal.backup.GroupChangeChatUpdate.Update.groupV2MigrationSelfInvitedUpdate:type_name -> signal.backup.GroupV2MigrationSelfInvitedUpdate - 104, // 168: signal.backup.GroupChangeChatUpdate.Update.groupV2MigrationInvitedMembersUpdate:type_name -> signal.backup.GroupV2MigrationInvitedMembersUpdate - 105, // 169: signal.backup.GroupChangeChatUpdate.Update.groupV2MigrationDroppedMembersUpdate:type_name -> signal.backup.GroupV2MigrationDroppedMembersUpdate - 96, // 170: signal.backup.GroupChangeChatUpdate.Update.groupSequenceOfRequestsAndCancelsUpdate:type_name -> signal.backup.GroupSequenceOfRequestsAndCancelsUpdate - 106, // 171: signal.backup.GroupChangeChatUpdate.Update.groupExpirationTimerUpdate:type_name -> signal.backup.GroupExpirationTimerUpdate - 148, // 172: signal.backup.ChatStyle.CustomChatColor.gradient:type_name -> signal.backup.ChatStyle.Gradient - 173, // [173:173] is the sub-list for method output_type - 173, // [173:173] is the sub-list for method input_type - 173, // [173:173] is the sub-list for extension type_name - 173, // [173:173] is the sub-list for extension extendee - 0, // [0:173] is the sub-list for field type_name + 63, // 46: signal.backup.ChatItem.poll:type_name -> signal.backup.Poll + 130, // 47: signal.backup.SendStatus.pending:type_name -> signal.backup.SendStatus.Pending + 131, // 48: signal.backup.SendStatus.sent:type_name -> signal.backup.SendStatus.Sent + 132, // 49: signal.backup.SendStatus.delivered:type_name -> signal.backup.SendStatus.Delivered + 133, // 50: signal.backup.SendStatus.read:type_name -> signal.backup.SendStatus.Read + 134, // 51: signal.backup.SendStatus.viewed:type_name -> signal.backup.SendStatus.Viewed + 135, // 52: signal.backup.SendStatus.skipped:type_name -> signal.backup.SendStatus.Skipped + 136, // 53: signal.backup.SendStatus.failed:type_name -> signal.backup.SendStatus.Failed + 61, // 54: signal.backup.Text.bodyRanges:type_name -> signal.backup.BodyRange + 60, // 55: signal.backup.StandardMessage.quote:type_name -> signal.backup.Quote + 46, // 56: signal.backup.StandardMessage.text:type_name -> signal.backup.Text + 58, // 57: signal.backup.StandardMessage.attachments:type_name -> signal.backup.MessageAttachment + 57, // 58: signal.backup.StandardMessage.linkPreview:type_name -> signal.backup.LinkPreview + 59, // 59: signal.backup.StandardMessage.longText:type_name -> signal.backup.FilePointer + 62, // 60: signal.backup.StandardMessage.reactions:type_name -> signal.backup.Reaction + 53, // 61: signal.backup.ContactMessage.contact:type_name -> signal.backup.ContactAttachment + 62, // 62: signal.backup.ContactMessage.reactions:type_name -> signal.backup.Reaction + 137, // 63: signal.backup.DirectStoryReplyMessage.textReply:type_name -> signal.backup.DirectStoryReplyMessage.TextReply + 62, // 64: signal.backup.DirectStoryReplyMessage.reactions:type_name -> signal.backup.Reaction + 138, // 65: signal.backup.PaymentNotification.transactionDetails:type_name -> signal.backup.PaymentNotification.TransactionDetails + 15, // 66: signal.backup.GiftBadge.state:type_name -> signal.backup.GiftBadge.State + 58, // 67: signal.backup.ViewOnceMessage.attachment:type_name -> signal.backup.MessageAttachment + 62, // 68: signal.backup.ViewOnceMessage.reactions:type_name -> signal.backup.Reaction + 142, // 69: signal.backup.ContactAttachment.name:type_name -> signal.backup.ContactAttachment.Name + 143, // 70: signal.backup.ContactAttachment.number:type_name -> signal.backup.ContactAttachment.Phone + 144, // 71: signal.backup.ContactAttachment.email:type_name -> signal.backup.ContactAttachment.Email + 145, // 72: signal.backup.ContactAttachment.address:type_name -> signal.backup.ContactAttachment.PostalAddress + 59, // 73: signal.backup.ContactAttachment.avatar:type_name -> signal.backup.FilePointer + 56, // 74: signal.backup.StickerMessage.sticker:type_name -> signal.backup.Sticker + 62, // 75: signal.backup.StickerMessage.reactions:type_name -> signal.backup.Reaction + 59, // 76: signal.backup.Sticker.data:type_name -> signal.backup.FilePointer + 59, // 77: signal.backup.LinkPreview.image:type_name -> signal.backup.FilePointer + 59, // 78: signal.backup.MessageAttachment.pointer:type_name -> signal.backup.FilePointer + 19, // 79: signal.backup.MessageAttachment.flag:type_name -> signal.backup.MessageAttachment.Flag + 146, // 80: signal.backup.FilePointer.locatorInfo:type_name -> signal.backup.FilePointer.LocatorInfo + 46, // 81: signal.backup.Quote.text:type_name -> signal.backup.Text + 147, // 82: signal.backup.Quote.attachments:type_name -> signal.backup.Quote.QuotedAttachment + 20, // 83: signal.backup.Quote.type:type_name -> signal.backup.Quote.Type + 21, // 84: signal.backup.BodyRange.style:type_name -> signal.backup.BodyRange.Style + 148, // 85: signal.backup.Poll.options:type_name -> signal.backup.Poll.PollOption + 67, // 86: signal.backup.ChatUpdateMessage.simpleUpdate:type_name -> signal.backup.SimpleChatUpdate + 73, // 87: signal.backup.ChatUpdateMessage.groupChange:type_name -> signal.backup.GroupChangeChatUpdate + 68, // 88: signal.backup.ChatUpdateMessage.expirationTimerChange:type_name -> signal.backup.ExpirationTimerChatUpdate + 69, // 89: signal.backup.ChatUpdateMessage.profileChange:type_name -> signal.backup.ProfileChangeChatUpdate + 71, // 90: signal.backup.ChatUpdateMessage.threadMerge:type_name -> signal.backup.ThreadMergeChatUpdate + 72, // 91: signal.backup.ChatUpdateMessage.sessionSwitchover:type_name -> signal.backup.SessionSwitchoverChatUpdate + 65, // 92: signal.backup.ChatUpdateMessage.individualCall:type_name -> signal.backup.IndividualCall + 66, // 93: signal.backup.ChatUpdateMessage.groupCall:type_name -> signal.backup.GroupCall + 70, // 94: signal.backup.ChatUpdateMessage.learnedProfileChange:type_name -> signal.backup.LearnedProfileChatUpdate + 108, // 95: signal.backup.ChatUpdateMessage.pollTerminate:type_name -> signal.backup.PollTerminateUpdate + 22, // 96: signal.backup.IndividualCall.type:type_name -> signal.backup.IndividualCall.Type + 23, // 97: signal.backup.IndividualCall.direction:type_name -> signal.backup.IndividualCall.Direction + 24, // 98: signal.backup.IndividualCall.state:type_name -> signal.backup.IndividualCall.State + 25, // 99: signal.backup.GroupCall.state:type_name -> signal.backup.GroupCall.State + 26, // 100: signal.backup.SimpleChatUpdate.type:type_name -> signal.backup.SimpleChatUpdate.Type + 150, // 101: signal.backup.GroupChangeChatUpdate.updates:type_name -> signal.backup.GroupChangeChatUpdate.Update + 1, // 102: signal.backup.GroupMembershipAccessLevelChangeUpdate.accessLevel:type_name -> signal.backup.GroupV2AccessLevel + 1, // 103: signal.backup.GroupAttributesAccessLevelChangeUpdate.accessLevel:type_name -> signal.backup.GroupV2AccessLevel + 151, // 104: signal.backup.GroupInvitationRevokedUpdate.invitees:type_name -> signal.backup.GroupInvitationRevokedUpdate.Invitee + 27, // 105: signal.backup.ChatStyle.wallpaperPreset:type_name -> signal.backup.ChatStyle.WallpaperPreset + 59, // 106: signal.backup.ChatStyle.wallpaperPhoto:type_name -> signal.backup.FilePointer + 154, // 107: signal.backup.ChatStyle.autoBubbleColor:type_name -> signal.backup.ChatStyle.AutomaticBubbleColor + 28, // 108: signal.backup.ChatStyle.bubbleColorPreset:type_name -> signal.backup.ChatStyle.BubbleColorPreset + 29, // 109: signal.backup.NotificationProfile.scheduleDaysEnabled:type_name -> signal.backup.NotificationProfile.DayOfWeek + 30, // 110: signal.backup.ChatFolder.folderType:type_name -> signal.backup.ChatFolder.FolderType + 3, // 111: signal.backup.AccountData.UsernameLink.color:type_name -> signal.backup.AccountData.UsernameLink.Color + 2, // 112: signal.backup.AccountData.AccountSettings.phoneNumberSharingMode:type_name -> signal.backup.AccountData.PhoneNumberSharingMode + 110, // 113: signal.backup.AccountData.AccountSettings.defaultChatStyle:type_name -> signal.backup.ChatStyle + 153, // 114: signal.backup.AccountData.AccountSettings.customChatColors:type_name -> signal.backup.ChatStyle.CustomChatColor + 121, // 115: signal.backup.Group.GroupSnapshot.title:type_name -> signal.backup.Group.GroupAttributeBlob + 121, // 116: signal.backup.Group.GroupSnapshot.description:type_name -> signal.backup.Group.GroupAttributeBlob + 121, // 117: signal.backup.Group.GroupSnapshot.disappearingMessagesTimer:type_name -> signal.backup.Group.GroupAttributeBlob + 126, // 118: signal.backup.Group.GroupSnapshot.accessControl:type_name -> signal.backup.Group.AccessControl + 122, // 119: signal.backup.Group.GroupSnapshot.members:type_name -> signal.backup.Group.Member + 123, // 120: signal.backup.Group.GroupSnapshot.membersPendingProfileKey:type_name -> signal.backup.Group.MemberPendingProfileKey + 124, // 121: signal.backup.Group.GroupSnapshot.membersPendingAdminApproval:type_name -> signal.backup.Group.MemberPendingAdminApproval + 125, // 122: signal.backup.Group.GroupSnapshot.members_banned:type_name -> signal.backup.Group.MemberBanned + 7, // 123: signal.backup.Group.Member.role:type_name -> signal.backup.Group.Member.Role + 122, // 124: signal.backup.Group.MemberPendingProfileKey.member:type_name -> signal.backup.Group.Member + 8, // 125: signal.backup.Group.AccessControl.attributes:type_name -> signal.backup.Group.AccessControl.AccessRequired + 8, // 126: signal.backup.Group.AccessControl.members:type_name -> signal.backup.Group.AccessControl.AccessRequired + 8, // 127: signal.backup.Group.AccessControl.addFromInviteLink:type_name -> signal.backup.Group.AccessControl.AccessRequired + 45, // 128: signal.backup.ChatItem.OutgoingMessageDetails.sendStatus:type_name -> signal.backup.SendStatus + 12, // 129: signal.backup.SendStatus.Failed.reason:type_name -> signal.backup.SendStatus.Failed.FailureReason + 46, // 130: signal.backup.DirectStoryReplyMessage.TextReply.text:type_name -> signal.backup.Text + 59, // 131: signal.backup.DirectStoryReplyMessage.TextReply.longText:type_name -> signal.backup.FilePointer + 141, // 132: signal.backup.PaymentNotification.TransactionDetails.transaction:type_name -> signal.backup.PaymentNotification.TransactionDetails.Transaction + 140, // 133: signal.backup.PaymentNotification.TransactionDetails.failedTransaction:type_name -> signal.backup.PaymentNotification.TransactionDetails.FailedTransaction + 13, // 134: signal.backup.PaymentNotification.TransactionDetails.FailedTransaction.reason:type_name -> signal.backup.PaymentNotification.TransactionDetails.FailedTransaction.FailureReason + 14, // 135: signal.backup.PaymentNotification.TransactionDetails.Transaction.status:type_name -> signal.backup.PaymentNotification.TransactionDetails.Transaction.Status + 139, // 136: signal.backup.PaymentNotification.TransactionDetails.Transaction.mobileCoinIdentification:type_name -> signal.backup.PaymentNotification.TransactionDetails.MobileCoinTxoIdentification + 16, // 137: signal.backup.ContactAttachment.Phone.type:type_name -> signal.backup.ContactAttachment.Phone.Type + 17, // 138: signal.backup.ContactAttachment.Email.type:type_name -> signal.backup.ContactAttachment.Email.Type + 18, // 139: signal.backup.ContactAttachment.PostalAddress.type:type_name -> signal.backup.ContactAttachment.PostalAddress.Type + 58, // 140: signal.backup.Quote.QuotedAttachment.thumbnail:type_name -> signal.backup.MessageAttachment + 149, // 141: signal.backup.Poll.PollOption.votes:type_name -> signal.backup.Poll.PollOption.PollVote + 74, // 142: signal.backup.GroupChangeChatUpdate.Update.genericGroupUpdate:type_name -> signal.backup.GenericGroupUpdate + 75, // 143: signal.backup.GroupChangeChatUpdate.Update.groupCreationUpdate:type_name -> signal.backup.GroupCreationUpdate + 76, // 144: signal.backup.GroupChangeChatUpdate.Update.groupNameUpdate:type_name -> signal.backup.GroupNameUpdate + 77, // 145: signal.backup.GroupChangeChatUpdate.Update.groupAvatarUpdate:type_name -> signal.backup.GroupAvatarUpdate + 78, // 146: signal.backup.GroupChangeChatUpdate.Update.groupDescriptionUpdate:type_name -> signal.backup.GroupDescriptionUpdate + 79, // 147: signal.backup.GroupChangeChatUpdate.Update.groupMembershipAccessLevelChangeUpdate:type_name -> signal.backup.GroupMembershipAccessLevelChangeUpdate + 80, // 148: signal.backup.GroupChangeChatUpdate.Update.groupAttributesAccessLevelChangeUpdate:type_name -> signal.backup.GroupAttributesAccessLevelChangeUpdate + 81, // 149: signal.backup.GroupChangeChatUpdate.Update.groupAnnouncementOnlyChangeUpdate:type_name -> signal.backup.GroupAnnouncementOnlyChangeUpdate + 82, // 150: signal.backup.GroupChangeChatUpdate.Update.groupAdminStatusUpdate:type_name -> signal.backup.GroupAdminStatusUpdate + 83, // 151: signal.backup.GroupChangeChatUpdate.Update.groupMemberLeftUpdate:type_name -> signal.backup.GroupMemberLeftUpdate + 84, // 152: signal.backup.GroupChangeChatUpdate.Update.groupMemberRemovedUpdate:type_name -> signal.backup.GroupMemberRemovedUpdate + 85, // 153: signal.backup.GroupChangeChatUpdate.Update.selfInvitedToGroupUpdate:type_name -> signal.backup.SelfInvitedToGroupUpdate + 86, // 154: signal.backup.GroupChangeChatUpdate.Update.selfInvitedOtherUserToGroupUpdate:type_name -> signal.backup.SelfInvitedOtherUserToGroupUpdate + 87, // 155: signal.backup.GroupChangeChatUpdate.Update.groupUnknownInviteeUpdate:type_name -> signal.backup.GroupUnknownInviteeUpdate + 88, // 156: signal.backup.GroupChangeChatUpdate.Update.groupInvitationAcceptedUpdate:type_name -> signal.backup.GroupInvitationAcceptedUpdate + 89, // 157: signal.backup.GroupChangeChatUpdate.Update.groupInvitationDeclinedUpdate:type_name -> signal.backup.GroupInvitationDeclinedUpdate + 90, // 158: signal.backup.GroupChangeChatUpdate.Update.groupMemberJoinedUpdate:type_name -> signal.backup.GroupMemberJoinedUpdate + 91, // 159: signal.backup.GroupChangeChatUpdate.Update.groupMemberAddedUpdate:type_name -> signal.backup.GroupMemberAddedUpdate + 92, // 160: signal.backup.GroupChangeChatUpdate.Update.groupSelfInvitationRevokedUpdate:type_name -> signal.backup.GroupSelfInvitationRevokedUpdate + 93, // 161: signal.backup.GroupChangeChatUpdate.Update.groupInvitationRevokedUpdate:type_name -> signal.backup.GroupInvitationRevokedUpdate + 94, // 162: signal.backup.GroupChangeChatUpdate.Update.groupJoinRequestUpdate:type_name -> signal.backup.GroupJoinRequestUpdate + 95, // 163: signal.backup.GroupChangeChatUpdate.Update.groupJoinRequestApprovalUpdate:type_name -> signal.backup.GroupJoinRequestApprovalUpdate + 96, // 164: signal.backup.GroupChangeChatUpdate.Update.groupJoinRequestCanceledUpdate:type_name -> signal.backup.GroupJoinRequestCanceledUpdate + 98, // 165: signal.backup.GroupChangeChatUpdate.Update.groupInviteLinkResetUpdate:type_name -> signal.backup.GroupInviteLinkResetUpdate + 99, // 166: signal.backup.GroupChangeChatUpdate.Update.groupInviteLinkEnabledUpdate:type_name -> signal.backup.GroupInviteLinkEnabledUpdate + 100, // 167: signal.backup.GroupChangeChatUpdate.Update.groupInviteLinkAdminApprovalUpdate:type_name -> signal.backup.GroupInviteLinkAdminApprovalUpdate + 101, // 168: signal.backup.GroupChangeChatUpdate.Update.groupInviteLinkDisabledUpdate:type_name -> signal.backup.GroupInviteLinkDisabledUpdate + 102, // 169: signal.backup.GroupChangeChatUpdate.Update.groupMemberJoinedByLinkUpdate:type_name -> signal.backup.GroupMemberJoinedByLinkUpdate + 103, // 170: signal.backup.GroupChangeChatUpdate.Update.groupV2MigrationUpdate:type_name -> signal.backup.GroupV2MigrationUpdate + 104, // 171: signal.backup.GroupChangeChatUpdate.Update.groupV2MigrationSelfInvitedUpdate:type_name -> signal.backup.GroupV2MigrationSelfInvitedUpdate + 105, // 172: signal.backup.GroupChangeChatUpdate.Update.groupV2MigrationInvitedMembersUpdate:type_name -> signal.backup.GroupV2MigrationInvitedMembersUpdate + 106, // 173: signal.backup.GroupChangeChatUpdate.Update.groupV2MigrationDroppedMembersUpdate:type_name -> signal.backup.GroupV2MigrationDroppedMembersUpdate + 97, // 174: signal.backup.GroupChangeChatUpdate.Update.groupSequenceOfRequestsAndCancelsUpdate:type_name -> signal.backup.GroupSequenceOfRequestsAndCancelsUpdate + 107, // 175: signal.backup.GroupChangeChatUpdate.Update.groupExpirationTimerUpdate:type_name -> signal.backup.GroupExpirationTimerUpdate + 152, // 176: signal.backup.ChatStyle.CustomChatColor.gradient:type_name -> signal.backup.ChatStyle.Gradient + 177, // [177:177] is the sub-list for method output_type + 177, // [177:177] is the sub-list for method input_type + 177, // [177:177] is the sub-list for extension type_name + 177, // [177:177] is the sub-list for extension extendee + 0, // [0:177] is the sub-list for field type_name } func init() { file_backuppb_Backup_proto_init() } @@ -12572,6 +12858,7 @@ func file_backuppb_Backup_proto_init() { (*ChatItem_GiftBadge)(nil), (*ChatItem_ViewOnceMessage)(nil), (*ChatItem_DirectStoryReplyMessage)(nil), + (*ChatItem_Poll)(nil), } file_backuppb_Backup_proto_msgTypes[14].OneofWrappers = []any{ (*SendStatus_Pending_)(nil), @@ -12598,7 +12885,7 @@ func file_backuppb_Backup_proto_init() { (*BodyRange_MentionAci)(nil), (*BodyRange_Style_)(nil), } - file_backuppb_Backup_proto_msgTypes[32].OneofWrappers = []any{ + file_backuppb_Backup_proto_msgTypes[33].OneofWrappers = []any{ (*ChatUpdateMessage_SimpleUpdate)(nil), (*ChatUpdateMessage_GroupChange)(nil), (*ChatUpdateMessage_ExpirationTimerChange)(nil), @@ -12608,14 +12895,14 @@ func file_backuppb_Backup_proto_init() { (*ChatUpdateMessage_IndividualCall)(nil), (*ChatUpdateMessage_GroupCall)(nil), (*ChatUpdateMessage_LearnedProfileChange)(nil), + (*ChatUpdateMessage_PollTerminate)(nil), } - file_backuppb_Backup_proto_msgTypes[33].OneofWrappers = []any{} file_backuppb_Backup_proto_msgTypes[34].OneofWrappers = []any{} - file_backuppb_Backup_proto_msgTypes[38].OneofWrappers = []any{ + file_backuppb_Backup_proto_msgTypes[35].OneofWrappers = []any{} + file_backuppb_Backup_proto_msgTypes[39].OneofWrappers = []any{ (*LearnedProfileChatUpdate_E164)(nil), (*LearnedProfileChatUpdate_Username)(nil), } - file_backuppb_Backup_proto_msgTypes[42].OneofWrappers = []any{} file_backuppb_Backup_proto_msgTypes[43].OneofWrappers = []any{} file_backuppb_Backup_proto_msgTypes[44].OneofWrappers = []any{} file_backuppb_Backup_proto_msgTypes[45].OneofWrappers = []any{} @@ -12624,51 +12911,52 @@ func file_backuppb_Backup_proto_init() { file_backuppb_Backup_proto_msgTypes[48].OneofWrappers = []any{} file_backuppb_Backup_proto_msgTypes[49].OneofWrappers = []any{} file_backuppb_Backup_proto_msgTypes[50].OneofWrappers = []any{} - file_backuppb_Backup_proto_msgTypes[52].OneofWrappers = []any{} + file_backuppb_Backup_proto_msgTypes[51].OneofWrappers = []any{} file_backuppb_Backup_proto_msgTypes[53].OneofWrappers = []any{} - file_backuppb_Backup_proto_msgTypes[55].OneofWrappers = []any{} + file_backuppb_Backup_proto_msgTypes[54].OneofWrappers = []any{} file_backuppb_Backup_proto_msgTypes[56].OneofWrappers = []any{} file_backuppb_Backup_proto_msgTypes[57].OneofWrappers = []any{} - file_backuppb_Backup_proto_msgTypes[59].OneofWrappers = []any{} + file_backuppb_Backup_proto_msgTypes[58].OneofWrappers = []any{} file_backuppb_Backup_proto_msgTypes[60].OneofWrappers = []any{} file_backuppb_Backup_proto_msgTypes[61].OneofWrappers = []any{} - file_backuppb_Backup_proto_msgTypes[63].OneofWrappers = []any{} - file_backuppb_Backup_proto_msgTypes[66].OneofWrappers = []any{} + file_backuppb_Backup_proto_msgTypes[62].OneofWrappers = []any{} + file_backuppb_Backup_proto_msgTypes[64].OneofWrappers = []any{} file_backuppb_Backup_proto_msgTypes[67].OneofWrappers = []any{} file_backuppb_Backup_proto_msgTypes[68].OneofWrappers = []any{} file_backuppb_Backup_proto_msgTypes[69].OneofWrappers = []any{} - file_backuppb_Backup_proto_msgTypes[75].OneofWrappers = []any{} - file_backuppb_Backup_proto_msgTypes[77].OneofWrappers = []any{ + file_backuppb_Backup_proto_msgTypes[70].OneofWrappers = []any{} + file_backuppb_Backup_proto_msgTypes[76].OneofWrappers = []any{} + file_backuppb_Backup_proto_msgTypes[79].OneofWrappers = []any{ (*ChatStyle_WallpaperPreset_)(nil), (*ChatStyle_WallpaperPhoto)(nil), (*ChatStyle_AutoBubbleColor)(nil), (*ChatStyle_BubbleColorPreset_)(nil), (*ChatStyle_CustomColorId)(nil), } - file_backuppb_Backup_proto_msgTypes[78].OneofWrappers = []any{} - file_backuppb_Backup_proto_msgTypes[81].OneofWrappers = []any{} - file_backuppb_Backup_proto_msgTypes[83].OneofWrappers = []any{ + file_backuppb_Backup_proto_msgTypes[80].OneofWrappers = []any{} + file_backuppb_Backup_proto_msgTypes[83].OneofWrappers = []any{} + file_backuppb_Backup_proto_msgTypes[85].OneofWrappers = []any{ (*AccountData_IAPSubscriberData_PurchaseToken)(nil), (*AccountData_IAPSubscriberData_OriginalTransactionId)(nil), } - file_backuppb_Backup_proto_msgTypes[88].OneofWrappers = []any{ + file_backuppb_Backup_proto_msgTypes[90].OneofWrappers = []any{ (*Group_GroupAttributeBlob_Title)(nil), (*Group_GroupAttributeBlob_Avatar)(nil), (*Group_GroupAttributeBlob_DisappearingMessagesDuration)(nil), (*Group_GroupAttributeBlob_DescriptionText)(nil), } - file_backuppb_Backup_proto_msgTypes[94].OneofWrappers = []any{} - file_backuppb_Backup_proto_msgTypes[105].OneofWrappers = []any{ + file_backuppb_Backup_proto_msgTypes[96].OneofWrappers = []any{} + file_backuppb_Backup_proto_msgTypes[107].OneofWrappers = []any{ (*PaymentNotification_TransactionDetails_Transaction_)(nil), (*PaymentNotification_TransactionDetails_FailedTransaction_)(nil), } - file_backuppb_Backup_proto_msgTypes[108].OneofWrappers = []any{} - file_backuppb_Backup_proto_msgTypes[113].OneofWrappers = []any{ + file_backuppb_Backup_proto_msgTypes[110].OneofWrappers = []any{} + file_backuppb_Backup_proto_msgTypes[115].OneofWrappers = []any{ (*FilePointer_LocatorInfo_PlaintextHash)(nil), (*FilePointer_LocatorInfo_EncryptedDigest)(nil), } - file_backuppb_Backup_proto_msgTypes[114].OneofWrappers = []any{} - file_backuppb_Backup_proto_msgTypes[115].OneofWrappers = []any{ + file_backuppb_Backup_proto_msgTypes[116].OneofWrappers = []any{} + file_backuppb_Backup_proto_msgTypes[119].OneofWrappers = []any{ (*GroupChangeChatUpdate_Update_GenericGroupUpdate)(nil), (*GroupChangeChatUpdate_Update_GroupCreationUpdate)(nil), (*GroupChangeChatUpdate_Update_GroupNameUpdate)(nil), @@ -12704,8 +12992,8 @@ func file_backuppb_Backup_proto_init() { (*GroupChangeChatUpdate_Update_GroupSequenceOfRequestsAndCancelsUpdate)(nil), (*GroupChangeChatUpdate_Update_GroupExpirationTimerUpdate)(nil), } - file_backuppb_Backup_proto_msgTypes[116].OneofWrappers = []any{} - file_backuppb_Backup_proto_msgTypes[118].OneofWrappers = []any{ + file_backuppb_Backup_proto_msgTypes[120].OneofWrappers = []any{} + file_backuppb_Backup_proto_msgTypes[122].OneofWrappers = []any{ (*ChatStyle_CustomChatColor_Solid)(nil), (*ChatStyle_CustomChatColor_Gradient)(nil), } @@ -12715,7 +13003,7 @@ func file_backuppb_Backup_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: unsafe.Slice(unsafe.StringData(file_backuppb_Backup_proto_rawDesc), len(file_backuppb_Backup_proto_rawDesc)), NumEnums: 31, - NumMessages: 120, + NumMessages: 124, NumExtensions: 0, NumServices: 0, }, diff --git a/pkg/signalmeow/protobuf/backuppb/Backup.proto b/pkg/signalmeow/protobuf/backuppb/Backup.proto index 464301d..66125fc 100644 --- a/pkg/signalmeow/protobuf/backuppb/Backup.proto +++ b/pkg/signalmeow/protobuf/backuppb/Backup.proto @@ -428,6 +428,7 @@ message ChatItem { GiftBadge giftBadge = 17; ViewOnceMessage viewOnceMessage = 18; DirectStoryReplyMessage directStoryReplyMessage = 19; // group story reply messages are not backed up + Poll poll = 20; } } @@ -759,6 +760,7 @@ message Quote { NORMAL = 1; GIFT_BADGE = 2; VIEW_ONCE = 3; + POLL = 4; } message QuotedAttachment { @@ -805,6 +807,25 @@ message Reaction { uint64 sortOrder = 4; } +message Poll { + + message PollOption { + + message PollVote { + uint64 voterId = 1; // A direct reference to Recipient proto id. Must be self or contact. + uint32 voteCount = 2; // Tracks how many times you voted. + } + + string option = 1; // Between 1-100 characters + repeated PollVote votes = 2; + } + + string question = 1; // Between 1-100 characters + bool allowMultiple = 2; + repeated PollOption options = 3; // At least two + bool hasEnded = 4; +} + message ChatUpdateMessage { // If unset, importers should ignore the update message without throwing an error. oneof update { @@ -817,6 +838,7 @@ message ChatUpdateMessage { IndividualCall individualCall = 7; GroupCall groupCall = 8; LearnedProfileChatUpdate learnedProfileChange = 9; + PollTerminateUpdate pollTerminate = 10; } } @@ -1182,6 +1204,11 @@ message GroupExpirationTimerUpdate { optional bytes updaterAci = 2; } +message PollTerminateUpdate { + uint64 targetSentTimestamp = 1; + string question = 2; // Between 1-100 characters +} + message StickerPack { bytes packId = 1; bytes packKey = 2; diff --git a/pkg/signalmeow/protobuf/update-protos.sh b/pkg/signalmeow/protobuf/update-protos.sh index bcdd71b..d8fea17 100755 --- a/pkg/signalmeow/protobuf/update-protos.sh +++ b/pkg/signalmeow/protobuf/update-protos.sh @@ -1,8 +1,8 @@ #!/bin/bash set -euo pipefail -ANDROID_GIT_REVISION=${1:-62fdf3d1aa9f637729ae67b55aadcc24f38f0117} -DESKTOP_GIT_REVISION=${1:-203a1cc5e3f9c1533a58caff72e13aa6eaeeddc7} +ANDROID_GIT_REVISION=${1:-d261f3ebf51864da067b968ee3366ed3e7369c78} +DESKTOP_GIT_REVISION=${1:-fb566c48e0fa146dfe0bea077ecdb3ff846ef80a} update_proto() { case "$1" in @@ -38,6 +38,7 @@ update_proto Signal-Android-App Backup.proto mv Backup.proto backuppb/Backup.proto update_proto Signal-Desktop DeviceName.proto -update_proto Signal-Desktop UnidentifiedDelivery.proto +# TODO this was moved to libsignal only +#update_proto Signal-Desktop UnidentifiedDelivery.proto # Android has CDSI.proto too, but the types have more generic names (since android uses a different package name) update_proto Signal-Desktop ContactDiscovery.proto From c9303dcd6dd89353d9b98fb31bf7a6491edc56c5 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Wed, 29 Oct 2025 14:36:15 +0200 Subject: [PATCH 440/580] msgconv/from-signal: add support for polls --- ROADMAP.md | 6 +- pkg/connector/backfill.go | 2 +- pkg/connector/config.go | 2 + pkg/connector/connector.go | 1 + pkg/connector/example-config.yaml | 2 + pkg/connector/handlesignal.go | 4 +- pkg/msgconv/from-signal-backup.go | 10 +++ pkg/msgconv/from-signal.go | 139 +++++++++++++++++++++++++++++- pkg/msgconv/msgconv.go | 1 + pkg/signalid/dbmeta.go | 3 +- 10 files changed, 163 insertions(+), 7 deletions(-) diff --git a/ROADMAP.md b/ROADMAP.md index 1695ea0..7f6db0d 100644 --- a/ROADMAP.md +++ b/ROADMAP.md @@ -5,6 +5,7 @@ * [x] Text * [x] Formatting * [x] Mentions + * [ ] Polls * [x] Media * [x] Images * [x] Audio files @@ -34,6 +35,7 @@ * [x] Text * [x] Formatting * [x] Mentions + * [x] Polls * [ ] Media * [x] Images * [x] Voice notes @@ -65,8 +67,8 @@ * [ ] Delivery receipts (there's no good way to bridge these) * [x] Disappearing messages * Misc - * [ ] Automatic portal creation - * [ ] After login + * [x] Automatic portal creation + * [x] After login * [x] When receiving message * [x] Linking as secondary device * [ ] Registering as primary device diff --git a/pkg/connector/backfill.go b/pkg/connector/backfill.go index 2dde03f..3f9a611 100644 --- a/pkg/connector/backfill.go +++ b/pkg/connector/backfill.go @@ -151,7 +151,7 @@ func (s *SignalClient) FetchMessages(ctx context.Context, params bridgev2.FetchM if dm == nil { continue } - cm := s.Main.MsgConv.ToMatrix(ctx, s.Client, params.Portal, s.Main.Bridge.Bot, dm, attMap) + cm := s.Main.MsgConv.ToMatrix(ctx, s.Client, params.Portal, senderACI, s.Main.Bridge.Bot, dm, attMap) convertedReactions := make([]*bridgev2.BackfillReaction, 0, len(reactions)) for _, reaction := range reactions { reactionSenderACI, err := getRecipientACI(reaction.AuthorId) diff --git a/pkg/connector/config.go b/pkg/connector/config.go index 4e42186..232571f 100644 --- a/pkg/connector/config.go +++ b/pkg/connector/config.go @@ -42,6 +42,7 @@ type SignalConfig struct { NoteToSelfAvatar id.ContentURIString `yaml:"note_to_self_avatar"` LocationFormat string `yaml:"location_format"` DisappearViewOnce bool `yaml:"disappear_view_once"` + ExtEvPolls bool `yaml:"extev_polls"` displaynameTemplate *template.Template `yaml:"-"` } @@ -103,6 +104,7 @@ func upgradeConfig(helper up.Helper) { helper.Copy(up.Str, "note_to_self_avatar") helper.Copy(up.Str, "location_format") helper.Copy(up.Bool, "disappear_view_once") + helper.Copy(up.Bool, "extev_polls") } func (s *SignalConnector) GetConfig() (string, any, up.Upgrader) { diff --git a/pkg/connector/connector.go b/pkg/connector/connector.go index e81ef7a..30be4a4 100644 --- a/pkg/connector/connector.go +++ b/pkg/connector/connector.go @@ -63,6 +63,7 @@ func (s *SignalConnector) Init(bridge *bridgev2.Bridge) { s.MsgConv = msgconv.NewMessageConverter(bridge) s.MsgConv.LocationFormat = s.Config.LocationFormat s.MsgConv.DisappearViewOnce = s.Config.DisappearViewOnce + s.MsgConv.ExtEvPolls = s.Config.ExtEvPolls } func (s *SignalConnector) SetMaxFileSize(maxSize int64) { diff --git a/pkg/connector/example-config.yaml b/pkg/connector/example-config.yaml index e9ff6b4..25fe035 100644 --- a/pkg/connector/example-config.yaml +++ b/pkg/connector/example-config.yaml @@ -24,3 +24,5 @@ note_to_self_avatar: mxc://maunium.net/REBIVrqjZwmaWpssCZpBlmlL location_format: 'https://www.google.com/maps/place/%[1]s,%[2]s' # Should view-once messages disappear shortly after sending a read receipt on Matrix? disappear_view_once: false +# Should polls be sent using unstable MSC3381 event types? +extev_polls: false diff --git a/pkg/connector/handlesignal.go b/pkg/connector/handlesignal.go index d60acc0..6a2f3b5 100644 --- a/pkg/connector/handlesignal.go +++ b/pkg/connector/handlesignal.go @@ -327,7 +327,7 @@ func (evt *Bv2ChatEvent) ConvertMessage(ctx context.Context, portal *bridgev2.Po if !ok { return nil, fmt.Errorf("ConvertMessage() called for non-DataMessage event") } - converted := evt.s.Main.MsgConv.ToMatrix(ctx, evt.s.Client, portal, intent, dataMsg, nil) + converted := evt.s.Main.MsgConv.ToMatrix(ctx, evt.s.Client, portal, evt.Info.Sender, intent, dataMsg, nil) if converted.Disappear.Type != "" { evtTS := evt.GetTimestamp() if !dataMsg.GetIsViewOnce() { @@ -352,7 +352,7 @@ func (evt *Bv2ChatEvent) ConvertEdit(ctx context.Context, portal *bridgev2.Porta return nil, fmt.Errorf("ConvertEdit() called for non-EditMessage event") } // TODO tell converter about existing parts to avoid reupload? - converted := evt.s.Main.MsgConv.ToMatrix(ctx, evt.s.Client, portal, intent, editMsg.GetDataMessage(), nil) + converted := evt.s.Main.MsgConv.ToMatrix(ctx, evt.s.Client, portal, evt.Info.Sender, intent, editMsg.GetDataMessage(), nil) // TODO can anything other than the text be edited? editPart := converted.Parts[len(converted.Parts)-1].ToEditPart(existing[len(existing)-1]) editPart.Part.EditCount++ diff --git a/pkg/msgconv/from-signal-backup.go b/pkg/msgconv/from-signal-backup.go index 7e8d4e1..97f756c 100644 --- a/pkg/msgconv/from-signal-backup.go +++ b/pkg/msgconv/from-signal-backup.go @@ -81,6 +81,16 @@ func BackupToDataMessage(ci *backuppb.ChatItem, attMap AttachmentMap) (*signalpb Emoji: ti.StickerMessage.Sticker.Emoji, Data: backupToSignalAttachment(ti.StickerMessage.Sticker.Data, 0, uuid.New(), attMap), } + case *backuppb.ChatItem_Poll: + dm.PollCreate = &signalpb.DataMessage_PollCreate{ + Question: &ti.Poll.Question, + AllowMultiple: &ti.Poll.AllowMultiple, + Options: exslices.CastFunc(ti.Poll.Options, func(from *backuppb.Poll_PollOption) string { + return from.Option + }), + } + // TODO handle votes + // TODO handle hasEnded somehow? case *backuppb.ChatItem_RemoteDeletedMessage: // TODO handle some other way? (also disappeared view-once messages) return nil, nil diff --git a/pkg/msgconv/from-signal.go b/pkg/msgconv/from-signal.go index ac3fe65..9392616 100644 --- a/pkg/msgconv/from-signal.go +++ b/pkg/msgconv/from-signal.go @@ -23,6 +23,7 @@ import ( "errors" "fmt" "net/http" + "strconv" "strings" "time" @@ -51,7 +52,7 @@ func calculateLength(dm *signalpb.DataMessage) int { if dm.GetFlags()&uint32(signalpb.DataMessage_EXPIRATION_TIMER_UPDATE) != 0 { return 1 } - if dm.Sticker != nil { + if dm.Sticker != nil || dm.PollVote != nil || dm.PollCreate != nil || dm.PollTerminate != nil { return 1 } length := len(dm.Attachments) + len(dm.Contact) @@ -80,6 +81,7 @@ func (mc *MessageConverter) ToMatrix( ctx context.Context, client *signalmeow.Client, portal *bridgev2.Portal, + sender uuid.UUID, intent bridgev2.MatrixAPI, dm *signalpb.DataMessage, attMap AttachmentMap, @@ -108,6 +110,18 @@ func (mc *MessageConverter) ToMatrix( // Don't allow any other parts in a sticker message return cm } + if dm.PollVote != nil { + cm.Parts = append(cm.Parts, mc.convertPollVoteToMatrix(ctx, dm.PollVote)) + return cm + } + if dm.PollCreate != nil { + cm.Parts = append(cm.Parts, mc.convertPollCreateToMatrix(dm.PollCreate)) + return cm + } + if dm.PollTerminate != nil { + cm.Parts = append(cm.Parts, mc.convertPollTerminateToMatrix(ctx, sender, dm.PollTerminate)) + return cm + } for i, att := range dm.GetAttachments() { if att.GetContentType() != "text/x-signal-plain" { cm.Parts = append(cm.Parts, mc.convertAttachmentToMatrix(ctx, i, att, attMap)) @@ -602,3 +616,126 @@ func (mc *MessageConverter) reuploadAttachment(ctx context.Context, att *signalp Extra: extra, }, nil } + +func (mc *MessageConverter) convertPollCreateToMatrix(create *signalpb.DataMessage_PollCreate) *bridgev2.ConvertedMessagePart { + evtType := event.EventMessage + if mc.ExtEvPolls { + evtType = event.EventUnstablePollStart + } + maxChoices := 1 + if create.GetAllowMultiple() { + maxChoices = len(create.GetOptions()) + } + msc3381Answers := make([]map[string]any, len(create.GetOptions())) + optionsListText := make([]string, len(create.GetOptions())) + optionsListHTML := make([]string, len(create.GetOptions())) + for i, option := range create.GetOptions() { + msc3381Answers[i] = map[string]any{ + "id": strconv.Itoa(i), + "org.matrix.msc1767.text": option, + } + optionsListText[i] = fmt.Sprintf("%d. %s\n", i+1, option) + optionsListHTML[i] = fmt.Sprintf("
  • %s
  • ", event.TextToHTML(option)) + } + body := fmt.Sprintf("%s\n\n%s\n\n(This message is a poll. Please open Signal to vote.)", create.GetQuestion(), strings.Join(optionsListText, "\n")) + formattedBody := fmt.Sprintf("

    %s

      %s

    (This message is a poll. Please open Signal to vote.)

    ", event.TextToHTML(create.GetQuestion()), strings.Join(optionsListHTML, "")) + return &bridgev2.ConvertedMessagePart{ + Type: evtType, + Content: &event.MessageEventContent{ + MsgType: event.MsgText, + Body: body, + Format: event.FormatHTML, + FormattedBody: formattedBody, + }, + Extra: map[string]any{ + "fi.mau.signal.poll": map[string]any{ + "question": create.GetQuestion(), + "allow_multiple": create.GetAllowMultiple(), + "options": create.GetOptions(), + }, + "org.matrix.msc1767.message": []map[string]any{ + {"mimetype": "text/html", "body": formattedBody}, + {"mimetype": "text/plain", "body": body}, + }, + "org.matrix.msc3381.poll.start": map[string]any{ + "kind": "org.matrix.msc3381.poll.disclosed", + "max_selections": maxChoices, + "question": map[string]any{ + "org.matrix.msc1767.text": create.GetQuestion(), + }, + "answers": msc3381Answers, + }, + }, + DBMetadata: nil, + DontBridge: false, + } +} + +func (mc *MessageConverter) convertPollTerminateToMatrix(ctx context.Context, senderACI uuid.UUID, terminate *signalpb.DataMessage_PollTerminate) *bridgev2.ConvertedMessagePart { + pollMessageID := signalid.MakeMessageID(senderACI, terminate.GetTargetSentTimestamp()) + pollMessage, err := mc.Bridge.DB.Message.GetPartByID(ctx, getPortal(ctx).Receiver, pollMessageID, "") + if err != nil { + zerolog.Ctx(ctx).Err(err).Msg("Failed to get poll terminate target message") + return &bridgev2.ConvertedMessagePart{ + Type: event.EventUnstablePollEnd, + Content: &event.MessageEventContent{}, + DontBridge: true, + } + } + return &bridgev2.ConvertedMessagePart{ + Type: event.EventUnstablePollEnd, + Content: &event.MessageEventContent{ + RelatesTo: &event.RelatesTo{ + Type: event.RelReference, + EventID: pollMessage.MXID, + }, + }, + Extra: map[string]any{ + "org.matrix.msc3381.poll.end": map[string]any{}, + }, + } +} + +var invalidPollVote = &bridgev2.ConvertedMessagePart{ + Type: event.EventUnstablePollResponse, + Content: &event.MessageEventContent{}, + DontBridge: true, +} + +func (mc *MessageConverter) convertPollVoteToMatrix(ctx context.Context, vote *signalpb.DataMessage_PollVote) *bridgev2.ConvertedMessagePart { + if len(vote.GetTargetAuthorAciBinary()) != 16 { + zerolog.Ctx(ctx).Debug(). + Str("author_aci_b64", base64.StdEncoding.EncodeToString(vote.GetTargetAuthorAciBinary())). + Msg("Invalid author ACI in poll vote") + return invalidPollVote + } + pollMessageID := signalid.MakeMessageID(uuid.UUID(vote.GetTargetAuthorAciBinary()), vote.GetTargetSentTimestamp()) + pollMessage, err := mc.Bridge.DB.Message.GetPartByID(ctx, getPortal(ctx).Receiver, pollMessageID, "") + if err != nil { + zerolog.Ctx(ctx).Err(err).Msg("Failed to get poll vote target message") + return invalidPollVote + } + mxOptionIDs := pollMessage.Metadata.(*signalid.MessageMetadata).MatrixPollOptionIDs + optionIDs := make([]string, len(vote.GetOptionIndexes())) + for i, optionIndex := range vote.GetOptionIndexes() { + if int(optionIndex) < len(mxOptionIDs) { + optionIDs[i] = mxOptionIDs[optionIndex] + } else { + optionIDs[i] = strconv.Itoa(int(optionIndex)) + } + } + return &bridgev2.ConvertedMessagePart{ + Type: event.EventUnstablePollResponse, + Content: &event.MessageEventContent{ + RelatesTo: &event.RelatesTo{ + Type: event.RelReference, + EventID: pollMessage.MXID, + }, + }, + Extra: map[string]any{ + "org.matrix.msc3381.poll.response": map[string]any{ + "answers": optionIDs, + }, + }, + } +} diff --git a/pkg/msgconv/msgconv.go b/pkg/msgconv/msgconv.go index 86e7e2d..1b8564a 100644 --- a/pkg/msgconv/msgconv.go +++ b/pkg/msgconv/msgconv.go @@ -48,6 +48,7 @@ type MessageConverter struct { LocationFormat string DisappearViewOnce bool DirectMedia bool + ExtEvPolls bool } func NewMessageConverter(br *bridgev2.Bridge) *MessageConverter { diff --git a/pkg/signalid/dbmeta.go b/pkg/signalid/dbmeta.go index 72112a8..bbbcc92 100644 --- a/pkg/signalid/dbmeta.go +++ b/pkg/signalid/dbmeta.go @@ -28,7 +28,8 @@ type PortalMetadata struct { } type MessageMetadata struct { - ContainsAttachments bool `json:"contains_attachments,omitempty"` + ContainsAttachments bool `json:"contains_attachments,omitempty"` + MatrixPollOptionIDs []string `json:"matrix_poll_option_ids,omitempty"` } type UserLoginMetadata struct { From 71e2e221f79e359bcffc48b6d90ba0f3e73cceb2 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Wed, 29 Oct 2025 14:50:26 +0200 Subject: [PATCH 441/580] handlematrix: add support for polls --- ROADMAP.md | 2 +- pkg/connector/handlematrix.go | 74 +++++++++++++++++++++++++++++++++-- 2 files changed, 71 insertions(+), 5 deletions(-) diff --git a/ROADMAP.md b/ROADMAP.md index 7f6db0d..228b271 100644 --- a/ROADMAP.md +++ b/ROADMAP.md @@ -5,7 +5,7 @@ * [x] Text * [x] Formatting * [x] Mentions - * [ ] Polls + * [x] Polls * [x] Media * [x] Images * [x] Audio files diff --git a/pkg/connector/handlematrix.go b/pkg/connector/handlematrix.go index 65e7b7c..3aa266b 100644 --- a/pkg/connector/handlematrix.go +++ b/pkg/connector/handlematrix.go @@ -21,6 +21,7 @@ import ( "crypto/sha256" "errors" "fmt" + "slices" "strconv" "time" @@ -52,6 +53,7 @@ var ( _ bridgev2.RoomTopicHandlingNetworkAPI = (*SignalClient)(nil) _ bridgev2.ChatViewingNetworkAPI = (*SignalClient)(nil) _ bridgev2.DisappearTimerChangingNetworkAPI = (*SignalClient)(nil) + _ bridgev2.PollHandlingNetworkAPI = (*SignalClient)(nil) ) func (s *SignalClient) sendMessage(ctx context.Context, portalID networkid.PortalID, content *signalpb.Content) error { @@ -116,9 +118,27 @@ func (s *SignalClient) HandleMatrixMessage(ctx context.Context, msg *bridgev2.Ma if err != nil { return nil, err } + return s.doSendMessage(ctx, ts, msg, converted, &signalid.MessageMetadata{ + ContainsAttachments: len(converted.Attachments) > 0, + }) +} + +func (s *SignalClient) doSendMessage( + ctx context.Context, + ts uint64, + msg *bridgev2.MatrixMessage, + converted *signalpb.DataMessage, + meta *signalid.MessageMetadata, +) (*bridgev2.MatrixMessageResponse, error) { + if ts == 0 { + ts = getTimestampForEvent(msg.InputTransactionID, msg.Event, msg.OrigSender) + } + if meta == nil { + meta = &signalid.MessageMetadata{} + } msgID := signalid.MakeMessageID(s.Client.Store.ACI, ts) msg.AddPendingToIgnore(networkid.TransactionID(msgID)) - err = s.sendMessage(ctx, msg.Portal.ID, &signalpb.Content{DataMessage: converted}) + err := s.sendMessage(ctx, msg.Portal.ID, &signalpb.Content{DataMessage: converted}) if err != nil { return nil, bridgev2.WrapErrorInStatus(err).WithSendNotice(true) } @@ -126,9 +146,7 @@ func (s *SignalClient) HandleMatrixMessage(ctx context.Context, msg *bridgev2.Ma ID: msgID, SenderID: signalid.MakeUserID(s.Client.Store.ACI), Timestamp: time.UnixMilli(int64(ts)), - Metadata: &signalid.MessageMetadata{ - ContainsAttachments: len(converted.Attachments) > 0, - }, + Metadata: meta, } return &bridgev2.MatrixMessageResponse{ DB: dbMsg, @@ -679,3 +697,51 @@ func (s *SignalClient) HandleMatrixDisappearingTimer(ctx context.Context, msg *b return true, nil } } + +func (s *SignalClient) HandleMatrixPollStart(ctx context.Context, msg *bridgev2.MatrixPollStart) (*bridgev2.MatrixMessageResponse, error) { + optionNames := make([]string, len(msg.Content.PollStart.Answers)) + optionIDs := make([]string, len(msg.Content.PollStart.Answers)) + for i, option := range msg.Content.PollStart.Answers { + optionNames[i] = option.Text + optionIDs[i] = option.ID + } + converted := &signalpb.DataMessage{ + PollCreate: &signalpb.DataMessage_PollCreate{ + Question: ptr.Ptr(msg.Content.PollStart.Question.Text), + AllowMultiple: ptr.Ptr(msg.Content.PollStart.MaxSelections != 1), + Options: optionNames, + }, + RequiredProtocolVersion: ptr.Ptr(uint32(signalpb.DataMessage_POLLS)), + } + return s.doSendMessage(ctx, 0, &msg.MatrixMessage, converted, &signalid.MessageMetadata{ + MatrixPollOptionIDs: optionIDs, + }) +} + +func (s *SignalClient) HandleMatrixPollVote(ctx context.Context, msg *bridgev2.MatrixPollVote) (*bridgev2.MatrixMessageResponse, error) { + senderACI, msgTS, err := signalid.ParseMessageID(msg.VoteTo.ID) + if err != nil { + return nil, err + } + mxOptions := msg.VoteTo.Metadata.(*signalid.MessageMetadata).MatrixPollOptionIDs + optionIndexes := make([]uint32, len(msg.Content.Response.Answers)) + for i, answer := range msg.Content.Response.Answers { + if idx := slices.Index(mxOptions, answer); idx >= 0 { + optionIndexes[i] = uint32(idx) + } else if idx, err = strconv.Atoi(answer); err == nil && idx >= 0 { + optionIndexes[i] = uint32(idx) + } else { + return nil, fmt.Errorf("unknown poll answer ID: %s", answer) + } + } + converted := &signalpb.DataMessage{ + PollVote: &signalpb.DataMessage_PollVote{ + TargetAuthorAciBinary: senderACI[:], + TargetSentTimestamp: &msgTS, + OptionIndexes: optionIndexes, + VoteCount: nil, // TODO + }, + RequiredProtocolVersion: ptr.Ptr(uint32(signalpb.DataMessage_POLLS)), + } + return s.doSendMessage(ctx, 0, &msg.MatrixMessage, converted, nil) +} From e3d058732adc0325674991dabf2fc65883a39024 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Thu, 30 Oct 2025 22:35:49 +0200 Subject: [PATCH 442/580] libsignal: update to v0.85.2 --- pkg/libsignalgo/libsignal | 2 +- pkg/libsignalgo/libsignal-ffi.h | 88 +++++++++++++++++++++++++++++++++ pkg/libsignalgo/version.go | 2 +- 3 files changed, 90 insertions(+), 2 deletions(-) diff --git a/pkg/libsignalgo/libsignal b/pkg/libsignalgo/libsignal index c02859f..57f2254 160000 --- a/pkg/libsignalgo/libsignal +++ b/pkg/libsignalgo/libsignal @@ -1 +1 @@ -Subproject commit c02859f57552477680fb7928c3c3426193040313 +Subproject commit 57f2254605086b0bf0c7d274ed8eaa6fafa84ee2 diff --git a/pkg/libsignalgo/libsignal-ffi.h b/pkg/libsignalgo/libsignal-ffi.h index a516a23..157f642 100644 --- a/pkg/libsignalgo/libsignal-ffi.h +++ b/pkg/libsignalgo/libsignal-ffi.h @@ -255,6 +255,8 @@ typedef enum { SignalErrorCodeRegistrationLock = 201, SignalErrorCodeKeyTransparencyError = 210, SignalErrorCodeKeyTransparencyVerificationFailed = 211, + SignalErrorCodeRequestUnauthorized = 220, + SignalErrorCodeMismatchedDevices = 221, } SignalErrorCode; enum SignalSvr2CredentialsResult { @@ -897,6 +899,35 @@ typedef struct { uint32_t second; } SignalPairOfc_charu32; +/** + * A representation of a array allocated on the Rust heap for use in C code. + */ +typedef struct { + uint32_t *base; + /** + * The number of elements in the buffer (not necessarily the number of bytes). + */ + size_t length; +} SignalOwnedBufferOfu32; + +typedef struct { + SignalServiceIdFixedWidthBinaryBytes account; + SignalOwnedBufferOfu32 missing_devices; + SignalOwnedBufferOfu32 extra_devices; + SignalOwnedBufferOfu32 stale_devices; +} SignalFfiMismatchedDevicesError; + +/** + * A representation of a array allocated on the Rust heap for use in C code. + */ +typedef struct { + SignalFfiMismatchedDevicesError *base; + /** + * The number of elements in the buffer (not necessarily the number of bytes). + */ + size_t length; +} SignalOwnedBufferOfFfiMismatchedDevicesError; + typedef struct { const char *first; SignalOwnedBuffer second; @@ -941,6 +972,17 @@ typedef struct { size_t length; } SignalOwnedBufferOfFfiRegisterResponseBadge; +/** + * A representation of a array allocated on the Rust heap for use in C code. + */ +typedef struct { + SignalServiceIdFixedWidthBinaryBytes *base; + /** + * The number of elements in the buffer (not necessarily the number of bytes). + */ + size_t length; +} SignalOwnedBufferOfServiceIdFixedWidthBinaryBytes; + typedef struct { SignalSenderKeyRecord *raw; } SignalMutPointerSenderKeyRecord; @@ -1418,6 +1460,42 @@ typedef struct { SignalCancellationId cancellation_id; } SignalCPromiseOptionalUuid; +typedef struct { + bool present; + const char *first; + uint8_t second[32]; +} SignalOptionalPairOfc_charu832; + +/** + * A C callback used to report the results of Rust futures. + * + * cbindgen will produce independent C types like `SignalCPromisei32` and + * `SignalCPromiseProtocolAddress`. + * + * This derives Copy because it behaves like a C type; nevertheless, a promise should still only be + * completed once. + */ +typedef struct { + void (*complete)(SignalFfiError *error, const SignalOptionalPairOfc_charu832 *result, const void *context); + const void *context; + SignalCancellationId cancellation_id; +} SignalCPromiseOptionalPairOfc_charu832; + +/** + * A C callback used to report the results of Rust futures. + * + * cbindgen will produce independent C types like `SignalCPromisei32` and + * `SignalCPromiseProtocolAddress`. + * + * This derives Copy because it behaves like a C type; nevertheless, a promise should still only be + * completed once. + */ +typedef struct { + void (*complete)(SignalFfiError *error, const SignalOwnedBufferOfServiceIdFixedWidthBinaryBytes *result, const void *context); + const void *context; + SignalCancellationId cancellation_id; +} SignalCPromiseOwnedBufferOfServiceIdFixedWidthBinaryBytes; + typedef struct { SignalValidatingMac *raw; } SignalMutPointerValidatingMac; @@ -1704,6 +1782,8 @@ SignalFfiError *signal_error_get_invalid_protocol_address(SignalPairOfc_charu32 SignalFfiError *signal_error_get_message(const char **out, SignalUnwindSafeArgSignalFfiError err); +SignalFfiError *signal_error_get_mismatched_device_errors(SignalOwnedBufferOfFfiMismatchedDevicesError *out, SignalUnwindSafeArgSignalFfiError err); + SignalFfiError *signal_error_get_our_fingerprint_version(uint32_t *out, SignalUnwindSafeArgSignalFfiError err); SignalFfiError *signal_error_get_rate_limit_challenge(SignalPairOfc_charOwnedBufferOfc_uchar *out, SignalUnwindSafeArgSignalFfiError err); @@ -1746,8 +1826,12 @@ void signal_free_buffer(const unsigned char *buf, size_t buf_len); void signal_free_bytestring_array(SignalBytestringArray array); +void signal_free_list_of_mismatched_device_errors(SignalOwnedBufferOfFfiMismatchedDevicesError buffer); + void signal_free_list_of_register_response_badges(SignalOwnedBufferOfFfiRegisterResponseBadge buffer); +void signal_free_list_of_service_ids(SignalOwnedBufferOfServiceIdFixedWidthBinaryBytes buffer); + void signal_free_list_of_strings(SignalOwnedBufferOfCStringPtr buffer); void signal_free_lookup_response_entry_list(SignalOwnedBufferOfFfiCdsiLookupResponseEntry buffer); @@ -2516,8 +2600,12 @@ SignalFfiError *signal_unauthenticated_chat_connection_init_listener(SignalConst SignalFfiError *signal_unauthenticated_chat_connection_look_up_username_hash(SignalCPromiseOptionalUuid *promise, SignalConstPointerTokioAsyncContext async_runtime, SignalConstPointerUnauthenticatedChatConnection chat, SignalBorrowedBuffer hash); +SignalFfiError *signal_unauthenticated_chat_connection_look_up_username_link(SignalCPromiseOptionalPairOfc_charu832 *promise, SignalConstPointerTokioAsyncContext async_runtime, SignalConstPointerUnauthenticatedChatConnection chat, const uint8_t (*uuid)[16], SignalBorrowedBuffer entropy); + SignalFfiError *signal_unauthenticated_chat_connection_send(SignalCPromiseFfiChatResponse *promise, SignalConstPointerTokioAsyncContext async_runtime, SignalConstPointerUnauthenticatedChatConnection chat, SignalConstPointerHttpRequest http_request, uint32_t timeout_millis); +SignalFfiError *signal_unauthenticated_chat_connection_send_multi_recipient_message(SignalCPromiseOwnedBufferOfServiceIdFixedWidthBinaryBytes *promise, SignalConstPointerTokioAsyncContext async_runtime, SignalConstPointerUnauthenticatedChatConnection chat, SignalBorrowedBuffer payload, uint64_t timestamp, SignalBorrowedBuffer auth, bool online_only, bool is_urgent); + SignalFfiError *signal_unidentified_sender_message_content_deserialize(SignalMutPointerUnidentifiedSenderMessageContent *out, SignalBorrowedBuffer data); SignalFfiError *signal_unidentified_sender_message_content_destroy(SignalMutPointerUnidentifiedSenderMessageContent p); diff --git a/pkg/libsignalgo/version.go b/pkg/libsignalgo/version.go index b859d49..b04d73b 100644 --- a/pkg/libsignalgo/version.go +++ b/pkg/libsignalgo/version.go @@ -2,4 +2,4 @@ package libsignalgo -const Version = "v0.84.0" +const Version = "v0.85.2" From f01415c61add68c6dca86ca04eb98118dc8f4c84 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Sun, 9 Nov 2025 11:41:52 +0200 Subject: [PATCH 443/580] dependencies: update mautrix-go --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index f61bdd1..464486c 100644 --- a/go.mod +++ b/go.mod @@ -18,7 +18,7 @@ require ( golang.org/x/net v0.46.0 google.golang.org/protobuf v1.36.10 gopkg.in/yaml.v3 v3.0.1 - maunium.net/go/mautrix v0.25.3-0.20251028130646-bea28c1381cd + maunium.net/go/mautrix v0.25.3-0.20251109094010-14e16a3a8190 ) require ( diff --git a/go.sum b/go.sum index fa344cc..f89121c 100644 --- a/go.sum +++ b/go.sum @@ -95,5 +95,5 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= maunium.net/go/mauflag v1.0.0 h1:YiaRc0tEI3toYtJMRIfjP+jklH45uDHtT80nUamyD4M= maunium.net/go/mauflag v1.0.0/go.mod h1:nLivPOpTpHnpzEh8jEdSL9UqO9+/KBJFmNRlwKfkPeA= -maunium.net/go/mautrix v0.25.3-0.20251028130646-bea28c1381cd h1:4OfgnwTd71vgHGc+kBwhWsb92ePZVvsDbyTLJiy+PKU= -maunium.net/go/mautrix v0.25.3-0.20251028130646-bea28c1381cd/go.mod h1:EWgYyp2iFZP7pnSm+rufHlO8YVnA2KnoNBDpwekiAwI= +maunium.net/go/mautrix v0.25.3-0.20251109094010-14e16a3a8190 h1:5v25ZS99ilLXHjYX3uMiyHGBNhFPXgOgGfr9GkakRTg= +maunium.net/go/mautrix v0.25.3-0.20251109094010-14e16a3a8190/go.mod h1:EWgYyp2iFZP7pnSm+rufHlO8YVnA2KnoNBDpwekiAwI= From 6987023492df81563d535ddc9ca73207a4059b9d Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Tue, 11 Nov 2025 13:30:22 +0200 Subject: [PATCH 444/580] libsignal: update to v0.86.2 --- CHANGELOG.md | 4 ++++ pkg/libsignalgo/libsignal | 2 +- pkg/libsignalgo/libsignal-ffi.h | 2 ++ pkg/libsignalgo/version.go | 2 +- 4 files changed, 8 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4e38aa4..858c3bc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,8 +1,12 @@ # v25.11 (unreleased) +* Updated libsignal to v0.86.2. * Added support for bridging invite state in groups for phone number invites. +* Added support for polls. * Fixed PNI signature not being sent when replying to message requests. * Fixed unnecessary repeating error notices when Signal is down. +* Fixed sticker size metadata on Matrix not matching how native Signal Desktop + renders them. # v25.10 diff --git a/pkg/libsignalgo/libsignal b/pkg/libsignalgo/libsignal index 57f2254..2dcd1e0 160000 --- a/pkg/libsignalgo/libsignal +++ b/pkg/libsignalgo/libsignal @@ -1 +1 @@ -Subproject commit 57f2254605086b0bf0c7d274ed8eaa6fafa84ee2 +Subproject commit 2dcd1e0b793469013043d3a0d37dc55f95b0babd diff --git a/pkg/libsignalgo/libsignal-ffi.h b/pkg/libsignalgo/libsignal-ffi.h index 157f642..26cbb6b 100644 --- a/pkg/libsignalgo/libsignal-ffi.h +++ b/pkg/libsignalgo/libsignal-ffi.h @@ -1510,6 +1510,8 @@ typedef uint8_t SignalRandomnessBytes[SignalRANDOMNESS_LEN]; typedef uint8_t SignalUnidentifiedAccessKey[SignalACCESS_KEY_LEN]; + + SignalFfiError *signal_account_entropy_pool_derive_backup_key(uint8_t (*out)[SignalBACKUP_KEY_LEN], const char *account_entropy); SignalFfiError *signal_account_entropy_pool_derive_svr_key(uint8_t (*out)[SignalSVR_KEY_LEN], const char *account_entropy); diff --git a/pkg/libsignalgo/version.go b/pkg/libsignalgo/version.go index b04d73b..b202516 100644 --- a/pkg/libsignalgo/version.go +++ b/pkg/libsignalgo/version.go @@ -2,4 +2,4 @@ package libsignalgo -const Version = "v0.85.2" +const Version = "v0.86.2" From f4aa0847651cff4fe7d28ca9ec975133f7715bfc Mon Sep 17 00:00:00 2001 From: Conan Date: Sat, 15 Nov 2025 04:21:29 +0800 Subject: [PATCH 445/580] handlematrix: implement DeleteChatHandlingNetworkAPI (#616) Co-authored-by: Tulir Asokan --- pkg/connector/capabilities.go | 4 +- pkg/connector/handlematrix.go | 87 +++++++++++++++++++++++++++++++++++ pkg/signalmeow/sending.go | 2 + 3 files changed, 92 insertions(+), 1 deletion(-) diff --git a/pkg/connector/capabilities.go b/pkg/connector/capabilities.go index b9cb632..ca2975c 100644 --- a/pkg/connector/capabilities.go +++ b/pkg/connector/capabilities.go @@ -38,7 +38,7 @@ func supportedIfFFmpeg() event.CapabilitySupportLevel { } func capID() string { - base := "fi.mau.signal.capabilities.2025_10_27" + base := "fi.mau.signal.capabilities.2025_10_28" if ffmpeg.Supported() { return base + "+ffmpeg" } @@ -169,6 +169,8 @@ var signalCaps = &event.RoomFeatures{ CustomEmojiReactions: false, ReadReceipts: true, TypingNotifications: true, + + DeleteChat: true, } var signalDisappearingCap = &event.DisappearingTimerCapability{ diff --git a/pkg/connector/handlematrix.go b/pkg/connector/handlematrix.go index 3aa266b..deb52e3 100644 --- a/pkg/connector/handlematrix.go +++ b/pkg/connector/handlematrix.go @@ -53,6 +53,7 @@ var ( _ bridgev2.RoomTopicHandlingNetworkAPI = (*SignalClient)(nil) _ bridgev2.ChatViewingNetworkAPI = (*SignalClient)(nil) _ bridgev2.DisappearTimerChangingNetworkAPI = (*SignalClient)(nil) + _ bridgev2.DeleteChatHandlingNetworkAPI = (*SignalClient)(nil) _ bridgev2.PollHandlingNetworkAPI = (*SignalClient)(nil) ) @@ -698,6 +699,92 @@ func (s *SignalClient) HandleMatrixDisappearingTimer(ctx context.Context, msg *b } } +func (s *SignalClient) HandleMatrixDeleteChat(ctx context.Context, msg *bridgev2.MatrixDeleteChat) error { + userID, groupID, err := signalid.ParsePortalID(msg.Portal.ID) + if err != nil { + return fmt.Errorf("failed to parse portal ID: %w", err) + } + + // Build ConversationIdentifier based on portal type + var conversationID *signalpb.ConversationIdentifier + if groupID == "" { + conversationID = &signalpb.ConversationIdentifier{ + Identifier: &signalpb.ConversationIdentifier_ThreadServiceId{ + ThreadServiceId: userID.String(), + }, + } + } else { + gid, err := groupID.Bytes() + if err != nil { + return fmt.Errorf("failed to parse group ID: %w", err) + } + conversationID = &signalpb.ConversationIdentifier{ + Identifier: &signalpb.ConversationIdentifier_ThreadGroupId{ + ThreadGroupId: gid[:], + }, + } + } + + // Retrieve most recent messages from the portal + var mostRecentMessages []*signalpb.AddressableMessage + dbMessages, err := s.Main.Bridge.DB.Message.GetMessagesBetweenTimeQuery( + ctx, + msg.Portal.PortalKey, + time.Now().Add(-30*24*time.Hour), // Last 30 days + time.Now(), + ) + if err != nil { + zerolog.Ctx(ctx).Warn().Err(err).Msg("Failed to get recent messages for conversation delete") + } else if len(dbMessages) > 0 { + // Limit to the 5 most recent messages overall + limit := 5 + startIdx := 0 + if len(dbMessages) > limit { + startIdx = len(dbMessages) - limit + } + + // Create AddressableMessage for most recent messages + for _, dbMsg := range dbMessages[startIdx:] { + senderACI, timestamp, err := signalid.ParseMessageID(dbMsg.ID) + if err != nil { + continue + } + + mostRecentMessages = append(mostRecentMessages, &signalpb.AddressableMessage{ + Author: &signalpb.AddressableMessage_AuthorServiceId{ + AuthorServiceId: senderACI.String(), + }, + SentTimestamp: proto.Uint64(timestamp), + }) + } + } + + recipientID := s.Client.Store.ACIServiceID() + // Send DeleteForMe sync message to self + result := s.Client.SendMessage(ctx, recipientID, &signalpb.Content{ + SyncMessage: &signalpb.SyncMessage{ + DeleteForMe: &signalpb.SyncMessage_DeleteForMe{ + ConversationDeletes: []*signalpb.SyncMessage_DeleteForMe_ConversationDelete{{ + Conversation: conversationID, + MostRecentMessages: mostRecentMessages, + IsFullDelete: proto.Bool(true), + }}, + }, + }, + }) + + zerolog.Ctx(ctx).Debug(). + Str("portal_id", string(msg.Portal.ID)). + Int("recent_messages_count", len(mostRecentMessages)). + Msg("Sent conversation deletion to Signal") + + if !result.WasSuccessful { + return fmt.Errorf("failed to send delete conversation sync message: %w %s %s", result.Error, userID, groupID) + } + + return nil +} + func (s *SignalClient) HandleMatrixPollStart(ctx context.Context, msg *bridgev2.MatrixPollStart) (*bridgev2.MatrixMessageResponse, error) { optionNames := make([]string, len(msg.Content.PollStart.Answers)) optionIDs := make([]string, len(msg.Content.PollStart.Answers)) diff --git a/pkg/signalmeow/sending.go b/pkg/signalmeow/sending.go index c1b2016..8bfc5a5 100644 --- a/pkg/signalmeow/sending.go +++ b/pkg/signalmeow/sending.go @@ -660,6 +660,8 @@ func (cli *Client) sendSyncCopy(ctx context.Context, content *signalpb.Content, syncContent = syncMessageFromSoloEditMessage(content.EditMessage, *result) } else if content.GetReceiptMessage().GetType() == signalpb.ReceiptMessage_READ { syncContent = syncMessageFromReadReceiptMessage(ctx, content.ReceiptMessage, result.Recipient) + } else if content.GetSyncMessage() != nil { + syncContent = content } if syncContent != nil { _, selfSendErr := cli.sendContent(ctx, cli.Store.ACIServiceID(), messageTS, syncContent, 0, true, false) From 12808bbe8a3ecb2d274436a8c198778162f71d4b Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Sat, 15 Nov 2025 18:40:57 +0200 Subject: [PATCH 446/580] libsignal: update to v0.86.4 --- CHANGELOG.md | 2 +- pkg/libsignalgo/libsignal | 2 +- pkg/libsignalgo/version.go | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 858c3bc..a3a256c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,6 @@ # v25.11 (unreleased) -* Updated libsignal to v0.86.2. +* Updated libsignal to v0.86.4. * Added support for bridging invite state in groups for phone number invites. * Added support for polls. * Fixed PNI signature not being sent when replying to message requests. diff --git a/pkg/libsignalgo/libsignal b/pkg/libsignalgo/libsignal index 2dcd1e0..5a64e17 160000 --- a/pkg/libsignalgo/libsignal +++ b/pkg/libsignalgo/libsignal @@ -1 +1 @@ -Subproject commit 2dcd1e0b793469013043d3a0d37dc55f95b0babd +Subproject commit 5a64e17ed4450eaf5fe29bfa611c9838736ac1a6 diff --git a/pkg/libsignalgo/version.go b/pkg/libsignalgo/version.go index b202516..dbb024d 100644 --- a/pkg/libsignalgo/version.go +++ b/pkg/libsignalgo/version.go @@ -2,4 +2,4 @@ package libsignalgo -const Version = "v0.86.2" +const Version = "v0.86.4" From 74d9ebb371d9d5b48458f967e7fade4589f8e905 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Sat, 15 Nov 2025 18:59:21 +0200 Subject: [PATCH 447/580] signalmeow/attachments: update group avatar upload url --- pkg/signalmeow/attachments.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/signalmeow/attachments.go b/pkg/signalmeow/attachments.go index ea03c21..67a55c8 100644 --- a/pkg/signalmeow/attachments.go +++ b/pkg/signalmeow/attachments.go @@ -305,7 +305,7 @@ func (cli *Client) UploadGroupAvatar(ctx context.Context, avatarBytes []byte, gi } // Get upload form from Signal server - formPath := "/v1/groups/avatar/form" + formPath := "/v2/groups/avatar/form" opts := &web.HTTPReqOpt{Username: &groupAuth.Username, Password: &groupAuth.Password, ContentType: web.ContentTypeProtobuf, Host: web.StorageHostname} resp, err := web.SendHTTPRequest(ctx, http.MethodGet, formPath, opts) if err != nil { From a3cab68309d741214c876eee0962ad2756a09604 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Sun, 16 Nov 2025 13:43:08 +0200 Subject: [PATCH 448/580] Bump version to v25.11 --- CHANGELOG.md | 2 +- cmd/mautrix-signal/main.go | 2 +- go.mod | 18 +++++++++--------- go.sum | 32 ++++++++++++++++---------------- 4 files changed, 27 insertions(+), 27 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a3a256c..4f147c6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,4 @@ -# v25.11 (unreleased) +# v25.11 * Updated libsignal to v0.86.4. * Added support for bridging invite state in groups for phone number invites. diff --git a/cmd/mautrix-signal/main.go b/cmd/mautrix-signal/main.go index 73a2921..522834f 100644 --- a/cmd/mautrix-signal/main.go +++ b/cmd/mautrix-signal/main.go @@ -34,7 +34,7 @@ var m = mxmain.BridgeMain{ Name: "mautrix-signal", URL: "https://github.com/mautrix/signal", Description: "A Matrix-Signal puppeting bridge.", - Version: "25.10", + Version: "25.11", SemCalVer: true, Connector: &connector.SignalConnector{}, diff --git a/go.mod b/go.mod index 464486c..e2700a0 100644 --- a/go.mod +++ b/go.mod @@ -2,7 +2,7 @@ module go.mau.fi/mautrix-signal go 1.24.0 -toolchain go1.25.3 +toolchain go1.25.4 require ( github.com/coder/websocket v1.8.14 @@ -12,13 +12,13 @@ require ( github.com/rs/zerolog v1.34.0 github.com/stretchr/testify v1.11.1 github.com/tidwall/gjson v1.18.0 - go.mau.fi/util v0.9.2 - golang.org/x/crypto v0.43.0 - golang.org/x/exp v0.0.0-20251009144603-d2f985daa21b - golang.org/x/net v0.46.0 + go.mau.fi/util v0.9.3 + golang.org/x/crypto v0.44.0 + golang.org/x/exp v0.0.0-20251113190631-e25ba8c21ef6 + golang.org/x/net v0.47.0 google.golang.org/protobuf v1.36.10 gopkg.in/yaml.v3 v3.0.1 - maunium.net/go/mautrix v0.25.3-0.20251109094010-14e16a3a8190 + maunium.net/go/mautrix v0.26.0 ) require ( @@ -40,9 +40,9 @@ require ( github.com/tidwall/sjson v1.2.5 // indirect github.com/yuin/goldmark v1.7.13 // indirect go.mau.fi/zeroconfig v0.2.0 // indirect - golang.org/x/sync v0.17.0 // indirect - golang.org/x/sys v0.37.0 // indirect - golang.org/x/text v0.30.0 // indirect + golang.org/x/sync v0.18.0 // indirect + golang.org/x/sys v0.38.0 // indirect + golang.org/x/text v0.31.0 // indirect gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect gopkg.in/natefinch/lumberjack.v2 v2.2.1 // indirect maunium.net/go/mauflag v1.0.0 // indirect diff --git a/go.sum b/go.sum index f89121c..9b47a04 100644 --- a/go.sum +++ b/go.sum @@ -65,25 +65,25 @@ github.com/tidwall/sjson v1.2.5 h1:kLy8mja+1c9jlljvWTlSazM7cKDRfJuR/bOJhcY5NcY= github.com/tidwall/sjson v1.2.5/go.mod h1:Fvgq9kS/6ociJEDnK0Fk1cpYF4FIW6ZF7LAe+6jwd28= github.com/yuin/goldmark v1.7.13 h1:GPddIs617DnBLFFVJFgpo1aBfe/4xcvMc3SB5t/D0pA= github.com/yuin/goldmark v1.7.13/go.mod h1:ip/1k0VRfGynBgxOz0yCqHrbZXhcjxyuS66Brc7iBKg= -go.mau.fi/util v0.9.2 h1:+S4Z03iCsGqU2WY8X2gySFsFjaLlUHFRDVCYvVwynKM= -go.mau.fi/util v0.9.2/go.mod h1:055elBBCJSdhRsmub7ci9hXZPgGr1U6dYg44cSgRgoU= +go.mau.fi/util v0.9.3 h1:aqNF8KDIN8bFpFbybSk+mEBil7IHeBwlujfyTnvP0uU= +go.mau.fi/util v0.9.3/go.mod h1:krWWfBM1jWTb5f8NCa2TLqWMQuM81X7TGQjhMjBeXmQ= go.mau.fi/zeroconfig v0.2.0 h1:e/OGEERqVRRKlgaro7E6bh8xXiKFSXB3eNNIud7FUjU= go.mau.fi/zeroconfig v0.2.0/go.mod h1:J0Vn0prHNOm493oZoQ84kq83ZaNCYZnq+noI1b1eN8w= -golang.org/x/crypto v0.43.0 h1:dduJYIi3A3KOfdGOHX8AVZ/jGiyPa3IbBozJ5kNuE04= -golang.org/x/crypto v0.43.0/go.mod h1:BFbav4mRNlXJL4wNeejLpWxB7wMbc79PdRGhWKncxR0= -golang.org/x/exp v0.0.0-20251009144603-d2f985daa21b h1:18qgiDvlvH7kk8Ioa8Ov+K6xCi0GMvmGfGW0sgd/SYA= -golang.org/x/exp v0.0.0-20251009144603-d2f985daa21b/go.mod h1:j/pmGrbnkbPtQfxEe5D0VQhZC6qKbfKifgD0oM7sR70= -golang.org/x/net v0.46.0 h1:giFlY12I07fugqwPuWJi68oOnpfqFnJIJzaIIm2JVV4= -golang.org/x/net v0.46.0/go.mod h1:Q9BGdFy1y4nkUwiLvT5qtyhAnEHgnQ/zd8PfU6nc210= -golang.org/x/sync v0.17.0 h1:l60nONMj9l5drqw6jlhIELNv9I0A4OFgRsG9k2oT9Ug= -golang.org/x/sync v0.17.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= +golang.org/x/crypto v0.44.0 h1:A97SsFvM3AIwEEmTBiaxPPTYpDC47w720rdiiUvgoAU= +golang.org/x/crypto v0.44.0/go.mod h1:013i+Nw79BMiQiMsOPcVCB5ZIJbYkerPrGnOa00tvmc= +golang.org/x/exp v0.0.0-20251113190631-e25ba8c21ef6 h1:zfMcR1Cs4KNuomFFgGefv5N0czO2XZpUbxGUy8i8ug0= +golang.org/x/exp v0.0.0-20251113190631-e25ba8c21ef6/go.mod h1:46edojNIoXTNOhySWIWdix628clX9ODXwPsQuG6hsK0= +golang.org/x/net v0.47.0 h1:Mx+4dIFzqraBXUugkia1OOvlD6LemFo1ALMHjrXDOhY= +golang.org/x/net v0.47.0/go.mod h1:/jNxtkgq5yWUGYkaZGqo27cfGZ1c5Nen03aYrrKpVRU= +golang.org/x/sync v0.18.0 h1:kr88TuHDroi+UVf+0hZnirlk8o8T+4MrK6mr60WkH/I= +golang.org/x/sync v0.18.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.37.0 h1:fdNQudmxPjkdUTPnLn5mdQv7Zwvbvpaxqs831goi9kQ= -golang.org/x/sys v0.37.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= -golang.org/x/text v0.30.0 h1:yznKA/E9zq54KzlzBEAWn1NXSQ8DIp/NYMy88xJjl4k= -golang.org/x/text v0.30.0/go.mod h1:yDdHFIX9t+tORqspjENWgzaCVXgk0yYnYuSZ8UzzBVM= +golang.org/x/sys v0.38.0 h1:3yZWxaJjBmCWXqhN1qh02AkOnCQ1poK6oF+a7xWL6Gc= +golang.org/x/sys v0.38.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= +golang.org/x/text v0.31.0 h1:aC8ghyu4JhP8VojJ2lEHBnochRno1sgL6nEi9WGFGMM= +golang.org/x/text v0.31.0/go.mod h1:tKRAlv61yKIjGGHX/4tP1LTbc13YSec1pxVEWXzfoeM= google.golang.org/protobuf v1.36.10 h1:AYd7cD/uASjIL6Q9LiTjz8JLcrh/88q5UObnmY3aOOE= google.golang.org/protobuf v1.36.10/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= @@ -95,5 +95,5 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= maunium.net/go/mauflag v1.0.0 h1:YiaRc0tEI3toYtJMRIfjP+jklH45uDHtT80nUamyD4M= maunium.net/go/mauflag v1.0.0/go.mod h1:nLivPOpTpHnpzEh8jEdSL9UqO9+/KBJFmNRlwKfkPeA= -maunium.net/go/mautrix v0.25.3-0.20251109094010-14e16a3a8190 h1:5v25ZS99ilLXHjYX3uMiyHGBNhFPXgOgGfr9GkakRTg= -maunium.net/go/mautrix v0.25.3-0.20251109094010-14e16a3a8190/go.mod h1:EWgYyp2iFZP7pnSm+rufHlO8YVnA2KnoNBDpwekiAwI= +maunium.net/go/mautrix v0.26.0 h1:valc2VmZF+oIY4bMq4Cd5H9cEKMRe8eP4FM7iiaYLxI= +maunium.net/go/mautrix v0.26.0/go.mod h1:NWMv+243NX/gDrLofJ2nNXJPrG8vzoM+WUCWph85S6Q= From 8afd786108ef8b59303231ffb31408ecf20dd5a7 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Mon, 17 Nov 2025 15:40:36 +0200 Subject: [PATCH 449/580] signalmeow/provisioning: fix link capabilities --- pkg/signalmeow/provisioning.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/signalmeow/provisioning.go b/pkg/signalmeow/provisioning.go index 8e87738..d877276 100644 --- a/pkg/signalmeow/provisioning.go +++ b/pkg/signalmeow/provisioning.go @@ -299,7 +299,7 @@ func startProvisioning(ctx context.Context, ws *websocket.Conn, provisioningCiph return "", fmt.Errorf("failed to unmarshal provisioning UUID: %w", err) } - linkCapabilities := []string{"backup4", "backup5"} + linkCapabilities := []string{"backup4,backup5"} if !allowBackup { linkCapabilities = []string{} } From f9adb1641599b74228e5292842a9ce983f00d9f5 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Wed, 19 Nov 2025 15:07:15 +0200 Subject: [PATCH 450/580] dependencies: update mautrix-go --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index e2700a0..e25aa3b 100644 --- a/go.mod +++ b/go.mod @@ -18,7 +18,7 @@ require ( golang.org/x/net v0.47.0 google.golang.org/protobuf v1.36.10 gopkg.in/yaml.v3 v3.0.1 - maunium.net/go/mautrix v0.26.0 + maunium.net/go/mautrix v0.26.1-0.20251119111538-57657d54eeac ) require ( diff --git a/go.sum b/go.sum index 9b47a04..a96f394 100644 --- a/go.sum +++ b/go.sum @@ -95,5 +95,5 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= maunium.net/go/mauflag v1.0.0 h1:YiaRc0tEI3toYtJMRIfjP+jklH45uDHtT80nUamyD4M= maunium.net/go/mauflag v1.0.0/go.mod h1:nLivPOpTpHnpzEh8jEdSL9UqO9+/KBJFmNRlwKfkPeA= -maunium.net/go/mautrix v0.26.0 h1:valc2VmZF+oIY4bMq4Cd5H9cEKMRe8eP4FM7iiaYLxI= -maunium.net/go/mautrix v0.26.0/go.mod h1:NWMv+243NX/gDrLofJ2nNXJPrG8vzoM+WUCWph85S6Q= +maunium.net/go/mautrix v0.26.1-0.20251119111538-57657d54eeac h1:zRQXrl+c9Isc1pJ7/MAdov8OKt+MVPGh5qjTzefxb+k= +maunium.net/go/mautrix v0.26.1-0.20251119111538-57657d54eeac/go.mod h1:NWMv+243NX/gDrLofJ2nNXJPrG8vzoM+WUCWph85S6Q= From 75653b339261db938e57ace37fd838bc9865d0d1 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Wed, 19 Nov 2025 23:15:02 +0200 Subject: [PATCH 451/580] dependencies: update mautrix-go again --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index e25aa3b..1d83420 100644 --- a/go.mod +++ b/go.mod @@ -18,7 +18,7 @@ require ( golang.org/x/net v0.47.0 google.golang.org/protobuf v1.36.10 gopkg.in/yaml.v3 v3.0.1 - maunium.net/go/mautrix v0.26.1-0.20251119111538-57657d54eeac + maunium.net/go/mautrix v0.26.1-0.20251119211341-fa56255a06be ) require ( diff --git a/go.sum b/go.sum index a96f394..dbd972c 100644 --- a/go.sum +++ b/go.sum @@ -95,5 +95,5 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= maunium.net/go/mauflag v1.0.0 h1:YiaRc0tEI3toYtJMRIfjP+jklH45uDHtT80nUamyD4M= maunium.net/go/mauflag v1.0.0/go.mod h1:nLivPOpTpHnpzEh8jEdSL9UqO9+/KBJFmNRlwKfkPeA= -maunium.net/go/mautrix v0.26.1-0.20251119111538-57657d54eeac h1:zRQXrl+c9Isc1pJ7/MAdov8OKt+MVPGh5qjTzefxb+k= -maunium.net/go/mautrix v0.26.1-0.20251119111538-57657d54eeac/go.mod h1:NWMv+243NX/gDrLofJ2nNXJPrG8vzoM+WUCWph85S6Q= +maunium.net/go/mautrix v0.26.1-0.20251119211341-fa56255a06be h1:RoTQW/g3Upum3RSzdbOlpxhphDsA7+FtFzmF3Obe0o0= +maunium.net/go/mautrix v0.26.1-0.20251119211341-fa56255a06be/go.mod h1:NWMv+243NX/gDrLofJ2nNXJPrG8vzoM+WUCWph85S6Q= From bc47e22ae4a2f7138f96a9fb79873a8b3900075f Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Wed, 19 Nov 2025 23:22:24 +0200 Subject: [PATCH 452/580] dependencies: update mautrix-go again --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 1d83420..9cd9dbb 100644 --- a/go.mod +++ b/go.mod @@ -18,7 +18,7 @@ require ( golang.org/x/net v0.47.0 google.golang.org/protobuf v1.36.10 gopkg.in/yaml.v3 v3.0.1 - maunium.net/go/mautrix v0.26.1-0.20251119211341-fa56255a06be + maunium.net/go/mautrix v0.26.1-0.20251119212156-1fac8ceb6653 ) require ( diff --git a/go.sum b/go.sum index dbd972c..835ede2 100644 --- a/go.sum +++ b/go.sum @@ -95,5 +95,5 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= maunium.net/go/mauflag v1.0.0 h1:YiaRc0tEI3toYtJMRIfjP+jklH45uDHtT80nUamyD4M= maunium.net/go/mauflag v1.0.0/go.mod h1:nLivPOpTpHnpzEh8jEdSL9UqO9+/KBJFmNRlwKfkPeA= -maunium.net/go/mautrix v0.26.1-0.20251119211341-fa56255a06be h1:RoTQW/g3Upum3RSzdbOlpxhphDsA7+FtFzmF3Obe0o0= -maunium.net/go/mautrix v0.26.1-0.20251119211341-fa56255a06be/go.mod h1:NWMv+243NX/gDrLofJ2nNXJPrG8vzoM+WUCWph85S6Q= +maunium.net/go/mautrix v0.26.1-0.20251119212156-1fac8ceb6653 h1:z62cPre4V+NGIonN5qlvt1ZtZH5/93ix9DR7KR8yImU= +maunium.net/go/mautrix v0.26.1-0.20251119212156-1fac8ceb6653/go.mod h1:NWMv+243NX/gDrLofJ2nNXJPrG8vzoM+WUCWph85S6Q= From b9061c2aa01cd1625a527092e33acc30ffa45fb0 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Thu, 20 Nov 2025 13:16:20 +0200 Subject: [PATCH 453/580] signalmeow/receiving: split sync message handling to new function --- pkg/signalmeow/receiving.go | 271 +++++++++++++++++++----------------- 1 file changed, 140 insertions(+), 131 deletions(-) diff --git a/pkg/signalmeow/receiving.go b/pkg/signalmeow/receiving.go index d630386..dc678e4 100644 --- a/pkg/signalmeow/receiving.go +++ b/pkg/signalmeow/receiving.go @@ -417,6 +417,22 @@ func (cli *Client) handleDecryptedResult( }() } + theirServiceID, err := result.SenderAddress.NameServiceID() + if err != nil { + log.Warn(). + Uint64("server_ts", envelope.GetServerTimestamp()). + Uint64("client_ts", envelope.GetTimestamp()). + Msg("Failed to get sender name as service ID") + return fmt.Errorf("failed to get sender name as service ID: %w", err) + } else if theirServiceID.Type != libsignalgo.ServiceIDTypeACI { + log.Warn(). + Any("their_service_id", theirServiceID). + Uint64("server_ts", envelope.GetServerTimestamp()). + Uint64("client_ts", envelope.GetTimestamp()). + Msg("Dropping message from non-ACI sender") + return nil + } + handlerSuccess := true // result.Err is set if there was an error during decryption and we // should notifiy the user that the message could not be decrypted @@ -430,12 +446,6 @@ func (cli *Client) handleDecryptedResult( logEvt.Msg("Decryption error with unknown sender") return nil } - theirServiceID, err := result.SenderAddress.NameServiceID() - if err != nil { - log.Err(err).Msg("Name error handling decryption error") - } else if theirServiceID.Type != libsignalgo.ServiceIDTypeACI { - log.Warn().Any("their_service_id", theirServiceID).Msg("Sender ServiceID is not an ACI") - } if errors.Is(result.Err, EventAlreadyProcessed) { logEvt.Discard().Msg("") log.Debug().Err(result.Err). @@ -471,12 +481,11 @@ func (cli *Client) handleDecryptedResult( return nil } - name, _ := result.SenderAddress.Name() - deviceId, _ := result.SenderAddress.DeviceID() - log.Trace().Any("raw_data", content).Str("sender", name).Uint("sender_device", deviceId).Msg("Raw event data") + deviceID, _ := result.SenderAddress.DeviceID() + log.Trace().Any("raw_data", content).Stringer("sender", theirServiceID).Uint("sender_device", deviceID).Msg("Raw event data") newLog := log.With(). - Str("sender_name", name). - Uint("sender_device_id", deviceId). + Stringer("sender_name", theirServiceID). + Uint("sender_device_id", deviceID). Str("destination_service_id", destinationServiceID.String()). Logger() log = &newLog @@ -507,15 +516,6 @@ func (cli *Client) handleDecryptedResult( } } - theirServiceID, err := result.SenderAddress.NameServiceID() - if err != nil { - log.Err(err).Msg("Name error") - return err - } else if theirServiceID.Type != libsignalgo.ServiceIDTypeACI { - log.Warn().Any("their_service_id", theirServiceID).Msg("Sender ServiceID is not an ACI") - return nil - } - if destinationServiceID == cli.Store.PNIServiceID() { _, err = cli.Store.RecipientStore.LoadAndUpdateRecipient(ctx, theirServiceID.UUID, uuid.Nil, func(recipient *types.Recipient) (changed bool, err error) { if !recipient.NeedsPNISignature { @@ -541,118 +541,11 @@ func (cli *Client) handleDecryptedResult( } } - // TODO: handle more sync messages - if content.SyncMessage != nil { - if content.SyncMessage.Keys != nil { - aep := libsignalgo.AccountEntropyPool(content.SyncMessage.Keys.GetAccountEntropyPool()) - cli.Store.MasterKey = content.SyncMessage.Keys.GetMaster() - if aep != "" { - aepMasterKey, err := aep.DeriveSVRKey() - if err != nil { - log.Err(err).Msg("Failed to derive master key from account entropy pool") - } else if cli.Store.MasterKey == nil { - cli.Store.MasterKey = aepMasterKey - log.Debug().Msg("Derived master key from account entropy pool (no master key in sync message)") - } else if !bytes.Equal(aepMasterKey, cli.Store.MasterKey) { - log.Warn().Msg("Derived master key doesn't match one in sync message") - } else { - log.Debug().Msg("Derived master key matches one in sync message") - } - } else { - log.Debug().Msg("No account entropy pool in sync message") - } - err = cli.Store.DeviceStore.PutDevice(ctx, &cli.Store.DeviceData) - if err != nil { - log.Err(err).Msg("Failed to save device after receiving master key") - } else { - log.Info().Msg("Received master key") - go cli.SyncStorage(ctx) - } - } else if content.SyncMessage.GetFetchLatest().GetType() == signalpb.SyncMessage_FetchLatest_STORAGE_MANIFEST { - log.Debug().Msg("Received storage manifest fetch latest notice") - go cli.SyncStorage(ctx) + if content.SyncMessage != nil && theirServiceID == cli.Store.ACIServiceID() { + handlerSuccess, err = cli.handleSyncMessage(ctx, content.SyncMessage, envelope) + if err != nil { + return err } - syncSent := content.SyncMessage.GetSent() - if syncSent.GetMessage() != nil || syncSent.GetEditMessage() != nil { - destination := syncSent.DestinationServiceId - var syncDestinationServiceID libsignalgo.ServiceID - if destination != nil { - syncDestinationServiceID, err = libsignalgo.ServiceIDFromString(*destination) - if err != nil { - log.Err(err).Msg("Sync message destination parse error") - return err - } - if syncSent.GetDestinationE164() != "" { - aci, pni := syncDestinationServiceID.ToACIAndPNI() - _, err = cli.Store.RecipientStore.UpdateRecipientE164(ctx, aci, pni, syncSent.GetDestinationE164()) - if err != nil { - log.Err(err).Msg("Failed to update recipient E164 after receiving sync message") - } - } - } - if destination == nil && syncSent.GetMessage().GetGroupV2() == nil && syncSent.GetEditMessage().GetDataMessage().GetGroupV2() == nil { - log.Warn().Msg("sync message sent destination is nil") - } else if content.SyncMessage.Sent.Message != nil { - // TODO handle expiration start ts, and maybe the sync message ts? - cli.incomingDataMessage(ctx, content.SyncMessage.Sent.Message, cli.Store.ACI, syncDestinationServiceID, envelope.GetServerTimestamp()) - } else if content.SyncMessage.Sent.EditMessage != nil { - cli.incomingEditMessage(ctx, content.SyncMessage.Sent.EditMessage, cli.Store.ACI, syncDestinationServiceID, envelope.GetServerTimestamp()) - } - } - if content.SyncMessage.Contacts != nil { - log.Debug().Msg("Recieved sync message contacts") - blob := content.SyncMessage.Contacts.Blob - if blob != nil { - contactsBytes, err := DownloadAttachmentWithPointer(ctx, blob, nil) - if err != nil { - log.Err(err).Msg("Contacts Sync DownloadAttachment error") - } - // unmarshall contacts - contacts, avatars, err := unmarshalContactDetailsMessages(contactsBytes) - if err != nil { - log.Err(err).Msg("Contacts Sync unmarshalContactDetailsMessages error") - } - log.Debug().Int("contact_count", len(contacts)).Msg("Contacts Sync received contacts") - convertedContacts := make([]*types.Recipient, 0, len(contacts)) - err = cli.Store.DoContactTxn(ctx, func(ctx context.Context) error { - for i, signalContact := range contacts { - if signalContact.Aci == nil || *signalContact.Aci == "" { - // TODO lookup PNI via CDSI and store that when ACI is missing? - log.Info(). - Any("contact", signalContact). - Msg("Signal Contact UUID is nil, skipping") - continue - } - contact, err := cli.StoreContactDetailsAsContact(ctx, signalContact, &avatars[i]) - if err != nil { - return err - } - convertedContacts = append(convertedContacts, contact) - } - return nil - }) - if err != nil { - log.Err(err).Msg("Error storing contacts") - } else { - handlerSuccess = cli.handleEvent(&events.ContactList{ - Contacts: convertedContacts, - }) - } - } - } - if content.SyncMessage.Read != nil { - handlerSuccess = cli.handleEvent(&events.ReadSelf{ - Timestamp: envelope.GetTimestamp(), - Messages: content.SyncMessage.GetRead(), - }) - } - if content.SyncMessage.DeleteForMe != nil { - handlerSuccess = cli.handleEvent(&events.DeleteForMe{ - Timestamp: envelope.GetTimestamp(), - SyncMessage_DeleteForMe: content.SyncMessage.DeleteForMe, - }) - } - } sendDeliveryReceipt := true @@ -725,6 +618,122 @@ func groupOrUserID(groupID types.GroupIdentifier, userID libsignalgo.ServiceID) return string(groupID) } +func (cli *Client) handleSyncMessage(ctx context.Context, msg *signalpb.SyncMessage, envelope *signalpb.Envelope) (handlerSuccess bool, err error) { + // TODO: handle more sync messages + handlerSuccess = true + log := zerolog.Ctx(ctx) + if msg.Keys != nil { + aep := libsignalgo.AccountEntropyPool(msg.Keys.GetAccountEntropyPool()) + cli.Store.MasterKey = msg.Keys.GetMaster() + if aep != "" { + aepMasterKey, err := aep.DeriveSVRKey() + if err != nil { + log.Err(err).Msg("Failed to derive master key from account entropy pool") + } else if cli.Store.MasterKey == nil { + cli.Store.MasterKey = aepMasterKey + log.Debug().Msg("Derived master key from account entropy pool (no master key in sync message)") + } else if !bytes.Equal(aepMasterKey, cli.Store.MasterKey) { + log.Warn().Msg("Derived master key doesn't match one in sync message") + } else { + log.Debug().Msg("Derived master key matches one in sync message") + } + } else { + log.Debug().Msg("No account entropy pool in sync message") + } + err = cli.Store.DeviceStore.PutDevice(ctx, &cli.Store.DeviceData) + if err != nil { + log.Err(err).Msg("Failed to save device after receiving master key") + } else { + log.Info().Msg("Received master key") + go cli.SyncStorage(ctx) + } + } else if msg.GetFetchLatest().GetType() == signalpb.SyncMessage_FetchLatest_STORAGE_MANIFEST { + log.Debug().Msg("Received storage manifest fetch latest notice") + go cli.SyncStorage(ctx) + } + syncSent := msg.GetSent() + if syncSent.GetMessage() != nil || syncSent.GetEditMessage() != nil { + destination := syncSent.DestinationServiceId + var syncDestinationServiceID libsignalgo.ServiceID + if destination != nil { + syncDestinationServiceID, err = libsignalgo.ServiceIDFromString(*destination) + if err != nil { + log.Err(err).Msg("Sync message destination parse error") + return + } + if syncSent.GetDestinationE164() != "" { + aci, pni := syncDestinationServiceID.ToACIAndPNI() + _, err = cli.Store.RecipientStore.UpdateRecipientE164(ctx, aci, pni, syncSent.GetDestinationE164()) + if err != nil { + log.Err(err).Msg("Failed to update recipient E164 after receiving sync message") + } + } + } + if destination == nil && syncSent.GetMessage().GetGroupV2() == nil && syncSent.GetEditMessage().GetDataMessage().GetGroupV2() == nil { + log.Warn().Msg("sync message sent destination is nil") + } else if msg.Sent.Message != nil { + // TODO handle expiration start ts, and maybe the sync message ts? + cli.incomingDataMessage(ctx, msg.Sent.Message, cli.Store.ACI, syncDestinationServiceID, envelope.GetServerTimestamp()) + } else if msg.Sent.EditMessage != nil { + cli.incomingEditMessage(ctx, msg.Sent.EditMessage, cli.Store.ACI, syncDestinationServiceID, envelope.GetServerTimestamp()) + } + } + if msg.Contacts != nil { + log.Debug().Msg("Recieved sync message contacts") + blob := msg.Contacts.Blob + if blob != nil { + contactsBytes, err := DownloadAttachmentWithPointer(ctx, blob, nil) + if err != nil { + log.Err(err).Msg("Contacts Sync DownloadAttachment error") + } + // unmarshall contacts + contacts, avatars, err := unmarshalContactDetailsMessages(contactsBytes) + if err != nil { + log.Err(err).Msg("Contacts Sync unmarshalContactDetailsMessages error") + } + log.Debug().Int("contact_count", len(contacts)).Msg("Contacts Sync received contacts") + convertedContacts := make([]*types.Recipient, 0, len(contacts)) + err = cli.Store.DoContactTxn(ctx, func(ctx context.Context) error { + for i, signalContact := range contacts { + if signalContact.Aci == nil || *signalContact.Aci == "" { + // TODO lookup PNI via CDSI and store that when ACI is missing? + log.Info(). + Any("contact", signalContact). + Msg("Signal Contact UUID is nil, skipping") + continue + } + contact, err := cli.StoreContactDetailsAsContact(ctx, signalContact, &avatars[i]) + if err != nil { + return err + } + convertedContacts = append(convertedContacts, contact) + } + return nil + }) + if err != nil { + log.Err(err).Msg("Error storing contacts") + } else { + handlerSuccess = cli.handleEvent(&events.ContactList{ + Contacts: convertedContacts, + }) + } + } + } + if msg.Read != nil { + handlerSuccess = cli.handleEvent(&events.ReadSelf{ + Timestamp: envelope.GetTimestamp(), + Messages: msg.GetRead(), + }) + } + if msg.DeleteForMe != nil { + handlerSuccess = cli.handleEvent(&events.DeleteForMe{ + Timestamp: envelope.GetTimestamp(), + SyncMessage_DeleteForMe: msg.DeleteForMe, + }) + } + return +} + func (cli *Client) handlePNISignatureMessage(ctx context.Context, sender libsignalgo.ServiceID, msg *signalpb.PniSignatureMessage) error { if sender.Type != libsignalgo.ServiceIDTypeACI { return fmt.Errorf("PNI signature message sender is not an ACI") From aab8af046c60c826d471fd17f88fde838b069cd6 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Thu, 20 Nov 2025 13:29:38 +0200 Subject: [PATCH 454/580] signalmeow: drop DMs from blocked contacts on signal --- pkg/signalmeow/receiving.go | 61 +++++++++++++------ pkg/signalmeow/storageservice.go | 4 ++ pkg/signalmeow/store/backup_store.go | 4 +- pkg/signalmeow/store/container.go | 2 +- pkg/signalmeow/store/device.go | 3 + pkg/signalmeow/store/recipient_store.go | 38 ++++++++++-- pkg/signalmeow/store/upgrades/00-latest.sql | 3 +- .../store/upgrades/23-recipient-blocked.sql | 2 + pkg/signalmeow/types/contact.go | 1 + 9 files changed, 94 insertions(+), 24 deletions(-) create mode 100644 pkg/signalmeow/store/upgrades/23-recipient-blocked.sql diff --git a/pkg/signalmeow/receiving.go b/pkg/signalmeow/receiving.go index dc678e4..9e035ce 100644 --- a/pkg/signalmeow/receiving.go +++ b/pkg/signalmeow/receiving.go @@ -548,13 +548,20 @@ func (cli *Client) handleDecryptedResult( } } - sendDeliveryReceipt := true + isBlocked, err := cli.Store.RecipientStore.IsBlocked(ctx, theirServiceID.UUID) + if err != nil { + log.Err(err).Stringer("sender", theirServiceID).Msg("Failed to check if sender is blocked") + } + + var sendDeliveryReceipt bool if content.DataMessage != nil { - handlerSuccess = cli.incomingDataMessage(ctx, content.DataMessage, theirServiceID.UUID, theirServiceID, envelope.GetServerTimestamp()) + handlerSuccess, sendDeliveryReceipt = cli.incomingDataMessage( + ctx, content.DataMessage, theirServiceID.UUID, theirServiceID, envelope.GetServerTimestamp(), isBlocked, + ) } else if content.EditMessage != nil { - handlerSuccess = cli.incomingEditMessage(ctx, content.EditMessage, theirServiceID.UUID, theirServiceID, envelope.GetServerTimestamp()) - } else { - sendDeliveryReceipt = false + handlerSuccess, sendDeliveryReceipt = cli.incomingEditMessage( + ctx, content.EditMessage, theirServiceID.UUID, theirServiceID, envelope.GetServerTimestamp(), isBlocked, + ) } if sendDeliveryReceipt && handlerSuccess { err = cli.sendDeliveryReceipts(ctx, []uint64{content.DataMessage.GetTimestamp()}, theirServiceID.UUID) @@ -563,7 +570,7 @@ func (cli *Client) handleDecryptedResult( } } - if content.TypingMessage != nil { + if content.TypingMessage != nil && (!isBlocked || content.TypingMessage.GetGroupId() != nil) { var groupID types.GroupIdentifier if content.TypingMessage.GetGroupId() != nil { gidBytes := content.TypingMessage.GetGroupId() @@ -581,7 +588,7 @@ func (cli *Client) handleDecryptedResult( } // DM call message (group call is an opaque callMessage and a groupCallUpdate in a dataMessage) - if content.CallMessage != nil && (content.CallMessage.Offer != nil || content.CallMessage.Hangup != nil) { + if content.CallMessage != nil && (content.CallMessage.Offer != nil || content.CallMessage.Hangup != nil) && !isBlocked { handlerSuccess = cli.handleEvent(&events.Call{ Info: events.MessageInfo{ Sender: theirServiceID.UUID, @@ -673,9 +680,9 @@ func (cli *Client) handleSyncMessage(ctx context.Context, msg *signalpb.SyncMess log.Warn().Msg("sync message sent destination is nil") } else if msg.Sent.Message != nil { // TODO handle expiration start ts, and maybe the sync message ts? - cli.incomingDataMessage(ctx, msg.Sent.Message, cli.Store.ACI, syncDestinationServiceID, envelope.GetServerTimestamp()) + cli.incomingDataMessage(ctx, msg.Sent.Message, cli.Store.ACI, syncDestinationServiceID, envelope.GetServerTimestamp(), false) } else if msg.Sent.EditMessage != nil { - cli.incomingEditMessage(ctx, msg.Sent.EditMessage, cli.Store.ACI, syncDestinationServiceID, envelope.GetServerTimestamp()) + cli.incomingEditMessage(ctx, msg.Sent.EditMessage, cli.Store.ACI, syncDestinationServiceID, envelope.GetServerTimestamp(), false) } } if msg.Contacts != nil { @@ -784,7 +791,14 @@ func (cli *Client) handlePNISignatureMessage(ctx context.Context, sender libsign return nil } -func (cli *Client) incomingEditMessage(ctx context.Context, editMessage *signalpb.EditMessage, messageSenderACI uuid.UUID, chatRecipient libsignalgo.ServiceID, serverTimestamp uint64) bool { +func (cli *Client) incomingEditMessage( + ctx context.Context, + editMessage *signalpb.EditMessage, + messageSenderACI uuid.UUID, + chatRecipient libsignalgo.ServiceID, + serverTimestamp uint64, + isBlocked bool, +) (handlerSuccess, sendDeliveryReceipt bool) { // If it's a group message, get the ID and invalidate cache if necessary var groupID types.GroupIdentifier var groupRevision uint32 @@ -796,9 +810,12 @@ func (cli *Client) incomingEditMessage(ctx context.Context, editMessage *signalp groupID, err = cli.StoreMasterKey(ctx, masterKey) if err != nil { zerolog.Ctx(ctx).Err(err).Msg("StoreMasterKey error") - return false + return } groupRevision = editMessage.GetDataMessage().GetGroupV2().GetRevision() + } else if isBlocked { + zerolog.Ctx(ctx).Debug().Msg("Dropping direct message from blocked user") + return true, false } return cli.handleEvent(&events.ChatEvent{ Info: events.MessageInfo{ @@ -808,17 +825,24 @@ func (cli *Client) incomingEditMessage(ctx context.Context, editMessage *signalp ServerTimestamp: serverTimestamp, }, Event: editMessage, - }) + }), true } -func (cli *Client) incomingDataMessage(ctx context.Context, dataMessage *signalpb.DataMessage, messageSenderACI uuid.UUID, chatRecipient libsignalgo.ServiceID, serverTimestamp uint64) bool { +func (cli *Client) incomingDataMessage( + ctx context.Context, + dataMessage *signalpb.DataMessage, + messageSenderACI uuid.UUID, + chatRecipient libsignalgo.ServiceID, + serverTimestamp uint64, + isBlocked bool, +) (handlerSuccess, sendDeliveryReceipt bool) { // If there's a profile key, save it if dataMessage.ProfileKey != nil { profileKey := libsignalgo.ProfileKey(dataMessage.ProfileKey) err := cli.Store.RecipientStore.StoreProfileKey(ctx, messageSenderACI, profileKey) if err != nil { zerolog.Ctx(ctx).Err(err).Msg("StoreProfileKey error") - return false + return } } @@ -833,9 +857,12 @@ func (cli *Client) incomingDataMessage(ctx context.Context, dataMessage *signalp groupID, err = cli.StoreMasterKey(ctx, masterKey) if err != nil { zerolog.Ctx(ctx).Err(err).Msg("StoreMasterKey error") - return false + return } groupRevision = dataMessage.GetGroupV2().GetRevision() + } else if isBlocked { + zerolog.Ctx(ctx).Debug().Msg("Dropping direct message from blocked user") + return true, false } evtInfo := events.MessageInfo{ @@ -851,12 +878,12 @@ func (cli *Client) incomingDataMessage(ctx context.Context, dataMessage *signalp Info: evtInfo, Timestamp: dataMessage.GetTimestamp(), IsRinging: isRinging, - }) + }), true } else { return cli.handleEvent(&events.ChatEvent{ Info: evtInfo, Event: dataMessage, - }) + }), true } } diff --git a/pkg/signalmeow/storageservice.go b/pkg/signalmeow/storageservice.go index 06b0283..7c35dec 100644 --- a/pkg/signalmeow/storageservice.go +++ b/pkg/signalmeow/storageservice.go @@ -99,6 +99,10 @@ func (cli *Client) processStorageInTxn(ctx context.Context, update *StorageUpdat changed = changed || recipient.E164 != contact.E164 recipient.E164 = contact.E164 } + if contact.Blocked != recipient.Blocked { + changed = true + recipient.Blocked = contact.Blocked + } topLevelChanged = changed return }) diff --git a/pkg/signalmeow/store/backup_store.go b/pkg/signalmeow/store/backup_store.go index 4575b05..fb5d5ff 100644 --- a/pkg/signalmeow/store/backup_store.go +++ b/pkg/signalmeow/store/backup_store.go @@ -161,9 +161,11 @@ func (s *sqlStore) AddBackupRecipient(ctx context.Context, recipient *backuppb.R if dest.Contact.ProfileGivenName != nil || dest.Contact.ProfileFamilyName != nil { recipient.Profile.Name = strings.TrimSpace(fmt.Sprintf("%s %s", dest.Contact.GetProfileGivenName(), dest.Contact.GetProfileFamilyName())) } + recipient.Blocked = dest.Contact.Blocked changed = oldRecipient.E164 != recipient.E164 || oldRecipient.Profile.Key != recipient.Profile.Key || - oldRecipient.Profile.Name != recipient.Profile.Name + oldRecipient.Profile.Name != recipient.Profile.Name || + oldRecipient.Blocked != recipient.Blocked return }) if err != nil { diff --git a/pkg/signalmeow/store/container.go b/pkg/signalmeow/store/container.go index f6842ac..e6335e5 100644 --- a/pkg/signalmeow/store/container.go +++ b/pkg/signalmeow/store/container.go @@ -85,7 +85,7 @@ func (c *Container) scanDevice(row dbutil.Scannable) (*Device, error) { device.AccountEntropyPool = libsignalgo.AccountEntropyPool(accountEntropyPool.String) device.EphemeralBackupKey = libsignalgo.BytesToBackupKey(ephemeralBackupKey) device.MediaRootBackupKey = libsignalgo.BytesToBackupKey(mediaRootBackupKey) - baseStore := &sqlStore{Container: c, AccountID: device.ACI} + baseStore := &sqlStore{Container: c, AccountID: device.ACI, blockCache: make(map[uuid.UUID]bool)} aciStore := &scopedSQLStore{Container: c, AccountID: device.ACI, ServiceID: device.ACIServiceID()} pniStore := &scopedSQLStore{Container: c, AccountID: device.ACI, ServiceID: device.PNIServiceID()} device.ACIPreKeyStore = aciStore diff --git a/pkg/signalmeow/store/device.go b/pkg/signalmeow/store/device.go index aabee03..8843ddf 100644 --- a/pkg/signalmeow/store/device.go +++ b/pkg/signalmeow/store/device.go @@ -18,6 +18,9 @@ type sqlStore struct { AccountID uuid.UUID contactLock sync.Mutex + + blockCacheLock sync.RWMutex + blockCache map[uuid.UUID]bool } type scopedSQLStore struct { diff --git a/pkg/signalmeow/store/recipient_store.go b/pkg/signalmeow/store/recipient_store.go index 9e2bb8e..00646df 100644 --- a/pkg/signalmeow/store/recipient_store.go +++ b/pkg/signalmeow/store/recipient_store.go @@ -38,6 +38,7 @@ type RecipientStore interface { MyProfileKey(ctx context.Context) (*libsignalgo.ProfileKey, error) LoadAndUpdateRecipient(ctx context.Context, aci, pni uuid.UUID, updater RecipientUpdaterFunc) (*types.Recipient, error) + IsBlocked(ctx context.Context, aci uuid.UUID) (bool, error) LoadRecipientByE164(ctx context.Context, e164 string) (*types.Recipient, error) StoreRecipient(ctx context.Context, recipient *types.Recipient) error UpdateRecipientE164(ctx context.Context, aci, pni uuid.UUID, e164 string) (*types.Recipient, error) @@ -62,7 +63,8 @@ const ( profile_about_emoji, profile_avatar_path, profile_fetched_at, - needs_pni_signature + needs_pni_signature, + blocked FROM signalmeow_recipients WHERE account_id = $1 ` @@ -87,9 +89,10 @@ const ( profile_about_emoji, profile_avatar_path, profile_fetched_at, - needs_pni_signature + needs_pni_signature, + blocked ) - VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14) + VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15) ON CONFLICT (account_id, aci_uuid) DO UPDATE SET pni_uuid = excluded.pni_uuid, e164_number = excluded.e164_number, @@ -102,7 +105,8 @@ const ( profile_about_emoji = excluded.profile_about_emoji, profile_avatar_path = excluded.profile_avatar_path, profile_fetched_at = excluded.profile_fetched_at, - needs_pni_signature = excluded.needs_pni_signature + needs_pni_signature = excluded.needs_pni_signature, + blocked = excluded.blocked ` upsertPNIRecipientQuery = ` INSERT INTO signalmeow_recipients ( @@ -139,6 +143,7 @@ func scanRecipient(row dbutil.Scannable) (*types.Recipient, error) { &recipient.Profile.AvatarPath, &profileFetchedAt, &recipient.NeedsPNISignature, + &recipient.Blocked, ) if errors.Is(err, sql.ErrNoRows) { return nil, nil @@ -208,6 +213,13 @@ func (s *sqlStore) LoadAndUpdateRecipient(ctx context.Context, aci, pni uuid.UUI return false, nil } } + defer func() { + if outRecipient != nil && outRecipient.ACI != uuid.Nil && outErr == nil { + s.blockCacheLock.Lock() + s.blockCache[outRecipient.ACI] = outRecipient.Blocked + s.blockCacheLock.Unlock() + } + }() if ctx.Value(contextKeyContactLock) == nil { s.contactLock.Lock() defer s.contactLock.Unlock() @@ -295,6 +307,20 @@ func (s *sqlStore) LoadAndUpdateRecipient(ctx context.Context, aci, pni uuid.UUI return } +func (s *sqlStore) IsBlocked(ctx context.Context, aci uuid.UUID) (bool, error) { + s.blockCacheLock.RLock() + cachedVal, ok := s.blockCache[aci] + s.blockCacheLock.RUnlock() + if ok { + return cachedVal, nil + } + recipient, err := s.LoadAndUpdateRecipient(ctx, aci, uuid.Nil, nil) + if err != nil { + return false, err + } + return recipient.Blocked, nil +} + func (s *sqlStore) UpdateRecipientE164(ctx context.Context, aci, pni uuid.UUID, e164 string) (*types.Recipient, error) { return s.LoadAndUpdateRecipient(ctx, aci, pni, func(recipient *types.Recipient) (bool, error) { if recipient.E164 != e164 { @@ -341,7 +367,11 @@ func (s *sqlStore) StoreRecipient(ctx context.Context, recipient *types.Recipien recipient.Profile.AvatarPath, dbutil.UnixMilliPtr(recipient.Profile.FetchedAt), recipient.NeedsPNISignature, + recipient.Blocked, ) + s.blockCacheLock.Lock() + s.blockCache[recipient.ACI] = recipient.Blocked + s.blockCacheLock.Unlock() } else if recipient.PNI != uuid.Nil { _, err = s.db.Exec( ctx, diff --git a/pkg/signalmeow/store/upgrades/00-latest.sql b/pkg/signalmeow/store/upgrades/00-latest.sql index 2c550c9..ddf871a 100644 --- a/pkg/signalmeow/store/upgrades/00-latest.sql +++ b/pkg/signalmeow/store/upgrades/00-latest.sql @@ -1,4 +1,4 @@ --- v0 -> v22 (compatible with v13+): Latest revision +-- v0 -> v23 (compatible with v13+): Latest revision CREATE TABLE signalmeow_device ( aci_uuid TEXT PRIMARY KEY, @@ -117,6 +117,7 @@ CREATE TABLE signalmeow_recipients ( profile_avatar_path TEXT NOT NULL DEFAULT '', profile_fetched_at BIGINT, needs_pni_signature BOOLEAN NOT NULL DEFAULT false, + blocked BOOLEAN NOT NULL DEFAULT false, CONSTRAINT signalmeow_contacts_account_id_fkey FOREIGN KEY (account_id) REFERENCES signalmeow_device (aci_uuid) ON DELETE CASCADE ON UPDATE CASCADE, diff --git a/pkg/signalmeow/store/upgrades/23-recipient-blocked.sql b/pkg/signalmeow/store/upgrades/23-recipient-blocked.sql new file mode 100644 index 0000000..3a9654a --- /dev/null +++ b/pkg/signalmeow/store/upgrades/23-recipient-blocked.sql @@ -0,0 +1,2 @@ +-- v23 (compatible with v13+): Store block status for recipients +ALTER TABLE signalmeow_recipients ADD COLUMN blocked BOOLEAN NOT NULL DEFAULT false; diff --git a/pkg/signalmeow/types/contact.go b/pkg/signalmeow/types/contact.go index 53852aa..bed25ac 100644 --- a/pkg/signalmeow/types/contact.go +++ b/pkg/signalmeow/types/contact.go @@ -55,6 +55,7 @@ type Recipient struct { Profile Profile NeedsPNISignature bool + Blocked bool } type ContactAvatar struct { From 67f53eb68ff633f87b2f0df43271bb6c0aaa0278 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Thu, 20 Nov 2025 17:15:32 +0200 Subject: [PATCH 455/580] signalmeow/receiving: fix handling missing sender address --- pkg/signalmeow/receiving.go | 31 ++++++++++++++++++------------- 1 file changed, 18 insertions(+), 13 deletions(-) diff --git a/pkg/signalmeow/receiving.go b/pkg/signalmeow/receiving.go index 9e035ce..12a360f 100644 --- a/pkg/signalmeow/receiving.go +++ b/pkg/signalmeow/receiving.go @@ -417,8 +417,17 @@ func (cli *Client) handleDecryptedResult( }() } - theirServiceID, err := result.SenderAddress.NameServiceID() - if err != nil { + var theirServiceID libsignalgo.ServiceID + var err error + if result.SenderAddress == nil { + log.Err(result.Err). + Bool("urgent", envelope.GetUrgent()). + Stringer("content_hint", result.ContentHint). + Uint64("server_ts", envelope.GetServerTimestamp()). + Uint64("client_ts", envelope.GetTimestamp()). + Msg("No sender address received") + return nil + } else if theirServiceID, err = result.SenderAddress.NameServiceID(); err != nil { log.Warn(). Uint64("server_ts", envelope.GetServerTimestamp()). Uint64("client_ts", envelope.GetTimestamp()). @@ -437,17 +446,7 @@ func (cli *Client) handleDecryptedResult( // result.Err is set if there was an error during decryption and we // should notifiy the user that the message could not be decrypted if result.Err != nil { - logEvt := log.Err(result.Err). - Bool("urgent", envelope.GetUrgent()). - Stringer("content_hint", result.ContentHint). - Uint64("server_ts", envelope.GetServerTimestamp()). - Uint64("client_ts", envelope.GetTimestamp()) - if result.SenderAddress == nil { - logEvt.Msg("Decryption error with unknown sender") - return nil - } if errors.Is(result.Err, EventAlreadyProcessed) { - logEvt.Discard().Msg("") log.Debug().Err(result.Err). Bool("urgent", envelope.GetUrgent()). Stringer("content_hint", result.ContentHint). @@ -457,7 +456,13 @@ func (cli *Client) handleDecryptedResult( Msg("Ignoring already processed event") return nil } - logEvt.Stringer("sender", theirServiceID).Msg("Decryption error with known sender") + log.Err(result.Err). + Bool("urgent", envelope.GetUrgent()). + Stringer("content_hint", result.ContentHint). + Uint64("server_ts", envelope.GetServerTimestamp()). + Uint64("client_ts", envelope.GetTimestamp()). + Stringer("sender", theirServiceID). + Msg("Decryption error with known sender") // Only send decryption error event if the message was urgent, // to prevent spamming errors for typing notifications and whatnot if envelope.GetUrgent() && From 2d7eec319f09a0e9e150399250c3d29fb867ccde Mon Sep 17 00:00:00 2001 From: Nick Mills-Barrett Date: Mon, 24 Nov 2025 15:20:48 +0000 Subject: [PATCH 456/580] signalmeow/web: use exsync.Map for response channels (#621) Co-authored-by: Tulir Asokan --- go.mod | 2 +- go.sum | 4 ++-- pkg/signalmeow/web/signalwebsocket.go | 16 ++++++---------- 3 files changed, 9 insertions(+), 13 deletions(-) diff --git a/go.mod b/go.mod index 9cd9dbb..a1be9e8 100644 --- a/go.mod +++ b/go.mod @@ -12,7 +12,7 @@ require ( github.com/rs/zerolog v1.34.0 github.com/stretchr/testify v1.11.1 github.com/tidwall/gjson v1.18.0 - go.mau.fi/util v0.9.3 + go.mau.fi/util v0.9.4-0.20251124151504-71e0e3476592 golang.org/x/crypto v0.44.0 golang.org/x/exp v0.0.0-20251113190631-e25ba8c21ef6 golang.org/x/net v0.47.0 diff --git a/go.sum b/go.sum index 835ede2..aeb8cf5 100644 --- a/go.sum +++ b/go.sum @@ -65,8 +65,8 @@ github.com/tidwall/sjson v1.2.5 h1:kLy8mja+1c9jlljvWTlSazM7cKDRfJuR/bOJhcY5NcY= github.com/tidwall/sjson v1.2.5/go.mod h1:Fvgq9kS/6ociJEDnK0Fk1cpYF4FIW6ZF7LAe+6jwd28= github.com/yuin/goldmark v1.7.13 h1:GPddIs617DnBLFFVJFgpo1aBfe/4xcvMc3SB5t/D0pA= github.com/yuin/goldmark v1.7.13/go.mod h1:ip/1k0VRfGynBgxOz0yCqHrbZXhcjxyuS66Brc7iBKg= -go.mau.fi/util v0.9.3 h1:aqNF8KDIN8bFpFbybSk+mEBil7IHeBwlujfyTnvP0uU= -go.mau.fi/util v0.9.3/go.mod h1:krWWfBM1jWTb5f8NCa2TLqWMQuM81X7TGQjhMjBeXmQ= +go.mau.fi/util v0.9.4-0.20251124151504-71e0e3476592 h1:qSGoV3kSle4DJIFNTK7AdA3NP5MuA6tlTvQrCKsY9iU= +go.mau.fi/util v0.9.4-0.20251124151504-71e0e3476592/go.mod h1:krWWfBM1jWTb5f8NCa2TLqWMQuM81X7TGQjhMjBeXmQ= go.mau.fi/zeroconfig v0.2.0 h1:e/OGEERqVRRKlgaro7E6bh8xXiKFSXB3eNNIud7FUjU= go.mau.fi/zeroconfig v0.2.0/go.mod h1:J0Vn0prHNOm493oZoQ84kq83ZaNCYZnq+noI1b1eN8w= golang.org/x/crypto v0.44.0 h1:A97SsFvM3AIwEEmTBiaxPPTYpDC47w720rdiiUvgoAU= diff --git a/pkg/signalmeow/web/signalwebsocket.go b/pkg/signalmeow/web/signalwebsocket.go index ca09208..e062c43 100644 --- a/pkg/signalmeow/web/signalwebsocket.go +++ b/pkg/signalmeow/web/signalwebsocket.go @@ -305,7 +305,7 @@ func (s *SignalWebsocket) connectLoop( retrying = false backoff = initialBackoff - responseChannels := make(map[uint64]chan *signalpb.WebSocketResponseMessage) + responseChannels := exsync.NewMap[uint64, chan *signalpb.WebSocketResponseMessage]() loopCtx, loopCancel := context.WithCancelCause(ctx) var wg sync.WaitGroup wg.Add(3) @@ -388,7 +388,7 @@ func (s *SignalWebsocket) connectLoop( // Clean up ws.Close(websocket.StatusGoingAway, "Going away") - for _, responseChannel := range responseChannels { + for _, responseChannel := range responseChannels.SwapData(nil) { close(responseChannel) } loopCancel(nil) @@ -407,7 +407,7 @@ func readLoop( ctx context.Context, ws *websocket.Conn, incomingRequestChan chan *signalpb.WebSocketRequestMessage, - responseChannels map[uint64]chan *signalpb.WebSocketResponseMessage, + responseChannels *exsync.Map[uint64, chan *signalpb.WebSocketResponseMessage], ) error { log := zerolog.Ctx(ctx).With(). Str("loop", "signal_websocket_read_loop"). @@ -447,7 +447,7 @@ func readLoop( if msg.Response.Id == nil { log.Fatal().Msg("Received response with no id") } - responseChannel, ok := responseChannels[*msg.Response.Id] + responseChannel, ok := responseChannels.Pop(*msg.Response.Id) if !ok { log.Warn(). Uint64("response_id", *msg.Response.Id). @@ -459,10 +459,6 @@ func readLoop( Uint32("response_status", *msg.Response.Status). Msg("Received WS response") responseChannel <- msg.Response - delete(responseChannels, *msg.Response.Id) - log.Debug(). - Uint64("response_id", *msg.Response.Id). - Msg("Deleted response channel for ID") close(responseChannel) } else if *msg.Type == signalpb.WebSocketMessage_UNKNOWN { return fmt.Errorf("received message with unknown type: %v", *msg.Type) @@ -486,7 +482,7 @@ func writeLoop( ctx context.Context, ws *websocket.Conn, sendChannel chan SignalWebsocketSendMessage, - responseChannels map[uint64]chan *signalpb.WebSocketResponseMessage, + responseChannels *exsync.Map[uint64, chan *signalpb.WebSocketResponseMessage], ) error { log := zerolog.Ctx(ctx).With(). Str("loop", "signal_websocket_write_loop"). @@ -509,7 +505,7 @@ func writeLoop( Request: request.RequestMessage, } request.RequestMessage.Id = &i - responseChannels[i] = request.ResponseChannel + responseChannels.Set(i, request.ResponseChannel) path := *request.RequestMessage.Path if len(path) > 30 { path = path[:40] From f8358f6eaf5fc27456bd1fa6ce1226f3e1a6af0e Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Mon, 24 Nov 2025 14:34:29 +0200 Subject: [PATCH 457/580] signalmeow/web: refactor SendRequest parameters --- pkg/signalmeow/groups.go | 3 +-- pkg/signalmeow/profile.go | 8 ++++---- pkg/signalmeow/sending.go | 9 ++++----- pkg/signalmeow/web/signalwebsocket.go | 19 ++++++++++++++++--- 4 files changed, 25 insertions(+), 14 deletions(-) diff --git a/pkg/signalmeow/groups.go b/pkg/signalmeow/groups.go index d938e10..7a3d64b 100644 --- a/pkg/signalmeow/groups.go +++ b/pkg/signalmeow/groups.go @@ -314,8 +314,7 @@ func (cli *Client) fetchNewGroupCreds(ctx context.Context, today time.Time) (*Gr Logger() sevenDaysOut := today.Add(7 * 24 * time.Hour) path := fmt.Sprintf("/v1/certificate/auth/group?redemptionStartSeconds=%d&redemptionEndSeconds=%d&pniAsServiceId=true", today.Unix(), sevenDaysOut.Unix()) - authRequest := web.CreateWSRequest(http.MethodGet, path, nil, nil, nil) - resp, err := cli.AuthedWS.SendRequest(ctx, authRequest) + resp, err := cli.AuthedWS.SendRequest(ctx, http.MethodGet, path, nil, nil) if err != nil { return nil, fmt.Errorf("SendRequest error: %w", err) } diff --git a/pkg/signalmeow/profile.go b/pkg/signalmeow/profile.go index 81f1ed8..9510f37 100644 --- a/pkg/signalmeow/profile.go +++ b/pkg/signalmeow/profile.go @@ -218,12 +218,12 @@ func (cli *Client) fetchProfileWithRequestAndKey(ctx context.Context, signalID u path += "/" + string(credentialRequest) path += "?credentialType=expiringProfileKey" } - profileRequest := web.CreateWSRequest(http.MethodGet, path, nil, nil, nil) + headers := http.Header{} if useUnidentified { - profileRequest.Headers = append(profileRequest.Headers, "unidentified-access-key:"+base64AccessKey) - profileRequest.Headers = append(profileRequest.Headers, "accept-language:en-CA") + headers.Set("Unidentified-Access-Key", base64AccessKey) + headers.Set("Accept-Language", "en-US") } - resp, err := cli.UnauthedWS.SendRequest(ctx, profileRequest) + resp, err := cli.UnauthedWS.SendRequest(ctx, http.MethodGet, path, nil, headers) if err != nil { return nil, fmt.Errorf("error sending request: %w", err) } diff --git a/pkg/signalmeow/sending.go b/pkg/signalmeow/sending.go index 8bfc5a5..11ed08d 100644 --- a/pkg/signalmeow/sending.go +++ b/pkg/signalmeow/sending.go @@ -884,17 +884,16 @@ func (cli *Client) sendContent( return false, err } path := fmt.Sprintf("/v1/messages/%s", recipient) - request := web.CreateWSRequest(http.MethodPut, path, jsonBytes, nil, nil) var response *signalpb.WebSocketResponseMessage if useUnidentifiedSender { log.Trace().Msg("Sending message over unidentified WS") - base64AccessKey := base64.StdEncoding.EncodeToString(accessKey[:]) - request.Headers = append(request.Headers, "unidentified-access-key:"+base64AccessKey) - response, err = cli.UnauthedWS.SendRequest(ctx, request) + response, err = cli.UnauthedWS.SendRequest(ctx, http.MethodPut, path, jsonBytes, http.Header{ + "Unidentified-Access-Key": []string{base64.StdEncoding.EncodeToString(accessKey[:])}, + }) } else { log.Trace().Msg("Sending message over authed WS") - response, err = cli.AuthedWS.SendRequest(ctx, request) + response, err = cli.AuthedWS.SendRequest(ctx, http.MethodPut, path, jsonBytes, nil) } sentUnidentified = useUnidentifiedSender if err != nil { diff --git a/pkg/signalmeow/web/signalwebsocket.go b/pkg/signalmeow/web/signalwebsocket.go index e062c43..75e22e1 100644 --- a/pkg/signalmeow/web/signalwebsocket.go +++ b/pkg/signalmeow/web/signalwebsocket.go @@ -560,13 +560,26 @@ func writeLoop( func (s *SignalWebsocket) SendRequest( ctx context.Context, - request *signalpb.WebSocketRequestMessage, + method, + path string, + body []byte, + headers http.Header, ) (*signalpb.WebSocketResponseMessage, error) { if s == nil { return nil, errors.New("websocket is nil") } - startTime := time.Now() - return s.sendRequestInternal(ctx, request, startTime, 0) + headerArray := make([]string, len(headers)) + for key, values := range headers { + for _, value := range values { + headerArray = append(headerArray, fmt.Sprintf("%s:%s", strings.ToLower(key), value)) + } + } + return s.sendRequestInternal(ctx, &signalpb.WebSocketRequestMessage{ + Verb: &method, + Path: &path, + Body: body, + Headers: headerArray, + }, time.Now(), 0) } func (s *SignalWebsocket) sendRequestInternal( From bd9b96e3a04575ab5bbae58cc18f67dde49956db Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Mon, 24 Nov 2025 15:03:02 +0200 Subject: [PATCH 458/580] signalmeow: move all normal authed requests to websocket --- pkg/connector/client.go | 6 --- pkg/signalmeow/attachments.go | 27 +++++------ pkg/signalmeow/backup.go | 19 +++----- pkg/signalmeow/client.go | 10 ++++ pkg/signalmeow/devicename.go | 13 ++--- pkg/signalmeow/groups.go | 15 ++---- pkg/signalmeow/keys.go | 44 +++++++---------- pkg/signalmeow/profile.go | 5 +- pkg/signalmeow/provisioning.go | 25 ++-------- pkg/signalmeow/pushreg.go | 23 +++------ pkg/signalmeow/receiving.go | 6 +++ pkg/signalmeow/sending.go | 15 +++--- pkg/signalmeow/serviceauth.go | 10 +--- pkg/signalmeow/storageservice.go | 6 +-- pkg/signalmeow/web/signalwebsocket.go | 7 +++ pkg/signalmeow/web/web.go | 69 +++++++++++++++------------ 16 files changed, 129 insertions(+), 171 deletions(-) diff --git a/pkg/connector/client.go b/pkg/connector/client.go index 0ff578f..c85ae35 100644 --- a/pkg/connector/client.go +++ b/pkg/connector/client.go @@ -298,12 +298,6 @@ func (s *SignalClient) postLoginConnect() { } func (s *SignalClient) tryConnect(ctx context.Context, retryCount int, doSync bool) { - err := s.Client.RegisterCapabilities(ctx) - if err != nil { - zerolog.Ctx(ctx).Err(err).Msg("Failed to register capabilities") - } else { - zerolog.Ctx(ctx).Debug().Msg("Successfully registered capabilities") - } ch, err := s.Client.StartReceiveLoops(ctx) if err != nil { zerolog.Ctx(ctx).Err(err).Msg("Failed to start receive loops") diff --git a/pkg/signalmeow/attachments.go b/pkg/signalmeow/attachments.go index 67a55c8..22884fe 100644 --- a/pkg/signalmeow/attachments.go +++ b/pkg/signalmeow/attachments.go @@ -70,8 +70,7 @@ func DownloadAttachmentWithPointer(ctx context.Context, a *signalpb.AttachmentPo } func DownloadAttachment(ctx context.Context, cdnID uint64, cdnKey string, cdnNumber uint32, key, digest []byte, plaintextDigest bool, size uint32) ([]byte, error) { - path := getAttachmentPath(cdnID, cdnKey) - resp, err := web.GetAttachment(ctx, path, cdnNumber, nil) + resp, err := web.GetAttachment(ctx, getAttachmentPath(cdnID, cdnKey), cdnNumber) if err != nil { return nil, err } @@ -174,15 +173,13 @@ func (cli *Client) UploadAttachment(ctx context.Context, body []byte) (*signalpb // Get upload attributes from Signal server attributesPath := "/v4/attachments/form/upload" - username, password := cli.Store.BasicAuthCreds() - opts := &web.HTTPReqOpt{Username: &username, Password: &password} - resp, err := web.SendHTTPRequest(ctx, http.MethodGet, attributesPath, opts) + resp, err := cli.AuthedWS.SendRequest(ctx, http.MethodGet, attributesPath, nil, nil) if err != nil { log.Err(err).Msg("Failed to request upload attributes") return nil, fmt.Errorf("failed to request upload attributes: %w", err) } var uploadAttributes attachmentV4UploadAttributes - err = web.DecodeHTTPResponseBody(ctx, &uploadAttributes, resp) + err = web.DecodeWSResponseBody(ctx, &uploadAttributes, resp) if err != nil { log.Err(err).Msg("Failed to decode upload attributes") return nil, fmt.Errorf("failed to decode upload attributes: %w", err) @@ -192,7 +189,7 @@ func (cli *Client) UploadAttachment(ctx context.Context, body []byte) (*signalpb err = cli.uploadAttachmentTUS(ctx, uploadAttributes, encryptedWithMAC) } else { log.Trace().Msg("Using legacy upload") - err = cli.uploadAttachmentLegacy(ctx, uploadAttributes, encryptedWithMAC, username, password) + err = cli.uploadAttachmentLegacy(ctx, uploadAttributes, encryptedWithMAC) } if err != nil { log.Err(err).Msg("Failed to upload attachment") @@ -218,11 +215,10 @@ func (cli *Client) uploadAttachmentLegacy( ctx context.Context, uploadAttributes attachmentV4UploadAttributes, encryptedWithMAC []byte, - username string, - password string, ) error { + username, password := cli.Store.BasicAuthCreds() // Allocate attachment on CDN - resp, err := web.SendHTTPRequest(ctx, http.MethodPost, "", &web.HTTPReqOpt{ + resp, err := web.SendHTTPRequest(ctx, "", http.MethodPost, "", &web.HTTPReqOpt{ OverrideURL: uploadAttributes.SignedUploadLocation, ContentType: web.ContentTypeOctetStream, Headers: uploadAttributes.Headers, @@ -236,7 +232,7 @@ func (cli *Client) uploadAttachmentLegacy( } // Upload attachment to CDN - resp, err = web.SendHTTPRequest(ctx, http.MethodPut, "", &web.HTTPReqOpt{ + resp, err = web.SendHTTPRequest(ctx, "", http.MethodPut, "", &web.HTTPReqOpt{ OverrideURL: resp.Header.Get("Location"), Body: encryptedWithMAC, ContentType: web.ContentTypeOctetStream, @@ -260,7 +256,7 @@ func (cli *Client) uploadAttachmentTUS( uploadAttributes.Headers["Upload-Length"] = fmt.Sprintf("%d", len(encryptedWithMAC)) uploadAttributes.Headers["Upload-Metadata"] = "filename " + base64.StdEncoding.EncodeToString([]byte(uploadAttributes.Key)) - resp, err := web.SendHTTPRequest(ctx, http.MethodPost, "", &web.HTTPReqOpt{ + resp, err := web.SendHTTPRequest(ctx, "", http.MethodPost, "", &web.HTTPReqOpt{ OverrideURL: uploadAttributes.SignedUploadLocation, Body: encryptedWithMAC, ContentType: web.ContentTypeOffsetOctetStream, @@ -306,8 +302,8 @@ func (cli *Client) UploadGroupAvatar(ctx context.Context, avatarBytes []byte, gi // Get upload form from Signal server formPath := "/v2/groups/avatar/form" - opts := &web.HTTPReqOpt{Username: &groupAuth.Username, Password: &groupAuth.Password, ContentType: web.ContentTypeProtobuf, Host: web.StorageHostname} - resp, err := web.SendHTTPRequest(ctx, http.MethodGet, formPath, opts) + opts := &web.HTTPReqOpt{Username: &groupAuth.Username, Password: &groupAuth.Password, ContentType: web.ContentTypeProtobuf} + resp, err := web.SendHTTPRequest(ctx, web.StorageHostname, http.MethodGet, formPath, opts) if err != nil { log.Err(err).Msg("Error sending request fetching avatar upload form") return "", err @@ -338,10 +334,9 @@ func (cli *Client) UploadGroupAvatar(ctx context.Context, avatarBytes []byte, gi w.Close() // Upload avatar to CDN - resp, err = web.SendHTTPRequest(ctx, http.MethodPost, "", &web.HTTPReqOpt{ + resp, err = web.SendHTTPRequest(ctx, web.CDN1Hostname, http.MethodPost, "", &web.HTTPReqOpt{ Body: requestBody.Bytes(), ContentType: web.ContentType(w.FormDataContentType()), - Host: web.CDN1Hostname, }) if err != nil { log.Err(err).Msg("Error sending request uploading attachment") diff --git a/pkg/signalmeow/backup.go b/pkg/signalmeow/backup.go index 43c2f78..fcbfff0 100644 --- a/pkg/signalmeow/backup.go +++ b/pkg/signalmeow/backup.go @@ -239,7 +239,7 @@ func (cli *Client) deriveTransferKeys() (aesKey, hmacKey [32]byte, err error) { } func downloadTransferArchive(ctx context.Context, meta *TransferArchiveMetadata, writeTo io.Writer) error { - resp, err := web.GetAttachment(ctx, getAttachmentPath(0, meta.Key), meta.CDN, nil) + resp, err := web.GetAttachment(ctx, getAttachmentPath(0, meta.Key), meta.CDN) if err != nil { return fmt.Errorf("failed to download transfer archive: %w", err) } @@ -291,21 +291,14 @@ func (cli *Client) tryRequestTransferArchive(ctx context.Context, timeout time.D reqCtx, cancel := context.WithTimeout(ctx, timeout+15*time.Second) defer cancel() path := "/v1/devices/transfer_archive?timeout=" + strconv.Itoa(int(timeout.Seconds())) - username, password := cli.Store.BasicAuthCreds() - opts := &web.HTTPReqOpt{Username: &username, Password: &password} - resp, err := web.SendHTTPRequest(reqCtx, http.MethodGet, path, opts) - defer func() { - if resp != nil && resp.Body != nil { - _ = resp.Body.Close() - } - }() + resp, err := cli.AuthedWS.SendRequest(reqCtx, http.MethodGet, path, nil, nil) if err != nil { return nil, err - } else if resp.StatusCode == http.StatusNoContent { + } else if resp.GetStatus() == http.StatusNoContent { return nil, nil - } else if resp.StatusCode != http.StatusOK { - return nil, fmt.Errorf("unexpected status code %d", resp.StatusCode) - } else if err = json.NewDecoder(resp.Body).Decode(&respBody); err != nil { + } else if resp.GetStatus() != http.StatusOK { + return nil, fmt.Errorf("unexpected status code %d", resp.GetStatus()) + } else if err = json.Unmarshal(resp.Body, &respBody); err != nil { return nil, fmt.Errorf("failed to decode response: %w", err) } else { return respBody, nil diff --git a/pkg/signalmeow/client.go b/pkg/signalmeow/client.go index 42979c1..ea5eb17 100644 --- a/pkg/signalmeow/client.go +++ b/pkg/signalmeow/client.go @@ -18,7 +18,9 @@ package signalmeow import ( "context" + "encoding/json" "errors" + "net/http" "net/url" "sync" "time" @@ -110,3 +112,11 @@ func (cli *Client) connectUnauthedWS(ctx context.Context) (chan web.SignalWebsoc func (cli *Client) IsLoggedIn() bool { return cli.Store != nil && cli.Store.IsDeviceLoggedIn() } + +func (cli *Client) GetRemoteConfig(ctx context.Context) (json.RawMessage, error) { + resp, err := cli.AuthedWS.SendRequest(ctx, http.MethodGet, "/v2/config", nil, nil) + if err != nil { + return nil, err + } + return resp.Body, web.DecodeWSResponseBody(ctx, nil, resp) +} diff --git a/pkg/signalmeow/devicename.go b/pkg/signalmeow/devicename.go index c22e94d..ceca1e4 100644 --- a/pkg/signalmeow/devicename.go +++ b/pkg/signalmeow/devicename.go @@ -30,7 +30,6 @@ import ( "go.mau.fi/mautrix-signal/pkg/libsignalgo" signalpb "go.mau.fi/mautrix-signal/pkg/signalmeow/protobuf" - "go.mau.fi/mautrix-signal/pkg/signalmeow/web" ) func hmacSHA256(key, input []byte) []byte { @@ -63,18 +62,12 @@ func (cli *Client) updateDeviceName(ctx context.Context, encryptedName []byte) e if err != nil { return fmt.Errorf("failed to marshal device name update request: %w", err) } - username, password := cli.Store.BasicAuthCreds() - resp, err := web.SendHTTPRequest(ctx, http.MethodPut, "/v1/accounts/name", &web.HTTPReqOpt{ - Body: reqData, - Username: &username, - Password: &password, - }) + resp, err := cli.AuthedWS.SendRequest(ctx, http.MethodPut, "/v1/accounts/name", reqData, nil) if err != nil { return fmt.Errorf("failed to send device name update request: %w", err) } - defer resp.Body.Close() - if resp.StatusCode < 200 || resp.StatusCode >= 300 { - return fmt.Errorf("device name update request returned status %d", resp.StatusCode) + if resp.GetStatus() < 200 || resp.GetStatus() >= 300 { + return fmt.Errorf("device name update request returned status %d", resp.GetStatus()) } return nil } diff --git a/pkg/signalmeow/groups.go b/pkg/signalmeow/groups.go index 7a3d64b..39753bb 100644 --- a/pkg/signalmeow/groups.go +++ b/pkg/signalmeow/groups.go @@ -648,9 +648,8 @@ func (cli *Client) fetchGroupWithMasterKey(ctx context.Context, groupMasterKey t Username: &groupAuth.Username, Password: &groupAuth.Password, ContentType: web.ContentTypeProtobuf, - Host: web.StorageHostname, } - response, err := web.SendHTTPRequest(ctx, http.MethodGet, "/v2/groups", opts) + response, err := web.SendHTTPRequest(ctx, web.StorageHostname, http.MethodGet, "/v2/groups", opts) if err != nil { return nil, err } @@ -695,11 +694,10 @@ func (cli *Client) parseGroupResponse(ctx context.Context, response *http.Respon func (cli *Client) DownloadGroupAvatar(ctx context.Context, avatarPath string, groupMasterKey types.SerializedGroupMasterKey) ([]byte, error) { username, password := cli.Store.BasicAuthCreds() opts := &web.HTTPReqOpt{ - Host: web.CDN1Hostname, Username: &username, Password: &password, } - resp, err := web.SendHTTPRequest(ctx, http.MethodGet, avatarPath, opts) + resp, err := web.SendHTTPRequest(ctx, web.CDN1Hostname, http.MethodGet, avatarPath, opts) if err != nil { return nil, fmt.Errorf("failed to send request: %w", err) } @@ -1503,9 +1501,8 @@ func (cli *Client) patchGroup(ctx context.Context, groupChange *signalpb.GroupCh Password: &groupAuth.Password, ContentType: web.ContentTypeProtobuf, Body: requestBody, - Host: web.StorageHostname, } - resp, err := web.SendHTTPRequest(ctx, http.MethodPatch, path, opts) + resp, err := web.SendHTTPRequest(ctx, web.StorageHostname, http.MethodPatch, path, opts) if err != nil { return nil, fmt.Errorf("SendRequest error: %w", err) } @@ -1738,9 +1735,8 @@ func (cli *Client) createGroupOnServer(ctx context.Context, decryptedGroup *Grou Password: &groupAuth.Password, ContentType: web.ContentTypeProtobuf, Body: requestBody, - Host: web.StorageHostname, } - resp, err := web.SendHTTPRequest(ctx, http.MethodPut, path, opts) + resp, err := web.SendHTTPRequest(ctx, web.StorageHostname, http.MethodPut, path, opts) if err != nil { return nil, fmt.Errorf("SendRequest error: %w", err) } @@ -1803,7 +1799,6 @@ func (cli *Client) GetGroupHistoryPage(ctx context.Context, gid types.GroupIdent Username: &groupAuth.Username, Password: &groupAuth.Password, ContentType: web.ContentTypeProtobuf, - Host: web.StorageHostname, Headers: map[string]string{ // TODO actually cache the data and provide real expiry timestamp "Cached-Send-Endorsements": "0", @@ -1811,7 +1806,7 @@ func (cli *Client) GetGroupHistoryPage(ctx context.Context, gid types.GroupIdent } // highest known epoch seems to always be 5, but that may change in the future. includeLastState is always false path := fmt.Sprintf("/v2/groups/logs/%d?maxSupportedChangeEpoch=%d&includeFirstState=%t&includeLastState=false", fromRevision, 5, includeFirstState) - response, err := web.SendHTTPRequest(ctx, http.MethodGet, path, opts) + response, err := web.SendHTTPRequest(ctx, web.StorageHostname, http.MethodGet, path, opts) if err != nil { return nil, err } diff --git a/pkg/signalmeow/keys.go b/pkg/signalmeow/keys.go index a3f2690..4756514 100644 --- a/pkg/signalmeow/keys.go +++ b/pkg/signalmeow/keys.go @@ -97,10 +97,9 @@ func (cli *Client) RegisterAllPreKeys(ctx context.Context, pks store.PreKeyStore KyberPreKeys: kyberPreKeys, IdentityKey: identityKey, } - preKeyUsername := fmt.Sprintf("%s.%d", cli.Store.ACI, cli.Store.DeviceID) log := zerolog.Ctx(ctx).With().Str("action", "register prekeys").Logger() log.Debug().Int("num_prekeys", len(preKeys)).Int("num_kyber_prekeys", len(kyberPreKeys)).Msg("Registering prekeys") - err = RegisterPreKeys(ctx, &generatedPreKeys, pni, preKeyUsername, cli.Store.Password) + err = cli.RegisterPreKeys(ctx, &generatedPreKeys, pni) if err != nil { return fmt.Errorf("failed to register prekeys: %w", err) } @@ -346,11 +345,11 @@ func KyberPreKeyToJSON(kyberPreKey *libsignalgo.KyberPreKeyRecord) (map[string]i var errPrekeyUpload422 = errors.New("http 422 while registering prekeys") -func RegisterPreKeys(ctx context.Context, generatedPreKeys *GeneratedPreKeys, pni bool, username string, password string) error { +func (cli *Client) RegisterPreKeys(ctx context.Context, generatedPreKeys *GeneratedPreKeys, pni bool) error { log := zerolog.Ctx(ctx).With().Str("action", "register prekeys").Logger() // Convert generated prekeys to JSON - preKeysJson := []map[string]interface{}{} - kyberPreKeysJson := []map[string]interface{}{} + preKeysJson := []map[string]any{} + kyberPreKeysJson := []map[string]any{} for _, preKey := range generatedPreKeys.PreKeys { preKeyJson, err := PreKeyToJSON(preKey) if err != nil { @@ -367,32 +366,27 @@ func RegisterPreKeys(ctx context.Context, generatedPreKeys *GeneratedPreKeys, pn } identityKey := generatedPreKeys.IdentityKey - register_json := map[string]interface{}{ + registerJSON := map[string]any{ "preKeys": preKeysJson, "pqPreKeys": kyberPreKeysJson, "identityKey": base64.StdEncoding.EncodeToString(identityKey), } // Send request - jsonBytes, err := json.Marshal(register_json) + jsonBytes, err := json.Marshal(registerJSON) if err != nil { log.Err(err).Msg("Error marshalling register JSON") return err } - opts := &web.HTTPReqOpt{Body: jsonBytes, Username: &username, Password: &password} - resp, err := web.SendHTTPRequest(ctx, http.MethodPut, keysPath(pni), opts) + resp, err := cli.AuthedWS.SendRequest(ctx, http.MethodPut, keysPath(pni), jsonBytes, nil) if err != nil { log.Err(err).Msg("Error sending request") return err } - defer resp.Body.Close() - // status code not 2xx - if resp.StatusCode == 422 { + if resp.GetStatus() == 422 { return errPrekeyUpload422 - } else if resp.StatusCode < 200 || resp.StatusCode >= 300 { - return fmt.Errorf("error registering prekeys: %v", resp.Status) } - return err + return web.DecodeWSResponseBody(ctx, nil, resp) } type prekeyResponse struct { @@ -434,18 +428,17 @@ func (cli *Client) FetchAndProcessPreKey(ctx context.Context, theirServiceID lib deviceIDPath = "/" + fmt.Sprint(specificDeviceID) } path := "/v2/keys/" + theirServiceID.String() + deviceIDPath + "?pq=true" - username, password := cli.Store.BasicAuthCreds() - resp, err := web.SendHTTPRequest(ctx, http.MethodGet, path, &web.HTTPReqOpt{Username: &username, Password: &password}) + resp, err := cli.AuthedWS.SendRequest(ctx, http.MethodGet, path, nil, nil) if err != nil { return fmt.Errorf("error sending request: %w", err) } - var prekeyResponse prekeyResponse - err = web.DecodeHTTPResponseBody(ctx, &prekeyResponse, resp) + var respData prekeyResponse + err = web.DecodeWSResponseBody(ctx, &respData, resp) if err != nil { return fmt.Errorf("error decoding response body: %w", err) } - rawIdentityKey, err := addBase64PaddingAndDecode(prekeyResponse.IdentityKey) + rawIdentityKey, err := addBase64PaddingAndDecode(respData.IdentityKey) if err != nil { return fmt.Errorf("error decoding identity key: %w", err) } @@ -458,7 +451,7 @@ func (cli *Client) FetchAndProcessPreKey(ctx context.Context, theirServiceID lib } // Process each prekey in response (should only be one at the moment) - for _, d := range prekeyResponse.Devices { + for _, d := range respData.Devices { var publicKey *libsignalgo.PublicKey var preKeyID uint32 if d.PreKey != nil { @@ -555,19 +548,18 @@ func keysPath(pni bool) string { func (cli *Client) GetMyKeyCounts(ctx context.Context, pni bool) (int, int, error) { log := zerolog.Ctx(ctx).With().Str("action", "get my key counts").Logger() - username, password := cli.Store.BasicAuthCreds() - resp, err := web.SendHTTPRequest(ctx, http.MethodGet, keysPath(pni), &web.HTTPReqOpt{Username: &username, Password: &password}) + resp, err := cli.AuthedWS.SendRequest(ctx, http.MethodGet, keysPath(pni), nil, nil) if err != nil { log.Err(err).Msg("Error sending request") return 0, 0, err } - var preKeyCountResponse preKeyCountResponse - err = web.DecodeHTTPResponseBody(ctx, &preKeyCountResponse, resp) + var respData preKeyCountResponse + err = web.DecodeWSResponseBody(ctx, &respData, resp) if err != nil { log.Err(err).Msg("Fetching prekey counts, error with response body") return 0, 0, err } - return preKeyCountResponse.Count, preKeyCountResponse.PQCount, err + return respData.Count, respData.PQCount, err } func (cli *Client) CheckAndUploadNewPreKeys(ctx context.Context, pks store.PreKeyStore) error { diff --git a/pkg/signalmeow/profile.go b/pkg/signalmeow/profile.go index 9510f37..4284a8b 100644 --- a/pkg/signalmeow/profile.go +++ b/pkg/signalmeow/profile.go @@ -229,7 +229,7 @@ func (cli *Client) fetchProfileWithRequestAndKey(ctx context.Context, signalID u } var profile types.Profile profile.FetchedAt = time.Now() - logEvt := log.Trace().Uint32("status_code", resp.GetStatus()) + logEvt := log.Trace().Uint32("status_code", resp.GetStatus()).Str("resp_message", resp.GetMessage()) if logEvt.Enabled() { if json.Valid(resp.Body) { logEvt.RawJSON("response_data", resp.Body) @@ -288,11 +288,10 @@ func (cli *Client) fetchProfileWithRequestAndKey(ctx context.Context, signalID u func (cli *Client) DownloadUserAvatar(ctx context.Context, avatarPath string, profileKey libsignalgo.ProfileKey) ([]byte, error) { username, password := cli.Store.BasicAuthCreds() opts := &web.HTTPReqOpt{ - Host: web.CDN1Hostname, Username: &username, Password: &password, } - resp, err := web.SendHTTPRequest(ctx, http.MethodGet, avatarPath, opts) + resp, err := web.SendHTTPRequest(ctx, web.CDN1Hostname, http.MethodGet, avatarPath, opts) if err != nil { return nil, fmt.Errorf("failed to send request: %w", err) } diff --git a/pkg/signalmeow/provisioning.go b/pkg/signalmeow/provisioning.go index d877276..2343e32 100644 --- a/pkg/signalmeow/provisioning.go +++ b/pkg/signalmeow/provisioning.go @@ -366,36 +366,19 @@ var signalCapabilities = map[string]any{ var signalCapabilitiesBody = exerrors.Must(json.Marshal(signalCapabilities)) func (cli *Client) RegisterCapabilities(ctx context.Context) error { - username, password := cli.Store.BasicAuthCreds() - resp, err := web.SendHTTPRequest(ctx, http.MethodPut, "/v1/devices/capabilities", &web.HTTPReqOpt{ - Body: signalCapabilitiesBody, - Username: &username, - Password: &password, - ContentType: web.ContentTypeJSON, - }) - if resp != nil { - _ = resp.Body.Close() - } + resp, err := cli.AuthedWS.SendRequest(ctx, http.MethodPut, "/v1/devices/capabilities", signalCapabilitiesBody, nil) if err != nil { return err - } else if resp.StatusCode >= 400 { - return fmt.Errorf("unexpected status code %d", resp.StatusCode) } - return nil + return web.DecodeWSResponseBody(ctx, nil, resp) } func (cli *Client) Unlink(ctx context.Context) error { - username, password := cli.Store.BasicAuthCreds() - resp, err := web.SendHTTPRequest(ctx, http.MethodDelete, fmt.Sprintf("/v1/devices/%d", cli.Store.DeviceID), &web.HTTPReqOpt{ - Username: &username, - Password: &password, - }) + resp, err := cli.AuthedWS.SendRequest(ctx, http.MethodDelete, fmt.Sprintf("/v1/devices/%d", cli.Store.DeviceID), nil, nil) if err != nil { return err - } else if resp.StatusCode >= 400 { - return fmt.Errorf("unexpected status code %d", resp.StatusCode) } - return nil + return web.DecodeWSResponseBody(ctx, nil, resp) } func confirmDevice( diff --git a/pkg/signalmeow/pushreg.go b/pkg/signalmeow/pushreg.go index fe45785..79d0318 100644 --- a/pkg/signalmeow/pushreg.go +++ b/pkg/signalmeow/pushreg.go @@ -19,9 +19,9 @@ package signalmeow import ( "context" "encoding/json" - "fmt" "net/http" + signalpb "go.mau.fi/mautrix-signal/pkg/signalmeow/protobuf" "go.mau.fi/mautrix-signal/pkg/signalmeow/web" ) @@ -36,30 +36,21 @@ type ReqRegisterAPNs struct { } func (cli *Client) registerPush(ctx context.Context, pushType string, data any) error { - username, password := cli.Store.BasicAuthCreds() - req := &web.HTTPReqOpt{ - Username: &username, - Password: &password, - } - var method string + var resp *signalpb.WebSocketResponseMessage + var err error if data != nil { - method = http.MethodPut - req.ContentType = web.ContentTypeJSON - var err error - req.Body, err = json.Marshal(data) + body, err := json.Marshal(data) if err != nil { return err } + resp, err = cli.AuthedWS.SendRequest(ctx, http.MethodPut, "/v1/accounts/"+pushType, body, nil) } else { - method = http.MethodDelete + resp, err = cli.AuthedWS.SendRequest(ctx, http.MethodDelete, "/v1/accounts/"+pushType, nil, nil) } - resp, err := web.SendHTTPRequest(ctx, method, "/v1/accounts/"+pushType, req) if err != nil { return err - } else if resp.StatusCode >= 300 || resp.StatusCode < 200 { - return fmt.Errorf("unexpected status code %d", resp.StatusCode) } - return nil + return web.DecodeWSResponseBody(ctx, nil, resp) } func (cli *Client) RegisterFCM(ctx context.Context, token string) error { diff --git a/pkg/signalmeow/receiving.go b/pkg/signalmeow/receiving.go index 12a360f..622f18c 100644 --- a/pkg/signalmeow/receiving.go +++ b/pkg/signalmeow/receiving.go @@ -255,6 +255,12 @@ func (cli *Client) StartReceiveLoops(ctx context.Context) (chan SignalConnection return case <-initialConnectChan: log.Info().Msg("Both websockets connected, sending contacts sync request") + err = cli.RegisterCapabilities(ctx) + if err != nil { + zerolog.Ctx(ctx).Err(err).Msg("Failed to register capabilities") + } else { + zerolog.Ctx(ctx).Debug().Msg("Successfully registered capabilities") + } // TODO hacky if cli.SyncContactsOnConnect { cli.SendContactSyncRequest(loopCtx) diff --git a/pkg/signalmeow/sending.go b/pkg/signalmeow/sending.go index 11ed08d..ee35cd4 100644 --- a/pkg/signalmeow/sending.go +++ b/pkg/signalmeow/sending.go @@ -70,17 +70,15 @@ func (cli *Client) senderCertificate(ctx context.Context, e164 bool) (*libsignal } var r response - username, password := cli.Store.BasicAuthCreds() - opts := &web.HTTPReqOpt{Username: &username, Password: &password} var query string if !e164 { query = "?includeE164=false" } - resp, err := web.SendHTTPRequest(ctx, http.MethodGet, "/v1/certificate/delivery"+query, opts) + resp, err := cli.AuthedWS.SendRequest(ctx, http.MethodGet, "/v1/certificate/delivery"+query, nil, nil) if err != nil { return nil, err } - err = web.DecodeHTTPResponseBody(ctx, &r, resp) + err = web.DecodeWSResponseBody(ctx, &r, resp) if err != nil { return nil, err } @@ -886,14 +884,15 @@ func (cli *Client) sendContent( path := fmt.Sprintf("/v1/messages/%s", recipient) var response *signalpb.WebSocketResponseMessage + header := http.Header{} + header.Set("Content-Type", string(web.ContentTypeJSON)) if useUnidentifiedSender { log.Trace().Msg("Sending message over unidentified WS") - response, err = cli.UnauthedWS.SendRequest(ctx, http.MethodPut, path, jsonBytes, http.Header{ - "Unidentified-Access-Key": []string{base64.StdEncoding.EncodeToString(accessKey[:])}, - }) + header.Set("Unidentified-Access-Key", base64.StdEncoding.EncodeToString(accessKey[:])) + response, err = cli.UnauthedWS.SendRequest(ctx, http.MethodPut, path, jsonBytes, header) } else { log.Trace().Msg("Sending message over authed WS") - response, err = cli.AuthedWS.SendRequest(ctx, http.MethodPut, path, jsonBytes, nil) + response, err = cli.AuthedWS.SendRequest(ctx, http.MethodPut, path, jsonBytes, header) } sentUnidentified = useUnidentifiedSender if err != nil { diff --git a/pkg/signalmeow/serviceauth.go b/pkg/signalmeow/serviceauth.go index b945f30..5365ded 100644 --- a/pkg/signalmeow/serviceauth.go +++ b/pkg/signalmeow/serviceauth.go @@ -58,20 +58,14 @@ func (cli *Client) getCredentialsWithCache(ctx context.Context, cache **basicExp } func (cli *Client) getCredentialsFromServer(ctx context.Context, path string) (*basicExpiringCredentials, error) { - username, password := cli.Store.BasicAuthCreds() - resp, err := web.SendHTTPRequest(ctx, http.MethodGet, path, &web.HTTPReqOpt{ - Username: &username, - Password: &password, - }) + resp, err := cli.AuthedWS.SendRequest(ctx, http.MethodGet, path, nil, nil) if err != nil { return nil, err - } else if resp.StatusCode >= 300 || resp.StatusCode < 200 { - return nil, fmt.Errorf("unexpected status code %d", resp.StatusCode) } var auth basicExpiringCredentials auth.CreatedAt = time.Now() - err = web.DecodeHTTPResponseBody(ctx, &auth, resp) + err = web.DecodeWSResponseBody(ctx, &auth, resp) if err != nil { return nil, fmt.Errorf("failed to decode response: %w", err) } diff --git a/pkg/signalmeow/storageservice.go b/pkg/signalmeow/storageservice.go index 7c35dec..45a008e 100644 --- a/pkg/signalmeow/storageservice.go +++ b/pkg/signalmeow/storageservice.go @@ -243,11 +243,10 @@ func (cli *Client) fetchStorageManifest(ctx context.Context, storageKey []byte, } var encryptedManifest signalpb.StorageManifest var manifestRecord signalpb.ManifestRecord - resp, err := web.SendHTTPRequest(ctx, http.MethodGet, path, &web.HTTPReqOpt{ + resp, err := web.SendHTTPRequest(ctx, web.StorageHostname, http.MethodGet, path, &web.HTTPReqOpt{ Username: &storageCreds.Username, Password: &storageCreds.Password, ContentType: web.ContentTypeProtobuf, - Host: web.StorageHostname, }) if err != nil { return nil, fmt.Errorf("failed to fetch storage manifest: %w", err) @@ -349,12 +348,11 @@ func (cli *Client) fetchStorageItemsChunk(ctx context.Context, recordKeys [][]by return nil, fmt.Errorf("failed to marshal read operation: %w", err) } var storageItems signalpb.StorageItems - resp, err := web.SendHTTPRequest(ctx, http.MethodPut, "/v1/storage/read", &web.HTTPReqOpt{ + resp, err := web.SendHTTPRequest(ctx, web.StorageHostname, http.MethodPut, "/v1/storage/read", &web.HTTPReqOpt{ Username: &storageCreds.Username, Password: &storageCreds.Password, Body: body, ContentType: web.ContentTypeProtobuf, - Host: web.StorageHostname, }) if err != nil { return nil, fmt.Errorf("failed to fetch storage records: %w", err) diff --git a/pkg/signalmeow/web/signalwebsocket.go b/pkg/signalmeow/web/signalwebsocket.go index 75e22e1..4c2ac7a 100644 --- a/pkg/signalmeow/web/signalwebsocket.go +++ b/pkg/signalmeow/web/signalwebsocket.go @@ -569,11 +569,18 @@ func (s *SignalWebsocket) SendRequest( return nil, errors.New("websocket is nil") } headerArray := make([]string, len(headers)) + var hasContentType bool for key, values := range headers { + if strings.ToLower(key) == "content-type" { + hasContentType = true + } for _, value := range values { headerArray = append(headerArray, fmt.Sprintf("%s:%s", strings.ToLower(key), value)) } } + if !hasContentType && body != nil { + headerArray = append(headerArray, "content-type:application/json") + } return s.sendRequestInternal(ctx, &signalpb.WebSocketRequestMessage{ Verb: &method, Path: &path, diff --git a/pkg/signalmeow/web/web.go b/pkg/signalmeow/web/web.go index 3644451..ed3558c 100644 --- a/pkg/signalmeow/web/web.go +++ b/pkg/signalmeow/web/web.go @@ -34,6 +34,7 @@ import ( "github.com/rs/zerolog" "go.mau.fi/mautrix-signal/pkg/libsignalgo" + signalpb "go.mau.fi/mautrix-signal/pkg/signalmeow/protobuf" ) const proxyUrlStr = "" // Set this to proxy requests @@ -106,25 +107,21 @@ type HTTPReqOpt struct { Username *string Password *string ContentType ContentType - Host string Headers map[string]string OverrideURL string // Override the full URL, if set ignores path and Host } var httpReqCounter = 0 -func SendHTTPRequest(ctx context.Context, method string, path string, opt *HTTPReqOpt) (*http.Response, error) { +func SendHTTPRequest(ctx context.Context, host, method, path string, opt *HTTPReqOpt) (*http.Response, error) { // Set defaults if opt == nil { opt = &HTTPReqOpt{} } - if opt.Host == "" { - opt.Host = APIHostname - } if len(path) > 0 && path[0] != '/' { path = "/" + path } - urlStr := "https://" + opt.Host + path + urlStr := "https://" + host + path if opt.OverrideURL != "" { urlStr = opt.OverrideURL } @@ -169,6 +166,22 @@ func SendHTTPRequest(ctx context.Context, method string, path string, opt *HTTPR return resp, nil } +func DecodeWSResponseBody(ctx context.Context, out any, resp *signalpb.WebSocketResponseMessage) error { + if resp.GetStatus() < 200 || resp.GetStatus() >= 300 { + zerolog.Ctx(ctx).Debug(). + Bytes("body", resp.Body). + Str("resp_message", resp.GetMessage()). + Strs("headers", resp.Headers). + Uint32("status_code", resp.GetStatus()). + Msg("Unexpected status code") + return fmt.Errorf("unexpected response status %d", resp.GetStatus()) + } + if out == nil { + return nil + } + return json.Unmarshal(resp.Body, &out) +} + // DecodeHTTPResponseBody checks status code, reads an http.Response's Body and decodes it into the provided interface. func DecodeHTTPResponseBody(ctx context.Context, out any, resp *http.Response) error { defer resp.Body.Close() @@ -192,37 +205,33 @@ func DecodeHTTPResponseBody(ctx context.Context, out any, resp *http.Response) e return nil } -func GetAttachment(ctx context.Context, path string, cdnNumber uint32, opt *HTTPReqOpt) (*http.Response, error) { +func GetAttachment(ctx context.Context, path string, cdnNumber uint32) (*http.Response, error) { log := zerolog.Ctx(ctx).With(). Str("action", "get_attachment"). Str("path", path). Uint32("cdn_number", cdnNumber). Logger() - if opt == nil { - opt = &HTTPReqOpt{} + var host string + if int(cdnNumber) > len(CDNHosts) { + log.Warn().Msg("Invalid CDN index") + host = CDN1Hostname + } else { + host = CDNHosts[cdnNumber] } - if opt.Host == "" { - if int(cdnNumber) > len(CDNHosts) { - log.Warn().Msg("Invalid CDN index") - opt.Host = CDN1Hostname - } else { - opt.Host = CDNHosts[cdnNumber] - } - if cdnNumber == 0 { - // This is basically a fallback if cdnNumber is not set - // but it also seems to be the right host if cdnNumber == 0 - opt.Host = CDNHosts[0] - } else if cdnNumber > 0 && int(cdnNumber) <= len(CDNHosts) { - // Pull CDN hosts from array (cdnNumber is 1-indexed, but we have a placeholder host at index 0) - // (the 1-indexed is just an assumption, other clients seem to only explicitly handle cdnNumber == 0 and 2) - opt.Host = CDNHosts[cdnNumber] - } else { - opt.Host = CDNHosts[0] - log.Warn().Msg("Invalid CDN index") - } + if cdnNumber == 0 { + // This is basically a fallback if cdnNumber is not set, + // but it also seems to be the right host if cdnNumber == 0 + host = CDNHosts[0] + } else if cdnNumber > 0 && int(cdnNumber) <= len(CDNHosts) { + // Pull CDN hosts from array (cdnNumber is 1-indexed, but we have a placeholder host at index 0) + // (the 1-indexed is just an assumption, other clients seem to only explicitly handle cdnNumber == 0 and 2) + host = CDNHosts[cdnNumber] + } else { + host = CDNHosts[0] + log.Warn().Msg("Invalid CDN index") } - log.Debug().Str("host", opt.Host).Msg("getting attachment") - urlStr := "https://" + opt.Host + path + log.Debug().Str("host", host).Msg("getting attachment") + urlStr := "https://" + host + path req, err := http.NewRequest(http.MethodGet, urlStr, nil) if err != nil { return nil, err From b06ca0eefe590ec05e72636dc9b258c90c21b72e Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Mon, 24 Nov 2025 16:53:26 +0200 Subject: [PATCH 459/580] handle*: fix bugs with polls --- pkg/connector/handlematrix.go | 24 +++++++++++------------- pkg/connector/handlesignal.go | 2 +- pkg/msgconv/from-matrix.go | 4 +--- pkg/signalmeow/sending.go | 3 ++- 4 files changed, 15 insertions(+), 18 deletions(-) diff --git a/pkg/connector/handlematrix.go b/pkg/connector/handlematrix.go index deb52e3..1dbd48a 100644 --- a/pkg/connector/handlematrix.go +++ b/pkg/connector/handlematrix.go @@ -112,28 +112,25 @@ func getTimestampForEvent(txnID networkid.RawTransactionID, evt *event.Event, or } func (s *SignalClient) HandleMatrixMessage(ctx context.Context, msg *bridgev2.MatrixMessage) (message *bridgev2.MatrixMessageResponse, err error) { - ts := getTimestampForEvent(msg.InputTransactionID, msg.Event, msg.OrigSender) converted, err := s.Main.MsgConv.ToSignal( - ctx, s.Client, msg.Portal, msg.Event, msg.Content, ts, msg.OrigSender != nil, msg.ReplyTo, + ctx, s.Client, msg.Portal, msg.Event, msg.Content, msg.OrigSender != nil, msg.ReplyTo, ) if err != nil { return nil, err } - return s.doSendMessage(ctx, ts, msg, converted, &signalid.MessageMetadata{ + return s.doSendMessage(ctx, msg, converted, &signalid.MessageMetadata{ ContainsAttachments: len(converted.Attachments) > 0, }) } func (s *SignalClient) doSendMessage( ctx context.Context, - ts uint64, msg *bridgev2.MatrixMessage, converted *signalpb.DataMessage, meta *signalid.MessageMetadata, ) (*bridgev2.MatrixMessageResponse, error) { - if ts == 0 { - ts = getTimestampForEvent(msg.InputTransactionID, msg.Event, msg.OrigSender) - } + ts := getTimestampForEvent(msg.InputTransactionID, msg.Event, msg.OrigSender) + converted.Timestamp = &ts if meta == nil { meta = &signalid.MessageMetadata{} } @@ -169,11 +166,12 @@ func (s *SignalClient) HandleMatrixEdit(ctx context.Context, msg *bridgev2.Matri return fmt.Errorf("failed to get message reply target: %w", err) } } - ts := getTimestampForEvent(msg.InputTransactionID, msg.Event, msg.OrigSender) - converted, err := s.Main.MsgConv.ToSignal(ctx, s.Client, msg.Portal, msg.Event, msg.Content, ts, msg.OrigSender != nil, replyTo) + converted, err := s.Main.MsgConv.ToSignal(ctx, s.Client, msg.Portal, msg.Event, msg.Content, msg.OrigSender != nil, replyTo) if err != nil { return err } + ts := getTimestampForEvent(msg.InputTransactionID, msg.Event, msg.OrigSender) + converted.Timestamp = &ts err = s.sendMessage(ctx, msg.Portal.ID, &signalpb.Content{EditMessage: &signalpb.EditMessage{ TargetSentTimestamp: proto.Uint64(targetSentTimestamp), DataMessage: converted, @@ -800,7 +798,7 @@ func (s *SignalClient) HandleMatrixPollStart(ctx context.Context, msg *bridgev2. }, RequiredProtocolVersion: ptr.Ptr(uint32(signalpb.DataMessage_POLLS)), } - return s.doSendMessage(ctx, 0, &msg.MatrixMessage, converted, &signalid.MessageMetadata{ + return s.doSendMessage(ctx, &msg.MatrixMessage, converted, &signalid.MessageMetadata{ MatrixPollOptionIDs: optionIDs, }) } @@ -826,9 +824,9 @@ func (s *SignalClient) HandleMatrixPollVote(ctx context.Context, msg *bridgev2.M TargetAuthorAciBinary: senderACI[:], TargetSentTimestamp: &msgTS, OptionIndexes: optionIndexes, - VoteCount: nil, // TODO + VoteCount: proto.Uint32(1), // TODO }, - RequiredProtocolVersion: ptr.Ptr(uint32(signalpb.DataMessage_POLLS)), + RequiredProtocolVersion: proto.Uint32(0), } - return s.doSendMessage(ctx, 0, &msg.MatrixMessage, converted, nil) + return s.doSendMessage(ctx, &msg.MatrixMessage, converted, nil) } diff --git a/pkg/connector/handlesignal.go b/pkg/connector/handlesignal.go index 6a2f3b5..0293a53 100644 --- a/pkg/connector/handlesignal.go +++ b/pkg/connector/handlesignal.go @@ -167,7 +167,7 @@ func (evt *Bv2ChatEvent) GetType() bridgev2.RemoteEventType { case *signalpb.DataMessage: switch { case innerEvt.Body != nil, innerEvt.Attachments != nil, innerEvt.Contact != nil, innerEvt.Sticker != nil, - innerEvt.Payment != nil, innerEvt.GiftBadge != nil, + innerEvt.Payment != nil, innerEvt.GiftBadge != nil, innerEvt.PollCreate != nil, innerEvt.PollVote != nil, innerEvt.GetRequiredProtocolVersion() > uint32(signalpb.DataMessage_CURRENT), innerEvt.GetFlags()&uint32(signalpb.DataMessage_EXPIRATION_TIMER_UPDATE) != 0: return bridgev2.RemoteEventMessage diff --git a/pkg/msgconv/from-matrix.go b/pkg/msgconv/from-matrix.go index 9af4dc5..67352f1 100644 --- a/pkg/msgconv/from-matrix.go +++ b/pkg/msgconv/from-matrix.go @@ -44,7 +44,6 @@ func (mc *MessageConverter) ToSignal( portal *bridgev2.Portal, evt *event.Event, content *event.MessageEventContent, - timestamp uint64, relaybotFormatted bool, replyTo *database.Message, ) (*signalpb.DataMessage, error) { @@ -55,8 +54,7 @@ func (mc *MessageConverter) ToSignal( } dm := &signalpb.DataMessage{ - Timestamp: ×tamp, - Preview: mc.convertURLPreviewToSignal(ctx, content), + Preview: mc.convertURLPreviewToSignal(ctx, content), } if replyTo != nil { authorACI, messageID, err := signalid.ParseMessageID(replyTo.ID) diff --git a/pkg/signalmeow/sending.go b/pkg/signalmeow/sending.go index ee35cd4..c1c0232 100644 --- a/pkg/signalmeow/sending.go +++ b/pkg/signalmeow/sending.go @@ -824,7 +824,6 @@ func (cli *Client) sendContent( Uint64("timestamp", messageTimestamp). Logger() ctx = log.WithContext(ctx) - log.Trace().Any("raw_content", content).Stringer("recipient", recipient).Msg("Raw data of outgoing message") // If it's a data message, add our profile key if content.DataMessage != nil { @@ -836,6 +835,8 @@ func (cli *Client) sendContent( } } + log.Trace().Any("raw_content", content).Stringer("recipient", recipient).Msg("Raw data of outgoing message") + if retryCount > 3 { log.Error().Int("retry_count", retryCount).Msg("sendContent too many retries") return false, fmt.Errorf("too many retries") From 974259ee3fafd3c2bb2869deeae39ed4a12cd2a2 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Mon, 24 Nov 2025 17:38:01 +0200 Subject: [PATCH 460/580] signalmeow/provisioning: remove prekey upload on login They need to be uploaded via the websocket, so easier to let the normal upload flow do it. --- pkg/connector/login.go | 43 ++++--------------------- pkg/signalmeow/keys.go | 57 ++++++++++++++-------------------- pkg/signalmeow/provisioning.go | 31 ++---------------- pkg/signalmeow/receiving.go | 13 ++++---- 4 files changed, 38 insertions(+), 106 deletions(-) diff --git a/pkg/connector/login.go b/pkg/connector/login.go index 12d548d..5cfdae1 100644 --- a/pkg/connector/login.go +++ b/pkg/connector/login.go @@ -52,8 +52,6 @@ type QRLogin struct { cancelChan context.CancelFunc ProvChan chan signalmeow.ProvisioningResponse newQRCount int - - ProvData *store.DeviceData } var _ bridgev2.LoginProcessDisplayAndWait = (*QRLogin)(nil) @@ -112,14 +110,6 @@ func (qr *QRLogin) Wait(ctx context.Context) (*bridgev2.LoginStep, error) { return nil, fmt.Errorf("login not started") } - if qr.ProvData == nil { - return qr.qrWait(ctx) - } else { - return qr.processingWait(ctx) - } -} - -func (qr *QRLogin) qrWait(ctx context.Context) (*bridgev2.LoginStep, error) { select { case resp := <-qr.ProvChan: if resp.Err != nil { @@ -132,15 +122,7 @@ func (qr *QRLogin) qrWait(ctx context.Context) (*bridgev2.LoginStep, error) { qr.cancelChan() return nil, fmt.Errorf("no signal account ID received") } - qr.ProvData = resp.ProvisioningData - return &bridgev2.LoginStep{ - Type: bridgev2.LoginStepTypeDisplayAndWait, - StepID: LoginStepProcess, - Instructions: fmt.Sprintf("Processing login as %s...", resp.ProvisioningData.Number), - DisplayAndWaitParams: &bridgev2.LoginDisplayAndWaitParams{ - Type: bridgev2.LoginDisplayTypeNothing, - }, - }, nil + return qr.loginComplete(ctx, resp.ProvisioningData) // Server will timeout the request after 60 seconds, but Signal Desktop opens // a new socket and gets a new QR code after 45 seconds. We should do the same. @@ -158,26 +140,13 @@ func (qr *QRLogin) qrWait(ctx context.Context) (*bridgev2.LoginStep, error) { } } -func (qr *QRLogin) processingWait(ctx context.Context) (*bridgev2.LoginStep, error) { +func (qr *QRLogin) loginComplete(ctx context.Context, provData *store.DeviceData) (*bridgev2.LoginStep, error) { defer qr.cancelChan() - newLoginID := signalid.MakeUserLoginID(qr.ProvData.ACI) - - select { - case resp := <-qr.ProvChan: - if resp.Err != nil { - return nil, resp.Err - } else if resp.State != signalmeow.StateProvisioningPreKeysRegistered { - return nil, fmt.Errorf("unexpected state %v", resp.State) - } - case <-ctx.Done(): - return nil, ctx.Err() - } - ul, err := qr.User.NewLogin(ctx, &database.UserLogin{ - ID: newLoginID, - RemoteName: qr.ProvData.Number, + ID: signalid.MakeUserLoginID(provData.ACI), + RemoteName: provData.Number, RemoteProfile: status.RemoteProfile{ - Phone: qr.ProvData.Number, + Phone: provData.Number, }, Metadata: &signalid.UserLoginMetadata{}, }, &bridgev2.NewLoginParams{ @@ -190,7 +159,7 @@ func (qr *QRLogin) processingWait(ctx context.Context) (*bridgev2.LoginStep, err return &bridgev2.LoginStep{ Type: bridgev2.LoginStepTypeComplete, StepID: LoginStepComplete, - Instructions: fmt.Sprintf("Successfully logged in as %s / %s", qr.ProvData.Number, qr.ProvData.ACI), + Instructions: fmt.Sprintf("Successfully logged in as %s / %s", provData.Number, provData.ACI), CompleteParams: &bridgev2.LoginCompleteParams{ UserLoginID: ul.ID, UserLogin: ul, diff --git a/pkg/signalmeow/keys.go b/pkg/signalmeow/keys.go index 4756514..19ad1f6 100644 --- a/pkg/signalmeow/keys.go +++ b/pkg/signalmeow/keys.go @@ -22,7 +22,7 @@ import ( "encoding/json" "errors" "fmt" - "math/rand" + "math/rand/v2" "net/http" "strings" "time" @@ -43,25 +43,6 @@ type GeneratedPreKeys struct { IdentityKey []uint8 } -func (cli *Client) GenerateAndRegisterPreKeys(ctx context.Context, pks store.PreKeyStore) error { - _, err := cli.GenerateAndSaveNextPreKeyBatch(ctx, pks, 0) - if err != nil { - return fmt.Errorf("failed to generate and save next prekey batch: %w", err) - } - _, err = cli.GenerateAndSaveNextKyberPreKeyBatch(ctx, pks, 0) - if err != nil { - return fmt.Errorf("failed to generate and save next kyber prekey batch: %w", err) - } - - // We need to upload all currently valid prekeys, not just the ones we just generated - err = cli.RegisterAllPreKeys(ctx, pks) - if err != nil { - return fmt.Errorf("failed to register prekey batches: %w", err) - } - - return err -} - func (cli *Client) RegisterAllPreKeys(ctx context.Context, pks store.PreKeyStore) error { var identityKeyPair *libsignalgo.IdentityKeyPair var pni bool @@ -97,8 +78,10 @@ func (cli *Client) RegisterAllPreKeys(ctx context.Context, pks store.PreKeyStore KyberPreKeys: kyberPreKeys, IdentityKey: identityKey, } - log := zerolog.Ctx(ctx).With().Str("action", "register prekeys").Logger() - log.Debug().Int("num_prekeys", len(preKeys)).Int("num_kyber_prekeys", len(kyberPreKeys)).Msg("Registering prekeys") + zerolog.Ctx(ctx).Debug(). + Int("num_prekeys", len(preKeys)). + Int("num_kyber_prekeys", len(kyberPreKeys)). + Msg("Registering all prekeys") err = cli.RegisterPreKeys(ctx, &generatedPreKeys, pni) if err != nil { return fmt.Errorf("failed to register prekeys: %w", err) @@ -596,23 +579,29 @@ func (cli *Client) keyCheckLoop(ctx context.Context) { log := zerolog.Ctx(ctx).With().Str("action", "start key check loop").Logger() // Do the initial check in 5-10 minutes after starting the loop - window_start := 0 - window_size := 1 + windowStart := 0 + windowSize := 1 + firstRun := true for { - random_minutes_in_window := rand.Intn(window_size) + window_start - check_time := time.Duration(random_minutes_in_window) * time.Minute - log.Debug().Dur("check_time", check_time).Msg("Waiting to check for new prekeys") + randomMinutesInWindow := rand.IntN(windowSize) + windowStart + checkTime := time.Duration(randomMinutesInWindow) * time.Minute + if firstRun { + checkTime = 0 + firstRun = false + } else { + log.Debug().Dur("check_time", checkTime).Msg("Waiting to check for new prekeys") + } select { case <-ctx.Done(): return - case <-time.After(check_time): + case <-time.After(checkTime): err := cli.CheckAndUploadNewPreKeys(ctx, cli.Store.ACIPreKeyStore) if err != nil { log.Err(err).Msg("Error checking and uploading new prekeys for ACI identity") // Retry within half an hour - window_start = 5 - window_size = 25 + windowStart = 5 + windowSize = 25 continue } err = cli.CheckAndUploadNewPreKeys(ctx, cli.Store.PNIPreKeyStore) @@ -628,13 +617,13 @@ func (cli *Client) keyCheckLoop(ctx context.Context) { } log.Err(err).Msg("Error checking and uploading new prekeys for PNI identity") // Retry within half an hour - window_start = 5 - window_size = 25 + windowStart = 5 + windowSize = 25 continue } // After a successful check, check again in 36 to 60 hours - window_start = 36 * 60 - window_size = 24 * 60 + windowStart = 36 * 60 + windowSize = 24 * 60 } } } diff --git a/pkg/signalmeow/provisioning.go b/pkg/signalmeow/provisioning.go index 2343e32..48a8042 100644 --- a/pkg/signalmeow/provisioning.go +++ b/pkg/signalmeow/provisioning.go @@ -22,7 +22,7 @@ import ( "encoding/base64" "encoding/json" "fmt" - mrand "math/rand" + mrand "math/rand/v2" "net/http" "net/url" "time" @@ -54,7 +54,6 @@ const ( StateProvisioningError ProvisioningState = iota StateProvisioningURLReceived StateProvisioningDataReceived - StateProvisioningPreKeysRegistered ) func (s ProvisioningState) String() string { @@ -65,8 +64,6 @@ func (s ProvisioningState) String() string { return "StateProvisioningURLReceived" case StateProvisioningDataReceived: return "StateProvisioningDataReceived" - case StateProvisioningPreKeysRegistered: - return "StateProvisioningPreKeysRegistered" default: return fmt.Sprintf("ProvisioningState(%d)", s) } @@ -128,8 +125,8 @@ func PerformProvisioning(ctx context.Context, deviceStore store.DeviceStore, dev username := *provisioningMessage.Number password := random.String(22) code := provisioningMessage.ProvisioningCode - aciRegistrationID := mrand.Intn(16383) + 1 - pniRegistrationID := mrand.Intn(16383) + 1 + aciRegistrationID := mrand.IntN(16383) + 1 + pniRegistrationID := mrand.IntN(16383) + 1 aciSignedPreKey := GenerateSignedPreKey(1, aciIdentityKeyPair) pniSignedPreKey := GenerateSignedPreKey(1, pniIdentityKeyPair) aciPQLastResortPreKey := GenerateKyberPreKeys(1, 1, aciIdentityKeyPair)[0] @@ -250,28 +247,6 @@ func PerformProvisioning(ctx context.Context, deviceStore store.DeviceStore, dev // Return the provisioning data c <- ProvisioningResponse{State: StateProvisioningDataReceived, ProvisioningData: data} - - // Generate, store, and register prekeys - // TODO hacky client construction - cli := &Client{Store: device} - err = cli.GenerateAndRegisterPreKeys(ctx, device.ACIPreKeyStore) - if err != nil { - c <- ProvisioningResponse{ - State: StateProvisioningError, - Err: fmt.Errorf("error generating and registering ACI prekeys: %w", err), - } - return - } - err = cli.GenerateAndRegisterPreKeys(ctx, device.PNIPreKeyStore) - if err != nil { - c <- ProvisioningResponse{ - State: StateProvisioningError, - Err: fmt.Errorf("error generating and registering PNI prekeys: %w", err), - } - return - } - - c <- ProvisioningResponse{State: StateProvisioningPreKeysRegistered} }() return c } diff --git a/pkg/signalmeow/receiving.go b/pkg/signalmeow/receiving.go index 622f18c..7267d0b 100644 --- a/pkg/signalmeow/receiving.go +++ b/pkg/signalmeow/receiving.go @@ -261,6 +261,12 @@ func (cli *Client) StartReceiveLoops(ctx context.Context) (chan SignalConnection } else { zerolog.Ctx(ctx).Debug().Msg("Successfully registered capabilities") } + // Start loop to check for and upload more prekeys + cli.loopWg.Add(1) + go func() { + defer cli.loopWg.Done() + cli.keyCheckLoop(loopCtx) + }() // TODO hacky if cli.SyncContactsOnConnect { cli.SendContactSyncRequest(loopCtx) @@ -273,13 +279,6 @@ func (cli *Client) StartReceiveLoops(ctx context.Context) (chan SignalConnection } }() - // Start loop to check for and upload more prekeys - cli.loopWg.Add(1) - go func() { - defer cli.loopWg.Done() - cli.keyCheckLoop(loopCtx) - }() - return statusChan, nil } From 7a72795f5d1b2038d30c50d735785371393e84c7 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Mon, 24 Nov 2025 17:43:32 +0200 Subject: [PATCH 461/580] signalmeow/receiving: remove redundant loop waiting for websocket connect --- pkg/signalmeow/receiving.go | 49 +++++++++++++++++-------------------- 1 file changed, 23 insertions(+), 26 deletions(-) diff --git a/pkg/signalmeow/receiving.go b/pkg/signalmeow/receiving.go index 7267d0b..2a023ca 100644 --- a/pkg/signalmeow/receiving.go +++ b/pkg/signalmeow/receiving.go @@ -249,32 +249,29 @@ func (cli *Client) StartReceiveLoops(ctx context.Context) (chan SignalConnection cli.loopWg.Add(1) go func() { defer cli.loopWg.Done() - for { - select { - case <-loopCtx.Done(): - return - case <-initialConnectChan: - log.Info().Msg("Both websockets connected, sending contacts sync request") - err = cli.RegisterCapabilities(ctx) - if err != nil { - zerolog.Ctx(ctx).Err(err).Msg("Failed to register capabilities") - } else { - zerolog.Ctx(ctx).Debug().Msg("Successfully registered capabilities") - } - // Start loop to check for and upload more prekeys - cli.loopWg.Add(1) - go func() { - defer cli.loopWg.Done() - cli.keyCheckLoop(loopCtx) - }() - // TODO hacky - if cli.SyncContactsOnConnect { - cli.SendContactSyncRequest(loopCtx) - } - if cli.Store.MasterKey == nil { - cli.SendStorageMasterKeyRequest(loopCtx) - } - return + select { + case <-loopCtx.Done(): + return + case <-initialConnectChan: + log.Info().Msg("Both websockets connected, sending contacts sync request") + err = cli.RegisterCapabilities(ctx) + if err != nil { + zerolog.Ctx(ctx).Err(err).Msg("Failed to register capabilities") + } else { + zerolog.Ctx(ctx).Debug().Msg("Successfully registered capabilities") + } + // Start loop to check for and upload more prekeys + cli.loopWg.Add(1) + go func() { + defer cli.loopWg.Done() + cli.keyCheckLoop(loopCtx) + }() + // TODO hacky + if cli.SyncContactsOnConnect { + cli.SendContactSyncRequest(loopCtx) + } + if cli.Store.MasterKey == nil { + cli.SendStorageMasterKeyRequest(loopCtx) } } }() From cd598b872197522bdea96c5b6a28af66364232a2 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Mon, 24 Nov 2025 17:57:18 +0200 Subject: [PATCH 462/580] signalmeow/web: include server response content in logs --- pkg/signalmeow/web/signalwebsocket.go | 18 ++++++++++++++---- pkg/signalmeow/web/web.go | 2 +- 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/pkg/signalmeow/web/signalwebsocket.go b/pkg/signalmeow/web/signalwebsocket.go index 4c2ac7a..c4172aa 100644 --- a/pkg/signalmeow/web/signalwebsocket.go +++ b/pkg/signalmeow/web/signalwebsocket.go @@ -19,6 +19,7 @@ package web import ( "context" "encoding/base64" + "encoding/json" "errors" "fmt" "net/http" @@ -454,10 +455,19 @@ func readLoop( Msg("Received response with unknown id") continue } - log.Debug(). - Uint64("response_id", *msg.Response.Id). - Uint32("response_status", *msg.Response.Status). - Msg("Received WS response") + logEvt := log.Debug(). + Uint64("response_id", msg.Response.GetId()). + Uint32("response_status", msg.Response.GetStatus()). + Str("response_message", msg.Response.GetMessage()) + if log.GetLevel() == zerolog.TraceLevel { + logEvt.Strs("response_headers", msg.Response.Headers) + if json.Valid(msg.Response.Body) { + logEvt.RawJSON("response_body", msg.Response.Body) + } else { + logEvt.Str("response_body", base64.StdEncoding.EncodeToString(msg.Response.Body)) + } + } + logEvt.Msg("Received WS response") responseChannel <- msg.Response close(responseChannel) } else if *msg.Type == signalpb.WebSocketMessage_UNKNOWN { diff --git a/pkg/signalmeow/web/web.go b/pkg/signalmeow/web/web.go index ed3558c..cb1efa7 100644 --- a/pkg/signalmeow/web/web.go +++ b/pkg/signalmeow/web/web.go @@ -168,7 +168,7 @@ func SendHTTPRequest(ctx context.Context, host, method, path string, opt *HTTPRe func DecodeWSResponseBody(ctx context.Context, out any, resp *signalpb.WebSocketResponseMessage) error { if resp.GetStatus() < 200 || resp.GetStatus() >= 300 { - zerolog.Ctx(ctx).Debug(). + zerolog.Ctx(ctx).Warn(). Bytes("body", resp.Body). Str("resp_message", resp.GetMessage()). Strs("headers", resp.Headers). From c54b104b2ec67615f1f6a080646ac9879a26f86b Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Mon, 24 Nov 2025 18:16:46 +0200 Subject: [PATCH 463/580] signalmeow/sending: remove incorrect check for sync messages --- pkg/signalmeow/sending.go | 50 ++++++++++++++++++--------------------- 1 file changed, 23 insertions(+), 27 deletions(-) diff --git a/pkg/signalmeow/sending.go b/pkg/signalmeow/sending.go index c1c0232..d919546 100644 --- a/pkg/signalmeow/sending.go +++ b/pkg/signalmeow/sending.go @@ -623,14 +623,13 @@ func (cli *Client) sendToGroup(ctx context.Context, recipients []*libsignalgo.Se } } - // No need to send to ourselves if we don't have any other devices - if cli.howManyOtherDevicesDoWeHave(ctx) > 0 { - var syncContent *signalpb.Content - if content.GetDataMessage() != nil { - syncContent = syncMessageFromGroupDataMessage(content.DataMessage, result.SuccessfullySentTo) - } else if content.GetEditMessage() != nil { - syncContent = syncMessageFromGroupEditMessage(content.EditMessage, result.SuccessfullySentTo) - } + var syncContent *signalpb.Content + if content.GetDataMessage() != nil { + syncContent = syncMessageFromGroupDataMessage(content.DataMessage, result.SuccessfullySentTo) + } else if content.GetEditMessage() != nil { + syncContent = syncMessageFromGroupEditMessage(content.EditMessage, result.SuccessfullySentTo) + } + if syncContent != nil { _, selfSendErr := cli.sendContent(ctx, cli.Store.ACIServiceID(), messageTimestamp, syncContent, 0, true, true) if selfSendErr != nil { zerolog.Ctx(ctx).Err(selfSendErr).Msg("Failed to send sync message to myself") @@ -649,25 +648,22 @@ func (cli *Client) sendToGroup(ctx context.Context, recipients []*libsignalgo.Se } func (cli *Client) sendSyncCopy(ctx context.Context, content *signalpb.Content, messageTS uint64, result *SuccessfulSendResult) bool { - // If we have other devices, send Sync messages to them too - if cli.howManyOtherDevicesDoWeHave(ctx) > 0 { - var syncContent *signalpb.Content - if content.GetDataMessage() != nil { - syncContent = syncMessageFromSoloDataMessage(content.DataMessage, *result) - } else if content.GetEditMessage() != nil { - syncContent = syncMessageFromSoloEditMessage(content.EditMessage, *result) - } else if content.GetReceiptMessage().GetType() == signalpb.ReceiptMessage_READ { - syncContent = syncMessageFromReadReceiptMessage(ctx, content.ReceiptMessage, result.Recipient) - } else if content.GetSyncMessage() != nil { - syncContent = content - } - if syncContent != nil { - _, selfSendErr := cli.sendContent(ctx, cli.Store.ACIServiceID(), messageTS, syncContent, 0, true, false) - if selfSendErr != nil { - zerolog.Ctx(ctx).Err(selfSendErr).Msg("Failed to send sync message to myself") - } else { - return true - } + var syncContent *signalpb.Content + if content.GetDataMessage() != nil { + syncContent = syncMessageFromSoloDataMessage(content.DataMessage, *result) + } else if content.GetEditMessage() != nil { + syncContent = syncMessageFromSoloEditMessage(content.EditMessage, *result) + } else if content.GetReceiptMessage().GetType() == signalpb.ReceiptMessage_READ { + syncContent = syncMessageFromReadReceiptMessage(ctx, content.ReceiptMessage, result.Recipient) + } else if content.GetSyncMessage() != nil { + syncContent = content + } + if syncContent != nil { + _, selfSendErr := cli.sendContent(ctx, cli.Store.ACIServiceID(), messageTS, syncContent, 0, true, false) + if selfSendErr != nil { + zerolog.Ctx(ctx).Err(selfSendErr).Msg("Failed to send sync message to myself") + } else { + return true } } return false From edacab163c9031d427d6d8a0d4ed4d1c073b7652 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Mon, 24 Nov 2025 18:18:50 +0200 Subject: [PATCH 464/580] client: unlink before disconnecting websocket --- pkg/connector/client.go | 10 +++++----- pkg/signalmeow/web/signalwebsocket.go | 3 ++- pkg/signalmeow/web/web.go | 3 +++ 3 files changed, 10 insertions(+), 6 deletions(-) diff --git a/pkg/connector/client.go b/pkg/connector/client.go index c85ae35..233ad91 100644 --- a/pkg/connector/client.go +++ b/pkg/connector/client.go @@ -78,14 +78,14 @@ func (s *SignalClient) LogoutRemote(ctx context.Context) { if s.Client == nil { return } - err := s.Client.StopReceiveLoops() - if err != nil { - zerolog.Ctx(ctx).Err(err).Msg("Failed to stop receive loops for logout") - } - err = s.Client.Unlink(ctx) + err := s.Client.Unlink(ctx) if err != nil { zerolog.Ctx(ctx).Err(err).Msg("Failed to unlink device") } + err = s.Client.StopReceiveLoops() + if err != nil { + zerolog.Ctx(ctx).Err(err).Msg("Failed to stop receive loops for logout") + } err = s.Main.Store.DeleteDevice(context.TODO(), &s.Client.Store.DeviceData) if err != nil { zerolog.Ctx(ctx).Err(err).Msg("Failed to delete device from store") diff --git a/pkg/signalmeow/web/signalwebsocket.go b/pkg/signalmeow/web/signalwebsocket.go index c4172aa..38dcc4d 100644 --- a/pkg/signalmeow/web/signalwebsocket.go +++ b/pkg/signalmeow/web/signalwebsocket.go @@ -619,7 +619,8 @@ func (s *SignalWebsocket) sendRequestInternal( } response := <-responseChannel - if response == nil { + isSelfDelete := request.GetVerb() == http.MethodDelete && strings.HasPrefix(request.GetPath(), "/v1/devices/") + if response == nil && !isSelfDelete { // If out of retries, return error no matter what if retryCount >= 3 { // TODO: I think error isn't getting passed in this context (as it's not the one in writeLoop) diff --git a/pkg/signalmeow/web/web.go b/pkg/signalmeow/web/web.go index cb1efa7..e16d7c7 100644 --- a/pkg/signalmeow/web/web.go +++ b/pkg/signalmeow/web/web.go @@ -167,6 +167,9 @@ func SendHTTPRequest(ctx context.Context, host, method, path string, opt *HTTPRe } func DecodeWSResponseBody(ctx context.Context, out any, resp *signalpb.WebSocketResponseMessage) error { + if resp == nil { + return nil + } if resp.GetStatus() < 200 || resp.GetStatus() >= 300 { zerolog.Ctx(ctx).Warn(). Bytes("body", resp.Body). From c7b7ea71f81c3c23ae266700b712d9edef01e182 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Tue, 25 Nov 2025 15:55:32 +0200 Subject: [PATCH 465/580] main: adjust signalmeow user agent --- cmd/mautrix-signal/main.go | 4 ++++ pkg/signalmeow/web/web.go | 3 ++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/cmd/mautrix-signal/main.go b/cmd/mautrix-signal/main.go index 522834f..d224f32 100644 --- a/cmd/mautrix-signal/main.go +++ b/cmd/mautrix-signal/main.go @@ -17,9 +17,12 @@ package main import ( + "fmt" + "maunium.net/go/mautrix/bridgev2/matrix/mxmain" "go.mau.fi/mautrix-signal/pkg/connector" + "go.mau.fi/mautrix-signal/pkg/signalmeow/web" ) // Information to find out exactly which commit the bridge was built from. @@ -41,6 +44,7 @@ var m = mxmain.BridgeMain{ } func main() { + web.UserAgent = fmt.Sprintf("mautrix-signal/%s %s", m.Version, web.BaseUserAgent) m.PostStart = func() { if m.Matrix.Provisioning != nil { m.Matrix.Provisioning.Router.HandleFunc("GET /v2/resolve_identifier/{phonenum}", legacyProvResolveIdentifier) diff --git a/pkg/signalmeow/web/web.go b/pkg/signalmeow/web/web.go index e16d7c7..84a04b9 100644 --- a/pkg/signalmeow/web/web.go +++ b/pkg/signalmeow/web/web.go @@ -40,7 +40,8 @@ import ( const proxyUrlStr = "" // Set this to proxy requests const caCertPath = "" // Set this to trust a self-signed cert (ie. for mitmproxy) -var UserAgent = "signalmeow/0.1.0 libsignal/" + libsignalgo.Version + " go/" + strings.TrimPrefix(runtime.Version(), "go") +var BaseUserAgent = "libsignal/" + libsignalgo.Version + " go/" + strings.TrimPrefix(runtime.Version(), "go") +var UserAgent = "signalmeow/0.1.0 " + BaseUserAgent var SignalAgent = "MAU" const ( From 60c42c68fc556615ee31003cea0c997f426f1f38 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Tue, 25 Nov 2025 20:15:52 +0200 Subject: [PATCH 466/580] signalmeow/groups: fix group cache --- pkg/connector/connector.go | 13 +- pkg/signalmeow/client.go | 31 +++- pkg/signalmeow/groupcache.go | 281 +++++++++++++++++++++++++++++++++++ pkg/signalmeow/groups.go | 120 ++++----------- pkg/signalmeow/profile.go | 8 - pkg/signalmeow/receiving.go | 2 +- pkg/signalmeow/sending.go | 10 +- 7 files changed, 349 insertions(+), 116 deletions(-) create mode 100644 pkg/signalmeow/groupcache.go diff --git a/pkg/connector/connector.go b/pkg/connector/connector.go index 30be4a4..59f8640 100644 --- a/pkg/connector/connector.go +++ b/pkg/connector/connector.go @@ -94,13 +94,12 @@ func (s *SignalConnector) LoadUserLogin(ctx context.Context, login *bridgev2.Use queueEmptyWaiter: exsync.NewEvent(), } if device != nil { - sc.Client = &signalmeow.Client{ - Store: device, - Log: sc.UserLogin.Log.With().Str("component", "signalmeow").Logger(), - EventHandler: sc.handleSignalEvent, - - SyncContactsOnConnect: s.Config.SyncContactsOnStartup, - } + sc.Client = signalmeow.NewClient( + device, + sc.UserLogin.Log.With().Str("component", "signalmeow").Logger(), + sc.handleSignalEvent, + ) + sc.Client.SyncContactsOnConnect = s.Config.SyncContactsOnStartup } login.Client = sc return nil diff --git a/pkg/signalmeow/client.go b/pkg/signalmeow/client.go index ea5eb17..2a7f470 100644 --- a/pkg/signalmeow/client.go +++ b/pkg/signalmeow/client.go @@ -30,6 +30,7 @@ import ( "go.mau.fi/mautrix-signal/pkg/libsignalgo" "go.mau.fi/mautrix-signal/pkg/signalmeow/events" "go.mau.fi/mautrix-signal/pkg/signalmeow/store" + "go.mau.fi/mautrix-signal/pkg/signalmeow/types" "go.mau.fi/mautrix-signal/pkg/signalmeow/web" ) @@ -37,14 +38,14 @@ type Client struct { Store *store.Device Log zerolog.Logger - SenderCertificateWithE164 *libsignalgo.SenderCertificate - SenderCertificateNoE164 *libsignalgo.SenderCertificate - GroupCredentials *GroupCredentials - GroupCache *GroupCache - ProfileCache *ProfileCache - GroupCallCache *map[string]bool - LastContactRequestTime time.Time - SyncContactsOnConnect bool + senderCertificateWithE164 *libsignalgo.SenderCertificate + senderCertificateNoE164 *libsignalgo.SenderCertificate + senderCertificateCache sync.Mutex + + GroupCache *GroupCache + ProfileCache *ProfileCache + LastContactRequestTime time.Time + SyncContactsOnConnect bool encryptionLock sync.Mutex @@ -66,6 +67,20 @@ type Client struct { writeCallbackCounter chan time.Time } +func NewClient(device *store.Device, log zerolog.Logger, evtHandler func(events.SignalEvent) bool) *Client { + return &Client{ + Store: device, + Log: log, + EventHandler: evtHandler, + GroupCache: NewGroupCache(), + ProfileCache: &ProfileCache{ + profiles: make(map[string]*types.Profile), + errors: make(map[string]*error), + lastFetched: make(map[string]time.Time), + }, + } +} + func (cli *Client) handleEvent(evt events.SignalEvent) bool { return cli.EventHandler(evt) } diff --git a/pkg/signalmeow/groupcache.go b/pkg/signalmeow/groupcache.go new file mode 100644 index 0000000..557203a --- /dev/null +++ b/pkg/signalmeow/groupcache.go @@ -0,0 +1,281 @@ +// mautrix-signal - A Matrix-signal puppeting bridge. +// Copyright (C) 2025 Tulir Asokan +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +package signalmeow + +import ( + "context" + "fmt" + "slices" + "sync" + "time" + + "github.com/google/uuid" + + "go.mau.fi/mautrix-signal/pkg/libsignalgo" + "go.mau.fi/mautrix-signal/pkg/signalmeow/types" +) + +type cachedGroup struct { + *Group + SendEndorsement []byte + FetchedAt time.Time + UpdatedAt time.Time +} + +type GroupCache struct { + credentials *GroupCredentials + credentialsLock sync.RWMutex + + data map[types.GroupIdentifier]*cachedGroup + lock sync.RWMutex + + activeCalls map[types.GroupIdentifier]string + callsLock sync.RWMutex +} + +func NewGroupCache() *GroupCache { + return &GroupCache{ + data: make(map[types.GroupIdentifier]*cachedGroup), + activeCalls: make(map[types.GroupIdentifier]string), + } +} + +func (gc *GroupCache) GetCredentials( + ctx context.Context, + fetch func(context.Context, time.Time) (*GroupCredentials, error), +) (*GroupCredential, error) { + today := time.Now().Truncate(24 * time.Hour) + gc.credentialsLock.RLock() + cred := gc.getCachedCredentials(today.Unix()) + gc.credentialsLock.RUnlock() + if cred != nil { + return cred, nil + } + + gc.credentialsLock.Lock() + defer gc.credentialsLock.Unlock() + cred = gc.getCachedCredentials(today.Unix()) + if cred != nil { + return cred, nil + } + creds, err := fetch(ctx, today) + if err != nil { + return nil, err + } + gc.credentials = creds + cred = gc.getCachedCredentials(today.Unix()) + if cred == nil { + return nil, fmt.Errorf("no credentials for today after fetch") + } + return cred, nil +} + +func (gc *GroupCache) getCachedCredentials(today int64) *GroupCredential { + if gc.credentials == nil { + return nil + } + for _, cred := range gc.credentials.Credentials { + if cred.RedemptionTime == today { + return &cred + } + } + return nil +} + +func (gc *GroupCache) UpdateActiveCall(id types.GroupIdentifier, callID string) bool { + gc.callsLock.Lock() + defer gc.callsLock.Unlock() + currentCallID, ok := gc.activeCalls[id] + if ok { + // If we do, then this must be ending the call + if currentCallID == callID { + delete(gc.activeCalls, id) + return false + } + } + gc.activeCalls[id] = callID + return true +} + +func (gc *GroupCache) Get(id types.GroupIdentifier) (*Group, bool) { + gc.lock.RLock() + defer gc.lock.RUnlock() + c, ok := gc.data[id] + if !ok { + return nil, false + } + return c.Group, true +} + +func (gc *GroupCache) Delete(id types.GroupIdentifier) { + gc.lock.Lock() + defer gc.lock.Unlock() + delete(gc.data, id) +} + +func (gc *GroupCache) Put(data *Group, endorsementResponse []byte) { + gc.lock.Lock() + defer gc.lock.Unlock() + cached, exists := gc.data[data.GroupIdentifier] + if exists && cached.Revision > data.Revision { + return + } + gc.data[data.GroupIdentifier] = &cachedGroup{ + Group: data, + FetchedAt: time.Now(), + UpdatedAt: time.Now(), + + //SendEndorsement: endorsementResponse, + } +} + +func (gc *GroupCache) ApplyUpdate(change *GroupChange, endorsementResponse []byte) { + rawGroupID, err := masterKeyToBytes(change.GroupMasterKey).GroupIdentifier() + if err != nil { + return + } + id := types.GroupIdentifier(rawGroupID.String()) + + gc.lock.Lock() + defer gc.lock.Unlock() + + cached, exists := gc.data[id] + if !exists || cached.Revision >= change.Revision { + return + } else if cached.Revision < change.Revision-1 { + // We missed an update, evict + delete(gc.data, id) + return + } + + // Pending member adds, promotes and removes + cached.PendingMembers = append(cached.PendingMembers, change.AddPendingMembers...) + for _, promo := range change.PromotePendingMembers { + cached.PendingMembers = slices.DeleteFunc(cached.PendingMembers, func(p *PendingMember) bool { + return p.ServiceID.Type == libsignalgo.ServiceIDTypeACI && p.ServiceID.UUID == promo.ACI + }) + cached.Members = append(cached.Members, &GroupMember{ + ACI: promo.ACI, + ProfileKey: promo.ProfileKey, + Role: GroupMember_DEFAULT, + JoinedAtRevision: change.Revision, + }) + } + for _, promo := range change.PromotePendingPniAciMembers { + cached.PendingMembers = slices.DeleteFunc(cached.PendingMembers, func(p *PendingMember) bool { + return (p.ServiceID.Type == libsignalgo.ServiceIDTypePNI && p.ServiceID.UUID == promo.PNI) || + (p.ServiceID.Type == libsignalgo.ServiceIDTypeACI && p.ServiceID.UUID == promo.ACI) + }) + cached.Members = append(cached.Members, &GroupMember{ + ACI: promo.ACI, + ProfileKey: promo.ProfileKey, + Role: GroupMember_DEFAULT, + JoinedAtRevision: change.Revision, + }) + } + cached.PendingMembers = slices.DeleteFunc(cached.PendingMembers, func(p *PendingMember) bool { + return slices.ContainsFunc(change.DeletePendingMembers, func(s *libsignalgo.ServiceID) bool { + return s != nil && p.ServiceID == *s + }) + }) + + // Requesting member adds, promotes and removes + cached.RequestingMembers = append(cached.RequestingMembers, change.AddRequestingMembers...) + for _, promo := range change.PromoteRequestingMembers { + var profileKey libsignalgo.ProfileKey + cached.RequestingMembers = slices.DeleteFunc(cached.RequestingMembers, func(r *RequestingMember) bool { + if r.ACI == promo.ACI { + profileKey = r.ProfileKey + return true + } + return false + }) + cached.Members = append(cached.Members, &GroupMember{ + ACI: promo.ACI, + ProfileKey: profileKey, + Role: promo.Role, + JoinedAtRevision: change.Revision, + }) + } + cached.RequestingMembers = slices.DeleteFunc(cached.RequestingMembers, func(r *RequestingMember) bool { + return slices.ContainsFunc(change.DeleteRequestingMembers, func(u *uuid.UUID) bool { + return u != nil && r.ACI == *u + }) + }) + + // Direct member adds, removes and modifications + for _, member := range change.AddMembers { + cached.Members = append(cached.Members, &GroupMember{ + ACI: member.ACI, + Role: member.Role, + ProfileKey: member.ProfileKey, + JoinedAtRevision: member.JoinedAtRevision, + }) + } + for _, rm := range change.ModifyMemberRoles { + cached.findMemberOrEmpty(rm.ACI).Role = rm.Role + } + for _, pk := range change.ModifyMemberProfileKeys { + cached.findMemberOrEmpty(pk.ACI).ProfileKey = pk.ProfileKey + } + cached.Members = slices.DeleteFunc(cached.Members, func(member *GroupMember) bool { + return slices.ContainsFunc(change.DeleteMembers, func(u *uuid.UUID) bool { + return u != nil && *u == member.ACI + }) + }) + + // Banned members + cached.BannedMembers = append(cached.BannedMembers, change.AddBannedMembers...) + cached.BannedMembers = slices.DeleteFunc(cached.BannedMembers, func(b *BannedMember) bool { + return slices.ContainsFunc(change.DeleteBannedMembers, func(s *libsignalgo.ServiceID) bool { + return s != nil && b.ServiceID == *s + }) + }) + + // Non-member modifications + if change.ModifyInviteLinkPassword != nil { + cached.InviteLinkPassword = change.ModifyInviteLinkPassword + } + if change.ModifyTitle != nil { + cached.Title = *change.ModifyTitle + } + if change.ModifyDescription != nil { + cached.Description = *change.ModifyDescription + } + if change.ModifyAvatar != nil { + cached.AvatarPath = *change.ModifyAvatar + } + if change.ModifyAnnouncementsOnly != nil { + cached.AnnouncementsOnly = *change.ModifyAnnouncementsOnly + } + if change.ModifyDisappearingMessagesDuration != nil { + cached.DisappearingMessagesDuration = *change.ModifyDisappearingMessagesDuration + } + if change.ModifyAttributesAccess != nil { + cached.AccessControl.Attributes = *change.ModifyAttributesAccess + } + if change.ModifyMemberAccess != nil { + cached.AccessControl.Members = *change.ModifyMemberAccess + } + if change.ModifyAddFromInviteLinkAccess != nil { + cached.AccessControl.AddFromInviteLink = *change.ModifyAddFromInviteLinkAccess + } + + // TODO handle endorsement responses + cached.UpdatedAt = time.Now() + cached.Revision = change.Revision +} diff --git a/pkg/signalmeow/groups.go b/pkg/signalmeow/groups.go index 39753bb..f25f835 100644 --- a/pkg/signalmeow/groups.go +++ b/pkg/signalmeow/groups.go @@ -114,6 +114,15 @@ func (group *Group) GetInviteLink() (string, error) { return "https://signal.group/#" + inviteLinkPath, nil } +func (group *Group) findMemberOrEmpty(aci uuid.UUID) *GroupMember { + for _, member := range group.Members { + if member.ACI == aci { + return member + } + } + return &GroupMember{} +} + type GroupAccessControl struct { Members AccessControl AddFromInviteLink AccessControl @@ -328,51 +337,22 @@ func (cli *Client) fetchNewGroupCreds(ctx context.Context, today time.Time) (*Gr log.Err(err).Msg("json.Unmarshal error") return nil, err } - // make sure pni matches device pni if creds.PNI != cli.Store.PNI { - err := fmt.Errorf("creds.PNI != d.PNI") - log.Err(err).Msg("creds.PNI != d.PNI") - return nil, err + return nil, fmt.Errorf("mismatching PNI in group credentials: %s != %s", creds.PNI, cli.Store.PNI) } return &creds, nil } -func (cli *Client) getCachedAuthorizationForToday(today time.Time) *GroupCredential { - if cli.GroupCredentials == nil { - // No cached credentials - return nil - } - allCreds := cli.GroupCredentials - // Get the credential for today - for _, cred := range allCreds.Credentials { - if cred.RedemptionTime == today.Unix() { - return &cred - } - } - return nil -} - func (cli *Client) GetAuthorizationForToday(ctx context.Context, masterKey libsignalgo.GroupMasterKey) (*GroupAuth, error) { log := zerolog.Ctx(ctx).With(). Str("action", "get authorization for today"). Logger() - // Timestamps for the start of today, and 7 days later - today := time.Now().Truncate(24 * time.Hour) - todayCred := cli.getCachedAuthorizationForToday(today) - if todayCred == nil { - creds, err := cli.fetchNewGroupCreds(ctx, today) - if err != nil { - return nil, fmt.Errorf("fetchNewGroupCreds error: %w", err) - } - cli.GroupCredentials = creds - todayCred = cli.getCachedAuthorizationForToday(today) - } - if todayCred == nil { - return nil, fmt.Errorf("couldn't get credential for today") + todayCred, err := cli.GroupCache.GetCredentials(ctx, cli.fetchNewGroupCreds) + if err != nil { + return nil, fmt.Errorf("failed to get group credentials: %w", err) } - //TODO: cache cred after unmarshalling redemptionTime := uint64(todayCred.RedemptionTime) credential := todayCred.Credential authCredentialResponse, err := libsignalgo.NewAuthCredentialWithPniResponse(credential) @@ -674,6 +654,7 @@ func (cli *Client) parseGroupResponse(ctx context.Context, response *http.Respon if err != nil { return nil, fmt.Errorf("failed to decrypt group: %w", err) } + cli.GroupCache.Put(group, groupResponse.GroupSendEndorsementsResponse) // Store the profile keys in case they're new for _, member := range group.Members { @@ -717,22 +698,11 @@ func (cli *Client) DownloadGroupAvatar(ctx context.Context, avatarPath string, g } func (cli *Client) RetrieveGroupByID(ctx context.Context, gid types.GroupIdentifier, revision uint32) (*Group, error) { - cli.initGroupCache() - - lastFetched, ok := cli.GroupCache.lastFetched[gid] - if ok && time.Since(lastFetched) < 1*time.Hour { - group, ok := cli.GroupCache.groups[gid] - if ok && group.Revision >= revision { - return group, nil - } + cached, ok := cli.GroupCache.Get(gid) + if ok && cached.Revision >= revision { + return cached, nil } - group, err := cli.fetchGroupByID(ctx, gid) - if err != nil { - return nil, err - } - cli.GroupCache.groups[gid] = group - cli.GroupCache.lastFetched[gid] = time.Now() - return group, nil + return cli.fetchGroupByID(ctx, gid) } // We should store the group master key in the group store as soon as we see it, @@ -750,40 +720,6 @@ func (cli *Client) StoreMasterKey(ctx context.Context, groupMasterKey types.Seri return groupIdentifier, nil } -// We need to track active calls so we don't send too many IncomingSignalMessageCalls -// Of course for group calls Signal doesn't tell us *anything* so we're mostly just inferring -// So we just jam a new call ID in, and return true if we *think* this is a new incoming call -func (cli *Client) UpdateActiveCalls(gid types.GroupIdentifier, callID string) (isActive bool) { - cli.initGroupCache() - // Check to see if we currently have an active call for this group - currentCallID, ok := cli.GroupCache.activeCalls[gid] - if ok { - // If we do, then this must be ending the call - if currentCallID == callID { - delete(cli.GroupCache.activeCalls, gid) - return false - } - } - cli.GroupCache.activeCalls[gid] = callID - return true -} - -func (cli *Client) initGroupCache() { - if cli.GroupCache == nil { - cli.GroupCache = &GroupCache{ - groups: make(map[types.GroupIdentifier]*Group), - lastFetched: make(map[types.GroupIdentifier]time.Time), - activeCalls: make(map[types.GroupIdentifier]string), - } - } -} - -type GroupCache struct { - groups map[types.GroupIdentifier]*Group - lastFetched map[types.GroupIdentifier]time.Time - activeCalls map[types.GroupIdentifier]string -} - func (cli *Client) DecryptGroupChange(ctx context.Context, groupContext *signalpb.GroupContextV2) (*GroupChange, error) { masterKeyBytes := libsignalgo.GroupMasterKey(groupContext.MasterKey) groupMasterKey := masterKeyFromBytes(masterKeyBytes) @@ -801,6 +737,15 @@ func (cli *Client) decryptGroupChange(ctx context.Context, encryptedGroupChange log := zerolog.Ctx(ctx).With().Str("action", "decrypt group change").Logger() serverSignature := encryptedGroupChange.ServerSignature encryptedActionsBytes := encryptedGroupChange.Actions + var success bool + defer func() { + if !success { + rawGroupID, _ := masterKeyToBytes(groupMasterKey).GroupIdentifier() + if rawGroupID != nil { + cli.GroupCache.Delete(types.GroupIdentifier(rawGroupID.String())) + } + } + }() var err error if verifySignature { @@ -1103,6 +1048,9 @@ func (cli *Client) decryptGroupChange(ctx context.Context, encryptedGroupChange decryptedGroupChange.ModifyInviteLinkPassword = &inviteLinkPassword } + success = true + cli.GroupCache.ApplyUpdate(decryptedGroupChange, nil) + return decryptedGroupChange, nil } @@ -1574,9 +1522,7 @@ func (cli *Client) UpdateGroup(ctx context.Context, groupChange *GroupChange, gi return 0, fmt.Errorf("failed to update group: %w", err) } } else if errors.Is(err, ConflictError) { - delete(cli.GroupCache.groups, gid) - delete(cli.GroupCache.lastFetched, gid) - delete(cli.GroupCache.activeCalls, gid) + cli.GroupCache.Delete(gid) group, err = cli.RetrieveGroupByID(ctx, gid, 0) if err != nil { return 0, fmt.Errorf("failed to fetch group after conflict: %w", err) @@ -1590,12 +1536,10 @@ func (cli *Client) UpdateGroup(ctx context.Context, groupChange *GroupChange, gi return 0, fmt.Errorf("unknown error encrypting and signing group change: %w", err) } } - delete(cli.GroupCache.groups, gid) - delete(cli.GroupCache.lastFetched, gid) - delete(cli.GroupCache.activeCalls, gid) if signedGroupChange == nil { return 0, fmt.Errorf("no signed group change returned: %w", err) } + cli.GroupCache.ApplyUpdate(groupChange, signedGroupChange.GroupSendEndorsementsResponse) groupChangeBytes, err := proto.Marshal(signedGroupChange.GroupChange) if err != nil { return 0, fmt.Errorf("failed to marshal signed group change: %w", err) diff --git a/pkg/signalmeow/profile.go b/pkg/signalmeow/profile.go index 4284a8b..f40d6ce 100644 --- a/pkg/signalmeow/profile.go +++ b/pkg/signalmeow/profile.go @@ -134,14 +134,6 @@ func (cli *Client) getCachedProfileByID(signalID uuid.UUID, refreshAfter time.Du } func (cli *Client) RetrieveProfileByID(ctx context.Context, signalID uuid.UUID, refreshAfter time.Duration) (*types.Profile, error) { - if cli.ProfileCache == nil { - cli.ProfileCache = &ProfileCache{ - profiles: make(map[string]*types.Profile), - errors: make(map[string]*error), - lastFetched: make(map[string]time.Time), - } - } - // Check if we have a cached profile that is less than an hour old // or if we have a cached error that is less than an hour old profile, err := cli.getCachedProfileByID(signalID, refreshAfter) diff --git a/pkg/signalmeow/receiving.go b/pkg/signalmeow/receiving.go index 2a023ca..0feee6b 100644 --- a/pkg/signalmeow/receiving.go +++ b/pkg/signalmeow/receiving.go @@ -880,7 +880,7 @@ func (cli *Client) incomingDataMessage( } // Hacky special case for group calls to cache the state if dataMessage.GroupCallUpdate != nil { - isRinging := cli.UpdateActiveCalls(groupID, dataMessage.GroupCallUpdate.GetEraId()) + isRinging := cli.GroupCache.UpdateActiveCall(groupID, dataMessage.GroupCallUpdate.GetEraId()) return cli.handleEvent(&events.Call{ Info: evtInfo, Timestamp: dataMessage.GetTimestamp(), diff --git a/pkg/signalmeow/sending.go b/pkg/signalmeow/sending.go index d919546..e8dc71f 100644 --- a/pkg/signalmeow/sending.go +++ b/pkg/signalmeow/sending.go @@ -42,15 +42,17 @@ import ( // Sending func (cli *Client) senderCertificate(ctx context.Context, e164 bool) (*libsignalgo.SenderCertificate, error) { - cached := cli.SenderCertificateNoE164 + cli.senderCertificateCache.Lock() + defer cli.senderCertificateCache.Unlock() + cached := cli.senderCertificateNoE164 if e164 { - cached = cli.SenderCertificateWithE164 + cached = cli.senderCertificateWithE164 } setCache := func(val *libsignalgo.SenderCertificate) { if e164 { - cli.SenderCertificateWithE164 = val + cli.senderCertificateWithE164 = val } else { - cli.SenderCertificateNoE164 = val + cli.senderCertificateNoE164 = val } } if cached != nil { From 659222b31bc77729b5b09e3274ee7756547a3ca1 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Thu, 27 Nov 2025 16:53:59 +0200 Subject: [PATCH 467/580] signalmeow: implement sending with sender keys --- go.mod | 2 +- go.sum | 4 +- pkg/libsignalgo/profilekey.go | 22 +- pkg/libsignalgo/sealedsender.go | 47 ++- pkg/libsignalgo/serviceid.go | 13 + pkg/signalmeow/keys.go | 8 + pkg/signalmeow/senderkey.go | 374 ++++++++++++++++++ pkg/signalmeow/sending.go | 328 +++++++-------- pkg/signalmeow/store/device.go | 2 +- pkg/signalmeow/store/sender_key_store.go | 67 +++- pkg/signalmeow/store/session_store.go | 65 ++- pkg/signalmeow/store/upgrades/00-latest.sql | 9 + .../upgrades/24-outbound-sender-keys.sql | 9 + pkg/signalmeow/web/web.go | 9 +- 14 files changed, 755 insertions(+), 204 deletions(-) create mode 100644 pkg/signalmeow/senderkey.go create mode 100644 pkg/signalmeow/store/upgrades/24-outbound-sender-keys.sql diff --git a/go.mod b/go.mod index a1be9e8..0b128b6 100644 --- a/go.mod +++ b/go.mod @@ -12,7 +12,7 @@ require ( github.com/rs/zerolog v1.34.0 github.com/stretchr/testify v1.11.1 github.com/tidwall/gjson v1.18.0 - go.mau.fi/util v0.9.4-0.20251124151504-71e0e3476592 + go.mau.fi/util v0.9.4-0.20251126134359-7710832c1450 golang.org/x/crypto v0.44.0 golang.org/x/exp v0.0.0-20251113190631-e25ba8c21ef6 golang.org/x/net v0.47.0 diff --git a/go.sum b/go.sum index aeb8cf5..f2d3989 100644 --- a/go.sum +++ b/go.sum @@ -65,8 +65,8 @@ github.com/tidwall/sjson v1.2.5 h1:kLy8mja+1c9jlljvWTlSazM7cKDRfJuR/bOJhcY5NcY= github.com/tidwall/sjson v1.2.5/go.mod h1:Fvgq9kS/6ociJEDnK0Fk1cpYF4FIW6ZF7LAe+6jwd28= github.com/yuin/goldmark v1.7.13 h1:GPddIs617DnBLFFVJFgpo1aBfe/4xcvMc3SB5t/D0pA= github.com/yuin/goldmark v1.7.13/go.mod h1:ip/1k0VRfGynBgxOz0yCqHrbZXhcjxyuS66Brc7iBKg= -go.mau.fi/util v0.9.4-0.20251124151504-71e0e3476592 h1:qSGoV3kSle4DJIFNTK7AdA3NP5MuA6tlTvQrCKsY9iU= -go.mau.fi/util v0.9.4-0.20251124151504-71e0e3476592/go.mod h1:krWWfBM1jWTb5f8NCa2TLqWMQuM81X7TGQjhMjBeXmQ= +go.mau.fi/util v0.9.4-0.20251126134359-7710832c1450 h1:sYj7slS8b3sav+hYnC2VXEqRpRS6bVvyuQIUGF85k04= +go.mau.fi/util v0.9.4-0.20251126134359-7710832c1450/go.mod h1:krWWfBM1jWTb5f8NCa2TLqWMQuM81X7TGQjhMjBeXmQ= go.mau.fi/zeroconfig v0.2.0 h1:e/OGEERqVRRKlgaro7E6bh8xXiKFSXB3eNNIud7FUjU= go.mau.fi/zeroconfig v0.2.0/go.mod h1:J0Vn0prHNOm493oZoQ84kq83ZaNCYZnq+noI1b1eN8w= golang.org/x/crypto v0.44.0 h1:A97SsFvM3AIwEEmTBiaxPPTYpDC47w720rdiiUvgoAU= diff --git a/pkg/libsignalgo/profilekey.go b/pkg/libsignalgo/profilekey.go index 8d2ae04..e49801a 100644 --- a/pkg/libsignalgo/profilekey.go +++ b/pkg/libsignalgo/profilekey.go @@ -23,6 +23,7 @@ package libsignalgo */ import "C" import ( + "encoding/base64" "errors" "runtime" "unsafe" @@ -54,10 +55,6 @@ func (pk *ProfileKey) IsEmpty() bool { return pk == nil || *pk == blankProfileKey } -func (ak *AccessKey) String() string { - return string(ak[:]) -} - func (pv *ProfileKeyVersion) String() string { return string(pv[:]) } @@ -69,6 +66,23 @@ func (pk *ProfileKey) Slice() []byte { return pk[:] } +func (ak *AccessKey) Xor(other *AccessKey) *AccessKey { + if ak == nil { + return other + } else if other == nil { + return ak + } + var result AccessKey + for i := 0; i < C.SignalACCESS_KEY_LEN; i++ { + result[i] = ak[i] ^ other[i] + } + return &result +} + +func (ak *AccessKey) String() string { + return base64.StdEncoding.EncodeToString(ak[:]) +} + func (pk *ProfileKey) GetCommitment(u uuid.UUID) (*ProfileKeyCommitment, error) { c_result := [C.SignalPROFILE_KEY_COMMITMENT_LEN]C.uchar{} c_profileKey := (*[C.SignalPROFILE_KEY_LEN]C.uchar)(unsafe.Pointer(pk)) diff --git a/pkg/libsignalgo/sealedsender.go b/pkg/libsignalgo/sealedsender.go index 1530183..5a55a2c 100644 --- a/pkg/libsignalgo/sealedsender.go +++ b/pkg/libsignalgo/sealedsender.go @@ -24,6 +24,7 @@ import "C" import ( "context" "runtime" + "unsafe" "github.com/google/uuid" ) @@ -78,8 +79,50 @@ func SealedSenderEncrypt(ctx context.Context, usmc *UnidentifiedSenderMessageCon return CopySignalOwnedBufferToBytes(encrypted), nil } -func SealedSenderMultiRecipientEncrypt(messageContent *UnidentifiedSenderMessageContent, forRecipients []*Address, identityStore IdentityKeyStore, sessionStore SessionStore, ctx *CallbackContext) ([]byte, error) { - panic("not implemented") +type SessionAddressTuple struct { + ServiceID ServiceID + DeviceID int + Address *Address + Record *SessionRecord +} + +func SealedSenderMultiRecipientEncrypt( + ctx context.Context, + usmc *UnidentifiedSenderMessageContent, + recipients []SessionAddressTuple, + identityStore IdentityKeyStore, +) ([]byte, error) { + var encrypted C.SignalOwnedBuffer = C.SignalOwnedBuffer{} + callbackCtx := NewCallbackContext(ctx) + defer callbackCtx.Unref() + recipientAddresses := make([]C.SignalConstPointerProtocolAddress, len(recipients)) + recipientSessions := make([]C.SignalConstPointerSessionRecord, len(recipients)) + for i, recipient := range recipients { + recipientAddresses[i] = recipient.Address.constPtr() + recipientSessions[i] = recipient.Record.constPtr() + } + signalFfiError := C.signal_sealed_sender_multi_recipient_encrypt( + &encrypted, + C.SignalBorrowedSliceOfConstPointerProtocolAddress{ + base: unsafe.SliceData(recipientAddresses), + length: C.size_t(len(recipientAddresses)), + }, + C.SignalBorrowedSliceOfConstPointerSessionRecord{ + base: unsafe.SliceData(recipientSessions), + length: C.size_t(len(recipientSessions)), + }, + BytesToBuffer(nil), + usmc.constPtr(), + callbackCtx.wrapIdentityKeyStore(identityStore), + ) + runtime.KeepAlive(usmc) + runtime.KeepAlive(recipients) + runtime.KeepAlive(recipientAddresses) + runtime.KeepAlive(recipientSessions) + if signalFfiError != nil { + return nil, callbackCtx.wrapError(signalFfiError) + } + return CopySignalOwnedBufferToBytes(encrypted), nil } type SealedSenderResult struct { diff --git a/pkg/libsignalgo/serviceid.go b/pkg/libsignalgo/serviceid.go index 19513de..6b0c864 100644 --- a/pkg/libsignalgo/serviceid.go +++ b/pkg/libsignalgo/serviceid.go @@ -118,6 +118,19 @@ func (s ServiceID) GoString() string { return fmt.Sprintf(`libsignalgo.ServiceID{Type: %#v, UUID: uuid.MustParse("%s")}`, s.Type, s.UUID) } +func (s ServiceID) MarshalText() ([]byte, error) { + return []byte(s.String()), nil +} + +func (s *ServiceID) UnmarshalText(text []byte) error { + parsed, err := ServiceIDFromString(string(text)) + if err != nil { + return err + } + *s = parsed + return nil +} + func (s ServiceID) MarshalZerologObject(e *zerolog.Event) { e.Stringer("type", s.Type) e.Stringer("uuid", s.UUID) diff --git a/pkg/signalmeow/keys.go b/pkg/signalmeow/keys.go index 19ad1f6..724565a 100644 --- a/pkg/signalmeow/keys.go +++ b/pkg/signalmeow/keys.go @@ -404,16 +404,24 @@ func addBase64PaddingAndDecode(data string) ([]byte, error) { return base64.StdEncoding.DecodeString(data) } +var ( + ErrUnregisteredUser = errors.New("got 404 when fetching prekey, user is unregistered") + ErrDevicesChanged = errors.New("device list changed while sending skdm") +) + func (cli *Client) FetchAndProcessPreKey(ctx context.Context, theirServiceID libsignalgo.ServiceID, specificDeviceID int) error { // Fetch prekey deviceIDPath := "/*" if specificDeviceID >= 0 { deviceIDPath = "/" + fmt.Sprint(specificDeviceID) } + // TODO this should be done via the unauthed websocket if possible path := "/v2/keys/" + theirServiceID.String() + deviceIDPath + "?pq=true" resp, err := cli.AuthedWS.SendRequest(ctx, http.MethodGet, path, nil, nil) if err != nil { return fmt.Errorf("error sending request: %w", err) + } else if resp.GetStatus() == 404 { + return ErrUnregisteredUser } var respData prekeyResponse err = web.DecodeWSResponseBody(ctx, &respData, resp) diff --git a/pkg/signalmeow/senderkey.go b/pkg/signalmeow/senderkey.go new file mode 100644 index 0000000..133ef80 --- /dev/null +++ b/pkg/signalmeow/senderkey.go @@ -0,0 +1,374 @@ +// mautrix-signal - A Matrix-signal puppeting bridge. +// Copyright (C) 2025 Tulir Asokan +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +package signalmeow + +import ( + "context" + "encoding/json" + "errors" + "fmt" + "maps" + "net/http" + "slices" + "time" + + "github.com/google/uuid" + "github.com/rs/zerolog" + "go.mau.fi/util/exslices" + "google.golang.org/protobuf/proto" + + "go.mau.fi/mautrix-signal/pkg/libsignalgo" + signalpb "go.mau.fi/mautrix-signal/pkg/signalmeow/protobuf" + "go.mau.fi/mautrix-signal/pkg/signalmeow/store" + "go.mau.fi/mautrix-signal/pkg/signalmeow/types" + "go.mau.fi/mautrix-signal/pkg/signalmeow/web" +) + +const SenderKeyMaxAge = 14 * 24 * time.Hour + +type contextKey int + +const ( + contextKeyEncryptionLock contextKey = iota +) + +func (cli *Client) sendToGroupWithSenderKey( + ctx context.Context, + groupID types.GroupIdentifier, + allRecipients []libsignalgo.ServiceID, + content *signalpb.Content, + messageTimestamp uint64, + retries int, +) (*GroupMessageSendResult, error) { + if retries >= 3 { + return cli.sendToGroup(ctx, allRecipients, content, messageTimestamp, nil) + } + myAddress, err := cli.Store.ACIServiceID().Address(uint(cli.Store.DeviceID)) + if err != nil { + return nil, fmt.Errorf("failed to get own address: %w", err) + } + log := zerolog.Ctx(ctx) + + cli.encryptionLock.Lock() + unlocked := false + doUnlock := func() { + if !unlocked { + unlocked = true + cli.encryptionLock.Unlock() + } + } + defer doUnlock() + ctx = context.WithValue(ctx, contextKeyEncryptionLock, true) + result := &GroupMessageSendResult{ + SuccessfullySentTo: make([]SuccessfulSendResult, 0), + FailedToSendTo: make([]FailedSendResult, 0), + } + + deviceIDs, senderKeyRecipients, fallbackRecipients := cli.getDevicesIDs(ctx, allRecipients, result) + ski, err := cli.Store.SenderKeyStore.GetSenderKeyInfo(ctx, groupID) + if err != nil { + return nil, fmt.Errorf("failed to get sender key info: %w", err) + } else if ski == nil || time.Since(ski.CreatedAt) > SenderKeyMaxAge { + if ski != nil && time.Since(ski.CreatedAt) > SenderKeyMaxAge { + log.Debug().Any("old_sender_key_info", ski).Msg("Sender key expired, creating new one") + err = cli.Store.SenderKeyStore.DeleteSenderKey(ctx, myAddress, ski.DistributionID) + if err != nil { + return nil, fmt.Errorf("failed to delete old sender key: %w", err) + } + } else { + log.Debug().Msg("No existing sender key, creating new one") + } + ski = &store.SenderKeyInfo{ + DistributionID: uuid.New(), + CreatedAt: time.Now(), + SharedWith: make(map[libsignalgo.ServiceID][]int), + } + } else { + log.Debug().Any("sender_key_info", ski).Msg("Reusing existing sender key") + } + xak, devicesAddedTo, reset := diffRecipients(ski.SharedWith, deviceIDs) + if reset { + log.Debug().Msg("Resetting sender key due to recipient device changes") + devicesAddedTo = slices.Collect(maps.Keys(deviceIDs)) + err = cli.Store.SenderKeyStore.DeleteSenderKey(ctx, myAddress, ski.DistributionID) + if err != nil { + return nil, fmt.Errorf("failed to delete old sender key: %w", err) + } + } + if len(devicesAddedTo) > 0 { + log.Debug(). + Any("devices_added_to", devicesAddedTo). + Msg("Sending sender key distribution message to users with new devices") + skdm, err := libsignalgo.NewSenderKeyDistributionMessage(ctx, myAddress, ski.DistributionID, cli.Store.SenderKeyStore) + if err != nil { + return nil, fmt.Errorf("failed to create sender key distribution message: %w", err) + } + skdmBytes, err := skdm.Serialize() + if err != nil { + return nil, fmt.Errorf("failed to serialize sender key distribution message: %w", err) + } + var needsRetry bool + for _, recipient := range devicesAddedTo { + log := log.With().Str("subaction", "skdm").Stringer("recipient_id", recipient).Logger() + _, err = cli.sendContent(log.WithContext(ctx), recipient, messageTimestamp, &signalpb.Content{ + SenderKeyDistributionMessage: skdmBytes, + }, 0, true, true) + if errors.Is(err, ErrDevicesChanged) || errors.Is(err, ErrUnregisteredUser) { + log.Warn().Err(err).Msg("Failed to send sender key distribution message due to device changes, will retry") + needsRetry = true + } else if err != nil { + log.Err(err).Msg("Failed to send sender key distribution message") + fallbackRecipients = append(fallbackRecipients, recipient) + delete(deviceIDs, recipient) + senderKeyRecipients = slices.DeleteFunc(senderKeyRecipients, func(tuple store.SessionAddressTuple) bool { + return tuple.ServiceID == recipient + }) + } else { + log.Debug().Msg("Successfully sent sender key distribution message") + ski.SharedWith[recipient] = deviceIDs[recipient].DeviceIDs + } + } + err = cli.Store.SenderKeyStore.PutSenderKeyInfo(ctx, groupID, ski) + if err != nil { + return nil, fmt.Errorf("failed to store updated sender key info: %w", err) + } + if needsRetry { + doUnlock() + return cli.sendToGroupWithSenderKey(ctx, groupID, allRecipients, content, messageTimestamp, retries+1) + } + } + ssCiphertext, err := cli.encryptWithSenderKey(ctx, groupID, ski.DistributionID, myAddress, senderKeyRecipients, content) + if err != nil { + return nil, err + } + header := http.Header{} + header.Set("Content-Type", string(web.ContentTypeMultiRecipientMessage)) + //if groupSendToken != nil { + // header.Set("Group-Send-Token", groupSendToken.String()) + //} else { + header.Set("Unidentified-Access-Key", xak.String()) + //} + path := fmt.Sprintf( + "/v1/messages/multi_recipient?ts=%d&urgent=%t&online=false", + messageTimestamp, isUrgent(content), + ) + log.Debug(). + Any("recipients", ski.SharedWith). + Any("fallback_recipients", fallbackRecipients). + Msg("Sending multi-recipient message with sender key") + resp, err := cli.UnauthedWS.SendRequest(ctx, http.MethodPut, path, ssCiphertext, header) + switch resp.GetStatus() { + case 200: + var respData MultiRecipient200Response + err = json.Unmarshal(resp.Body, &respData) + if err != nil { + return nil, fmt.Errorf("failed to unmarshal 200 response: %w", err) + } + log.Debug(). + Any("response_data", respData). + Msg("Got successful multi-recipient send response") + for serviceID := range deviceIDs { + if slices.Contains(respData.UUIDs404, serviceID) { + // TODO flag recipient as unregistered + err = cli.Store.ACISessionStore.RemoveAllSessionsForServiceID(ctx, serviceID) + if err != nil { + log.Err(err).Stringer("recipient_id", serviceID). + Msg("Failed to remove sessions after 404") + } + result.FailedToSendTo = append(result.FailedToSendTo, FailedSendResult{ + Recipient: serviceID, + Error: fmt.Errorf("multi-recipient send 404"), + }) + } else { + result.SuccessfullySentTo = append(result.SuccessfullySentTo, SuccessfulSendResult{ + Recipient: serviceID, + Unidentified: true, + }) + } + } + doUnlock() + // Send with fallback for any recipients that couldn't do sender key, plus our own sync copy + return cli.sendToGroup(ctx, fallbackRecipients, content, messageTimestamp, result) + case 401, 404: + log.Warn().Uint32("status_code", resp.GetStatus()). + Msg("Multi-recipient send failed, falling back to normal send") + doUnlock() + // Fall back to normal send for all recipients + return cli.sendToGroup(ctx, allRecipients, content, messageTimestamp, nil) + case 409, 410: + log.Warn().Uint32("status_code", resp.GetStatus()). + Msg("Multi-recipient send failed due to outdated device list, refreshing and retrying") + err = cli.handleMultiRecipient409410Response(ctx, resp) + if err != nil { + return nil, err + } + doUnlock() + // Retry recursively after fixing device lists + return cli.sendToGroupWithSenderKey(ctx, groupID, allRecipients, content, messageTimestamp, retries+1) + default: + return nil, fmt.Errorf("unexpected status code %d in multi-recipient send", resp.GetStatus()) + } +} + +func (cli *Client) encryptWithSenderKey( + ctx context.Context, + groupID types.GroupIdentifier, + distributionID uuid.UUID, + myAddress *libsignalgo.Address, + senderKeyRecipients []store.SessionAddressTuple, + content *signalpb.Content, +) ([]byte, error) { + plaintext, err := proto.Marshal(content) + if err != nil { + return nil, fmt.Errorf("failed to marshal content: %w", err) + } + plaintext, err = addPadding(3, plaintext) + if err != nil { + return nil, fmt.Errorf("failed to add padding: %w", err) + } + ciphertext, err := libsignalgo.GroupEncrypt(ctx, plaintext, myAddress, distributionID, cli.Store.SenderKeyStore) + if err != nil { + return nil, fmt.Errorf("failed to encrypt group message: %w", err) + } + cert, err := cli.senderCertificate(ctx, false) + if err != nil { + return nil, fmt.Errorf("failed to get sender certificate: %w", err) + } + groupIDBytes, err := groupID.Bytes() + if err != nil { + return nil, fmt.Errorf("failed to deserialize group ID: %w", err) + } + usmc, err := libsignalgo.NewUnidentifiedSenderMessageContent(ciphertext, cert, getContentHint(content), groupIDBytes[:]) + if err != nil { + return nil, fmt.Errorf("failed to create unidentified sender message content: %w", err) + } + ssCiphertext, err := libsignalgo.SealedSenderMultiRecipientEncrypt(ctx, usmc, senderKeyRecipients, cli.Store.ACIIdentityStore) + if err != nil { + return nil, fmt.Errorf("failed to create sealed sender multi-recipient message: %w", err) + } + return ssCiphertext, nil +} + +func diffRecipients( + prevDevices map[libsignalgo.ServiceID][]int, newDevices map[libsignalgo.ServiceID]senderKeySendMeta, +) ( + xak *libsignalgo.AccessKey, devicesAddedTo []libsignalgo.ServiceID, reset bool, +) { + collector := make(map[libsignalgo.ServiceID]uint8, max(len(prevDevices), len(newDevices))) + for key := range prevDevices { + collector[key] |= 0b01 + } + for key := range newDevices { + collector[key] |= 0b10 + } + for serviceID, mask := range collector { + if mask != 0b01 { + xak = xak.Xor(newDevices[serviceID].AccessKey) + } + switch mask { + case 0b01: + // Someone left the group + reset = true + case 0b10: + // Someone was added to the group + devicesAddedTo = append(devicesAddedTo, serviceID) + case 0b11: + removedDevices, addedDevices := exslices.Diff(prevDevices[serviceID], newDevices[serviceID].DeviceIDs) + if len(removedDevices) > 0 { + // Device was removed + reset = true + } else if len(addedDevices) > 0 { + // User got new devices + devicesAddedTo = append(devicesAddedTo, serviceID) + } + } + } + return +} + +type senderKeySendMeta struct { + DeviceIDs []int + AccessKey *libsignalgo.AccessKey +} + +func (cli *Client) getDevicesIDs(ctx context.Context, recipients []libsignalgo.ServiceID, result *GroupMessageSendResult) ( + map[libsignalgo.ServiceID]senderKeySendMeta, []store.SessionAddressTuple, []libsignalgo.ServiceID, +) { + log := zerolog.Ctx(ctx) + out := make(map[libsignalgo.ServiceID]senderKeySendMeta) + fallbackRecipients := recipients[:0] + senderKeyRecipients := make([]store.SessionAddressTuple, 0, len(recipients)) + for _, recipient := range recipients { + if recipient == cli.Store.ACIServiceID() { + // We'll send a sync copy to ourselves, not sender key and no need to include in fallback recipients either + continue + } + fallbackRecipients = append(fallbackRecipients, recipient) + if recipient.Type != libsignalgo.ServiceIDTypeACI { + continue + } + profileKey, err := cli.Store.RecipientStore.LoadProfileKey(ctx, recipient.UUID) + if err != nil { + log.Err(err).Stringer("recipient_id", recipient.UUID).Msg("Failed to get profile key") + continue + } else if profileKey == nil { + log.Debug().Stringer("recipient_id", recipient.UUID).Msg("No profile key for recipient") + continue + } + accessKey, err := profileKey.DeriveAccessKey() + if err != nil { + log.Err(err).Stringer("recipient_id", recipient.UUID).Msg("Failed to derive access key") + continue + } + sessions, err := cli.Store.ACISessionStore.AllSessionsForServiceID(ctx, recipient) + if err == nil && len(sessions) == 0 { + // No sessions, make one with prekey + err = cli.FetchAndProcessPreKey(ctx, recipient, -1) + if errors.Is(err, ErrUnregisteredUser) { + fallbackRecipients = fallbackRecipients[:len(fallbackRecipients)-1] + result.FailedToSendTo = append(result.FailedToSendTo, FailedSendResult{ + Recipient: recipient, + Error: err, + }) + log.Debug(). + Stringer("recipient_id", recipient). + Msg("Recipient is not registered, won't try to send") + continue + } else if err != nil { + log.Warn().Err(err).Stringer("recipient_id", recipient.UUID).Msg("Failed to fetch keys for recipient") + continue + } + sessions, err = cli.Store.ACISessionStore.AllSessionsForServiceID(ctx, recipient) + } + if err != nil { + log.Err(err).Stringer("recipient_id", recipient.UUID).Msg("Failed to get sessions for recipient") + continue + } else if len(sessions) == 0 { + log.Debug().Stringer("recipient_id", recipient.UUID).Msg("No sessions for recipient after fetching keys") + continue + } + fallbackRecipients = fallbackRecipients[:len(fallbackRecipients)-1] + out[recipient] = senderKeySendMeta{ + DeviceIDs: exslices.CastFunc(sessions, func(from store.SessionAddressTuple) int { + return from.DeviceID + }), + AccessKey: accessKey, + } + senderKeyRecipients = append(senderKeyRecipients, sessions...) + } + return out, senderKeyRecipients, fallbackRecipients +} diff --git a/pkg/signalmeow/sending.go b/pkg/signalmeow/sending.go index e8dc71f..d9fd831 100644 --- a/pkg/signalmeow/sending.go +++ b/pkg/signalmeow/sending.go @@ -143,72 +143,39 @@ func addPadding(version uint32, contents []byte) ([]byte, error) { } } -func checkForErrorWithSessions(err error, addresses []*libsignalgo.Address, sessionRecords []*libsignalgo.SessionRecord) error { - if err != nil { - return err +func (cli *Client) buildMessagesToSend( + ctx context.Context, + recipient libsignalgo.ServiceID, + content *signalpb.Content, + unauthenticated, isGroup bool, +) ([]MyMessage, error) { + if ctx.Value(contextKeyEncryptionLock) != true { + cli.encryptionLock.Lock() + defer cli.encryptionLock.Unlock() } - if addresses == nil || sessionRecords == nil { - return fmt.Errorf("addresses or session records are nil") - } - if len(addresses) != len(sessionRecords) { - return fmt.Errorf("mismatched number of addresses (%d) and session records (%d)", len(addresses), len(sessionRecords)) - } - if len(addresses) == 0 || len(sessionRecords) == 0 { - return fmt.Errorf("no addresses or session records") - } - return nil -} -func (cli *Client) howManyOtherDevicesDoWeHave(ctx context.Context) int { - addresses, _, err := cli.Store.ACISessionStore.AllSessionsForServiceID(ctx, cli.Store.ACIServiceID()) - if err != nil { - return 0 - } - // Filter out our deviceID - otherDevices := 0 - for _, address := range addresses { - deviceID, err := address.DeviceID() - if err != nil { - zerolog.Ctx(ctx).Err(err).Msg("Error getting deviceID from address") - continue - } - if deviceID != uint(cli.Store.DeviceID) { - otherDevices++ - } - } - return otherDevices -} - -func (cli *Client) buildMessagesToSend(ctx context.Context, recipient libsignalgo.ServiceID, content *signalpb.Content, unauthenticated, isGroup bool) ([]MyMessage, error) { - // We need to prevent multiple encryption operations from happening at once, or else ratchets can race - cli.encryptionLock.Lock() - defer cli.encryptionLock.Unlock() - - addresses, sessionRecords, err := cli.Store.ACISessionStore.AllSessionsForServiceID(ctx, recipient) - if err == nil && (len(addresses) == 0 || len(sessionRecords) == 0) { + sessions, err := cli.Store.ACISessionStore.AllSessionsForServiceID(ctx, recipient) + if err == nil && len(sessions) == 0 { // No sessions, make one with prekey err = cli.FetchAndProcessPreKey(ctx, recipient, -1) if err != nil { + // TODO flag 404s as unregistered return nil, err } - addresses, sessionRecords, err = cli.Store.ACISessionStore.AllSessionsForServiceID(ctx, recipient) + sessions, err = cli.Store.ACISessionStore.AllSessionsForServiceID(ctx, recipient) } - err = checkForErrorWithSessions(err, addresses, sessionRecords) if err != nil { return nil, err + } else if len(sessions) == 0 { + return nil, fmt.Errorf("no sessions found for recipient %s", recipient.String()) } - messages := make([]MyMessage, 0, len(addresses)) - for i, recipientAddress := range addresses { - recipientDeviceID, err := recipientAddress.DeviceID() - if err != nil { - return nil, err - } - + messages := make([]MyMessage, 0, len(sessions)) + for _, tuple := range sessions { // Don't send to this device that we are sending from - if recipient == cli.Store.ACIServiceID() && recipientDeviceID == uint(cli.Store.DeviceID) { + if recipient == cli.Store.ACIServiceID() && tuple.DeviceID == cli.Store.DeviceID { zerolog.Ctx(ctx).Debug(). - Uint("recipient_device_id", recipientDeviceID). + Int("recipient_device_id", tuple.DeviceID). Msg("Not sending to the device I'm sending from") continue } @@ -222,29 +189,28 @@ func (cli *Client) buildMessagesToSend(ctx context.Context, recipient libsignalg if err != nil { return nil, err } - sessionRecord := sessionRecords[i] var envelopeType int var encryptedPayload []byte if unauthenticated { includeE164 := !isGroup && cli.Store.AccountRecord.GetPhoneNumberSharingMode() == signalpb.AccountRecord_EVERYBODY envelopeType, encryptedPayload, err = cli.buildSSMessageToSend( - ctx, recipientAddress, paddedMessage, getContentHint(content), includeE164, + ctx, tuple.Address, paddedMessage, getContentHint(content), includeE164, ) } else { - envelopeType, encryptedPayload, err = cli.buildAuthedMessageToSend(ctx, recipientAddress, paddedMessage) + envelopeType, encryptedPayload, err = cli.buildAuthedMessageToSend(ctx, tuple.Address, paddedMessage) } if err != nil { return nil, err } - destinationRegistrationID, err := sessionRecord.GetRemoteRegistrationID() + destinationRegistrationID, err := tuple.Record.GetRemoteRegistrationID() if err != nil { return nil, err } outgoingMessage := MyMessage{ Type: envelopeType, - DestinationDeviceID: int(recipientDeviceID), + DestinationDeviceID: tuple.DeviceID, DestinationRegistrationID: int(destinationRegistrationID), Content: base64.StdEncoding.EncodeToString(encryptedPayload), } @@ -549,26 +515,28 @@ func (cli *Client) SendGroupUpdate(ctx context.Context, group *Group, groupConte GroupV2: groupContext, } content := wrapDataMessageInContent(dm) - var recipients []*libsignalgo.ServiceID + var recipients []libsignalgo.ServiceID for _, member := range group.Members { serviceID := member.UserServiceID() - recipients = append(recipients, &serviceID) + recipients = append(recipients, serviceID) } for _, member := range group.PendingMembers { - recipients = append(recipients, &member.ServiceID) + recipients = append(recipients, member.ServiceID) } if groupChange != nil { for _, member := range groupChange.AddPendingMembers { - recipients = append(recipients, &member.ServiceID) + recipients = append(recipients, member.ServiceID) } for _, member := range groupChange.AddMembers { serviceID := member.UserServiceID() - recipients = append(recipients, &serviceID) + recipients = append(recipients, serviceID) } } - return cli.sendToGroup(ctx, recipients, content, timestamp) + return cli.sendToGroup(ctx, recipients, content, timestamp, nil) } +const enableSenderKeySend = false + func (cli *Client) SendGroupMessage(ctx context.Context, gid types.GroupIdentifier, content *signalpb.Content) (*GroupMessageSendResult, error) { log := zerolog.Ctx(ctx).With(). Str("action", "send group message"). @@ -587,44 +555,83 @@ func (cli *Client) SendGroupMessage(ctx context.Context, gid types.GroupIdentifi } else if content.GetEditMessage().GetDataMessage() != nil { messageTimestamp = content.EditMessage.DataMessage.GetTimestamp() content.EditMessage.DataMessage.GroupV2 = groupMetadataForDataMessage(*group) + } else if content.GetTypingMessage() != nil { + messageTimestamp = content.TypingMessage.GetTimestamp() + groupIDBytes, err := group.GroupIdentifier.Bytes() + if err != nil { + return nil, err + } + content.TypingMessage.GroupId = groupIDBytes[:] } - var recipients []*libsignalgo.ServiceID + var recipients []libsignalgo.ServiceID for _, member := range group.Members { - serviceID := member.UserServiceID() - recipients = append(recipients, &serviceID) + recipients = append(recipients, member.UserServiceID()) } - return cli.sendToGroup(ctx, recipients, content, messageTimestamp) + if enableSenderKeySend { + return cli.sendToGroupWithSenderKey(ctx, gid, recipients, content, messageTimestamp, 0) + } + return cli.sendToGroup(ctx, recipients, content, messageTimestamp, nil) } -func (cli *Client) sendToGroup(ctx context.Context, recipients []*libsignalgo.ServiceID, content *signalpb.Content, messageTimestamp uint64) (*GroupMessageSendResult, error) { - // Send to each member of the group - result := &GroupMessageSendResult{ - SuccessfullySentTo: []SuccessfulSendResult{}, - FailedToSendTo: []FailedSendResult{}, +func (cli *Client) sendToGroup( + ctx context.Context, + recipients []libsignalgo.ServiceID, + content *signalpb.Content, + messageTimestamp uint64, + result *GroupMessageSendResult, +) (*GroupMessageSendResult, error) { + if result == nil { + result = &GroupMessageSendResult{ + SuccessfullySentTo: []SuccessfulSendResult{}, + FailedToSendTo: []FailedSendResult{}, + } + } + if content.TypingMessage != nil { + // Never send typing messages via fallback path + return result, nil } for _, recipient := range recipients { if recipient.Type == libsignalgo.ServiceIDTypeACI && recipient.UUID == cli.Store.ACI { // Don't send normal DataMessages to ourselves continue } - log := zerolog.Ctx(ctx).With().Stringer("member", *recipient).Logger() + log := zerolog.Ctx(ctx).With().Stringer("member", recipient).Logger() ctx := log.WithContext(ctx) - sentUnidentified, err := cli.sendContent(ctx, *recipient, messageTimestamp, content, 0, true, true) + sentUnidentified, err := cli.sendContent(ctx, recipient, messageTimestamp, content, 0, true, true) if err != nil { result.FailedToSendTo = append(result.FailedToSendTo, FailedSendResult{ - Recipient: *recipient, + Recipient: recipient, Error: err, }) log.Err(err).Msg("Failed to send to user") } else { result.SuccessfullySentTo = append(result.SuccessfullySentTo, SuccessfulSendResult{ - Recipient: *recipient, + Recipient: recipient, Unidentified: sentUnidentified, }) log.Trace().Msg("Successfully sent to user") } } + cli.sendGroupSyncCopy(ctx, content, messageTimestamp, result) + + if len(result.FailedToSendTo) == 0 && len(result.SuccessfullySentTo) == 0 { + return result, nil // I only sent to myself + } + if len(result.SuccessfullySentTo) == 0 { + lastError := result.FailedToSendTo[len(result.FailedToSendTo)-1].Error + return nil, fmt.Errorf("failed to send to any group members: %w", lastError) + } + + return result, nil +} + +func (cli *Client) sendGroupSyncCopy( + ctx context.Context, + content *signalpb.Content, + messageTimestamp uint64, + result *GroupMessageSendResult, +) { var syncContent *signalpb.Content if content.GetDataMessage() != nil { syncContent = syncMessageFromGroupDataMessage(content.DataMessage, result.SuccessfullySentTo) @@ -637,16 +644,6 @@ func (cli *Client) sendToGroup(ctx context.Context, recipients []*libsignalgo.Se zerolog.Ctx(ctx).Err(selfSendErr).Msg("Failed to send sync message to myself") } } - - if len(result.FailedToSendTo) == 0 && len(result.SuccessfullySentTo) == 0 { - return result, nil // I only sent to myself - } - if len(result.SuccessfullySentTo) == 0 { - lastError := result.FailedToSendTo[len(result.FailedToSendTo)-1].Error - return nil, fmt.Errorf("failed to send to any group members: %w", lastError) - } - - return result, nil } func (cli *Client) sendSyncCopy(ctx context.Context, content *signalpb.Content, messageTS uint64, result *SuccessfulSendResult) bool { @@ -862,6 +859,9 @@ func (cli *Client) sendContent( useUnidentifiedSender = false } } + if !useUnidentifiedSender && content.SenderKeyDistributionMessage != nil { + return false, fmt.Errorf("won't send sender key distribution message without sealed sender") + } var messages []MyMessage messages, err = cli.buildMessagesToSend(ctx, recipient, content, useUnidentifiedSender, isGroup) @@ -887,7 +887,7 @@ func (cli *Client) sendContent( header.Set("Content-Type", string(web.ContentTypeJSON)) if useUnidentifiedSender { log.Trace().Msg("Sending message over unidentified WS") - header.Set("Unidentified-Access-Key", base64.StdEncoding.EncodeToString(accessKey[:])) + header.Set("Unidentified-Access-Key", accessKey.String()) response, err = cli.UnauthedWS.SendRequest(ctx, http.MethodPut, path, jsonBytes, header) } else { log.Trace().Msg("Sending message over authed WS") @@ -921,11 +921,14 @@ func (cli *Client) sendContent( } if needToRetry { - var err error - if *response.Status == 409 { - err = cli.handle409(ctx, recipient, response) - } else if *response.Status == 410 { - err = cli.handle410(ctx, recipient, response) + if *response.Status == 409 || *response.Status == 410 { + err = cli.handleSingleRecipient409410Response(ctx, recipient, response) + if content.SenderKeyDistributionMessage != nil { + if err == nil { + err = ErrDevicesChanged + } + return false, err + } } else if *response.Status == 428 { err = cli.handle428(ctx, recipient, response) } @@ -939,6 +942,9 @@ func (cli *Client) sendContent( return sentUnidentified, err } } else if *response.Status == 401 && useUnidentifiedSender { + if content.SenderKeyDistributionMessage != nil { + return sentUnidentified, fmt.Errorf("unauthorized to send sender key distribution message via sealed sender") + } log.Debug().Msg("Retrying send without sealed sender") // Try to send again (**RECURSIVELY**) sentUnidentified, err = cli.sendContent(ctx, recipient, messageTimestamp, content, retryCount+1, false, isGroup) @@ -946,6 +952,13 @@ func (cli *Client) sendContent( log.Err(err).Msg("2nd try sendMessage error") return sentUnidentified, err } + } else if *response.Status == 404 { + // TODO flag recipient as unregistered + err = cli.Store.ACISessionStore.RemoveAllSessionsForServiceID(ctx, recipient) + if err != nil { + log.Err(err).Msg("Failed to remove sessions after 404") + } + return sentUnidentified, ErrUnregisteredUser } else if *response.Status != 200 { return sentUnidentified, fmt.Errorf("unexpected status code while sending: %d", *response.Status) } @@ -953,81 +966,88 @@ func (cli *Client) sendContent( return sentUnidentified, nil } -// A 409 means our device list was out of date, so we will fix it up -func (cli *Client) handle409(ctx context.Context, recipient libsignalgo.ServiceID, response *signalpb.WebSocketResponseMessage) error { - log := zerolog.Ctx(ctx) - // Decode json body - // TODO use an actual struct for this - var body map[string]interface{} - err := json.Unmarshal(response.Body, &body) - if err != nil { - log.Err(err).Msg("Unmarshal error") - return err - } - // check for missingDevices and extraDevices - if body["missingDevices"] != nil { - missingDevices := body["missingDevices"].([]any) - log.Debug().Any("missing_devices", missingDevices).Msg("missing devices found in 409 response") - // TODO: establish session with missing devices - for _, missingDevice := range missingDevices { - err = cli.FetchAndProcessPreKey(ctx, recipient, int(missingDevice.(float64))) - if err != nil { - return nil - } - } - } - if body["extraDevices"] != nil { - extraDevices := body["extraDevices"].([]any) - log.Debug().Any("extra_devices", extraDevices).Msg("extra devices found in 409 response") - for _, extraDevice := range extraDevices { - recipientAddr, err := recipient.Address(uint(extraDevice.(float64))) - if err != nil { - log.Err(err).Msg("NewAddress error") - return err - } - err = cli.Store.ACISessionStore.RemoveSession(ctx, recipientAddr) - if err != nil { - log.Err(err).Msg("RemoveSession error") - return err - } - } - } - return err +type SingleRecipient409410Response struct { + MissingDevices []uint `json:"missingDevices"` + ExtraDevices []uint `json:"extraDevices"` + StaleDevices []uint `json:"staleDevices"` } -// A 410 means we have a stale device, so get rid of it -func (cli *Client) handle410(ctx context.Context, recipient libsignalgo.ServiceID, response *signalpb.WebSocketResponseMessage) error { - log := zerolog.Ctx(ctx) - // Decode json body - // TODO use an actual struct - var body map[string]interface{} +type MultiRecipient409410Response struct { + UUID libsignalgo.ServiceID `json:"uuid"` + Devices SingleRecipient409410Response `json:"devices"` +} + +type MultiRecipient200Response struct { + UUIDs404 []libsignalgo.ServiceID `json:"uuids404"` + NeedsSync bool `json:"needsSync"` +} + +func (cli *Client) handleSingleRecipient409410Response(ctx context.Context, recipient libsignalgo.ServiceID, response *signalpb.WebSocketResponseMessage) error { + var body SingleRecipient409410Response err := json.Unmarshal(response.Body, &body) if err != nil { - log.Err(err).Msg("Unmarshal error") - return err + return fmt.Errorf("failed to unmarshal error response body: %w", err) } - // check for staleDevices and make new sessions with them - if body["staleDevices"] != nil { - staleDevices := body["staleDevices"].([]any) - log.Debug().Any("stale_devices", staleDevices).Msg("stale devices found in 410 response") - for _, staleDevice := range staleDevices { - recipientAddr, err := recipient.Address(uint(staleDevice.(float64))) + return cli.handle409410(ctx, recipient, body) +} + +func (cli *Client) handleMultiRecipient409410Response(ctx context.Context, response *signalpb.WebSocketResponseMessage) error { + var body []MultiRecipient409410Response + err := json.Unmarshal(response.Body, &body) + if err != nil { + return fmt.Errorf("failed to unmarshal error response body: %w", err) + } + for _, recipientBody := range body { + err = cli.handle409410(ctx, recipientBody.UUID, recipientBody.Devices) + if err != nil { + return err + } + } + return nil +} + +func (cli *Client) handle409410(ctx context.Context, recipient libsignalgo.ServiceID, body SingleRecipient409410Response) error { + log := zerolog.Ctx(ctx) + if body.StaleDevices != nil { + log.Debug().Uints("stale_devices", body.StaleDevices).Msg("stale devices found in 410 response") + for _, staleDevice := range body.StaleDevices { + recipientAddr, err := recipient.Address(staleDevice) if err != nil { - log.Err(err).Msg("error creating new UUID Address") - return err + return fmt.Errorf("failed to get address for stale device %s:%d: %w", recipient, staleDevice, err) } err = cli.Store.ACISessionStore.RemoveSession(ctx, recipientAddr) if err != nil { - log.Err(err).Msg("RemoveSession error") - return err + return fmt.Errorf("failed to remove session for stale device %s:%d: %w", recipient, staleDevice, err) } - err = cli.FetchAndProcessPreKey(ctx, recipient, int(staleDevice.(float64))) + err = cli.FetchAndProcessPreKey(ctx, recipient, int(staleDevice)) if err != nil { - return err + return fmt.Errorf("failed to fetch and process prekey for stale device %s:%d: %w", recipient, staleDevice, err) } } } - return err + if body.MissingDevices != nil { + log.Debug().Uints("missing_devices", body.MissingDevices).Msg("missing devices found in 409 response") + for _, missingDevice := range body.MissingDevices { + err := cli.FetchAndProcessPreKey(ctx, recipient, int(missingDevice)) + if err != nil { + return fmt.Errorf("failed to fetch and process prekey for missing device %s:%d: %w", recipient, missingDevice, err) + } + } + } + if body.ExtraDevices != nil { + log.Debug().Any("extra_devices", body.ExtraDevices).Msg("extra devices found in 409 response") + for _, extraDevice := range body.ExtraDevices { + recipientAddr, err := recipient.Address(extraDevice) + if err != nil { + return fmt.Errorf("failed to get address for extra device %s:%d: %w", recipient, extraDevice, err) + } + err = cli.Store.ACISessionStore.RemoveSession(ctx, recipientAddr) + if err != nil { + return fmt.Errorf("failed to remove session for extra device %s:%d: %w", recipient, extraDevice, err) + } + } + } + return nil } // We got rate limited. @@ -1091,5 +1111,5 @@ func (cli *Client) handle428(ctx context.Context, recipient libsignalgo.ServiceI // } // } //} - return nil + return fmt.Errorf("got 428 error") } diff --git a/pkg/signalmeow/store/device.go b/pkg/signalmeow/store/device.go index 8843ddf..e72c04f 100644 --- a/pkg/signalmeow/store/device.go +++ b/pkg/signalmeow/store/device.go @@ -76,7 +76,7 @@ type Device struct { ACIIdentityStore libsignalgo.IdentityKeyStore PNIIdentityStore libsignalgo.IdentityKeyStore IdentityKeyStore IdentityKeyStore - SenderKeyStore libsignalgo.SenderKeyStore + SenderKeyStore SenderKeyStore GroupStore GroupStore RecipientStore RecipientStore diff --git a/pkg/signalmeow/store/sender_key_store.go b/pkg/signalmeow/store/sender_key_store.go index 092bcdd..a38e389 100644 --- a/pkg/signalmeow/store/sender_key_store.go +++ b/pkg/signalmeow/store/sender_key_store.go @@ -21,18 +21,40 @@ import ( "database/sql" "errors" "fmt" + "time" "github.com/google/uuid" "go.mau.fi/util/dbutil" "go.mau.fi/mautrix-signal/pkg/libsignalgo" + "go.mau.fi/mautrix-signal/pkg/signalmeow/types" ) -var _ libsignalgo.SenderKeyStore = (*sqlStore)(nil) +type SenderKeyStore interface { + libsignalgo.SenderKeyStore + DeleteSenderKey(ctx context.Context, address *libsignalgo.Address, distributionID uuid.UUID) error + GetSenderKeyInfo(ctx context.Context, groupID types.GroupIdentifier) (*SenderKeyInfo, error) + PutSenderKeyInfo(ctx context.Context, groupID types.GroupIdentifier, info *SenderKeyInfo) error +} + +var _ SenderKeyStore = (*sqlStore)(nil) const ( - loadSenderKeyQuery = `SELECT key_record FROM signalmeow_sender_keys WHERE account_id=$1 AND sender_uuid=$2 AND sender_device_id=$3 AND distribution_id=$4` - storeSenderKeyQuery = `INSERT INTO signalmeow_sender_keys (account_id, sender_uuid, sender_device_id, distribution_id, key_record) VALUES ($1, $2, $3, $4, $5) ON CONFLICT (account_id, sender_uuid, sender_device_id, distribution_id) DO UPDATE SET key_record=excluded.key_record` + loadSenderKeyQuery = `SELECT key_record FROM signalmeow_sender_keys WHERE account_id=$1 AND sender_uuid=$2 AND sender_device_id=$3 AND distribution_id=$4` + storeSenderKeyQuery = `INSERT INTO signalmeow_sender_keys (account_id, sender_uuid, sender_device_id, distribution_id, key_record) VALUES ($1, $2, $3, $4, $5) ON CONFLICT (account_id, sender_uuid, sender_device_id, distribution_id) DO UPDATE SET key_record=excluded.key_record` + deleteSenderKeyQuery = `DELETE FROM signalmeow_sender_keys WHERE account_id=$1 AND sender_uuid=$2 AND sender_device_id=$3 AND distribution_id=$4` + + getSenderKeyInfoQuery = ` + SELECT distribution_id, shared_with + FROM signalmeow_outbound_sender_key_info + WHERE account_id=$1 AND group_id=$2 + ` + putSenderKeyInfoQuery = ` + INSERT INTO signalmeow_outbound_sender_key_info (account_id, group_id, distribution_id, shared_with) + VALUES ($1, $2, $3, $4) + ON CONFLICT (account_id, group_id) DO UPDATE + SET distribution_id=excluded.distribution_id, shared_with=excluded.shared_with + ` ) func scanSenderKey(row dbutil.Scannable) (*libsignalgo.SenderKeyRecord, error) { @@ -74,3 +96,42 @@ func (s *sqlStore) StoreSenderKey(ctx context.Context, sender *libsignalgo.Addre _, err = s.db.Exec(ctx, storeSenderKeyQuery, s.AccountID, senderUUID, deviceID, distributionID, serialized) return err } + +func (s *sqlStore) DeleteSenderKey(ctx context.Context, sender *libsignalgo.Address, distributionID uuid.UUID) error { + senderUUID, err := sender.Name() + if err != nil { + return fmt.Errorf("failed to get sender UUID: %w", err) + } + deviceID, err := sender.DeviceID() + if err != nil { + return fmt.Errorf("failed to get sender device ID: %w", err) + } + _, err = s.db.Exec(ctx, deleteSenderKeyQuery, s.AccountID, senderUUID, deviceID, distributionID) + return err +} + +type SenderKeyInfo struct { + DistributionID uuid.UUID `json:"distribution_id"` + SharedWith map[libsignalgo.ServiceID][]int `json:"shared_with"` + CreatedAt time.Time `json:"created_at"` +} + +func scanSenderKeyInfo(row dbutil.Scannable) (*SenderKeyInfo, error) { + var ski SenderKeyInfo + err := row.Scan(&ski.DistributionID, dbutil.JSON{Data: &ski}) + if errors.Is(err, sql.ErrNoRows) { + return nil, nil + } else if err != nil { + return nil, err + } + return &ski, nil +} + +func (s *sqlStore) GetSenderKeyInfo(ctx context.Context, groupID types.GroupIdentifier) (*SenderKeyInfo, error) { + return scanSenderKeyInfo(s.db.QueryRow(ctx, getSenderKeyInfoQuery, s.AccountID, groupID)) +} + +func (s *sqlStore) PutSenderKeyInfo(ctx context.Context, groupID types.GroupIdentifier, info *SenderKeyInfo) error { + _, err := s.db.Exec(ctx, putSenderKeyInfoQuery, s.AccountID, groupID, info.DistributionID, dbutil.JSON{Data: info}) + return err +} diff --git a/pkg/signalmeow/store/session_store.go b/pkg/signalmeow/store/session_store.go index 5fe6cba..3956714 100644 --- a/pkg/signalmeow/store/session_store.go +++ b/pkg/signalmeow/store/session_store.go @@ -30,40 +30,49 @@ import ( var _ SessionStore = (*scopedSQLStore)(nil) const ( - loadSessionQuery = `SELECT their_device_id, record FROM signalmeow_sessions WHERE account_id=$1 AND service_id=$2 AND their_service_id=$3 AND their_device_id=$4` + loadSessionQuery = `SELECT their_service_id, their_device_id, record FROM signalmeow_sessions WHERE account_id=$1 AND service_id=$2 AND their_service_id=$3 AND their_device_id=$4` storeSessionQuery = ` INSERT INTO signalmeow_sessions (account_id, service_id, their_service_id, their_device_id, record) VALUES ($1, $2, $3, $4, $5) ON CONFLICT (account_id, service_id, their_service_id, their_device_id) DO UPDATE SET record=excluded.record ` - allSessionsQuery = `SELECT their_device_id, record FROM signalmeow_sessions WHERE account_id=$1 AND service_id=$2 AND their_service_id=$3` - removeSessionQuery = `DELETE FROM signalmeow_sessions WHERE account_id=$1 AND service_id=$2 AND their_service_id=$3 AND their_device_id=$4` - deleteAllSessionsQuery = "DELETE FROM signalmeow_sessions WHERE account_id=$1" + allSessionsQuery = `SELECT their_service_id, their_device_id, record FROM signalmeow_sessions WHERE account_id=$1 AND service_id=$2 AND their_service_id=$3` + removeSessionQuery = `DELETE FROM signalmeow_sessions WHERE account_id=$1 AND service_id=$2 AND their_service_id=$3 AND their_device_id=$4` + removeSessionsForRecipientQuery = "DELETE FROM signalmeow_sessions WHERE account_id=$1 AND their_service_id=$2" + deleteAllSessionsQuery = "DELETE FROM signalmeow_sessions WHERE account_id=$1" ) +type SessionAddressTuple = libsignalgo.SessionAddressTuple + type SessionStore interface { libsignalgo.SessionStore ServiceScopedStore // AllSessionsForServiceID returns all sessions for the given service ID. - AllSessionsForServiceID(ctx context.Context, theirID libsignalgo.ServiceID) ([]*libsignalgo.Address, []*libsignalgo.SessionRecord, error) + AllSessionsForServiceID(ctx context.Context, theirID libsignalgo.ServiceID) ([]SessionAddressTuple, error) // RemoveSession removes the session for the given address. RemoveSession(ctx context.Context, address *libsignalgo.Address) error + RemoveAllSessionsForServiceID(ctx context.Context, theirID libsignalgo.ServiceID) error // RemoveAllSessions removes all sessions for our ACI UUID RemoveAllSessions(ctx context.Context) error } -func scanSessionRecord(row dbutil.Scannable) (int, *libsignalgo.SessionRecord, error) { - var record []byte - var deviceID int - err := row.Scan(&deviceID, &record) +func scanSessionRecord(row dbutil.Scannable) (tuple SessionAddressTuple, err error) { + var rawServiceID string + var rawRecord []byte + err = row.Scan(&rawServiceID, &tuple.DeviceID, &rawRecord) if errors.Is(err, sql.ErrNoRows) { - return 0, nil, nil + err = nil } else if err != nil { - return 0, nil, err + // return error as-is + } else if tuple.Record, err = libsignalgo.DeserializeSessionRecord(rawRecord); err != nil { + err = fmt.Errorf("failed to deserialize session record: %w", err) + } else if tuple.ServiceID, err = libsignalgo.ServiceIDFromString(rawServiceID); err != nil { + err = fmt.Errorf("failed to parse service ID: %w", err) + } else if tuple.Address, err = tuple.ServiceID.Address(uint(tuple.DeviceID)); err != nil { + err = fmt.Errorf("failed to construct address: %w", err) } - sessionRecord, err := libsignalgo.DeserializeSessionRecord(record) - return deviceID, sessionRecord, err + return } func (s *scopedSQLStore) RemoveSession(ctx context.Context, address *libsignalgo.Address) error { @@ -79,27 +88,17 @@ func (s *scopedSQLStore) RemoveSession(ctx context.Context, address *libsignalgo return err } -func (s *scopedSQLStore) AllSessionsForServiceID(ctx context.Context, theirID libsignalgo.ServiceID) ([]*libsignalgo.Address, []*libsignalgo.SessionRecord, error) { +func (s *scopedSQLStore) AllSessionsForServiceID(ctx context.Context, theirID libsignalgo.ServiceID) ([]SessionAddressTuple, error) { rows, err := s.db.Query(ctx, allSessionsQuery, s.AccountID, s.ServiceID, theirID) if err != nil { - return nil, nil, err + return nil, err } - defer rows.Close() - var records []*libsignalgo.SessionRecord - var addresses []*libsignalgo.Address - for rows.Next() { - deviceID, record, err := scanSessionRecord(rows) - if err != nil { - return nil, nil, err - } - records = append(records, record) - address, err := theirID.Address(uint(deviceID)) - if err != nil { - return nil, nil, err - } - addresses = append(addresses, address) - } - return addresses, records, rows.Err() + return dbutil.NewRowIterWithError(rows, scanSessionRecord, err).AsList() +} + +func (s *scopedSQLStore) RemoveAllSessionsForServiceID(ctx context.Context, theirID libsignalgo.ServiceID) error { + _, err := s.db.Exec(ctx, removeSessionsForRecipientQuery, s.AccountID, theirID) + return err } func (s *scopedSQLStore) LoadSession(ctx context.Context, address *libsignalgo.Address) (*libsignalgo.SessionRecord, error) { @@ -111,8 +110,8 @@ func (s *scopedSQLStore) LoadSession(ctx context.Context, address *libsignalgo.A if err != nil { return nil, fmt.Errorf("failed to get their device ID: %w", err) } - _, record, err := scanSessionRecord(s.db.QueryRow(ctx, loadSessionQuery, s.AccountID, s.ServiceID, theirServiceID, deviceID)) - return record, err + tuple, err := scanSessionRecord(s.db.QueryRow(ctx, loadSessionQuery, s.AccountID, s.ServiceID, theirServiceID, deviceID)) + return tuple.Record, err } func (s *scopedSQLStore) StoreSession(ctx context.Context, address *libsignalgo.Address, record *libsignalgo.SessionRecord) error { diff --git a/pkg/signalmeow/store/upgrades/00-latest.sql b/pkg/signalmeow/store/upgrades/00-latest.sql index ddf871a..7fe18a8 100644 --- a/pkg/signalmeow/store/upgrades/00-latest.sql +++ b/pkg/signalmeow/store/upgrades/00-latest.sql @@ -94,6 +94,15 @@ CREATE TABLE signalmeow_sender_keys ( FOREIGN KEY (account_id) REFERENCES signalmeow_device (aci_uuid) ON DELETE CASCADE ON UPDATE CASCADE ); +CREATE TABLE signalmeow_outbound_sender_key_info ( + account_id TEXT NOT NULL, + group_id TEXT NOT NULL, + distribution_id TEXT NOT NULL, + shared_with jsonb NOT NULL, + + PRIMARY KEY (account_id, group_id) +); + CREATE TABLE signalmeow_groups ( account_id TEXT NOT NULL, group_identifier TEXT NOT NULL, diff --git a/pkg/signalmeow/store/upgrades/24-outbound-sender-keys.sql b/pkg/signalmeow/store/upgrades/24-outbound-sender-keys.sql new file mode 100644 index 0000000..bcc3d34 --- /dev/null +++ b/pkg/signalmeow/store/upgrades/24-outbound-sender-keys.sql @@ -0,0 +1,9 @@ +-- v24 (compatible with v13+): Store outbound sender keys for groups +CREATE TABLE signalmeow_outbound_sender_key_info ( + account_id TEXT NOT NULL, + group_id TEXT NOT NULL, + distribution_id TEXT NOT NULL, + shared_with jsonb NOT NULL, + + PRIMARY KEY (account_id, group_id) +); diff --git a/pkg/signalmeow/web/web.go b/pkg/signalmeow/web/web.go index 84a04b9..f6c6743 100644 --- a/pkg/signalmeow/web/web.go +++ b/pkg/signalmeow/web/web.go @@ -97,10 +97,11 @@ func init() { type ContentType string const ( - ContentTypeJSON ContentType = "application/json" - ContentTypeProtobuf ContentType = "application/x-protobuf" - ContentTypeOctetStream ContentType = "application/octet-stream" - ContentTypeOffsetOctetStream ContentType = "application/offset+octet-stream" + ContentTypeJSON ContentType = "application/json" + ContentTypeProtobuf ContentType = "application/x-protobuf" + ContentTypeOctetStream ContentType = "application/octet-stream" + ContentTypeOffsetOctetStream ContentType = "application/offset+octet-stream" + ContentTypeMultiRecipientMessage ContentType = "application/vnd.signal-messenger.mrm" ) type HTTPReqOpt struct { From e4f9c344cbb9879c7d625c30c87430fc40eff7aa Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Thu, 27 Nov 2025 16:54:12 +0200 Subject: [PATCH 468/580] signalmeow/web: don't truncate paths in logs --- pkg/signalmeow/web/signalwebsocket.go | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/pkg/signalmeow/web/signalwebsocket.go b/pkg/signalmeow/web/signalwebsocket.go index 38dcc4d..f2631fe 100644 --- a/pkg/signalmeow/web/signalwebsocket.go +++ b/pkg/signalmeow/web/signalwebsocket.go @@ -516,10 +516,6 @@ func writeLoop( } request.RequestMessage.Id = &i responseChannels.Set(i, request.ResponseChannel) - path := *request.RequestMessage.Path - if len(path) > 30 { - path = path[:40] - } if !request.RequestTime.IsZero() { elapsed := time.Since(request.RequestTime) if elapsed > 1*time.Minute { @@ -528,14 +524,14 @@ func writeLoop( log.Warn(). Uint64("request_id", i). Str("request_verb", *request.RequestMessage.Verb). - Str("request_path", path). + Str("request_path", *request.RequestMessage.Path). Dur("elapsed", elapsed). Msg("Sending WS request") } else { log.Debug(). Uint64("request_id", i). Str("request_verb", *request.RequestMessage.Verb). - Str("request_path", path). + Str("request_path", *request.RequestMessage.Path). Dur("elapsed", elapsed). Msg("Sending WS request") } From 73e8668bc58db8032db2531c524e8ca05239d2bd Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Thu, 27 Nov 2025 16:54:23 +0200 Subject: [PATCH 469/580] handlematrix: enable typing notifications in groups --- pkg/connector/handlematrix.go | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/pkg/connector/handlematrix.go b/pkg/connector/handlematrix.go index 1dbd48a..968d55c 100644 --- a/pkg/connector/handlematrix.go +++ b/pkg/connector/handlematrix.go @@ -319,18 +319,21 @@ func (s *SignalClient) HandleMatrixReadReceipt(ctx context.Context, receipt *bri } func (s *SignalClient) HandleMatrixTyping(ctx context.Context, typing *bridgev2.MatrixTyping) error { - userID, _, err := signalid.ParsePortalID(typing.Portal.ID) + userID, groupID, err := signalid.ParsePortalID(typing.Portal.ID) if err != nil { return err } - // Only send typing notifications in DMs for now - // Sending efficiently to groups requires implementing the proper SenderKey stuff first + typingMessage := signalmeow.TypingMessage(typing.IsTyping) if !userID.IsEmpty() && userID.Type == libsignalgo.ServiceIDTypeACI { - typingMessage := signalmeow.TypingMessage(typing.IsTyping) result := s.Client.SendMessage(ctx, userID, typingMessage) if !result.WasSuccessful { return result.Error } + } else if groupID != "" { + _, err = s.Client.SendGroupMessage(ctx, groupID, typingMessage) + if err != nil { + return err + } } return nil } From daba2d098cd57171abd66bb1644ca25d6b26c13d Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Thu, 27 Nov 2025 17:15:13 +0200 Subject: [PATCH 470/580] handlematrix: remove duplicate error log --- pkg/connector/handlematrix.go | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/pkg/connector/handlematrix.go b/pkg/connector/handlematrix.go index 968d55c..e2472a2 100644 --- a/pkg/connector/handlematrix.go +++ b/pkg/connector/handlematrix.go @@ -73,17 +73,17 @@ func (s *SignalClient) sendMessage(ctx context.Context, portalID networkid.Porta Int("failed_to_send_to_count", len(result.FailedToSendTo)). Int("successfully_sent_to_count", len(result.SuccessfullySentTo)). Logger() - if len(result.FailedToSendTo) > 0 { - log.Error().Msg("Failed to send event to some members of Signal group") - } if len(result.SuccessfullySentTo) == 0 && len(result.FailedToSendTo) == 0 { log.Debug().Msg("No successes or failures - Probably sent to myself") } else if len(result.SuccessfullySentTo) == 0 { log.Error().Msg("Failed to send event to all members of Signal group") return errors.New("failed to send to any members of Signal group") - } else if len(result.SuccessfullySentTo) < totalRecipients { - log.Warn().Msg("Only sent event to some members of Signal group") + if len(result.FailedToSendTo) > 0 { + log.Warn().Msg("Failed to send event to some members of Signal group") + } else { + log.Warn().Msg("Only sent event to some members of Signal group") + } } else { log.Debug().Msg("Sent event to all members of Signal group") } From 48cc6ac0aa06f3e44d7cc17e970a8918b3a5cda9 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Thu, 27 Nov 2025 17:15:26 +0200 Subject: [PATCH 471/580] signalmeow/web: always log short response bodies --- pkg/signalmeow/web/signalwebsocket.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/signalmeow/web/signalwebsocket.go b/pkg/signalmeow/web/signalwebsocket.go index f2631fe..8a0c845 100644 --- a/pkg/signalmeow/web/signalwebsocket.go +++ b/pkg/signalmeow/web/signalwebsocket.go @@ -459,7 +459,7 @@ func readLoop( Uint64("response_id", msg.Response.GetId()). Uint32("response_status", msg.Response.GetStatus()). Str("response_message", msg.Response.GetMessage()) - if log.GetLevel() == zerolog.TraceLevel { + if log.GetLevel() == zerolog.TraceLevel || len(msg.Response.Body) < 256 { logEvt.Strs("response_headers", msg.Response.Headers) if json.Valid(msg.Response.Body) { logEvt.RawJSON("response_body", msg.Response.Body) From 33e0830088c84f756e13fd4cd7c552662423180b Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Thu, 27 Nov 2025 17:15:38 +0200 Subject: [PATCH 472/580] handlematrix: add support for encrypted room avatars --- pkg/connector/handlematrix.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkg/connector/handlematrix.go b/pkg/connector/handlematrix.go index e2472a2..cdd3c0a 100644 --- a/pkg/connector/handlematrix.go +++ b/pkg/connector/handlematrix.go @@ -380,8 +380,8 @@ func (s *SignalClient) HandleMatrixRoomAvatar(ctx context.Context, msg *bridgev2 } var avatarPath string var avatarHash [32]byte - if msg.Content.URL != "" { - data, err := s.Main.Bridge.Bot.DownloadMedia(ctx, msg.Content.URL, nil) + if msg.Content.URL != "" || msg.Content.MSC3414File != nil { + data, err := s.Main.Bridge.Bot.DownloadMedia(ctx, msg.Content.URL, msg.Content.MSC3414File) if err != nil { return false, fmt.Errorf("failed to download avatar: %w", err) } From 079223eed63b39f10978972ca689b5641813ee33 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Fri, 28 Nov 2025 16:18:45 +0200 Subject: [PATCH 473/580] signalmeow/store: fix latest version number --- pkg/signalmeow/store/upgrades/00-latest.sql | 2 +- pkg/signalmeow/store/upgrades/24-outbound-sender-keys.sql | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pkg/signalmeow/store/upgrades/00-latest.sql b/pkg/signalmeow/store/upgrades/00-latest.sql index 7fe18a8..4d42cde 100644 --- a/pkg/signalmeow/store/upgrades/00-latest.sql +++ b/pkg/signalmeow/store/upgrades/00-latest.sql @@ -1,4 +1,4 @@ --- v0 -> v23 (compatible with v13+): Latest revision +-- v0 -> v24 (compatible with v13+): Latest revision CREATE TABLE signalmeow_device ( aci_uuid TEXT PRIMARY KEY, diff --git a/pkg/signalmeow/store/upgrades/24-outbound-sender-keys.sql b/pkg/signalmeow/store/upgrades/24-outbound-sender-keys.sql index bcc3d34..4f02389 100644 --- a/pkg/signalmeow/store/upgrades/24-outbound-sender-keys.sql +++ b/pkg/signalmeow/store/upgrades/24-outbound-sender-keys.sql @@ -1,5 +1,5 @@ -- v24 (compatible with v13+): Store outbound sender keys for groups -CREATE TABLE signalmeow_outbound_sender_key_info ( +CREATE TABLE IF NOT EXISTS signalmeow_outbound_sender_key_info ( account_id TEXT NOT NULL, group_id TEXT NOT NULL, distribution_id TEXT NOT NULL, From 6abb263407707b7ee0245c3f2aab7c544b96d2bf Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Fri, 28 Nov 2025 16:17:38 +0200 Subject: [PATCH 474/580] signalmeow,libsignalgo: add support for group send endorsements --- pkg/connector/groupinfo.go | 2 +- pkg/libsignalgo/buffer.go | 18 ++ pkg/libsignalgo/conversions.go | 14 ++ pkg/libsignalgo/groupsecretparams.go | 4 + pkg/libsignalgo/groupsendendorsement.go | 215 ++++++++++++++++++++++++ pkg/signalmeow/client.go | 2 +- pkg/signalmeow/groupcache.go | 99 +++++++++-- pkg/signalmeow/groups.go | 43 ++++- pkg/signalmeow/senderkey.go | 48 ++++-- pkg/signalmeow/sending.go | 5 +- 10 files changed, 409 insertions(+), 41 deletions(-) create mode 100644 pkg/libsignalgo/groupsendendorsement.go diff --git a/pkg/connector/groupinfo.go b/pkg/connector/groupinfo.go index a025fa4..d958463 100644 --- a/pkg/connector/groupinfo.go +++ b/pkg/connector/groupinfo.go @@ -98,7 +98,7 @@ func inviteLinkToJoinRule(inviteLinkAccess signalmeow.AccessControl) event.JoinR } func (s *SignalClient) getGroupInfo(ctx context.Context, groupID types.GroupIdentifier, minRevision uint32, backupChat *store.BackupChat) (*bridgev2.ChatInfo, error) { - groupInfo, err := s.Client.RetrieveGroupByID(ctx, groupID, minRevision) + groupInfo, _, err := s.Client.RetrieveGroupByID(ctx, groupID, minRevision) if err != nil { return nil, fmt.Errorf("failed to retrieve group by id: %w", err) } diff --git a/pkg/libsignalgo/buffer.go b/pkg/libsignalgo/buffer.go index e6aafdd..5518656 100644 --- a/pkg/libsignalgo/buffer.go +++ b/pkg/libsignalgo/buffer.go @@ -21,6 +21,8 @@ package libsignalgo */ import "C" import ( + "fmt" + "runtime" "unsafe" ) @@ -42,6 +44,22 @@ func BytesToBuffer(data []byte) C.SignalBorrowedBuffer { return buf } +func ManyBytesToBuffer[T ~[]byte](datas []T) (C.SignalBorrowedSliceOfBuffers, func()) { + buffers := make([]C.SignalBorrowedBuffer, len(datas)) + var pinner runtime.Pinner + for i, data := range datas { + if len(data) == 0 { + panic(fmt.Errorf("empty slice passed to ManyBytesToBuffer at index %d", i)) + } + pinner.Pin(&data[0]) + buffers[i] = BytesToBuffer(data) + } + return C.SignalBorrowedSliceOfBuffers{ + base: unsafe.SliceData(buffers), + length: C.size_t(len(buffers)), + }, pinner.Unpin +} + func EmptyBorrowedBuffer() C.SignalBorrowedBuffer { return C.SignalBorrowedBuffer{} } diff --git a/pkg/libsignalgo/conversions.go b/pkg/libsignalgo/conversions.go index d17fa28..1963687 100644 --- a/pkg/libsignalgo/conversions.go +++ b/pkg/libsignalgo/conversions.go @@ -39,3 +39,17 @@ func CopySignalOwnedBufferToBytes(buffer C.SignalOwnedBuffer) (b []byte) { C.signal_free_buffer(buffer.base, buffer.length) return } + +func CopySignalBytestringArray[T ~[]byte](buffer C.SignalBytestringArray) (b []T) { + concatted := C.GoBytes(unsafe.Pointer(buffer.bytes.base), C.int(buffer.bytes.length)) + b = make([]T, int(buffer.lengths.length)) + sizeTSize := unsafe.Sizeof(C.size_t(0)) + offset := 0 + for i := 0; i < int(buffer.lengths.length); i++ { + length := int(*(*C.size_t)(unsafe.Add(unsafe.Pointer(buffer.lengths.base), uintptr(i)*sizeTSize))) + b[i] = concatted[offset : offset+length] + offset += length + } + C.signal_free_bytestring_array(buffer) + return +} diff --git a/pkg/libsignalgo/groupsecretparams.go b/pkg/libsignalgo/groupsecretparams.go index 5ad11fd..a6b370c 100644 --- a/pkg/libsignalgo/groupsecretparams.go +++ b/pkg/libsignalgo/groupsecretparams.go @@ -76,6 +76,10 @@ func (gmk GroupMasterKey) GroupIdentifier() (*GroupIdentifier, error) { } } +func (gmk GroupMasterKey) SecretParams() (GroupSecretParams, error) { + return DeriveGroupSecretParamsFromMasterKey(gmk) +} + func GenerateGroupSecretParamsWithRandomness(randomness Randomness) (GroupSecretParams, error) { var params [C.SignalGROUP_SECRET_PARAMS_LEN]C.uchar signalFfiError := C.signal_group_secret_params_generate_deterministic(¶ms, (*[C.SignalRANDOMNESS_LEN]C.uint8_t)(unsafe.Pointer(&randomness))) diff --git a/pkg/libsignalgo/groupsendendorsement.go b/pkg/libsignalgo/groupsendendorsement.go new file mode 100644 index 0000000..73f175e --- /dev/null +++ b/pkg/libsignalgo/groupsendendorsement.go @@ -0,0 +1,215 @@ +// mautrix-signal - A Matrix-signal puppeting bridge. +// Copyright (C) 2025 Tulir Asokan +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +package libsignalgo + +/* +#include "./libsignal-ffi.h" +*/ +import "C" +import ( + "encoding/base64" + "runtime" + "time" + "unsafe" +) + +type GroupSendFullToken []byte + +func (gsft GroupSendFullToken) String() string { + return base64.StdEncoding.EncodeToString(gsft) +} + +func (gsft GroupSendFullToken) CheckValidContents() error { + signalFfiError := C.signal_group_send_full_token_check_valid_contents( + BytesToBuffer(gsft), + ) + runtime.KeepAlive(gsft) + if signalFfiError != nil { + return wrapError(signalFfiError) + } + return nil +} + +func (gsft GroupSendFullToken) GetExpiration() (time.Time, error) { + var expiration C.uint64_t + signalFfiError := C.signal_group_send_full_token_get_expiration( + &expiration, + BytesToBuffer(gsft), + ) + runtime.KeepAlive(gsft) + if signalFfiError != nil { + return time.Time{}, wrapError(signalFfiError) + } + return time.Unix(int64(expiration), 0), nil +} + +type GroupSendToken []byte + +func (gst GroupSendToken) CheckValidContents() error { + signalFfiError := C.signal_group_send_token_check_valid_contents( + BytesToBuffer(gst), + ) + runtime.KeepAlive(gst) + if signalFfiError != nil { + return wrapError(signalFfiError) + } + return nil +} + +func (gst GroupSendToken) ToFullToken(expiration time.Time) (GroupSendFullToken, error) { + var fullToken C.SignalOwnedBuffer = C.SignalOwnedBuffer{} + signalFfiError := C.signal_group_send_token_to_full_token( + &fullToken, + BytesToBuffer(gst), + C.uint64_t(expiration.Unix()), + ) + runtime.KeepAlive(gst) + if signalFfiError != nil { + return nil, wrapError(signalFfiError) + } + return CopySignalOwnedBufferToBytes(fullToken), nil +} + +type GroupSendEndorsement []byte + +func (gse GroupSendEndorsement) ToToken(groupSecretParams *GroupSecretParams) (GroupSendToken, error) { + var token C.SignalOwnedBuffer = C.SignalOwnedBuffer{} + signalFfiError := C.signal_group_send_endorsement_to_token( + &token, + BytesToBuffer(gse), + (*[C.SignalGROUP_SECRET_PARAMS_LEN]C.uint8_t)(unsafe.Pointer(groupSecretParams)), + ) + runtime.KeepAlive(gse) + runtime.KeepAlive(groupSecretParams) + if signalFfiError != nil { + return nil, wrapError(signalFfiError) + } + return CopySignalOwnedBufferToBytes(token), nil +} + +func (gse GroupSendEndorsement) ToFullToken(params *GroupSecretParams, expiration time.Time) (GroupSendFullToken, error) { + token, err := gse.ToToken(params) + if err != nil { + return nil, err + } + return token.ToFullToken(expiration) +} + +func (gse GroupSendEndorsement) CheckValidContents() error { + signalFfiError := C.signal_group_send_endorsement_check_valid_contents( + BytesToBuffer(gse), + ) + runtime.KeepAlive(gse) + if signalFfiError != nil { + return wrapError(signalFfiError) + } + return nil +} + +func (gse GroupSendEndorsement) Remove(other GroupSendEndorsement) (GroupSendEndorsement, error) { + var result C.SignalOwnedBuffer = C.SignalOwnedBuffer{} + signalFfiError := C.signal_group_send_endorsement_remove( + &result, + BytesToBuffer(gse), + BytesToBuffer(other), + ) + runtime.KeepAlive(gse) + runtime.KeepAlive(other) + if signalFfiError != nil { + return nil, wrapError(signalFfiError) + } + return CopySignalOwnedBufferToBytes(result), nil +} + +func GroupSendEndorsementCombine(endorsements ...GroupSendEndorsement) (GroupSendEndorsement, error) { + var result C.SignalOwnedBuffer = C.SignalOwnedBuffer{} + cEndorsements, unpin := ManyBytesToBuffer(endorsements) + defer unpin() + signalFfiError := C.signal_group_send_endorsement_combine( + &result, + cEndorsements, + ) + runtime.KeepAlive(endorsements) + if signalFfiError != nil { + return nil, wrapError(signalFfiError) + } + return CopySignalOwnedBufferToBytes(result), nil +} + +type GroupSendEndorsementsResponse []byte + +func (gser GroupSendEndorsementsResponse) GetExpiration() (time.Time, error) { + var expiration C.uint64_t + signalFfiError := C.signal_group_send_endorsements_response_get_expiration( + &expiration, + BytesToBuffer(gser), + ) + runtime.KeepAlive(gser) + if signalFfiError != nil { + return time.Time{}, wrapError(signalFfiError) + } + return time.Unix(int64(expiration), 0), nil +} + +func (gser GroupSendEndorsementsResponse) CheckValidContents() error { + signalFfiError := C.signal_group_send_endorsements_response_check_valid_contents( + BytesToBuffer(gser), + ) + runtime.KeepAlive(gser) + if signalFfiError != nil { + return wrapError(signalFfiError) + } + return nil +} + +func (gser GroupSendEndorsementsResponse) ReceiveWithServiceIDs( + groupMembers []ServiceID, localUser ServiceID, params *GroupSecretParams, spp *ServerPublicParams, +) (GroupSendEndorsement, map[ServiceID]GroupSendEndorsement, error) { + var out C.SignalBytestringArray = C.SignalBytestringArray{} + concatenatedMembers := make([]byte, len(groupMembers)*17) + for i, member := range groupMembers { + copy(concatenatedMembers[i*17:(i+1)*17], member.FixedBytes()[:]) + } + signalFfiError := C.signal_group_send_endorsements_response_receive_and_combine_with_service_ids( + &out, + BytesToBuffer(gser), + BytesToBuffer(concatenatedMembers), + localUser.CFixedBytes(), + C.uint64_t(time.Now().Unix()), + (*[C.SignalGROUP_SECRET_PARAMS_LEN]C.uint8_t)(unsafe.Pointer(params)), + C.SignalConstPointerServerPublicParams{spp}, + ) + runtime.KeepAlive(gser) + runtime.KeepAlive(concatenatedMembers) + runtime.KeepAlive(params) + runtime.KeepAlive(spp) + if signalFfiError != nil { + return nil, nil, wrapError(signalFfiError) + } + endorsements := CopySignalBytestringArray[GroupSendEndorsement](out) + memberEndorsements := make(map[ServiceID]GroupSendEndorsement, len(groupMembers)) + for i, member := range groupMembers { + if len(endorsements) > i && len(endorsements[i]) > 0 { + memberEndorsements[member] = endorsements[i] + } + } + combined, err := GroupSendEndorsementCombine(endorsements...) + if err != nil { + return nil, memberEndorsements, err + } + return combined, memberEndorsements, nil +} diff --git a/pkg/signalmeow/client.go b/pkg/signalmeow/client.go index 2a7f470..52fa12d 100644 --- a/pkg/signalmeow/client.go +++ b/pkg/signalmeow/client.go @@ -72,7 +72,7 @@ func NewClient(device *store.Device, log zerolog.Logger, evtHandler func(events. Store: device, Log: log, EventHandler: evtHandler, - GroupCache: NewGroupCache(), + GroupCache: NewGroupCache(device.ACIServiceID()), ProfileCache: &ProfileCache{ profiles: make(map[string]*types.Profile), errors: make(map[string]*error), diff --git a/pkg/signalmeow/groupcache.go b/pkg/signalmeow/groupcache.go index 557203a..ee8259f 100644 --- a/pkg/signalmeow/groupcache.go +++ b/pkg/signalmeow/groupcache.go @@ -29,14 +29,31 @@ import ( "go.mau.fi/mautrix-signal/pkg/signalmeow/types" ) +type SendEndorsementCache struct { + SendEndorsement libsignalgo.GroupSendEndorsement + MemberEndorsements map[libsignalgo.ServiceID]libsignalgo.GroupSendEndorsement + Expiration time.Time + SecretParams *libsignalgo.GroupSecretParams +} + +func (sec *SendEndorsementCache) GetToken() (libsignalgo.GroupSendFullToken, error) { + return sec.GetTokenWith(sec.SendEndorsement) +} + +func (sec *SendEndorsementCache) GetTokenWith(altToken libsignalgo.GroupSendEndorsement) (libsignalgo.GroupSendFullToken, error) { + return altToken.ToFullToken(sec.SecretParams, sec.Expiration) +} + type cachedGroup struct { *Group - SendEndorsement []byte - FetchedAt time.Time - UpdatedAt time.Time + *SendEndorsementCache + FetchedAt time.Time + UpdatedAt time.Time } type GroupCache struct { + serviceID libsignalgo.ServiceID + credentials *GroupCredentials credentialsLock sync.RWMutex @@ -47,8 +64,9 @@ type GroupCache struct { callsLock sync.RWMutex } -func NewGroupCache() *GroupCache { +func NewGroupCache(serviceID libsignalgo.ServiceID) *GroupCache { return &GroupCache{ + serviceID: serviceID, data: make(map[types.GroupIdentifier]*cachedGroup), activeCalls: make(map[types.GroupIdentifier]string), } @@ -111,14 +129,14 @@ func (gc *GroupCache) UpdateActiveCall(id types.GroupIdentifier, callID string) return true } -func (gc *GroupCache) Get(id types.GroupIdentifier) (*Group, bool) { +func (gc *GroupCache) Get(id types.GroupIdentifier) (*Group, *SendEndorsementCache, bool) { gc.lock.RLock() defer gc.lock.RUnlock() c, ok := gc.data[id] - if !ok { - return nil, false + if !ok || time.Until(c.Expiration) < 5*time.Minute { + return nil, nil, false } - return c.Group, true + return c.Group, c.SendEndorsementCache, true } func (gc *GroupCache) Delete(id types.GroupIdentifier) { @@ -127,26 +145,50 @@ func (gc *GroupCache) Delete(id types.GroupIdentifier) { delete(gc.data, id) } -func (gc *GroupCache) Put(data *Group, endorsementResponse []byte) { +func (gc *GroupCache) Put(data *Group, endorsementResponse libsignalgo.GroupSendEndorsementsResponse) error { + gsp, err := masterKeyToBytes(data.GroupMasterKey).SecretParams() + if err != nil { + return fmt.Errorf("failed to get secret params: %w", err) + } + expiration, err := endorsementResponse.GetExpiration() + if err != nil { + return fmt.Errorf("failed to get endorsement expiration: %w", err) + } + endorsement, memberEndorsements, err := endorsementResponse.ReceiveWithServiceIDs(data.getMemberServiceIDs(), gc.serviceID, &gsp, prodServerPublicParams) + if err != nil { + return fmt.Errorf("failed to receive endorsements: %w", err) + } + gc.lock.Lock() defer gc.lock.Unlock() cached, exists := gc.data[data.GroupIdentifier] if exists && cached.Revision > data.Revision { - return + return nil } gc.data[data.GroupIdentifier] = &cachedGroup{ Group: data, FetchedAt: time.Now(), UpdatedAt: time.Now(), - //SendEndorsement: endorsementResponse, + SendEndorsementCache: &SendEndorsementCache{ + Expiration: expiration, + SendEndorsement: endorsement, + MemberEndorsements: memberEndorsements, + SecretParams: &gsp, + }, } + return nil } -func (gc *GroupCache) ApplyUpdate(change *GroupChange, endorsementResponse []byte) { - rawGroupID, err := masterKeyToBytes(change.GroupMasterKey).GroupIdentifier() +func (gc *GroupCache) ApplyUpdate(change *GroupChange, endorsementResponse libsignalgo.GroupSendEndorsementsResponse) error { + mkBytes := masterKeyToBytes(change.GroupMasterKey) + rawGroupID, err := mkBytes.GroupIdentifier() if err != nil { - return + return fmt.Errorf("failed to get group identifier: %w", err) + } + gsp, err := mkBytes.SecretParams() + if err != nil { + return fmt.Errorf("failed to get secret params: %w", err) } id := types.GroupIdentifier(rawGroupID.String()) @@ -155,11 +197,11 @@ func (gc *GroupCache) ApplyUpdate(change *GroupChange, endorsementResponse []byt cached, exists := gc.data[id] if !exists || cached.Revision >= change.Revision { - return + return nil } else if cached.Revision < change.Revision-1 { // We missed an update, evict delete(gc.data, id) - return + return nil } // Pending member adds, promotes and removes @@ -275,7 +317,30 @@ func (gc *GroupCache) ApplyUpdate(change *GroupChange, endorsementResponse []byt cached.AccessControl.AddFromInviteLink = *change.ModifyAddFromInviteLinkAccess } - // TODO handle endorsement responses cached.UpdatedAt = time.Now() cached.Revision = change.Revision + endorsement, memberEndorsements, err := endorsementResponse.ReceiveWithServiceIDs( + cached.getMemberServiceIDs(), + gc.serviceID, + &gsp, + prodServerPublicParams, + ) + if err != nil { + delete(gc.data, id) + return fmt.Errorf("failed to receive endorsements: %w", err) + } + expiration, err := endorsementResponse.GetExpiration() + if err != nil { + delete(gc.data, id) + return fmt.Errorf("failed to get endorsement expiration: %w", err) + } + // TODO do these responses overwrite the entire thing? + cached.SendEndorsementCache = &SendEndorsementCache{ + SendEndorsement: endorsement, + MemberEndorsements: memberEndorsements, + Expiration: expiration, + SecretParams: &gsp, + } + + return nil } diff --git a/pkg/signalmeow/groups.go b/pkg/signalmeow/groups.go index f25f835..d8ba4b3 100644 --- a/pkg/signalmeow/groups.go +++ b/pkg/signalmeow/groups.go @@ -31,6 +31,7 @@ import ( "github.com/google/uuid" "github.com/rs/zerolog" + "go.mau.fi/util/exslices" "go.mau.fi/util/ptr" "go.mau.fi/util/random" "google.golang.org/protobuf/proto" @@ -90,6 +91,12 @@ type Group struct { //PublicKey *libsignalgo.PublicKey } +func (group *Group) getMemberServiceIDs() []libsignalgo.ServiceID { + return exslices.CastFunc(group.Members, func(from *GroupMember) libsignalgo.ServiceID { + return libsignalgo.NewACIServiceID(from.ACI) + }) +} + func (group *Group) GetInviteLink() (string, error) { if group.InviteLinkPassword == nil { return "", fmt.Errorf("no invite link password set") @@ -654,7 +661,10 @@ func (cli *Client) parseGroupResponse(ctx context.Context, response *http.Respon if err != nil { return nil, fmt.Errorf("failed to decrypt group: %w", err) } - cli.GroupCache.Put(group, groupResponse.GroupSendEndorsementsResponse) + err = cli.GroupCache.Put(group, groupResponse.GroupSendEndorsementsResponse) + if err != nil { + zerolog.Ctx(ctx).Err(err).Msg("Failed to cache group response") + } // Store the profile keys in case they're new for _, member := range group.Members { @@ -697,12 +707,21 @@ func (cli *Client) DownloadGroupAvatar(ctx context.Context, avatarPath string, g return decrypted, nil } -func (cli *Client) RetrieveGroupByID(ctx context.Context, gid types.GroupIdentifier, revision uint32) (*Group, error) { - cached, ok := cli.GroupCache.Get(gid) +func (cli *Client) RetrieveGroupByID(ctx context.Context, gid types.GroupIdentifier, revision uint32) (*Group, *SendEndorsementCache, error) { + cached, endorsement, ok := cli.GroupCache.Get(gid) if ok && cached.Revision >= revision { - return cached, nil + return cached, endorsement, nil } - return cli.fetchGroupByID(ctx, gid) + group, err := cli.fetchGroupByID(ctx, gid) + if err != nil { + return nil, nil, err + } + cached, endorsement, ok = cli.GroupCache.Get(gid) + if !ok { + zerolog.Ctx(ctx).Warn().Msg("Group not found in cache after fetching") + return group, nil, nil + } + return cached, endorsement, nil } // We should store the group master key in the group store as soon as we see it, @@ -1049,7 +1068,10 @@ func (cli *Client) decryptGroupChange(ctx context.Context, encryptedGroupChange } success = true - cli.GroupCache.ApplyUpdate(decryptedGroupChange, nil) + err = cli.GroupCache.ApplyUpdate(decryptedGroupChange, nil) + if err != nil { + log.Err(err).Msg("Failed to apply group change to cache") + } return decryptedGroupChange, nil } @@ -1499,7 +1521,7 @@ func (cli *Client) UpdateGroup(ctx context.Context, groupChange *GroupChange, gi masterKeyBytes := masterKeyToBytes(groupMasterKey) var refetchedAddMemberCredentials bool var signedGroupChange *signalpb.GroupChangeResponse - group, err := cli.RetrieveGroupByID(ctx, gid, 0) + group, _, err := cli.RetrieveGroupByID(ctx, gid, 0) if err != nil { return 0, fmt.Errorf("failed to fetch group info to update: %w", err) } @@ -1523,7 +1545,7 @@ func (cli *Client) UpdateGroup(ctx context.Context, groupChange *GroupChange, gi } } else if errors.Is(err, ConflictError) { cli.GroupCache.Delete(gid) - group, err = cli.RetrieveGroupByID(ctx, gid, 0) + group, _, err = cli.RetrieveGroupByID(ctx, gid, 0) if err != nil { return 0, fmt.Errorf("failed to fetch group after conflict: %w", err) } @@ -1539,7 +1561,10 @@ func (cli *Client) UpdateGroup(ctx context.Context, groupChange *GroupChange, gi if signedGroupChange == nil { return 0, fmt.Errorf("no signed group change returned: %w", err) } - cli.GroupCache.ApplyUpdate(groupChange, signedGroupChange.GroupSendEndorsementsResponse) + err = cli.GroupCache.ApplyUpdate(groupChange, signedGroupChange.GroupSendEndorsementsResponse) + if err != nil { + log.Err(err).Msg("Failed to apply group change to cache") + } groupChangeBytes, err := proto.Marshal(signedGroupChange.GroupChange) if err != nil { return 0, fmt.Errorf("failed to marshal signed group change: %w", err) diff --git a/pkg/signalmeow/senderkey.go b/pkg/signalmeow/senderkey.go index 133ef80..9dbe96f 100644 --- a/pkg/signalmeow/senderkey.go +++ b/pkg/signalmeow/senderkey.go @@ -50,6 +50,7 @@ func (cli *Client) sendToGroupWithSenderKey( ctx context.Context, groupID types.GroupIdentifier, allRecipients []libsignalgo.ServiceID, + sec SendEndorsementCache, content *signalpb.Content, messageTimestamp uint64, retries int, @@ -78,7 +79,7 @@ func (cli *Client) sendToGroupWithSenderKey( FailedToSendTo: make([]FailedSendResult, 0), } - deviceIDs, senderKeyRecipients, fallbackRecipients := cli.getDevicesIDs(ctx, allRecipients, result) + deviceIDs, senderKeyRecipients, fallbackRecipients := cli.getDevicesIDs(ctx, allRecipients, sec, result) ski, err := cli.Store.SenderKeyStore.GetSenderKeyInfo(ctx, groupID) if err != nil { return nil, fmt.Errorf("failed to get sender key info: %w", err) @@ -148,7 +149,7 @@ func (cli *Client) sendToGroupWithSenderKey( } if needsRetry { doUnlock() - return cli.sendToGroupWithSenderKey(ctx, groupID, allRecipients, content, messageTimestamp, retries+1) + return cli.sendToGroupWithSenderKey(ctx, groupID, allRecipients, sec, content, messageTimestamp, retries+1) } } ssCiphertext, err := cli.encryptWithSenderKey(ctx, groupID, ski.DistributionID, myAddress, senderKeyRecipients, content) @@ -157,11 +158,27 @@ func (cli *Client) sendToGroupWithSenderKey( } header := http.Header{} header.Set("Content-Type", string(web.ContentTypeMultiRecipientMessage)) - //if groupSendToken != nil { - // header.Set("Group-Send-Token", groupSendToken.String()) - //} else { - header.Set("Unidentified-Access-Key", xak.String()) - //} + if sec.SendEndorsement != nil { + wantedEndorsements := make([]libsignalgo.GroupSendEndorsement, 0, len(deviceIDs)) + for serviceID := range deviceIDs { + endorsement, ok := sec.MemberEndorsements[serviceID] + if !ok { + return nil, fmt.Errorf("missing group send endorsement for service ID %s", serviceID.String()) + } + wantedEndorsements = append(wantedEndorsements, endorsement) + } + combinedEndorsement, err := libsignalgo.GroupSendEndorsementCombine(wantedEndorsements...) + if err != nil { + return nil, fmt.Errorf("failed to combine group send endorsements: %w", err) + } + groupSendToken, err := sec.GetTokenWith(combinedEndorsement) + if err != nil { + return nil, fmt.Errorf("failed to create group send full token: %w", err) + } + header.Set("Group-Send-Token", groupSendToken.String()) + } else { + header.Set("Unidentified-Access-Key", xak.String()) + } path := fmt.Sprintf( "/v1/messages/multi_recipient?ts=%d&urgent=%t&online=false", messageTimestamp, isUrgent(content), @@ -218,7 +235,7 @@ func (cli *Client) sendToGroupWithSenderKey( } doUnlock() // Retry recursively after fixing device lists - return cli.sendToGroupWithSenderKey(ctx, groupID, allRecipients, content, messageTimestamp, retries+1) + return cli.sendToGroupWithSenderKey(ctx, groupID, allRecipients, sec, content, messageTimestamp, retries+1) default: return nil, fmt.Errorf("unexpected status code %d in multi-recipient send", resp.GetStatus()) } @@ -305,8 +322,15 @@ type senderKeySendMeta struct { AccessKey *libsignalgo.AccessKey } -func (cli *Client) getDevicesIDs(ctx context.Context, recipients []libsignalgo.ServiceID, result *GroupMessageSendResult) ( - map[libsignalgo.ServiceID]senderKeySendMeta, []store.SessionAddressTuple, []libsignalgo.ServiceID, +func (cli *Client) getDevicesIDs( + ctx context.Context, + recipients []libsignalgo.ServiceID, + sendEndorsement SendEndorsementCache, + result *GroupMessageSendResult, +) ( + map[libsignalgo.ServiceID]senderKeySendMeta, + []store.SessionAddressTuple, + []libsignalgo.ServiceID, ) { log := zerolog.Ctx(ctx) out := make(map[libsignalgo.ServiceID]senderKeySendMeta) @@ -321,6 +345,10 @@ func (cli *Client) getDevicesIDs(ctx context.Context, recipients []libsignalgo.S if recipient.Type != libsignalgo.ServiceIDTypeACI { continue } + _, hasEndorsement := sendEndorsement.MemberEndorsements[recipient] + if !hasEndorsement { + continue + } profileKey, err := cli.Store.RecipientStore.LoadProfileKey(ctx, recipient.UUID) if err != nil { log.Err(err).Stringer("recipient_id", recipient.UUID).Msg("Failed to get profile key") diff --git a/pkg/signalmeow/sending.go b/pkg/signalmeow/sending.go index d9fd831..e37fdf0 100644 --- a/pkg/signalmeow/sending.go +++ b/pkg/signalmeow/sending.go @@ -543,11 +543,10 @@ func (cli *Client) SendGroupMessage(ctx context.Context, gid types.GroupIdentifi Stringer("group_id", gid). Logger() ctx = log.WithContext(ctx) - group, err := cli.RetrieveGroupByID(ctx, gid, 0) + group, endorsement, err := cli.RetrieveGroupByID(ctx, gid, 0) if err != nil { return nil, err } - var messageTimestamp uint64 if content.GetDataMessage() != nil { messageTimestamp = content.DataMessage.GetTimestamp() @@ -568,7 +567,7 @@ func (cli *Client) SendGroupMessage(ctx context.Context, gid types.GroupIdentifi recipients = append(recipients, member.UserServiceID()) } if enableSenderKeySend { - return cli.sendToGroupWithSenderKey(ctx, gid, recipients, content, messageTimestamp, 0) + return cli.sendToGroupWithSenderKey(ctx, gid, recipients, ptr.Val(endorsement), content, messageTimestamp, 0) } return cli.sendToGroup(ctx, recipients, content, messageTimestamp, nil) } From 207fc6a996d117df87dce6cad3f2c314fcf05743 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Fri, 28 Nov 2025 16:51:51 +0200 Subject: [PATCH 475/580] signalmeow: add cache for unregistered ACIs --- pkg/signalmeow/keys.go | 8 +++-- pkg/signalmeow/receiving.go | 1 + pkg/signalmeow/senderkey.go | 2 +- pkg/signalmeow/sending.go | 5 ++- pkg/signalmeow/store/recipient_store.go | 35 +++++++++++++++++++ pkg/signalmeow/store/upgrades/00-latest.sql | 6 +++- .../upgrades/25-unregistered-user-cache.sql | 4 +++ 7 files changed, 54 insertions(+), 7 deletions(-) create mode 100644 pkg/signalmeow/store/upgrades/25-unregistered-user-cache.sql diff --git a/pkg/signalmeow/keys.go b/pkg/signalmeow/keys.go index 724565a..f1801e5 100644 --- a/pkg/signalmeow/keys.go +++ b/pkg/signalmeow/keys.go @@ -405,11 +405,14 @@ func addBase64PaddingAndDecode(data string) ([]byte, error) { } var ( - ErrUnregisteredUser = errors.New("got 404 when fetching prekey, user is unregistered") + ErrUnregisteredUser = errors.New("user is unregistered") ErrDevicesChanged = errors.New("device list changed while sending skdm") ) func (cli *Client) FetchAndProcessPreKey(ctx context.Context, theirServiceID libsignalgo.ServiceID, specificDeviceID int) error { + if cli.Store.RecipientStore.IsUnregistered(ctx, theirServiceID) { + return fmt.Errorf("%w (cached)", ErrUnregisteredUser) + } // Fetch prekey deviceIDPath := "/*" if specificDeviceID >= 0 { @@ -421,7 +424,8 @@ func (cli *Client) FetchAndProcessPreKey(ctx context.Context, theirServiceID lib if err != nil { return fmt.Errorf("error sending request: %w", err) } else if resp.GetStatus() == 404 { - return ErrUnregisteredUser + cli.Store.RecipientStore.MarkUnregistered(ctx, theirServiceID, true) + return fmt.Errorf("%w (404 while querying keys)", ErrUnregisteredUser) } var respData prekeyResponse err = web.DecodeWSResponseBody(ctx, &respData, resp) diff --git a/pkg/signalmeow/receiving.go b/pkg/signalmeow/receiving.go index 0feee6b..a699fbc 100644 --- a/pkg/signalmeow/receiving.go +++ b/pkg/signalmeow/receiving.go @@ -443,6 +443,7 @@ func (cli *Client) handleDecryptedResult( Msg("Dropping message from non-ACI sender") return nil } + cli.Store.RecipientStore.MarkUnregistered(ctx, theirServiceID, false) handlerSuccess := true // result.Err is set if there was an error during decryption and we diff --git a/pkg/signalmeow/senderkey.go b/pkg/signalmeow/senderkey.go index 9dbe96f..4f54c81 100644 --- a/pkg/signalmeow/senderkey.go +++ b/pkg/signalmeow/senderkey.go @@ -200,12 +200,12 @@ func (cli *Client) sendToGroupWithSenderKey( Msg("Got successful multi-recipient send response") for serviceID := range deviceIDs { if slices.Contains(respData.UUIDs404, serviceID) { - // TODO flag recipient as unregistered err = cli.Store.ACISessionStore.RemoveAllSessionsForServiceID(ctx, serviceID) if err != nil { log.Err(err).Stringer("recipient_id", serviceID). Msg("Failed to remove sessions after 404") } + cli.Store.RecipientStore.MarkUnregistered(ctx, serviceID, true) result.FailedToSendTo = append(result.FailedToSendTo, FailedSendResult{ Recipient: serviceID, Error: fmt.Errorf("multi-recipient send 404"), diff --git a/pkg/signalmeow/sending.go b/pkg/signalmeow/sending.go index e37fdf0..47695d9 100644 --- a/pkg/signalmeow/sending.go +++ b/pkg/signalmeow/sending.go @@ -159,7 +159,6 @@ func (cli *Client) buildMessagesToSend( // No sessions, make one with prekey err = cli.FetchAndProcessPreKey(ctx, recipient, -1) if err != nil { - // TODO flag 404s as unregistered return nil, err } sessions, err = cli.Store.ACISessionStore.AllSessionsForServiceID(ctx, recipient) @@ -952,12 +951,12 @@ func (cli *Client) sendContent( return sentUnidentified, err } } else if *response.Status == 404 { - // TODO flag recipient as unregistered err = cli.Store.ACISessionStore.RemoveAllSessionsForServiceID(ctx, recipient) if err != nil { log.Err(err).Msg("Failed to remove sessions after 404") } - return sentUnidentified, ErrUnregisteredUser + cli.Store.RecipientStore.MarkUnregistered(ctx, recipient, true) + return sentUnidentified, fmt.Errorf("%w (send returned 404)", ErrUnregisteredUser) } else if *response.Status != 200 { return sentUnidentified, fmt.Errorf("unexpected status code while sending: %d", *response.Status) } diff --git a/pkg/signalmeow/store/recipient_store.go b/pkg/signalmeow/store/recipient_store.go index 00646df..98c7315 100644 --- a/pkg/signalmeow/store/recipient_store.go +++ b/pkg/signalmeow/store/recipient_store.go @@ -43,6 +43,9 @@ type RecipientStore interface { StoreRecipient(ctx context.Context, recipient *types.Recipient) error UpdateRecipientE164(ctx context.Context, aci, pni uuid.UUID, e164 string) (*types.Recipient, error) + IsUnregistered(ctx context.Context, serviceID libsignalgo.ServiceID) bool + MarkUnregistered(ctx context.Context, serviceID libsignalgo.ServiceID, unregistered bool) + LoadAllContacts(ctx context.Context) ([]*types.Recipient, error) } @@ -387,3 +390,35 @@ func (s *sqlStore) StoreRecipient(ctx context.Context, recipient *types.Recipien } return } + +const ( + isUnregisteredQuery = `SELECT 1 FROM signalmeow_unregistered_users WHERE aci_uuid=$1` + markUnregisteredQuery = `INSERT INTO signalmeow_unregistered_users (aci_uuid) VALUES ($1) ON CONFLICT (aci_uuid) DO NOTHING` + markRegisteredQuery = `DELETE FROM signalmeow_unregistered_users WHERE aci_uuid=$1` +) + +func (s *sqlStore) IsUnregistered(ctx context.Context, serviceID libsignalgo.ServiceID) (unregistered bool) { + if serviceID.Type != libsignalgo.ServiceIDTypeACI { + return + } + _ = s.db.QueryRow(ctx, isUnregisteredQuery, serviceID.UUID).Scan(&unregistered) + return +} + +func (s *sqlStore) MarkUnregistered(ctx context.Context, serviceID libsignalgo.ServiceID, unregistered bool) { + if serviceID.Type != libsignalgo.ServiceIDTypeACI { + return + } + var err error + if unregistered { + _, err = s.db.Exec(ctx, markUnregisteredQuery, serviceID.UUID) + } else { + _, err = s.db.Exec(ctx, markRegisteredQuery, serviceID.UUID) + } + if err != nil { + zerolog.Ctx(ctx).Err(err). + Stringer("service_id", serviceID). + Bool("unregistered", unregistered). + Msg("Failed to mark recipient as unregistered") + } +} diff --git a/pkg/signalmeow/store/upgrades/00-latest.sql b/pkg/signalmeow/store/upgrades/00-latest.sql index 4d42cde..dee3509 100644 --- a/pkg/signalmeow/store/upgrades/00-latest.sql +++ b/pkg/signalmeow/store/upgrades/00-latest.sql @@ -1,4 +1,4 @@ --- v0 -> v24 (compatible with v13+): Latest revision +-- v0 -> v25 (compatible with v13+): Latest revision CREATE TABLE signalmeow_device ( aci_uuid TEXT PRIMARY KEY, @@ -134,6 +134,10 @@ CREATE TABLE signalmeow_recipients ( CONSTRAINT signalmeow_contacts_pni_unique UNIQUE (account_id, pni_uuid) ); +CREATE TABLE signalmeow_unregistered_users ( + aci_uuid uuid PRIMARY KEY +); + CREATE TABLE signalmeow_backup_recipient ( account_id TEXT NOT NULL, recipient_id BIGINT NOT NULL, diff --git a/pkg/signalmeow/store/upgrades/25-unregistered-user-cache.sql b/pkg/signalmeow/store/upgrades/25-unregistered-user-cache.sql new file mode 100644 index 0000000..04a5233 --- /dev/null +++ b/pkg/signalmeow/store/upgrades/25-unregistered-user-cache.sql @@ -0,0 +1,4 @@ +-- v25 (compatible with v13+): Cache unregistered users +CREATE TABLE signalmeow_unregistered_users ( + aci_uuid uuid PRIMARY KEY +); From 30e80bb18bb210c58736e4d34692867a3e44be08 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Fri, 28 Nov 2025 16:59:12 +0200 Subject: [PATCH 476/580] signalmeow/sending: enable sender key sending --- pkg/signalmeow/sending.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/signalmeow/sending.go b/pkg/signalmeow/sending.go index 47695d9..97fdcdf 100644 --- a/pkg/signalmeow/sending.go +++ b/pkg/signalmeow/sending.go @@ -534,7 +534,7 @@ func (cli *Client) SendGroupUpdate(ctx context.Context, group *Group, groupConte return cli.sendToGroup(ctx, recipients, content, timestamp, nil) } -const enableSenderKeySend = false +const enableSenderKeySend = true func (cli *Client) SendGroupMessage(ctx context.Context, gid types.GroupIdentifier, content *signalpb.Content) (*GroupMessageSendResult, error) { log := zerolog.Ctx(ctx).With(). From d8ccce0e477258759c5395a2112797f2c4de5393 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Fri, 28 Nov 2025 22:02:16 +0200 Subject: [PATCH 477/580] build: replace build-go with go tool and remove debug mode --- Dockerfile | 16 ++-------------- build-go.sh | 9 +-------- build-rust.sh | 9 +-------- go.mod | 13 ++++++++----- go.sum | 22 ++++++++++++---------- 5 files changed, 24 insertions(+), 45 deletions(-) diff --git a/Dockerfile b/Dockerfile index 9c5e495..162ac86 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,5 +1,5 @@ # -- Build libsignal (with Rust) -- -FROM rust:1-alpine as rust-builder +FROM rust:1-alpine AS rust-builder RUN apk add --no-cache git make cmake protoc musl-dev g++ clang-dev WORKDIR /build @@ -7,12 +7,11 @@ WORKDIR /build COPY pkg/libsignalgo/libsignal/. pkg/libsignalgo/libsignal/. COPY build-rust.sh . -ARG DBG=0 RUN ./build-rust.sh # -- Build mautrix-signal (with Go) -- FROM golang:1-alpine3.22 AS go-builder -RUN apk add --no-cache git ca-certificates build-base olm-dev +RUN apk add --no-cache git ca-certificates build-base olm-dev zlib-dev WORKDIR /build # Copy all files needed for Go build, and no Rust files @@ -26,15 +25,9 @@ COPY pkg/connector/. pkg/connector/. COPY cmd/. cmd/. COPY .git .git -ARG DBG=0 ENV LIBRARY_PATH=. COPY --from=rust-builder /build/pkg/libsignalgo/libsignal/target/*/libsignal_ffi.a ./ RUN < Date: Tue, 2 Dec 2025 15:26:16 +0200 Subject: [PATCH 478/580] dependencies: update mautrix-go --- go.mod | 2 +- go.sum | 4 ++-- pkg/connector/handlematrix.go | 35 +++++++++++++++++------------------ 3 files changed, 20 insertions(+), 21 deletions(-) diff --git a/go.mod b/go.mod index 29e277e..35a4fb2 100644 --- a/go.mod +++ b/go.mod @@ -20,7 +20,7 @@ require ( golang.org/x/net v0.47.0 google.golang.org/protobuf v1.36.10 gopkg.in/yaml.v3 v3.0.1 - maunium.net/go/mautrix v0.26.1-0.20251128114054-1d1ecb228668 + maunium.net/go/mautrix v0.26.1-0.20251202132204-2eeece694254 ) require ( diff --git a/go.sum b/go.sum index 64f1f5c..cc4b594 100644 --- a/go.sum +++ b/go.sum @@ -97,5 +97,5 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= maunium.net/go/mauflag v1.0.0 h1:YiaRc0tEI3toYtJMRIfjP+jklH45uDHtT80nUamyD4M= maunium.net/go/mauflag v1.0.0/go.mod h1:nLivPOpTpHnpzEh8jEdSL9UqO9+/KBJFmNRlwKfkPeA= -maunium.net/go/mautrix v0.26.1-0.20251128114054-1d1ecb228668 h1:Y6B67gtYwMpePlI9Spz1EKVsLiAvKJ+rxRBZRWbGjmI= -maunium.net/go/mautrix v0.26.1-0.20251128114054-1d1ecb228668/go.mod h1:NaesYcOQWFDbixVYywCVS+Twlzab9hOUpFNlCBlvciE= +maunium.net/go/mautrix v0.26.1-0.20251202132204-2eeece694254 h1:rsc4H0sZVban6xQeIS6err1YangUiK5WzVfTS6s03ms= +maunium.net/go/mautrix v0.26.1-0.20251202132204-2eeece694254/go.mod h1:NaesYcOQWFDbixVYywCVS+Twlzab9hOUpFNlCBlvciE= diff --git a/pkg/connector/handlematrix.go b/pkg/connector/handlematrix.go index cdd3c0a..25d3f53 100644 --- a/pkg/connector/handlematrix.go +++ b/pkg/connector/handlematrix.go @@ -405,22 +405,21 @@ func (s *SignalClient) HandleMatrixRoomTopic(ctx context.Context, msg *bridgev2. }, nil) } -func (s *SignalClient) HandleMatrixMembership(ctx context.Context, msg *bridgev2.MatrixMembershipChange) (bool, error) { +func (s *SignalClient) HandleMatrixMembership(ctx context.Context, msg *bridgev2.MatrixMembershipChange) (*bridgev2.MatrixMembershipResult, error) { var targetIntent bridgev2.MatrixAPI var targetSignalID libsignalgo.ServiceID var err error if msg.Portal.RoomType == database.RoomTypeDM { - //TODO: this probably needs to revert some changes and clean up the portal on leaves switch msg.Type { case bridgev2.Invite: - return false, fmt.Errorf("cannot invite additional user to dm") + return nil, fmt.Errorf("cannot invite additional user to dm") default: - return false, nil + return nil, nil } } targetSignalID, err = signalid.ParseGhostOrUserLoginID(msg.Target) if err != nil { - return false, fmt.Errorf("failed to parse target signal id: %w", err) + return nil, fmt.Errorf("failed to parse target signal id: %w", err) } switch target := msg.Target.(type) { case *bridgev2.Ghost: @@ -430,12 +429,12 @@ func (s *SignalClient) HandleMatrixMembership(ctx context.Context, msg *bridgev2 if targetIntent == nil { ghost, err := s.Main.Bridge.GetGhostByID(ctx, networkid.UserID(target.ID)) if err != nil { - return false, fmt.Errorf("failed to get ghost for user: %w", err) + return nil, fmt.Errorf("failed to get ghost for user: %w", err) } targetIntent = ghost.Intent } default: - return false, fmt.Errorf("cannot get target intent: unknown type: %T", target) + return nil, fmt.Errorf("cannot get target intent: unknown type: %T", target) } log := zerolog.Ctx(ctx).With(). Str("From Membership", string(msg.Type.From)). @@ -455,7 +454,7 @@ func (s *SignalClient) HandleMatrixMembership(ctx context.Context, msg *bridgev2 switch msg.Type { case bridgev2.AcceptInvite: if targetSignalID.Type != libsignalgo.ServiceIDTypeACI { - return false, fmt.Errorf("can't accept invite for non-ACI service ID") + return nil, fmt.Errorf("can't accept invite for non-ACI service ID") } gc.PromotePendingMembers = []*signalmeow.PromotePendingMember{{ ACI: targetSignalID.UUID, @@ -464,7 +463,7 @@ func (s *SignalClient) HandleMatrixMembership(ctx context.Context, msg *bridgev2 gc.DeletePendingMembers = []*libsignalgo.ServiceID{&targetSignalID} case bridgev2.Leave, bridgev2.Kick: if targetSignalID.Type != libsignalgo.ServiceIDTypeACI { - return false, fmt.Errorf("can't kick non-ACI service ID") + return nil, fmt.Errorf("can't kick non-ACI service ID") } gc.DeleteMembers = []*uuid.UUID{&targetSignalID.UUID} case bridgev2.Invite: @@ -500,7 +499,7 @@ func (s *SignalClient) HandleMatrixMembership(ctx context.Context, msg *bridgev2 // }} case bridgev2.AcceptKnock: if targetSignalID.Type != libsignalgo.ServiceIDTypeACI { - return false, fmt.Errorf("can't accept knock from non-ACI service ID") + return nil, fmt.Errorf("can't accept knock from non-ACI service ID") } gc.PromoteRequestingMembers = []*signalmeow.RoleMember{{ ACI: targetSignalID.UUID, @@ -508,7 +507,7 @@ func (s *SignalClient) HandleMatrixMembership(ctx context.Context, msg *bridgev2 }} case bridgev2.RetractKnock, bridgev2.RejectKnock: if targetSignalID.Type != libsignalgo.ServiceIDTypeACI { - return false, fmt.Errorf("can't reject knock from non-ACI service ID") + return nil, fmt.Errorf("can't reject knock from non-ACI service ID") } gc.DeleteRequestingMembers = []*uuid.UUID{&targetSignalID.UUID} case bridgev2.BanKnocked, bridgev2.BanInvited, bridgev2.BanJoined, bridgev2.BanLeft: @@ -519,39 +518,39 @@ func (s *SignalClient) HandleMatrixMembership(ctx context.Context, msg *bridgev2 switch msg.Type { case bridgev2.BanJoined: if targetSignalID.Type != libsignalgo.ServiceIDTypeACI { - return false, fmt.Errorf("can't ban joined non-ACI service ID") + return nil, fmt.Errorf("can't ban joined non-ACI service ID") } gc.DeleteMembers = []*uuid.UUID{&targetSignalID.UUID} case bridgev2.BanInvited: gc.DeletePendingMembers = []*libsignalgo.ServiceID{&targetSignalID} case bridgev2.BanKnocked: if targetSignalID.Type != libsignalgo.ServiceIDTypeACI { - return false, fmt.Errorf("can't ban knocked non-ACI service ID") + return nil, fmt.Errorf("can't ban knocked non-ACI service ID") } gc.DeleteRequestingMembers = []*uuid.UUID{&targetSignalID.UUID} } case bridgev2.Unban: gc.DeleteBannedMembers = []*libsignalgo.ServiceID{&targetSignalID} default: - return false, fmt.Errorf("unsupported membership change: %s -> %s", msg.Type.From, msg.Type.To) + return nil, fmt.Errorf("unsupported membership change: %s -> %s", msg.Type.From, msg.Type.To) } _, groupID, err := signalid.ParsePortalID(msg.Portal.ID) if err != nil || groupID == "" { - return false, err + return nil, err } gc.Revision = msg.Portal.Metadata.(*signalid.PortalMetadata).Revision + 1 revision, err := s.Client.UpdateGroup(ctx, gc, groupID) if err != nil { - return false, err + return nil, err } if msg.Type == bridgev2.Invite && targetSignalID.Type != libsignalgo.ServiceIDTypePNI { err = targetIntent.EnsureJoined(ctx, msg.Portal.MXID) if err != nil { - return false, err + return nil, err } } msg.Portal.Metadata.(*signalid.PortalMetadata).Revision = revision - return true, nil + return nil, nil } func plToRole(pl int) signalmeow.GroupMemberRole { From f286c41844dcc60c32951010a68a21236fe121e5 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Fri, 5 Dec 2025 16:02:23 +0200 Subject: [PATCH 479/580] chatinfo: re-query recipient if ACI is marked as unregistered --- pkg/connector/chatinfo.go | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/pkg/connector/chatinfo.go b/pkg/connector/chatinfo.go index 88cf3e2..c8d6c2b 100644 --- a/pkg/connector/chatinfo.go +++ b/pkg/connector/chatinfo.go @@ -212,7 +212,7 @@ func (s *SignalClient) ResolveIdentifier(ctx context.Context, number string, _ b e164String := fmt.Sprintf("+%d", e164Number) if recipient, err = s.Client.ContactByE164(ctx, e164String); err != nil { return nil, fmt.Errorf("error looking up number in local contact list: %w", err) - } else if recipient != nil { + } else if recipient != nil && (recipient.ACI == uuid.Nil || !s.Client.Store.RecipientStore.IsUnregistered(ctx, libsignalgo.NewACIServiceID(recipient.ACI))) { aci = recipient.ACI pni = recipient.PNI } else if resp, err := s.Client.LookupPhone(ctx, e164Number); err != nil { @@ -228,6 +228,9 @@ func (s *SignalClient) ResolveIdentifier(ctx context.Context, number string, _ b zerolog.Ctx(ctx).Err(err).Msg("Failed to save recipient entry after looking up phone") } aci, pni = recipient.ACI, recipient.PNI + if aci != uuid.Nil { + s.Client.Store.RecipientStore.MarkUnregistered(ctx, libsignalgo.NewACIServiceID(aci), false) + } } } else { aci, pni = serviceID.ToACIAndPNI() From b2a6d23eed957d202501ef5a70323fdca5695fb1 Mon Sep 17 00:00:00 2001 From: Conan Date: Mon, 8 Dec 2025 21:32:08 +0800 Subject: [PATCH 480/580] capabilities: bump bridge info version (#625) --- pkg/connector/capabilities.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/connector/capabilities.go b/pkg/connector/capabilities.go index ca2975c..97affb9 100644 --- a/pkg/connector/capabilities.go +++ b/pkg/connector/capabilities.go @@ -231,5 +231,5 @@ func (s *SignalConnector) GetCapabilities() *bridgev2.NetworkGeneralCapabilities } func (s *SignalConnector) GetBridgeInfoVersion() (info, capabilities int) { - return 1, 6 + return 1, 7 } From b4048bf1e3baec7f5c5730e86489f91040618435 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Mon, 8 Dec 2025 16:45:42 +0200 Subject: [PATCH 481/580] signalmeow/receiving: read group ID from USMC --- pkg/libsignalgo/sealedsender.go | 28 ++++++++++++++++------------ pkg/signalmeow/receiving_decrypt.go | 7 +++++++ 2 files changed, 23 insertions(+), 12 deletions(-) diff --git a/pkg/libsignalgo/sealedsender.go b/pkg/libsignalgo/sealedsender.go index 5a55a2c..fd05031 100644 --- a/pkg/libsignalgo/sealedsender.go +++ b/pkg/libsignalgo/sealedsender.go @@ -23,6 +23,7 @@ package libsignalgo import "C" import ( "context" + "fmt" "runtime" "unsafe" @@ -252,18 +253,21 @@ func (usmc *UnidentifiedSenderMessageContent) GetContents() ([]byte, error) { return CopySignalOwnedBufferToBytes(contents), nil } -//func (usmc *UnidentifiedSenderMessageContent) GetGroupID() ([]byte, error) { -// var groupID *C.uchar -// var length C.ulong -// signalFfiError := C.signal_unidentified_sender_message_content_get_group_id(&groupID, &length, usmc.ptr) -// if signalFfiError != nil { -// return nil, wrapError(signalFfiError) -// } -// if groupID == nil { -// return nil, nil -// } -// return CopyBufferToBytes(groupID, length), nil -//} +func (usmc *UnidentifiedSenderMessageContent) GetGroupID() (*GroupIdentifier, error) { + var contents C.SignalOwnedBuffer = C.SignalOwnedBuffer{} + signalFfiError := C.signal_unidentified_sender_message_content_get_group_id_or_empty(&contents, usmc.constPtr()) + runtime.KeepAlive(usmc) + if signalFfiError != nil { + return nil, wrapError(signalFfiError) + } + bytes := CopySignalOwnedBufferToBytes(contents) + if len(bytes) == 0 { + return nil, nil + } else if len(bytes) != GroupIdentifierLength { + return nil, fmt.Errorf("unexpected group ID length: %d", len(bytes)) + } + return (*GroupIdentifier)(bytes), nil +} func (usmc *UnidentifiedSenderMessageContent) GetSenderCertificate() (*SenderCertificate, error) { var senderCertificate C.SignalMutPointerSenderCertificate diff --git a/pkg/signalmeow/receiving_decrypt.go b/pkg/signalmeow/receiving_decrypt.go index 1ffceb0..e5c1b7a 100644 --- a/pkg/signalmeow/receiving_decrypt.go +++ b/pkg/signalmeow/receiving_decrypt.go @@ -39,6 +39,7 @@ type DecryptionResult struct { Content *signalpb.Content ContentHint signalpb.UnidentifiedSenderMessage_Message_ContentHint Err error + GroupID *libsignalgo.GroupIdentifier } func (cli *Client) decryptEnvelope( @@ -315,6 +316,10 @@ func (cli *Client) decryptUnidentifiedSenderEnvelope(ctx context.Context, destin if err != nil { return result, fmt.Errorf("failed to get content hint: %w", err) } + result.GroupID, err = usmc.GetGroupID() + if err != nil { + return result, fmt.Errorf("failed to get group ID: %w", err) + } result.ContentHint = signalpb.UnidentifiedSenderMessage_Message_ContentHint(contentHint) senderUUID, err := senderCertificate.GetSenderUUID() if err != nil { @@ -339,6 +344,7 @@ func (cli *Client) decryptUnidentifiedSenderEnvelope(ctx context.Context, destin } newLog := log.With(). Stringer("sender_uuid", senderUUID). + Stringer("group_id", result.GroupID). Uint32("sender_device_id", senderDeviceID). Str("sender_e164", senderE164). Uint8("sealed_sender_type", uint8(messageType)). @@ -372,6 +378,7 @@ func (cli *Client) decryptUnidentifiedSenderEnvelope(ctx context.Context, destin if err != nil { return result, err } + resultPtr.GroupID = result.GroupID return *resultPtr, nil } From 36e9f02dce312d8407acf7ac3f6da08a387f942e Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Mon, 8 Dec 2025 23:11:45 +0200 Subject: [PATCH 482/580] signalmeow: add support for retry receipts --- pkg/libsignalgo/decryptionerrormessage.go | 9 +- pkg/libsignalgo/publickey.go | 3 + pkg/libsignalgo/sealedsender.go | 14 +- pkg/libsignalgo/session_test.go | 2 +- pkg/libsignalgo/sessionrecord.go | 3 + pkg/signalmeow/client.go | 10 ++ pkg/signalmeow/receiving.go | 62 +++++-- pkg/signalmeow/receiving_decrypt.go | 42 ++++- pkg/signalmeow/retry.go | 206 ++++++++++++++++++++++ pkg/signalmeow/senderkey.go | 26 +-- pkg/signalmeow/sending.go | 161 +++++++++-------- 11 files changed, 425 insertions(+), 113 deletions(-) create mode 100644 pkg/signalmeow/retry.go diff --git a/pkg/libsignalgo/decryptionerrormessage.go b/pkg/libsignalgo/decryptionerrormessage.go index 105fffc..434d40f 100644 --- a/pkg/libsignalgo/decryptionerrormessage.go +++ b/pkg/libsignalgo/decryptionerrormessage.go @@ -23,7 +23,6 @@ package libsignalgo import "C" import ( "runtime" - "time" ) type DecryptionErrorMessage struct { @@ -49,7 +48,7 @@ func DeserializeDecryptionErrorMessage(messageBytes []byte) (*DecryptionErrorMes return wrapDecryptionErrorMessage(dem.raw), nil } -func DecryptionErrorMessageForOriginalMessage(originalBytes []byte, originalType uint8, originalTs uint64, originalSenderDeviceID uint) (*DecryptionErrorMessage, error) { +func DecryptionErrorMessageForOriginalMessage(originalBytes []byte, originalType CiphertextMessageType, originalTs uint64, originalSenderDeviceID uint) (*DecryptionErrorMessage, error) { var dem C.SignalMutPointerDecryptionErrorMessage signalFfiError := C.signal_decryption_error_message_for_original_message( &dem, @@ -112,14 +111,14 @@ func (dem *DecryptionErrorMessage) Serialize() ([]byte, error) { return CopySignalOwnedBufferToBytes(serialized), nil } -func (dem *DecryptionErrorMessage) GetTimestamp() (time.Time, error) { +func (dem *DecryptionErrorMessage) GetTimestamp() (uint64, error) { var ts C.uint64_t signalFfiError := C.signal_decryption_error_message_get_timestamp(&ts, dem.constPtr()) runtime.KeepAlive(dem) if signalFfiError != nil { - return time.Time{}, wrapError(signalFfiError) + return 0, wrapError(signalFfiError) } - return time.UnixMilli(int64(ts)), nil + return uint64(ts), nil } func (dem *DecryptionErrorMessage) GetDeviceID() (uint32, error) { diff --git a/pkg/libsignalgo/publickey.go b/pkg/libsignalgo/publickey.go index dcf9647..bd7452e 100644 --- a/pkg/libsignalgo/publickey.go +++ b/pkg/libsignalgo/publickey.go @@ -29,6 +29,9 @@ type PublicKey struct { } func wrapPublicKey(ptr *C.SignalPublicKey) *PublicKey { + if ptr == nil { + return nil + } publicKey := &PublicKey{ptr: ptr} runtime.SetFinalizer(publicKey, (*PublicKey).Destroy) return publicKey diff --git a/pkg/libsignalgo/sealedsender.go b/pkg/libsignalgo/sealedsender.go index fd05031..5327f1c 100644 --- a/pkg/libsignalgo/sealedsender.go +++ b/pkg/libsignalgo/sealedsender.go @@ -44,7 +44,7 @@ func NewSealedSenderAddress(e164 string, uuid uuid.UUID, deviceID uint32) *Seale } } -func SealedSenderEncryptPlaintext(ctx context.Context, message []byte, contentHint UnidentifiedSenderMessageContentHint, forAddress *Address, fromSenderCert *SenderCertificate, sessionStore SessionStore, identityStore IdentityKeyStore) ([]byte, error) { +func SealedSenderEncryptPlaintext(ctx context.Context, message []byte, contentHint UnidentifiedSenderMessageContentHint, forAddress *Address, fromSenderCert *SenderCertificate, sessionStore SessionStore, identityStore IdentityKeyStore, groupID *GroupIdentifier) ([]byte, error) { ciphertextMessage, err := Encrypt(ctx, message, forAddress, sessionStore, identityStore) if err != nil { return nil, err @@ -54,7 +54,7 @@ func SealedSenderEncryptPlaintext(ctx context.Context, message []byte, contentHi ciphertextMessage, fromSenderCert, contentHint, - nil, + groupID, ) if err != nil { return nil, err @@ -170,18 +170,22 @@ func wrapUnidentifiedSenderMessageContent(ptr *C.SignalUnidentifiedSenderMessage return messageContent } -func NewUnidentifiedSenderMessageContent(message *CiphertextMessage, senderCertificate *SenderCertificate, contentHint UnidentifiedSenderMessageContentHint, groupID []byte) (*UnidentifiedSenderMessageContent, error) { +func NewUnidentifiedSenderMessageContent(message *CiphertextMessage, senderCertificate *SenderCertificate, contentHint UnidentifiedSenderMessageContentHint, groupID *GroupIdentifier) (*UnidentifiedSenderMessageContent, error) { var usmc C.SignalMutPointerUnidentifiedSenderMessageContent + var groupIDBytes []byte + if groupID != nil { + groupIDBytes = groupID[:] + } signalFfiError := C.signal_unidentified_sender_message_content_new( &usmc, message.constPtr(), senderCertificate.constPtr(), C.uint32_t(contentHint), - BytesToBuffer(groupID), + BytesToBuffer(groupIDBytes), ) runtime.KeepAlive(message) runtime.KeepAlive(senderCertificate) - runtime.KeepAlive(groupID) + runtime.KeepAlive(groupIDBytes) if signalFfiError != nil { return nil, wrapError(signalFfiError) } diff --git a/pkg/libsignalgo/session_test.go b/pkg/libsignalgo/session_test.go index 30af762..6d0b720 100644 --- a/pkg/libsignalgo/session_test.go +++ b/pkg/libsignalgo/session_test.go @@ -241,7 +241,7 @@ func TestSealedSenderEncrypt_Repeated(t *testing.T) { }() for i := 0; i < 100; i++ { message := []byte(fmt.Sprintf("%04d vision", i)) - ciphertext, err := libsignalgo.SealedSenderEncryptPlaintext(ctx, message, libsignalgo.UnidentifiedSenderMessageContentHintDefault, bobAddress, senderCert, aliceStore, aliceStore) + ciphertext, err := libsignalgo.SealedSenderEncryptPlaintext(ctx, message, libsignalgo.UnidentifiedSenderMessageContentHintDefault, bobAddress, senderCert, aliceStore, aliceStore, nil) require.NoError(t, err) assert.NotNil(t, ciphertext) } diff --git a/pkg/libsignalgo/sessionrecord.go b/pkg/libsignalgo/sessionrecord.go index a2ee9dd..b4f2afb 100644 --- a/pkg/libsignalgo/sessionrecord.go +++ b/pkg/libsignalgo/sessionrecord.go @@ -83,6 +83,9 @@ func (sr *SessionRecord) ArchiveCurrentState() error { } func (sr *SessionRecord) CurrentRatchetKeyMatches(key *PublicKey) (bool, error) { + if sr == nil || key == nil { + return false, nil + } var result C.bool signalFfiError := C.signal_session_record_current_ratchet_key_matches( &result, diff --git a/pkg/signalmeow/client.go b/pkg/signalmeow/client.go index 52fa12d..57598cd 100644 --- a/pkg/signalmeow/client.go +++ b/pkg/signalmeow/client.go @@ -26,9 +26,11 @@ import ( "time" "github.com/rs/zerolog" + "go.mau.fi/util/exsync" "go.mau.fi/mautrix-signal/pkg/libsignalgo" "go.mau.fi/mautrix-signal/pkg/signalmeow/events" + signalpb "go.mau.fi/mautrix-signal/pkg/signalmeow/protobuf" "go.mau.fi/mautrix-signal/pkg/signalmeow/store" "go.mau.fi/mautrix-signal/pkg/signalmeow/types" "go.mau.fi/mautrix-signal/pkg/signalmeow/web" @@ -42,6 +44,8 @@ type Client struct { senderCertificateNoE164 *libsignalgo.SenderCertificate senderCertificateCache sync.Mutex + sendCache *exsync.RingBuffer[sendCacheKey, *signalpb.Content] + GroupCache *GroupCache ProfileCache *ProfileCache LastContactRequestTime time.Time @@ -67,6 +71,11 @@ type Client struct { writeCallbackCounter chan time.Time } +// InMemorySendCacheSize specifies how large the cache for sent messages is, which is used to respond to retry receipts. +// The cache is large because every group member will be listed separately. +// 2k entries should hold at least 2 messages in max size groups. +var InMemorySendCacheSize = 2048 + func NewClient(device *store.Device, log zerolog.Logger, evtHandler func(events.SignalEvent) bool) *Client { return &Client{ Store: device, @@ -78,6 +87,7 @@ func NewClient(device *store.Device, log zerolog.Logger, evtHandler func(events. errors: make(map[string]*error), lastFetched: make(map[string]time.Time), }, + sendCache: exsync.NewRingBuffer[sendCacheKey, *signalpb.Content](InMemorySendCacheSize), } } diff --git a/pkg/signalmeow/receiving.go b/pkg/signalmeow/receiving.go index a699fbc..b5ed96d 100644 --- a/pkg/signalmeow/receiving.go +++ b/pkg/signalmeow/receiving.go @@ -397,7 +397,7 @@ func (cli *Client) handleDecryptedResult( result DecryptionResult, envelope *signalpb.Envelope, destinationServiceID libsignalgo.ServiceID, -) error { +) (retErr error) { if errors.Is(result.Err, context.Canceled) { return result.Err } else if ctx.Err() != nil { @@ -446,6 +446,11 @@ func (cli *Client) handleDecryptedResult( cli.Store.RecipientStore.MarkUnregistered(ctx, theirServiceID, false) handlerSuccess := true + defer func() { + if retErr == nil && !handlerSuccess { + retErr = ErrHandlerFailed + } + }() // result.Err is set if there was an error during decryption and we // should notifiy the user that the message could not be decrypted if result.Err != nil { @@ -477,6 +482,14 @@ func (cli *Client) handleDecryptedResult( Timestamp: envelope.GetTimestamp(), }) } + if result.Retriable { + go func() { + err := cli.sendRetryRequest(ctx, result, envelope.GetTimestamp()) + if err != nil { + log.Err(err).Msg("Failed to send retry request in background") + } + }() + } if !handlerSuccess { return ErrHandlerFailed } @@ -490,7 +503,11 @@ func (cli *Client) handleDecryptedResult( } deviceID, _ := result.SenderAddress.DeviceID() - log.Trace().Any("raw_data", content).Stringer("sender", theirServiceID).Uint("sender_device", deviceID).Msg("Raw event data") + log.Trace(). + Any("raw_data", content). + Stringer("sender", theirServiceID). + Uint("sender_device", deviceID). + Msg("Raw event data") newLog := log.With(). Stringer("sender_name", theirServiceID). Uint("sender_device_id", deviceID). @@ -502,7 +519,26 @@ func (cli *Client) handleDecryptedResult( if result.CiphertextHash != nil { logEvt = logEvt.Hex("ciphertext_hash", result.CiphertextHash[:]) } - logEvt.Msg("Decrypted message") + logEvt.Bool("unencrypted", result.Unencrypted).Msg("Decrypted message") + + if content.DecryptionErrorMessage != nil { + handlerSuccess = true + dem, err := libsignalgo.DeserializeDecryptionErrorMessage(content.DecryptionErrorMessage) + if err != nil { + log.Warn().Err(err).Msg("Failed to unmarshal decryption error message") + } else { + go func() { + err := cli.handleRetryRequest(ctx, result, dem) + if err != nil { + log.Err(err).Msg("Failed to handle decryption error message in background") + } + }() + } + return + } else if result.Unencrypted { + log.Warn().Msg("Unexpected non-decryption-error content in unencrypted message") + return nil + } // If there's a sender key distribution message, process it if content.GetSenderKeyDistributionMessage() != nil { @@ -538,22 +574,20 @@ func (cli *Client) handleDecryptedResult( } } - if content.GetPniSignatureMessage() != nil { + if content.PniSignatureMessage != nil { log.Debug().Msg("Content includes PNI signature message") - err = cli.handlePNISignatureMessage(ctx, theirServiceID, content.GetPniSignatureMessage()) + err = cli.handlePNISignatureMessage(ctx, theirServiceID, content.PniSignatureMessage) if err != nil { log.Err(err). - Hex("pni_raw", content.GetPniSignatureMessage().GetPni()). + Hex("pni_raw", content.PniSignatureMessage.GetPni()). Stringer("aci", theirServiceID.UUID). Msg("Failed to verify ACI-PNI mapping") } } if content.SyncMessage != nil && theirServiceID == cli.Store.ACIServiceID() { - handlerSuccess, err = cli.handleSyncMessage(ctx, content.SyncMessage, envelope) - if err != nil { - return err - } + handlerSuccess = cli.handleSyncMessage(ctx, content.SyncMessage, envelope) + return nil } isBlocked, err := cli.Store.RecipientStore.IsBlocked(ctx, theirServiceID.UUID) @@ -620,9 +654,6 @@ func (cli *Client) handleDecryptedResult( Content: content.ReceiptMessage, }) && handlerSuccess } - if !handlerSuccess { - return ErrHandlerFailed - } return nil } @@ -633,7 +664,7 @@ func groupOrUserID(groupID types.GroupIdentifier, userID libsignalgo.ServiceID) return string(groupID) } -func (cli *Client) handleSyncMessage(ctx context.Context, msg *signalpb.SyncMessage, envelope *signalpb.Envelope) (handlerSuccess bool, err error) { +func (cli *Client) handleSyncMessage(ctx context.Context, msg *signalpb.SyncMessage, envelope *signalpb.Envelope) (handlerSuccess bool) { // TODO: handle more sync messages handlerSuccess = true log := zerolog.Ctx(ctx) @@ -655,7 +686,7 @@ func (cli *Client) handleSyncMessage(ctx context.Context, msg *signalpb.SyncMess } else { log.Debug().Msg("No account entropy pool in sync message") } - err = cli.Store.DeviceStore.PutDevice(ctx, &cli.Store.DeviceData) + err := cli.Store.DeviceStore.PutDevice(ctx, &cli.Store.DeviceData) if err != nil { log.Err(err).Msg("Failed to save device after receiving master key") } else { @@ -671,6 +702,7 @@ func (cli *Client) handleSyncMessage(ctx context.Context, msg *signalpb.SyncMess destination := syncSent.DestinationServiceId var syncDestinationServiceID libsignalgo.ServiceID if destination != nil { + var err error syncDestinationServiceID, err = libsignalgo.ServiceIDFromString(*destination) if err != nil { log.Err(err).Msg("Sync message destination parse error") diff --git a/pkg/signalmeow/receiving_decrypt.go b/pkg/signalmeow/receiving_decrypt.go index e5c1b7a..5c8da08 100644 --- a/pkg/signalmeow/receiving_decrypt.go +++ b/pkg/signalmeow/receiving_decrypt.go @@ -40,6 +40,11 @@ type DecryptionResult struct { ContentHint signalpb.UnidentifiedSenderMessage_Message_ContentHint Err error GroupID *libsignalgo.GroupIdentifier + Unencrypted bool + + Retriable bool + Ciphertext []byte + CiphertextType libsignalgo.CiphertextMessageType } func (cli *Client) decryptEnvelope( @@ -80,12 +85,30 @@ func (cli *Client) decryptEnvelope( bundleType = "ciphertext" } if err != nil { - return DecryptionResult{Err: fmt.Errorf("failed to decrypt %s envelope: %w", bundleType, err), SenderAddress: sender} + return DecryptionResult{ + SenderAddress: sender, + Err: fmt.Errorf("failed to decrypt %s envelope: %w", bundleType, err), + Retriable: true, // TODO should these ever be not retriable? + Ciphertext: envelope.Content, + CiphertextType: libsignalgo.CiphertextMessageType(envelope.GetType()), + } } return *result case signalpb.Envelope_PLAINTEXT_CONTENT: - return DecryptionResult{Err: fmt.Errorf("plaintext messages are not supported")} + addr, err := libsignalgo.NewUUIDAddressFromString(envelope.GetSourceServiceId(), uint(envelope.GetSourceDevice())) + if err != nil { + return DecryptionResult{Err: fmt.Errorf("failed to wrap address: %v", err)} + } + content, err := stripPadding(envelope.GetContent()) + if err != nil { + return DecryptionResult{Err: fmt.Errorf("failed to strip padding: %w", err)} + } + return DecryptionResult{ + SenderAddress: addr, + Content: &signalpb.Content{DecryptionErrorMessage: content}, + Unencrypted: true, + } case signalpb.Envelope_SERVER_DELIVERY_RECEIPT: return DecryptionResult{Err: fmt.Errorf("server delivery receipt envelopes are not yet supported")} @@ -342,6 +365,8 @@ func (cli *Client) decryptUnidentifiedSenderEnvelope(ctx context.Context, destin if err != nil { return result, fmt.Errorf("failed to get USMC contents: %w", err) } + result.Ciphertext = usmcContents + result.CiphertextType = messageType newLog := log.With(). Stringer("sender_uuid", senderUUID). Stringer("group_id", result.GroupID). @@ -369,13 +394,20 @@ func (cli *Client) decryptUnidentifiedSenderEnvelope(ctx context.Context, destin case libsignalgo.CiphertextMessageTypeWhisper: resultPtr, err = cli.decryptCiphertextEnvelope(ctx, destinationServiceID, senderAddress, usmcContents, envelope.GetServerTimestamp()) case libsignalgo.CiphertextMessageTypePlaintext: - // TODO: handle plaintext (usually DecryptionErrorMessage) and retries - // when implementing SenderKey groups - return result, fmt.Errorf("unsupported plaintext sealed sender message") + usmcContents, err = stripPadding(usmcContents) + if err != nil { + err = fmt.Errorf("failed to strip padding: %w", err) + } + result.Unencrypted = true + result.Content = &signalpb.Content{ + DecryptionErrorMessage: usmcContents, + } + return result, err default: return result, fmt.Errorf("unsupported sealed sender message type %d", messageType) } if err != nil { + result.Retriable = result.ContentHint == signalpb.UnidentifiedSenderMessage_Message_RESENDABLE return result, err } resultPtr.GroupID = result.GroupID diff --git a/pkg/signalmeow/retry.go b/pkg/signalmeow/retry.go new file mode 100644 index 0000000..2c89ecc --- /dev/null +++ b/pkg/signalmeow/retry.go @@ -0,0 +1,206 @@ +// mautrix-signal - A Matrix-signal puppeting bridge. +// Copyright (C) 2025 Tulir Asokan +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +package signalmeow + +import ( + "context" + "fmt" + "slices" + "time" + + "github.com/rs/zerolog" + + "go.mau.fi/mautrix-signal/pkg/libsignalgo" + signalpb "go.mau.fi/mautrix-signal/pkg/signalmeow/protobuf" + "go.mau.fi/mautrix-signal/pkg/signalmeow/types" +) + +type sendCacheKey struct { + recipient libsignalgo.ServiceID + groupID types.GroupIdentifier + timestamp uint64 +} + +const RetryRespondMaxAge = 30 * 24 * time.Hour + +func (cli *Client) sendRetryRequest(ctx context.Context, result DecryptionResult, originalTS uint64) error { + serviceID, err := result.SenderAddress.NameServiceID() + if err != nil { + return fmt.Errorf("failed to get sender name as service ID: %w", err) + } + deviceID, err := result.SenderAddress.DeviceID() + if err != nil { + return fmt.Errorf("failed to get sender device ID: %w", err) + } + dem, err := libsignalgo.DecryptionErrorMessageForOriginalMessage(result.Ciphertext, result.CiphertextType, originalTS, deviceID) + if err != nil { + return fmt.Errorf("failed to create decryption error message: %w", err) + } + demBytes, err := dem.Serialize() + if err != nil { + return fmt.Errorf("failed to serialize decryption error message: %w", err) + } + ptc, err := libsignalgo.PlaintextContentFromDecryptionErrorMessage(dem) + if err != nil { + return fmt.Errorf("failed to create plaintext content from decryption error message: %w", err) + } + ctm, err := libsignalgo.NewCiphertextMessage(ptc) + if err != nil { + return fmt.Errorf("failed to create ciphertext message from plaintext content: %w", err) + } + _, err = cli.sendContent(ctx, serviceID, uint64(time.Now().UnixMilli()), &signalpb.Content{ + DecryptionErrorMessage: demBytes, + }, 0, true, result.GroupID, ctm) + if err != nil { + return fmt.Errorf("failed to send decryption error message: %w", err) + } + zerolog.Ctx(ctx).Debug(). + Stringer("sender_service_id", serviceID). + Uint("sender_device_id", deviceID). + Stringer("group_id", result.GroupID). + Msg("Sent retry receipt") + return nil +} + +func (cli *Client) handleRetryRequest( + ctx context.Context, + result DecryptionResult, + dem *libsignalgo.DecryptionErrorMessage, +) error { + destDeviceID, err := dem.GetDeviceID() + if err != nil { + return fmt.Errorf("failed to get device ID from decryption error message: %w", err) + } else if int(destDeviceID) != cli.Store.DeviceID { + zerolog.Ctx(ctx).Debug(). + Uint32("dest_device_id", destDeviceID). + Msg("Ignoring decryption error message for another device") + return nil + } + serviceID, err := result.SenderAddress.NameServiceID() + if err != nil { + return fmt.Errorf("failed to get sender name as service ID: %w", err) + } + deviceID, err := result.SenderAddress.DeviceID() + if err != nil { + return fmt.Errorf("failed to get sender device ID: %w", err) + } + ts, err := dem.GetTimestamp() + if err != nil { + return fmt.Errorf("failed to get timestamp: %w", err) + } + + cli.encryptionLock.Lock() + defer cli.encryptionLock.Unlock() + ctx = context.WithValue(ctx, contextKeyEncryptionLock, true) + var didArchiveSession bool + if ratchetKey, err := dem.GetRatchetKey(); err != nil { + return fmt.Errorf("failed to get ratchet key: %w", err) + } else if ratchetKey == nil { + // No need to archive session if no ratchet key is provided, it was probably a sender key decryption error + } else if session, err := cli.Store.ACISessionStore.LoadSession(ctx, result.SenderAddress); err != nil { + return fmt.Errorf("failed to load session for sender: %w", err) + } else if match, err := session.CurrentRatchetKeyMatches(ratchetKey); err != nil { + return fmt.Errorf("failed to check ratchet key match: %w", err) + } else if match { + err = session.ArchiveCurrentState() + if err != nil { + return fmt.Errorf("failed to archive current session state: %w", err) + } + err = cli.Store.ACISessionStore.StoreSession(ctx, result.SenderAddress, session) + if err != nil { + return fmt.Errorf("failed to store archived session: %w", err) + } + didArchiveSession = true + } + var skdmBytes []byte + groupID := types.BytesToGroupIdentifier(result.GroupID) + if groupID != "" { + ski, err := cli.Store.SenderKeyStore.GetSenderKeyInfo(ctx, groupID) + if err != nil { + return fmt.Errorf("failed to get sender key info for group %s: %w", groupID, err) + } + myAddress, err := cli.Store.ACIServiceID().Address(uint(cli.Store.DeviceID)) + if err != nil { + return fmt.Errorf("failed to get own address: %w", err) + } + if slices.Contains(ski.SharedWith[serviceID], int(deviceID)) { + skdm, err := libsignalgo.NewSenderKeyDistributionMessage(ctx, myAddress, ski.DistributionID, cli.Store.SenderKeyStore) + if err != nil { + return fmt.Errorf("failed to create sender key distribution message: %w", err) + } + skdmBytes, err = skdm.Serialize() + if err != nil { + return fmt.Errorf("failed to serialize sender key distribution message: %w", err) + } + } else { + zerolog.Ctx(ctx).Warn(). + Stringer("group_id", result.GroupID). + Stringer("sender_service_id", serviceID). + Stringer("distribution_id", ski.DistributionID). + Uint("sender_device_id", deviceID). + Ints("shared_with", ski.SharedWith[serviceID]). + Msg("Sender key distribution list doesn't contain retry receipt sender") + } + } + var retryContent *signalpb.Content + var cacheHit bool + if time.Since(time.UnixMilli(int64(ts))) < RetryRespondMaxAge { + retryContent, cacheHit = cli.sendCache.Get(sendCacheKey{ + groupID: groupID, + recipient: serviceID, + timestamp: ts, + }) + if !cacheHit { + // TODO add support for external caches + } + } + if retryContent == nil { + retryContent = &signalpb.Content{} + } + retryContent.SenderKeyDistributionMessage = skdmBytes + if !cacheHit && skdmBytes == nil { + if !didArchiveSession { + zerolog.Ctx(ctx).Debug(). + Uint64("msg_timestamp", ts). + Stringer("sender_service_id", serviceID). + Uint("sender_device_id", deviceID). + Stringer("group_id", result.GroupID). + Msg("Not responding to decryption error message") + return nil + } + retryContent.NullMessage = &signalpb.NullMessage{} + } + responseTimestamp := uint64(time.Now().UnixMilli()) + if cacheHit { + responseTimestamp = ts + } + zerolog.Ctx(ctx).Debug(). + Uint32("dest_device_id", destDeviceID). + Uint64("requested_msg_timestamp", ts). + Stringer("sender_service_id", serviceID). + Uint("sender_device_id", deviceID). + Stringer("group_id", result.GroupID). + Bool("did_archive_session", didArchiveSession). + Bool("found_message_in_cache", cacheHit). + Bool("including_skdm", skdmBytes != nil). + Msg("Responding to decryption error message") + _, err = cli.sendContent(ctx, serviceID, responseTimestamp, retryContent, 0, true, result.GroupID, nil) + if err != nil { + return fmt.Errorf("failed to send response: %w", err) + } + return nil +} diff --git a/pkg/signalmeow/senderkey.go b/pkg/signalmeow/senderkey.go index 4f54c81..b676d6c 100644 --- a/pkg/signalmeow/senderkey.go +++ b/pkg/signalmeow/senderkey.go @@ -48,7 +48,7 @@ const ( func (cli *Client) sendToGroupWithSenderKey( ctx context.Context, - groupID types.GroupIdentifier, + groupID *libsignalgo.GroupIdentifier, allRecipients []libsignalgo.ServiceID, sec SendEndorsementCache, content *signalpb.Content, @@ -56,7 +56,7 @@ func (cli *Client) sendToGroupWithSenderKey( retries int, ) (*GroupMessageSendResult, error) { if retries >= 3 { - return cli.sendToGroup(ctx, allRecipients, content, messageTimestamp, nil) + return cli.sendToGroup(ctx, allRecipients, content, messageTimestamp, nil, groupID) } myAddress, err := cli.Store.ACIServiceID().Address(uint(cli.Store.DeviceID)) if err != nil { @@ -79,8 +79,9 @@ func (cli *Client) sendToGroupWithSenderKey( FailedToSendTo: make([]FailedSendResult, 0), } + groupIDStr := types.GroupIdentifier(groupID.String()) deviceIDs, senderKeyRecipients, fallbackRecipients := cli.getDevicesIDs(ctx, allRecipients, sec, result) - ski, err := cli.Store.SenderKeyStore.GetSenderKeyInfo(ctx, groupID) + ski, err := cli.Store.SenderKeyStore.GetSenderKeyInfo(ctx, groupIDStr) if err != nil { return nil, fmt.Errorf("failed to get sender key info: %w", err) } else if ski == nil || time.Since(ski.CreatedAt) > SenderKeyMaxAge { @@ -127,7 +128,7 @@ func (cli *Client) sendToGroupWithSenderKey( log := log.With().Str("subaction", "skdm").Stringer("recipient_id", recipient).Logger() _, err = cli.sendContent(log.WithContext(ctx), recipient, messageTimestamp, &signalpb.Content{ SenderKeyDistributionMessage: skdmBytes, - }, 0, true, true) + }, 0, true, groupID, nil) if errors.Is(err, ErrDevicesChanged) || errors.Is(err, ErrUnregisteredUser) { log.Warn().Err(err).Msg("Failed to send sender key distribution message due to device changes, will retry") needsRetry = true @@ -143,7 +144,7 @@ func (cli *Client) sendToGroupWithSenderKey( ski.SharedWith[recipient] = deviceIDs[recipient].DeviceIDs } } - err = cli.Store.SenderKeyStore.PutSenderKeyInfo(ctx, groupID, ski) + err = cli.Store.SenderKeyStore.PutSenderKeyInfo(ctx, groupIDStr, ski) if err != nil { return nil, fmt.Errorf("failed to store updated sender key info: %w", err) } @@ -156,6 +157,9 @@ func (cli *Client) sendToGroupWithSenderKey( if err != nil { return nil, err } + for recipientID := range ski.SharedWith { + cli.addSendCache(recipientID, groupIDStr, messageTimestamp, content) + } header := http.Header{} header.Set("Content-Type", string(web.ContentTypeMultiRecipientMessage)) if sec.SendEndorsement != nil { @@ -219,13 +223,13 @@ func (cli *Client) sendToGroupWithSenderKey( } doUnlock() // Send with fallback for any recipients that couldn't do sender key, plus our own sync copy - return cli.sendToGroup(ctx, fallbackRecipients, content, messageTimestamp, result) + return cli.sendToGroup(ctx, fallbackRecipients, content, messageTimestamp, result, groupID) case 401, 404: log.Warn().Uint32("status_code", resp.GetStatus()). Msg("Multi-recipient send failed, falling back to normal send") doUnlock() // Fall back to normal send for all recipients - return cli.sendToGroup(ctx, allRecipients, content, messageTimestamp, nil) + return cli.sendToGroup(ctx, allRecipients, content, messageTimestamp, nil, groupID) case 409, 410: log.Warn().Uint32("status_code", resp.GetStatus()). Msg("Multi-recipient send failed due to outdated device list, refreshing and retrying") @@ -243,7 +247,7 @@ func (cli *Client) sendToGroupWithSenderKey( func (cli *Client) encryptWithSenderKey( ctx context.Context, - groupID types.GroupIdentifier, + groupID *libsignalgo.GroupIdentifier, distributionID uuid.UUID, myAddress *libsignalgo.Address, senderKeyRecipients []store.SessionAddressTuple, @@ -265,11 +269,7 @@ func (cli *Client) encryptWithSenderKey( if err != nil { return nil, fmt.Errorf("failed to get sender certificate: %w", err) } - groupIDBytes, err := groupID.Bytes() - if err != nil { - return nil, fmt.Errorf("failed to deserialize group ID: %w", err) - } - usmc, err := libsignalgo.NewUnidentifiedSenderMessageContent(ciphertext, cert, getContentHint(content), groupIDBytes[:]) + usmc, err := libsignalgo.NewUnidentifiedSenderMessageContent(ciphertext, cert, getContentHint(content), groupID) if err != nil { return nil, fmt.Errorf("failed to create unidentified sender message content: %w", err) } diff --git a/pkg/signalmeow/sending.go b/pkg/signalmeow/sending.go index 97fdcdf..0ea55f9 100644 --- a/pkg/signalmeow/sending.go +++ b/pkg/signalmeow/sending.go @@ -147,7 +147,9 @@ func (cli *Client) buildMessagesToSend( ctx context.Context, recipient libsignalgo.ServiceID, content *signalpb.Content, - unauthenticated, isGroup bool, + unauthenticated bool, + groupID *libsignalgo.GroupIdentifier, + ctmOverride *libsignalgo.CiphertextMessage, ) ([]MyMessage, error) { if ctx.Value(contextKeyEncryptionLock) != true { cli.encryptionLock.Lock() @@ -179,26 +181,19 @@ func (cli *Client) buildMessagesToSend( continue } - // Build message payload serializedMessage, err := proto.Marshal(content) if err != nil { return nil, err } - paddedMessage, err := addPadding(3, serializedMessage) // TODO: figure out how to get actual version + paddedMessage, err := addPadding(3, serializedMessage) if err != nil { return nil, err } - var envelopeType int - var encryptedPayload []byte - if unauthenticated { - includeE164 := !isGroup && cli.Store.AccountRecord.GetPhoneNumberSharingMode() == signalpb.AccountRecord_EVERYBODY - envelopeType, encryptedPayload, err = cli.buildSSMessageToSend( - ctx, tuple.Address, paddedMessage, getContentHint(content), includeE164, - ) - } else { - envelopeType, encryptedPayload, err = cli.buildAuthedMessageToSend(ctx, tuple.Address, paddedMessage) - } + includeE164 := groupID == nil && cli.Store.AccountRecord.GetPhoneNumberSharingMode() == signalpb.AccountRecord_EVERYBODY + envelopeType, encryptedPayload, err := cli.buildMessageToSend( + ctx, tuple.Address, paddedMessage, getContentHint(content), ctmOverride, groupID, includeE164, unauthenticated, + ) if err != nil { return nil, err } @@ -208,7 +203,7 @@ func (cli *Client) buildMessagesToSend( return nil, err } outgoingMessage := MyMessage{ - Type: envelopeType, + Type: int(envelopeType), DestinationDeviceID: tuple.DeviceID, DestinationRegistrationID: int(destinationRegistrationID), Content: base64.StdEncoding.EncodeToString(encryptedPayload), @@ -219,54 +214,59 @@ func (cli *Client) buildMessagesToSend( return messages, nil } -func (cli *Client) buildAuthedMessageToSend(ctx context.Context, recipientAddress *libsignalgo.Address, paddedMessage []byte) (envelopeType int, encryptedPayload []byte, err error) { - cipherTextMessage, err := libsignalgo.Encrypt( - ctx, - paddedMessage, - recipientAddress, - cli.Store.ACISessionStore, - cli.Store.ACIIdentityStore, - ) - if err != nil { - return 0, nil, err +func ctmTypeToEnvelopeType(ctmType libsignalgo.CiphertextMessageType) signalpb.Envelope_Type { + switch ctmType { + case libsignalgo.CiphertextMessageTypeWhisper: + return signalpb.Envelope_CIPHERTEXT // 2 -> 1 + case libsignalgo.CiphertextMessageTypePreKey: + return signalpb.Envelope_PREKEY_BUNDLE // 3 -> 3 + case libsignalgo.CiphertextMessageTypeSenderKey: + return signalpb.Envelope_SENDERKEY_MESSAGE // 7 -> 7 + case libsignalgo.CiphertextMessageTypePlaintext: + return signalpb.Envelope_PLAINTEXT_CONTENT // 8 -> 8 + default: + return signalpb.Envelope_UNKNOWN } - encryptedPayload, err = cipherTextMessage.Serialize() - if err != nil { - return 0, nil, err - } - - // OMG Signal are you serious why can't your magic numbers just align - cipherMessageType, _ := cipherTextMessage.MessageType() - if cipherMessageType == libsignalgo.CiphertextMessageTypePreKey { // 3 -> 3 - envelopeType = int(signalpb.Envelope_PREKEY_BUNDLE) - } else if cipherMessageType == libsignalgo.CiphertextMessageTypeWhisper { // 2 -> 1 - envelopeType = int(signalpb.Envelope_CIPHERTEXT) - } else { - return 0, nil, fmt.Errorf("unknown message type: %v", cipherMessageType) - } - return envelopeType, encryptedPayload, nil } -func (cli *Client) buildSSMessageToSend(ctx context.Context, recipientAddress *libsignalgo.Address, paddedMessage []byte, contentHint libsignalgo.UnidentifiedSenderMessageContentHint, includeE164 bool) (envelopeType int, encryptedPayload []byte, err error) { +func (cli *Client) buildMessageToSend( + ctx context.Context, + recipientAddress *libsignalgo.Address, + paddedMessage []byte, + contentHint libsignalgo.UnidentifiedSenderMessageContentHint, + ciphertextMessage *libsignalgo.CiphertextMessage, + groupID *libsignalgo.GroupIdentifier, + includeE164, sealedSender bool, +) (envelopeType signalpb.Envelope_Type, encryptedPayload []byte, err error) { + if ciphertextMessage == nil { + ciphertextMessage, err = libsignalgo.Encrypt( + ctx, + paddedMessage, + recipientAddress, + cli.Store.ACISessionStore, + cli.Store.ACIIdentityStore, + ) + if err != nil { + return 0, nil, err + } + } + cipherMessageType, _ := ciphertextMessage.MessageType() + envelopeType = ctmTypeToEnvelopeType(cipherMessageType) + if !sealedSender { + encryptedPayload, err = ciphertextMessage.Serialize() + return + } cert, err := cli.senderCertificate(ctx, includeE164) if err != nil { return 0, nil, err } - encryptedPayload, err = libsignalgo.SealedSenderEncryptPlaintext( - ctx, - paddedMessage, - contentHint, - recipientAddress, - cert, - cli.Store.ACISessionStore, - cli.Store.ACIIdentityStore, - ) + usmc, err := libsignalgo.NewUnidentifiedSenderMessageContent(ciphertextMessage, cert, contentHint, groupID) if err != nil { return 0, nil, err } - envelopeType = int(signalpb.Envelope_UNIDENTIFIED_SENDER) - - return envelopeType, encryptedPayload, nil + encryptedPayload, err = libsignalgo.SealedSenderEncrypt(ctx, usmc, recipientAddress, cli.Store.ACIIdentityStore) + envelopeType = signalpb.Envelope_UNIDENTIFIED_SENDER + return } type SuccessfulSendResult struct { @@ -427,7 +427,7 @@ func (cli *Client) SendContactSyncRequest(ctx context.Context) error { Type: signalpb.SyncMessage_Request_CONTACTS.Enum(), }, }, - }, 0, false, false) + }, 0, false, nil, nil) if err != nil { log.Err(err).Msg("Failed to send contact sync request message to myself") return err @@ -447,7 +447,7 @@ func (cli *Client) SendStorageMasterKeyRequest(ctx context.Context) error { Type: signalpb.SyncMessage_Request_KEYS.Enum(), }, }, - }, 0, false, false) + }, 0, false, nil, nil) if err != nil { log.Err(err).Msg("Failed to send key sync request message to myself") return err @@ -502,11 +502,23 @@ func wrapDataMessageInContent(dm *signalpb.DataMessage) *signalpb.Content { } } +func (cli *Client) addSendCache(recipient libsignalgo.ServiceID, groupID types.GroupIdentifier, ts uint64, content *signalpb.Content) { + cli.sendCache.Push(sendCacheKey{ + recipient: recipient, + groupID: groupID, + timestamp: ts, + }, content) +} + func (cli *Client) SendGroupUpdate(ctx context.Context, group *Group, groupContext *signalpb.GroupContextV2, groupChange *GroupChange) (*GroupMessageSendResult, error) { log := zerolog.Ctx(ctx).With(). Str("action", "send group change message"). Stringer("group_id", group.GroupIdentifier). Logger() + gidBytes, err := group.GroupIdentifier.Bytes() + if err != nil { + return nil, err + } ctx = log.WithContext(ctx) timestamp := currentMessageTimestamp() dm := &signalpb.DataMessage{ @@ -518,20 +530,24 @@ func (cli *Client) SendGroupUpdate(ctx context.Context, group *Group, groupConte for _, member := range group.Members { serviceID := member.UserServiceID() recipients = append(recipients, serviceID) + cli.addSendCache(serviceID, group.GroupIdentifier, timestamp, content) } for _, member := range group.PendingMembers { recipients = append(recipients, member.ServiceID) + cli.addSendCache(member.ServiceID, group.GroupIdentifier, timestamp, content) } if groupChange != nil { for _, member := range groupChange.AddPendingMembers { recipients = append(recipients, member.ServiceID) + cli.addSendCache(member.ServiceID, group.GroupIdentifier, timestamp, content) } for _, member := range groupChange.AddMembers { serviceID := member.UserServiceID() recipients = append(recipients, serviceID) + cli.addSendCache(serviceID, group.GroupIdentifier, timestamp, content) } } - return cli.sendToGroup(ctx, recipients, content, timestamp, nil) + return cli.sendToGroup(ctx, recipients, content, timestamp, nil, &gidBytes) } const enableSenderKeySend = true @@ -565,10 +581,14 @@ func (cli *Client) SendGroupMessage(ctx context.Context, gid types.GroupIdentifi for _, member := range group.Members { recipients = append(recipients, member.UserServiceID()) } - if enableSenderKeySend { - return cli.sendToGroupWithSenderKey(ctx, gid, recipients, ptr.Val(endorsement), content, messageTimestamp, 0) + gidBytes, err := gid.Bytes() + if err != nil { + return nil, err } - return cli.sendToGroup(ctx, recipients, content, messageTimestamp, nil) + if enableSenderKeySend { + return cli.sendToGroupWithSenderKey(ctx, &gidBytes, recipients, ptr.Val(endorsement), content, messageTimestamp, 0) + } + return cli.sendToGroup(ctx, recipients, content, messageTimestamp, nil, &gidBytes) } func (cli *Client) sendToGroup( @@ -577,6 +597,7 @@ func (cli *Client) sendToGroup( content *signalpb.Content, messageTimestamp uint64, result *GroupMessageSendResult, + groupID *libsignalgo.GroupIdentifier, ) (*GroupMessageSendResult, error) { if result == nil { result = &GroupMessageSendResult{ @@ -595,7 +616,7 @@ func (cli *Client) sendToGroup( } log := zerolog.Ctx(ctx).With().Stringer("member", recipient).Logger() ctx := log.WithContext(ctx) - sentUnidentified, err := cli.sendContent(ctx, recipient, messageTimestamp, content, 0, true, true) + sentUnidentified, err := cli.sendContent(ctx, recipient, messageTimestamp, content, 0, true, groupID, nil) if err != nil { result.FailedToSendTo = append(result.FailedToSendTo, FailedSendResult{ Recipient: recipient, @@ -611,7 +632,7 @@ func (cli *Client) sendToGroup( } } - cli.sendGroupSyncCopy(ctx, content, messageTimestamp, result) + cli.sendGroupSyncCopy(ctx, content, messageTimestamp, result, groupID) if len(result.FailedToSendTo) == 0 && len(result.SuccessfullySentTo) == 0 { return result, nil // I only sent to myself @@ -629,6 +650,7 @@ func (cli *Client) sendGroupSyncCopy( content *signalpb.Content, messageTimestamp uint64, result *GroupMessageSendResult, + groupID *libsignalgo.GroupIdentifier, ) { var syncContent *signalpb.Content if content.GetDataMessage() != nil { @@ -637,7 +659,7 @@ func (cli *Client) sendGroupSyncCopy( syncContent = syncMessageFromGroupEditMessage(content.EditMessage, result.SuccessfullySentTo) } if syncContent != nil { - _, selfSendErr := cli.sendContent(ctx, cli.Store.ACIServiceID(), messageTimestamp, syncContent, 0, true, true) + _, selfSendErr := cli.sendContent(ctx, cli.Store.ACIServiceID(), messageTimestamp, syncContent, 0, true, groupID, nil) if selfSendErr != nil { zerolog.Ctx(ctx).Err(selfSendErr).Msg("Failed to send sync message to myself") } @@ -656,7 +678,7 @@ func (cli *Client) sendSyncCopy(ctx context.Context, content *signalpb.Content, syncContent = content } if syncContent != nil { - _, selfSendErr := cli.sendContent(ctx, cli.Store.ACIServiceID(), messageTS, syncContent, 0, true, false) + _, selfSendErr := cli.sendContent(ctx, cli.Store.ACIServiceID(), messageTS, syncContent, 0, true, nil, nil) if selfSendErr != nil { zerolog.Ctx(ctx).Err(selfSendErr).Msg("Failed to send sync message to myself") } else { @@ -740,8 +762,9 @@ func (cli *Client) SendMessage(ctx context.Context, recipientID libsignalgo.Serv } } + cli.addSendCache(recipientID, "", messageTimestamp, content) // Send to the recipient - sentUnidentified, err := cli.sendContent(ctx, recipientID, messageTimestamp, content, 0, true, false) + sentUnidentified, err := cli.sendContent(ctx, recipientID, messageTimestamp, content, 0, true, nil, nil) if err != nil { return SendMessageResult{ WasSuccessful: false, @@ -793,8 +816,7 @@ func isUrgent(content *signalpb.Content) bool { func getContentHint(content *signalpb.Content) libsignalgo.UnidentifiedSenderMessageContentHint { if content.DataMessage != nil || content.EditMessage != nil { - // TODO add support for resending before setting this - //return libsignalgo.UnidentifiedSenderMessageContentHintResendable + return libsignalgo.UnidentifiedSenderMessageContentHintResendable } if content.TypingMessage != nil || content.ReceiptMessage != nil { return libsignalgo.UnidentifiedSenderMessageContentHintImplicit @@ -809,7 +831,8 @@ func (cli *Client) sendContent( content *signalpb.Content, retryCount int, useUnidentifiedSender bool, - isGroup bool, + groupID *libsignalgo.GroupIdentifier, + ctmOverride *libsignalgo.CiphertextMessage, ) (sentUnidentified bool, err error) { log := zerolog.Ctx(ctx).With(). Str("action", "send content"). @@ -862,7 +885,7 @@ func (cli *Client) sendContent( } var messages []MyMessage - messages, err = cli.buildMessagesToSend(ctx, recipient, content, useUnidentifiedSender, isGroup) + messages, err = cli.buildMessagesToSend(ctx, recipient, content, useUnidentifiedSender, groupID, ctmOverride) if err != nil { log.Err(err).Msg("Error building messages to send") return false, err @@ -934,7 +957,7 @@ func (cli *Client) sendContent( return false, err } // Try to send again (**RECURSIVELY**) - sentUnidentified, err = cli.sendContent(ctx, recipient, messageTimestamp, content, retryCount+1, sentUnidentified, isGroup) + sentUnidentified, err = cli.sendContent(ctx, recipient, messageTimestamp, content, retryCount+1, sentUnidentified, groupID, ctmOverride) if err != nil { log.Err(err).Msg("2nd try sendMessage error") return sentUnidentified, err @@ -945,7 +968,7 @@ func (cli *Client) sendContent( } log.Debug().Msg("Retrying send without sealed sender") // Try to send again (**RECURSIVELY**) - sentUnidentified, err = cli.sendContent(ctx, recipient, messageTimestamp, content, retryCount+1, false, isGroup) + sentUnidentified, err = cli.sendContent(ctx, recipient, messageTimestamp, content, retryCount+1, false, groupID, ctmOverride) if err != nil { log.Err(err).Msg("2nd try sendMessage error") return sentUnidentified, err From bcc5917067dc8a1ed542d434200b517559fe7582 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Mon, 8 Dec 2025 23:34:32 +0200 Subject: [PATCH 483/580] libsignalgo: add debug for duplicate destinations in multi-recipient send --- pkg/libsignalgo/sealedsender.go | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/pkg/libsignalgo/sealedsender.go b/pkg/libsignalgo/sealedsender.go index 5327f1c..eb6f655 100644 --- a/pkg/libsignalgo/sealedsender.go +++ b/pkg/libsignalgo/sealedsender.go @@ -24,10 +24,14 @@ import "C" import ( "context" "fmt" + "maps" "runtime" + "slices" "unsafe" "github.com/google/uuid" + "github.com/rs/zerolog" + "go.mau.fi/util/exerrors" ) type SealedSenderAddress struct { @@ -98,10 +102,31 @@ func SealedSenderMultiRecipientEncrypt( defer callbackCtx.Unref() recipientAddresses := make([]C.SignalConstPointerProtocolAddress, len(recipients)) recipientSessions := make([]C.SignalConstPointerSessionRecord, len(recipients)) + + type dedupTuple struct { + Name string + DeviceID uint + } + deviceDedup := make(map[dedupTuple]struct{}) + var duplicateFound *dedupTuple + for i, recipient := range recipients { + name := exerrors.Must(recipient.Address.Name()) + deviceID := exerrors.Must(recipient.Address.DeviceID()) + dedupKey := dedupTuple{name, deviceID} + if _, exists := deviceDedup[dedupKey]; exists { + duplicateFound = &dedupKey + } recipientAddresses[i] = recipient.Address.constPtr() recipientSessions[i] = recipient.Record.constPtr() } + if duplicateFound != nil { + zerolog.Ctx(ctx).Debug(). + Any("full_list", slices.Collect(maps.Keys(deviceDedup))). + Any("last_duplicate", *duplicateFound). + Msg("Duplicate debug data") + return nil, fmt.Errorf("duplicate recipient addresses found in SealedSenderMultiRecipientEncrypt") + } signalFfiError := C.signal_sealed_sender_multi_recipient_encrypt( &encrypted, C.SignalBorrowedSliceOfConstPointerProtocolAddress{ From b661b30b851d6892915a94acf71d1522a43cbcfa Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Tue, 9 Dec 2025 00:14:50 +0200 Subject: [PATCH 484/580] commands: add command to reset sender key --- pkg/connector/commands.go | 73 ++++++++++++++++++++++++ pkg/connector/connector.go | 2 + pkg/signalmeow/senderkey.go | 18 ++++++ pkg/signalmeow/store/sender_key_store.go | 10 ++++ 4 files changed, 103 insertions(+) create mode 100644 pkg/connector/commands.go diff --git a/pkg/connector/commands.go b/pkg/connector/commands.go new file mode 100644 index 0000000..0be2370 --- /dev/null +++ b/pkg/connector/commands.go @@ -0,0 +1,73 @@ +// mautrix-signal - A Matrix-Signal puppeting bridge. +// Copyright (C) 2025 Tulir Asokan +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +package connector + +import ( + "errors" + + "maunium.net/go/mautrix/bridgev2" + "maunium.net/go/mautrix/bridgev2/commands" + "maunium.net/go/mautrix/bridgev2/networkid" + + "go.mau.fi/mautrix-signal/pkg/signalid" +) + +var CmdDiscardSenderKey = &commands.FullHandler{ + Func: fnDiscardSenderKey, + Name: "discard-sender-key", + Help: commands.HelpMeta{ + Section: commands.HelpSectionChats, + Description: "Discard the Signal-side sender key in the current group", + Args: "[_login ID_]", + }, + RequiresPortal: true, + RequiresLogin: true, +} + +func fnDiscardSenderKey(ce *commands.Event) { + _, groupID, _ := signalid.ParsePortalID(ce.Portal.ID) + if groupID == "" { + ce.Reply("This command can only be used in group chat portals") + return + } + var login *bridgev2.UserLogin + if len(ce.Args) > 0 { + login = ce.Bridge.GetCachedUserLoginByID(networkid.UserLoginID(ce.Args[0])) + if login == nil || login.UserMXID != ce.User.MXID { + ce.Reply("Login not found") + return + } + } else { + var err error + login, _, err = ce.Portal.FindPreferredLogin(ce.Ctx, ce.User, false) + if errors.Is(err, bridgev2.ErrNotLoggedIn) { + ce.Reply("You're not logged in in this portal") + return + } else if err != nil { + ce.Log.Err(err).Msg("Failed to find preferred login for portal") + ce.Reply("Failed to find preferred login for portal") + return + } + } + distributionID, err := login.Client.(*SignalClient).Client.ResetSenderKey(ce.Ctx, groupID) + if err != nil { + ce.Log.Err(err).Msg("Failed to reset sender key") + ce.Reply("Failed to reset sender key") + } else { + ce.Reply("Reset sender key with distribution ID %s", distributionID) + } +} diff --git a/pkg/connector/connector.go b/pkg/connector/connector.go index 59f8640..0debb30 100644 --- a/pkg/connector/connector.go +++ b/pkg/connector/connector.go @@ -26,6 +26,7 @@ import ( "go.mau.fi/util/dbutil" "go.mau.fi/util/exsync" "maunium.net/go/mautrix/bridgev2" + "maunium.net/go/mautrix/bridgev2/commands" "maunium.net/go/mautrix/bridgev2/networkid" "maunium.net/go/mautrix/event" "maunium.net/go/mautrix/id" @@ -64,6 +65,7 @@ func (s *SignalConnector) Init(bridge *bridgev2.Bridge) { s.MsgConv.LocationFormat = s.Config.LocationFormat s.MsgConv.DisappearViewOnce = s.Config.DisappearViewOnce s.MsgConv.ExtEvPolls = s.Config.ExtEvPolls + bridge.Commands.(*commands.Processor).AddHandlers(CmdDiscardSenderKey) } func (s *SignalConnector) SetMaxFileSize(maxSize int64) { diff --git a/pkg/signalmeow/senderkey.go b/pkg/signalmeow/senderkey.go index b676d6c..1c0da8a 100644 --- a/pkg/signalmeow/senderkey.go +++ b/pkg/signalmeow/senderkey.go @@ -46,6 +46,24 @@ const ( contextKeyEncryptionLock contextKey = iota ) +func (cli *Client) ResetSenderKey(ctx context.Context, groupID types.GroupIdentifier) (uuid.UUID, error) { + cli.encryptionLock.Lock() + defer cli.encryptionLock.Unlock() + info, err := cli.Store.SenderKeyStore.GetSenderKeyInfo(ctx, groupID) + if err != nil { + return uuid.Nil, fmt.Errorf("failed to get sender key info: %w", err) + } else if info == nil { + return uuid.Nil, nil + } else if myAddress, err := cli.Store.ACIServiceID().Address(uint(cli.Store.DeviceID)); err != nil { + return uuid.Nil, fmt.Errorf("failed to get own address: %w", err) + } else if err = cli.Store.SenderKeyStore.DeleteSenderKey(ctx, myAddress, info.DistributionID); err != nil { + return info.DistributionID, fmt.Errorf("failed to delete sender key: %w", err) + } else if err = cli.Store.SenderKeyStore.DeleteSenderKeyInfo(ctx, groupID); err != nil { + return info.DistributionID, fmt.Errorf("failed to delete sender key info: %w", err) + } + return info.DistributionID, nil +} + func (cli *Client) sendToGroupWithSenderKey( ctx context.Context, groupID *libsignalgo.GroupIdentifier, diff --git a/pkg/signalmeow/store/sender_key_store.go b/pkg/signalmeow/store/sender_key_store.go index a38e389..1334066 100644 --- a/pkg/signalmeow/store/sender_key_store.go +++ b/pkg/signalmeow/store/sender_key_store.go @@ -34,6 +34,7 @@ type SenderKeyStore interface { libsignalgo.SenderKeyStore DeleteSenderKey(ctx context.Context, address *libsignalgo.Address, distributionID uuid.UUID) error GetSenderKeyInfo(ctx context.Context, groupID types.GroupIdentifier) (*SenderKeyInfo, error) + DeleteSenderKeyInfo(ctx context.Context, groupID types.GroupIdentifier) error PutSenderKeyInfo(ctx context.Context, groupID types.GroupIdentifier, info *SenderKeyInfo) error } @@ -55,6 +56,10 @@ const ( ON CONFLICT (account_id, group_id) DO UPDATE SET distribution_id=excluded.distribution_id, shared_with=excluded.shared_with ` + deleteSenderKeyInfoQuery = ` + DELETE FROM signalmeow_outbound_sender_key_info + WHERE account_id=$1 AND group_id=$2 + ` ) func scanSenderKey(row dbutil.Scannable) (*libsignalgo.SenderKeyRecord, error) { @@ -135,3 +140,8 @@ func (s *sqlStore) PutSenderKeyInfo(ctx context.Context, groupID types.GroupIden _, err := s.db.Exec(ctx, putSenderKeyInfoQuery, s.AccountID, groupID, info.DistributionID, dbutil.JSON{Data: info}) return err } + +func (s *sqlStore) DeleteSenderKeyInfo(ctx context.Context, groupID types.GroupIdentifier) error { + _, err := s.db.Exec(ctx, deleteSenderKeyInfoQuery, s.AccountID, groupID) + return err +} From 1d43ea8c003775ee9816c53b3cb89fc62dff22d9 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Tue, 9 Dec 2025 12:41:39 +0200 Subject: [PATCH 485/580] client: add connecting bridge state --- pkg/connector/client.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/pkg/connector/client.go b/pkg/connector/client.go index 233ad91..c1ad75c 100644 --- a/pkg/connector/client.go +++ b/pkg/connector/client.go @@ -298,6 +298,9 @@ func (s *SignalClient) postLoginConnect() { } func (s *SignalClient) tryConnect(ctx context.Context, retryCount int, doSync bool) { + if retryCount == 0 { + s.UserLogin.BridgeState.Send(status.BridgeState{StateEvent: status.StateConnecting}) + } ch, err := s.Client.StartReceiveLoops(ctx) if err != nil { zerolog.Ctx(ctx).Err(err).Msg("Failed to start receive loops") From cb678dd2f0b7cc3929671830bf9f2606713a7d64 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Tue, 9 Dec 2025 16:42:57 +0200 Subject: [PATCH 486/580] handle*,chatinfo: implement new interface for message requests --- go.mod | 4 +- go.sum | 8 +-- pkg/connector/capabilities.go | 6 +- pkg/connector/chatinfo.go | 6 +- pkg/connector/handlematrix.go | 110 +++++++++++++++++++++++++++---- pkg/connector/handlesignal.go | 32 +++++++++ pkg/signalmeow/events/message.go | 29 +++++--- pkg/signalmeow/receiving.go | 26 ++++++++ pkg/signalmeow/sending.go | 7 +- 9 files changed, 194 insertions(+), 34 deletions(-) diff --git a/go.mod b/go.mod index 35a4fb2..03c6635 100644 --- a/go.mod +++ b/go.mod @@ -14,13 +14,13 @@ require ( github.com/rs/zerolog v1.34.0 github.com/stretchr/testify v1.11.1 github.com/tidwall/gjson v1.18.0 - go.mau.fi/util v0.9.4-0.20251128195053-c7fab4d88a04 + go.mau.fi/util v0.9.4-0.20251206205611-85e6fd6551e0 golang.org/x/crypto v0.45.0 golang.org/x/exp v0.0.0-20251125195548-87e1e737ad39 golang.org/x/net v0.47.0 google.golang.org/protobuf v1.36.10 gopkg.in/yaml.v3 v3.0.1 - maunium.net/go/mautrix v0.26.1-0.20251202132204-2eeece694254 + maunium.net/go/mautrix v0.26.1-0.20251209144156-31579be20ad8 ) require ( diff --git a/go.sum b/go.sum index cc4b594..e085181 100644 --- a/go.sum +++ b/go.sum @@ -65,8 +65,8 @@ github.com/tidwall/sjson v1.2.5 h1:kLy8mja+1c9jlljvWTlSazM7cKDRfJuR/bOJhcY5NcY= github.com/tidwall/sjson v1.2.5/go.mod h1:Fvgq9kS/6ociJEDnK0Fk1cpYF4FIW6ZF7LAe+6jwd28= github.com/yuin/goldmark v1.7.13 h1:GPddIs617DnBLFFVJFgpo1aBfe/4xcvMc3SB5t/D0pA= github.com/yuin/goldmark v1.7.13/go.mod h1:ip/1k0VRfGynBgxOz0yCqHrbZXhcjxyuS66Brc7iBKg= -go.mau.fi/util v0.9.4-0.20251128195053-c7fab4d88a04 h1:1xsqu1gqwLUBEolvrsURhj/A3e9GACg95i8gITI0Be0= -go.mau.fi/util v0.9.4-0.20251128195053-c7fab4d88a04/go.mod h1:viDmhBOAFfcqDdKSk53EPJV3N4Mi8Jst5/ahGJ/vwsA= +go.mau.fi/util v0.9.4-0.20251206205611-85e6fd6551e0 h1:ESebxPGULuuxxcZigjcBFyyU62tiyY6ivtX17P4BkvY= +go.mau.fi/util v0.9.4-0.20251206205611-85e6fd6551e0/go.mod h1:viDmhBOAFfcqDdKSk53EPJV3N4Mi8Jst5/ahGJ/vwsA= go.mau.fi/zeroconfig v0.2.0 h1:e/OGEERqVRRKlgaro7E6bh8xXiKFSXB3eNNIud7FUjU= go.mau.fi/zeroconfig v0.2.0/go.mod h1:J0Vn0prHNOm493oZoQ84kq83ZaNCYZnq+noI1b1eN8w= golang.org/x/crypto v0.45.0 h1:jMBrvKuj23MTlT0bQEOBcAE0mjg8mK9RXFhRH6nyF3Q= @@ -97,5 +97,5 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= maunium.net/go/mauflag v1.0.0 h1:YiaRc0tEI3toYtJMRIfjP+jklH45uDHtT80nUamyD4M= maunium.net/go/mauflag v1.0.0/go.mod h1:nLivPOpTpHnpzEh8jEdSL9UqO9+/KBJFmNRlwKfkPeA= -maunium.net/go/mautrix v0.26.1-0.20251202132204-2eeece694254 h1:rsc4H0sZVban6xQeIS6err1YangUiK5WzVfTS6s03ms= -maunium.net/go/mautrix v0.26.1-0.20251202132204-2eeece694254/go.mod h1:NaesYcOQWFDbixVYywCVS+Twlzab9hOUpFNlCBlvciE= +maunium.net/go/mautrix v0.26.1-0.20251209144156-31579be20ad8 h1:dbv3iOml42fzC9l1/M2nWPmUPhsesvMJJjgw9ArdnmQ= +maunium.net/go/mautrix v0.26.1-0.20251209144156-31579be20ad8/go.mod h1:pzwIT42s+BhBjEYovmcOt69VlNW2RkJ6pCyZjYQHKIc= diff --git a/pkg/connector/capabilities.go b/pkg/connector/capabilities.go index 97affb9..e791324 100644 --- a/pkg/connector/capabilities.go +++ b/pkg/connector/capabilities.go @@ -38,7 +38,7 @@ func supportedIfFFmpeg() event.CapabilitySupportLevel { } func capID() string { - base := "fi.mau.signal.capabilities.2025_10_28" + base := "fi.mau.signal.capabilities.2025_12_09" if ffmpeg.Supported() { return base + "+ffmpeg" } @@ -171,6 +171,10 @@ var signalCaps = &event.RoomFeatures{ TypingNotifications: true, DeleteChat: true, + MessageRequest: &event.MessageRequestFeatures{ + AcceptWithMessage: event.CapLevelPartialSupport, + AcceptWithButton: event.CapLevelFullySupported, + }, } var signalDisappearingCap = &event.DisappearingTimerCapability{ diff --git a/pkg/connector/chatinfo.go b/pkg/connector/chatinfo.go index c8d6c2b..7e5a983 100644 --- a/pkg/connector/chatinfo.go +++ b/pkg/connector/chatinfo.go @@ -480,9 +480,9 @@ func (s *SignalClient) makeCreateDMResponse(ctx context.Context, recipient *type Members: members, Type: ptr.Ptr(database.RoomTypeDM), - CanBackfill: backupChat != nil, - - ExtraUpdates: updatePortalSyncMeta, + MessageRequest: ptr.Ptr(recipient.ACI != uuid.Nil && recipient.NeedsPNISignature), + CanBackfill: backupChat != nil, + ExtraUpdates: updatePortalSyncMeta, }, } } diff --git a/pkg/connector/handlematrix.go b/pkg/connector/handlematrix.go index 25d3f53..0c47a08 100644 --- a/pkg/connector/handlematrix.go +++ b/pkg/connector/handlematrix.go @@ -43,18 +43,19 @@ import ( ) var ( - _ bridgev2.EditHandlingNetworkAPI = (*SignalClient)(nil) - _ bridgev2.ReactionHandlingNetworkAPI = (*SignalClient)(nil) - _ bridgev2.RedactionHandlingNetworkAPI = (*SignalClient)(nil) - _ bridgev2.ReadReceiptHandlingNetworkAPI = (*SignalClient)(nil) - _ bridgev2.TypingHandlingNetworkAPI = (*SignalClient)(nil) - _ bridgev2.RoomNameHandlingNetworkAPI = (*SignalClient)(nil) - _ bridgev2.RoomAvatarHandlingNetworkAPI = (*SignalClient)(nil) - _ bridgev2.RoomTopicHandlingNetworkAPI = (*SignalClient)(nil) - _ bridgev2.ChatViewingNetworkAPI = (*SignalClient)(nil) - _ bridgev2.DisappearTimerChangingNetworkAPI = (*SignalClient)(nil) - _ bridgev2.DeleteChatHandlingNetworkAPI = (*SignalClient)(nil) - _ bridgev2.PollHandlingNetworkAPI = (*SignalClient)(nil) + _ bridgev2.EditHandlingNetworkAPI = (*SignalClient)(nil) + _ bridgev2.ReactionHandlingNetworkAPI = (*SignalClient)(nil) + _ bridgev2.RedactionHandlingNetworkAPI = (*SignalClient)(nil) + _ bridgev2.ReadReceiptHandlingNetworkAPI = (*SignalClient)(nil) + _ bridgev2.TypingHandlingNetworkAPI = (*SignalClient)(nil) + _ bridgev2.RoomNameHandlingNetworkAPI = (*SignalClient)(nil) + _ bridgev2.RoomAvatarHandlingNetworkAPI = (*SignalClient)(nil) + _ bridgev2.RoomTopicHandlingNetworkAPI = (*SignalClient)(nil) + _ bridgev2.ChatViewingNetworkAPI = (*SignalClient)(nil) + _ bridgev2.DisappearTimerChangingNetworkAPI = (*SignalClient)(nil) + _ bridgev2.DeleteChatHandlingNetworkAPI = (*SignalClient)(nil) + _ bridgev2.PollHandlingNetworkAPI = (*SignalClient)(nil) + _ bridgev2.MessageRequestAcceptingNetworkAPI = (*SignalClient)(nil) ) func (s *SignalClient) sendMessage(ctx context.Context, portalID networkid.PortalID, content *signalpb.Content) error { @@ -705,6 +706,14 @@ func (s *SignalClient) HandleMatrixDeleteChat(ctx context.Context, msg *bridgev2 return fmt.Errorf("failed to parse portal ID: %w", err) } + if msg.Content.FromMessageRequest { + // TODO block and delete support? + err = s.syncMessageRequestResponse(ctx, msg.Portal, signalpb.SyncMessage_MessageRequestResponse_DELETE) + if err != nil { + return fmt.Errorf("failed to send message request delete sync: %w", err) + } + } + // Build ConversationIdentifier based on portal type var conversationID *signalpb.ConversationIdentifier if groupID == "" { @@ -832,3 +841,80 @@ func (s *SignalClient) HandleMatrixPollVote(ctx context.Context, msg *bridgev2.M } return s.doSendMessage(ctx, &msg.MatrixMessage, converted, nil) } + +func (s *SignalClient) syncMessageRequestResponse( + ctx context.Context, + portal *bridgev2.Portal, + respType signalpb.SyncMessage_MessageRequestResponse_Type, +) error { + userID, groupID, err := signalid.ParsePortalID(portal.ID) + if err != nil { + return err + } + accept := &signalpb.SyncMessage_MessageRequestResponse{ + Type: respType.Enum(), + } + if groupID != "" { + gidBytes, err := groupID.Bytes() + if err != nil { + return fmt.Errorf("failed to parse group ID: %w", err) + } + accept.GroupId = gidBytes[:] + } else if userID.Type == libsignalgo.ServiceIDTypeACI { + accept.ThreadAci = ptr.Ptr(userID.UUID.String()) + } else { + return fmt.Errorf("invalid portal ID for message request response: %s", portal.ID) + } + res := s.Client.SendMessage(ctx, libsignalgo.NewACIServiceID(s.Client.Store.ACI), &signalpb.Content{ + SyncMessage: &signalpb.SyncMessage{ + MessageRequestResponse: accept, + }, + }) + if !res.WasSuccessful { + return res.Error + } + return nil +} + +func (s *SignalClient) HandleMatrixAcceptMessageRequest(ctx context.Context, msg *bridgev2.MatrixAcceptMessageRequest) error { + userID, _, err := signalid.ParsePortalID(msg.Portal.ID) + if err != nil { + return err + } + err = s.syncMessageRequestResponse(ctx, msg.Portal, signalpb.SyncMessage_MessageRequestResponse_ACCEPT) + if err != nil { + return fmt.Errorf("failed to sync message request acceptance: %w", err) + } + if userID.Type == libsignalgo.ServiceIDTypeACI { + profileKey, err := s.Client.ProfileKeyForSignalID(ctx, s.Client.Store.ACI) + if err != nil { + return fmt.Errorf("failed to get own profile key: %w", err) + } + var pniSig *signalpb.PniSignatureMessage + if s.Client.Store.AccountRecord.GetPhoneNumberSharingMode() == signalpb.AccountRecord_EVERYBODY { + sig, err := s.Client.Store.PNIIdentityKeyPair.SignAlternateIdentity(s.Client.Store.ACIIdentityKeyPair.GetIdentityKey()) + if err != nil { + return fmt.Errorf("failed to generate PNI signature: %w", err) + } + pniSig = &signalpb.PniSignatureMessage{ + Pni: s.Client.Store.PNI[:], + Signature: sig, + } + } + res := s.Client.SendMessage(ctx, userID, &signalpb.Content{ + DataMessage: &signalpb.DataMessage{ + Flags: proto.Uint32(uint32(signalpb.DataMessage_PROFILE_KEY_UPDATE)), + ProfileKey: profileKey.Slice(), + Timestamp: proto.Uint64(getTimestampForEvent(msg.InputTransactionID, msg.Event, msg.OrigSender)), + + RequiredProtocolVersion: proto.Uint32(0), + }, + PniSignatureMessage: pniSig, + }) + if !res.WasSuccessful { + return fmt.Errorf("failed to share profile key to accept message request: %w", res.Error) + } + // TODO send read receipts too? + } + return nil +} diff --git a/pkg/connector/handlesignal.go b/pkg/connector/handlesignal.go index 0293a53..6e0e302 100644 --- a/pkg/connector/handlesignal.go +++ b/pkg/connector/handlesignal.go @@ -26,6 +26,7 @@ import ( "github.com/google/uuid" "github.com/rs/zerolog" "go.mau.fi/util/exzerolog" + "go.mau.fi/util/ptr" "maunium.net/go/mautrix/bridgev2" "maunium.net/go/mautrix/bridgev2/database" "maunium.net/go/mautrix/bridgev2/networkid" @@ -52,6 +53,8 @@ func (s *SignalClient) handleSignalEvent(rawEvt events.SignalEvent) bool { return s.handleSignalReadSelf(evt) case *events.DeleteForMe: return s.handleSignalDeleteForMe(evt) + case *events.MessageRequestResponse: + return s.handleSignalMessageRequestResponse(evt) case *events.Call: return s.Main.Bridge.QueueRemoteEvent(s.UserLogin, s.wrapCallEvent(evt)).Success case *events.ContactList: @@ -620,6 +623,35 @@ func (s *SignalClient) handleSignalDeleteForMe(evt *events.DeleteForMe) bool { return true } +func (s *SignalClient) handleSignalMessageRequestResponse(evt *events.MessageRequestResponse) bool { + if evt.Type != signalpb.SyncMessage_MessageRequestResponse_ACCEPT { + // TODO do we need to do anything with blocks/deletes here or are they sent as normal delete events? + return true + } + var portalKey networkid.PortalKey + if evt.GroupID != nil { + portalKey = s.makePortalKey(evt.GroupID.String()) + } else if evt.ThreadACI != uuid.Nil { + portalKey = s.makeDMPortalKey(libsignalgo.NewACIServiceID(evt.ThreadACI)) + } else { + return true + } + res := s.UserLogin.QueueRemoteEvent(&simplevent.ChatInfoChange{ + EventMeta: simplevent.EventMeta{ + Type: bridgev2.RemoteEventChatInfoChange, + PortalKey: portalKey, + Timestamp: time.UnixMilli(int64(evt.Timestamp)), + StreamOrder: int64(evt.Timestamp), + }, + ChatInfoChange: &bridgev2.ChatInfoChange{ + ChatInfo: &bridgev2.ChatInfo{ + MessageRequest: ptr.Ptr(false), + }, + }, + }) + return res.Success +} + func (s *SignalClient) handleSignalACIFound(evt *events.ACIFound) { log := s.UserLogin.Log.With(). Str("action", "handle aci found"). diff --git a/pkg/signalmeow/events/message.go b/pkg/signalmeow/events/message.go index 0642c33..7d3732a 100644 --- a/pkg/signalmeow/events/message.go +++ b/pkg/signalmeow/events/message.go @@ -28,16 +28,17 @@ type SignalEvent interface { isSignalEvent() } -func (*ChatEvent) isSignalEvent() {} -func (*DecryptionError) isSignalEvent() {} -func (*Receipt) isSignalEvent() {} -func (*ReadSelf) isSignalEvent() {} -func (*Call) isSignalEvent() {} -func (*ContactList) isSignalEvent() {} -func (*ACIFound) isSignalEvent() {} -func (*DeleteForMe) isSignalEvent() {} -func (*QueueEmpty) isSignalEvent() {} -func (*LoggedOut) isSignalEvent() {} +func (*ChatEvent) isSignalEvent() {} +func (*DecryptionError) isSignalEvent() {} +func (*Receipt) isSignalEvent() {} +func (*ReadSelf) isSignalEvent() {} +func (*Call) isSignalEvent() {} +func (*ContactList) isSignalEvent() {} +func (*ACIFound) isSignalEvent() {} +func (*DeleteForMe) isSignalEvent() {} +func (*MessageRequestResponse) isSignalEvent() {} +func (*QueueEmpty) isSignalEvent() {} +func (*LoggedOut) isSignalEvent() {} type MessageInfo struct { Sender uuid.UUID @@ -89,6 +90,14 @@ type DeleteForMe struct { *signalpb.SyncMessage_DeleteForMe } +type MessageRequestResponse struct { + Timestamp uint64 + ThreadACI uuid.UUID + GroupID *libsignalgo.GroupIdentifier + Type signalpb.SyncMessage_MessageRequestResponse_Type + Raw *signalpb.SyncMessage_MessageRequestResponse +} + type QueueEmpty struct{} type LoggedOut struct{ Error error } diff --git a/pkg/signalmeow/receiving.go b/pkg/signalmeow/receiving.go index b5ed96d..8cc0be7 100644 --- a/pkg/signalmeow/receiving.go +++ b/pkg/signalmeow/receiving.go @@ -778,6 +778,32 @@ func (cli *Client) handleSyncMessage(ctx context.Context, msg *signalpb.SyncMess SyncMessage_DeleteForMe: msg.DeleteForMe, }) } + if msg.MessageRequestResponse != nil { + aciUUID, _ := uuid.Parse(msg.MessageRequestResponse.GetThreadAci()) + if aciUUID != uuid.Nil && msg.MessageRequestResponse.GetType() == signalpb.SyncMessage_MessageRequestResponse_ACCEPT { + _, err := cli.Store.RecipientStore.LoadAndUpdateRecipient(ctx, aciUUID, uuid.Nil, func(recipient *types.Recipient) (changed bool, err error) { + if recipient.NeedsPNISignature { + recipient.NeedsPNISignature = false + return true, nil + } + return false, nil + }) + if err != nil { + log.Err(err).Msg("Failed to clear needs_pni_signature flag after message request accept") + } + } + var groupID *libsignalgo.GroupIdentifier + if len(msg.MessageRequestResponse.GroupId) == libsignalgo.GroupIdentifierLength { + groupID = (*libsignalgo.GroupIdentifier)(msg.MessageRequestResponse.GroupId) + } + handlerSuccess = cli.handleEvent(&events.MessageRequestResponse{ + Timestamp: envelope.GetTimestamp(), + ThreadACI: aciUUID, + GroupID: groupID, + Type: msg.MessageRequestResponse.GetType(), + Raw: msg.MessageRequestResponse, + }) + } return } diff --git a/pkg/signalmeow/sending.go b/pkg/signalmeow/sending.go index 0ea55f9..fa0818a 100644 --- a/pkg/signalmeow/sending.go +++ b/pkg/signalmeow/sending.go @@ -708,7 +708,7 @@ func (cli *Client) SendMessage(ctx context.Context, recipientID libsignalgo.Serv isTypingOrReceipt := content.TypingMessage != nil || content.ReceiptMessage != nil recipientData, err := cli.Store.RecipientStore.LoadAndUpdateRecipient(ctx, aci, pni, func(recipientData *types.Recipient) (changed bool, err error) { needsPNISignature = recipientID.Type == libsignalgo.ServiceIDTypeACI && recipientData.NeedsPNISignature - if needsPNISignature && !isTypingOrReceipt { + if needsPNISignature && !isTypingOrReceipt && content.PniSignatureMessage == nil { zerolog.Ctx(ctx).Debug(). Stringer("recipient", recipientID). Msg("Including PNI identity in message") @@ -722,6 +722,9 @@ func (cli *Client) SendMessage(ctx context.Context, recipientID libsignalgo.Serv Signature: sig, } return true, nil + } else if needsPNISignature && content.PniSignatureMessage != nil { + recipientData.NeedsPNISignature = false + return true, nil } return false, nil }) @@ -842,7 +845,7 @@ func (cli *Client) sendContent( ctx = log.WithContext(ctx) // If it's a data message, add our profile key - if content.DataMessage != nil { + if content.DataMessage != nil && content.DataMessage.ProfileKey == nil { profileKey, err := cli.ProfileKeyForSignalID(ctx, cli.Store.ACI) if err != nil { log.Err(err).Msg("Error getting profile key, not adding to outgoing message") From 3b4b6cf753dffca4bf2f6015d16b8e312924985b Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Wed, 10 Dec 2025 18:30:00 +0200 Subject: [PATCH 487/580] msgconv/from-signal: fix panic if poll vote target isn't found --- pkg/msgconv/from-signal.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/pkg/msgconv/from-signal.go b/pkg/msgconv/from-signal.go index 9392616..c8ac40e 100644 --- a/pkg/msgconv/from-signal.go +++ b/pkg/msgconv/from-signal.go @@ -714,6 +714,9 @@ func (mc *MessageConverter) convertPollVoteToMatrix(ctx context.Context, vote *s if err != nil { zerolog.Ctx(ctx).Err(err).Msg("Failed to get poll vote target message") return invalidPollVote + } else if pollMessage == nil { + zerolog.Ctx(ctx).Warn().Msg("Poll vote target message not found") + return invalidPollVote } mxOptionIDs := pollMessage.Metadata.(*signalid.MessageMetadata).MatrixPollOptionIDs optionIDs := make([]string, len(vote.GetOptionIndexes())) From c79057718a98a1c18089a8d3dc8daef6a7f120c1 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Thu, 11 Dec 2025 14:18:00 +0200 Subject: [PATCH 488/580] libsignal: update to v0.86.8 --- pkg/libsignalgo/libsignal | 2 +- pkg/libsignalgo/version.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pkg/libsignalgo/libsignal b/pkg/libsignalgo/libsignal index 5a64e17..ace4048 160000 --- a/pkg/libsignalgo/libsignal +++ b/pkg/libsignalgo/libsignal @@ -1 +1 @@ -Subproject commit 5a64e17ed4450eaf5fe29bfa611c9838736ac1a6 +Subproject commit ace404879f5dc146a512d88f696115715095a841 diff --git a/pkg/libsignalgo/version.go b/pkg/libsignalgo/version.go index dbb024d..f690184 100644 --- a/pkg/libsignalgo/version.go +++ b/pkg/libsignalgo/version.go @@ -2,4 +2,4 @@ package libsignalgo -const Version = "v0.86.4" +const Version = "v0.86.8" From 2c78df26384716d7c338a59d5f928395f8607089 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Thu, 11 Dec 2025 15:31:47 +0200 Subject: [PATCH 489/580] changelog: update --- CHANGELOG.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4f147c6..6785804 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,13 @@ +# v25.12 (unreleased) + +* Updated libsignal to v0.86.8. +* Added support for dropping incoming DMs from blocked contacts on Signal. +* Added support for sender key encryption when sending to groups, which makes + sending much faster and enables sending typing notifications. +* Added support for encryption retry receipts. +* Fixed bugs with handling poll votes. +* Fixed history transfer option not showing up when pairing with Signal Android. + # v25.11 * Updated libsignal to v0.86.4. From 7f8b0b7596566af3b973eaa9c7128e41861f7ed8 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Thu, 11 Dec 2025 16:27:19 +0200 Subject: [PATCH 490/580] signalmeow/store: handle message request and unregistered status from backup --- pkg/signalmeow/store/backup_store.go | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/pkg/signalmeow/store/backup_store.go b/pkg/signalmeow/store/backup_store.go index fb5d5ff..2b1adf7 100644 --- a/pkg/signalmeow/store/backup_store.go +++ b/pkg/signalmeow/store/backup_store.go @@ -161,11 +161,13 @@ func (s *sqlStore) AddBackupRecipient(ctx context.Context, recipient *backuppb.R if dest.Contact.ProfileGivenName != nil || dest.Contact.ProfileFamilyName != nil { recipient.Profile.Name = strings.TrimSpace(fmt.Sprintf("%s %s", dest.Contact.GetProfileGivenName(), dest.Contact.GetProfileFamilyName())) } + recipient.NeedsPNISignature = dest.Contact.GetVisibility() == backuppb.Contact_HIDDEN_MESSAGE_REQUEST recipient.Blocked = dest.Contact.Blocked changed = oldRecipient.E164 != recipient.E164 || oldRecipient.Profile.Key != recipient.Profile.Key || oldRecipient.Profile.Name != recipient.Profile.Name || - oldRecipient.Blocked != recipient.Blocked + oldRecipient.Blocked != recipient.Blocked || + oldRecipient.NeedsPNISignature != recipient.NeedsPNISignature return }) if err != nil { @@ -177,6 +179,9 @@ func (s *sqlStore) AddBackupRecipient(ctx context.Context, recipient *backuppb.R Any("entry", dest.Contact). Msg("Both ACI and PNI are invalid for registered contact recipient") } + if aci != uuid.Nil { + s.MarkUnregistered(ctx, libsignalgo.NewACIServiceID(aci), dest.Contact.GetNotRegistered() != nil) + } case *backuppb.Recipient_Group: groupMasterKey = types.SerializedGroupMasterKey(base64.StdEncoding.EncodeToString(dest.Group.MasterKey)) if len(dest.Group.MasterKey) == libsignalgo.GroupMasterKeyLength { From e4ad808ad0b1f984a352affd401d634bd079f60c Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Thu, 11 Dec 2025 16:28:39 +0200 Subject: [PATCH 491/580] dependencies: update --- go.mod | 20 ++++++++++---------- go.sum | 36 ++++++++++++++++++------------------ 2 files changed, 28 insertions(+), 28 deletions(-) diff --git a/go.mod b/go.mod index 03c6635..33f2f4d 100644 --- a/go.mod +++ b/go.mod @@ -2,7 +2,7 @@ module go.mau.fi/mautrix-signal go 1.24.0 -toolchain go1.25.4 +toolchain go1.25.5 tool go.mau.fi/util/cmd/maubuild @@ -14,13 +14,13 @@ require ( github.com/rs/zerolog v1.34.0 github.com/stretchr/testify v1.11.1 github.com/tidwall/gjson v1.18.0 - go.mau.fi/util v0.9.4-0.20251206205611-85e6fd6551e0 - golang.org/x/crypto v0.45.0 - golang.org/x/exp v0.0.0-20251125195548-87e1e737ad39 - golang.org/x/net v0.47.0 + go.mau.fi/util v0.9.4-0.20251211121531-f6527b4882ae + golang.org/x/crypto v0.46.0 + golang.org/x/exp v0.0.0-20251209150349-8475f28825e9 + golang.org/x/net v0.48.0 google.golang.org/protobuf v1.36.10 gopkg.in/yaml.v3 v3.0.1 - maunium.net/go/mautrix v0.26.1-0.20251209144156-31579be20ad8 + maunium.net/go/mautrix v0.26.1-0.20251211121745-efd4136c7a93 ) require ( @@ -42,10 +42,10 @@ require ( github.com/tidwall/sjson v1.2.5 // indirect github.com/yuin/goldmark v1.7.13 // indirect go.mau.fi/zeroconfig v0.2.0 // indirect - golang.org/x/mod v0.30.0 // indirect - golang.org/x/sync v0.18.0 // indirect - golang.org/x/sys v0.38.0 // indirect - golang.org/x/text v0.31.0 // indirect + golang.org/x/mod v0.31.0 // indirect + golang.org/x/sync v0.19.0 // indirect + golang.org/x/sys v0.39.0 // indirect + golang.org/x/text v0.32.0 // indirect gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect gopkg.in/natefinch/lumberjack.v2 v2.2.1 // indirect maunium.net/go/mauflag v1.0.0 // indirect diff --git a/go.sum b/go.sum index e085181..090940f 100644 --- a/go.sum +++ b/go.sum @@ -65,27 +65,27 @@ github.com/tidwall/sjson v1.2.5 h1:kLy8mja+1c9jlljvWTlSazM7cKDRfJuR/bOJhcY5NcY= github.com/tidwall/sjson v1.2.5/go.mod h1:Fvgq9kS/6ociJEDnK0Fk1cpYF4FIW6ZF7LAe+6jwd28= github.com/yuin/goldmark v1.7.13 h1:GPddIs617DnBLFFVJFgpo1aBfe/4xcvMc3SB5t/D0pA= github.com/yuin/goldmark v1.7.13/go.mod h1:ip/1k0VRfGynBgxOz0yCqHrbZXhcjxyuS66Brc7iBKg= -go.mau.fi/util v0.9.4-0.20251206205611-85e6fd6551e0 h1:ESebxPGULuuxxcZigjcBFyyU62tiyY6ivtX17P4BkvY= -go.mau.fi/util v0.9.4-0.20251206205611-85e6fd6551e0/go.mod h1:viDmhBOAFfcqDdKSk53EPJV3N4Mi8Jst5/ahGJ/vwsA= +go.mau.fi/util v0.9.4-0.20251211121531-f6527b4882ae h1:tocQOutgT+Z/V6w668Jpk3D5942K5p25XmRAvXg8s2E= +go.mau.fi/util v0.9.4-0.20251211121531-f6527b4882ae/go.mod h1:OwI76F1QINxtH/TOydGAAj5/VvtPG0RnZzB41rtnKcA= go.mau.fi/zeroconfig v0.2.0 h1:e/OGEERqVRRKlgaro7E6bh8xXiKFSXB3eNNIud7FUjU= go.mau.fi/zeroconfig v0.2.0/go.mod h1:J0Vn0prHNOm493oZoQ84kq83ZaNCYZnq+noI1b1eN8w= -golang.org/x/crypto v0.45.0 h1:jMBrvKuj23MTlT0bQEOBcAE0mjg8mK9RXFhRH6nyF3Q= -golang.org/x/crypto v0.45.0/go.mod h1:XTGrrkGJve7CYK7J8PEww4aY7gM3qMCElcJQ8n8JdX4= -golang.org/x/exp v0.0.0-20251125195548-87e1e737ad39 h1:DHNhtq3sNNzrvduZZIiFyXWOL9IWaDPHqTnLJp+rCBY= -golang.org/x/exp v0.0.0-20251125195548-87e1e737ad39/go.mod h1:46edojNIoXTNOhySWIWdix628clX9ODXwPsQuG6hsK0= -golang.org/x/mod v0.30.0 h1:fDEXFVZ/fmCKProc/yAXXUijritrDzahmwwefnjoPFk= -golang.org/x/mod v0.30.0/go.mod h1:lAsf5O2EvJeSFMiBxXDki7sCgAxEUcZHXoXMKT4GJKc= -golang.org/x/net v0.47.0 h1:Mx+4dIFzqraBXUugkia1OOvlD6LemFo1ALMHjrXDOhY= -golang.org/x/net v0.47.0/go.mod h1:/jNxtkgq5yWUGYkaZGqo27cfGZ1c5Nen03aYrrKpVRU= -golang.org/x/sync v0.18.0 h1:kr88TuHDroi+UVf+0hZnirlk8o8T+4MrK6mr60WkH/I= -golang.org/x/sync v0.18.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= +golang.org/x/crypto v0.46.0 h1:cKRW/pmt1pKAfetfu+RCEvjvZkA9RimPbh7bhFjGVBU= +golang.org/x/crypto v0.46.0/go.mod h1:Evb/oLKmMraqjZ2iQTwDwvCtJkczlDuTmdJXoZVzqU0= +golang.org/x/exp v0.0.0-20251209150349-8475f28825e9 h1:MDfG8Cvcqlt9XXrmEiD4epKn7VJHZO84hejP9Jmp0MM= +golang.org/x/exp v0.0.0-20251209150349-8475f28825e9/go.mod h1:EPRbTFwzwjXj9NpYyyrvenVh9Y+GFeEvMNh7Xuz7xgU= +golang.org/x/mod v0.31.0 h1:HaW9xtz0+kOcWKwli0ZXy79Ix+UW/vOfmWI5QVd2tgI= +golang.org/x/mod v0.31.0/go.mod h1:43JraMp9cGx1Rx3AqioxrbrhNsLl2l/iNAvuBkrezpg= +golang.org/x/net v0.48.0 h1:zyQRTTrjc33Lhh0fBgT/H3oZq9WuvRR5gPC70xpDiQU= +golang.org/x/net v0.48.0/go.mod h1:+ndRgGjkh8FGtu1w1FGbEC31if4VrNVMuKTgcAAnQRY= +golang.org/x/sync v0.19.0 h1:vV+1eWNmZ5geRlYjzm2adRgW2/mcpevXNg50YZtPCE4= +golang.org/x/sync v0.19.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.38.0 h1:3yZWxaJjBmCWXqhN1qh02AkOnCQ1poK6oF+a7xWL6Gc= -golang.org/x/sys v0.38.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= -golang.org/x/text v0.31.0 h1:aC8ghyu4JhP8VojJ2lEHBnochRno1sgL6nEi9WGFGMM= -golang.org/x/text v0.31.0/go.mod h1:tKRAlv61yKIjGGHX/4tP1LTbc13YSec1pxVEWXzfoeM= +golang.org/x/sys v0.39.0 h1:CvCKL8MeisomCi6qNZ+wbb0DN9E5AATixKsvNtMoMFk= +golang.org/x/sys v0.39.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= +golang.org/x/text v0.32.0 h1:ZD01bjUt1FQ9WJ0ClOL5vxgxOI/sVCNgX1YtKwcY0mU= +golang.org/x/text v0.32.0/go.mod h1:o/rUWzghvpD5TXrTIBuJU77MTaN0ljMWE47kxGJQ7jY= google.golang.org/protobuf v1.36.10 h1:AYd7cD/uASjIL6Q9LiTjz8JLcrh/88q5UObnmY3aOOE= google.golang.org/protobuf v1.36.10/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= @@ -97,5 +97,5 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= maunium.net/go/mauflag v1.0.0 h1:YiaRc0tEI3toYtJMRIfjP+jklH45uDHtT80nUamyD4M= maunium.net/go/mauflag v1.0.0/go.mod h1:nLivPOpTpHnpzEh8jEdSL9UqO9+/KBJFmNRlwKfkPeA= -maunium.net/go/mautrix v0.26.1-0.20251209144156-31579be20ad8 h1:dbv3iOml42fzC9l1/M2nWPmUPhsesvMJJjgw9ArdnmQ= -maunium.net/go/mautrix v0.26.1-0.20251209144156-31579be20ad8/go.mod h1:pzwIT42s+BhBjEYovmcOt69VlNW2RkJ6pCyZjYQHKIc= +maunium.net/go/mautrix v0.26.1-0.20251211121745-efd4136c7a93 h1:IG8VJk3YT7N4yGVW5VnJiEt9rA3nKZNatXngxFbwhPs= +maunium.net/go/mautrix v0.26.1-0.20251211121745-efd4136c7a93/go.mod h1:tMXkJiGf+2dEPvfrmhQVD6jReL5E8jI1o2dPSsy/39Y= From b2dbdb684c162a8bc4e3f1c3443dea50571b2355 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Thu, 11 Dec 2025 17:53:48 +0200 Subject: [PATCH 492/580] signalmeow: store whitelisted flag and use it for message requests --- pkg/connector/chatinfo.go | 2 +- pkg/connector/client.go | 4 ++- pkg/connector/handlesignal.go | 25 +++++++++++++++++++ pkg/signalmeow/receiving.go | 19 ++++++++------ pkg/signalmeow/sending.go | 8 +++--- pkg/signalmeow/storageservice.go | 5 ++++ pkg/signalmeow/store/backup_store.go | 11 +++++--- pkg/signalmeow/store/recipient_store.go | 13 +++++++--- pkg/signalmeow/store/upgrades/00-latest.sql | 3 ++- .../upgrades/26-recipient-whitelisted.sql | 2 ++ pkg/signalmeow/types/contact.go | 5 ++++ 11 files changed, 76 insertions(+), 21 deletions(-) create mode 100644 pkg/signalmeow/store/upgrades/26-recipient-whitelisted.sql diff --git a/pkg/connector/chatinfo.go b/pkg/connector/chatinfo.go index 7e5a983..081c6d3 100644 --- a/pkg/connector/chatinfo.go +++ b/pkg/connector/chatinfo.go @@ -480,7 +480,7 @@ func (s *SignalClient) makeCreateDMResponse(ctx context.Context, recipient *type Members: members, Type: ptr.Ptr(database.RoomTypeDM), - MessageRequest: ptr.Ptr(recipient.ACI != uuid.Nil && recipient.NeedsPNISignature), + MessageRequest: ptr.Ptr(recipient.ACI != uuid.Nil && recipient.ProbablyMessageRequest()), CanBackfill: backupChat != nil, ExtraUpdates: updatePortalSyncMeta, }, diff --git a/pkg/connector/client.go b/pkg/connector/client.go index c1ad75c..fb77bb0 100644 --- a/pkg/connector/client.go +++ b/pkg/connector/client.go @@ -287,10 +287,12 @@ func (s *SignalClient) postLoginConnect() { s.tryConnect(ctx, 0, false) if s.Client.Store.EphemeralBackupKey != nil { go func() { - s.syncChats(ctx) if s.Client.Store.MasterKey != nil { s.Client.SyncStorage(ctx) + } else { + s.UserLogin.Log.Warn().Msg("No master key for storage sync before backup sync") } + s.syncChats(ctx) }() } else if s.Client.Store.MasterKey != nil { go s.Client.SyncStorage(ctx) diff --git a/pkg/connector/handlesignal.go b/pkg/connector/handlesignal.go index 6e0e302..0ad8555 100644 --- a/pkg/connector/handlesignal.go +++ b/pkg/connector/handlesignal.go @@ -642,6 +642,9 @@ func (s *SignalClient) handleSignalMessageRequestResponse(evt *events.MessageReq PortalKey: portalKey, Timestamp: time.UnixMilli(int64(evt.Timestamp)), StreamOrder: int64(evt.Timestamp), + LogContext: func(c zerolog.Context) zerolog.Context { + return c.Str("action", "unmark message request").Str("source", "sync message") + }, }, ChatInfoChange: &bridgev2.ChatInfoChange{ ChatInfo: &bridgev2.ChatInfo{ @@ -706,6 +709,28 @@ func (s *SignalClient) handleSignalContactList(evt *events.ContactList) { if contact.ACI == s.Client.Store.ACI { s.updateRemoteProfile(ctx, true) } + if ptr.Val(contact.Whitelisted) { + portal, err := s.Main.Bridge.GetExistingPortalByKey(ctx, s.makeDMPortalKey(libsignalgo.NewACIServiceID(contact.ACI))) + if err != nil { + log.Err(err).Msg("Failed to get existing portal to update contact info") + continue + } else if portal != nil && portal.MessageRequest { + s.UserLogin.QueueRemoteEvent(&simplevent.ChatInfoChange{ + EventMeta: simplevent.EventMeta{ + Type: bridgev2.RemoteEventChatInfoChange, + LogContext: func(c zerolog.Context) zerolog.Context { + return c.Str("action", "unmark message request").Str("source", "contact list") + }, + PortalKey: portal.PortalKey, + }, + ChatInfoChange: &bridgev2.ChatInfoChange{ + ChatInfo: &bridgev2.ChatInfo{ + MessageRequest: ptr.Ptr(false), + }, + }, + }) + } + } } } diff --git a/pkg/signalmeow/receiving.go b/pkg/signalmeow/receiving.go index 8cc0be7..a836893 100644 --- a/pkg/signalmeow/receiving.go +++ b/pkg/signalmeow/receiving.go @@ -29,6 +29,7 @@ import ( "github.com/google/uuid" "github.com/rs/zerolog" + "go.mau.fi/util/ptr" "google.golang.org/protobuf/proto" "go.mau.fi/mautrix-signal/pkg/libsignalgo" @@ -562,12 +563,17 @@ func (cli *Client) handleDecryptedResult( if destinationServiceID == cli.Store.PNIServiceID() { _, err = cli.Store.RecipientStore.LoadAndUpdateRecipient(ctx, theirServiceID.UUID, uuid.Nil, func(recipient *types.Recipient) (changed bool, err error) { + if recipient.Whitelisted == nil { + log.Debug().Msg("Marking recipient as not whitelisted") + recipient.Whitelisted = ptr.Ptr(false) + changed = true + } if !recipient.NeedsPNISignature { log.Debug().Msg("Marking recipient as needing PNI signature") recipient.NeedsPNISignature = true - return true, nil + changed = true } - return false, nil + return }) if err != nil { log.Err(err).Msg("Failed to set needs_pni_signature flag after receiving message to PNI service ID") @@ -782,11 +788,10 @@ func (cli *Client) handleSyncMessage(ctx context.Context, msg *signalpb.SyncMess aciUUID, _ := uuid.Parse(msg.MessageRequestResponse.GetThreadAci()) if aciUUID != uuid.Nil && msg.MessageRequestResponse.GetType() == signalpb.SyncMessage_MessageRequestResponse_ACCEPT { _, err := cli.Store.RecipientStore.LoadAndUpdateRecipient(ctx, aciUUID, uuid.Nil, func(recipient *types.Recipient) (changed bool, err error) { - if recipient.NeedsPNISignature { - recipient.NeedsPNISignature = false - return true, nil - } - return false, nil + changed = !ptr.Val(recipient.Whitelisted) || recipient.NeedsPNISignature + recipient.Whitelisted = ptr.Ptr(true) + recipient.NeedsPNISignature = false + return }) if err != nil { log.Err(err).Msg("Failed to clear needs_pni_signature flag after message request accept") diff --git a/pkg/signalmeow/sending.go b/pkg/signalmeow/sending.go index fa0818a..9a523bd 100644 --- a/pkg/signalmeow/sending.go +++ b/pkg/signalmeow/sending.go @@ -698,7 +698,6 @@ func (cli *Client) SendMessage(ctx context.Context, recipientID libsignalgo.Serv } else { messageTimestamp = currentMessageTimestamp() } - needsPNISignature := false var aci, pni uuid.UUID if recipientID.Type == libsignalgo.ServiceIDTypeACI { aci = recipientID.UUID @@ -707,7 +706,10 @@ func (cli *Client) SendMessage(ctx context.Context, recipientID libsignalgo.Serv } isTypingOrReceipt := content.TypingMessage != nil || content.ReceiptMessage != nil recipientData, err := cli.Store.RecipientStore.LoadAndUpdateRecipient(ctx, aci, pni, func(recipientData *types.Recipient) (changed bool, err error) { - needsPNISignature = recipientID.Type == libsignalgo.ServiceIDTypeACI && recipientData.NeedsPNISignature + if content.GetDataMessage().GetFlags() == uint32(signalpb.DataMessage_PROFILE_KEY_UPDATE) { + recipientData.Whitelisted = ptr.Ptr(true) + } + needsPNISignature := recipientID.Type == libsignalgo.ServiceIDTypeACI && recipientData.NeedsPNISignature if needsPNISignature && !isTypingOrReceipt && content.PniSignatureMessage == nil { zerolog.Ctx(ctx).Debug(). Stringer("recipient", recipientID). @@ -732,7 +734,7 @@ func (cli *Client) SendMessage(ctx context.Context, recipientID libsignalgo.Serv zerolog.Ctx(ctx).Err(err).Msg("Failed to get message recipient data") } // Treat needs PNI signature as "this is a message request" and don't send receipts/typing - if needsPNISignature && isTypingOrReceipt { + if recipientData.ProbablyMessageRequest() && isTypingOrReceipt { zerolog.Ctx(ctx).Debug().Msg("Not sending typing/receipt message to recipient as needs PNI signature flag is set") res := SuccessfulSendResult{Recipient: recipientID} if content.GetReceiptMessage().GetType() == signalpb.ReceiptMessage_READ { diff --git a/pkg/signalmeow/storageservice.go b/pkg/signalmeow/storageservice.go index 45a008e..97c3d26 100644 --- a/pkg/signalmeow/storageservice.go +++ b/pkg/signalmeow/storageservice.go @@ -30,6 +30,7 @@ import ( "github.com/google/uuid" "github.com/rs/zerolog" "go.mau.fi/util/exerrors" + "go.mau.fi/util/ptr" "golang.org/x/crypto/hkdf" "golang.org/x/exp/maps" "google.golang.org/protobuf/proto" @@ -103,6 +104,10 @@ func (cli *Client) processStorageInTxn(ctx context.Context, update *StorageUpdat changed = true recipient.Blocked = contact.Blocked } + if !ptr.Val(recipient.Whitelisted) { + changed = true + recipient.Whitelisted = &contact.Whitelisted + } topLevelChanged = changed return }) diff --git a/pkg/signalmeow/store/backup_store.go b/pkg/signalmeow/store/backup_store.go index 2b1adf7..e99b110 100644 --- a/pkg/signalmeow/store/backup_store.go +++ b/pkg/signalmeow/store/backup_store.go @@ -161,13 +161,16 @@ func (s *sqlStore) AddBackupRecipient(ctx context.Context, recipient *backuppb.R if dest.Contact.ProfileGivenName != nil || dest.Contact.ProfileFamilyName != nil { recipient.Profile.Name = strings.TrimSpace(fmt.Sprintf("%s %s", dest.Contact.GetProfileGivenName(), dest.Contact.GetProfileFamilyName())) } - recipient.NeedsPNISignature = dest.Contact.GetVisibility() == backuppb.Contact_HIDDEN_MESSAGE_REQUEST + if dest.Contact.ProfileSharing && !ptr.Val(recipient.Whitelisted) { + recipient.Whitelisted = ptr.Ptr(true) + changed = true + } recipient.Blocked = dest.Contact.Blocked - changed = oldRecipient.E164 != recipient.E164 || + changed = changed || + oldRecipient.E164 != recipient.E164 || oldRecipient.Profile.Key != recipient.Profile.Key || oldRecipient.Profile.Name != recipient.Profile.Name || - oldRecipient.Blocked != recipient.Blocked || - oldRecipient.NeedsPNISignature != recipient.NeedsPNISignature + oldRecipient.Blocked != recipient.Blocked return }) if err != nil { diff --git a/pkg/signalmeow/store/recipient_store.go b/pkg/signalmeow/store/recipient_store.go index 98c7315..5f328be 100644 --- a/pkg/signalmeow/store/recipient_store.go +++ b/pkg/signalmeow/store/recipient_store.go @@ -67,7 +67,8 @@ const ( profile_avatar_path, profile_fetched_at, needs_pni_signature, - blocked + blocked, + whitelisted FROM signalmeow_recipients WHERE account_id = $1 ` @@ -93,9 +94,10 @@ const ( profile_avatar_path, profile_fetched_at, needs_pni_signature, - blocked + blocked, + whitelisted ) - VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15) + VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16) ON CONFLICT (account_id, aci_uuid) DO UPDATE SET pni_uuid = excluded.pni_uuid, e164_number = excluded.e164_number, @@ -109,7 +111,8 @@ const ( profile_avatar_path = excluded.profile_avatar_path, profile_fetched_at = excluded.profile_fetched_at, needs_pni_signature = excluded.needs_pni_signature, - blocked = excluded.blocked + blocked = excluded.blocked, + whitelisted = excluded.whitelisted ` upsertPNIRecipientQuery = ` INSERT INTO signalmeow_recipients ( @@ -147,6 +150,7 @@ func scanRecipient(row dbutil.Scannable) (*types.Recipient, error) { &profileFetchedAt, &recipient.NeedsPNISignature, &recipient.Blocked, + &recipient.Whitelisted, ) if errors.Is(err, sql.ErrNoRows) { return nil, nil @@ -371,6 +375,7 @@ func (s *sqlStore) StoreRecipient(ctx context.Context, recipient *types.Recipien dbutil.UnixMilliPtr(recipient.Profile.FetchedAt), recipient.NeedsPNISignature, recipient.Blocked, + recipient.Whitelisted, ) s.blockCacheLock.Lock() s.blockCache[recipient.ACI] = recipient.Blocked diff --git a/pkg/signalmeow/store/upgrades/00-latest.sql b/pkg/signalmeow/store/upgrades/00-latest.sql index dee3509..8f54eac 100644 --- a/pkg/signalmeow/store/upgrades/00-latest.sql +++ b/pkg/signalmeow/store/upgrades/00-latest.sql @@ -1,4 +1,4 @@ --- v0 -> v25 (compatible with v13+): Latest revision +-- v0 -> v26 (compatible with v13+): Latest revision CREATE TABLE signalmeow_device ( aci_uuid TEXT PRIMARY KEY, @@ -127,6 +127,7 @@ CREATE TABLE signalmeow_recipients ( profile_fetched_at BIGINT, needs_pni_signature BOOLEAN NOT NULL DEFAULT false, blocked BOOLEAN NOT NULL DEFAULT false, + whitelisted BOOLEAN, CONSTRAINT signalmeow_contacts_account_id_fkey FOREIGN KEY (account_id) REFERENCES signalmeow_device (aci_uuid) ON DELETE CASCADE ON UPDATE CASCADE, diff --git a/pkg/signalmeow/store/upgrades/26-recipient-whitelisted.sql b/pkg/signalmeow/store/upgrades/26-recipient-whitelisted.sql new file mode 100644 index 0000000..c61bf33 --- /dev/null +++ b/pkg/signalmeow/store/upgrades/26-recipient-whitelisted.sql @@ -0,0 +1,2 @@ +-- v26 (compatible with v13+): Store whitelisted status for recipients +ALTER TABLE signalmeow_recipients ADD COLUMN whitelisted BOOLEAN; diff --git a/pkg/signalmeow/types/contact.go b/pkg/signalmeow/types/contact.go index bed25ac..889dd3e 100644 --- a/pkg/signalmeow/types/contact.go +++ b/pkg/signalmeow/types/contact.go @@ -56,6 +56,11 @@ type Recipient struct { NeedsPNISignature bool Blocked bool + Whitelisted *bool +} + +func (r *Recipient) ProbablyMessageRequest() bool { + return r != nil && (r.NeedsPNISignature || (r.Whitelisted != nil && !*r.Whitelisted)) } type ContactAvatar struct { From fe3c072cd1f71fe90739574cc446e3ae2a552bd6 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Sun, 14 Dec 2025 14:08:06 +0200 Subject: [PATCH 493/580] dependencies: update mautrix-go --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 33f2f4d..2d6984d 100644 --- a/go.mod +++ b/go.mod @@ -20,7 +20,7 @@ require ( golang.org/x/net v0.48.0 google.golang.org/protobuf v1.36.10 gopkg.in/yaml.v3 v3.0.1 - maunium.net/go/mautrix v0.26.1-0.20251211121745-efd4136c7a93 + maunium.net/go/mautrix v0.26.1-0.20251213090909-cb6f673e7a70 ) require ( diff --git a/go.sum b/go.sum index 090940f..3bcf2a9 100644 --- a/go.sum +++ b/go.sum @@ -97,5 +97,5 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= maunium.net/go/mauflag v1.0.0 h1:YiaRc0tEI3toYtJMRIfjP+jklH45uDHtT80nUamyD4M= maunium.net/go/mauflag v1.0.0/go.mod h1:nLivPOpTpHnpzEh8jEdSL9UqO9+/KBJFmNRlwKfkPeA= -maunium.net/go/mautrix v0.26.1-0.20251211121745-efd4136c7a93 h1:IG8VJk3YT7N4yGVW5VnJiEt9rA3nKZNatXngxFbwhPs= -maunium.net/go/mautrix v0.26.1-0.20251211121745-efd4136c7a93/go.mod h1:tMXkJiGf+2dEPvfrmhQVD6jReL5E8jI1o2dPSsy/39Y= +maunium.net/go/mautrix v0.26.1-0.20251213090909-cb6f673e7a70 h1:qLTFD+r20eh81SaFUpgBhIsQkDSzUNJWcCQPx+WNnm0= +maunium.net/go/mautrix v0.26.1-0.20251213090909-cb6f673e7a70/go.mod h1:tMXkJiGf+2dEPvfrmhQVD6jReL5E8jI1o2dPSsy/39Y= From df733a3c77670cd6f8e5eb2a43f30863d088eb52 Mon Sep 17 00:00:00 2001 From: Michael Hoang Date: Mon, 15 Dec 2025 19:46:57 +0100 Subject: [PATCH 494/580] signalmeow/storageservice: fix nickname clearing not being bridged (#623) --- pkg/signalmeow/storageservice.go | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/pkg/signalmeow/storageservice.go b/pkg/signalmeow/storageservice.go index 97c3d26..676fc7f 100644 --- a/pkg/signalmeow/storageservice.go +++ b/pkg/signalmeow/storageservice.go @@ -92,9 +92,13 @@ func (cli *Client) processStorageInTxn(ctx context.Context, update *StorageUpdat changed = true recipient.ContactName = strings.TrimSpace(fmt.Sprintf("%s %s", contact.SystemGivenName, contact.SystemFamilyName)) } + newNickname := "" if contact.Nickname != nil { + newNickname = strings.TrimSpace(fmt.Sprintf("%s %s", contact.Nickname.Given, contact.Nickname.Family)) + } + if recipient.Nickname != newNickname { changed = true - recipient.Nickname = strings.TrimSpace(fmt.Sprintf("%s %s", contact.Nickname.Given, contact.Nickname.Family)) + recipient.Nickname = newNickname } if contact.E164 != "" { changed = changed || recipient.E164 != contact.E164 From 57865d0cf4cf10ece07a0a8b69394927e382de38 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Sun, 14 Dec 2025 14:38:49 +0200 Subject: [PATCH 495/580] docker: update to Alpine 3.23 --- Dockerfile | 4 ++-- Dockerfile.ci | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Dockerfile b/Dockerfile index 162ac86..63e7542 100644 --- a/Dockerfile +++ b/Dockerfile @@ -10,7 +10,7 @@ COPY build-rust.sh . RUN ./build-rust.sh # -- Build mautrix-signal (with Go) -- -FROM golang:1-alpine3.22 AS go-builder +FROM golang:1-alpine3.23 AS go-builder RUN apk add --no-cache git ca-certificates build-base olm-dev zlib-dev WORKDIR /build @@ -32,7 +32,7 @@ EOF RUN ./build-go.sh # -- Run mautrix-signal -- -FROM alpine:3.22 +FROM alpine:3.23 ENV UID=1337 \ GID=1337 diff --git a/Dockerfile.ci b/Dockerfile.ci index 7d34502..ea2699f 100644 --- a/Dockerfile.ci +++ b/Dockerfile.ci @@ -1,6 +1,6 @@ ARG DOCKER_HUB="docker.io" -FROM ${DOCKER_HUB}/alpine:3.22 +FROM ${DOCKER_HUB}/alpine:3.23 ENV UID=1337 \ GID=1337 From 464b0601c173dd207e25c9218f11f39727193bfe Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Tue, 16 Dec 2025 12:39:04 +0200 Subject: [PATCH 496/580] ci: update actions and pre-commit hooks --- .github/workflows/go.yml | 8 ++++---- .github/workflows/stale.yml | 2 +- .pre-commit-config.yaml | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml index 3913002..767c119 100644 --- a/.github/workflows/go.yml +++ b/.github/workflows/go.yml @@ -15,10 +15,10 @@ jobs: name: Lint ${{ matrix.go-version == '1.25' && '(latest)' || '(old)' }} steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 - name: Set up Go - uses: actions/setup-go@v5 + uses: actions/setup-go@v6 with: go-version: ${{ matrix.go-version }} cache: true @@ -44,10 +44,10 @@ jobs: name: Test ${{ matrix.go-version == '1.25' && '(latest)' || '(old)' }} steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 - name: Set up Go - uses: actions/setup-go@v5 + uses: actions/setup-go@v6 with: go-version: ${{ matrix.go-version }} cache: true diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml index c2003f3..c15f2fa 100644 --- a/.github/workflows/stale.yml +++ b/.github/workflows/stale.yml @@ -17,7 +17,7 @@ jobs: lock-stale: runs-on: ubuntu-latest steps: - - uses: dessant/lock-threads@v5 + - uses: dessant/lock-threads@v6 id: lock with: issue-inactive-days: 90 diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index f6b3302..c9cc6a3 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -9,7 +9,7 @@ repos: - id: check-added-large-files - repo: https://github.com/tekwizely/pre-commit-golang - rev: v1.0.0-rc.2 + rev: v1.0.0-rc.4 hooks: - id: go-imports exclude: "pb\\.go$" From 1e4b47375c3707bbb36b6361560b3f0766a14875 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Tue, 16 Dec 2025 12:41:32 +0200 Subject: [PATCH 497/580] Bump version to v25.12 --- CHANGELOG.md | 8 +++++++- cmd/mautrix-signal/main.go | 2 +- go.mod | 8 ++++---- go.sum | 15 ++++++++------- 4 files changed, 20 insertions(+), 13 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6785804..1a5d207 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,12 +1,18 @@ -# v25.12 (unreleased) +# v25.12 * Updated libsignal to v0.86.8. +* Updated Docker image to Alpine 3.23. * Added support for dropping incoming DMs from blocked contacts on Signal. * Added support for sender key encryption when sending to groups, which makes sending much faster and enables sending typing notifications. * Added support for encryption retry receipts. * Fixed bugs with handling poll votes. * Fixed history transfer option not showing up when pairing with Signal Android. +* Fixed nicknames being cleared not being bridged + (thanks to [@Enzime] in [#623]). + +[#623]: https://github.com/mautrix/signal/pull/623 +[@Enzime]: https://github.com/Enzime # v25.11 diff --git a/cmd/mautrix-signal/main.go b/cmd/mautrix-signal/main.go index d224f32..130e307 100644 --- a/cmd/mautrix-signal/main.go +++ b/cmd/mautrix-signal/main.go @@ -37,7 +37,7 @@ var m = mxmain.BridgeMain{ Name: "mautrix-signal", URL: "https://github.com/mautrix/signal", Description: "A Matrix-Signal puppeting bridge.", - Version: "25.11", + Version: "25.12", SemCalVer: true, Connector: &connector.SignalConnector{}, diff --git a/go.mod b/go.mod index 2d6984d..f898ff1 100644 --- a/go.mod +++ b/go.mod @@ -14,18 +14,18 @@ require ( github.com/rs/zerolog v1.34.0 github.com/stretchr/testify v1.11.1 github.com/tidwall/gjson v1.18.0 - go.mau.fi/util v0.9.4-0.20251211121531-f6527b4882ae + go.mau.fi/util v0.9.4 golang.org/x/crypto v0.46.0 golang.org/x/exp v0.0.0-20251209150349-8475f28825e9 golang.org/x/net v0.48.0 - google.golang.org/protobuf v1.36.10 + google.golang.org/protobuf v1.36.11 gopkg.in/yaml.v3 v3.0.1 - maunium.net/go/mautrix v0.26.1-0.20251213090909-cb6f673e7a70 + maunium.net/go/mautrix v0.26.1 ) require ( filippo.io/edwards25519 v1.1.0 // indirect - github.com/coreos/go-systemd/v22 v22.5.0 // indirect + github.com/coreos/go-systemd/v22 v22.6.0 // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/kr/pretty v0.3.1 // indirect github.com/lib/pq v1.10.9 // indirect diff --git a/go.sum b/go.sum index 3bcf2a9..62da235 100644 --- a/go.sum +++ b/go.sum @@ -4,8 +4,9 @@ github.com/DATA-DOG/go-sqlmock v1.5.2 h1:OcvFkGmslmlZibjAjaHm3L//6LiuBgolP7Oputl github.com/DATA-DOG/go-sqlmock v1.5.2/go.mod h1:88MAG/4G7SMwSE3CeA0ZKzrT5CiOU3OJ+JlNzwDqpNU= github.com/coder/websocket v1.8.14 h1:9L0p0iKiNOibykf283eHkKUHHrpG7f65OE3BhhO7v9g= github.com/coder/websocket v1.8.14/go.mod h1:NX3SzP+inril6yawo5CQXx8+fk145lPDC6pumgx0mVg= -github.com/coreos/go-systemd/v22 v22.5.0 h1:RrqgGjYQKalulkV8NGVIfkXQf6YYmOyiJKk8iXXhfZs= github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= +github.com/coreos/go-systemd/v22 v22.6.0 h1:aGVa/v8B7hpb0TKl0MWoAavPDmHvobFe5R5zn0bCJWo= +github.com/coreos/go-systemd/v22 v22.6.0/go.mod h1:iG+pp635Fo7ZmV/j14KUcmEyWF+0X7Lua8rrTWzYgWU= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= @@ -65,8 +66,8 @@ github.com/tidwall/sjson v1.2.5 h1:kLy8mja+1c9jlljvWTlSazM7cKDRfJuR/bOJhcY5NcY= github.com/tidwall/sjson v1.2.5/go.mod h1:Fvgq9kS/6ociJEDnK0Fk1cpYF4FIW6ZF7LAe+6jwd28= github.com/yuin/goldmark v1.7.13 h1:GPddIs617DnBLFFVJFgpo1aBfe/4xcvMc3SB5t/D0pA= github.com/yuin/goldmark v1.7.13/go.mod h1:ip/1k0VRfGynBgxOz0yCqHrbZXhcjxyuS66Brc7iBKg= -go.mau.fi/util v0.9.4-0.20251211121531-f6527b4882ae h1:tocQOutgT+Z/V6w668Jpk3D5942K5p25XmRAvXg8s2E= -go.mau.fi/util v0.9.4-0.20251211121531-f6527b4882ae/go.mod h1:OwI76F1QINxtH/TOydGAAj5/VvtPG0RnZzB41rtnKcA= +go.mau.fi/util v0.9.4 h1:gWdUff+K2rCynRPysXalqqQyr2ahkSWaestH6YhSpso= +go.mau.fi/util v0.9.4/go.mod h1:647nVfwUvuhlZFOnro3aRNPmRd2y3iDha9USb8aKSmM= go.mau.fi/zeroconfig v0.2.0 h1:e/OGEERqVRRKlgaro7E6bh8xXiKFSXB3eNNIud7FUjU= go.mau.fi/zeroconfig v0.2.0/go.mod h1:J0Vn0prHNOm493oZoQ84kq83ZaNCYZnq+noI1b1eN8w= golang.org/x/crypto v0.46.0 h1:cKRW/pmt1pKAfetfu+RCEvjvZkA9RimPbh7bhFjGVBU= @@ -86,8 +87,8 @@ golang.org/x/sys v0.39.0 h1:CvCKL8MeisomCi6qNZ+wbb0DN9E5AATixKsvNtMoMFk= golang.org/x/sys v0.39.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= golang.org/x/text v0.32.0 h1:ZD01bjUt1FQ9WJ0ClOL5vxgxOI/sVCNgX1YtKwcY0mU= golang.org/x/text v0.32.0/go.mod h1:o/rUWzghvpD5TXrTIBuJU77MTaN0ljMWE47kxGJQ7jY= -google.golang.org/protobuf v1.36.10 h1:AYd7cD/uASjIL6Q9LiTjz8JLcrh/88q5UObnmY3aOOE= -google.golang.org/protobuf v1.36.10/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= +google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE= +google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= @@ -97,5 +98,5 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= maunium.net/go/mauflag v1.0.0 h1:YiaRc0tEI3toYtJMRIfjP+jklH45uDHtT80nUamyD4M= maunium.net/go/mauflag v1.0.0/go.mod h1:nLivPOpTpHnpzEh8jEdSL9UqO9+/KBJFmNRlwKfkPeA= -maunium.net/go/mautrix v0.26.1-0.20251213090909-cb6f673e7a70 h1:qLTFD+r20eh81SaFUpgBhIsQkDSzUNJWcCQPx+WNnm0= -maunium.net/go/mautrix v0.26.1-0.20251213090909-cb6f673e7a70/go.mod h1:tMXkJiGf+2dEPvfrmhQVD6jReL5E8jI1o2dPSsy/39Y= +maunium.net/go/mautrix v0.26.1 h1:FWCC1xY5vwJ5ou3duEBjB6w9IIlwfc9el3q3Mju3Dlg= +maunium.net/go/mautrix v0.26.1/go.mod h1:UySSpb8OqXG1sMJ6dDqyzmfcqr2ayZK+KzwqOTAkAOM= From 7fc0b062ee41673f25d849175a6086c2730ab585 Mon Sep 17 00:00:00 2001 From: Nick Mills-Barrett Date: Wed, 17 Dec 2025 10:16:32 +0000 Subject: [PATCH 498/580] client: exit sleep during connect retry if context canceled --- pkg/connector/client.go | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/pkg/connector/client.go b/pkg/connector/client.go index fb77bb0..e224c17 100644 --- a/pkg/connector/client.go +++ b/pkg/connector/client.go @@ -312,7 +312,12 @@ func (s *SignalClient) tryConnect(ctx context.Context, retryCount int, doSync bo retryInSeconds = 150 } zerolog.Ctx(ctx).Debug().Int("retry_in_seconds", retryInSeconds).Msg("Sleeping and retrying connection") - time.Sleep(time.Duration(retryInSeconds) * time.Second) + select { + case <-time.After(time.Duration(retryInSeconds) * time.Second): + case <-ctx.Done(): + zerolog.Ctx(ctx).Info().Msg("Context canceled, exit tryConnect") + return + } s.tryConnect(ctx, retryCount+1, doSync) } else { go s.bridgeStateLoop(ch) From 28c03d8e0e69566d6339578a706441841d7e0ec1 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Sun, 21 Dec 2025 23:34:31 +0200 Subject: [PATCH 499/580] libsignalgo/sealedsender: remove unnecessary debug code --- pkg/libsignalgo/sealedsender.go | 24 ------------------------ 1 file changed, 24 deletions(-) diff --git a/pkg/libsignalgo/sealedsender.go b/pkg/libsignalgo/sealedsender.go index eb6f655..56ffe8b 100644 --- a/pkg/libsignalgo/sealedsender.go +++ b/pkg/libsignalgo/sealedsender.go @@ -24,14 +24,10 @@ import "C" import ( "context" "fmt" - "maps" "runtime" - "slices" "unsafe" "github.com/google/uuid" - "github.com/rs/zerolog" - "go.mau.fi/util/exerrors" ) type SealedSenderAddress struct { @@ -103,30 +99,10 @@ func SealedSenderMultiRecipientEncrypt( recipientAddresses := make([]C.SignalConstPointerProtocolAddress, len(recipients)) recipientSessions := make([]C.SignalConstPointerSessionRecord, len(recipients)) - type dedupTuple struct { - Name string - DeviceID uint - } - deviceDedup := make(map[dedupTuple]struct{}) - var duplicateFound *dedupTuple - for i, recipient := range recipients { - name := exerrors.Must(recipient.Address.Name()) - deviceID := exerrors.Must(recipient.Address.DeviceID()) - dedupKey := dedupTuple{name, deviceID} - if _, exists := deviceDedup[dedupKey]; exists { - duplicateFound = &dedupKey - } recipientAddresses[i] = recipient.Address.constPtr() recipientSessions[i] = recipient.Record.constPtr() } - if duplicateFound != nil { - zerolog.Ctx(ctx).Debug(). - Any("full_list", slices.Collect(maps.Keys(deviceDedup))). - Any("last_duplicate", *duplicateFound). - Msg("Duplicate debug data") - return nil, fmt.Errorf("duplicate recipient addresses found in SealedSenderMultiRecipientEncrypt") - } signalFfiError := C.signal_sealed_sender_multi_recipient_encrypt( &encrypted, C.SignalBorrowedSliceOfConstPointerProtocolAddress{ From e04ff8b0f6a72a6e202d554a61dc2cbf85718986 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Sun, 21 Dec 2025 23:34:49 +0200 Subject: [PATCH 500/580] signalmeow/senderkey: don't mutate recipient list when finding target devices --- pkg/signalmeow/senderkey.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/signalmeow/senderkey.go b/pkg/signalmeow/senderkey.go index 1c0da8a..e8a0714 100644 --- a/pkg/signalmeow/senderkey.go +++ b/pkg/signalmeow/senderkey.go @@ -352,8 +352,8 @@ func (cli *Client) getDevicesIDs( ) { log := zerolog.Ctx(ctx) out := make(map[libsignalgo.ServiceID]senderKeySendMeta) - fallbackRecipients := recipients[:0] senderKeyRecipients := make([]store.SessionAddressTuple, 0, len(recipients)) + fallbackRecipients := make([]libsignalgo.ServiceID, 0) for _, recipient := range recipients { if recipient == cli.Store.ACIServiceID() { // We'll send a sync copy to ourselves, not sender key and no need to include in fallback recipients either From 189fb181cc33605d0c96629639093bd76f14636d Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Wed, 24 Dec 2025 20:07:53 +0200 Subject: [PATCH 501/580] signalmeow/senderkey: fall back to normal send if there are no sender key recipients --- pkg/signalmeow/senderkey.go | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/pkg/signalmeow/senderkey.go b/pkg/signalmeow/senderkey.go index e8a0714..096d524 100644 --- a/pkg/signalmeow/senderkey.go +++ b/pkg/signalmeow/senderkey.go @@ -99,6 +99,11 @@ func (cli *Client) sendToGroupWithSenderKey( groupIDStr := types.GroupIdentifier(groupID.String()) deviceIDs, senderKeyRecipients, fallbackRecipients := cli.getDevicesIDs(ctx, allRecipients, sec, result) + if len(senderKeyRecipients) == 0 { + doUnlock() + log.Debug().Msg("No sender key recipients, falling back to normal send") + return cli.sendToGroup(ctx, allRecipients, content, messageTimestamp, result, groupID) + } ski, err := cli.Store.SenderKeyStore.GetSenderKeyInfo(ctx, groupIDStr) if err != nil { return nil, fmt.Errorf("failed to get sender key info: %w", err) From f01385849b0988d42a0744970f41465733a73471 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Sun, 28 Dec 2025 20:14:46 +0200 Subject: [PATCH 502/580] signalmeow/receiving: save PNI identity keys from sync messages --- pkg/signalmeow/receiving.go | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/pkg/signalmeow/receiving.go b/pkg/signalmeow/receiving.go index a836893..1b4dce0 100644 --- a/pkg/signalmeow/receiving.go +++ b/pkg/signalmeow/receiving.go @@ -722,6 +722,19 @@ func (cli *Client) handleSyncMessage(ctx context.Context, msg *signalpb.SyncMess } } } + for _, unident := range syncSent.GetUnidentifiedStatus() { + changed, err := cli.saveSyncPNIIdentityKey(ctx, unident.GetDestinationServiceId(), unident.GetDestinationPniIdentityKey()) + if err != nil { + log.Err(err). + Str("destination_service_id", unident.GetDestinationServiceId()). + Msg("Failed to save PNI identity key from sync message") + } else if changed { + log.Debug(). + Str("destination_service_id", unident.GetDestinationServiceId()). + Msg("Saved new PNI identity key from sync message") + } + } + if destination == nil && syncSent.GetMessage().GetGroupV2() == nil && syncSent.GetEditMessage().GetDataMessage().GetGroupV2() == nil { log.Warn().Msg("sync message sent destination is nil") } else if msg.Sent.Message != nil { @@ -812,6 +825,27 @@ func (cli *Client) handleSyncMessage(ctx context.Context, msg *signalpb.SyncMess return } +func (cli *Client) saveSyncPNIIdentityKey(ctx context.Context, serviceIDString string, identityKeyBytes []byte) (bool, error) { + if identityKeyBytes == nil { + return false, nil + } + identityKey, err := libsignalgo.DeserializeIdentityKey(identityKeyBytes) + if err != nil { + return false, fmt.Errorf("failed to deserialize PNI identity key: %w", err) + } + serviceID, err := libsignalgo.ServiceIDFromString(serviceIDString) + if err != nil { + return false, fmt.Errorf("failed to parse PNI service ID: %w", err) + } else if serviceID.Type != libsignalgo.ServiceIDTypePNI { + return false, nil + } + changed, err := cli.Store.IdentityKeyStore.SaveIdentityKey(ctx, serviceID, identityKey) + if err != nil { + return false, fmt.Errorf("failed to save PNI identity key: %w", err) + } + return changed, nil +} + func (cli *Client) handlePNISignatureMessage(ctx context.Context, sender libsignalgo.ServiceID, msg *signalpb.PniSignatureMessage) error { if sender.Type != libsignalgo.ServiceIDTypeACI { return fmt.Errorf("PNI signature message sender is not an ACI") From 71af50b90cbfff70126ef88cdfd8fb33528308b4 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Tue, 30 Dec 2025 23:00:49 +0200 Subject: [PATCH 503/580] chatinfo,handlematrix: fix handling room avatars --- pkg/connector/chatinfo.go | 4 ++-- pkg/connector/handlematrix.go | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/pkg/connector/chatinfo.go b/pkg/connector/chatinfo.go index 081c6d3..4ce1f9d 100644 --- a/pkg/connector/chatinfo.go +++ b/pkg/connector/chatinfo.go @@ -326,9 +326,9 @@ func (s *SignalClient) CreateGroup(ctx context.Context, params *bridgev2.GroupCr } var avatarBytes []byte var avatarMXC id.ContentURIString - if params.Avatar != nil { + if params.Avatar != nil && params.Avatar.URL != "" { avatarMXC = params.Avatar.URL - avatarBytes, err = s.Main.Bridge.Bot.DownloadMedia(ctx, params.Avatar.URL, params.Avatar.MSC3414File) + avatarBytes, err = s.Main.Bridge.Bot.DownloadMedia(ctx, params.Avatar.URL, nil) if err != nil { return nil, fmt.Errorf("failed to download avatar: %w", err) } diff --git a/pkg/connector/handlematrix.go b/pkg/connector/handlematrix.go index 0c47a08..610dd81 100644 --- a/pkg/connector/handlematrix.go +++ b/pkg/connector/handlematrix.go @@ -381,8 +381,8 @@ func (s *SignalClient) HandleMatrixRoomAvatar(ctx context.Context, msg *bridgev2 } var avatarPath string var avatarHash [32]byte - if msg.Content.URL != "" || msg.Content.MSC3414File != nil { - data, err := s.Main.Bridge.Bot.DownloadMedia(ctx, msg.Content.URL, msg.Content.MSC3414File) + if msg.Content.URL != "" { + data, err := s.Main.Bridge.Bot.DownloadMedia(ctx, msg.Content.URL, nil) if err != nil { return false, fmt.Errorf("failed to download avatar: %w", err) } From b33d7c82462fe882245f332f7f36a5515c4ec4ff Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Mon, 5 Jan 2026 01:08:18 +0200 Subject: [PATCH 504/580] signalmeow/sending: fix typing message envelope timestamps in DMs --- pkg/signalmeow/sending.go | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/pkg/signalmeow/sending.go b/pkg/signalmeow/sending.go index 9a523bd..404571c 100644 --- a/pkg/signalmeow/sending.go +++ b/pkg/signalmeow/sending.go @@ -691,12 +691,22 @@ func (cli *Client) sendSyncCopy(ctx context.Context, content *signalpb.Content, func (cli *Client) SendMessage(ctx context.Context, recipientID libsignalgo.ServiceID, content *signalpb.Content) SendMessageResult { // Assemble the content to send var messageTimestamp uint64 - if content.GetDataMessage() != nil { + switch { + case content.DataMessage != nil: messageTimestamp = *content.DataMessage.Timestamp - } else if content.GetEditMessage().GetDataMessage() != nil { + case content.EditMessage != nil: messageTimestamp = *content.EditMessage.DataMessage.Timestamp - } else { + case content.TypingMessage != nil: + messageTimestamp = *content.TypingMessage.Timestamp + case content.SyncMessage != nil, + content.NullMessage != nil, + content.ReceiptMessage != nil, + content.PniSignatureMessage != nil, + content.SenderKeyDistributionMessage != nil, + content.DecryptionErrorMessage != nil: messageTimestamp = currentMessageTimestamp() + default: + panic(fmt.Errorf("unsupported payload in SendMessage")) } var aci, pni uuid.UUID if recipientID.Type == libsignalgo.ServiceIDTypeACI { From 880849def7edfd54bfac41558e7a2d3d4dc7d2e7 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Wed, 7 Jan 2026 14:21:59 +0200 Subject: [PATCH 505/580] signalmeow/web: fix response bodies not being closed --- pkg/signalmeow/attachments.go | 5 +++++ pkg/signalmeow/groups.go | 5 +++++ pkg/signalmeow/profile.go | 2 +- pkg/signalmeow/storageservice.go | 4 +++- pkg/signalmeow/web/web.go | 8 +++++++- 5 files changed, 21 insertions(+), 3 deletions(-) diff --git a/pkg/signalmeow/attachments.go b/pkg/signalmeow/attachments.go index 22884fe..6b78c68 100644 --- a/pkg/signalmeow/attachments.go +++ b/pkg/signalmeow/attachments.go @@ -225,6 +225,7 @@ func (cli *Client) uploadAttachmentLegacy( Username: &username, Password: &password, }) + web.CloseBody(resp) if err != nil { return fmt.Errorf("failed to send allocate request: %w", err) } else if resp.StatusCode < 200 || resp.StatusCode >= 300 { @@ -239,6 +240,7 @@ func (cli *Client) uploadAttachmentLegacy( Username: &username, Password: &password, }) + web.CloseBody(resp) if err != nil { return fmt.Errorf("failed to send upload request: %w", err) } else if resp.StatusCode < 200 || resp.StatusCode >= 300 { @@ -262,6 +264,7 @@ func (cli *Client) uploadAttachmentTUS( ContentType: web.ContentTypeOffsetOctetStream, Headers: uploadAttributes.Headers, }) + web.CloseBody(resp) // TODO actually support resuming on error if err != nil { return fmt.Errorf("failed to send upload request: %w", err) @@ -309,6 +312,7 @@ func (cli *Client) UploadGroupAvatar(ctx context.Context, avatarBytes []byte, gi return "", err } body, err := io.ReadAll(resp.Body) + web.CloseBody(resp) if err != nil { log.Err(err).Msg("Error decoding response body fetching upload attributes") return "", err @@ -338,6 +342,7 @@ func (cli *Client) UploadGroupAvatar(ctx context.Context, avatarBytes []byte, gi Body: requestBody.Bytes(), ContentType: web.ContentType(w.FormDataContentType()), }) + web.CloseBody(resp) if err != nil { log.Err(err).Msg("Error sending request uploading attachment") return "", err diff --git a/pkg/signalmeow/groups.go b/pkg/signalmeow/groups.go index d8ba4b3..d956fcc 100644 --- a/pkg/signalmeow/groups.go +++ b/pkg/signalmeow/groups.go @@ -637,6 +637,7 @@ func (cli *Client) fetchGroupWithMasterKey(ctx context.Context, groupMasterKey t ContentType: web.ContentTypeProtobuf, } response, err := web.SendHTTPRequest(ctx, web.StorageHostname, http.MethodGet, "/v2/groups", opts) + defer web.CloseBody(response) if err != nil { return nil, err } @@ -689,6 +690,7 @@ func (cli *Client) DownloadGroupAvatar(ctx context.Context, avatarPath string, g Password: &password, } resp, err := web.SendHTTPRequest(ctx, web.CDN1Hostname, http.MethodGet, avatarPath, opts) + defer web.CloseBody(resp) if err != nil { return nil, fmt.Errorf("failed to send request: %w", err) } @@ -1473,6 +1475,7 @@ func (cli *Client) patchGroup(ctx context.Context, groupChange *signalpb.GroupCh Body: requestBody, } resp, err := web.SendHTTPRequest(ctx, web.StorageHostname, http.MethodPatch, path, opts) + defer web.CloseBody(resp) if err != nil { return nil, fmt.Errorf("SendRequest error: %w", err) } @@ -1706,6 +1709,7 @@ func (cli *Client) createGroupOnServer(ctx context.Context, decryptedGroup *Grou Body: requestBody, } resp, err := web.SendHTTPRequest(ctx, web.StorageHostname, http.MethodPut, path, opts) + defer web.CloseBody(resp) if err != nil { return nil, fmt.Errorf("SendRequest error: %w", err) } @@ -1776,6 +1780,7 @@ func (cli *Client) GetGroupHistoryPage(ctx context.Context, gid types.GroupIdent // highest known epoch seems to always be 5, but that may change in the future. includeLastState is always false path := fmt.Sprintf("/v2/groups/logs/%d?maxSupportedChangeEpoch=%d&includeFirstState=%t&includeLastState=false", fromRevision, 5, includeFirstState) response, err := web.SendHTTPRequest(ctx, web.StorageHostname, http.MethodGet, path, opts) + defer web.CloseBody(response) if err != nil { return nil, err } diff --git a/pkg/signalmeow/profile.go b/pkg/signalmeow/profile.go index f40d6ce..a515f5a 100644 --- a/pkg/signalmeow/profile.go +++ b/pkg/signalmeow/profile.go @@ -287,7 +287,7 @@ func (cli *Client) DownloadUserAvatar(ctx context.Context, avatarPath string, pr if err != nil { return nil, fmt.Errorf("failed to send request: %w", err) } - defer resp.Body.Close() + defer web.CloseBody(resp) if resp.StatusCode < 200 || resp.StatusCode >= 300 { return nil, fmt.Errorf("unexpected response status %d", resp.StatusCode) } diff --git a/pkg/signalmeow/storageservice.go b/pkg/signalmeow/storageservice.go index 676fc7f..fcf6848 100644 --- a/pkg/signalmeow/storageservice.go +++ b/pkg/signalmeow/storageservice.go @@ -257,6 +257,7 @@ func (cli *Client) fetchStorageManifest(ctx context.Context, storageKey []byte, Password: &storageCreds.Password, ContentType: web.ContentTypeProtobuf, }) + defer web.CloseBody(resp) if err != nil { return nil, fmt.Errorf("failed to fetch storage manifest: %w", err) } else if resp.StatusCode == http.StatusNoContent { @@ -363,11 +364,12 @@ func (cli *Client) fetchStorageItemsChunk(ctx context.Context, recordKeys [][]by Body: body, ContentType: web.ContentTypeProtobuf, }) + defer web.CloseBody(resp) if err != nil { return nil, fmt.Errorf("failed to fetch storage records: %w", err) } else if resp.StatusCode != http.StatusOK { return nil, fmt.Errorf("unexpected status code %d fetching storage records", resp.StatusCode) - } else if body, err := io.ReadAll(resp.Body); err != nil { + } else if body, err = io.ReadAll(resp.Body); err != nil { return nil, fmt.Errorf("failed to read storage manifest response: %w", err) } else if err = proto.Unmarshal(body, &storageItems); err != nil { return nil, fmt.Errorf("failed to unmarshal encrypted storage manifest: %w", err) diff --git a/pkg/signalmeow/web/web.go b/pkg/signalmeow/web/web.go index f6c6743..e18ee5a 100644 --- a/pkg/signalmeow/web/web.go +++ b/pkg/signalmeow/web/web.go @@ -168,6 +168,12 @@ func SendHTTPRequest(ctx context.Context, host, method, path string, opt *HTTPRe return resp, nil } +func CloseBody(resp *http.Response) { + if resp != nil && resp.Body != nil { + _ = resp.Body.Close() + } +} + func DecodeWSResponseBody(ctx context.Context, out any, resp *signalpb.WebSocketResponseMessage) error { if resp == nil { return nil @@ -189,7 +195,7 @@ func DecodeWSResponseBody(ctx context.Context, out any, resp *signalpb.WebSocket // DecodeHTTPResponseBody checks status code, reads an http.Response's Body and decodes it into the provided interface. func DecodeHTTPResponseBody(ctx context.Context, out any, resp *http.Response) error { - defer resp.Body.Close() + defer CloseBody(resp) // Check if status code indicates success if resp.StatusCode < 200 || resp.StatusCode >= 300 { From a2264b2bcac4d262d408450c825c82bb80faedb8 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Wed, 7 Jan 2026 15:23:42 +0200 Subject: [PATCH 506/580] client: only sync contacts on startup every 3 days --- pkg/connector/connector.go | 4 +++- pkg/connector/handlesignal.go | 6 ++++++ pkg/signalid/dbmeta.go | 3 ++- 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/pkg/connector/connector.go b/pkg/connector/connector.go index 0debb30..f9bdd68 100644 --- a/pkg/connector/connector.go +++ b/pkg/connector/connector.go @@ -32,6 +32,7 @@ import ( "maunium.net/go/mautrix/id" "go.mau.fi/mautrix-signal/pkg/msgconv" + "go.mau.fi/mautrix-signal/pkg/signalid" "go.mau.fi/mautrix-signal/pkg/signalmeow" "go.mau.fi/mautrix-signal/pkg/signalmeow/store" ) @@ -101,7 +102,8 @@ func (s *SignalConnector) LoadUserLogin(ctx context.Context, login *bridgev2.Use sc.UserLogin.Log.With().Str("component", "signalmeow").Logger(), sc.handleSignalEvent, ) - sc.Client.SyncContactsOnConnect = s.Config.SyncContactsOnStartup + sc.Client.SyncContactsOnConnect = s.Config.SyncContactsOnStartup && + time.Since(login.Metadata.(*signalid.UserLoginMetadata).LastContactSync.Time) > 3*24*time.Hour } login.Client = sc return nil diff --git a/pkg/connector/handlesignal.go b/pkg/connector/handlesignal.go index 0ad8555..c9f16c1 100644 --- a/pkg/connector/handlesignal.go +++ b/pkg/connector/handlesignal.go @@ -26,6 +26,7 @@ import ( "github.com/google/uuid" "github.com/rs/zerolog" "go.mau.fi/util/exzerolog" + "go.mau.fi/util/jsontime" "go.mau.fi/util/ptr" "maunium.net/go/mautrix/bridgev2" "maunium.net/go/mautrix/bridgev2/database" @@ -732,6 +733,11 @@ func (s *SignalClient) handleSignalContactList(evt *events.ContactList) { } } } + s.UserLogin.Metadata.(*signalid.UserLoginMetadata).LastContactSync = jsontime.UnixMilliNow() + err := s.UserLogin.Save(ctx) + if err != nil { + log.Err(err).Msg("Failed to update last contact sync time") + } } func (s *SignalClient) updateRemoteProfile(ctx context.Context, resendState bool) { diff --git a/pkg/signalid/dbmeta.go b/pkg/signalid/dbmeta.go index bbbcc92..8f42e6f 100644 --- a/pkg/signalid/dbmeta.go +++ b/pkg/signalid/dbmeta.go @@ -33,7 +33,8 @@ type MessageMetadata struct { } type UserLoginMetadata struct { - ChatsSynced bool `json:"chats_synced,omitempty"` + ChatsSynced bool `json:"chats_synced,omitempty"` + LastContactSync jsontime.UnixMilli `json:"last_contact_sync,omitempty"` } type GhostMetadata struct { From 9921199fa8ae7cf0e504ae54b8f30eabc8abfef7 Mon Sep 17 00:00:00 2001 From: Nick Mills-Barrett Date: Fri, 9 Jan 2026 12:08:09 +0000 Subject: [PATCH 507/580] signalmeow/web: expose websocket ping timeouts --- pkg/signalmeow/web/signalwebsocket.go | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/pkg/signalmeow/web/signalwebsocket.go b/pkg/signalmeow/web/signalwebsocket.go index 8a0c845..272acbb 100644 --- a/pkg/signalmeow/web/signalwebsocket.go +++ b/pkg/signalmeow/web/signalwebsocket.go @@ -37,6 +37,10 @@ import ( "go.mau.fi/mautrix-signal/pkg/signalmeow/wspb" ) +var WebsocketPingInterval = 30 * time.Second +var WebsocketPingTimeout = 20 * time.Second +var WebsocketPingTimeoutLimit = 5 + const WebsocketProvisioningPath = "/v1/websocket/provisioning/" const WebsocketPath = "/v1/websocket/" @@ -342,20 +346,20 @@ func (s *SignalWebsocket) connectLoop( // Ping loop (send a keepalive Ping every 30s) go func() { defer wg.Done() - ticker := time.NewTicker(30 * time.Second) + ticker := time.NewTicker(WebsocketPingInterval) defer ticker.Stop() pingTimeoutCount := 0 for { select { case <-ticker.C: - pingCtx, cancel := context.WithTimeout(loopCtx, 20*time.Second) + pingCtx, cancel := context.WithTimeout(loopCtx, WebsocketPingTimeout) err := ws.Ping(pingCtx) cancel() if err != nil { pingTimeoutCount++ log.Err(err).Msg("Failed to send ping") - if pingTimeoutCount >= 5 { + if pingTimeoutCount >= WebsocketPingTimeoutLimit { log.Warn().Msg("Ping timeout count exceeded, closing websocket") err = ws.Close(websocket.StatusNormalClosure, "Ping timeout") if err != nil { From f62599145fe836e75835ede91b95400bf3a88f09 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Thu, 15 Jan 2026 14:08:00 +0200 Subject: [PATCH 508/580] connector,signalmeow: implement network connection resetting (#629) --- go.mod | 4 ++-- go.sum | 8 ++++---- pkg/connector/connector.go | 23 ++++++++++++++++++++++ pkg/signalmeow/receiving.go | 5 +++++ pkg/signalmeow/web/signalwebsocket.go | 20 +++++++++++++++++++ pkg/signalmeow/web/web.go | 28 ++++----------------------- 6 files changed, 58 insertions(+), 30 deletions(-) diff --git a/go.mod b/go.mod index f898ff1..05dfac3 100644 --- a/go.mod +++ b/go.mod @@ -14,13 +14,13 @@ require ( github.com/rs/zerolog v1.34.0 github.com/stretchr/testify v1.11.1 github.com/tidwall/gjson v1.18.0 - go.mau.fi/util v0.9.4 + go.mau.fi/util v0.9.5-0.20260114152041-9f2e2b82b503 golang.org/x/crypto v0.46.0 golang.org/x/exp v0.0.0-20251209150349-8475f28825e9 golang.org/x/net v0.48.0 google.golang.org/protobuf v1.36.11 gopkg.in/yaml.v3 v3.0.1 - maunium.net/go/mautrix v0.26.1 + maunium.net/go/mautrix v0.26.2-0.20260115120200-34bcd027e54c ) require ( diff --git a/go.sum b/go.sum index 62da235..dfd2ccc 100644 --- a/go.sum +++ b/go.sum @@ -66,8 +66,8 @@ github.com/tidwall/sjson v1.2.5 h1:kLy8mja+1c9jlljvWTlSazM7cKDRfJuR/bOJhcY5NcY= github.com/tidwall/sjson v1.2.5/go.mod h1:Fvgq9kS/6ociJEDnK0Fk1cpYF4FIW6ZF7LAe+6jwd28= github.com/yuin/goldmark v1.7.13 h1:GPddIs617DnBLFFVJFgpo1aBfe/4xcvMc3SB5t/D0pA= github.com/yuin/goldmark v1.7.13/go.mod h1:ip/1k0VRfGynBgxOz0yCqHrbZXhcjxyuS66Brc7iBKg= -go.mau.fi/util v0.9.4 h1:gWdUff+K2rCynRPysXalqqQyr2ahkSWaestH6YhSpso= -go.mau.fi/util v0.9.4/go.mod h1:647nVfwUvuhlZFOnro3aRNPmRd2y3iDha9USb8aKSmM= +go.mau.fi/util v0.9.5-0.20260114152041-9f2e2b82b503 h1:L7ctH5wX8TrkZvIZmfxPkHQ1b8NZYw4fIr5WxXaewPw= +go.mau.fi/util v0.9.5-0.20260114152041-9f2e2b82b503/go.mod h1:647nVfwUvuhlZFOnro3aRNPmRd2y3iDha9USb8aKSmM= go.mau.fi/zeroconfig v0.2.0 h1:e/OGEERqVRRKlgaro7E6bh8xXiKFSXB3eNNIud7FUjU= go.mau.fi/zeroconfig v0.2.0/go.mod h1:J0Vn0prHNOm493oZoQ84kq83ZaNCYZnq+noI1b1eN8w= golang.org/x/crypto v0.46.0 h1:cKRW/pmt1pKAfetfu+RCEvjvZkA9RimPbh7bhFjGVBU= @@ -98,5 +98,5 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= maunium.net/go/mauflag v1.0.0 h1:YiaRc0tEI3toYtJMRIfjP+jklH45uDHtT80nUamyD4M= maunium.net/go/mauflag v1.0.0/go.mod h1:nLivPOpTpHnpzEh8jEdSL9UqO9+/KBJFmNRlwKfkPeA= -maunium.net/go/mautrix v0.26.1 h1:FWCC1xY5vwJ5ou3duEBjB6w9IIlwfc9el3q3Mju3Dlg= -maunium.net/go/mautrix v0.26.1/go.mod h1:UySSpb8OqXG1sMJ6dDqyzmfcqr2ayZK+KzwqOTAkAOM= +maunium.net/go/mautrix v0.26.2-0.20260115120200-34bcd027e54c h1:ZtJgvgFoH4hxNxFSavFXw7HUnjq49OyjxoEyGcjGk4k= +maunium.net/go/mautrix v0.26.2-0.20260115120200-34bcd027e54c/go.mod h1:vUvbzvY00Tbl8WjBdp5afvc69uIxujnfGHpAugxvR/Q= diff --git a/pkg/connector/connector.go b/pkg/connector/connector.go index f9bdd68..0343d02 100644 --- a/pkg/connector/connector.go +++ b/pkg/connector/connector.go @@ -24,6 +24,7 @@ import ( "github.com/google/uuid" "go.mau.fi/util/dbutil" + "go.mau.fi/util/exhttp" "go.mau.fi/util/exsync" "maunium.net/go/mautrix/bridgev2" "maunium.net/go/mautrix/bridgev2/commands" @@ -35,6 +36,7 @@ import ( "go.mau.fi/mautrix-signal/pkg/signalid" "go.mau.fi/mautrix-signal/pkg/signalmeow" "go.mau.fi/mautrix-signal/pkg/signalmeow/store" + "go.mau.fi/mautrix-signal/pkg/signalmeow/web" ) type SignalConnector struct { @@ -74,6 +76,7 @@ func (s *SignalConnector) SetMaxFileSize(maxSize int64) { } func (s *SignalConnector) Start(ctx context.Context) error { + s.ResetHTTPTransport() err := s.Store.Upgrade(ctx) if err != nil { return bridgev2.DBUpgradeError{Err: err, Section: "signalmeow"} @@ -81,6 +84,26 @@ func (s *SignalConnector) Start(ctx context.Context) error { return nil } +func (s *SignalConnector) ResetHTTPTransport() { + settings := exhttp.SensibleClientSettings + hs, ok := s.Bridge.Matrix.(bridgev2.MatrixConnectorWithHTTPSettings) + if ok { + settings = hs.GetHTTPClientSettings() + } + oldClient := web.SignalHTTPClient + web.SignalHTTPClient = settings.WithTLSConfig(web.SignalTLSConfig).Compile() + oldClient.CloseIdleConnections() +} + +func (s *SignalConnector) ResetNetworkConnections() { + for _, login := range s.Bridge.GetAllCachedUserLogins() { + c := login.Client.(*SignalClient) + if c.Client != nil { + c.Client.ForceReconnect() + } + } +} + func (s *SignalConnector) LoadUserLogin(ctx context.Context, login *bridgev2.UserLogin) error { aci, err := uuid.Parse(string(login.ID)) if err != nil { diff --git a/pkg/signalmeow/receiving.go b/pkg/signalmeow/receiving.go index 1b4dce0..b802e06 100644 --- a/pkg/signalmeow/receiving.go +++ b/pkg/signalmeow/receiving.go @@ -280,6 +280,11 @@ func (cli *Client) StartReceiveLoops(ctx context.Context) (chan SignalConnection return statusChan, nil } +func (cli *Client) ForceReconnect() { + cli.AuthedWS.ForceReconnect() + cli.UnauthedWS.ForceReconnect() +} + func (cli *Client) StopReceiveLoops() error { defer func() { cli.AuthedWS = nil diff --git a/pkg/signalmeow/web/signalwebsocket.go b/pkg/signalmeow/web/signalwebsocket.go index 272acbb..a2153a1 100644 --- a/pkg/signalmeow/web/signalwebsocket.go +++ b/pkg/signalmeow/web/signalwebsocket.go @@ -59,6 +59,7 @@ type SignalWebsocket struct { closeEvt *exsync.Event closeCalled atomic.Bool cancel atomic.Pointer[context.CancelFunc] + cancelConn atomic.Pointer[context.CancelCauseFunc] } func NewSignalWebsocket(basicAuth *url.Userinfo) *SignalWebsocket { @@ -160,6 +161,19 @@ func (s *SignalWebsocket) pushOutgoing(ctx context.Context, send SignalWebsocket } } +var ErrForcedReconnect = errors.New("forced reconnect") + +func (s *SignalWebsocket) ForceReconnect() { + if s == nil { + return + } + cancelFn := s.cancelConn.Load() + if cancelFn == nil { + return + } + (*cancelFn)(ErrForcedReconnect) +} + func (s *SignalWebsocket) connectLoop( ctx context.Context, requestHandler RequestHandlerFunc, @@ -312,6 +326,7 @@ func (s *SignalWebsocket) connectLoop( responseChannels := exsync.NewMap[uint64, chan *signalpb.WebSocketResponseMessage]() loopCtx, loopCancel := context.WithCancelCause(ctx) + s.cancelConn.Store(&loopCancel) var wg sync.WaitGroup wg.Add(3) @@ -389,6 +404,11 @@ func (s *SignalWebsocket) connectLoop( } else { errorCount++ s.pushStatus(ctx, SignalWebsocketConnectionEventDisconnected, ctxCauseErr) + if errors.Is(ctxCauseErr, ErrForcedReconnect) { + // Skip the delay for forced reconnects + // TODO should the delay be lowered globally? + isFirstConnect = true + } } // Clean up diff --git a/pkg/signalmeow/web/web.go b/pkg/signalmeow/web/web.go index e18ee5a..d0fcd01 100644 --- a/pkg/signalmeow/web/web.go +++ b/pkg/signalmeow/web/web.go @@ -26,8 +26,6 @@ import ( "fmt" "io" "net/http" - "net/url" - "os" "runtime" "strings" @@ -37,9 +35,6 @@ import ( signalpb "go.mau.fi/mautrix-signal/pkg/signalmeow/protobuf" ) -const proxyUrlStr = "" // Set this to proxy requests -const caCertPath = "" // Set this to trust a self-signed cert (ie. for mitmproxy) - var BaseUserAgent = "libsignal/" + libsignalgo.Version + " go/" + strings.TrimPrefix(runtime.Version(), "go") var UserAgent = "signalmeow/0.1.0 " + BaseUserAgent var SignalAgent = "MAU" @@ -61,11 +56,11 @@ var CDNHosts = []string{ //go:embed signal-root.crt.der var signalRootCertBytes []byte +var SignalCertPool = x509.NewCertPool() +var SignalTLSConfig = &tls.Config{RootCAs: SignalCertPool} var signalTransport = &http.Transport{ ForceAttemptHTTP2: true, - TLSClientConfig: &tls.Config{ - RootCAs: x509.NewCertPool(), - }, + TLSClientConfig: SignalTLSConfig, } var SignalHTTPClient = &http.Client{ Transport: signalTransport, @@ -76,22 +71,7 @@ func init() { if err != nil { panic(err) } - signalTransport.TLSClientConfig.RootCAs.AddCert(cert) - - if proxyUrlStr != "" { - proxyURL, err := url.Parse(proxyUrlStr) - if err != nil { - panic(err) - } - signalTransport.Proxy = http.ProxyURL(proxyURL) - } - if caCertPath != "" { - caCert, err := os.ReadFile(caCertPath) - if err != nil { - panic(err) - } - signalTransport.TLSClientConfig.RootCAs.AppendCertsFromPEM(caCert) - } + SignalCertPool.AddCert(cert) } type ContentType string From d19f3bdce3fdfc94aeaaea66eb9a3bcdc6555746 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Fri, 16 Jan 2026 15:01:48 +0200 Subject: [PATCH 509/580] libsignal: update to v0.86.12 --- pkg/libsignalgo/error.go | 107 +++++++++--- pkg/libsignalgo/groupcipher.go | 2 +- pkg/libsignalgo/kyberprekeystore.go | 35 ++-- pkg/libsignalgo/libsignal | 2 +- pkg/libsignalgo/libsignal-ffi.h | 154 ++++++++++++------ .../senderkeydistributionmessage.go | 2 +- pkg/libsignalgo/serviceid.go | 6 - pkg/libsignalgo/version.go | 2 +- 8 files changed, 209 insertions(+), 101 deletions(-) diff --git a/pkg/libsignalgo/error.go b/pkg/libsignalgo/error.go index b0d79c8..b25130b 100644 --- a/pkg/libsignalgo/error.go +++ b/pkg/libsignalgo/error.go @@ -27,33 +27,86 @@ import ( type ErrorCode int const ( - ErrorCodeUnknownError ErrorCode = 1 - ErrorCodeInvalidState ErrorCode = 2 - ErrorCodeInternalError ErrorCode = 3 - ErrorCodeNullParameter ErrorCode = 4 - ErrorCodeInvalidArgument ErrorCode = 5 - ErrorCodeInvalidType ErrorCode = 6 - ErrorCodeInvalidUtf8String ErrorCode = 7 - ErrorCodeProtobufError ErrorCode = 10 - ErrorCodeLegacyCiphertextVersion ErrorCode = 21 - ErrorCodeUnknownCiphertextVersion ErrorCode = 22 - ErrorCodeUnrecognizedMessageVersion ErrorCode = 23 - ErrorCodeInvalidMessage ErrorCode = 30 - ErrorCodeSealedSenderSelfSend ErrorCode = 31 - ErrorCodeInvalidKey ErrorCode = 40 - ErrorCodeInvalidSignature ErrorCode = 41 - ErrorCodeInvalidAttestationData ErrorCode = 42 - ErrorCodeFingerprintVersionMismatch ErrorCode = 51 - ErrorCodeFingerprintParsingError ErrorCode = 52 - ErrorCodeUntrustedIdentity ErrorCode = 60 - ErrorCodeInvalidKeyIdentifier ErrorCode = 70 - ErrorCodeSessionNotFound ErrorCode = 80 - ErrorCodeInvalidRegistrationId ErrorCode = 81 - ErrorCodeInvalidSession ErrorCode = 82 - ErrorCodeInvalidSenderKeySession ErrorCode = 83 - ErrorCodeDuplicatedMessage ErrorCode = 90 - ErrorCodeCallbackError ErrorCode = 100 - ErrorCodeVerificationFailure ErrorCode = 110 + ErrorCodeUnknownError ErrorCode = 1 + ErrorCodeInvalidState ErrorCode = 2 + ErrorCodeInternalError ErrorCode = 3 + ErrorCodeNullParameter ErrorCode = 4 + ErrorCodeInvalidArgument ErrorCode = 5 + ErrorCodeInvalidType ErrorCode = 6 + ErrorCodeInvalidUtf8String ErrorCode = 7 + ErrorCodeCancelled ErrorCode = 8 + ErrorCodeProtobufError ErrorCode = 10 + ErrorCodeLegacyCiphertextVersion ErrorCode = 21 + ErrorCodeUnknownCiphertextVersion ErrorCode = 22 + ErrorCodeUnrecognizedMessageVersion ErrorCode = 23 + ErrorCodeInvalidMessage ErrorCode = 30 + ErrorCodeSealedSenderSelfSend ErrorCode = 31 + ErrorCodeInvalidKey ErrorCode = 40 + ErrorCodeInvalidSignature ErrorCode = 41 + ErrorCodeInvalidAttestationData ErrorCode = 42 + ErrorCodeFingerprintVersionMismatch ErrorCode = 51 + ErrorCodeFingerprintParsingError ErrorCode = 52 + ErrorCodeUntrustedIdentity ErrorCode = 60 + ErrorCodeInvalidKeyIdentifier ErrorCode = 70 + ErrorCodeSessionNotFound ErrorCode = 80 + ErrorCodeInvalidRegistrationId ErrorCode = 81 + ErrorCodeInvalidSession ErrorCode = 82 + ErrorCodeInvalidSenderKeySession ErrorCode = 83 + ErrorCodeInvalidProtocolAddress ErrorCode = 84 + ErrorCodeDuplicatedMessage ErrorCode = 90 + ErrorCodeCallbackError ErrorCode = 100 + ErrorCodeVerificationFailure ErrorCode = 110 + ErrorCodeUsernameCannotBeEmpty ErrorCode = 120 + ErrorCodeUsernameCannotStartWithDigit ErrorCode = 121 + ErrorCodeUsernameMissingSeparator ErrorCode = 122 + ErrorCodeUsernameBadDiscriminatorCharacter ErrorCode = 123 + ErrorCodeUsernameBadNicknameCharacter ErrorCode = 124 + ErrorCodeUsernameTooShort ErrorCode = 125 + ErrorCodeUsernameTooLong ErrorCode = 126 + ErrorCodeUsernameLinkInvalidEntropyDataLength ErrorCode = 127 + ErrorCodeUsernameLinkInvalid ErrorCode = 128 + ErrorCodeUsernameDiscriminatorCannotBeEmpty ErrorCode = 130 + ErrorCodeUsernameDiscriminatorCannotBeZero ErrorCode = 131 + ErrorCodeUsernameDiscriminatorCannotBeSingleDigit ErrorCode = 132 + ErrorCodeUsernameDiscriminatorCannotHaveLeadingZeros ErrorCode = 133 + ErrorCodeUsernameDiscriminatorTooLarge ErrorCode = 134 + ErrorCodeIoError ErrorCode = 140 + ErrorCodeInvalidMediaInput ErrorCode = 141 + ErrorCodeUnsupportedMediaInput ErrorCode = 142 + ErrorCodeConnectionTimedOut ErrorCode = 143 + ErrorCodeNetworkProtocol ErrorCode = 144 + ErrorCodeRateLimited ErrorCode = 145 + ErrorCodeWebSocket ErrorCode = 146 + ErrorCodeCdsiInvalidToken ErrorCode = 147 + ErrorCodeConnectionFailed ErrorCode = 148 + ErrorCodeChatServiceInactive ErrorCode = 149 + ErrorCodeRequestTimedOut ErrorCode = 150 + ErrorCodeRateLimitChallenge ErrorCode = 151 + ErrorCodePossibleCaptiveNetwork ErrorCode = 152 + ErrorCodeSvrDataMissing ErrorCode = 160 + ErrorCodeSvrRestoreFailed ErrorCode = 161 + ErrorCodeSvrRotationMachineTooManySteps ErrorCode = 162 + ErrorCodeSvrRequestFailed ErrorCode = 163 + ErrorCodeAppExpired ErrorCode = 170 + ErrorCodeDeviceDeregistered ErrorCode = 171 + ErrorCodeConnectionInvalidated ErrorCode = 172 + ErrorCodeConnectedElsewhere ErrorCode = 173 + ErrorCodeBackupValidation ErrorCode = 180 + ErrorCodeRegistrationInvalidSessionId ErrorCode = 190 + ErrorCodeRegistrationUnknown ErrorCode = 192 + ErrorCodeRegistrationSessionNotFound ErrorCode = 193 + ErrorCodeRegistrationNotReadyForVerification ErrorCode = 194 + ErrorCodeRegistrationSendVerificationCodeFailed ErrorCode = 195 + ErrorCodeRegistrationCodeNotDeliverable ErrorCode = 196 + ErrorCodeRegistrationSessionUpdateRejected ErrorCode = 197 + ErrorCodeRegistrationCredentialsCouldNotBeParsed ErrorCode = 198 + ErrorCodeRegistrationDeviceTransferPossible ErrorCode = 199 + ErrorCodeRegistrationRecoveryVerificationFailed ErrorCode = 200 + ErrorCodeRegistrationLock ErrorCode = 201 + ErrorCodeKeyTransparencyError ErrorCode = 210 + ErrorCodeKeyTransparencyVerificationFailed ErrorCode = 211 + ErrorCodeRequestUnauthorized ErrorCode = 220 + ErrorCodeMismatchedDevices ErrorCode = 221 ) type SignalError struct { diff --git a/pkg/libsignalgo/groupcipher.go b/pkg/libsignalgo/groupcipher.go index 7b58207..9ec5997 100644 --- a/pkg/libsignalgo/groupcipher.go +++ b/pkg/libsignalgo/groupcipher.go @@ -36,7 +36,7 @@ func GroupEncrypt(ctx context.Context, ptext []byte, sender *Address, distributi signalFfiError := C.signal_group_encrypt_message( &ciphertextMessage, sender.constPtr(), - (*[C.SignalUUID_LEN]C.uchar)(unsafe.Pointer(&distributionID)), + *(*C.SignalUuid)(unsafe.Pointer(&distributionID)), BytesToBuffer(ptext), callbackCtx.wrapSenderKeyStore(store)) runtime.KeepAlive(ptext) diff --git a/pkg/libsignalgo/kyberprekeystore.go b/pkg/libsignalgo/kyberprekeystore.go index 072db99..ebb5a9f 100644 --- a/pkg/libsignalgo/kyberprekeystore.go +++ b/pkg/libsignalgo/kyberprekeystore.go @@ -20,11 +20,10 @@ package libsignalgo /* #include "./libsignal-ffi.h" -typedef const SignalKyberPreKeyRecord const_kyber_pre_key_record; - -extern int signal_load_kyber_pre_key_callback(void *store_ctx, SignalKyberPreKeyRecord **recordp, uint32_t id); -extern int signal_store_kyber_pre_key_callback(void *store_ctx, uint32_t id, const_kyber_pre_key_record *record); -extern int signal_mark_kyber_pre_key_used_callback(void *store_ctx, uint32_t id); +extern int signal_load_kyber_pre_key_callback(void *store_ctx, SignalMutPointerKyberPreKeyRecord *recordp, uint32_t id); +extern int signal_store_kyber_pre_key_callback(void *store_ctx, uint32_t id, SignalMutPointerKyberPreKeyRecord record); +extern int signal_mark_kyber_pre_key_used_callback(void *store_ctx, uint32_t id, uint32_t ec_prekey_id, SignalMutPointerPublicKey base_key); +extern void signal_destroy_kyber_pre_key_store_callback(void *store_ctx); */ import "C" import ( @@ -39,21 +38,21 @@ type KyberPreKeyStore interface { } //export signal_load_kyber_pre_key_callback -func signal_load_kyber_pre_key_callback(storeCtx unsafe.Pointer, keyp **C.SignalKyberPreKeyRecord, id C.uint32_t) C.int { +func signal_load_kyber_pre_key_callback(storeCtx unsafe.Pointer, keyp *C.SignalMutPointerKyberPreKeyRecord, id C.uint32_t) C.int { return wrapStoreCallback(storeCtx, func(store KyberPreKeyStore, ctx context.Context) error { key, err := store.LoadKyberPreKey(ctx, uint32(id)) if err == nil && key != nil { key.CancelFinalizer() - *keyp = key.ptr + keyp.raw = key.ptr } return err }) } //export signal_store_kyber_pre_key_callback -func signal_store_kyber_pre_key_callback(storeCtx unsafe.Pointer, id C.uint32_t, preKeyRecord *C.const_kyber_pre_key_record) C.int { +func signal_store_kyber_pre_key_callback(storeCtx unsafe.Pointer, id C.uint32_t, preKeyRecord C.SignalMutPointerKyberPreKeyRecord) C.int { return wrapStoreCallback(storeCtx, func(store KyberPreKeyStore, ctx context.Context) error { - record := KyberPreKeyRecord{ptr: (*C.SignalKyberPreKeyRecord)(unsafe.Pointer(preKeyRecord))} + record := KyberPreKeyRecord{ptr: preKeyRecord.raw} cloned, err := record.Clone() if err != nil { return err @@ -63,18 +62,24 @@ func signal_store_kyber_pre_key_callback(storeCtx unsafe.Pointer, id C.uint32_t, } //export signal_mark_kyber_pre_key_used_callback -func signal_mark_kyber_pre_key_used_callback(storeCtx unsafe.Pointer, id C.uint32_t) C.int { +func signal_mark_kyber_pre_key_used_callback(storeCtx unsafe.Pointer, id C.uint32_t, ecPrekeyID C.uint32_t, baseKey C.SignalMutPointerPublicKey) C.int { return wrapStoreCallback(storeCtx, func(store KyberPreKeyStore, ctx context.Context) error { - err := store.MarkKyberPreKeyUsed(ctx, uint32(id)) - return err + // TODO use ecPrekeyID and baseKey? + return store.MarkKyberPreKeyUsed(ctx, uint32(id)) }) } +//export signal_destroy_kyber_pre_key_store_callback +func signal_destroy_kyber_pre_key_store_callback(storeCtx unsafe.Pointer) { + // No-op: Go's garbage collector handles cleanup +} + func (ctx *CallbackContext) wrapKyberPreKeyStore(store KyberPreKeyStore) C.SignalConstPointerFfiKyberPreKeyStoreStruct { return C.SignalConstPointerFfiKyberPreKeyStoreStruct{&C.SignalKyberPreKeyStore{ ctx: wrapStore(ctx, store), - load_kyber_pre_key: C.SignalLoadKyberPreKey(C.signal_load_kyber_pre_key_callback), - store_kyber_pre_key: C.SignalStoreKyberPreKey(C.signal_store_kyber_pre_key_callback), - mark_kyber_pre_key_used: C.SignalMarkKyberPreKeyUsed(C.signal_mark_kyber_pre_key_used_callback), + load_kyber_pre_key: C.SignalFfiBridgeKyberPreKeyStoreLoadKyberPreKey(C.signal_load_kyber_pre_key_callback), + store_kyber_pre_key: C.SignalFfiBridgeKyberPreKeyStoreStoreKyberPreKey(C.signal_store_kyber_pre_key_callback), + mark_kyber_pre_key_used: C.SignalFfiBridgeKyberPreKeyStoreMarkKyberPreKeyUsed(C.signal_mark_kyber_pre_key_used_callback), + destroy: C.SignalFfiBridgeKyberPreKeyStoreDestroy(C.signal_destroy_kyber_pre_key_store_callback), }} } diff --git a/pkg/libsignalgo/libsignal b/pkg/libsignalgo/libsignal index ace4048..0480b16 160000 --- a/pkg/libsignalgo/libsignal +++ b/pkg/libsignalgo/libsignal @@ -1 +1 @@ -Subproject commit ace404879f5dc146a512d88f696115715095a841 +Subproject commit 0480b16ac3c4ca9d641bc160b1b231f89d2e5fe3 diff --git a/pkg/libsignalgo/libsignal-ffi.h b/pkg/libsignalgo/libsignal-ffi.h index 26cbb6b..e2ddc02 100644 --- a/pkg/libsignalgo/libsignal-ffi.h +++ b/pkg/libsignalgo/libsignal-ffi.h @@ -233,6 +233,7 @@ typedef enum { SignalErrorCodeChatServiceInactive = 149, SignalErrorCodeRequestTimedOut = 150, SignalErrorCodeRateLimitChallenge = 151, + SignalErrorCodePossibleCaptiveNetwork = 152, SignalErrorCodeSvrDataMissing = 160, SignalErrorCodeSvrRestoreFailed = 161, SignalErrorCodeSvrRotationMachineTooManySteps = 162, @@ -341,6 +342,8 @@ typedef struct SignalPrivateKey SignalPrivateKey; */ typedef struct SignalProtocolAddress SignalProtocolAddress; +typedef struct SignalProvisioningChatConnection SignalProvisioningChatConnection; + typedef struct SignalPublicKey SignalPublicKey; typedef struct SignalRegisterAccountRequest SignalRegisterAccountRequest; @@ -511,9 +514,13 @@ typedef struct { SignalChatConnectionInfo *raw; } SignalMutPointerChatConnectionInfo; -typedef void (*SignalReceivedIncomingMessage)(void *ctx, SignalOwnedBuffer envelope, uint64_t timestamp_millis, SignalServerMessageAck *cleanup); +typedef struct { + SignalServerMessageAck *raw; +} SignalMutPointerServerMessageAck; -typedef void (*SignalReceivedQueueEmpty)(void *ctx); +typedef int (*SignalFfiChatListenerReceivedIncomingMessage)(void *ctx, SignalOwnedBuffer envelope, uint64_t timestamp, SignalMutPointerServerMessageAck ack); + +typedef int (*SignalFfiChatListenerReceivedQueueEmpty)(void *ctx); /** * A representation of a array allocated on the Rust heap for use in C code. @@ -533,34 +540,19 @@ typedef struct { typedef SignalBytestringArray SignalStringArray; -typedef void (*SignalReceivedAlerts)(void *ctx, SignalStringArray alerts); +typedef int (*SignalFfiChatListenerReceivedAlerts)(void *ctx, SignalStringArray alerts); -typedef void (*SignalConnectionInterrupted)(void *ctx, SignalFfiError *error); +typedef int (*SignalFfiChatListenerConnectionInterrupted)(void *ctx, SignalFfiError *disconnect_cause); -typedef void (*SignalDestroyChatListener)(void *ctx); +typedef void (*SignalFfiChatListenerDestroy)(void *ctx); -/** - * Callbacks for [`ChatListener`]. - * - * Callbacks will be serialized (i.e. two calls will not come in at the same time), but may not - * always happen on the same thread. Calls should be responded to promptly to avoid blocking later - * messages. - * - * # Safety - * - * This type contains raw pointers. Code that constructs an instance of this type must ensure - * memory safety assuming that - * - the callback function pointer fields are called with `ctx` as an argument; - * - the `destroy` function pointer field is called with `ctx` as an argument; - * - no function pointer fields are called after `destroy` is called. - */ typedef struct { void *ctx; - SignalReceivedIncomingMessage received_incoming_message; - SignalReceivedQueueEmpty received_queue_empty; - SignalReceivedAlerts received_alerts; - SignalConnectionInterrupted connection_interrupted; - SignalDestroyChatListener destroy; + SignalFfiChatListenerReceivedIncomingMessage received_incoming_message; + SignalFfiChatListenerReceivedQueueEmpty received_queue_empty; + SignalFfiChatListenerReceivedAlerts received_alerts; + SignalFfiChatListenerConnectionInterrupted connection_interrupted; + SignalFfiChatListenerDestroy destroy; } SignalFfiChatListenerStruct; typedef struct { @@ -610,6 +602,13 @@ typedef struct { const SignalHttpRequest *raw; } SignalConstPointerHttpRequest; +/** + * A wrapper type for raw UUIDs, because C treats arrays specially in argument position. + */ +typedef struct { + uint8_t bytes[16]; +} SignalUuid; + /** * The fixed-width binary representation of a ServiceId. * @@ -860,22 +859,23 @@ typedef struct { SignalKyberPreKeyRecord *raw; } SignalMutPointerKyberPreKeyRecord; -typedef int (*SignalLoadKyberPreKey)(void *store_ctx, SignalMutPointerKyberPreKeyRecord *recordp, uint32_t id); +typedef int (*SignalFfiBridgeKyberPreKeyStoreLoadKyberPreKey)(void *ctx, SignalMutPointerKyberPreKeyRecord *out, uint32_t id); -typedef struct { - const SignalKyberPreKeyRecord *raw; -} SignalConstPointerKyberPreKeyRecord; +typedef int (*SignalFfiBridgeKyberPreKeyStoreStoreKyberPreKey)(void *ctx, uint32_t id, SignalMutPointerKyberPreKeyRecord record); -typedef int (*SignalStoreKyberPreKey)(void *store_ctx, uint32_t id, SignalConstPointerKyberPreKeyRecord record); +typedef int (*SignalFfiBridgeKyberPreKeyStoreMarkKyberPreKeyUsed)(void *ctx, uint32_t id, uint32_t ec_prekey_id, SignalMutPointerPublicKey base_key); -typedef int (*SignalMarkKyberPreKeyUsed)(void *store_ctx, uint32_t id, uint32_t signed_prekey_id, SignalConstPointerPublicKey base_key); +typedef void (*SignalFfiBridgeKyberPreKeyStoreDestroy)(void *ctx); typedef struct { void *ctx; - SignalLoadKyberPreKey load_kyber_pre_key; - SignalStoreKyberPreKey store_kyber_pre_key; - SignalMarkKyberPreKeyUsed mark_kyber_pre_key_used; -} SignalKyberPreKeyStore; + SignalFfiBridgeKyberPreKeyStoreLoadKyberPreKey load_kyber_pre_key; + SignalFfiBridgeKyberPreKeyStoreStoreKyberPreKey store_kyber_pre_key; + SignalFfiBridgeKyberPreKeyStoreMarkKyberPreKeyUsed mark_kyber_pre_key_used; + SignalFfiBridgeKyberPreKeyStoreDestroy destroy; +} SignalFfiBridgeKyberPreKeyStoreStruct; + +typedef SignalFfiBridgeKyberPreKeyStoreStruct SignalKyberPreKeyStore; typedef struct { const SignalKyberPreKeyStore *raw; @@ -1104,6 +1104,10 @@ typedef struct { SignalKyberSecretKey *raw; } SignalMutPointerKyberSecretKey; +typedef struct { + const SignalKyberPreKeyRecord *raw; +} SignalConstPointerKyberPreKeyRecord; + typedef struct { const SignalKyberPublicKey *raw; } SignalConstPointerKyberPublicKey; @@ -1186,6 +1190,49 @@ typedef struct { const SignalSenderKeyDistributionMessage *raw; } SignalConstPointerSenderKeyDistributionMessage; +typedef struct { + SignalProvisioningChatConnection *raw; +} SignalMutPointerProvisioningChatConnection; + +/** + * A C callback used to report the results of Rust futures. + * + * cbindgen will produce independent C types like `SignalCPromisei32` and + * `SignalCPromiseProtocolAddress`. + * + * This derives Copy because it behaves like a C type; nevertheless, a promise should still only be + * completed once. + */ +typedef struct { + void (*complete)(SignalFfiError *error, const SignalMutPointerProvisioningChatConnection *result, const void *context); + const void *context; + SignalCancellationId cancellation_id; +} SignalCPromiseMutPointerProvisioningChatConnection; + +typedef struct { + const SignalProvisioningChatConnection *raw; +} SignalConstPointerProvisioningChatConnection; + +typedef int (*SignalFfiProvisioningListenerReceivedAddress)(void *ctx, const char *address, SignalMutPointerServerMessageAck send_ack); + +typedef int (*SignalFfiProvisioningListenerReceivedEnvelope)(void *ctx, SignalOwnedBuffer envelope, SignalMutPointerServerMessageAck send_ack); + +typedef int (*SignalFfiProvisioningListenerConnectionInterrupted)(void *ctx, SignalFfiError *disconnect_cause); + +typedef void (*SignalFfiProvisioningListenerDestroy)(void *ctx); + +typedef struct { + void *ctx; + SignalFfiProvisioningListenerReceivedAddress received_address; + SignalFfiProvisioningListenerReceivedEnvelope received_envelope; + SignalFfiProvisioningListenerConnectionInterrupted connection_interrupted; + SignalFfiProvisioningListenerDestroy destroy; +} SignalFfiProvisioningListenerStruct; + +typedef struct { + const SignalFfiProvisioningListenerStruct *raw; +} SignalConstPointerFfiProvisioningListenerStruct; + typedef struct { SignalRegisterAccountRequest *raw; } SignalMutPointerRegisterAccountRequest; @@ -1209,7 +1256,10 @@ typedef struct { const SignalRegisterAccountResponse *raw; } SignalConstPointerRegisterAccountResponse; -typedef uint8_t SignalOptionalUuid[17]; +typedef struct { + bool present; + uint8_t bytes[16]; +} SignalOptionalUuid; typedef SignalAccountAttributes SignalRegistrationAccountAttributes; @@ -1402,10 +1452,6 @@ typedef struct { const SignalSenderKeyMessage *raw; } SignalConstPointerSenderKeyMessage; -typedef struct { - SignalServerMessageAck *raw; -} SignalMutPointerServerMessageAck; - typedef struct { const SignalServerMessageAck *raw; } SignalConstPointerServerMessageAck; @@ -1606,7 +1652,7 @@ SignalFfiError *signal_backup_auth_credential_request_context_check_valid_conten SignalFfiError *signal_backup_auth_credential_request_context_get_request(SignalOwnedBuffer *out, SignalBorrowedBuffer context_bytes); -SignalFfiError *signal_backup_auth_credential_request_context_new(SignalOwnedBuffer *out, const uint8_t (*backup_key)[32], const uint8_t (*uuid)[16]); +SignalFfiError *signal_backup_auth_credential_request_context_new(SignalOwnedBuffer *out, const uint8_t (*backup_key)[32], SignalUuid uuid); SignalFfiError *signal_backup_auth_credential_request_context_receive_response(SignalOwnedBuffer *out, SignalBorrowedBuffer context_bytes, SignalBorrowedBuffer response_bytes, uint64_t expected_redemption_time, SignalBorrowedBuffer params_bytes); @@ -1804,7 +1850,7 @@ uint32_t signal_error_get_type(const SignalFfiError *err); SignalFfiError *signal_error_get_unknown_fields(SignalStringArray *out, SignalUnwindSafeArgSignalFfiError err); -SignalFfiError *signal_error_get_uuid(uint8_t (*out)[16], SignalUnwindSafeArgSignalFfiError err); +SignalFfiError *signal_error_get_uuid(SignalUuid *out, SignalUnwindSafeArgSignalFfiError err); SignalFfiError *signal_expiring_profile_key_credential_check_valid_contents(SignalBorrowedBuffer buffer); @@ -1850,7 +1896,7 @@ SignalFfiError *signal_generic_server_secret_params_get_public_params(SignalOwne SignalFfiError *signal_group_decrypt_message(SignalOwnedBuffer *out, SignalConstPointerProtocolAddress sender, SignalBorrowedBuffer message, SignalConstPointerFfiSenderKeyStoreStruct store); -SignalFfiError *signal_group_encrypt_message(SignalMutPointerCiphertextMessage *out, SignalConstPointerProtocolAddress sender, const uint8_t (*distribution_id)[16], SignalBorrowedBuffer message, SignalConstPointerFfiSenderKeyStoreStruct store); +SignalFfiError *signal_group_encrypt_message(SignalMutPointerCiphertextMessage *out, SignalConstPointerProtocolAddress sender, SignalUuid distribution_id, SignalBorrowedBuffer message, SignalConstPointerFfiSenderKeyStoreStruct store); SignalFfiError *signal_group_master_key_check_valid_contents(SignalBorrowedBuffer buffer); @@ -2226,6 +2272,16 @@ SignalFfiError *signal_profile_key_get_commitment(unsigned char (*out)[SignalPRO SignalFfiError *signal_profile_key_get_profile_key_version(uint8_t (*out)[SignalPROFILE_KEY_VERSION_ENCODED_LEN], const unsigned char (*profile_key)[SignalPROFILE_KEY_LEN], const SignalServiceIdFixedWidthBinaryBytes *user_id); +SignalFfiError *signal_provisioning_chat_connection_connect(SignalCPromiseMutPointerProvisioningChatConnection *promise, SignalConstPointerTokioAsyncContext async_runtime, SignalConstPointerConnectionManager connection_manager); + +SignalFfiError *signal_provisioning_chat_connection_destroy(SignalMutPointerProvisioningChatConnection p); + +SignalFfiError *signal_provisioning_chat_connection_disconnect(SignalCPromisebool *promise, SignalConstPointerTokioAsyncContext async_runtime, SignalConstPointerProvisioningChatConnection chat); + +SignalFfiError *signal_provisioning_chat_connection_info(SignalMutPointerChatConnectionInfo *out, SignalConstPointerProvisioningChatConnection chat); + +SignalFfiError *signal_provisioning_chat_connection_init_listener(SignalConstPointerProvisioningChatConnection chat, SignalConstPointerFfiProvisioningListenerStruct listener); + SignalFfiError *signal_publickey_clone(SignalMutPointerPublicKey *new_obj, SignalConstPointerPublicKey obj); SignalFfiError *signal_publickey_compare(int32_t *out, SignalConstPointerPublicKey key1, SignalConstPointerPublicKey key2); @@ -2402,7 +2458,7 @@ SignalFfiError *signal_sender_certificate_validate(bool *out, SignalConstPointer SignalFfiError *signal_sender_key_distribution_message_clone(SignalMutPointerSenderKeyDistributionMessage *new_obj, SignalConstPointerSenderKeyDistributionMessage obj); -SignalFfiError *signal_sender_key_distribution_message_create(SignalMutPointerSenderKeyDistributionMessage *out, SignalConstPointerProtocolAddress sender, const uint8_t (*distribution_id)[16], SignalConstPointerFfiSenderKeyStoreStruct store); +SignalFfiError *signal_sender_key_distribution_message_create(SignalMutPointerSenderKeyDistributionMessage *out, SignalConstPointerProtocolAddress sender, SignalUuid distribution_id, SignalConstPointerFfiSenderKeyStoreStruct store); SignalFfiError *signal_sender_key_distribution_message_deserialize(SignalMutPointerSenderKeyDistributionMessage *out, SignalBorrowedBuffer data); @@ -2412,13 +2468,13 @@ SignalFfiError *signal_sender_key_distribution_message_get_chain_id(uint32_t *ou SignalFfiError *signal_sender_key_distribution_message_get_chain_key(SignalOwnedBuffer *out, SignalConstPointerSenderKeyDistributionMessage obj); -SignalFfiError *signal_sender_key_distribution_message_get_distribution_id(uint8_t (*out)[16], SignalConstPointerSenderKeyDistributionMessage obj); +SignalFfiError *signal_sender_key_distribution_message_get_distribution_id(SignalUuid *out, SignalConstPointerSenderKeyDistributionMessage obj); SignalFfiError *signal_sender_key_distribution_message_get_iteration(uint32_t *out, SignalConstPointerSenderKeyDistributionMessage obj); SignalFfiError *signal_sender_key_distribution_message_get_signature_key(SignalMutPointerPublicKey *out, SignalConstPointerSenderKeyDistributionMessage m); -SignalFfiError *signal_sender_key_distribution_message_new(SignalMutPointerSenderKeyDistributionMessage *out, uint8_t message_version, const uint8_t (*distribution_id)[16], uint32_t chain_id, uint32_t iteration, SignalBorrowedBuffer chainkey, SignalConstPointerPublicKey pk); +SignalFfiError *signal_sender_key_distribution_message_new(SignalMutPointerSenderKeyDistributionMessage *out, uint8_t message_version, SignalUuid distribution_id, uint32_t chain_id, uint32_t iteration, SignalBorrowedBuffer chainkey, SignalConstPointerPublicKey pk); SignalFfiError *signal_sender_key_distribution_message_serialize(SignalOwnedBuffer *out, SignalConstPointerSenderKeyDistributionMessage obj); @@ -2432,11 +2488,11 @@ SignalFfiError *signal_sender_key_message_get_chain_id(uint32_t *out, SignalCons SignalFfiError *signal_sender_key_message_get_cipher_text(SignalOwnedBuffer *out, SignalConstPointerSenderKeyMessage obj); -SignalFfiError *signal_sender_key_message_get_distribution_id(uint8_t (*out)[16], SignalConstPointerSenderKeyMessage obj); +SignalFfiError *signal_sender_key_message_get_distribution_id(SignalUuid *out, SignalConstPointerSenderKeyMessage obj); SignalFfiError *signal_sender_key_message_get_iteration(uint32_t *out, SignalConstPointerSenderKeyMessage obj); -SignalFfiError *signal_sender_key_message_new(SignalMutPointerSenderKeyMessage *out, uint8_t message_version, const uint8_t (*distribution_id)[16], uint32_t chain_id, uint32_t iteration, SignalBorrowedBuffer ciphertext, SignalConstPointerPrivateKey pk); +SignalFfiError *signal_sender_key_message_new(SignalMutPointerSenderKeyMessage *out, uint8_t message_version, SignalUuid distribution_id, uint32_t chain_id, uint32_t iteration, SignalBorrowedBuffer ciphertext, SignalConstPointerPrivateKey pk); SignalFfiError *signal_sender_key_message_serialize(SignalOwnedBuffer *out, SignalConstPointerSenderKeyMessage obj); @@ -2602,7 +2658,7 @@ SignalFfiError *signal_unauthenticated_chat_connection_init_listener(SignalConst SignalFfiError *signal_unauthenticated_chat_connection_look_up_username_hash(SignalCPromiseOptionalUuid *promise, SignalConstPointerTokioAsyncContext async_runtime, SignalConstPointerUnauthenticatedChatConnection chat, SignalBorrowedBuffer hash); -SignalFfiError *signal_unauthenticated_chat_connection_look_up_username_link(SignalCPromiseOptionalPairOfc_charu832 *promise, SignalConstPointerTokioAsyncContext async_runtime, SignalConstPointerUnauthenticatedChatConnection chat, const uint8_t (*uuid)[16], SignalBorrowedBuffer entropy); +SignalFfiError *signal_unauthenticated_chat_connection_look_up_username_link(SignalCPromiseOptionalPairOfc_charu832 *promise, SignalConstPointerTokioAsyncContext async_runtime, SignalConstPointerUnauthenticatedChatConnection chat, SignalUuid uuid, SignalBorrowedBuffer entropy); SignalFfiError *signal_unauthenticated_chat_connection_send(SignalCPromiseFfiChatResponse *promise, SignalConstPointerTokioAsyncContext async_runtime, SignalConstPointerUnauthenticatedChatConnection chat, SignalConstPointerHttpRequest http_request, uint32_t timeout_millis); diff --git a/pkg/libsignalgo/senderkeydistributionmessage.go b/pkg/libsignalgo/senderkeydistributionmessage.go index d07c558..c9f6099 100644 --- a/pkg/libsignalgo/senderkeydistributionmessage.go +++ b/pkg/libsignalgo/senderkeydistributionmessage.go @@ -60,7 +60,7 @@ func NewSenderKeyDistributionMessage(ctx context.Context, sender *Address, distr signalFfiError := C.signal_sender_key_distribution_message_create( &skdm, sender.constPtr(), - (*[C.SignalUUID_LEN]C.uchar)(unsafe.Pointer(&distributionID)), + *(*C.SignalUuid)(unsafe.Pointer(&distributionID)), callbackCtx.wrapSenderKeyStore(store), ) runtime.KeepAlive(sender) diff --git a/pkg/libsignalgo/serviceid.go b/pkg/libsignalgo/serviceid.go index 6b0c864..ae7cea7 100644 --- a/pkg/libsignalgo/serviceid.go +++ b/pkg/libsignalgo/serviceid.go @@ -31,12 +31,6 @@ import ( "github.com/rs/zerolog" ) -func init() { - if C.SignalUUID_LEN != 16 { - panic("libsignal-ffi uuid type size mismatch") - } -} - type ServiceIDType byte const ( diff --git a/pkg/libsignalgo/version.go b/pkg/libsignalgo/version.go index f690184..fddfaa8 100644 --- a/pkg/libsignalgo/version.go +++ b/pkg/libsignalgo/version.go @@ -2,4 +2,4 @@ package libsignalgo -const Version = "v0.86.8" +const Version = "v0.86.12" From f0c6cc1e0466662a8a8762ebddf7c76364a9e4aa Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Fri, 16 Jan 2026 15:03:08 +0200 Subject: [PATCH 510/580] dependencies: update --- go.mod | 24 ++++++++++++------------ go.sum | 44 ++++++++++++++++++++++---------------------- 2 files changed, 34 insertions(+), 34 deletions(-) diff --git a/go.mod b/go.mod index 05dfac3..ff53eb1 100644 --- a/go.mod +++ b/go.mod @@ -2,7 +2,7 @@ module go.mau.fi/mautrix-signal go 1.24.0 -toolchain go1.25.5 +toolchain go1.25.6 tool go.mau.fi/util/cmd/maubuild @@ -14,13 +14,13 @@ require ( github.com/rs/zerolog v1.34.0 github.com/stretchr/testify v1.11.1 github.com/tidwall/gjson v1.18.0 - go.mau.fi/util v0.9.5-0.20260114152041-9f2e2b82b503 - golang.org/x/crypto v0.46.0 - golang.org/x/exp v0.0.0-20251209150349-8475f28825e9 - golang.org/x/net v0.48.0 + go.mau.fi/util v0.9.5 + golang.org/x/crypto v0.47.0 + golang.org/x/exp v0.0.0-20260112195511-716be5621a96 + golang.org/x/net v0.49.0 google.golang.org/protobuf v1.36.11 gopkg.in/yaml.v3 v3.0.1 - maunium.net/go/mautrix v0.26.2-0.20260115120200-34bcd027e54c + maunium.net/go/mautrix v0.26.2 ) require ( @@ -31,8 +31,8 @@ require ( github.com/lib/pq v1.10.9 // indirect github.com/mattn/go-colorable v0.1.14 // indirect github.com/mattn/go-isatty v0.0.20 // indirect - github.com/mattn/go-sqlite3 v1.14.32 // indirect - github.com/petermattis/goid v0.0.0-20251121121749-a11dd1a45f9a // indirect + github.com/mattn/go-sqlite3 v1.14.33 // indirect + github.com/petermattis/goid v0.0.0-20260113132338-7c7de50cc741 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/rogpeppe/go-internal v1.10.0 // indirect github.com/rs/xid v1.6.0 // indirect @@ -40,12 +40,12 @@ require ( github.com/tidwall/match v1.1.1 // indirect github.com/tidwall/pretty v1.2.1 // indirect github.com/tidwall/sjson v1.2.5 // indirect - github.com/yuin/goldmark v1.7.13 // indirect + github.com/yuin/goldmark v1.7.16 // indirect go.mau.fi/zeroconfig v0.2.0 // indirect - golang.org/x/mod v0.31.0 // indirect + golang.org/x/mod v0.32.0 // indirect golang.org/x/sync v0.19.0 // indirect - golang.org/x/sys v0.39.0 // indirect - golang.org/x/text v0.32.0 // indirect + golang.org/x/sys v0.40.0 // indirect + golang.org/x/text v0.33.0 // indirect gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect gopkg.in/natefinch/lumberjack.v2 v2.2.1 // indirect maunium.net/go/mauflag v1.0.0 // indirect diff --git a/go.sum b/go.sum index dfd2ccc..3c13426 100644 --- a/go.sum +++ b/go.sum @@ -35,10 +35,10 @@ github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWE github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mattn/go-pointer v0.0.1 h1:n+XhsuGeVO6MEAp7xyEukFINEa+Quek5psIR/ylA6o0= github.com/mattn/go-pointer v0.0.1/go.mod h1:2zXcozF6qYGgmsG+SeTZz3oAbFLdD3OWqnUbNvJZAlc= -github.com/mattn/go-sqlite3 v1.14.32 h1:JD12Ag3oLy1zQA+BNn74xRgaBbdhbNIDYvQUEuuErjs= -github.com/mattn/go-sqlite3 v1.14.32/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y= -github.com/petermattis/goid v0.0.0-20251121121749-a11dd1a45f9a h1:VweslR2akb/ARhXfqSfRbj1vpWwYXf3eeAUyw/ndms0= -github.com/petermattis/goid v0.0.0-20251121121749-a11dd1a45f9a/go.mod h1:pxMtw7cyUw6B2bRH0ZBANSPg+AoSud1I1iyJHI69jH4= +github.com/mattn/go-sqlite3 v1.14.33 h1:A5blZ5ulQo2AtayQ9/limgHEkFreKj1Dv226a1K73s0= +github.com/mattn/go-sqlite3 v1.14.33/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y= +github.com/petermattis/goid v0.0.0-20260113132338-7c7de50cc741 h1:KPpdlQLZcHfTMQRi6bFQ7ogNO0ltFT4PmtwTLW4W+14= +github.com/petermattis/goid v0.0.0-20260113132338-7c7de50cc741/go.mod h1:pxMtw7cyUw6B2bRH0ZBANSPg+AoSud1I1iyJHI69jH4= github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= @@ -64,29 +64,29 @@ github.com/tidwall/pretty v1.2.1 h1:qjsOFOWWQl+N3RsoF5/ssm1pHmJJwhjlSbZ51I6wMl4= github.com/tidwall/pretty v1.2.1/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU= github.com/tidwall/sjson v1.2.5 h1:kLy8mja+1c9jlljvWTlSazM7cKDRfJuR/bOJhcY5NcY= github.com/tidwall/sjson v1.2.5/go.mod h1:Fvgq9kS/6ociJEDnK0Fk1cpYF4FIW6ZF7LAe+6jwd28= -github.com/yuin/goldmark v1.7.13 h1:GPddIs617DnBLFFVJFgpo1aBfe/4xcvMc3SB5t/D0pA= -github.com/yuin/goldmark v1.7.13/go.mod h1:ip/1k0VRfGynBgxOz0yCqHrbZXhcjxyuS66Brc7iBKg= -go.mau.fi/util v0.9.5-0.20260114152041-9f2e2b82b503 h1:L7ctH5wX8TrkZvIZmfxPkHQ1b8NZYw4fIr5WxXaewPw= -go.mau.fi/util v0.9.5-0.20260114152041-9f2e2b82b503/go.mod h1:647nVfwUvuhlZFOnro3aRNPmRd2y3iDha9USb8aKSmM= +github.com/yuin/goldmark v1.7.16 h1:n+CJdUxaFMiDUNnWC3dMWCIQJSkxH4uz3ZwQBkAlVNE= +github.com/yuin/goldmark v1.7.16/go.mod h1:ip/1k0VRfGynBgxOz0yCqHrbZXhcjxyuS66Brc7iBKg= +go.mau.fi/util v0.9.5 h1:7AoWPCIZJGv4jvtFEuCe3GhAbI7uF9ckIooaXvwlIR4= +go.mau.fi/util v0.9.5/go.mod h1:g1uvZ03VQhtTt2BgaRGVytS/Zj67NV0YNIECch0sQCQ= go.mau.fi/zeroconfig v0.2.0 h1:e/OGEERqVRRKlgaro7E6bh8xXiKFSXB3eNNIud7FUjU= go.mau.fi/zeroconfig v0.2.0/go.mod h1:J0Vn0prHNOm493oZoQ84kq83ZaNCYZnq+noI1b1eN8w= -golang.org/x/crypto v0.46.0 h1:cKRW/pmt1pKAfetfu+RCEvjvZkA9RimPbh7bhFjGVBU= -golang.org/x/crypto v0.46.0/go.mod h1:Evb/oLKmMraqjZ2iQTwDwvCtJkczlDuTmdJXoZVzqU0= -golang.org/x/exp v0.0.0-20251209150349-8475f28825e9 h1:MDfG8Cvcqlt9XXrmEiD4epKn7VJHZO84hejP9Jmp0MM= -golang.org/x/exp v0.0.0-20251209150349-8475f28825e9/go.mod h1:EPRbTFwzwjXj9NpYyyrvenVh9Y+GFeEvMNh7Xuz7xgU= -golang.org/x/mod v0.31.0 h1:HaW9xtz0+kOcWKwli0ZXy79Ix+UW/vOfmWI5QVd2tgI= -golang.org/x/mod v0.31.0/go.mod h1:43JraMp9cGx1Rx3AqioxrbrhNsLl2l/iNAvuBkrezpg= -golang.org/x/net v0.48.0 h1:zyQRTTrjc33Lhh0fBgT/H3oZq9WuvRR5gPC70xpDiQU= -golang.org/x/net v0.48.0/go.mod h1:+ndRgGjkh8FGtu1w1FGbEC31if4VrNVMuKTgcAAnQRY= +golang.org/x/crypto v0.47.0 h1:V6e3FRj+n4dbpw86FJ8Fv7XVOql7TEwpHapKoMJ/GO8= +golang.org/x/crypto v0.47.0/go.mod h1:ff3Y9VzzKbwSSEzWqJsJVBnWmRwRSHt/6Op5n9bQc4A= +golang.org/x/exp v0.0.0-20260112195511-716be5621a96 h1:Z/6YuSHTLOHfNFdb8zVZomZr7cqNgTJvA8+Qz75D8gU= +golang.org/x/exp v0.0.0-20260112195511-716be5621a96/go.mod h1:nzimsREAkjBCIEFtHiYkrJyT+2uy9YZJB7H1k68CXZU= +golang.org/x/mod v0.32.0 h1:9F4d3PHLljb6x//jOyokMv3eX+YDeepZSEo3mFJy93c= +golang.org/x/mod v0.32.0/go.mod h1:SgipZ/3h2Ci89DlEtEXWUk/HteuRin+HHhN+WbNhguU= +golang.org/x/net v0.49.0 h1:eeHFmOGUTtaaPSGNmjBKpbng9MulQsJURQUAfUwY++o= +golang.org/x/net v0.49.0/go.mod h1:/ysNB2EvaqvesRkuLAyjI1ycPZlQHM3q01F02UY/MV8= golang.org/x/sync v0.19.0 h1:vV+1eWNmZ5geRlYjzm2adRgW2/mcpevXNg50YZtPCE4= golang.org/x/sync v0.19.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.39.0 h1:CvCKL8MeisomCi6qNZ+wbb0DN9E5AATixKsvNtMoMFk= -golang.org/x/sys v0.39.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= -golang.org/x/text v0.32.0 h1:ZD01bjUt1FQ9WJ0ClOL5vxgxOI/sVCNgX1YtKwcY0mU= -golang.org/x/text v0.32.0/go.mod h1:o/rUWzghvpD5TXrTIBuJU77MTaN0ljMWE47kxGJQ7jY= +golang.org/x/sys v0.40.0 h1:DBZZqJ2Rkml6QMQsZywtnjnnGvHza6BTfYFWY9kjEWQ= +golang.org/x/sys v0.40.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= +golang.org/x/text v0.33.0 h1:B3njUFyqtHDUI5jMn1YIr5B0IE2U0qck04r6d4KPAxE= +golang.org/x/text v0.33.0/go.mod h1:LuMebE6+rBincTi9+xWTY8TztLzKHc/9C1uBCG27+q8= google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE= google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= @@ -98,5 +98,5 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= maunium.net/go/mauflag v1.0.0 h1:YiaRc0tEI3toYtJMRIfjP+jklH45uDHtT80nUamyD4M= maunium.net/go/mauflag v1.0.0/go.mod h1:nLivPOpTpHnpzEh8jEdSL9UqO9+/KBJFmNRlwKfkPeA= -maunium.net/go/mautrix v0.26.2-0.20260115120200-34bcd027e54c h1:ZtJgvgFoH4hxNxFSavFXw7HUnjq49OyjxoEyGcjGk4k= -maunium.net/go/mautrix v0.26.2-0.20260115120200-34bcd027e54c/go.mod h1:vUvbzvY00Tbl8WjBdp5afvc69uIxujnfGHpAugxvR/Q= +maunium.net/go/mautrix v0.26.2 h1:rLiZLQoSKCJDZ+mF1gBQS4p74h3jZXs83g8D4W6Te8g= +maunium.net/go/mautrix v0.26.2/go.mod h1:CUxSZcjPtQNxsZLRQqETAxg2hiz7bjWT+L1HCYoMMKo= From b425489845e5de7e3320614de9531d914d6ee5be Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Fri, 16 Jan 2026 15:08:11 +0200 Subject: [PATCH 511/580] Bump version to v26.01 --- CHANGELOG.md | 9 +++++++++ cmd/mautrix-signal/main.go | 2 +- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1a5d207..29f2299 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,12 @@ +# v26.01 + +* Updated libsignal to v0.86.12. +* Changed automatic contact list sync option to only sync every 3 days rather + than on every restart. +* Fixed sending messages to groups with no other registered members. +* Fixed sender key sends failing if some users had changed devices. +* Fixed timestamps of outgoing typing notifications in DMs. + # v25.12 * Updated libsignal to v0.86.8. diff --git a/cmd/mautrix-signal/main.go b/cmd/mautrix-signal/main.go index 130e307..5391084 100644 --- a/cmd/mautrix-signal/main.go +++ b/cmd/mautrix-signal/main.go @@ -37,7 +37,7 @@ var m = mxmain.BridgeMain{ Name: "mautrix-signal", URL: "https://github.com/mautrix/signal", Description: "A Matrix-Signal puppeting bridge.", - Version: "25.12", + Version: "26.01", SemCalVer: true, Connector: &connector.SignalConnector{}, From 6b66216d24d8a7ec3e1f1dc6f47add3d26105c2a Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Mon, 19 Jan 2026 15:17:21 +0200 Subject: [PATCH 512/580] dependencies: update mautrix-go --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index ff53eb1..d135335 100644 --- a/go.mod +++ b/go.mod @@ -20,7 +20,7 @@ require ( golang.org/x/net v0.49.0 google.golang.org/protobuf v1.36.11 gopkg.in/yaml.v3 v3.0.1 - maunium.net/go/mautrix v0.26.2 + maunium.net/go/mautrix v0.26.3-0.20260119125818-e28f7170bc4b ) require ( diff --git a/go.sum b/go.sum index 3c13426..05055d0 100644 --- a/go.sum +++ b/go.sum @@ -98,5 +98,5 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= maunium.net/go/mauflag v1.0.0 h1:YiaRc0tEI3toYtJMRIfjP+jklH45uDHtT80nUamyD4M= maunium.net/go/mauflag v1.0.0/go.mod h1:nLivPOpTpHnpzEh8jEdSL9UqO9+/KBJFmNRlwKfkPeA= -maunium.net/go/mautrix v0.26.2 h1:rLiZLQoSKCJDZ+mF1gBQS4p74h3jZXs83g8D4W6Te8g= -maunium.net/go/mautrix v0.26.2/go.mod h1:CUxSZcjPtQNxsZLRQqETAxg2hiz7bjWT+L1HCYoMMKo= +maunium.net/go/mautrix v0.26.3-0.20260119125818-e28f7170bc4b h1:OaZ5Y1l4XACFlgy4BmZcCLdYPJZzgZWqZJnpdSITmoM= +maunium.net/go/mautrix v0.26.3-0.20260119125818-e28f7170bc4b/go.mod h1:CUxSZcjPtQNxsZLRQqETAxg2hiz7bjWT+L1HCYoMMKo= From a820c16ab6adffeac18c86b0f160e0cc7876f6de Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Tue, 20 Jan 2026 12:14:00 +0200 Subject: [PATCH 513/580] dependencies: update mautrix-go --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index d135335..d430a07 100644 --- a/go.mod +++ b/go.mod @@ -20,7 +20,7 @@ require ( golang.org/x/net v0.49.0 google.golang.org/protobuf v1.36.11 gopkg.in/yaml.v3 v3.0.1 - maunium.net/go/mautrix v0.26.3-0.20260119125818-e28f7170bc4b + maunium.net/go/mautrix v0.26.3-0.20260120100901-a55693bbd7c6 ) require ( diff --git a/go.sum b/go.sum index 05055d0..64cbfa9 100644 --- a/go.sum +++ b/go.sum @@ -98,5 +98,5 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= maunium.net/go/mauflag v1.0.0 h1:YiaRc0tEI3toYtJMRIfjP+jklH45uDHtT80nUamyD4M= maunium.net/go/mauflag v1.0.0/go.mod h1:nLivPOpTpHnpzEh8jEdSL9UqO9+/KBJFmNRlwKfkPeA= -maunium.net/go/mautrix v0.26.3-0.20260119125818-e28f7170bc4b h1:OaZ5Y1l4XACFlgy4BmZcCLdYPJZzgZWqZJnpdSITmoM= -maunium.net/go/mautrix v0.26.3-0.20260119125818-e28f7170bc4b/go.mod h1:CUxSZcjPtQNxsZLRQqETAxg2hiz7bjWT+L1HCYoMMKo= +maunium.net/go/mautrix v0.26.3-0.20260120100901-a55693bbd7c6 h1:Xi2JR5xkAs1tdvL/qNYK/koLaPwi8/ZbWAKXOe3q2tI= +maunium.net/go/mautrix v0.26.3-0.20260120100901-a55693bbd7c6/go.mod h1:CUxSZcjPtQNxsZLRQqETAxg2hiz7bjWT+L1HCYoMMKo= From 45690972cd60867c00fc7def38524d8e61c00592 Mon Sep 17 00:00:00 2001 From: SpiritCroc Date: Fri, 23 Jan 2026 16:46:10 +0100 Subject: [PATCH 514/580] handlesignal: assign beeper action message content for incoming calls (#632) --- go.mod | 4 ++-- go.sum | 7 ++++--- pkg/connector/handlesignal.go | 3 +++ 3 files changed, 9 insertions(+), 5 deletions(-) diff --git a/go.mod b/go.mod index d430a07..5f90925 100644 --- a/go.mod +++ b/go.mod @@ -20,7 +20,7 @@ require ( golang.org/x/net v0.49.0 google.golang.org/protobuf v1.36.11 gopkg.in/yaml.v3 v3.0.1 - maunium.net/go/mautrix v0.26.3-0.20260120100901-a55693bbd7c6 + maunium.net/go/mautrix v0.26.3-0.20260123143817-d057f1c6732e ) require ( @@ -37,7 +37,7 @@ require ( github.com/rogpeppe/go-internal v1.10.0 // indirect github.com/rs/xid v1.6.0 // indirect github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e // indirect - github.com/tidwall/match v1.1.1 // indirect + github.com/tidwall/match v1.2.0 // indirect github.com/tidwall/pretty v1.2.1 // indirect github.com/tidwall/sjson v1.2.5 // indirect github.com/yuin/goldmark v1.7.16 // indirect diff --git a/go.sum b/go.sum index 64cbfa9..cb0c5ee 100644 --- a/go.sum +++ b/go.sum @@ -57,8 +57,9 @@ github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD github.com/tidwall/gjson v1.14.2/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= github.com/tidwall/gjson v1.18.0 h1:FIDeeyB800efLX89e5a8Y0BNH+LOngJyGrIWxG2FKQY= github.com/tidwall/gjson v1.18.0/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= -github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA= github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM= +github.com/tidwall/match v1.2.0 h1:0pt8FlkOwjN2fPt4bIl4BoNxb98gGHN2ObFEDkrfZnM= +github.com/tidwall/match v1.2.0/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM= github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU= github.com/tidwall/pretty v1.2.1 h1:qjsOFOWWQl+N3RsoF5/ssm1pHmJJwhjlSbZ51I6wMl4= github.com/tidwall/pretty v1.2.1/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU= @@ -98,5 +99,5 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= maunium.net/go/mauflag v1.0.0 h1:YiaRc0tEI3toYtJMRIfjP+jklH45uDHtT80nUamyD4M= maunium.net/go/mauflag v1.0.0/go.mod h1:nLivPOpTpHnpzEh8jEdSL9UqO9+/KBJFmNRlwKfkPeA= -maunium.net/go/mautrix v0.26.3-0.20260120100901-a55693bbd7c6 h1:Xi2JR5xkAs1tdvL/qNYK/koLaPwi8/ZbWAKXOe3q2tI= -maunium.net/go/mautrix v0.26.3-0.20260120100901-a55693bbd7c6/go.mod h1:CUxSZcjPtQNxsZLRQqETAxg2hiz7bjWT+L1HCYoMMKo= +maunium.net/go/mautrix v0.26.3-0.20260123143817-d057f1c6732e h1:lV73mGcvK73DWiAjZY4HBCo/Wr9R5Q8OgQ7U2Giraww= +maunium.net/go/mautrix v0.26.3-0.20260123143817-d057f1c6732e/go.mod h1:CUxSZcjPtQNxsZLRQqETAxg2hiz7bjWT+L1HCYoMMKo= diff --git a/pkg/connector/handlesignal.go b/pkg/connector/handlesignal.go index c9f16c1..fb1a3ce 100644 --- a/pkg/connector/handlesignal.go +++ b/pkg/connector/handlesignal.go @@ -102,6 +102,9 @@ func convertCallEvent(ctx context.Context, portal *bridgev2.Portal, intent bridg if userID, _, _ := signalid.ParsePortalID(portal.ID); !userID.IsEmpty() { content.MsgType = event.MsgText } + content.BeeperActionMessage = &event.BeeperActionMessage{ + Type: event.BeeperActionMessageCall, + } } else { content.Body = "Call ended" } From 30d983192206f42ce546c3933b6af0d02610f9e4 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Thu, 29 Jan 2026 18:30:26 +0200 Subject: [PATCH 515/580] signalmeow/senderkey: log removed devices when resetting --- pkg/signalmeow/senderkey.go | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/pkg/signalmeow/senderkey.go b/pkg/signalmeow/senderkey.go index 096d524..48a3203 100644 --- a/pkg/signalmeow/senderkey.go +++ b/pkg/signalmeow/senderkey.go @@ -125,9 +125,11 @@ func (cli *Client) sendToGroupWithSenderKey( } else { log.Debug().Any("sender_key_info", ski).Msg("Reusing existing sender key") } - xak, devicesAddedTo, reset := diffRecipients(ski.SharedWith, deviceIDs) - if reset { - log.Debug().Msg("Resetting sender key due to recipient device changes") + xak, devicesAddedTo, removedDevices := diffRecipients(ski.SharedWith, deviceIDs) + if len(removedDevices) > 0 { + log.Debug(). + Any("removed_devices", removedDevices). + Msg("Resetting sender key due to recipient device changes") devicesAddedTo = slices.Collect(maps.Keys(deviceIDs)) err = cli.Store.SenderKeyStore.DeleteSenderKey(ctx, myAddress, ski.DistributionID) if err != nil { @@ -304,9 +306,12 @@ func (cli *Client) encryptWithSenderKey( } func diffRecipients( - prevDevices map[libsignalgo.ServiceID][]int, newDevices map[libsignalgo.ServiceID]senderKeySendMeta, + prevDevices map[libsignalgo.ServiceID][]int, + newDevices map[libsignalgo.ServiceID]senderKeySendMeta, ) ( - xak *libsignalgo.AccessKey, devicesAddedTo []libsignalgo.ServiceID, reset bool, + xak *libsignalgo.AccessKey, + devicesAddedTo []libsignalgo.ServiceID, + globalRemovedDevices map[libsignalgo.ServiceID][]int, ) { collector := make(map[libsignalgo.ServiceID]uint8, max(len(prevDevices), len(newDevices))) for key := range prevDevices { @@ -315,6 +320,7 @@ func diffRecipients( for key := range newDevices { collector[key] |= 0b10 } + globalRemovedDevices = make(map[libsignalgo.ServiceID][]int) for serviceID, mask := range collector { if mask != 0b01 { xak = xak.Xor(newDevices[serviceID].AccessKey) @@ -322,7 +328,7 @@ func diffRecipients( switch mask { case 0b01: // Someone left the group - reset = true + globalRemovedDevices[serviceID] = prevDevices[serviceID] case 0b10: // Someone was added to the group devicesAddedTo = append(devicesAddedTo, serviceID) @@ -330,7 +336,7 @@ func diffRecipients( removedDevices, addedDevices := exslices.Diff(prevDevices[serviceID], newDevices[serviceID].DeviceIDs) if len(removedDevices) > 0 { // Device was removed - reset = true + globalRemovedDevices[serviceID] = removedDevices } else if len(addedDevices) > 0 { // User got new devices devicesAddedTo = append(devicesAddedTo, serviceID) From c90be170f490cda593a270dcfdf7fb7a204d7178 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Thu, 29 Jan 2026 18:45:34 +0200 Subject: [PATCH 516/580] signalmeow/sending: refetch prekeys on error 80 --- pkg/libsignalgo/error.go | 8 ++++++++ pkg/signalmeow/sending.go | 9 +++++++-- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/pkg/libsignalgo/error.go b/pkg/libsignalgo/error.go index b25130b..888f8ea 100644 --- a/pkg/libsignalgo/error.go +++ b/pkg/libsignalgo/error.go @@ -26,6 +26,10 @@ import ( type ErrorCode int +func (e ErrorCode) Error() string { + return fmt.Sprintf("libsignalgo.ErrorCode(%d)", int(e)) +} + const ( ErrorCodeUnknownError ErrorCode = 1 ErrorCodeInvalidState ErrorCode = 2 @@ -118,6 +122,10 @@ func (e *SignalError) Error() string { return fmt.Sprintf("%d: %s", e.Code, e.Message) } +func (e *SignalError) Unwrap() error { + return e.Code +} + func (ctx *CallbackContext) wrapError(signalError *C.SignalFfiError) error { if signalError == nil { return nil diff --git a/pkg/signalmeow/sending.go b/pkg/signalmeow/sending.go index 404571c..8e6b892 100644 --- a/pkg/signalmeow/sending.go +++ b/pkg/signalmeow/sending.go @@ -150,6 +150,7 @@ func (cli *Client) buildMessagesToSend( unauthenticated bool, groupID *libsignalgo.GroupIdentifier, ctmOverride *libsignalgo.CiphertextMessage, + forceResync bool, ) ([]MyMessage, error) { if ctx.Value(contextKeyEncryptionLock) != true { cli.encryptionLock.Lock() @@ -157,7 +158,7 @@ func (cli *Client) buildMessagesToSend( } sessions, err := cli.Store.ACISessionStore.AllSessionsForServiceID(ctx, recipient) - if err == nil && len(sessions) == 0 { + if err == nil && (len(sessions) == 0 || forceResync) { // No sessions, make one with prekey err = cli.FetchAndProcessPreKey(ctx, recipient, -1) if err != nil { @@ -900,7 +901,11 @@ func (cli *Client) sendContent( } var messages []MyMessage - messages, err = cli.buildMessagesToSend(ctx, recipient, content, useUnidentifiedSender, groupID, ctmOverride) + messages, err = cli.buildMessagesToSend(ctx, recipient, content, useUnidentifiedSender, groupID, ctmOverride, false) + if errors.Is(err, libsignalgo.ErrorCodeSessionNotFound) { + log.Err(err).Msg("Got session not found error from libsignal, trying to refetch prekeys") + messages, err = cli.buildMessagesToSend(ctx, recipient, content, useUnidentifiedSender, groupID, ctmOverride, true) + } if err != nil { log.Err(err).Msg("Error building messages to send") return false, err From 93da772584b20ac1975e872e26739b273314b73e Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Thu, 29 Jan 2026 19:47:37 +0200 Subject: [PATCH 517/580] dependencies: update mautrix-go --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 5f90925..728ffb7 100644 --- a/go.mod +++ b/go.mod @@ -20,7 +20,7 @@ require ( golang.org/x/net v0.49.0 google.golang.org/protobuf v1.36.11 gopkg.in/yaml.v3 v3.0.1 - maunium.net/go/mautrix v0.26.3-0.20260123143817-d057f1c6732e + maunium.net/go/mautrix v0.26.3-0.20260129174719-d2364b382275 ) require ( diff --git a/go.sum b/go.sum index cb0c5ee..8dba58f 100644 --- a/go.sum +++ b/go.sum @@ -99,5 +99,5 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= maunium.net/go/mauflag v1.0.0 h1:YiaRc0tEI3toYtJMRIfjP+jklH45uDHtT80nUamyD4M= maunium.net/go/mauflag v1.0.0/go.mod h1:nLivPOpTpHnpzEh8jEdSL9UqO9+/KBJFmNRlwKfkPeA= -maunium.net/go/mautrix v0.26.3-0.20260123143817-d057f1c6732e h1:lV73mGcvK73DWiAjZY4HBCo/Wr9R5Q8OgQ7U2Giraww= -maunium.net/go/mautrix v0.26.3-0.20260123143817-d057f1c6732e/go.mod h1:CUxSZcjPtQNxsZLRQqETAxg2hiz7bjWT+L1HCYoMMKo= +maunium.net/go/mautrix v0.26.3-0.20260129174719-d2364b382275 h1:r8BL0+HW4Dar1xV7Fc7NV/LxGH6VCvffkCUGe9ZfJg8= +maunium.net/go/mautrix v0.26.3-0.20260129174719-d2364b382275/go.mod h1:CUxSZcjPtQNxsZLRQqETAxg2hiz7bjWT+L1HCYoMMKo= From d603b7665d15b5514a115c4d77d7d4525976a5a2 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Mon, 9 Feb 2026 13:54:02 +0200 Subject: [PATCH 518/580] libsignal: update to v0.87.1 --- pkg/libsignalgo/identitykey.go | 3 +- pkg/libsignalgo/identitykeystore.go | 80 +++++------ pkg/libsignalgo/libsignal | 2 +- pkg/libsignalgo/libsignal-ffi.h | 150 +++++++++++++-------- pkg/libsignalgo/prekeystore.go | 27 ++-- pkg/libsignalgo/publickey.go | 10 +- pkg/libsignalgo/senderkeystore.go | 34 ++--- pkg/libsignalgo/sessionstore.go | 30 +++-- pkg/libsignalgo/signedprekeystore.go | 25 ++-- pkg/libsignalgo/update-ffi-docker-inner.sh | 2 +- pkg/libsignalgo/version.go | 2 +- 11 files changed, 207 insertions(+), 158 deletions(-) diff --git a/pkg/libsignalgo/identitykey.go b/pkg/libsignalgo/identitykey.go index f35d116..0226e11 100644 --- a/pkg/libsignalgo/identitykey.go +++ b/pkg/libsignalgo/identitykey.go @@ -84,8 +84,7 @@ func (i *IdentityKey) VerifyAlternateIdentity(other *IdentityKey, signature []by } func (i *IdentityKey) Equal(other *IdentityKey) (bool, error) { - result, err := i.publicKey.Compare(other.publicKey) - return result == 0, err + return i.publicKey.Equal(other.publicKey) } type IdentityKeyPair struct { diff --git a/pkg/libsignalgo/identitykeystore.go b/pkg/libsignalgo/identitykeystore.go index c59b660..6a425e8 100644 --- a/pkg/libsignalgo/identitykeystore.go +++ b/pkg/libsignalgo/identitykeystore.go @@ -20,14 +20,12 @@ package libsignalgo /* #include "./libsignal-ffi.h" -typedef const SignalProtocolAddress const_address; -typedef const SignalPublicKey const_public_key; - -extern int signal_get_identity_key_pair_callback(void *store_ctx, SignalPrivateKey **keyp); +extern int signal_get_identity_key_pair_callback(void *store_ctx, SignalMutPointerPrivateKey *keyp); extern int signal_get_local_registration_id_callback(void *store_ctx, uint32_t *idp); -extern int signal_save_identity_key_callback(void *store_ctx, const_address *address, const_public_key *public_key); -extern int signal_get_identity_key_callback(void *store_ctx, SignalPublicKey **public_keyp, const_address *address); -extern int signal_is_trusted_identity_callback(void *store_ctx, const_address *address, const_public_key *public_key, unsigned int direction); +extern int signal_save_identity_key_callback(void *store_ctx, uint8_t *out, SignalMutPointerProtocolAddress address, SignalMutPointerPublicKey public_key); +extern int signal_get_identity_key_callback(void *store_ctx, SignalMutPointerPublicKey *public_keyp, SignalMutPointerProtocolAddress address); +extern int signal_is_trusted_identity_callback(void *store_ctx, bool *out, SignalMutPointerProtocolAddress address, SignalMutPointerPublicKey public_key, uint32_t direction); +extern void signal_destroy_identity_key_store_callback(void *store_ctx); */ import "C" import ( @@ -51,21 +49,21 @@ type IdentityKeyStore interface { } //export signal_get_identity_key_pair_callback -func signal_get_identity_key_pair_callback(storeCtx unsafe.Pointer, keyp **C.SignalPrivateKey) C.int { +func signal_get_identity_key_pair_callback(storeCtx unsafe.Pointer, keyp *C.SignalMutPointerPrivateKey) C.int { return wrapStoreCallback(storeCtx, func(store IdentityKeyStore, ctx context.Context) error { key, err := store.GetIdentityKeyPair(ctx) if err != nil { return err } if key == nil { - *keyp = nil + keyp.raw = nil } else { clone, err := key.privateKey.Clone() if err != nil { return err } clone.CancelFinalizer() - *keyp = clone.ptr + keyp.raw = clone.ptr } return err }) @@ -83,17 +81,17 @@ func signal_get_local_registration_id_callback(storeCtx unsafe.Pointer, idp *C.u } //export signal_save_identity_key_callback -func signal_save_identity_key_callback(storeCtx unsafe.Pointer, address *C.const_address, publicKey *C.const_public_key) C.int { - return wrapStoreCallbackCustomReturn(storeCtx, func(store IdentityKeyStore, ctx context.Context) (int, error) { - publicKeyStruct := PublicKey{ptr: (*C.SignalPublicKey)(unsafe.Pointer(publicKey))} +func signal_save_identity_key_callback(storeCtx unsafe.Pointer, out *C.uint8_t, address C.SignalMutPointerProtocolAddress, publicKey C.SignalMutPointerPublicKey) C.int { + return wrapStoreCallback(storeCtx, func(store IdentityKeyStore, ctx context.Context) error { + publicKeyStruct := PublicKey{ptr: publicKey.raw} cloned, err := publicKeyStruct.Clone() if err != nil { - return -1, err + return err } - addr := &Address{ptr: (*C.SignalProtocolAddress)(unsafe.Pointer(address))} + addr := &Address{ptr: address.raw} theirServiceID, err := addr.NameServiceID() if err != nil { - return -1, err + return err } replaced, err := store.SaveIdentityKey( ctx, @@ -101,20 +99,21 @@ func signal_save_identity_key_callback(storeCtx unsafe.Pointer, address *C.const &IdentityKey{cloned}, ) if err != nil { - return -1, err + return err } if replaced { - return 1, nil + *out = 1 } else { - return 0, nil + *out = 0 } + return nil }) } //export signal_get_identity_key_callback -func signal_get_identity_key_callback(storeCtx unsafe.Pointer, public_keyp **C.SignalPublicKey, address *C.const_address) C.int { +func signal_get_identity_key_callback(storeCtx unsafe.Pointer, public_keyp *C.SignalMutPointerPublicKey, address C.SignalMutPointerProtocolAddress) C.int { return wrapStoreCallback(storeCtx, func(store IdentityKeyStore, ctx context.Context) error { - addr := &Address{ptr: (*C.SignalProtocolAddress)(unsafe.Pointer(address))} + addr := &Address{ptr: address.raw} theirServiceID, err := addr.NameServiceID() if err != nil { return err @@ -122,39 +121,42 @@ func signal_get_identity_key_callback(storeCtx unsafe.Pointer, public_keyp **C.S key, err := store.GetIdentityKey(ctx, theirServiceID) if err == nil && key != nil { key.publicKey.CancelFinalizer() - *public_keyp = key.publicKey.ptr + public_keyp.raw = key.publicKey.ptr } return err }) } //export signal_is_trusted_identity_callback -func signal_is_trusted_identity_callback(storeCtx unsafe.Pointer, address *C.const_address, public_key *C.const_public_key, direction C.uint) C.int { - return wrapStoreCallbackCustomReturn(storeCtx, func(store IdentityKeyStore, ctx context.Context) (int, error) { - addr := &Address{ptr: (*C.SignalProtocolAddress)(unsafe.Pointer(address))} +func signal_is_trusted_identity_callback(storeCtx unsafe.Pointer, out *C.bool, address C.SignalMutPointerProtocolAddress, public_key C.SignalMutPointerPublicKey, direction C.uint32_t) C.int { + return wrapStoreCallback(storeCtx, func(store IdentityKeyStore, ctx context.Context) error { + addr := &Address{ptr: address.raw} theirServiceID, err := addr.NameServiceID() if err != nil { - return -1, err + return err } - trusted, err := store.IsTrustedIdentity(ctx, theirServiceID, &IdentityKey{&PublicKey{ptr: (*C.SignalPublicKey)(unsafe.Pointer(public_key))}}, SignalDirection(direction)) + trusted, err := store.IsTrustedIdentity(ctx, theirServiceID, &IdentityKey{&PublicKey{ptr: public_key.raw}}, SignalDirection(direction)) if err != nil { - return -1, err - } - if trusted { - return 1, nil - } else { - return 0, nil + return err } + *out = C.bool(trusted) + return nil }) } +//export signal_destroy_identity_key_store_callback +func signal_destroy_identity_key_store_callback(storeCtx unsafe.Pointer) { + // No-op: Go's garbage collector handles cleanup +} + func (ctx *CallbackContext) wrapIdentityKeyStore(store IdentityKeyStore) C.SignalConstPointerFfiIdentityKeyStoreStruct { return C.SignalConstPointerFfiIdentityKeyStoreStruct{&C.SignalIdentityKeyStore{ - ctx: wrapStore(ctx, store), - get_identity_key_pair: C.SignalGetIdentityKeyPair(C.signal_get_identity_key_pair_callback), - get_local_registration_id: C.SignalGetLocalRegistrationId(C.signal_get_local_registration_id_callback), - save_identity: C.SignalSaveIdentityKey(C.signal_save_identity_key_callback), - get_identity: C.SignalGetIdentityKey(C.signal_get_identity_key_callback), - is_trusted_identity: C.SignalIsTrustedIdentity(C.signal_is_trusted_identity_callback), + ctx: wrapStore(ctx, store), + get_local_identity_private_key: C.SignalFfiBridgeIdentityKeyStoreGetLocalIdentityPrivateKey(C.signal_get_identity_key_pair_callback), + get_local_registration_id: C.SignalFfiBridgeIdentityKeyStoreGetLocalRegistrationId(C.signal_get_local_registration_id_callback), + get_identity_key: C.SignalFfiBridgeIdentityKeyStoreGetIdentityKey(C.signal_get_identity_key_callback), + save_identity_key: C.SignalFfiBridgeIdentityKeyStoreSaveIdentityKey(C.signal_save_identity_key_callback), + is_trusted_identity: C.SignalFfiBridgeIdentityKeyStoreIsTrustedIdentity(C.signal_is_trusted_identity_callback), + destroy: C.SignalFfiBridgeIdentityKeyStoreDestroy(C.signal_destroy_identity_key_store_callback), }} } diff --git a/pkg/libsignalgo/libsignal b/pkg/libsignalgo/libsignal index 0480b16..f08390b 160000 --- a/pkg/libsignalgo/libsignal +++ b/pkg/libsignalgo/libsignal @@ -1 +1 @@ -Subproject commit 0480b16ac3c4ca9d641bc160b1b231f89d2e5fe3 +Subproject commit f08390b0e2f67d5faf47bb9d1a3db191314db93c diff --git a/pkg/libsignalgo/libsignal-ffi.h b/pkg/libsignalgo/libsignal-ffi.h index e2ddc02..deb72cd 100644 --- a/pkg/libsignalgo/libsignal-ffi.h +++ b/pkg/libsignalgo/libsignal-ffi.h @@ -29,6 +29,8 @@ SPDX-License-Identifier: AGPL-3.0-only #define SignalBackupId_LEN 16 +#define SignalCallLinkSecretParams_ROOT_KEY_MAX_BYTES_FOR_SHO 16 + #define SignalNUM_AUTH_CRED_ATTRIBUTES 3 #define SignalNUM_PROFILE_KEY_CRED_ATTRIBUTES 4 @@ -755,50 +757,52 @@ typedef struct { SignalSessionRecord *raw; } SignalMutPointerSessionRecord; -typedef int (*SignalLoadSession)(void *store_ctx, SignalMutPointerSessionRecord *recordp, SignalConstPointerProtocolAddress address); +typedef int (*SignalFfiBridgeSessionStoreLoadSession)(void *ctx, SignalMutPointerSessionRecord *out, SignalMutPointerProtocolAddress address); -typedef struct { - const SignalSessionRecord *raw; -} SignalConstPointerSessionRecord; +typedef int (*SignalFfiBridgeSessionStoreStoreSession)(void *ctx, SignalMutPointerProtocolAddress address, SignalMutPointerSessionRecord record); -typedef int (*SignalStoreSession)(void *store_ctx, SignalConstPointerProtocolAddress address, SignalConstPointerSessionRecord record); +typedef void (*SignalFfiBridgeSessionStoreDestroy)(void *ctx); typedef struct { void *ctx; - SignalLoadSession load_session; - SignalStoreSession store_session; -} SignalSessionStore; + SignalFfiBridgeSessionStoreLoadSession load_session; + SignalFfiBridgeSessionStoreStoreSession store_session; + SignalFfiBridgeSessionStoreDestroy destroy; +} SignalFfiBridgeSessionStoreStruct; + +typedef SignalFfiBridgeSessionStoreStruct SignalSessionStore; typedef struct { const SignalSessionStore *raw; } SignalConstPointerFfiSessionStoreStruct; -typedef int (*SignalGetIdentityKeyPair)(void *store_ctx, SignalMutPointerPrivateKey *keyp); +typedef int (*SignalFfiBridgeIdentityKeyStoreGetLocalIdentityPrivateKey)(void *ctx, SignalMutPointerPrivateKey *out); -typedef int (*SignalGetLocalRegistrationId)(void *store_ctx, uint32_t *idp); - -typedef struct { - const SignalPublicKey *raw; -} SignalConstPointerPublicKey; - -typedef int (*SignalSaveIdentityKey)(void *store_ctx, SignalConstPointerProtocolAddress address, SignalConstPointerPublicKey public_key); +typedef int (*SignalFfiBridgeIdentityKeyStoreGetLocalRegistrationId)(void *ctx, uint32_t *out); typedef struct { SignalPublicKey *raw; } SignalMutPointerPublicKey; -typedef int (*SignalGetIdentityKey)(void *store_ctx, SignalMutPointerPublicKey *public_keyp, SignalConstPointerProtocolAddress address); +typedef int (*SignalFfiBridgeIdentityKeyStoreGetIdentityKey)(void *ctx, SignalMutPointerPublicKey *out, SignalMutPointerProtocolAddress address); -typedef int (*SignalIsTrustedIdentity)(void *store_ctx, SignalConstPointerProtocolAddress address, SignalConstPointerPublicKey public_key, unsigned int direction); +typedef int (*SignalFfiBridgeIdentityKeyStoreSaveIdentityKey)(void *ctx, uint8_t *out, SignalMutPointerProtocolAddress address, SignalMutPointerPublicKey public_key); + +typedef int (*SignalFfiBridgeIdentityKeyStoreIsTrustedIdentity)(void *ctx, bool *out, SignalMutPointerProtocolAddress address, SignalMutPointerPublicKey public_key, uint32_t direction); + +typedef void (*SignalFfiBridgeIdentityKeyStoreDestroy)(void *ctx); typedef struct { void *ctx; - SignalGetIdentityKeyPair get_identity_key_pair; - SignalGetLocalRegistrationId get_local_registration_id; - SignalSaveIdentityKey save_identity; - SignalGetIdentityKey get_identity; - SignalIsTrustedIdentity is_trusted_identity; -} SignalIdentityKeyStore; + SignalFfiBridgeIdentityKeyStoreGetLocalIdentityPrivateKey get_local_identity_private_key; + SignalFfiBridgeIdentityKeyStoreGetLocalRegistrationId get_local_registration_id; + SignalFfiBridgeIdentityKeyStoreGetIdentityKey get_identity_key; + SignalFfiBridgeIdentityKeyStoreSaveIdentityKey save_identity_key; + SignalFfiBridgeIdentityKeyStoreIsTrustedIdentity is_trusted_identity; + SignalFfiBridgeIdentityKeyStoreDestroy destroy; +} SignalFfiBridgeIdentityKeyStoreStruct; + +typedef SignalFfiBridgeIdentityKeyStoreStruct SignalIdentityKeyStore; typedef struct { const SignalIdentityKeyStore *raw; @@ -812,22 +816,23 @@ typedef struct { SignalPreKeyRecord *raw; } SignalMutPointerPreKeyRecord; -typedef int (*SignalLoadPreKey)(void *store_ctx, SignalMutPointerPreKeyRecord *recordp, uint32_t id); +typedef int (*SignalFfiBridgePreKeyStoreLoadPreKey)(void *ctx, SignalMutPointerPreKeyRecord *out, uint32_t id); -typedef struct { - const SignalPreKeyRecord *raw; -} SignalConstPointerPreKeyRecord; +typedef int (*SignalFfiBridgePreKeyStoreStorePreKey)(void *ctx, uint32_t id, SignalMutPointerPreKeyRecord record); -typedef int (*SignalStorePreKey)(void *store_ctx, uint32_t id, SignalConstPointerPreKeyRecord record); +typedef int (*SignalFfiBridgePreKeyStoreRemovePreKey)(void *ctx, uint32_t id); -typedef int (*SignalRemovePreKey)(void *store_ctx, uint32_t id); +typedef void (*SignalFfiBridgePreKeyStoreDestroy)(void *ctx); typedef struct { void *ctx; - SignalLoadPreKey load_pre_key; - SignalStorePreKey store_pre_key; - SignalRemovePreKey remove_pre_key; -} SignalPreKeyStore; + SignalFfiBridgePreKeyStoreLoadPreKey load_pre_key; + SignalFfiBridgePreKeyStoreStorePreKey store_pre_key; + SignalFfiBridgePreKeyStoreRemovePreKey remove_pre_key; + SignalFfiBridgePreKeyStoreDestroy destroy; +} SignalFfiBridgePreKeyStoreStruct; + +typedef SignalFfiBridgePreKeyStoreStruct SignalPreKeyStore; typedef struct { const SignalPreKeyStore *raw; @@ -837,19 +842,20 @@ typedef struct { SignalSignedPreKeyRecord *raw; } SignalMutPointerSignedPreKeyRecord; -typedef int (*SignalLoadSignedPreKey)(void *store_ctx, SignalMutPointerSignedPreKeyRecord *recordp, uint32_t id); +typedef int (*SignalFfiBridgeSignedPreKeyStoreLoadSignedPreKey)(void *ctx, SignalMutPointerSignedPreKeyRecord *out, uint32_t id); -typedef struct { - const SignalSignedPreKeyRecord *raw; -} SignalConstPointerSignedPreKeyRecord; +typedef int (*SignalFfiBridgeSignedPreKeyStoreStoreSignedPreKey)(void *ctx, uint32_t id, SignalMutPointerSignedPreKeyRecord record); -typedef int (*SignalStoreSignedPreKey)(void *store_ctx, uint32_t id, SignalConstPointerSignedPreKeyRecord record); +typedef void (*SignalFfiBridgeSignedPreKeyStoreDestroy)(void *ctx); typedef struct { void *ctx; - SignalLoadSignedPreKey load_signed_pre_key; - SignalStoreSignedPreKey store_signed_pre_key; -} SignalSignedPreKeyStore; + SignalFfiBridgeSignedPreKeyStoreLoadSignedPreKey load_signed_pre_key; + SignalFfiBridgeSignedPreKeyStoreStoreSignedPreKey store_signed_pre_key; + SignalFfiBridgeSignedPreKeyStoreDestroy destroy; +} SignalFfiBridgeSignedPreKeyStoreStruct; + +typedef SignalFfiBridgeSignedPreKeyStoreStruct SignalSignedPreKeyStore; typedef struct { const SignalSignedPreKeyStore *raw; @@ -946,6 +952,10 @@ typedef struct { const SignalFingerprint *raw; } SignalConstPointerFingerprint; +typedef struct { + const SignalPublicKey *raw; +} SignalConstPointerPublicKey; + typedef struct { /** * The badge ID. @@ -987,19 +997,20 @@ typedef struct { SignalSenderKeyRecord *raw; } SignalMutPointerSenderKeyRecord; -typedef int (*SignalLoadSenderKey)(void *store_ctx, SignalMutPointerSenderKeyRecord*, SignalConstPointerProtocolAddress, const uint8_t (*distribution_id)[16]); +typedef int (*SignalFfiBridgeSenderKeyStoreLoadSenderKey)(void *ctx, SignalMutPointerSenderKeyRecord *out, SignalMutPointerProtocolAddress sender, SignalUuid distribution_id); -typedef struct { - const SignalSenderKeyRecord *raw; -} SignalConstPointerSenderKeyRecord; +typedef int (*SignalFfiBridgeSenderKeyStoreStoreSenderKey)(void *ctx, SignalMutPointerProtocolAddress sender, SignalUuid distribution_id, SignalMutPointerSenderKeyRecord record); -typedef int (*SignalStoreSenderKey)(void *store_ctx, SignalConstPointerProtocolAddress, const uint8_t (*distribution_id)[16], SignalConstPointerSenderKeyRecord); +typedef void (*SignalFfiBridgeSenderKeyStoreDestroy)(void *ctx); typedef struct { void *ctx; - SignalLoadSenderKey load_sender_key; - SignalStoreSenderKey store_sender_key; -} SignalSenderKeyStore; + SignalFfiBridgeSenderKeyStoreLoadSenderKey load_sender_key; + SignalFfiBridgeSenderKeyStoreStoreSenderKey store_sender_key; + SignalFfiBridgeSenderKeyStoreDestroy destroy; +} SignalFfiBridgeSenderKeyStoreStruct; + +typedef SignalFfiBridgeSenderKeyStoreStruct SignalSenderKeyStore; typedef struct { const SignalSenderKeyStore *raw; @@ -1136,15 +1147,20 @@ typedef struct { const SignalMessageBackupValidationOutcome *raw; } SignalConstPointerMessageBackupValidationOutcome; -typedef int (*SignalRead)(void *ctx, uint8_t *buf, size_t buf_len, size_t *amount_read); +typedef int (*SignalFfiBridgeInputStreamRead)(void *ctx, size_t *out, SignalBorrowedMutableBuffer buf); -typedef int (*SignalSkip)(void *ctx, uint64_t amount); +typedef int (*SignalFfiBridgeInputStreamSkip)(void *ctx, uint64_t amount); + +typedef void (*SignalFfiBridgeInputStreamDestroy)(void *ctx); typedef struct { void *ctx; - SignalRead read; - SignalSkip skip; -} SignalInputStream; + SignalFfiBridgeInputStreamRead read; + SignalFfiBridgeInputStreamSkip skip; + SignalFfiBridgeInputStreamDestroy destroy; +} SignalFfiBridgeInputStreamStruct; + +typedef SignalFfiBridgeInputStreamStruct SignalInputStream; typedef struct { const SignalInputStream *raw; @@ -1182,6 +1198,10 @@ typedef struct { const SignalPreKeyBundle *raw; } SignalConstPointerPreKeyBundle; +typedef struct { + const SignalPreKeyRecord *raw; +} SignalConstPointerPreKeyRecord; + typedef struct { SignalPreKeySignalMessage *raw; } SignalMutPointerPreKeySignalMessage; @@ -1374,6 +1394,10 @@ typedef struct { size_t length; } SignalBorrowedSliceOfConstPointerProtocolAddress; +typedef struct { + const SignalSessionRecord *raw; +} SignalConstPointerSessionRecord; + typedef struct { const SignalConstPointerSessionRecord *base; size_t length; @@ -1452,6 +1476,10 @@ typedef struct { const SignalSenderKeyMessage *raw; } SignalConstPointerSenderKeyMessage; +typedef struct { + const SignalSenderKeyRecord *raw; +} SignalConstPointerSenderKeyRecord; + typedef struct { const SignalServerMessageAck *raw; } SignalConstPointerServerMessageAck; @@ -1468,6 +1496,10 @@ typedef struct { const SignalSgxClientState *raw; } SignalConstPointerSgxClientState; +typedef struct { + const SignalSignedPreKeyRecord *raw; +} SignalConstPointerSignedPreKeyRecord; + typedef struct { SignalTokioAsyncContext *raw; } SignalMutPointerTokioAsyncContext; @@ -1546,7 +1578,9 @@ typedef struct { SignalValidatingMac *raw; } SignalMutPointerValidatingMac; -typedef SignalInputStream SignalSyncInputStream; +typedef SignalFfiBridgeInputStreamStruct SignalFfiBridgeSyncInputStreamStruct; + +typedef SignalFfiBridgeSyncInputStreamStruct SignalSyncInputStream; typedef struct { const SignalSyncInputStream *raw; @@ -2284,8 +2318,6 @@ SignalFfiError *signal_provisioning_chat_connection_init_listener(SignalConstPoi SignalFfiError *signal_publickey_clone(SignalMutPointerPublicKey *new_obj, SignalConstPointerPublicKey obj); -SignalFfiError *signal_publickey_compare(int32_t *out, SignalConstPointerPublicKey key1, SignalConstPointerPublicKey key2); - SignalFfiError *signal_publickey_deserialize(SignalMutPointerPublicKey *out, SignalBorrowedBuffer data); SignalFfiError *signal_publickey_destroy(SignalMutPointerPublicKey p); @@ -2646,6 +2678,8 @@ SignalFfiError *signal_tokio_async_context_destroy(SignalMutPointerTokioAsyncCon SignalFfiError *signal_tokio_async_context_new(SignalMutPointerTokioAsyncContext *out); +SignalFfiError *signal_unauthenticated_chat_connection_account_exists(SignalCPromisebool *promise, SignalConstPointerTokioAsyncContext async_runtime, SignalConstPointerUnauthenticatedChatConnection chat, const SignalServiceIdFixedWidthBinaryBytes *account); + SignalFfiError *signal_unauthenticated_chat_connection_connect(SignalCPromiseMutPointerUnauthenticatedChatConnection *promise, SignalConstPointerTokioAsyncContext async_runtime, SignalConstPointerConnectionManager connection_manager, SignalBorrowedBytestringArray languages); SignalFfiError *signal_unauthenticated_chat_connection_destroy(SignalMutPointerUnauthenticatedChatConnection p); diff --git a/pkg/libsignalgo/prekeystore.go b/pkg/libsignalgo/prekeystore.go index 643e286..ed8ea21 100644 --- a/pkg/libsignalgo/prekeystore.go +++ b/pkg/libsignalgo/prekeystore.go @@ -20,11 +20,10 @@ package libsignalgo /* #include "./libsignal-ffi.h" -typedef const SignalPreKeyRecord const_pre_key_record; - -extern int signal_load_pre_key_callback(void *store_ctx, SignalPreKeyRecord **recordp, uint32_t id); -extern int signal_store_pre_key_callback(void *store_ctx, uint32_t id, const_pre_key_record *record); +extern int signal_load_pre_key_callback(void *store_ctx, SignalMutPointerPreKeyRecord *recordp, uint32_t id); +extern int signal_store_pre_key_callback(void *store_ctx, uint32_t id, SignalMutPointerPreKeyRecord record); extern int signal_remove_pre_key_callback(void *store_ctx, uint32_t id); +extern void signal_destroy_pre_key_store_callback(void *store_ctx); */ import "C" import ( @@ -39,21 +38,21 @@ type PreKeyStore interface { } //export signal_load_pre_key_callback -func signal_load_pre_key_callback(storeCtx unsafe.Pointer, keyp **C.SignalPreKeyRecord, id C.uint32_t) C.int { +func signal_load_pre_key_callback(storeCtx unsafe.Pointer, keyp *C.SignalMutPointerPreKeyRecord, id C.uint32_t) C.int { return wrapStoreCallback(storeCtx, func(store PreKeyStore, ctx context.Context) error { key, err := store.LoadPreKey(ctx, uint32(id)) if err == nil && key != nil { key.CancelFinalizer() - *keyp = key.ptr + keyp.raw = key.ptr } return err }) } //export signal_store_pre_key_callback -func signal_store_pre_key_callback(storeCtx unsafe.Pointer, id C.uint32_t, preKeyRecord *C.const_pre_key_record) C.int { +func signal_store_pre_key_callback(storeCtx unsafe.Pointer, id C.uint32_t, preKeyRecord C.SignalMutPointerPreKeyRecord) C.int { return wrapStoreCallback(storeCtx, func(store PreKeyStore, ctx context.Context) error { - record := PreKeyRecord{ptr: (*C.SignalPreKeyRecord)(unsafe.Pointer(preKeyRecord))} + record := PreKeyRecord{ptr: preKeyRecord.raw} cloned, err := record.Clone() if err != nil { return err @@ -69,11 +68,17 @@ func signal_remove_pre_key_callback(storeCtx unsafe.Pointer, id C.uint32_t) C.in }) } +//export signal_destroy_pre_key_store_callback +func signal_destroy_pre_key_store_callback(storeCtx unsafe.Pointer) { + // No-op: Go's garbage collector handles cleanup +} + func (ctx *CallbackContext) wrapPreKeyStore(store PreKeyStore) C.SignalConstPointerFfiPreKeyStoreStruct { return C.SignalConstPointerFfiPreKeyStoreStruct{&C.SignalPreKeyStore{ ctx: wrapStore(ctx, store), - load_pre_key: C.SignalLoadPreKey(C.signal_load_pre_key_callback), - store_pre_key: C.SignalStorePreKey(C.signal_store_pre_key_callback), - remove_pre_key: C.SignalRemovePreKey(C.signal_remove_pre_key_callback), + load_pre_key: C.SignalFfiBridgePreKeyStoreLoadPreKey(C.signal_load_pre_key_callback), + store_pre_key: C.SignalFfiBridgePreKeyStoreStorePreKey(C.signal_store_pre_key_callback), + remove_pre_key: C.SignalFfiBridgePreKeyStoreRemovePreKey(C.signal_remove_pre_key_callback), + destroy: C.SignalFfiBridgePreKeyStoreDestroy(C.signal_destroy_pre_key_store_callback), }} } diff --git a/pkg/libsignalgo/publickey.go b/pkg/libsignalgo/publickey.go index bd7452e..fdd76e5 100644 --- a/pkg/libsignalgo/publickey.go +++ b/pkg/libsignalgo/publickey.go @@ -84,15 +84,15 @@ func (k *PublicKey) CancelFinalizer() { runtime.SetFinalizer(k, nil) } -func (k *PublicKey) Compare(other *PublicKey) (int, error) { - var comparison C.int - signalFfiError := C.signal_publickey_compare(&comparison, k.constPtr(), other.constPtr()) +func (k *PublicKey) Equal(other *PublicKey) (bool, error) { + var comparison C.bool + signalFfiError := C.signal_publickey_equals(&comparison, k.constPtr(), other.constPtr()) runtime.KeepAlive(k) runtime.KeepAlive(other) if signalFfiError != nil { - return 0, wrapError(signalFfiError) + return false, wrapError(signalFfiError) } - return int(comparison), nil + return bool(comparison), nil } func (k *PublicKey) Bytes() ([]byte, error) { diff --git a/pkg/libsignalgo/senderkeystore.go b/pkg/libsignalgo/senderkeystore.go index 30df4ad..a07a287 100644 --- a/pkg/libsignalgo/senderkeystore.go +++ b/pkg/libsignalgo/senderkeystore.go @@ -20,13 +20,9 @@ package libsignalgo /* #include "./libsignal-ffi.h" -typedef const SignalProtocolAddress const_address; - -typedef const SignalSenderKeyRecord const_sender_key_record; -typedef const uint8_t const_uuid_bytes[16]; - -extern int signal_load_sender_key_callback(void *store_ctx, SignalSenderKeyRecord**, const_address*, const_uuid_bytes*); -extern int signal_store_sender_key_callback(void *store_ctx, const_address*, const_uuid_bytes*, const_sender_key_record*); +extern int signal_load_sender_key_callback(void *store_ctx, SignalMutPointerSenderKeyRecord *out, SignalMutPointerProtocolAddress sender, SignalUuid distribution_id); +extern int signal_store_sender_key_callback(void *store_ctx, SignalMutPointerProtocolAddress sender, SignalUuid distribution_id, SignalMutPointerSenderKeyRecord record); +extern void signal_destroy_sender_key_store_callback(void *store_ctx); */ import "C" import ( @@ -42,36 +38,40 @@ type SenderKeyStore interface { } //export signal_load_sender_key_callback -func signal_load_sender_key_callback(storeCtx unsafe.Pointer, recordp **C.SignalSenderKeyRecord, address *C.const_address, distributionIDBytes *C.const_uuid_bytes) C.int { +func signal_load_sender_key_callback(storeCtx unsafe.Pointer, recordp *C.SignalMutPointerSenderKeyRecord, address C.SignalMutPointerProtocolAddress, distributionID C.SignalUuid) C.int { return wrapStoreCallback(storeCtx, func(store SenderKeyStore, ctx context.Context) error { - distributionID := uuid.UUID(*(*[16]byte)(unsafe.Pointer(distributionIDBytes))) - record, err := store.LoadSenderKey(ctx, &Address{ptr: (*C.SignalProtocolAddress)(unsafe.Pointer(address))}, distributionID) + record, err := store.LoadSenderKey(ctx, &Address{ptr: address.raw}, *(*uuid.UUID)(unsafe.Pointer(&distributionID))) if err == nil && record != nil { record.CancelFinalizer() - *recordp = record.ptr + recordp.raw = record.ptr } return err }) } //export signal_store_sender_key_callback -func signal_store_sender_key_callback(storeCtx unsafe.Pointer, address *C.const_address, distributionIDBytes *C.const_uuid_bytes, senderKeyRecord *C.const_sender_key_record) C.int { +func signal_store_sender_key_callback(storeCtx unsafe.Pointer, address C.SignalMutPointerProtocolAddress, distributionID C.SignalUuid, senderKeyRecord C.SignalMutPointerSenderKeyRecord) C.int { return wrapStoreCallback(storeCtx, func(store SenderKeyStore, ctx context.Context) error { - distributionID := uuid.UUID(*(*[16]byte)(unsafe.Pointer(distributionIDBytes))) - record := SenderKeyRecord{ptr: (*C.SignalSenderKeyRecord)(unsafe.Pointer(senderKeyRecord))} + record := SenderKeyRecord{ptr: senderKeyRecord.raw} cloned, err := record.Clone() if err != nil { return err } - return store.StoreSenderKey(ctx, &Address{ptr: (*C.SignalProtocolAddress)(unsafe.Pointer(address))}, distributionID, cloned) + return store.StoreSenderKey(ctx, &Address{ptr: address.raw}, *(*uuid.UUID)(unsafe.Pointer(&distributionID)), cloned) }) } +//export signal_destroy_sender_key_store_callback +func signal_destroy_sender_key_store_callback(storeCtx unsafe.Pointer) { + // No-op: Go's garbage collector handles cleanup +} + func (ctx *CallbackContext) wrapSenderKeyStore(store SenderKeyStore) C.SignalConstPointerFfiSenderKeyStoreStruct { return C.SignalConstPointerFfiSenderKeyStoreStruct{&C.SignalSenderKeyStore{ ctx: wrapStore(ctx, store), - load_sender_key: C.SignalLoadSenderKey(C.signal_load_sender_key_callback), - store_sender_key: C.SignalStoreSenderKey(C.signal_store_sender_key_callback), + load_sender_key: C.SignalFfiBridgeSenderKeyStoreLoadSenderKey(C.signal_load_sender_key_callback), + store_sender_key: C.SignalFfiBridgeSenderKeyStoreStoreSenderKey(C.signal_store_sender_key_callback), + destroy: C.SignalFfiBridgeSenderKeyStoreDestroy(C.signal_destroy_sender_key_store_callback), }} } diff --git a/pkg/libsignalgo/sessionstore.go b/pkg/libsignalgo/sessionstore.go index da430c1..2515232 100644 --- a/pkg/libsignalgo/sessionstore.go +++ b/pkg/libsignalgo/sessionstore.go @@ -20,11 +20,9 @@ package libsignalgo /* #include "./libsignal-ffi.h" -typedef const SignalSessionRecord const_session_record; -typedef const SignalProtocolAddress const_address; - -extern int signal_load_session_callback(void *store_ctx, SignalSessionRecord **recordp, const_address *address); -extern int signal_store_session_callback(void *store_ctx, const_address *address, const_session_record *record); +extern int signal_load_session_callback(void *store_ctx, SignalMutPointerSessionRecord *recordp, SignalMutPointerProtocolAddress address); +extern int signal_store_session_callback(void *store_ctx, SignalMutPointerProtocolAddress address, SignalMutPointerSessionRecord record); +extern void signal_destroy_session_store_callback(void *store_ctx); */ import "C" import ( @@ -38,33 +36,39 @@ type SessionStore interface { } //export signal_load_session_callback -func signal_load_session_callback(storeCtx unsafe.Pointer, recordp **C.SignalSessionRecord, address *C.const_address) C.int { +func signal_load_session_callback(storeCtx unsafe.Pointer, recordp *C.SignalMutPointerSessionRecord, address C.SignalMutPointerProtocolAddress) C.int { return wrapStoreCallback(storeCtx, func(store SessionStore, ctx context.Context) error { - record, err := store.LoadSession(ctx, &Address{ptr: (*C.SignalProtocolAddress)(unsafe.Pointer(address))}) + record, err := store.LoadSession(ctx, &Address{ptr: address.raw}) if err == nil && record != nil { record.CancelFinalizer() - *recordp = record.ptr + recordp.raw = record.ptr } return err }) } //export signal_store_session_callback -func signal_store_session_callback(storeCtx unsafe.Pointer, address *C.const_address, sessionRecord *C.const_session_record) C.int { +func signal_store_session_callback(storeCtx unsafe.Pointer, address C.SignalMutPointerProtocolAddress, sessionRecord C.SignalMutPointerSessionRecord) C.int { return wrapStoreCallback(storeCtx, func(store SessionStore, ctx context.Context) error { - record := SessionRecord{ptr: (*C.SignalSessionRecord)(unsafe.Pointer(sessionRecord))} + record := SessionRecord{ptr: sessionRecord.raw} cloned, err := record.Clone() if err != nil { return err } - return store.StoreSession(ctx, &Address{ptr: (*C.SignalProtocolAddress)(unsafe.Pointer(address))}, cloned) + return store.StoreSession(ctx, &Address{ptr: address.raw}, cloned) }) } +//export signal_destroy_session_store_callback +func signal_destroy_session_store_callback(storeCtx unsafe.Pointer) { + // No-op: Go's garbage collector handles cleanup +} + func (ctx *CallbackContext) wrapSessionStore(store SessionStore) C.SignalConstPointerFfiSessionStoreStruct { return C.SignalConstPointerFfiSessionStoreStruct{&C.SignalSessionStore{ ctx: wrapStore(ctx, store), - load_session: C.SignalLoadSession(C.signal_load_session_callback), - store_session: C.SignalStoreSession(C.signal_store_session_callback), + load_session: C.SignalFfiBridgeSessionStoreLoadSession(C.signal_load_session_callback), + store_session: C.SignalFfiBridgeSessionStoreStoreSession(C.signal_store_session_callback), + destroy: C.SignalFfiBridgeSessionStoreDestroy(C.signal_destroy_session_store_callback), }} } diff --git a/pkg/libsignalgo/signedprekeystore.go b/pkg/libsignalgo/signedprekeystore.go index b595578..cfb3015 100644 --- a/pkg/libsignalgo/signedprekeystore.go +++ b/pkg/libsignalgo/signedprekeystore.go @@ -20,10 +20,9 @@ package libsignalgo /* #include "./libsignal-ffi.h" -typedef const SignalSignedPreKeyRecord const_signed_pre_key_record; - -extern int signal_load_signed_pre_key_callback(void *store_ctx, SignalSignedPreKeyRecord **recordp, uint32_t id); -extern int signal_store_signed_pre_key_callback(void *store_ctx, uint32_t id, const_signed_pre_key_record *record); +extern int signal_load_signed_pre_key_callback(void *store_ctx, SignalMutPointerSignedPreKeyRecord *recordp, uint32_t id); +extern int signal_store_signed_pre_key_callback(void *store_ctx, uint32_t id, SignalMutPointerSignedPreKeyRecord record); +extern void signal_destroy_signed_pre_key_store_callback(void *store_ctx); */ import "C" import ( @@ -37,21 +36,21 @@ type SignedPreKeyStore interface { } //export signal_load_signed_pre_key_callback -func signal_load_signed_pre_key_callback(storeCtx unsafe.Pointer, keyp **C.SignalSignedPreKeyRecord, id C.uint32_t) C.int { +func signal_load_signed_pre_key_callback(storeCtx unsafe.Pointer, keyp *C.SignalMutPointerSignedPreKeyRecord, id C.uint32_t) C.int { return wrapStoreCallback(storeCtx, func(store SignedPreKeyStore, ctx context.Context) error { key, err := store.LoadSignedPreKey(ctx, uint32(id)) if err == nil && key != nil { key.CancelFinalizer() - *keyp = key.ptr + keyp.raw = key.ptr } return err }) } //export signal_store_signed_pre_key_callback -func signal_store_signed_pre_key_callback(storeCtx unsafe.Pointer, id C.uint32_t, preKeyRecord *C.const_signed_pre_key_record) C.int { +func signal_store_signed_pre_key_callback(storeCtx unsafe.Pointer, id C.uint32_t, preKeyRecord C.SignalMutPointerSignedPreKeyRecord) C.int { return wrapStoreCallback(storeCtx, func(store SignedPreKeyStore, ctx context.Context) error { - record := SignedPreKeyRecord{ptr: (*C.SignalSignedPreKeyRecord)(unsafe.Pointer(preKeyRecord))} + record := SignedPreKeyRecord{ptr: preKeyRecord.raw} cloned, err := record.Clone() if err != nil { return err @@ -60,10 +59,16 @@ func signal_store_signed_pre_key_callback(storeCtx unsafe.Pointer, id C.uint32_t }) } +//export signal_destroy_signed_pre_key_store_callback +func signal_destroy_signed_pre_key_store_callback(storeCtx unsafe.Pointer) { + // No-op: Go's garbage collector handles cleanup +} + func (ctx *CallbackContext) wrapSignedPreKeyStore(store SignedPreKeyStore) C.SignalConstPointerFfiSignedPreKeyStoreStruct { return C.SignalConstPointerFfiSignedPreKeyStoreStruct{&C.SignalSignedPreKeyStore{ ctx: wrapStore(ctx, store), - load_signed_pre_key: C.SignalLoadSignedPreKey(C.signal_load_signed_pre_key_callback), - store_signed_pre_key: C.SignalStoreSignedPreKey(C.signal_store_signed_pre_key_callback), + load_signed_pre_key: C.SignalFfiBridgeSignedPreKeyStoreLoadSignedPreKey(C.signal_load_signed_pre_key_callback), + store_signed_pre_key: C.SignalFfiBridgeSignedPreKeyStoreStoreSignedPreKey(C.signal_store_signed_pre_key_callback), + destroy: C.SignalFfiBridgeSignedPreKeyStoreDestroy(C.signal_destroy_signed_pre_key_store_callback), }} } diff --git a/pkg/libsignalgo/update-ffi-docker-inner.sh b/pkg/libsignalgo/update-ffi-docker-inner.sh index 7641701..e343887 100755 --- a/pkg/libsignalgo/update-ffi-docker-inner.sh +++ b/pkg/libsignalgo/update-ffi-docker-inner.sh @@ -1,7 +1,7 @@ #!/bin/sh cd /data export RUSTFLAGS="-Ctarget-feature=-crt-static" RUSTC_WRAPPER="" -apk add --no-cache git make cmake protoc musl-dev g++ clang-dev cbindgen +apk add --no-cache git make cmake protobuf-dev musl-dev g++ clang-dev cbindgen cd libsignal cargo build -p libsignal-ffi --release cbindgen --profile release rust/bridge/ffi -o libsignal-ffi.h diff --git a/pkg/libsignalgo/version.go b/pkg/libsignalgo/version.go index fddfaa8..8f445ad 100644 --- a/pkg/libsignalgo/version.go +++ b/pkg/libsignalgo/version.go @@ -2,4 +2,4 @@ package libsignalgo -const Version = "v0.86.12" +const Version = "v0.87.1" From eb955598253755732e0de57880f535ad6bfdd922 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Mon, 9 Feb 2026 14:13:18 +0200 Subject: [PATCH 519/580] signalmeow: update protobufs --- pkg/signalmeow/groups.go | 94 +- .../protobuf/ContactDiscovery.pb.go | 4 +- pkg/signalmeow/protobuf/DeviceName.pb.go | 4 +- pkg/signalmeow/protobuf/Groups.pb.go | 1857 ++++++++-------- pkg/signalmeow/protobuf/Groups.proto | 325 +-- pkg/signalmeow/protobuf/Provisioning.pb.go | 4 +- pkg/signalmeow/protobuf/SignalService.pb.go | 1147 ++++++---- pkg/signalmeow/protobuf/SignalService.proto | 46 +- .../protobuf/StickerResources.pb.go | 4 +- pkg/signalmeow/protobuf/StorageService.pb.go | 129 +- pkg/signalmeow/protobuf/StorageService.proto | 29 +- .../protobuf/UnidentifiedDelivery.pb.go | 4 +- .../protobuf/WebSocketResources.pb.go | 4 +- pkg/signalmeow/protobuf/backuppb/Backup.pb.go | 1897 ++++++++++++----- pkg/signalmeow/protobuf/backuppb/Backup.proto | 78 + pkg/signalmeow/protobuf/update-protos.sh | 6 +- 16 files changed, 3547 insertions(+), 2085 deletions(-) diff --git a/pkg/signalmeow/groups.go b/pkg/signalmeow/groups.go index d956fcc..dcdfe7d 100644 --- a/pkg/signalmeow/groups.go +++ b/pkg/signalmeow/groups.go @@ -106,8 +106,8 @@ func (group *Group) GetInviteLink() (string, error) { if err != nil { return "", fmt.Errorf("couldn't decode invite link password") } - inviteLinkContents := signalpb.GroupInviteLink_V1Contents{ - V1Contents: &signalpb.GroupInviteLink_GroupInviteLinkContentsV1{ + inviteLinkContents := signalpb.GroupInviteLink_ContentsV1{ + ContentsV1: &signalpb.GroupInviteLink_GroupInviteLinkContentsV1{ GroupMasterKey: masterKeyBytes[:], InviteLinkPassword: inviteLinkPasswordBytes, }, @@ -471,7 +471,7 @@ func decryptGroup(ctx context.Context, encryptedGroup *signalpb.Group, groupMast descriptionBlob, err := decryptGroupPropertyIntoBlob(groupSecretParams, encryptedGroup.Description) if err == nil { // treat a failure in obtaining the description as non-fatal - decryptedGroup.Description = cleanupStringProperty(descriptionBlob.GetDescription()) + decryptedGroup.Description = cleanupStringProperty(descriptionBlob.GetDescriptionText()) } if encryptedGroup.DisappearingMessagesTimer != nil && len(encryptedGroup.DisappearingMessagesTimer) > 0 { @@ -483,8 +483,8 @@ func decryptGroup(ctx context.Context, encryptedGroup *signalpb.Group, groupMast } // These aren't encrypted - decryptedGroup.AvatarPath = encryptedGroup.Avatar - decryptedGroup.Revision = encryptedGroup.Revision + decryptedGroup.AvatarPath = encryptedGroup.AvatarUrl + decryptedGroup.Revision = encryptedGroup.Version // Decrypt members for _, member := range encryptedGroup.Members { @@ -498,7 +498,7 @@ func decryptGroup(ctx context.Context, encryptedGroup *signalpb.Group, groupMast decryptedGroup.Members = append(decryptedGroup.Members, decryptedMember) } - for _, pendingMember := range encryptedGroup.PendingMembers { + for _, pendingMember := range encryptedGroup.MembersPendingProfileKey { if pendingMember == nil { continue } @@ -510,7 +510,7 @@ func decryptGroup(ctx context.Context, encryptedGroup *signalpb.Group, groupMast decryptedGroup.PendingMembers = append(decryptedGroup.PendingMembers, decryptedPendingMember) } - for _, requestingMember := range encryptedGroup.RequestingMembers { + for _, requestingMember := range encryptedGroup.MembersPendingAdminApproval { if requestingMember == nil { continue } @@ -521,7 +521,7 @@ func decryptGroup(ctx context.Context, encryptedGroup *signalpb.Group, groupMast decryptedGroup.RequestingMembers = append(decryptedGroup.RequestingMembers, decryptedRequestingMember) } - for _, bannedMember := range encryptedGroup.BannedMembers { + for _, bannedMember := range encryptedGroup.MembersBanned { if bannedMember == nil { continue } @@ -789,14 +789,14 @@ func (cli *Client) decryptGroupChange(ctx context.Context, encryptedGroupChange return nil, err } - sourceServiceID, err := groupSecretParams.DecryptServiceID(libsignalgo.UUIDCiphertext(encryptedActions.SourceServiceId)) + sourceServiceID, err := groupSecretParams.DecryptServiceID(libsignalgo.UUIDCiphertext(encryptedActions.SourceUserId)) if err != nil { log.Err(err).Msg("Couldn't decrypt source serviceID") return nil, err } decryptedGroupChange := &GroupChange{ GroupMasterKey: groupMasterKey, - Revision: encryptedActions.Revision, + Revision: encryptedActions.Version, SourceServiceID: sourceServiceID, } @@ -816,7 +816,7 @@ func (cli *Client) decryptGroupChange(ctx context.Context, encryptedGroupChange descriptionBlob, err := decryptGroupPropertyIntoBlob(groupSecretParams, encryptedActions.ModifyDescription.Description) if err == nil { // treat a failure in obtaining the description as non-fatal - newDescription := cleanupStringProperty(descriptionBlob.GetDescription()) + newDescription := cleanupStringProperty(descriptionBlob.GetDescriptionText()) decryptedGroupChange.ModifyDescription = &newDescription } } @@ -891,7 +891,7 @@ func (cli *Client) decryptGroupChange(ctx context.Context, encryptedGroupChange } } - for _, addPendingMember := range encryptedActions.AddPendingMembers { + for _, addPendingMember := range encryptedActions.AddMembersPendingProfileKey { if addPendingMember == nil { continue } @@ -904,7 +904,7 @@ func (cli *Client) decryptGroupChange(ctx context.Context, encryptedGroupChange decryptedGroupChange.AddPendingMembers = append(decryptedGroupChange.AddPendingMembers, decryptedPendingMember) } - for _, deletePendingMember := range encryptedActions.DeletePendingMembers { + for _, deletePendingMember := range encryptedActions.DeleteMembersPendingProfileKey { if deletePendingMember == nil { continue } @@ -917,7 +917,7 @@ func (cli *Client) decryptGroupChange(ctx context.Context, encryptedGroupChange decryptedGroupChange.DeletePendingMembers = append(decryptedGroupChange.DeletePendingMembers, &userID) } - for _, promotePendingMember := range encryptedActions.PromotePendingMembers { + for _, promotePendingMember := range encryptedActions.PromoteMembersPendingProfileKey { if promotePendingMember == nil { continue } @@ -936,7 +936,7 @@ func (cli *Client) decryptGroupChange(ctx context.Context, encryptedGroupChange } } - for _, promotePendingPniAciMember := range encryptedActions.PromotePendingPniAciMembers { + for _, promotePendingPniAciMember := range encryptedActions.PromoteMembersPendingPniAciProfileKey { // TODO: pretending this is a PendingMember should do for mautrix-signal, but we probably want to treat them separately at some point if promotePendingPniAciMember == nil { continue @@ -966,7 +966,7 @@ func (cli *Client) decryptGroupChange(ctx context.Context, encryptedGroupChange } } - for _, addRequestingMember := range encryptedActions.AddRequestingMembers { + for _, addRequestingMember := range encryptedActions.AddMembersPendingAdminApproval { if addRequestingMember == nil { continue } @@ -982,7 +982,7 @@ func (cli *Client) decryptGroupChange(ctx context.Context, encryptedGroupChange } } - for _, deleteRequestingMember := range encryptedActions.DeleteRequestingMembers { + for _, deleteRequestingMember := range encryptedActions.DeleteMembersPendingAdminApproval { if deleteRequestingMember == nil { continue } @@ -995,7 +995,7 @@ func (cli *Client) decryptGroupChange(ctx context.Context, encryptedGroupChange decryptedGroupChange.DeleteRequestingMembers = append(decryptedGroupChange.DeleteRequestingMembers, &serviceID.UUID) } - for _, promoteRequestingMember := range encryptedActions.PromoteRequestingMembers { + for _, promoteRequestingMember := range encryptedActions.PromoteMembersPendingAdminApproval { if promoteRequestingMember == nil { continue } @@ -1011,7 +1011,7 @@ func (cli *Client) decryptGroupChange(ctx context.Context, encryptedGroupChange }) } - for _, addBannedMember := range encryptedActions.AddBannedMembers { + for _, addBannedMember := range encryptedActions.AddMembersBanned { if addBannedMember == nil { continue } @@ -1028,7 +1028,7 @@ func (cli *Client) decryptGroupChange(ctx context.Context, encryptedGroupChange }) } - for _, deleteBannedMember := range encryptedActions.DeleteBannedMembers { + for _, deleteBannedMember := range encryptedActions.DeleteMembersBanned { if deleteBannedMember == nil { continue } @@ -1056,8 +1056,8 @@ func (cli *Client) decryptGroupChange(ctx context.Context, encryptedGroupChange if encryptedActions.ModifyAnnouncementsOnly != nil { decryptedGroupChange.ModifyAnnouncementsOnly = &encryptedActions.ModifyAnnouncementsOnly.AnnouncementsOnly } - if encryptedActions.ModifyDisappearingMessagesTimer != nil && len(encryptedActions.ModifyDisappearingMessagesTimer.Timer) > 0 { - timerBlob, err := decryptGroupPropertyIntoBlob(groupSecretParams, encryptedActions.ModifyDisappearingMessagesTimer.Timer) + if encryptedActions.ModifyDisappearingMessageTimer != nil && len(encryptedActions.ModifyDisappearingMessageTimer.Timer) > 0 { + timerBlob, err := decryptGroupPropertyIntoBlob(groupSecretParams, encryptedActions.ModifyDisappearingMessageTimer.Timer) if err != nil { return nil, err } @@ -1128,11 +1128,11 @@ func decryptMember(ctx context.Context, member *signalpb.Member, groupSecretPara ACI: *aci, ProfileKey: *profileKey, Role: GroupMemberRole(member.Role), - JoinedAtRevision: member.JoinedAtRevision, + JoinedAtRevision: member.JoinedAtVersion, }, nil } -func decryptPendingMember(ctx context.Context, pendingMember *signalpb.PendingMember, groupSecretParams libsignalgo.GroupSecretParams) (*PendingMember, error) { +func decryptPendingMember(ctx context.Context, pendingMember *signalpb.MemberPendingProfileKey, groupSecretParams libsignalgo.GroupSecretParams) (*PendingMember, error) { log := zerolog.Ctx(ctx) encryptedUserID := libsignalgo.UUIDCiphertext(pendingMember.Member.UserId) userID, err := groupSecretParams.DecryptServiceID(encryptedUserID) @@ -1155,7 +1155,7 @@ func decryptPendingMember(ctx context.Context, pendingMember *signalpb.PendingMe }, nil } -func decryptRequestingMember(ctx context.Context, requestingMember *signalpb.RequestingMember, groupSecretParams libsignalgo.GroupSecretParams) (*RequestingMember, error) { +func decryptRequestingMember(ctx context.Context, requestingMember *signalpb.MemberPendingAdminApproval, groupSecretParams libsignalgo.GroupSecretParams) (*RequestingMember, error) { aci, profileKey, err := decryptPKeyAndIDorPresentation(ctx, requestingMember.UserId, requestingMember.ProfileKey, requestingMember.Presentation, groupSecretParams) if err != nil { return nil, err @@ -1176,7 +1176,7 @@ func (cli *Client) EncryptAndSignGroupChange(ctx context.Context, decryptedGroup log.Err(err).Msg("Could not get groupSecretParams from master key") return nil, err } - groupChangeActions := &signalpb.GroupChange_Actions{Revision: decryptedGroupChange.Revision} + groupChangeActions := &signalpb.GroupChange_Actions{Version: decryptedGroupChange.Revision} if decryptedGroupChange.ModifyTitle != nil { attributeBlob := signalpb.GroupAttributeBlob{Content: &signalpb.GroupAttributeBlob_Title{Title: *decryptedGroupChange.ModifyTitle}} encryptedTitle, err := encryptBlobIntoGroupProperty(groupSecretParams, &attributeBlob) @@ -1187,7 +1187,7 @@ func (cli *Client) EncryptAndSignGroupChange(ctx context.Context, decryptedGroup groupChangeActions.ModifyTitle = &signalpb.GroupChange_Actions_ModifyTitleAction{Title: *encryptedTitle} } if decryptedGroupChange.ModifyDescription != nil { - attributeBlob := signalpb.GroupAttributeBlob{Content: &signalpb.GroupAttributeBlob_Description{Description: *decryptedGroupChange.ModifyDescription}} + attributeBlob := signalpb.GroupAttributeBlob{Content: &signalpb.GroupAttributeBlob_DescriptionText{DescriptionText: *decryptedGroupChange.ModifyDescription}} encryptedDescription, err := encryptBlobIntoGroupProperty(groupSecretParams, &attributeBlob) if err != nil { log.Err(err).Msg("Could not get encrypt description") @@ -1209,7 +1209,7 @@ func (cli *Client) EncryptAndSignGroupChange(ctx context.Context, decryptedGroup JoinFromInviteLink: addMember.JoinFromInviteLink, }) } else { - groupChangeActions.AddPendingMembers = append(groupChangeActions.AddPendingMembers, &signalpb.GroupChange_Actions_AddPendingMemberAction{ + groupChangeActions.AddMembersPendingProfileKey = append(groupChangeActions.AddMembersPendingProfileKey, &signalpb.GroupChange_Actions_AddMemberPendingProfileKeyAction{ Added: encryptedPendingMember, }) } @@ -1241,7 +1241,7 @@ func (cli *Client) EncryptAndSignGroupChange(ctx context.Context, decryptedGroup log.Err(err).Msg("Failed to encrypt pendingMember") return nil, err } - groupChangeActions.AddPendingMembers = append(groupChangeActions.AddPendingMembers, &signalpb.GroupChange_Actions_AddPendingMemberAction{ + groupChangeActions.AddMembersPendingProfileKey = append(groupChangeActions.AddMembersPendingProfileKey, &signalpb.GroupChange_Actions_AddMemberPendingProfileKeyAction{ Added: encryptedPendingMember, }) } @@ -1251,7 +1251,7 @@ func (cli *Client) EncryptAndSignGroupChange(ctx context.Context, decryptedGroup log.Err(err).Msg("Encrypt UserId error for deletePendingMember") return nil, err } - groupChangeActions.DeletePendingMembers = append(groupChangeActions.DeletePendingMembers, &signalpb.GroupChange_Actions_DeletePendingMemberAction{ + groupChangeActions.DeleteMembersPendingProfileKey = append(groupChangeActions.DeleteMembersPendingProfileKey, &signalpb.GroupChange_Actions_DeleteMemberPendingProfileKeyAction{ DeletedUserId: encryptedUserID[:], }) } @@ -1269,7 +1269,7 @@ func (cli *Client) EncryptAndSignGroupChange(ctx context.Context, decryptedGroup log.Err(err).Msg("failed creating expiring profile key credential presentation for addMember") return nil, err } - groupChangeActions.PromotePendingMembers = append(groupChangeActions.PromotePendingMembers, &signalpb.GroupChange_Actions_PromotePendingMemberAction{ + groupChangeActions.PromoteMembersPendingProfileKey = append(groupChangeActions.PromoteMembersPendingProfileKey, &signalpb.GroupChange_Actions_PromoteMemberPendingProfileKeyAction{ Presentation: *presentation, }) } @@ -1287,8 +1287,8 @@ func (cli *Client) EncryptAndSignGroupChange(ctx context.Context, decryptedGroup log.Err(err).Msg("failed creating expiring profile key credential presentation for addMember") return nil, err } - groupChangeActions.AddRequestingMembers = append(groupChangeActions.AddRequestingMembers, &signalpb.GroupChange_Actions_AddRequestingMemberAction{ - Added: &signalpb.RequestingMember{ + groupChangeActions.AddMembersPendingAdminApproval = append(groupChangeActions.AddMembersPendingAdminApproval, &signalpb.GroupChange_Actions_AddMemberPendingAdminApprovalAction{ + Added: &signalpb.MemberPendingAdminApproval{ Presentation: *presentation, }, }) @@ -1299,7 +1299,7 @@ func (cli *Client) EncryptAndSignGroupChange(ctx context.Context, decryptedGroup log.Err(err).Msg("Encrypt UserId error for deleteRequestingMember") return nil, err } - groupChangeActions.DeleteRequestingMembers = append(groupChangeActions.DeleteRequestingMembers, &signalpb.GroupChange_Actions_DeleteRequestingMemberAction{ + groupChangeActions.DeleteMembersPendingAdminApproval = append(groupChangeActions.DeleteMembersPendingAdminApproval, &signalpb.GroupChange_Actions_DeleteMemberPendingAdminApprovalAction{ DeletedUserId: encryptedUserID[:], }) } @@ -1310,7 +1310,7 @@ func (cli *Client) EncryptAndSignGroupChange(ctx context.Context, decryptedGroup return nil, err } - groupChangeActions.PromoteRequestingMembers = append(groupChangeActions.PromoteRequestingMembers, &signalpb.GroupChange_Actions_PromoteRequestingMemberAction{ + groupChangeActions.PromoteMembersPendingAdminApproval = append(groupChangeActions.PromoteMembersPendingAdminApproval, &signalpb.GroupChange_Actions_PromoteMemberPendingAdminApprovalAction{ UserId: encryptedUserID[:], Role: signalpb.Member_Role(promoteRequestingMember.Role), }) @@ -1321,8 +1321,8 @@ func (cli *Client) EncryptAndSignGroupChange(ctx context.Context, decryptedGroup log.Err(err).Msg("Encrypt UserId error for promoteRequestingMember") return nil, err } - groupChangeActions.AddBannedMembers = append(groupChangeActions.AddBannedMembers, &signalpb.GroupChange_Actions_AddBannedMemberAction{ - Added: &signalpb.BannedMember{ + groupChangeActions.AddMembersBanned = append(groupChangeActions.AddMembersBanned, &signalpb.GroupChange_Actions_AddMemberBannedAction{ + Added: &signalpb.MemberBanned{ UserId: encryptedUserID[:], Timestamp: addBannedMember.Timestamp, }, @@ -1334,7 +1334,7 @@ func (cli *Client) EncryptAndSignGroupChange(ctx context.Context, decryptedGroup log.Err(err).Msg("Encrypt UserId error for promoteRequestingMember") return nil, err } - groupChangeActions.DeleteBannedMembers = append(groupChangeActions.DeleteBannedMembers, &signalpb.GroupChange_Actions_DeleteBannedMemberAction{ + groupChangeActions.DeleteMembersBanned = append(groupChangeActions.DeleteMembersBanned, &signalpb.GroupChange_Actions_DeleteMemberBannedAction{ DeletedUserId: encryptedUserID[:], }) } @@ -1365,7 +1365,7 @@ func (cli *Client) EncryptAndSignGroupChange(ctx context.Context, decryptedGroup log.Err(err).Msg("Could not get encrypt Title") return nil, err } - groupChangeActions.ModifyDisappearingMessagesTimer = &signalpb.GroupChange_Actions_ModifyDisappearingMessagesTimerAction{Timer: *encryptedTimer} + groupChangeActions.ModifyDisappearingMessageTimer = &signalpb.GroupChange_Actions_ModifyDisappearingMessageTimerAction{Timer: *encryptedTimer} } if decryptedGroupChange.ModifyInviteLinkPassword != nil { inviteLinkPasswordBytes, err := inviteLinkPasswordToBytes(*decryptedGroupChange.ModifyInviteLinkPassword) @@ -1380,7 +1380,7 @@ func (cli *Client) EncryptAndSignGroupChange(ctx context.Context, decryptedGroup return cli.patchGroup(ctx, groupChangeActions, groupMasterKey, nil) } -func (cli *Client) encryptMember(ctx context.Context, member *GroupMember, groupSecretParams *libsignalgo.GroupSecretParams) (*signalpb.Member, *signalpb.PendingMember, error) { +func (cli *Client) encryptMember(ctx context.Context, member *GroupMember, groupSecretParams *libsignalgo.GroupSecretParams) (*signalpb.Member, *signalpb.MemberPendingProfileKey, error) { log := zerolog.Ctx(ctx) expiringProfileKeyCredential, err := cli.FetchExpiringProfileKeyCredentialById(ctx, member.ACI) if err != nil { @@ -1408,7 +1408,7 @@ func (cli *Client) encryptMember(ctx context.Context, member *GroupMember, group return &encryptedMember, nil, nil } -func (cli *Client) encryptPendingMember(ctx context.Context, pendingMember *PendingMember, groupSecretParams *libsignalgo.GroupSecretParams) (*signalpb.PendingMember, error) { +func (cli *Client) encryptPendingMember(ctx context.Context, pendingMember *PendingMember, groupSecretParams *libsignalgo.GroupSecretParams) (*signalpb.MemberPendingProfileKey, error) { log := zerolog.Ctx(ctx) encryptedUserID, err := groupSecretParams.EncryptServiceID(pendingMember.ServiceID) if err != nil { @@ -1420,7 +1420,7 @@ func (cli *Client) encryptPendingMember(ctx context.Context, pendingMember *Pend log.Err(err).Msg("Encrypt AddedByUserId error for addPendingMember") return nil, err } - encryptedPendingMember := signalpb.PendingMember{ + encryptedPendingMember := signalpb.MemberPendingProfileKey{ AddedByUserId: encryptedAddedByUserID[:], Member: &signalpb.Member{ UserId: encryptedUserID[:], @@ -1600,12 +1600,12 @@ func (cli *Client) EncryptGroup(ctx context.Context, decryptedGroup *Group, grou encryptedGroup := &signalpb.Group{ PublicKey: groupPublicParams[:], Title: *encryptedTitle, - Avatar: decryptedGroup.AvatarPath, + AvatarUrl: decryptedGroup.AvatarPath, AnnouncementsOnly: decryptedGroup.AnnouncementsOnly, - Revision: 0, + Version: 0, } if decryptedGroup.Description != "" { - attributeBlob := signalpb.GroupAttributeBlob{Content: &signalpb.GroupAttributeBlob_Description{Description: decryptedGroup.Description}} + attributeBlob := signalpb.GroupAttributeBlob{Content: &signalpb.GroupAttributeBlob_DescriptionText{DescriptionText: decryptedGroup.Description}} encryptedDescription, err := encryptBlobIntoGroupProperty(groupSecretParams, &attributeBlob) if err != nil { log.Err(err).Msg("Could not get encrypt Description") @@ -1631,7 +1631,7 @@ func (cli *Client) EncryptGroup(ctx context.Context, decryptedGroup *Group, grou if encryptedMember != nil { encryptedGroup.Members = append(encryptedGroup.Members, encryptedMember) } else { - encryptedGroup.PendingMembers = append(encryptedGroup.PendingMembers, encryptedPendingMember) + encryptedGroup.MembersPendingProfileKey = append(encryptedGroup.MembersPendingProfileKey, encryptedPendingMember) } } for _, pendingMember := range decryptedGroup.PendingMembers { @@ -1640,7 +1640,7 @@ func (cli *Client) EncryptGroup(ctx context.Context, decryptedGroup *Group, grou log.Err(err).Msg("Failed to encrypt pendingMember") return nil, err } - encryptedGroup.PendingMembers = append(encryptedGroup.PendingMembers, encryptedPendingMember) + encryptedGroup.MembersPendingProfileKey = append(encryptedGroup.MembersPendingProfileKey, encryptedPendingMember) } return encryptedGroup, nil } diff --git a/pkg/signalmeow/protobuf/ContactDiscovery.pb.go b/pkg/signalmeow/protobuf/ContactDiscovery.pb.go index 5523a0e..637a2d2 100644 --- a/pkg/signalmeow/protobuf/ContactDiscovery.pb.go +++ b/pkg/signalmeow/protobuf/ContactDiscovery.pb.go @@ -1,7 +1,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.36.10 -// protoc v3.21.12 +// protoc-gen-go v1.36.11 +// protoc v6.33.5 // source: ContactDiscovery.proto // Copyright 2021 Signal Messenger, LLC diff --git a/pkg/signalmeow/protobuf/DeviceName.pb.go b/pkg/signalmeow/protobuf/DeviceName.pb.go index 144428d..5666b7e 100644 --- a/pkg/signalmeow/protobuf/DeviceName.pb.go +++ b/pkg/signalmeow/protobuf/DeviceName.pb.go @@ -1,7 +1,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.36.10 -// protoc v3.21.12 +// protoc-gen-go v1.36.11 +// protoc v6.33.5 // source: DeviceName.proto // Copyright 2018 Signal Messenger, LLC diff --git a/pkg/signalmeow/protobuf/Groups.pb.go b/pkg/signalmeow/protobuf/Groups.pb.go index 3e5cc7a..c7717ff 100644 --- a/pkg/signalmeow/protobuf/Groups.pb.go +++ b/pkg/signalmeow/protobuf/Groups.pb.go @@ -1,12 +1,11 @@ -//* -// Copyright (C) 2019 Open Whisper Systems // -// Licensed according to the LICENSE file in this repository. +// Copyright 2020 Signal Messenger, LLC +// SPDX-License-Identifier: AGPL-3.0-only // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.36.10 -// protoc v3.21.12 +// protoc-gen-go v1.36.11 +// protoc v6.33.5 // source: Groups.proto package signalpb @@ -223,14 +222,16 @@ func (x *AvatarUploadAttributes) GetSignature() string { } type Member struct { - state protoimpl.MessageState `protogen:"open.v1"` - UserId []byte `protobuf:"bytes,1,opt,name=userId,proto3" json:"userId,omitempty"` - Role Member_Role `protobuf:"varint,2,opt,name=role,proto3,enum=Member_Role" json:"role,omitempty"` - ProfileKey []byte `protobuf:"bytes,3,opt,name=profileKey,proto3" json:"profileKey,omitempty"` - Presentation []byte `protobuf:"bytes,4,opt,name=presentation,proto3" json:"presentation,omitempty"` // Only set when sending to server - JoinedAtRevision uint32 `protobuf:"varint,5,opt,name=joinedAtRevision,proto3" json:"joinedAtRevision,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` + UserId []byte `protobuf:"bytes,1,opt,name=userId,proto3" json:"userId,omitempty"` + Role Member_Role `protobuf:"varint,2,opt,name=role,proto3,enum=signal.Member_Role" json:"role,omitempty"` + ProfileKey []byte `protobuf:"bytes,3,opt,name=profileKey,proto3" json:"profileKey,omitempty"` + Presentation []byte `protobuf:"bytes,4,opt,name=presentation,proto3" json:"presentation,omitempty"` + JoinedAtVersion uint32 `protobuf:"varint,5,opt,name=joinedAtVersion,proto3" json:"joinedAtVersion,omitempty"` + LabelEmoji []byte `protobuf:"bytes,6,opt,name=labelEmoji,proto3" json:"labelEmoji,omitempty"` // decrypts to a UTF-8 string + LabelString []byte `protobuf:"bytes,7,opt,name=labelString,proto3" json:"labelString,omitempty"` // decrypts to a UTF-8 string + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } func (x *Member) Reset() { @@ -291,36 +292,50 @@ func (x *Member) GetPresentation() []byte { return nil } -func (x *Member) GetJoinedAtRevision() uint32 { +func (x *Member) GetJoinedAtVersion() uint32 { if x != nil { - return x.JoinedAtRevision + return x.JoinedAtVersion } return 0 } -type PendingMember struct { +func (x *Member) GetLabelEmoji() []byte { + if x != nil { + return x.LabelEmoji + } + return nil +} + +func (x *Member) GetLabelString() []byte { + if x != nil { + return x.LabelString + } + return nil +} + +type MemberPendingProfileKey struct { state protoimpl.MessageState `protogen:"open.v1"` Member *Member `protobuf:"bytes,1,opt,name=member,proto3" json:"member,omitempty"` AddedByUserId []byte `protobuf:"bytes,2,opt,name=addedByUserId,proto3" json:"addedByUserId,omitempty"` - Timestamp uint64 `protobuf:"varint,3,opt,name=timestamp,proto3" json:"timestamp,omitempty"` + Timestamp uint64 `protobuf:"varint,3,opt,name=timestamp,proto3" json:"timestamp,omitempty"` // ms since epoch unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } -func (x *PendingMember) Reset() { - *x = PendingMember{} +func (x *MemberPendingProfileKey) Reset() { + *x = MemberPendingProfileKey{} mi := &file_Groups_proto_msgTypes[2] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } -func (x *PendingMember) String() string { +func (x *MemberPendingProfileKey) String() string { return protoimpl.X.MessageStringOf(x) } -func (*PendingMember) ProtoMessage() {} +func (*MemberPendingProfileKey) ProtoMessage() {} -func (x *PendingMember) ProtoReflect() protoreflect.Message { +func (x *MemberPendingProfileKey) ProtoReflect() protoreflect.Message { mi := &file_Groups_proto_msgTypes[2] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -332,56 +347,56 @@ func (x *PendingMember) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use PendingMember.ProtoReflect.Descriptor instead. -func (*PendingMember) Descriptor() ([]byte, []int) { +// Deprecated: Use MemberPendingProfileKey.ProtoReflect.Descriptor instead. +func (*MemberPendingProfileKey) Descriptor() ([]byte, []int) { return file_Groups_proto_rawDescGZIP(), []int{2} } -func (x *PendingMember) GetMember() *Member { +func (x *MemberPendingProfileKey) GetMember() *Member { if x != nil { return x.Member } return nil } -func (x *PendingMember) GetAddedByUserId() []byte { +func (x *MemberPendingProfileKey) GetAddedByUserId() []byte { if x != nil { return x.AddedByUserId } return nil } -func (x *PendingMember) GetTimestamp() uint64 { +func (x *MemberPendingProfileKey) GetTimestamp() uint64 { if x != nil { return x.Timestamp } return 0 } -type RequestingMember struct { +type MemberPendingAdminApproval struct { state protoimpl.MessageState `protogen:"open.v1"` UserId []byte `protobuf:"bytes,1,opt,name=userId,proto3" json:"userId,omitempty"` ProfileKey []byte `protobuf:"bytes,2,opt,name=profileKey,proto3" json:"profileKey,omitempty"` - Presentation []byte `protobuf:"bytes,3,opt,name=presentation,proto3" json:"presentation,omitempty"` // Only set when sending to server - Timestamp uint64 `protobuf:"varint,4,opt,name=timestamp,proto3" json:"timestamp,omitempty"` + Presentation []byte `protobuf:"bytes,3,opt,name=presentation,proto3" json:"presentation,omitempty"` + Timestamp uint64 `protobuf:"varint,4,opt,name=timestamp,proto3" json:"timestamp,omitempty"` // ms since epoch unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } -func (x *RequestingMember) Reset() { - *x = RequestingMember{} +func (x *MemberPendingAdminApproval) Reset() { + *x = MemberPendingAdminApproval{} mi := &file_Groups_proto_msgTypes[3] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } -func (x *RequestingMember) String() string { +func (x *MemberPendingAdminApproval) String() string { return protoimpl.X.MessageStringOf(x) } -func (*RequestingMember) ProtoMessage() {} +func (*MemberPendingAdminApproval) ProtoMessage() {} -func (x *RequestingMember) ProtoReflect() protoreflect.Message { +func (x *MemberPendingAdminApproval) ProtoReflect() protoreflect.Message { mi := &file_Groups_proto_msgTypes[3] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -393,61 +408,61 @@ func (x *RequestingMember) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use RequestingMember.ProtoReflect.Descriptor instead. -func (*RequestingMember) Descriptor() ([]byte, []int) { +// Deprecated: Use MemberPendingAdminApproval.ProtoReflect.Descriptor instead. +func (*MemberPendingAdminApproval) Descriptor() ([]byte, []int) { return file_Groups_proto_rawDescGZIP(), []int{3} } -func (x *RequestingMember) GetUserId() []byte { +func (x *MemberPendingAdminApproval) GetUserId() []byte { if x != nil { return x.UserId } return nil } -func (x *RequestingMember) GetProfileKey() []byte { +func (x *MemberPendingAdminApproval) GetProfileKey() []byte { if x != nil { return x.ProfileKey } return nil } -func (x *RequestingMember) GetPresentation() []byte { +func (x *MemberPendingAdminApproval) GetPresentation() []byte { if x != nil { return x.Presentation } return nil } -func (x *RequestingMember) GetTimestamp() uint64 { +func (x *MemberPendingAdminApproval) GetTimestamp() uint64 { if x != nil { return x.Timestamp } return 0 } -type BannedMember struct { +type MemberBanned struct { state protoimpl.MessageState `protogen:"open.v1"` UserId []byte `protobuf:"bytes,1,opt,name=userId,proto3" json:"userId,omitempty"` - Timestamp uint64 `protobuf:"varint,2,opt,name=timestamp,proto3" json:"timestamp,omitempty"` + Timestamp uint64 `protobuf:"varint,2,opt,name=timestamp,proto3" json:"timestamp,omitempty"` // ms since epoch unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } -func (x *BannedMember) Reset() { - *x = BannedMember{} +func (x *MemberBanned) Reset() { + *x = MemberBanned{} mi := &file_Groups_proto_msgTypes[4] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } -func (x *BannedMember) String() string { +func (x *MemberBanned) String() string { return protoimpl.X.MessageStringOf(x) } -func (*BannedMember) ProtoMessage() {} +func (*MemberBanned) ProtoMessage() {} -func (x *BannedMember) ProtoReflect() protoreflect.Message { +func (x *MemberBanned) ProtoReflect() protoreflect.Message { mi := &file_Groups_proto_msgTypes[4] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -459,19 +474,19 @@ func (x *BannedMember) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use BannedMember.ProtoReflect.Descriptor instead. -func (*BannedMember) Descriptor() ([]byte, []int) { +// Deprecated: Use MemberBanned.ProtoReflect.Descriptor instead. +func (*MemberBanned) Descriptor() ([]byte, []int) { return file_Groups_proto_rawDescGZIP(), []int{4} } -func (x *BannedMember) GetUserId() []byte { +func (x *MemberBanned) GetUserId() []byte { if x != nil { return x.UserId } return nil } -func (x *BannedMember) GetTimestamp() uint64 { +func (x *MemberBanned) GetTimestamp() uint64 { if x != nil { return x.Timestamp } @@ -480,9 +495,9 @@ func (x *BannedMember) GetTimestamp() uint64 { type AccessControl struct { state protoimpl.MessageState `protogen:"open.v1"` - Attributes AccessControl_AccessRequired `protobuf:"varint,1,opt,name=attributes,proto3,enum=AccessControl_AccessRequired" json:"attributes,omitempty"` - Members AccessControl_AccessRequired `protobuf:"varint,2,opt,name=members,proto3,enum=AccessControl_AccessRequired" json:"members,omitempty"` - AddFromInviteLink AccessControl_AccessRequired `protobuf:"varint,3,opt,name=addFromInviteLink,proto3,enum=AccessControl_AccessRequired" json:"addFromInviteLink,omitempty"` + Attributes AccessControl_AccessRequired `protobuf:"varint,1,opt,name=attributes,proto3,enum=signal.AccessControl_AccessRequired" json:"attributes,omitempty"` + Members AccessControl_AccessRequired `protobuf:"varint,2,opt,name=members,proto3,enum=signal.AccessControl_AccessRequired" json:"members,omitempty"` + AddFromInviteLink AccessControl_AccessRequired `protobuf:"varint,3,opt,name=addFromInviteLink,proto3,enum=signal.AccessControl_AccessRequired" json:"addFromInviteLink,omitempty"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } @@ -539,22 +554,24 @@ func (x *AccessControl) GetAddFromInviteLink() AccessControl_AccessRequired { } type Group struct { - state protoimpl.MessageState `protogen:"open.v1"` - PublicKey []byte `protobuf:"bytes,1,opt,name=publicKey,proto3" json:"publicKey,omitempty"` - Title []byte `protobuf:"bytes,2,opt,name=title,proto3" json:"title,omitempty"` - Avatar string `protobuf:"bytes,3,opt,name=avatar,proto3" json:"avatar,omitempty"` - DisappearingMessagesTimer []byte `protobuf:"bytes,4,opt,name=disappearingMessagesTimer,proto3" json:"disappearingMessagesTimer,omitempty"` - AccessControl *AccessControl `protobuf:"bytes,5,opt,name=accessControl,proto3" json:"accessControl,omitempty"` - Revision uint32 `protobuf:"varint,6,opt,name=revision,proto3" json:"revision,omitempty"` - Members []*Member `protobuf:"bytes,7,rep,name=members,proto3" json:"members,omitempty"` - PendingMembers []*PendingMember `protobuf:"bytes,8,rep,name=pendingMembers,proto3" json:"pendingMembers,omitempty"` - RequestingMembers []*RequestingMember `protobuf:"bytes,9,rep,name=requestingMembers,proto3" json:"requestingMembers,omitempty"` - InviteLinkPassword []byte `protobuf:"bytes,10,opt,name=inviteLinkPassword,proto3" json:"inviteLinkPassword,omitempty"` - Description []byte `protobuf:"bytes,11,opt,name=description,proto3" json:"description,omitempty"` - AnnouncementsOnly bool `protobuf:"varint,12,opt,name=announcementsOnly,proto3" json:"announcementsOnly,omitempty"` - BannedMembers []*BannedMember `protobuf:"bytes,13,rep,name=bannedMembers,proto3" json:"bannedMembers,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` + PublicKey []byte `protobuf:"bytes,1,opt,name=publicKey,proto3" json:"publicKey,omitempty"` + Title []byte `protobuf:"bytes,2,opt,name=title,proto3" json:"title,omitempty"` + Description []byte `protobuf:"bytes,11,opt,name=description,proto3" json:"description,omitempty"` + // The URL for this group's avatar. The content at this URL can be + // decrypted/deserialized into a `GroupAttributeBlob`. + AvatarUrl string `protobuf:"bytes,3,opt,name=avatarUrl,proto3" json:"avatarUrl,omitempty"` + DisappearingMessagesTimer []byte `protobuf:"bytes,4,opt,name=disappearingMessagesTimer,proto3" json:"disappearingMessagesTimer,omitempty"` + AccessControl *AccessControl `protobuf:"bytes,5,opt,name=accessControl,proto3" json:"accessControl,omitempty"` + Version uint32 `protobuf:"varint,6,opt,name=version,proto3" json:"version,omitempty"` + Members []*Member `protobuf:"bytes,7,rep,name=members,proto3" json:"members,omitempty"` + MembersPendingProfileKey []*MemberPendingProfileKey `protobuf:"bytes,8,rep,name=membersPendingProfileKey,proto3" json:"membersPendingProfileKey,omitempty"` + MembersPendingAdminApproval []*MemberPendingAdminApproval `protobuf:"bytes,9,rep,name=membersPendingAdminApproval,proto3" json:"membersPendingAdminApproval,omitempty"` + InviteLinkPassword []byte `protobuf:"bytes,10,opt,name=inviteLinkPassword,proto3" json:"inviteLinkPassword,omitempty"` + AnnouncementsOnly bool `protobuf:"varint,12,opt,name=announcements_only,json=announcementsOnly,proto3" json:"announcements_only,omitempty"` + MembersBanned []*MemberBanned `protobuf:"bytes,13,rep,name=members_banned,json=membersBanned,proto3" json:"members_banned,omitempty"` // next: 14 + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } func (x *Group) Reset() { @@ -601,9 +618,16 @@ func (x *Group) GetTitle() []byte { return nil } -func (x *Group) GetAvatar() string { +func (x *Group) GetDescription() []byte { if x != nil { - return x.Avatar + return x.Description + } + return nil +} + +func (x *Group) GetAvatarUrl() string { + if x != nil { + return x.AvatarUrl } return "" } @@ -622,9 +646,9 @@ func (x *Group) GetAccessControl() *AccessControl { return nil } -func (x *Group) GetRevision() uint32 { +func (x *Group) GetVersion() uint32 { if x != nil { - return x.Revision + return x.Version } return 0 } @@ -636,16 +660,16 @@ func (x *Group) GetMembers() []*Member { return nil } -func (x *Group) GetPendingMembers() []*PendingMember { +func (x *Group) GetMembersPendingProfileKey() []*MemberPendingProfileKey { if x != nil { - return x.PendingMembers + return x.MembersPendingProfileKey } return nil } -func (x *Group) GetRequestingMembers() []*RequestingMember { +func (x *Group) GetMembersPendingAdminApproval() []*MemberPendingAdminApproval { if x != nil { - return x.RequestingMembers + return x.MembersPendingAdminApproval } return nil } @@ -657,13 +681,6 @@ func (x *Group) GetInviteLinkPassword() []byte { return nil } -func (x *Group) GetDescription() []byte { - if x != nil { - return x.Description - } - return nil -} - func (x *Group) GetAnnouncementsOnly() bool { if x != nil { return x.AnnouncementsOnly @@ -671,225 +688,9 @@ func (x *Group) GetAnnouncementsOnly() bool { return false } -func (x *Group) GetBannedMembers() []*BannedMember { +func (x *Group) GetMembersBanned() []*MemberBanned { if x != nil { - return x.BannedMembers - } - return nil -} - -type GroupChange struct { - state protoimpl.MessageState `protogen:"open.v1"` - Actions []byte `protobuf:"bytes,1,opt,name=actions,proto3" json:"actions,omitempty"` - ServerSignature []byte `protobuf:"bytes,2,opt,name=serverSignature,proto3" json:"serverSignature,omitempty"` - ChangeEpoch uint32 `protobuf:"varint,3,opt,name=changeEpoch,proto3" json:"changeEpoch,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache -} - -func (x *GroupChange) Reset() { - *x = GroupChange{} - mi := &file_Groups_proto_msgTypes[7] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) -} - -func (x *GroupChange) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*GroupChange) ProtoMessage() {} - -func (x *GroupChange) ProtoReflect() protoreflect.Message { - mi := &file_Groups_proto_msgTypes[7] - if x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use GroupChange.ProtoReflect.Descriptor instead. -func (*GroupChange) Descriptor() ([]byte, []int) { - return file_Groups_proto_rawDescGZIP(), []int{7} -} - -func (x *GroupChange) GetActions() []byte { - if x != nil { - return x.Actions - } - return nil -} - -func (x *GroupChange) GetServerSignature() []byte { - if x != nil { - return x.ServerSignature - } - return nil -} - -func (x *GroupChange) GetChangeEpoch() uint32 { - if x != nil { - return x.ChangeEpoch - } - return 0 -} - -type GroupResponse struct { - state protoimpl.MessageState `protogen:"open.v1"` - Group *Group `protobuf:"bytes,1,opt,name=group,proto3" json:"group,omitempty"` - GroupSendEndorsementsResponse []byte `protobuf:"bytes,2,opt,name=groupSendEndorsementsResponse,proto3" json:"groupSendEndorsementsResponse,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache -} - -func (x *GroupResponse) Reset() { - *x = GroupResponse{} - mi := &file_Groups_proto_msgTypes[8] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) -} - -func (x *GroupResponse) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*GroupResponse) ProtoMessage() {} - -func (x *GroupResponse) ProtoReflect() protoreflect.Message { - mi := &file_Groups_proto_msgTypes[8] - if x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use GroupResponse.ProtoReflect.Descriptor instead. -func (*GroupResponse) Descriptor() ([]byte, []int) { - return file_Groups_proto_rawDescGZIP(), []int{8} -} - -func (x *GroupResponse) GetGroup() *Group { - if x != nil { - return x.Group - } - return nil -} - -func (x *GroupResponse) GetGroupSendEndorsementsResponse() []byte { - if x != nil { - return x.GroupSendEndorsementsResponse - } - return nil -} - -type GroupChanges struct { - state protoimpl.MessageState `protogen:"open.v1"` - GroupChanges []*GroupChanges_GroupChangeState `protobuf:"bytes,1,rep,name=groupChanges,proto3" json:"groupChanges,omitempty"` - GroupSendEndorsementsResponse []byte `protobuf:"bytes,2,opt,name=groupSendEndorsementsResponse,proto3" json:"groupSendEndorsementsResponse,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache -} - -func (x *GroupChanges) Reset() { - *x = GroupChanges{} - mi := &file_Groups_proto_msgTypes[9] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) -} - -func (x *GroupChanges) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*GroupChanges) ProtoMessage() {} - -func (x *GroupChanges) ProtoReflect() protoreflect.Message { - mi := &file_Groups_proto_msgTypes[9] - if x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use GroupChanges.ProtoReflect.Descriptor instead. -func (*GroupChanges) Descriptor() ([]byte, []int) { - return file_Groups_proto_rawDescGZIP(), []int{9} -} - -func (x *GroupChanges) GetGroupChanges() []*GroupChanges_GroupChangeState { - if x != nil { - return x.GroupChanges - } - return nil -} - -func (x *GroupChanges) GetGroupSendEndorsementsResponse() []byte { - if x != nil { - return x.GroupSendEndorsementsResponse - } - return nil -} - -type GroupChangeResponse struct { - state protoimpl.MessageState `protogen:"open.v1"` - GroupChange *GroupChange `protobuf:"bytes,1,opt,name=groupChange,proto3" json:"groupChange,omitempty"` - GroupSendEndorsementsResponse []byte `protobuf:"bytes,2,opt,name=groupSendEndorsementsResponse,proto3" json:"groupSendEndorsementsResponse,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache -} - -func (x *GroupChangeResponse) Reset() { - *x = GroupChangeResponse{} - mi := &file_Groups_proto_msgTypes[10] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) -} - -func (x *GroupChangeResponse) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*GroupChangeResponse) ProtoMessage() {} - -func (x *GroupChangeResponse) ProtoReflect() protoreflect.Message { - mi := &file_Groups_proto_msgTypes[10] - if x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use GroupChangeResponse.ProtoReflect.Descriptor instead. -func (*GroupChangeResponse) Descriptor() ([]byte, []int) { - return file_Groups_proto_rawDescGZIP(), []int{10} -} - -func (x *GroupChangeResponse) GetGroupChange() *GroupChange { - if x != nil { - return x.GroupChange - } - return nil -} - -func (x *GroupChangeResponse) GetGroupSendEndorsementsResponse() []byte { - if x != nil { - return x.GroupSendEndorsementsResponse + return x.MembersBanned } return nil } @@ -901,7 +702,7 @@ type GroupAttributeBlob struct { // *GroupAttributeBlob_Title // *GroupAttributeBlob_Avatar // *GroupAttributeBlob_DisappearingMessagesDuration - // *GroupAttributeBlob_Description + // *GroupAttributeBlob_DescriptionText Content isGroupAttributeBlob_Content `protobuf_oneof:"content"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache @@ -909,7 +710,7 @@ type GroupAttributeBlob struct { func (x *GroupAttributeBlob) Reset() { *x = GroupAttributeBlob{} - mi := &file_Groups_proto_msgTypes[11] + mi := &file_Groups_proto_msgTypes[7] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -921,7 +722,7 @@ func (x *GroupAttributeBlob) String() string { func (*GroupAttributeBlob) ProtoMessage() {} func (x *GroupAttributeBlob) ProtoReflect() protoreflect.Message { - mi := &file_Groups_proto_msgTypes[11] + mi := &file_Groups_proto_msgTypes[7] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -934,7 +735,7 @@ func (x *GroupAttributeBlob) ProtoReflect() protoreflect.Message { // Deprecated: Use GroupAttributeBlob.ProtoReflect.Descriptor instead. func (*GroupAttributeBlob) Descriptor() ([]byte, []int) { - return file_Groups_proto_rawDescGZIP(), []int{11} + return file_Groups_proto_rawDescGZIP(), []int{7} } func (x *GroupAttributeBlob) GetContent() isGroupAttributeBlob_Content { @@ -971,10 +772,10 @@ func (x *GroupAttributeBlob) GetDisappearingMessagesDuration() uint32 { return 0 } -func (x *GroupAttributeBlob) GetDescription() string { +func (x *GroupAttributeBlob) GetDescriptionText() string { if x != nil { - if x, ok := x.Content.(*GroupAttributeBlob_Description); ok { - return x.Description + if x, ok := x.Content.(*GroupAttributeBlob_DescriptionText); ok { + return x.DescriptionText } } return "" @@ -996,8 +797,8 @@ type GroupAttributeBlob_DisappearingMessagesDuration struct { DisappearingMessagesDuration uint32 `protobuf:"varint,3,opt,name=disappearingMessagesDuration,proto3,oneof"` } -type GroupAttributeBlob_Description struct { - Description string `protobuf:"bytes,4,opt,name=description,proto3,oneof"` +type GroupAttributeBlob_DescriptionText struct { + DescriptionText string `protobuf:"bytes,4,opt,name=descriptionText,proto3,oneof"` } func (*GroupAttributeBlob_Title) isGroupAttributeBlob_Content() {} @@ -1006,13 +807,13 @@ func (*GroupAttributeBlob_Avatar) isGroupAttributeBlob_Content() {} func (*GroupAttributeBlob_DisappearingMessagesDuration) isGroupAttributeBlob_Content() {} -func (*GroupAttributeBlob_Description) isGroupAttributeBlob_Content() {} +func (*GroupAttributeBlob_DescriptionText) isGroupAttributeBlob_Content() {} type GroupInviteLink struct { state protoimpl.MessageState `protogen:"open.v1"` // Types that are valid to be assigned to Contents: // - // *GroupInviteLink_V1Contents + // *GroupInviteLink_ContentsV1 Contents isGroupInviteLink_Contents `protobuf_oneof:"contents"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache @@ -1020,7 +821,7 @@ type GroupInviteLink struct { func (x *GroupInviteLink) Reset() { *x = GroupInviteLink{} - mi := &file_Groups_proto_msgTypes[12] + mi := &file_Groups_proto_msgTypes[8] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1032,7 +833,7 @@ func (x *GroupInviteLink) String() string { func (*GroupInviteLink) ProtoMessage() {} func (x *GroupInviteLink) ProtoReflect() protoreflect.Message { - mi := &file_Groups_proto_msgTypes[12] + mi := &file_Groups_proto_msgTypes[8] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1045,7 +846,7 @@ func (x *GroupInviteLink) ProtoReflect() protoreflect.Message { // Deprecated: Use GroupInviteLink.ProtoReflect.Descriptor instead. func (*GroupInviteLink) Descriptor() ([]byte, []int) { - return file_Groups_proto_rawDescGZIP(), []int{12} + return file_Groups_proto_rawDescGZIP(), []int{8} } func (x *GroupInviteLink) GetContents() isGroupInviteLink_Contents { @@ -1055,10 +856,10 @@ func (x *GroupInviteLink) GetContents() isGroupInviteLink_Contents { return nil } -func (x *GroupInviteLink) GetV1Contents() *GroupInviteLink_GroupInviteLinkContentsV1 { +func (x *GroupInviteLink) GetContentsV1() *GroupInviteLink_GroupInviteLinkContentsV1 { if x != nil { - if x, ok := x.Contents.(*GroupInviteLink_V1Contents); ok { - return x.V1Contents + if x, ok := x.Contents.(*GroupInviteLink_ContentsV1); ok { + return x.ContentsV1 } } return nil @@ -1068,29 +869,29 @@ type isGroupInviteLink_Contents interface { isGroupInviteLink_Contents() } -type GroupInviteLink_V1Contents struct { - V1Contents *GroupInviteLink_GroupInviteLinkContentsV1 `protobuf:"bytes,1,opt,name=v1Contents,proto3,oneof"` +type GroupInviteLink_ContentsV1 struct { + ContentsV1 *GroupInviteLink_GroupInviteLinkContentsV1 `protobuf:"bytes,1,opt,name=contentsV1,proto3,oneof"` } -func (*GroupInviteLink_V1Contents) isGroupInviteLink_Contents() {} +func (*GroupInviteLink_ContentsV1) isGroupInviteLink_Contents() {} type GroupJoinInfo struct { state protoimpl.MessageState `protogen:"open.v1"` PublicKey []byte `protobuf:"bytes,1,opt,name=publicKey,proto3" json:"publicKey,omitempty"` Title []byte `protobuf:"bytes,2,opt,name=title,proto3" json:"title,omitempty"` + Description []byte `protobuf:"bytes,8,opt,name=description,proto3" json:"description,omitempty"` Avatar string `protobuf:"bytes,3,opt,name=avatar,proto3" json:"avatar,omitempty"` MemberCount uint32 `protobuf:"varint,4,opt,name=memberCount,proto3" json:"memberCount,omitempty"` - AddFromInviteLink AccessControl_AccessRequired `protobuf:"varint,5,opt,name=addFromInviteLink,proto3,enum=AccessControl_AccessRequired" json:"addFromInviteLink,omitempty"` - Revision uint32 `protobuf:"varint,6,opt,name=revision,proto3" json:"revision,omitempty"` + AddFromInviteLink AccessControl_AccessRequired `protobuf:"varint,5,opt,name=addFromInviteLink,proto3,enum=signal.AccessControl_AccessRequired" json:"addFromInviteLink,omitempty"` + Version uint32 `protobuf:"varint,6,opt,name=version,proto3" json:"version,omitempty"` PendingAdminApproval bool `protobuf:"varint,7,opt,name=pendingAdminApproval,proto3" json:"pendingAdminApproval,omitempty"` - Description []byte `protobuf:"bytes,8,opt,name=description,proto3" json:"description,omitempty"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } func (x *GroupJoinInfo) Reset() { *x = GroupJoinInfo{} - mi := &file_Groups_proto_msgTypes[13] + mi := &file_Groups_proto_msgTypes[9] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1102,7 +903,7 @@ func (x *GroupJoinInfo) String() string { func (*GroupJoinInfo) ProtoMessage() {} func (x *GroupJoinInfo) ProtoReflect() protoreflect.Message { - mi := &file_Groups_proto_msgTypes[13] + mi := &file_Groups_proto_msgTypes[9] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1115,7 +916,7 @@ func (x *GroupJoinInfo) ProtoReflect() protoreflect.Message { // Deprecated: Use GroupJoinInfo.ProtoReflect.Descriptor instead. func (*GroupJoinInfo) Descriptor() ([]byte, []int) { - return file_Groups_proto_rawDescGZIP(), []int{13} + return file_Groups_proto_rawDescGZIP(), []int{9} } func (x *GroupJoinInfo) GetPublicKey() []byte { @@ -1132,6 +933,13 @@ func (x *GroupJoinInfo) GetTitle() []byte { return nil } +func (x *GroupJoinInfo) GetDescription() []byte { + if x != nil { + return x.Description + } + return nil +} + func (x *GroupJoinInfo) GetAvatar() string { if x != nil { return x.Avatar @@ -1153,9 +961,9 @@ func (x *GroupJoinInfo) GetAddFromInviteLink() AccessControl_AccessRequired { return AccessControl_UNKNOWN } -func (x *GroupJoinInfo) GetRevision() uint32 { +func (x *GroupJoinInfo) GetVersion() uint32 { if x != nil { - return x.Revision + return x.Version } return 0 } @@ -1167,34 +975,236 @@ func (x *GroupJoinInfo) GetPendingAdminApproval() bool { return false } -func (x *GroupJoinInfo) GetDescription() []byte { +type GroupChange struct { + state protoimpl.MessageState `protogen:"open.v1"` + Actions []byte `protobuf:"bytes,1,opt,name=actions,proto3" json:"actions,omitempty"` + ServerSignature []byte `protobuf:"bytes,2,opt,name=serverSignature,proto3" json:"serverSignature,omitempty"` + ChangeEpoch uint32 `protobuf:"varint,3,opt,name=changeEpoch,proto3" json:"changeEpoch,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *GroupChange) Reset() { + *x = GroupChange{} + mi := &file_Groups_proto_msgTypes[10] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *GroupChange) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GroupChange) ProtoMessage() {} + +func (x *GroupChange) ProtoReflect() protoreflect.Message { + mi := &file_Groups_proto_msgTypes[10] if x != nil { - return x.Description + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GroupChange.ProtoReflect.Descriptor instead. +func (*GroupChange) Descriptor() ([]byte, []int) { + return file_Groups_proto_rawDescGZIP(), []int{10} +} + +func (x *GroupChange) GetActions() []byte { + if x != nil { + return x.Actions } return nil } -type GroupExternalCredential struct { +func (x *GroupChange) GetServerSignature() []byte { + if x != nil { + return x.ServerSignature + } + return nil +} + +func (x *GroupChange) GetChangeEpoch() uint32 { + if x != nil { + return x.ChangeEpoch + } + return 0 +} + +type ExternalGroupCredential struct { state protoimpl.MessageState `protogen:"open.v1"` Token string `protobuf:"bytes,1,opt,name=token,proto3" json:"token,omitempty"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } -func (x *GroupExternalCredential) Reset() { - *x = GroupExternalCredential{} +func (x *ExternalGroupCredential) Reset() { + *x = ExternalGroupCredential{} + mi := &file_Groups_proto_msgTypes[11] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ExternalGroupCredential) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ExternalGroupCredential) ProtoMessage() {} + +func (x *ExternalGroupCredential) ProtoReflect() protoreflect.Message { + mi := &file_Groups_proto_msgTypes[11] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ExternalGroupCredential.ProtoReflect.Descriptor instead. +func (*ExternalGroupCredential) Descriptor() ([]byte, []int) { + return file_Groups_proto_rawDescGZIP(), []int{11} +} + +func (x *ExternalGroupCredential) GetToken() string { + if x != nil { + return x.Token + } + return "" +} + +type GroupResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + Group *Group `protobuf:"bytes,1,opt,name=group,proto3" json:"group,omitempty"` + GroupSendEndorsementsResponse []byte `protobuf:"bytes,2,opt,name=group_send_endorsements_response,json=groupSendEndorsementsResponse,proto3" json:"group_send_endorsements_response,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *GroupResponse) Reset() { + *x = GroupResponse{} + mi := &file_Groups_proto_msgTypes[12] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *GroupResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GroupResponse) ProtoMessage() {} + +func (x *GroupResponse) ProtoReflect() protoreflect.Message { + mi := &file_Groups_proto_msgTypes[12] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GroupResponse.ProtoReflect.Descriptor instead. +func (*GroupResponse) Descriptor() ([]byte, []int) { + return file_Groups_proto_rawDescGZIP(), []int{12} +} + +func (x *GroupResponse) GetGroup() *Group { + if x != nil { + return x.Group + } + return nil +} + +func (x *GroupResponse) GetGroupSendEndorsementsResponse() []byte { + if x != nil { + return x.GroupSendEndorsementsResponse + } + return nil +} + +type GroupChanges struct { + state protoimpl.MessageState `protogen:"open.v1"` + GroupChanges []*GroupChanges_GroupChangeState `protobuf:"bytes,1,rep,name=groupChanges,proto3" json:"groupChanges,omitempty"` + GroupSendEndorsementsResponse []byte `protobuf:"bytes,2,opt,name=group_send_endorsements_response,json=groupSendEndorsementsResponse,proto3" json:"group_send_endorsements_response,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *GroupChanges) Reset() { + *x = GroupChanges{} + mi := &file_Groups_proto_msgTypes[13] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *GroupChanges) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GroupChanges) ProtoMessage() {} + +func (x *GroupChanges) ProtoReflect() protoreflect.Message { + mi := &file_Groups_proto_msgTypes[13] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GroupChanges.ProtoReflect.Descriptor instead. +func (*GroupChanges) Descriptor() ([]byte, []int) { + return file_Groups_proto_rawDescGZIP(), []int{13} +} + +func (x *GroupChanges) GetGroupChanges() []*GroupChanges_GroupChangeState { + if x != nil { + return x.GroupChanges + } + return nil +} + +func (x *GroupChanges) GetGroupSendEndorsementsResponse() []byte { + if x != nil { + return x.GroupSendEndorsementsResponse + } + return nil +} + +type GroupChangeResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + GroupChange *GroupChange `protobuf:"bytes,1,opt,name=group_change,json=groupChange,proto3" json:"group_change,omitempty"` + GroupSendEndorsementsResponse []byte `protobuf:"bytes,2,opt,name=group_send_endorsements_response,json=groupSendEndorsementsResponse,proto3" json:"group_send_endorsements_response,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *GroupChangeResponse) Reset() { + *x = GroupChangeResponse{} mi := &file_Groups_proto_msgTypes[14] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } -func (x *GroupExternalCredential) String() string { +func (x *GroupChangeResponse) String() string { return protoimpl.X.MessageStringOf(x) } -func (*GroupExternalCredential) ProtoMessage() {} +func (*GroupChangeResponse) ProtoMessage() {} -func (x *GroupExternalCredential) ProtoReflect() protoreflect.Message { +func (x *GroupChangeResponse) ProtoReflect() protoreflect.Message { mi := &file_Groups_proto_msgTypes[14] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -1206,52 +1216,114 @@ func (x *GroupExternalCredential) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use GroupExternalCredential.ProtoReflect.Descriptor instead. -func (*GroupExternalCredential) Descriptor() ([]byte, []int) { +// Deprecated: Use GroupChangeResponse.ProtoReflect.Descriptor instead. +func (*GroupChangeResponse) Descriptor() ([]byte, []int) { return file_Groups_proto_rawDescGZIP(), []int{14} } -func (x *GroupExternalCredential) GetToken() string { +func (x *GroupChangeResponse) GetGroupChange() *GroupChange { if x != nil { - return x.Token + return x.GroupChange } - return "" + return nil +} + +func (x *GroupChangeResponse) GetGroupSendEndorsementsResponse() []byte { + if x != nil { + return x.GroupSendEndorsementsResponse + } + return nil +} + +type GroupInviteLink_GroupInviteLinkContentsV1 struct { + state protoimpl.MessageState `protogen:"open.v1"` + GroupMasterKey []byte `protobuf:"bytes,1,opt,name=groupMasterKey,proto3" json:"groupMasterKey,omitempty"` + InviteLinkPassword []byte `protobuf:"bytes,2,opt,name=inviteLinkPassword,proto3" json:"inviteLinkPassword,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *GroupInviteLink_GroupInviteLinkContentsV1) Reset() { + *x = GroupInviteLink_GroupInviteLinkContentsV1{} + mi := &file_Groups_proto_msgTypes[15] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *GroupInviteLink_GroupInviteLinkContentsV1) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GroupInviteLink_GroupInviteLinkContentsV1) ProtoMessage() {} + +func (x *GroupInviteLink_GroupInviteLinkContentsV1) ProtoReflect() protoreflect.Message { + mi := &file_Groups_proto_msgTypes[15] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GroupInviteLink_GroupInviteLinkContentsV1.ProtoReflect.Descriptor instead. +func (*GroupInviteLink_GroupInviteLinkContentsV1) Descriptor() ([]byte, []int) { + return file_Groups_proto_rawDescGZIP(), []int{8, 0} +} + +func (x *GroupInviteLink_GroupInviteLinkContentsV1) GetGroupMasterKey() []byte { + if x != nil { + return x.GroupMasterKey + } + return nil +} + +func (x *GroupInviteLink_GroupInviteLinkContentsV1) GetInviteLinkPassword() []byte { + if x != nil { + return x.InviteLinkPassword + } + return nil } type GroupChange_Actions struct { - state protoimpl.MessageState `protogen:"open.v1"` - SourceServiceId []byte `protobuf:"bytes,1,opt,name=sourceServiceId,proto3" json:"sourceServiceId,omitempty"` - GroupId []byte `protobuf:"bytes,25,opt,name=groupId,proto3" json:"groupId,omitempty"` // Only set when receiving from server - Revision uint32 `protobuf:"varint,2,opt,name=revision,proto3" json:"revision,omitempty"` - AddMembers []*GroupChange_Actions_AddMemberAction `protobuf:"bytes,3,rep,name=addMembers,proto3" json:"addMembers,omitempty"` - DeleteMembers []*GroupChange_Actions_DeleteMemberAction `protobuf:"bytes,4,rep,name=deleteMembers,proto3" json:"deleteMembers,omitempty"` - ModifyMemberRoles []*GroupChange_Actions_ModifyMemberRoleAction `protobuf:"bytes,5,rep,name=modifyMemberRoles,proto3" json:"modifyMemberRoles,omitempty"` - ModifyMemberProfileKeys []*GroupChange_Actions_ModifyMemberProfileKeyAction `protobuf:"bytes,6,rep,name=modifyMemberProfileKeys,proto3" json:"modifyMemberProfileKeys,omitempty"` - AddPendingMembers []*GroupChange_Actions_AddPendingMemberAction `protobuf:"bytes,7,rep,name=addPendingMembers,proto3" json:"addPendingMembers,omitempty"` - DeletePendingMembers []*GroupChange_Actions_DeletePendingMemberAction `protobuf:"bytes,8,rep,name=deletePendingMembers,proto3" json:"deletePendingMembers,omitempty"` - PromotePendingMembers []*GroupChange_Actions_PromotePendingMemberAction `protobuf:"bytes,9,rep,name=promotePendingMembers,proto3" json:"promotePendingMembers,omitempty"` - ModifyTitle *GroupChange_Actions_ModifyTitleAction `protobuf:"bytes,10,opt,name=modifyTitle,proto3" json:"modifyTitle,omitempty"` - ModifyAvatar *GroupChange_Actions_ModifyAvatarAction `protobuf:"bytes,11,opt,name=modifyAvatar,proto3" json:"modifyAvatar,omitempty"` - ModifyDisappearingMessagesTimer *GroupChange_Actions_ModifyDisappearingMessagesTimerAction `protobuf:"bytes,12,opt,name=modifyDisappearingMessagesTimer,proto3" json:"modifyDisappearingMessagesTimer,omitempty"` - ModifyAttributesAccess *GroupChange_Actions_ModifyAttributesAccessControlAction `protobuf:"bytes,13,opt,name=modifyAttributesAccess,proto3" json:"modifyAttributesAccess,omitempty"` - ModifyMemberAccess *GroupChange_Actions_ModifyMembersAccessControlAction `protobuf:"bytes,14,opt,name=modifyMemberAccess,proto3" json:"modifyMemberAccess,omitempty"` - ModifyAddFromInviteLinkAccess *GroupChange_Actions_ModifyAddFromInviteLinkAccessControlAction `protobuf:"bytes,15,opt,name=modifyAddFromInviteLinkAccess,proto3" json:"modifyAddFromInviteLinkAccess,omitempty"` - AddRequestingMembers []*GroupChange_Actions_AddRequestingMemberAction `protobuf:"bytes,16,rep,name=addRequestingMembers,proto3" json:"addRequestingMembers,omitempty"` - DeleteRequestingMembers []*GroupChange_Actions_DeleteRequestingMemberAction `protobuf:"bytes,17,rep,name=deleteRequestingMembers,proto3" json:"deleteRequestingMembers,omitempty"` - PromoteRequestingMembers []*GroupChange_Actions_PromoteRequestingMemberAction `protobuf:"bytes,18,rep,name=promoteRequestingMembers,proto3" json:"promoteRequestingMembers,omitempty"` - ModifyInviteLinkPassword *GroupChange_Actions_ModifyInviteLinkPasswordAction `protobuf:"bytes,19,opt,name=modifyInviteLinkPassword,proto3" json:"modifyInviteLinkPassword,omitempty"` - ModifyDescription *GroupChange_Actions_ModifyDescriptionAction `protobuf:"bytes,20,opt,name=modifyDescription,proto3" json:"modifyDescription,omitempty"` - ModifyAnnouncementsOnly *GroupChange_Actions_ModifyAnnouncementsOnlyAction `protobuf:"bytes,21,opt,name=modifyAnnouncementsOnly,proto3" json:"modifyAnnouncementsOnly,omitempty"` - AddBannedMembers []*GroupChange_Actions_AddBannedMemberAction `protobuf:"bytes,22,rep,name=addBannedMembers,proto3" json:"addBannedMembers,omitempty"` - DeleteBannedMembers []*GroupChange_Actions_DeleteBannedMemberAction `protobuf:"bytes,23,rep,name=deleteBannedMembers,proto3" json:"deleteBannedMembers,omitempty"` - PromotePendingPniAciMembers []*GroupChange_Actions_PromotePendingPniAciMemberProfileKeyAction `protobuf:"bytes,24,rep,name=promotePendingPniAciMembers,proto3" json:"promotePendingPniAciMembers,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` + SourceUserId []byte `protobuf:"bytes,1,opt,name=sourceUserId,proto3" json:"sourceUserId,omitempty"` + // clients should not provide this value; the server will provide it in the response buffer to ensure the signature is binding to a particular group + // if clients set it during a request the server will respond with 400. + GroupId []byte `protobuf:"bytes,25,opt,name=group_id,json=groupId,proto3" json:"group_id,omitempty"` + Version uint32 `protobuf:"varint,2,opt,name=version,proto3" json:"version,omitempty"` + AddMembers []*GroupChange_Actions_AddMemberAction `protobuf:"bytes,3,rep,name=addMembers,proto3" json:"addMembers,omitempty"` + DeleteMembers []*GroupChange_Actions_DeleteMemberAction `protobuf:"bytes,4,rep,name=deleteMembers,proto3" json:"deleteMembers,omitempty"` + ModifyMemberRoles []*GroupChange_Actions_ModifyMemberRoleAction `protobuf:"bytes,5,rep,name=modifyMemberRoles,proto3" json:"modifyMemberRoles,omitempty"` + ModifyMemberProfileKeys []*GroupChange_Actions_ModifyMemberProfileKeyAction `protobuf:"bytes,6,rep,name=modifyMemberProfileKeys,proto3" json:"modifyMemberProfileKeys,omitempty"` + AddMembersPendingProfileKey []*GroupChange_Actions_AddMemberPendingProfileKeyAction `protobuf:"bytes,7,rep,name=addMembersPendingProfileKey,proto3" json:"addMembersPendingProfileKey,omitempty"` + DeleteMembersPendingProfileKey []*GroupChange_Actions_DeleteMemberPendingProfileKeyAction `protobuf:"bytes,8,rep,name=deleteMembersPendingProfileKey,proto3" json:"deleteMembersPendingProfileKey,omitempty"` + PromoteMembersPendingProfileKey []*GroupChange_Actions_PromoteMemberPendingProfileKeyAction `protobuf:"bytes,9,rep,name=promoteMembersPendingProfileKey,proto3" json:"promoteMembersPendingProfileKey,omitempty"` + ModifyTitle *GroupChange_Actions_ModifyTitleAction `protobuf:"bytes,10,opt,name=modifyTitle,proto3" json:"modifyTitle,omitempty"` + ModifyAvatar *GroupChange_Actions_ModifyAvatarAction `protobuf:"bytes,11,opt,name=modifyAvatar,proto3" json:"modifyAvatar,omitempty"` + ModifyDisappearingMessageTimer *GroupChange_Actions_ModifyDisappearingMessageTimerAction `protobuf:"bytes,12,opt,name=modifyDisappearingMessageTimer,proto3" json:"modifyDisappearingMessageTimer,omitempty"` + ModifyAttributesAccess *GroupChange_Actions_ModifyAttributesAccessControlAction `protobuf:"bytes,13,opt,name=modifyAttributesAccess,proto3" json:"modifyAttributesAccess,omitempty"` + ModifyMemberAccess *GroupChange_Actions_ModifyMembersAccessControlAction `protobuf:"bytes,14,opt,name=modifyMemberAccess,proto3" json:"modifyMemberAccess,omitempty"` + ModifyAddFromInviteLinkAccess *GroupChange_Actions_ModifyAddFromInviteLinkAccessControlAction `protobuf:"bytes,15,opt,name=modifyAddFromInviteLinkAccess,proto3" json:"modifyAddFromInviteLinkAccess,omitempty"` // change epoch = 1 + AddMembersPendingAdminApproval []*GroupChange_Actions_AddMemberPendingAdminApprovalAction `protobuf:"bytes,16,rep,name=addMembersPendingAdminApproval,proto3" json:"addMembersPendingAdminApproval,omitempty"` // change epoch = 1 + DeleteMembersPendingAdminApproval []*GroupChange_Actions_DeleteMemberPendingAdminApprovalAction `protobuf:"bytes,17,rep,name=deleteMembersPendingAdminApproval,proto3" json:"deleteMembersPendingAdminApproval,omitempty"` // change epoch = 1 + PromoteMembersPendingAdminApproval []*GroupChange_Actions_PromoteMemberPendingAdminApprovalAction `protobuf:"bytes,18,rep,name=promoteMembersPendingAdminApproval,proto3" json:"promoteMembersPendingAdminApproval,omitempty"` // change epoch = 1 + ModifyInviteLinkPassword *GroupChange_Actions_ModifyInviteLinkPasswordAction `protobuf:"bytes,19,opt,name=modifyInviteLinkPassword,proto3" json:"modifyInviteLinkPassword,omitempty"` // change epoch = 1 + ModifyDescription *GroupChange_Actions_ModifyDescriptionAction `protobuf:"bytes,20,opt,name=modifyDescription,proto3" json:"modifyDescription,omitempty"` // change epoch = 2 + ModifyAnnouncementsOnly *GroupChange_Actions_ModifyAnnouncementsOnlyAction `protobuf:"bytes,21,opt,name=modify_announcements_only,json=modifyAnnouncementsOnly,proto3" json:"modify_announcements_only,omitempty"` // change epoch = 3 + AddMembersBanned []*GroupChange_Actions_AddMemberBannedAction `protobuf:"bytes,22,rep,name=add_members_banned,json=addMembersBanned,proto3" json:"add_members_banned,omitempty"` // change epoch = 4 + DeleteMembersBanned []*GroupChange_Actions_DeleteMemberBannedAction `protobuf:"bytes,23,rep,name=delete_members_banned,json=deleteMembersBanned,proto3" json:"delete_members_banned,omitempty"` // change epoch = 4 + PromoteMembersPendingPniAciProfileKey []*GroupChange_Actions_PromoteMemberPendingPniAciProfileKeyAction `protobuf:"bytes,24,rep,name=promote_members_pending_pni_aci_profile_key,json=promoteMembersPendingPniAciProfileKey,proto3" json:"promote_members_pending_pni_aci_profile_key,omitempty"` // change epoch = 5 + ModifyMemberLabels []*GroupChange_Actions_ModifyMemberLabelAction `protobuf:"bytes,26,rep,name=modifyMemberLabels,proto3" json:"modifyMemberLabels,omitempty"` // change epoch = 6; + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } func (x *GroupChange_Actions) Reset() { *x = GroupChange_Actions{} - mi := &file_Groups_proto_msgTypes[15] + mi := &file_Groups_proto_msgTypes[16] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1263,7 +1335,7 @@ func (x *GroupChange_Actions) String() string { func (*GroupChange_Actions) ProtoMessage() {} func (x *GroupChange_Actions) ProtoReflect() protoreflect.Message { - mi := &file_Groups_proto_msgTypes[15] + mi := &file_Groups_proto_msgTypes[16] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1276,12 +1348,12 @@ func (x *GroupChange_Actions) ProtoReflect() protoreflect.Message { // Deprecated: Use GroupChange_Actions.ProtoReflect.Descriptor instead. func (*GroupChange_Actions) Descriptor() ([]byte, []int) { - return file_Groups_proto_rawDescGZIP(), []int{7, 0} + return file_Groups_proto_rawDescGZIP(), []int{10, 0} } -func (x *GroupChange_Actions) GetSourceServiceId() []byte { +func (x *GroupChange_Actions) GetSourceUserId() []byte { if x != nil { - return x.SourceServiceId + return x.SourceUserId } return nil } @@ -1293,9 +1365,9 @@ func (x *GroupChange_Actions) GetGroupId() []byte { return nil } -func (x *GroupChange_Actions) GetRevision() uint32 { +func (x *GroupChange_Actions) GetVersion() uint32 { if x != nil { - return x.Revision + return x.Version } return 0 } @@ -1328,23 +1400,23 @@ func (x *GroupChange_Actions) GetModifyMemberProfileKeys() []*GroupChange_Action return nil } -func (x *GroupChange_Actions) GetAddPendingMembers() []*GroupChange_Actions_AddPendingMemberAction { +func (x *GroupChange_Actions) GetAddMembersPendingProfileKey() []*GroupChange_Actions_AddMemberPendingProfileKeyAction { if x != nil { - return x.AddPendingMembers + return x.AddMembersPendingProfileKey } return nil } -func (x *GroupChange_Actions) GetDeletePendingMembers() []*GroupChange_Actions_DeletePendingMemberAction { +func (x *GroupChange_Actions) GetDeleteMembersPendingProfileKey() []*GroupChange_Actions_DeleteMemberPendingProfileKeyAction { if x != nil { - return x.DeletePendingMembers + return x.DeleteMembersPendingProfileKey } return nil } -func (x *GroupChange_Actions) GetPromotePendingMembers() []*GroupChange_Actions_PromotePendingMemberAction { +func (x *GroupChange_Actions) GetPromoteMembersPendingProfileKey() []*GroupChange_Actions_PromoteMemberPendingProfileKeyAction { if x != nil { - return x.PromotePendingMembers + return x.PromoteMembersPendingProfileKey } return nil } @@ -1363,9 +1435,9 @@ func (x *GroupChange_Actions) GetModifyAvatar() *GroupChange_Actions_ModifyAvata return nil } -func (x *GroupChange_Actions) GetModifyDisappearingMessagesTimer() *GroupChange_Actions_ModifyDisappearingMessagesTimerAction { +func (x *GroupChange_Actions) GetModifyDisappearingMessageTimer() *GroupChange_Actions_ModifyDisappearingMessageTimerAction { if x != nil { - return x.ModifyDisappearingMessagesTimer + return x.ModifyDisappearingMessageTimer } return nil } @@ -1391,23 +1463,23 @@ func (x *GroupChange_Actions) GetModifyAddFromInviteLinkAccess() *GroupChange_Ac return nil } -func (x *GroupChange_Actions) GetAddRequestingMembers() []*GroupChange_Actions_AddRequestingMemberAction { +func (x *GroupChange_Actions) GetAddMembersPendingAdminApproval() []*GroupChange_Actions_AddMemberPendingAdminApprovalAction { if x != nil { - return x.AddRequestingMembers + return x.AddMembersPendingAdminApproval } return nil } -func (x *GroupChange_Actions) GetDeleteRequestingMembers() []*GroupChange_Actions_DeleteRequestingMemberAction { +func (x *GroupChange_Actions) GetDeleteMembersPendingAdminApproval() []*GroupChange_Actions_DeleteMemberPendingAdminApprovalAction { if x != nil { - return x.DeleteRequestingMembers + return x.DeleteMembersPendingAdminApproval } return nil } -func (x *GroupChange_Actions) GetPromoteRequestingMembers() []*GroupChange_Actions_PromoteRequestingMemberAction { +func (x *GroupChange_Actions) GetPromoteMembersPendingAdminApproval() []*GroupChange_Actions_PromoteMemberPendingAdminApprovalAction { if x != nil { - return x.PromoteRequestingMembers + return x.PromoteMembersPendingAdminApproval } return nil } @@ -1433,23 +1505,30 @@ func (x *GroupChange_Actions) GetModifyAnnouncementsOnly() *GroupChange_Actions_ return nil } -func (x *GroupChange_Actions) GetAddBannedMembers() []*GroupChange_Actions_AddBannedMemberAction { +func (x *GroupChange_Actions) GetAddMembersBanned() []*GroupChange_Actions_AddMemberBannedAction { if x != nil { - return x.AddBannedMembers + return x.AddMembersBanned } return nil } -func (x *GroupChange_Actions) GetDeleteBannedMembers() []*GroupChange_Actions_DeleteBannedMemberAction { +func (x *GroupChange_Actions) GetDeleteMembersBanned() []*GroupChange_Actions_DeleteMemberBannedAction { if x != nil { - return x.DeleteBannedMembers + return x.DeleteMembersBanned } return nil } -func (x *GroupChange_Actions) GetPromotePendingPniAciMembers() []*GroupChange_Actions_PromotePendingPniAciMemberProfileKeyAction { +func (x *GroupChange_Actions) GetPromoteMembersPendingPniAciProfileKey() []*GroupChange_Actions_PromoteMemberPendingPniAciProfileKeyAction { if x != nil { - return x.PromotePendingPniAciMembers + return x.PromoteMembersPendingPniAciProfileKey + } + return nil +} + +func (x *GroupChange_Actions) GetModifyMemberLabels() []*GroupChange_Actions_ModifyMemberLabelAction { + if x != nil { + return x.ModifyMemberLabels } return nil } @@ -1464,7 +1543,7 @@ type GroupChange_Actions_AddMemberAction struct { func (x *GroupChange_Actions_AddMemberAction) Reset() { *x = GroupChange_Actions_AddMemberAction{} - mi := &file_Groups_proto_msgTypes[16] + mi := &file_Groups_proto_msgTypes[17] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1476,7 +1555,7 @@ func (x *GroupChange_Actions_AddMemberAction) String() string { func (*GroupChange_Actions_AddMemberAction) ProtoMessage() {} func (x *GroupChange_Actions_AddMemberAction) ProtoReflect() protoreflect.Message { - mi := &file_Groups_proto_msgTypes[16] + mi := &file_Groups_proto_msgTypes[17] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1489,7 +1568,7 @@ func (x *GroupChange_Actions_AddMemberAction) ProtoReflect() protoreflect.Messag // Deprecated: Use GroupChange_Actions_AddMemberAction.ProtoReflect.Descriptor instead. func (*GroupChange_Actions_AddMemberAction) Descriptor() ([]byte, []int) { - return file_Groups_proto_rawDescGZIP(), []int{7, 0, 0} + return file_Groups_proto_rawDescGZIP(), []int{10, 0, 0} } func (x *GroupChange_Actions_AddMemberAction) GetAdded() *Member { @@ -1515,7 +1594,7 @@ type GroupChange_Actions_DeleteMemberAction struct { func (x *GroupChange_Actions_DeleteMemberAction) Reset() { *x = GroupChange_Actions_DeleteMemberAction{} - mi := &file_Groups_proto_msgTypes[17] + mi := &file_Groups_proto_msgTypes[18] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1527,7 +1606,7 @@ func (x *GroupChange_Actions_DeleteMemberAction) String() string { func (*GroupChange_Actions_DeleteMemberAction) ProtoMessage() {} func (x *GroupChange_Actions_DeleteMemberAction) ProtoReflect() protoreflect.Message { - mi := &file_Groups_proto_msgTypes[17] + mi := &file_Groups_proto_msgTypes[18] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1540,7 +1619,7 @@ func (x *GroupChange_Actions_DeleteMemberAction) ProtoReflect() protoreflect.Mes // Deprecated: Use GroupChange_Actions_DeleteMemberAction.ProtoReflect.Descriptor instead. func (*GroupChange_Actions_DeleteMemberAction) Descriptor() ([]byte, []int) { - return file_Groups_proto_rawDescGZIP(), []int{7, 0, 1} + return file_Groups_proto_rawDescGZIP(), []int{10, 0, 1} } func (x *GroupChange_Actions_DeleteMemberAction) GetDeletedUserId() []byte { @@ -1553,14 +1632,14 @@ func (x *GroupChange_Actions_DeleteMemberAction) GetDeletedUserId() []byte { type GroupChange_Actions_ModifyMemberRoleAction struct { state protoimpl.MessageState `protogen:"open.v1"` UserId []byte `protobuf:"bytes,1,opt,name=userId,proto3" json:"userId,omitempty"` - Role Member_Role `protobuf:"varint,2,opt,name=role,proto3,enum=Member_Role" json:"role,omitempty"` + Role Member_Role `protobuf:"varint,2,opt,name=role,proto3,enum=signal.Member_Role" json:"role,omitempty"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } func (x *GroupChange_Actions_ModifyMemberRoleAction) Reset() { *x = GroupChange_Actions_ModifyMemberRoleAction{} - mi := &file_Groups_proto_msgTypes[18] + mi := &file_Groups_proto_msgTypes[19] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1572,7 +1651,7 @@ func (x *GroupChange_Actions_ModifyMemberRoleAction) String() string { func (*GroupChange_Actions_ModifyMemberRoleAction) ProtoMessage() {} func (x *GroupChange_Actions_ModifyMemberRoleAction) ProtoReflect() protoreflect.Message { - mi := &file_Groups_proto_msgTypes[18] + mi := &file_Groups_proto_msgTypes[19] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1585,7 +1664,7 @@ func (x *GroupChange_Actions_ModifyMemberRoleAction) ProtoReflect() protoreflect // Deprecated: Use GroupChange_Actions_ModifyMemberRoleAction.ProtoReflect.Descriptor instead. func (*GroupChange_Actions_ModifyMemberRoleAction) Descriptor() ([]byte, []int) { - return file_Groups_proto_rawDescGZIP(), []int{7, 0, 2} + return file_Groups_proto_rawDescGZIP(), []int{10, 0, 2} } func (x *GroupChange_Actions_ModifyMemberRoleAction) GetUserId() []byte { @@ -1602,18 +1681,78 @@ func (x *GroupChange_Actions_ModifyMemberRoleAction) GetRole() Member_Role { return Member_UNKNOWN } +type GroupChange_Actions_ModifyMemberLabelAction struct { + state protoimpl.MessageState `protogen:"open.v1"` + UserId []byte `protobuf:"bytes,1,opt,name=userId,proto3" json:"userId,omitempty"` + LabelEmoji []byte `protobuf:"bytes,2,opt,name=labelEmoji,proto3" json:"labelEmoji,omitempty"` // decrypts to a UTF-8 string + LabelString []byte `protobuf:"bytes,3,opt,name=labelString,proto3" json:"labelString,omitempty"` // decrypts to a UTF-8 string + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *GroupChange_Actions_ModifyMemberLabelAction) Reset() { + *x = GroupChange_Actions_ModifyMemberLabelAction{} + mi := &file_Groups_proto_msgTypes[20] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *GroupChange_Actions_ModifyMemberLabelAction) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GroupChange_Actions_ModifyMemberLabelAction) ProtoMessage() {} + +func (x *GroupChange_Actions_ModifyMemberLabelAction) ProtoReflect() protoreflect.Message { + mi := &file_Groups_proto_msgTypes[20] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GroupChange_Actions_ModifyMemberLabelAction.ProtoReflect.Descriptor instead. +func (*GroupChange_Actions_ModifyMemberLabelAction) Descriptor() ([]byte, []int) { + return file_Groups_proto_rawDescGZIP(), []int{10, 0, 3} +} + +func (x *GroupChange_Actions_ModifyMemberLabelAction) GetUserId() []byte { + if x != nil { + return x.UserId + } + return nil +} + +func (x *GroupChange_Actions_ModifyMemberLabelAction) GetLabelEmoji() []byte { + if x != nil { + return x.LabelEmoji + } + return nil +} + +func (x *GroupChange_Actions_ModifyMemberLabelAction) GetLabelString() []byte { + if x != nil { + return x.LabelString + } + return nil +} + type GroupChange_Actions_ModifyMemberProfileKeyAction struct { state protoimpl.MessageState `protogen:"open.v1"` - Presentation []byte `protobuf:"bytes,1,opt,name=presentation,proto3" json:"presentation,omitempty"` // Only set when sending to server - UserId []byte `protobuf:"bytes,2,opt,name=user_id,json=userId,proto3" json:"user_id,omitempty"` // Only set when receiving from server - ProfileKey []byte `protobuf:"bytes,3,opt,name=profile_key,json=profileKey,proto3" json:"profile_key,omitempty"` // Only set when receiving from server + Presentation []byte `protobuf:"bytes,1,opt,name=presentation,proto3" json:"presentation,omitempty"` + UserId []byte `protobuf:"bytes,2,opt,name=user_id,json=userId,proto3" json:"user_id,omitempty"` + ProfileKey []byte `protobuf:"bytes,3,opt,name=profile_key,json=profileKey,proto3" json:"profile_key,omitempty"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } func (x *GroupChange_Actions_ModifyMemberProfileKeyAction) Reset() { *x = GroupChange_Actions_ModifyMemberProfileKeyAction{} - mi := &file_Groups_proto_msgTypes[19] + mi := &file_Groups_proto_msgTypes[21] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1625,7 +1764,7 @@ func (x *GroupChange_Actions_ModifyMemberProfileKeyAction) String() string { func (*GroupChange_Actions_ModifyMemberProfileKeyAction) ProtoMessage() {} func (x *GroupChange_Actions_ModifyMemberProfileKeyAction) ProtoReflect() protoreflect.Message { - mi := &file_Groups_proto_msgTypes[19] + mi := &file_Groups_proto_msgTypes[21] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1638,7 +1777,7 @@ func (x *GroupChange_Actions_ModifyMemberProfileKeyAction) ProtoReflect() protor // Deprecated: Use GroupChange_Actions_ModifyMemberProfileKeyAction.ProtoReflect.Descriptor instead. func (*GroupChange_Actions_ModifyMemberProfileKeyAction) Descriptor() ([]byte, []int) { - return file_Groups_proto_rawDescGZIP(), []int{7, 0, 3} + return file_Groups_proto_rawDescGZIP(), []int{10, 0, 4} } func (x *GroupChange_Actions_ModifyMemberProfileKeyAction) GetPresentation() []byte { @@ -1662,28 +1801,28 @@ func (x *GroupChange_Actions_ModifyMemberProfileKeyAction) GetProfileKey() []byt return nil } -type GroupChange_Actions_AddPendingMemberAction struct { - state protoimpl.MessageState `protogen:"open.v1"` - Added *PendingMember `protobuf:"bytes,1,opt,name=added,proto3" json:"added,omitempty"` +type GroupChange_Actions_AddMemberPendingProfileKeyAction struct { + state protoimpl.MessageState `protogen:"open.v1"` + Added *MemberPendingProfileKey `protobuf:"bytes,1,opt,name=added,proto3" json:"added,omitempty"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } -func (x *GroupChange_Actions_AddPendingMemberAction) Reset() { - *x = GroupChange_Actions_AddPendingMemberAction{} - mi := &file_Groups_proto_msgTypes[20] +func (x *GroupChange_Actions_AddMemberPendingProfileKeyAction) Reset() { + *x = GroupChange_Actions_AddMemberPendingProfileKeyAction{} + mi := &file_Groups_proto_msgTypes[22] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } -func (x *GroupChange_Actions_AddPendingMemberAction) String() string { +func (x *GroupChange_Actions_AddMemberPendingProfileKeyAction) String() string { return protoimpl.X.MessageStringOf(x) } -func (*GroupChange_Actions_AddPendingMemberAction) ProtoMessage() {} +func (*GroupChange_Actions_AddMemberPendingProfileKeyAction) ProtoMessage() {} -func (x *GroupChange_Actions_AddPendingMemberAction) ProtoReflect() protoreflect.Message { - mi := &file_Groups_proto_msgTypes[20] +func (x *GroupChange_Actions_AddMemberPendingProfileKeyAction) ProtoReflect() protoreflect.Message { + mi := &file_Groups_proto_msgTypes[22] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1694,40 +1833,40 @@ func (x *GroupChange_Actions_AddPendingMemberAction) ProtoReflect() protoreflect return mi.MessageOf(x) } -// Deprecated: Use GroupChange_Actions_AddPendingMemberAction.ProtoReflect.Descriptor instead. -func (*GroupChange_Actions_AddPendingMemberAction) Descriptor() ([]byte, []int) { - return file_Groups_proto_rawDescGZIP(), []int{7, 0, 4} +// Deprecated: Use GroupChange_Actions_AddMemberPendingProfileKeyAction.ProtoReflect.Descriptor instead. +func (*GroupChange_Actions_AddMemberPendingProfileKeyAction) Descriptor() ([]byte, []int) { + return file_Groups_proto_rawDescGZIP(), []int{10, 0, 5} } -func (x *GroupChange_Actions_AddPendingMemberAction) GetAdded() *PendingMember { +func (x *GroupChange_Actions_AddMemberPendingProfileKeyAction) GetAdded() *MemberPendingProfileKey { if x != nil { return x.Added } return nil } -type GroupChange_Actions_DeletePendingMemberAction struct { +type GroupChange_Actions_DeleteMemberPendingProfileKeyAction struct { state protoimpl.MessageState `protogen:"open.v1"` DeletedUserId []byte `protobuf:"bytes,1,opt,name=deletedUserId,proto3" json:"deletedUserId,omitempty"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } -func (x *GroupChange_Actions_DeletePendingMemberAction) Reset() { - *x = GroupChange_Actions_DeletePendingMemberAction{} - mi := &file_Groups_proto_msgTypes[21] +func (x *GroupChange_Actions_DeleteMemberPendingProfileKeyAction) Reset() { + *x = GroupChange_Actions_DeleteMemberPendingProfileKeyAction{} + mi := &file_Groups_proto_msgTypes[23] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } -func (x *GroupChange_Actions_DeletePendingMemberAction) String() string { +func (x *GroupChange_Actions_DeleteMemberPendingProfileKeyAction) String() string { return protoimpl.X.MessageStringOf(x) } -func (*GroupChange_Actions_DeletePendingMemberAction) ProtoMessage() {} +func (*GroupChange_Actions_DeleteMemberPendingProfileKeyAction) ProtoMessage() {} -func (x *GroupChange_Actions_DeletePendingMemberAction) ProtoReflect() protoreflect.Message { - mi := &file_Groups_proto_msgTypes[21] +func (x *GroupChange_Actions_DeleteMemberPendingProfileKeyAction) ProtoReflect() protoreflect.Message { + mi := &file_Groups_proto_msgTypes[23] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1738,42 +1877,42 @@ func (x *GroupChange_Actions_DeletePendingMemberAction) ProtoReflect() protorefl return mi.MessageOf(x) } -// Deprecated: Use GroupChange_Actions_DeletePendingMemberAction.ProtoReflect.Descriptor instead. -func (*GroupChange_Actions_DeletePendingMemberAction) Descriptor() ([]byte, []int) { - return file_Groups_proto_rawDescGZIP(), []int{7, 0, 5} +// Deprecated: Use GroupChange_Actions_DeleteMemberPendingProfileKeyAction.ProtoReflect.Descriptor instead. +func (*GroupChange_Actions_DeleteMemberPendingProfileKeyAction) Descriptor() ([]byte, []int) { + return file_Groups_proto_rawDescGZIP(), []int{10, 0, 6} } -func (x *GroupChange_Actions_DeletePendingMemberAction) GetDeletedUserId() []byte { +func (x *GroupChange_Actions_DeleteMemberPendingProfileKeyAction) GetDeletedUserId() []byte { if x != nil { return x.DeletedUserId } return nil } -type GroupChange_Actions_PromotePendingMemberAction struct { +type GroupChange_Actions_PromoteMemberPendingProfileKeyAction struct { state protoimpl.MessageState `protogen:"open.v1"` - Presentation []byte `protobuf:"bytes,1,opt,name=presentation,proto3" json:"presentation,omitempty"` // Only set when sending to server - UserId []byte `protobuf:"bytes,2,opt,name=user_id,json=userId,proto3" json:"user_id,omitempty"` // Only set when receiving from server - ProfileKey []byte `protobuf:"bytes,3,opt,name=profile_key,json=profileKey,proto3" json:"profile_key,omitempty"` // Only set when receiving from server + Presentation []byte `protobuf:"bytes,1,opt,name=presentation,proto3" json:"presentation,omitempty"` + UserId []byte `protobuf:"bytes,2,opt,name=user_id,json=userId,proto3" json:"user_id,omitempty"` + ProfileKey []byte `protobuf:"bytes,3,opt,name=profile_key,json=profileKey,proto3" json:"profile_key,omitempty"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } -func (x *GroupChange_Actions_PromotePendingMemberAction) Reset() { - *x = GroupChange_Actions_PromotePendingMemberAction{} - mi := &file_Groups_proto_msgTypes[22] +func (x *GroupChange_Actions_PromoteMemberPendingProfileKeyAction) Reset() { + *x = GroupChange_Actions_PromoteMemberPendingProfileKeyAction{} + mi := &file_Groups_proto_msgTypes[24] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } -func (x *GroupChange_Actions_PromotePendingMemberAction) String() string { +func (x *GroupChange_Actions_PromoteMemberPendingProfileKeyAction) String() string { return protoimpl.X.MessageStringOf(x) } -func (*GroupChange_Actions_PromotePendingMemberAction) ProtoMessage() {} +func (*GroupChange_Actions_PromoteMemberPendingProfileKeyAction) ProtoMessage() {} -func (x *GroupChange_Actions_PromotePendingMemberAction) ProtoReflect() protoreflect.Message { - mi := &file_Groups_proto_msgTypes[22] +func (x *GroupChange_Actions_PromoteMemberPendingProfileKeyAction) ProtoReflect() protoreflect.Message { + mi := &file_Groups_proto_msgTypes[24] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1784,57 +1923,57 @@ func (x *GroupChange_Actions_PromotePendingMemberAction) ProtoReflect() protoref return mi.MessageOf(x) } -// Deprecated: Use GroupChange_Actions_PromotePendingMemberAction.ProtoReflect.Descriptor instead. -func (*GroupChange_Actions_PromotePendingMemberAction) Descriptor() ([]byte, []int) { - return file_Groups_proto_rawDescGZIP(), []int{7, 0, 6} +// Deprecated: Use GroupChange_Actions_PromoteMemberPendingProfileKeyAction.ProtoReflect.Descriptor instead. +func (*GroupChange_Actions_PromoteMemberPendingProfileKeyAction) Descriptor() ([]byte, []int) { + return file_Groups_proto_rawDescGZIP(), []int{10, 0, 7} } -func (x *GroupChange_Actions_PromotePendingMemberAction) GetPresentation() []byte { +func (x *GroupChange_Actions_PromoteMemberPendingProfileKeyAction) GetPresentation() []byte { if x != nil { return x.Presentation } return nil } -func (x *GroupChange_Actions_PromotePendingMemberAction) GetUserId() []byte { +func (x *GroupChange_Actions_PromoteMemberPendingProfileKeyAction) GetUserId() []byte { if x != nil { return x.UserId } return nil } -func (x *GroupChange_Actions_PromotePendingMemberAction) GetProfileKey() []byte { +func (x *GroupChange_Actions_PromoteMemberPendingProfileKeyAction) GetProfileKey() []byte { if x != nil { return x.ProfileKey } return nil } -type GroupChange_Actions_PromotePendingPniAciMemberProfileKeyAction struct { +type GroupChange_Actions_PromoteMemberPendingPniAciProfileKeyAction struct { state protoimpl.MessageState `protogen:"open.v1"` - Presentation []byte `protobuf:"bytes,1,opt,name=presentation,proto3" json:"presentation,omitempty"` // Only set when sending to server - UserId []byte `protobuf:"bytes,2,opt,name=userId,proto3" json:"userId,omitempty"` // Only set when receiving from server - Pni []byte `protobuf:"bytes,3,opt,name=pni,proto3" json:"pni,omitempty"` // Only set when receiving from server - ProfileKey []byte `protobuf:"bytes,4,opt,name=profileKey,proto3" json:"profileKey,omitempty"` // Only set when receiving from server + Presentation []byte `protobuf:"bytes,1,opt,name=presentation,proto3" json:"presentation,omitempty"` + UserId []byte `protobuf:"bytes,2,opt,name=user_id,json=userId,proto3" json:"user_id,omitempty"` + Pni []byte `protobuf:"bytes,3,opt,name=pni,proto3" json:"pni,omitempty"` + ProfileKey []byte `protobuf:"bytes,4,opt,name=profile_key,json=profileKey,proto3" json:"profile_key,omitempty"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } -func (x *GroupChange_Actions_PromotePendingPniAciMemberProfileKeyAction) Reset() { - *x = GroupChange_Actions_PromotePendingPniAciMemberProfileKeyAction{} - mi := &file_Groups_proto_msgTypes[23] +func (x *GroupChange_Actions_PromoteMemberPendingPniAciProfileKeyAction) Reset() { + *x = GroupChange_Actions_PromoteMemberPendingPniAciProfileKeyAction{} + mi := &file_Groups_proto_msgTypes[25] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } -func (x *GroupChange_Actions_PromotePendingPniAciMemberProfileKeyAction) String() string { +func (x *GroupChange_Actions_PromoteMemberPendingPniAciProfileKeyAction) String() string { return protoimpl.X.MessageStringOf(x) } -func (*GroupChange_Actions_PromotePendingPniAciMemberProfileKeyAction) ProtoMessage() {} +func (*GroupChange_Actions_PromoteMemberPendingPniAciProfileKeyAction) ProtoMessage() {} -func (x *GroupChange_Actions_PromotePendingPniAciMemberProfileKeyAction) ProtoReflect() protoreflect.Message { - mi := &file_Groups_proto_msgTypes[23] +func (x *GroupChange_Actions_PromoteMemberPendingPniAciProfileKeyAction) ProtoReflect() protoreflect.Message { + mi := &file_Groups_proto_msgTypes[25] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1845,61 +1984,61 @@ func (x *GroupChange_Actions_PromotePendingPniAciMemberProfileKeyAction) ProtoRe return mi.MessageOf(x) } -// Deprecated: Use GroupChange_Actions_PromotePendingPniAciMemberProfileKeyAction.ProtoReflect.Descriptor instead. -func (*GroupChange_Actions_PromotePendingPniAciMemberProfileKeyAction) Descriptor() ([]byte, []int) { - return file_Groups_proto_rawDescGZIP(), []int{7, 0, 7} +// Deprecated: Use GroupChange_Actions_PromoteMemberPendingPniAciProfileKeyAction.ProtoReflect.Descriptor instead. +func (*GroupChange_Actions_PromoteMemberPendingPniAciProfileKeyAction) Descriptor() ([]byte, []int) { + return file_Groups_proto_rawDescGZIP(), []int{10, 0, 8} } -func (x *GroupChange_Actions_PromotePendingPniAciMemberProfileKeyAction) GetPresentation() []byte { +func (x *GroupChange_Actions_PromoteMemberPendingPniAciProfileKeyAction) GetPresentation() []byte { if x != nil { return x.Presentation } return nil } -func (x *GroupChange_Actions_PromotePendingPniAciMemberProfileKeyAction) GetUserId() []byte { +func (x *GroupChange_Actions_PromoteMemberPendingPniAciProfileKeyAction) GetUserId() []byte { if x != nil { return x.UserId } return nil } -func (x *GroupChange_Actions_PromotePendingPniAciMemberProfileKeyAction) GetPni() []byte { +func (x *GroupChange_Actions_PromoteMemberPendingPniAciProfileKeyAction) GetPni() []byte { if x != nil { return x.Pni } return nil } -func (x *GroupChange_Actions_PromotePendingPniAciMemberProfileKeyAction) GetProfileKey() []byte { +func (x *GroupChange_Actions_PromoteMemberPendingPniAciProfileKeyAction) GetProfileKey() []byte { if x != nil { return x.ProfileKey } return nil } -type GroupChange_Actions_AddRequestingMemberAction struct { - state protoimpl.MessageState `protogen:"open.v1"` - Added *RequestingMember `protobuf:"bytes,1,opt,name=added,proto3" json:"added,omitempty"` +type GroupChange_Actions_AddMemberPendingAdminApprovalAction struct { + state protoimpl.MessageState `protogen:"open.v1"` + Added *MemberPendingAdminApproval `protobuf:"bytes,1,opt,name=added,proto3" json:"added,omitempty"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } -func (x *GroupChange_Actions_AddRequestingMemberAction) Reset() { - *x = GroupChange_Actions_AddRequestingMemberAction{} - mi := &file_Groups_proto_msgTypes[24] +func (x *GroupChange_Actions_AddMemberPendingAdminApprovalAction) Reset() { + *x = GroupChange_Actions_AddMemberPendingAdminApprovalAction{} + mi := &file_Groups_proto_msgTypes[26] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } -func (x *GroupChange_Actions_AddRequestingMemberAction) String() string { +func (x *GroupChange_Actions_AddMemberPendingAdminApprovalAction) String() string { return protoimpl.X.MessageStringOf(x) } -func (*GroupChange_Actions_AddRequestingMemberAction) ProtoMessage() {} +func (*GroupChange_Actions_AddMemberPendingAdminApprovalAction) ProtoMessage() {} -func (x *GroupChange_Actions_AddRequestingMemberAction) ProtoReflect() protoreflect.Message { - mi := &file_Groups_proto_msgTypes[24] +func (x *GroupChange_Actions_AddMemberPendingAdminApprovalAction) ProtoReflect() protoreflect.Message { + mi := &file_Groups_proto_msgTypes[26] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1910,40 +2049,40 @@ func (x *GroupChange_Actions_AddRequestingMemberAction) ProtoReflect() protorefl return mi.MessageOf(x) } -// Deprecated: Use GroupChange_Actions_AddRequestingMemberAction.ProtoReflect.Descriptor instead. -func (*GroupChange_Actions_AddRequestingMemberAction) Descriptor() ([]byte, []int) { - return file_Groups_proto_rawDescGZIP(), []int{7, 0, 8} +// Deprecated: Use GroupChange_Actions_AddMemberPendingAdminApprovalAction.ProtoReflect.Descriptor instead. +func (*GroupChange_Actions_AddMemberPendingAdminApprovalAction) Descriptor() ([]byte, []int) { + return file_Groups_proto_rawDescGZIP(), []int{10, 0, 9} } -func (x *GroupChange_Actions_AddRequestingMemberAction) GetAdded() *RequestingMember { +func (x *GroupChange_Actions_AddMemberPendingAdminApprovalAction) GetAdded() *MemberPendingAdminApproval { if x != nil { return x.Added } return nil } -type GroupChange_Actions_DeleteRequestingMemberAction struct { +type GroupChange_Actions_DeleteMemberPendingAdminApprovalAction struct { state protoimpl.MessageState `protogen:"open.v1"` DeletedUserId []byte `protobuf:"bytes,1,opt,name=deletedUserId,proto3" json:"deletedUserId,omitempty"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } -func (x *GroupChange_Actions_DeleteRequestingMemberAction) Reset() { - *x = GroupChange_Actions_DeleteRequestingMemberAction{} - mi := &file_Groups_proto_msgTypes[25] +func (x *GroupChange_Actions_DeleteMemberPendingAdminApprovalAction) Reset() { + *x = GroupChange_Actions_DeleteMemberPendingAdminApprovalAction{} + mi := &file_Groups_proto_msgTypes[27] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } -func (x *GroupChange_Actions_DeleteRequestingMemberAction) String() string { +func (x *GroupChange_Actions_DeleteMemberPendingAdminApprovalAction) String() string { return protoimpl.X.MessageStringOf(x) } -func (*GroupChange_Actions_DeleteRequestingMemberAction) ProtoMessage() {} +func (*GroupChange_Actions_DeleteMemberPendingAdminApprovalAction) ProtoMessage() {} -func (x *GroupChange_Actions_DeleteRequestingMemberAction) ProtoReflect() protoreflect.Message { - mi := &file_Groups_proto_msgTypes[25] +func (x *GroupChange_Actions_DeleteMemberPendingAdminApprovalAction) ProtoReflect() protoreflect.Message { + mi := &file_Groups_proto_msgTypes[27] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1954,41 +2093,41 @@ func (x *GroupChange_Actions_DeleteRequestingMemberAction) ProtoReflect() protor return mi.MessageOf(x) } -// Deprecated: Use GroupChange_Actions_DeleteRequestingMemberAction.ProtoReflect.Descriptor instead. -func (*GroupChange_Actions_DeleteRequestingMemberAction) Descriptor() ([]byte, []int) { - return file_Groups_proto_rawDescGZIP(), []int{7, 0, 9} +// Deprecated: Use GroupChange_Actions_DeleteMemberPendingAdminApprovalAction.ProtoReflect.Descriptor instead. +func (*GroupChange_Actions_DeleteMemberPendingAdminApprovalAction) Descriptor() ([]byte, []int) { + return file_Groups_proto_rawDescGZIP(), []int{10, 0, 10} } -func (x *GroupChange_Actions_DeleteRequestingMemberAction) GetDeletedUserId() []byte { +func (x *GroupChange_Actions_DeleteMemberPendingAdminApprovalAction) GetDeletedUserId() []byte { if x != nil { return x.DeletedUserId } return nil } -type GroupChange_Actions_PromoteRequestingMemberAction struct { +type GroupChange_Actions_PromoteMemberPendingAdminApprovalAction struct { state protoimpl.MessageState `protogen:"open.v1"` UserId []byte `protobuf:"bytes,1,opt,name=userId,proto3" json:"userId,omitempty"` - Role Member_Role `protobuf:"varint,2,opt,name=role,proto3,enum=Member_Role" json:"role,omitempty"` + Role Member_Role `protobuf:"varint,2,opt,name=role,proto3,enum=signal.Member_Role" json:"role,omitempty"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } -func (x *GroupChange_Actions_PromoteRequestingMemberAction) Reset() { - *x = GroupChange_Actions_PromoteRequestingMemberAction{} - mi := &file_Groups_proto_msgTypes[26] +func (x *GroupChange_Actions_PromoteMemberPendingAdminApprovalAction) Reset() { + *x = GroupChange_Actions_PromoteMemberPendingAdminApprovalAction{} + mi := &file_Groups_proto_msgTypes[28] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } -func (x *GroupChange_Actions_PromoteRequestingMemberAction) String() string { +func (x *GroupChange_Actions_PromoteMemberPendingAdminApprovalAction) String() string { return protoimpl.X.MessageStringOf(x) } -func (*GroupChange_Actions_PromoteRequestingMemberAction) ProtoMessage() {} +func (*GroupChange_Actions_PromoteMemberPendingAdminApprovalAction) ProtoMessage() {} -func (x *GroupChange_Actions_PromoteRequestingMemberAction) ProtoReflect() protoreflect.Message { - mi := &file_Groups_proto_msgTypes[26] +func (x *GroupChange_Actions_PromoteMemberPendingAdminApprovalAction) ProtoReflect() protoreflect.Message { + mi := &file_Groups_proto_msgTypes[28] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1999,47 +2138,47 @@ func (x *GroupChange_Actions_PromoteRequestingMemberAction) ProtoReflect() proto return mi.MessageOf(x) } -// Deprecated: Use GroupChange_Actions_PromoteRequestingMemberAction.ProtoReflect.Descriptor instead. -func (*GroupChange_Actions_PromoteRequestingMemberAction) Descriptor() ([]byte, []int) { - return file_Groups_proto_rawDescGZIP(), []int{7, 0, 10} +// Deprecated: Use GroupChange_Actions_PromoteMemberPendingAdminApprovalAction.ProtoReflect.Descriptor instead. +func (*GroupChange_Actions_PromoteMemberPendingAdminApprovalAction) Descriptor() ([]byte, []int) { + return file_Groups_proto_rawDescGZIP(), []int{10, 0, 11} } -func (x *GroupChange_Actions_PromoteRequestingMemberAction) GetUserId() []byte { +func (x *GroupChange_Actions_PromoteMemberPendingAdminApprovalAction) GetUserId() []byte { if x != nil { return x.UserId } return nil } -func (x *GroupChange_Actions_PromoteRequestingMemberAction) GetRole() Member_Role { +func (x *GroupChange_Actions_PromoteMemberPendingAdminApprovalAction) GetRole() Member_Role { if x != nil { return x.Role } return Member_UNKNOWN } -type GroupChange_Actions_AddBannedMemberAction struct { +type GroupChange_Actions_AddMemberBannedAction struct { state protoimpl.MessageState `protogen:"open.v1"` - Added *BannedMember `protobuf:"bytes,1,opt,name=added,proto3" json:"added,omitempty"` + Added *MemberBanned `protobuf:"bytes,1,opt,name=added,proto3" json:"added,omitempty"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } -func (x *GroupChange_Actions_AddBannedMemberAction) Reset() { - *x = GroupChange_Actions_AddBannedMemberAction{} - mi := &file_Groups_proto_msgTypes[27] +func (x *GroupChange_Actions_AddMemberBannedAction) Reset() { + *x = GroupChange_Actions_AddMemberBannedAction{} + mi := &file_Groups_proto_msgTypes[29] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } -func (x *GroupChange_Actions_AddBannedMemberAction) String() string { +func (x *GroupChange_Actions_AddMemberBannedAction) String() string { return protoimpl.X.MessageStringOf(x) } -func (*GroupChange_Actions_AddBannedMemberAction) ProtoMessage() {} +func (*GroupChange_Actions_AddMemberBannedAction) ProtoMessage() {} -func (x *GroupChange_Actions_AddBannedMemberAction) ProtoReflect() protoreflect.Message { - mi := &file_Groups_proto_msgTypes[27] +func (x *GroupChange_Actions_AddMemberBannedAction) ProtoReflect() protoreflect.Message { + mi := &file_Groups_proto_msgTypes[29] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2050,40 +2189,40 @@ func (x *GroupChange_Actions_AddBannedMemberAction) ProtoReflect() protoreflect. return mi.MessageOf(x) } -// Deprecated: Use GroupChange_Actions_AddBannedMemberAction.ProtoReflect.Descriptor instead. -func (*GroupChange_Actions_AddBannedMemberAction) Descriptor() ([]byte, []int) { - return file_Groups_proto_rawDescGZIP(), []int{7, 0, 11} +// Deprecated: Use GroupChange_Actions_AddMemberBannedAction.ProtoReflect.Descriptor instead. +func (*GroupChange_Actions_AddMemberBannedAction) Descriptor() ([]byte, []int) { + return file_Groups_proto_rawDescGZIP(), []int{10, 0, 12} } -func (x *GroupChange_Actions_AddBannedMemberAction) GetAdded() *BannedMember { +func (x *GroupChange_Actions_AddMemberBannedAction) GetAdded() *MemberBanned { if x != nil { return x.Added } return nil } -type GroupChange_Actions_DeleteBannedMemberAction struct { +type GroupChange_Actions_DeleteMemberBannedAction struct { state protoimpl.MessageState `protogen:"open.v1"` DeletedUserId []byte `protobuf:"bytes,1,opt,name=deletedUserId,proto3" json:"deletedUserId,omitempty"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } -func (x *GroupChange_Actions_DeleteBannedMemberAction) Reset() { - *x = GroupChange_Actions_DeleteBannedMemberAction{} - mi := &file_Groups_proto_msgTypes[28] +func (x *GroupChange_Actions_DeleteMemberBannedAction) Reset() { + *x = GroupChange_Actions_DeleteMemberBannedAction{} + mi := &file_Groups_proto_msgTypes[30] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } -func (x *GroupChange_Actions_DeleteBannedMemberAction) String() string { +func (x *GroupChange_Actions_DeleteMemberBannedAction) String() string { return protoimpl.X.MessageStringOf(x) } -func (*GroupChange_Actions_DeleteBannedMemberAction) ProtoMessage() {} +func (*GroupChange_Actions_DeleteMemberBannedAction) ProtoMessage() {} -func (x *GroupChange_Actions_DeleteBannedMemberAction) ProtoReflect() protoreflect.Message { - mi := &file_Groups_proto_msgTypes[28] +func (x *GroupChange_Actions_DeleteMemberBannedAction) ProtoReflect() protoreflect.Message { + mi := &file_Groups_proto_msgTypes[30] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2094,12 +2233,12 @@ func (x *GroupChange_Actions_DeleteBannedMemberAction) ProtoReflect() protorefle return mi.MessageOf(x) } -// Deprecated: Use GroupChange_Actions_DeleteBannedMemberAction.ProtoReflect.Descriptor instead. -func (*GroupChange_Actions_DeleteBannedMemberAction) Descriptor() ([]byte, []int) { - return file_Groups_proto_rawDescGZIP(), []int{7, 0, 12} +// Deprecated: Use GroupChange_Actions_DeleteMemberBannedAction.ProtoReflect.Descriptor instead. +func (*GroupChange_Actions_DeleteMemberBannedAction) Descriptor() ([]byte, []int) { + return file_Groups_proto_rawDescGZIP(), []int{10, 0, 13} } -func (x *GroupChange_Actions_DeleteBannedMemberAction) GetDeletedUserId() []byte { +func (x *GroupChange_Actions_DeleteMemberBannedAction) GetDeletedUserId() []byte { if x != nil { return x.DeletedUserId } @@ -2115,7 +2254,7 @@ type GroupChange_Actions_ModifyTitleAction struct { func (x *GroupChange_Actions_ModifyTitleAction) Reset() { *x = GroupChange_Actions_ModifyTitleAction{} - mi := &file_Groups_proto_msgTypes[29] + mi := &file_Groups_proto_msgTypes[31] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2127,7 +2266,7 @@ func (x *GroupChange_Actions_ModifyTitleAction) String() string { func (*GroupChange_Actions_ModifyTitleAction) ProtoMessage() {} func (x *GroupChange_Actions_ModifyTitleAction) ProtoReflect() protoreflect.Message { - mi := &file_Groups_proto_msgTypes[29] + mi := &file_Groups_proto_msgTypes[31] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2140,7 +2279,7 @@ func (x *GroupChange_Actions_ModifyTitleAction) ProtoReflect() protoreflect.Mess // Deprecated: Use GroupChange_Actions_ModifyTitleAction.ProtoReflect.Descriptor instead. func (*GroupChange_Actions_ModifyTitleAction) Descriptor() ([]byte, []int) { - return file_Groups_proto_rawDescGZIP(), []int{7, 0, 13} + return file_Groups_proto_rawDescGZIP(), []int{10, 0, 14} } func (x *GroupChange_Actions_ModifyTitleAction) GetTitle() []byte { @@ -2159,7 +2298,7 @@ type GroupChange_Actions_ModifyDescriptionAction struct { func (x *GroupChange_Actions_ModifyDescriptionAction) Reset() { *x = GroupChange_Actions_ModifyDescriptionAction{} - mi := &file_Groups_proto_msgTypes[30] + mi := &file_Groups_proto_msgTypes[32] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2171,7 +2310,7 @@ func (x *GroupChange_Actions_ModifyDescriptionAction) String() string { func (*GroupChange_Actions_ModifyDescriptionAction) ProtoMessage() {} func (x *GroupChange_Actions_ModifyDescriptionAction) ProtoReflect() protoreflect.Message { - mi := &file_Groups_proto_msgTypes[30] + mi := &file_Groups_proto_msgTypes[32] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2184,7 +2323,7 @@ func (x *GroupChange_Actions_ModifyDescriptionAction) ProtoReflect() protoreflec // Deprecated: Use GroupChange_Actions_ModifyDescriptionAction.ProtoReflect.Descriptor instead. func (*GroupChange_Actions_ModifyDescriptionAction) Descriptor() ([]byte, []int) { - return file_Groups_proto_rawDescGZIP(), []int{7, 0, 14} + return file_Groups_proto_rawDescGZIP(), []int{10, 0, 15} } func (x *GroupChange_Actions_ModifyDescriptionAction) GetDescription() []byte { @@ -2203,7 +2342,7 @@ type GroupChange_Actions_ModifyAvatarAction struct { func (x *GroupChange_Actions_ModifyAvatarAction) Reset() { *x = GroupChange_Actions_ModifyAvatarAction{} - mi := &file_Groups_proto_msgTypes[31] + mi := &file_Groups_proto_msgTypes[33] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2215,7 +2354,7 @@ func (x *GroupChange_Actions_ModifyAvatarAction) String() string { func (*GroupChange_Actions_ModifyAvatarAction) ProtoMessage() {} func (x *GroupChange_Actions_ModifyAvatarAction) ProtoReflect() protoreflect.Message { - mi := &file_Groups_proto_msgTypes[31] + mi := &file_Groups_proto_msgTypes[33] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2228,7 +2367,7 @@ func (x *GroupChange_Actions_ModifyAvatarAction) ProtoReflect() protoreflect.Mes // Deprecated: Use GroupChange_Actions_ModifyAvatarAction.ProtoReflect.Descriptor instead. func (*GroupChange_Actions_ModifyAvatarAction) Descriptor() ([]byte, []int) { - return file_Groups_proto_rawDescGZIP(), []int{7, 0, 15} + return file_Groups_proto_rawDescGZIP(), []int{10, 0, 16} } func (x *GroupChange_Actions_ModifyAvatarAction) GetAvatar() string { @@ -2238,28 +2377,28 @@ func (x *GroupChange_Actions_ModifyAvatarAction) GetAvatar() string { return "" } -type GroupChange_Actions_ModifyDisappearingMessagesTimerAction struct { +type GroupChange_Actions_ModifyDisappearingMessageTimerAction struct { state protoimpl.MessageState `protogen:"open.v1"` Timer []byte `protobuf:"bytes,1,opt,name=timer,proto3" json:"timer,omitempty"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } -func (x *GroupChange_Actions_ModifyDisappearingMessagesTimerAction) Reset() { - *x = GroupChange_Actions_ModifyDisappearingMessagesTimerAction{} - mi := &file_Groups_proto_msgTypes[32] +func (x *GroupChange_Actions_ModifyDisappearingMessageTimerAction) Reset() { + *x = GroupChange_Actions_ModifyDisappearingMessageTimerAction{} + mi := &file_Groups_proto_msgTypes[34] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } -func (x *GroupChange_Actions_ModifyDisappearingMessagesTimerAction) String() string { +func (x *GroupChange_Actions_ModifyDisappearingMessageTimerAction) String() string { return protoimpl.X.MessageStringOf(x) } -func (*GroupChange_Actions_ModifyDisappearingMessagesTimerAction) ProtoMessage() {} +func (*GroupChange_Actions_ModifyDisappearingMessageTimerAction) ProtoMessage() {} -func (x *GroupChange_Actions_ModifyDisappearingMessagesTimerAction) ProtoReflect() protoreflect.Message { - mi := &file_Groups_proto_msgTypes[32] +func (x *GroupChange_Actions_ModifyDisappearingMessageTimerAction) ProtoReflect() protoreflect.Message { + mi := &file_Groups_proto_msgTypes[34] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2270,12 +2409,12 @@ func (x *GroupChange_Actions_ModifyDisappearingMessagesTimerAction) ProtoReflect return mi.MessageOf(x) } -// Deprecated: Use GroupChange_Actions_ModifyDisappearingMessagesTimerAction.ProtoReflect.Descriptor instead. -func (*GroupChange_Actions_ModifyDisappearingMessagesTimerAction) Descriptor() ([]byte, []int) { - return file_Groups_proto_rawDescGZIP(), []int{7, 0, 16} +// Deprecated: Use GroupChange_Actions_ModifyDisappearingMessageTimerAction.ProtoReflect.Descriptor instead. +func (*GroupChange_Actions_ModifyDisappearingMessageTimerAction) Descriptor() ([]byte, []int) { + return file_Groups_proto_rawDescGZIP(), []int{10, 0, 17} } -func (x *GroupChange_Actions_ModifyDisappearingMessagesTimerAction) GetTimer() []byte { +func (x *GroupChange_Actions_ModifyDisappearingMessageTimerAction) GetTimer() []byte { if x != nil { return x.Timer } @@ -2284,14 +2423,14 @@ func (x *GroupChange_Actions_ModifyDisappearingMessagesTimerAction) GetTimer() [ type GroupChange_Actions_ModifyAttributesAccessControlAction struct { state protoimpl.MessageState `protogen:"open.v1"` - AttributesAccess AccessControl_AccessRequired `protobuf:"varint,1,opt,name=attributesAccess,proto3,enum=AccessControl_AccessRequired" json:"attributesAccess,omitempty"` + AttributesAccess AccessControl_AccessRequired `protobuf:"varint,1,opt,name=attributesAccess,proto3,enum=signal.AccessControl_AccessRequired" json:"attributesAccess,omitempty"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } func (x *GroupChange_Actions_ModifyAttributesAccessControlAction) Reset() { *x = GroupChange_Actions_ModifyAttributesAccessControlAction{} - mi := &file_Groups_proto_msgTypes[33] + mi := &file_Groups_proto_msgTypes[35] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2303,7 +2442,7 @@ func (x *GroupChange_Actions_ModifyAttributesAccessControlAction) String() strin func (*GroupChange_Actions_ModifyAttributesAccessControlAction) ProtoMessage() {} func (x *GroupChange_Actions_ModifyAttributesAccessControlAction) ProtoReflect() protoreflect.Message { - mi := &file_Groups_proto_msgTypes[33] + mi := &file_Groups_proto_msgTypes[35] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2316,7 +2455,7 @@ func (x *GroupChange_Actions_ModifyAttributesAccessControlAction) ProtoReflect() // Deprecated: Use GroupChange_Actions_ModifyAttributesAccessControlAction.ProtoReflect.Descriptor instead. func (*GroupChange_Actions_ModifyAttributesAccessControlAction) Descriptor() ([]byte, []int) { - return file_Groups_proto_rawDescGZIP(), []int{7, 0, 17} + return file_Groups_proto_rawDescGZIP(), []int{10, 0, 18} } func (x *GroupChange_Actions_ModifyAttributesAccessControlAction) GetAttributesAccess() AccessControl_AccessRequired { @@ -2328,14 +2467,14 @@ func (x *GroupChange_Actions_ModifyAttributesAccessControlAction) GetAttributesA type GroupChange_Actions_ModifyMembersAccessControlAction struct { state protoimpl.MessageState `protogen:"open.v1"` - MembersAccess AccessControl_AccessRequired `protobuf:"varint,1,opt,name=membersAccess,proto3,enum=AccessControl_AccessRequired" json:"membersAccess,omitempty"` + MembersAccess AccessControl_AccessRequired `protobuf:"varint,1,opt,name=membersAccess,proto3,enum=signal.AccessControl_AccessRequired" json:"membersAccess,omitempty"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } func (x *GroupChange_Actions_ModifyMembersAccessControlAction) Reset() { *x = GroupChange_Actions_ModifyMembersAccessControlAction{} - mi := &file_Groups_proto_msgTypes[34] + mi := &file_Groups_proto_msgTypes[36] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2347,7 +2486,7 @@ func (x *GroupChange_Actions_ModifyMembersAccessControlAction) String() string { func (*GroupChange_Actions_ModifyMembersAccessControlAction) ProtoMessage() {} func (x *GroupChange_Actions_ModifyMembersAccessControlAction) ProtoReflect() protoreflect.Message { - mi := &file_Groups_proto_msgTypes[34] + mi := &file_Groups_proto_msgTypes[36] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2360,7 +2499,7 @@ func (x *GroupChange_Actions_ModifyMembersAccessControlAction) ProtoReflect() pr // Deprecated: Use GroupChange_Actions_ModifyMembersAccessControlAction.ProtoReflect.Descriptor instead. func (*GroupChange_Actions_ModifyMembersAccessControlAction) Descriptor() ([]byte, []int) { - return file_Groups_proto_rawDescGZIP(), []int{7, 0, 18} + return file_Groups_proto_rawDescGZIP(), []int{10, 0, 19} } func (x *GroupChange_Actions_ModifyMembersAccessControlAction) GetMembersAccess() AccessControl_AccessRequired { @@ -2372,14 +2511,14 @@ func (x *GroupChange_Actions_ModifyMembersAccessControlAction) GetMembersAccess( type GroupChange_Actions_ModifyAddFromInviteLinkAccessControlAction struct { state protoimpl.MessageState `protogen:"open.v1"` - AddFromInviteLinkAccess AccessControl_AccessRequired `protobuf:"varint,1,opt,name=addFromInviteLinkAccess,proto3,enum=AccessControl_AccessRequired" json:"addFromInviteLinkAccess,omitempty"` + AddFromInviteLinkAccess AccessControl_AccessRequired `protobuf:"varint,1,opt,name=addFromInviteLinkAccess,proto3,enum=signal.AccessControl_AccessRequired" json:"addFromInviteLinkAccess,omitempty"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } func (x *GroupChange_Actions_ModifyAddFromInviteLinkAccessControlAction) Reset() { *x = GroupChange_Actions_ModifyAddFromInviteLinkAccessControlAction{} - mi := &file_Groups_proto_msgTypes[35] + mi := &file_Groups_proto_msgTypes[37] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2391,7 +2530,7 @@ func (x *GroupChange_Actions_ModifyAddFromInviteLinkAccessControlAction) String( func (*GroupChange_Actions_ModifyAddFromInviteLinkAccessControlAction) ProtoMessage() {} func (x *GroupChange_Actions_ModifyAddFromInviteLinkAccessControlAction) ProtoReflect() protoreflect.Message { - mi := &file_Groups_proto_msgTypes[35] + mi := &file_Groups_proto_msgTypes[37] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2404,7 +2543,7 @@ func (x *GroupChange_Actions_ModifyAddFromInviteLinkAccessControlAction) ProtoRe // Deprecated: Use GroupChange_Actions_ModifyAddFromInviteLinkAccessControlAction.ProtoReflect.Descriptor instead. func (*GroupChange_Actions_ModifyAddFromInviteLinkAccessControlAction) Descriptor() ([]byte, []int) { - return file_Groups_proto_rawDescGZIP(), []int{7, 0, 19} + return file_Groups_proto_rawDescGZIP(), []int{10, 0, 20} } func (x *GroupChange_Actions_ModifyAddFromInviteLinkAccessControlAction) GetAddFromInviteLinkAccess() AccessControl_AccessRequired { @@ -2423,7 +2562,7 @@ type GroupChange_Actions_ModifyInviteLinkPasswordAction struct { func (x *GroupChange_Actions_ModifyInviteLinkPasswordAction) Reset() { *x = GroupChange_Actions_ModifyInviteLinkPasswordAction{} - mi := &file_Groups_proto_msgTypes[36] + mi := &file_Groups_proto_msgTypes[38] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2435,7 +2574,7 @@ func (x *GroupChange_Actions_ModifyInviteLinkPasswordAction) String() string { func (*GroupChange_Actions_ModifyInviteLinkPasswordAction) ProtoMessage() {} func (x *GroupChange_Actions_ModifyInviteLinkPasswordAction) ProtoReflect() protoreflect.Message { - mi := &file_Groups_proto_msgTypes[36] + mi := &file_Groups_proto_msgTypes[38] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2448,7 +2587,7 @@ func (x *GroupChange_Actions_ModifyInviteLinkPasswordAction) ProtoReflect() prot // Deprecated: Use GroupChange_Actions_ModifyInviteLinkPasswordAction.ProtoReflect.Descriptor instead. func (*GroupChange_Actions_ModifyInviteLinkPasswordAction) Descriptor() ([]byte, []int) { - return file_Groups_proto_rawDescGZIP(), []int{7, 0, 20} + return file_Groups_proto_rawDescGZIP(), []int{10, 0, 21} } func (x *GroupChange_Actions_ModifyInviteLinkPasswordAction) GetInviteLinkPassword() []byte { @@ -2460,14 +2599,14 @@ func (x *GroupChange_Actions_ModifyInviteLinkPasswordAction) GetInviteLinkPasswo type GroupChange_Actions_ModifyAnnouncementsOnlyAction struct { state protoimpl.MessageState `protogen:"open.v1"` - AnnouncementsOnly bool `protobuf:"varint,1,opt,name=announcementsOnly,proto3" json:"announcementsOnly,omitempty"` + AnnouncementsOnly bool `protobuf:"varint,1,opt,name=announcements_only,json=announcementsOnly,proto3" json:"announcements_only,omitempty"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } func (x *GroupChange_Actions_ModifyAnnouncementsOnlyAction) Reset() { *x = GroupChange_Actions_ModifyAnnouncementsOnlyAction{} - mi := &file_Groups_proto_msgTypes[37] + mi := &file_Groups_proto_msgTypes[39] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2479,7 +2618,7 @@ func (x *GroupChange_Actions_ModifyAnnouncementsOnlyAction) String() string { func (*GroupChange_Actions_ModifyAnnouncementsOnlyAction) ProtoMessage() {} func (x *GroupChange_Actions_ModifyAnnouncementsOnlyAction) ProtoReflect() protoreflect.Message { - mi := &file_Groups_proto_msgTypes[37] + mi := &file_Groups_proto_msgTypes[39] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2492,7 +2631,7 @@ func (x *GroupChange_Actions_ModifyAnnouncementsOnlyAction) ProtoReflect() proto // Deprecated: Use GroupChange_Actions_ModifyAnnouncementsOnlyAction.ProtoReflect.Descriptor instead. func (*GroupChange_Actions_ModifyAnnouncementsOnlyAction) Descriptor() ([]byte, []int) { - return file_Groups_proto_rawDescGZIP(), []int{7, 0, 21} + return file_Groups_proto_rawDescGZIP(), []int{10, 0, 22} } func (x *GroupChange_Actions_ModifyAnnouncementsOnlyAction) GetAnnouncementsOnly() bool { @@ -2512,7 +2651,7 @@ type GroupChanges_GroupChangeState struct { func (x *GroupChanges_GroupChangeState) Reset() { *x = GroupChanges_GroupChangeState{} - mi := &file_Groups_proto_msgTypes[38] + mi := &file_Groups_proto_msgTypes[40] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2524,7 +2663,7 @@ func (x *GroupChanges_GroupChangeState) String() string { func (*GroupChanges_GroupChangeState) ProtoMessage() {} func (x *GroupChanges_GroupChangeState) ProtoReflect() protoreflect.Message { - mi := &file_Groups_proto_msgTypes[38] + mi := &file_Groups_proto_msgTypes[40] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2537,7 +2676,7 @@ func (x *GroupChanges_GroupChangeState) ProtoReflect() protoreflect.Message { // Deprecated: Use GroupChanges_GroupChangeState.ProtoReflect.Descriptor instead. func (*GroupChanges_GroupChangeState) Descriptor() ([]byte, []int) { - return file_Groups_proto_rawDescGZIP(), []int{9, 0} + return file_Groups_proto_rawDescGZIP(), []int{13, 0} } func (x *GroupChanges_GroupChangeState) GetGroupChange() *GroupChange { @@ -2554,63 +2693,11 @@ func (x *GroupChanges_GroupChangeState) GetGroupState() *Group { return nil } -type GroupInviteLink_GroupInviteLinkContentsV1 struct { - state protoimpl.MessageState `protogen:"open.v1"` - GroupMasterKey []byte `protobuf:"bytes,1,opt,name=groupMasterKey,proto3" json:"groupMasterKey,omitempty"` - InviteLinkPassword []byte `protobuf:"bytes,2,opt,name=inviteLinkPassword,proto3" json:"inviteLinkPassword,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache -} - -func (x *GroupInviteLink_GroupInviteLinkContentsV1) Reset() { - *x = GroupInviteLink_GroupInviteLinkContentsV1{} - mi := &file_Groups_proto_msgTypes[39] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) -} - -func (x *GroupInviteLink_GroupInviteLinkContentsV1) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*GroupInviteLink_GroupInviteLinkContentsV1) ProtoMessage() {} - -func (x *GroupInviteLink_GroupInviteLinkContentsV1) ProtoReflect() protoreflect.Message { - mi := &file_Groups_proto_msgTypes[39] - if x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use GroupInviteLink_GroupInviteLinkContentsV1.ProtoReflect.Descriptor instead. -func (*GroupInviteLink_GroupInviteLinkContentsV1) Descriptor() ([]byte, []int) { - return file_Groups_proto_rawDescGZIP(), []int{12, 0} -} - -func (x *GroupInviteLink_GroupInviteLinkContentsV1) GetGroupMasterKey() []byte { - if x != nil { - return x.GroupMasterKey - } - return nil -} - -func (x *GroupInviteLink_GroupInviteLinkContentsV1) GetInviteLinkPassword() []byte { - if x != nil { - return x.InviteLinkPassword - } - return nil -} - var File_Groups_proto protoreflect.FileDescriptor const file_Groups_proto_rawDesc = "" + "\n" + - "\fGroups.proto\"\xc4\x01\n" + + "\fGroups.proto\x12\x06signal\"\xc4\x01\n" + "\x16AvatarUploadAttributes\x12\x10\n" + "\x03key\x18\x01 \x01(\tR\x03key\x12\x1e\n" + "\n" + @@ -2620,193 +2707,203 @@ const file_Groups_proto_rawDesc = "" + "\talgorithm\x18\x04 \x01(\tR\talgorithm\x12\x12\n" + "\x04date\x18\x05 \x01(\tR\x04date\x12\x16\n" + "\x06policy\x18\x06 \x01(\tR\x06policy\x12\x1c\n" + - "\tsignature\x18\a \x01(\tR\tsignature\"\xe7\x01\n" + + "\tsignature\x18\a \x01(\tR\tsignature\"\xae\x02\n" + "\x06Member\x12\x16\n" + - "\x06userId\x18\x01 \x01(\fR\x06userId\x12 \n" + - "\x04role\x18\x02 \x01(\x0e2\f.Member.RoleR\x04role\x12\x1e\n" + + "\x06userId\x18\x01 \x01(\fR\x06userId\x12'\n" + + "\x04role\x18\x02 \x01(\x0e2\x13.signal.Member.RoleR\x04role\x12\x1e\n" + "\n" + "profileKey\x18\x03 \x01(\fR\n" + "profileKey\x12\"\n" + - "\fpresentation\x18\x04 \x01(\fR\fpresentation\x12*\n" + - "\x10joinedAtRevision\x18\x05 \x01(\rR\x10joinedAtRevision\"3\n" + + "\fpresentation\x18\x04 \x01(\fR\fpresentation\x12(\n" + + "\x0fjoinedAtVersion\x18\x05 \x01(\rR\x0fjoinedAtVersion\x12\x1e\n" + + "\n" + + "labelEmoji\x18\x06 \x01(\fR\n" + + "labelEmoji\x12 \n" + + "\vlabelString\x18\a \x01(\fR\vlabelString\"3\n" + "\x04Role\x12\v\n" + "\aUNKNOWN\x10\x00\x12\v\n" + "\aDEFAULT\x10\x01\x12\x11\n" + - "\rADMINISTRATOR\x10\x02\"t\n" + - "\rPendingMember\x12\x1f\n" + - "\x06member\x18\x01 \x01(\v2\a.MemberR\x06member\x12$\n" + + "\rADMINISTRATOR\x10\x02\"\x85\x01\n" + + "\x17MemberPendingProfileKey\x12&\n" + + "\x06member\x18\x01 \x01(\v2\x0e.signal.MemberR\x06member\x12$\n" + "\raddedByUserId\x18\x02 \x01(\fR\raddedByUserId\x12\x1c\n" + - "\ttimestamp\x18\x03 \x01(\x04R\ttimestamp\"\x8c\x01\n" + - "\x10RequestingMember\x12\x16\n" + + "\ttimestamp\x18\x03 \x01(\x04R\ttimestamp\"\x96\x01\n" + + "\x1aMemberPendingAdminApproval\x12\x16\n" + "\x06userId\x18\x01 \x01(\fR\x06userId\x12\x1e\n" + "\n" + "profileKey\x18\x02 \x01(\fR\n" + "profileKey\x12\"\n" + "\fpresentation\x18\x03 \x01(\fR\fpresentation\x12\x1c\n" + "\ttimestamp\x18\x04 \x01(\x04R\ttimestamp\"D\n" + - "\fBannedMember\x12\x16\n" + + "\fMemberBanned\x12\x16\n" + "\x06userId\x18\x01 \x01(\fR\x06userId\x12\x1c\n" + - "\ttimestamp\x18\x02 \x01(\x04R\ttimestamp\"\xae\x02\n" + - "\rAccessControl\x12=\n" + + "\ttimestamp\x18\x02 \x01(\x04R\ttimestamp\"\xc3\x02\n" + + "\rAccessControl\x12D\n" + "\n" + - "attributes\x18\x01 \x01(\x0e2\x1d.AccessControl.AccessRequiredR\n" + - "attributes\x127\n" + - "\amembers\x18\x02 \x01(\x0e2\x1d.AccessControl.AccessRequiredR\amembers\x12K\n" + - "\x11addFromInviteLink\x18\x03 \x01(\x0e2\x1d.AccessControl.AccessRequiredR\x11addFromInviteLink\"X\n" + + "attributes\x18\x01 \x01(\x0e2$.signal.AccessControl.AccessRequiredR\n" + + "attributes\x12>\n" + + "\amembers\x18\x02 \x01(\x0e2$.signal.AccessControl.AccessRequiredR\amembers\x12R\n" + + "\x11addFromInviteLink\x18\x03 \x01(\x0e2$.signal.AccessControl.AccessRequiredR\x11addFromInviteLink\"X\n" + "\x0eAccessRequired\x12\v\n" + "\aUNKNOWN\x10\x00\x12\a\n" + "\x03ANY\x10\x01\x12\n" + "\n" + "\x06MEMBER\x10\x02\x12\x11\n" + "\rADMINISTRATOR\x10\x03\x12\x11\n" + - "\rUNSATISFIABLE\x10\x04\"\xb4\x04\n" + + "\rUNSATISFIABLE\x10\x04\"\x99\x05\n" + "\x05Group\x12\x1c\n" + "\tpublicKey\x18\x01 \x01(\fR\tpublicKey\x12\x14\n" + - "\x05title\x18\x02 \x01(\fR\x05title\x12\x16\n" + - "\x06avatar\x18\x03 \x01(\tR\x06avatar\x12<\n" + - "\x19disappearingMessagesTimer\x18\x04 \x01(\fR\x19disappearingMessagesTimer\x124\n" + - "\raccessControl\x18\x05 \x01(\v2\x0e.AccessControlR\raccessControl\x12\x1a\n" + - "\brevision\x18\x06 \x01(\rR\brevision\x12!\n" + - "\amembers\x18\a \x03(\v2\a.MemberR\amembers\x126\n" + - "\x0ependingMembers\x18\b \x03(\v2\x0e.PendingMemberR\x0ependingMembers\x12?\n" + - "\x11requestingMembers\x18\t \x03(\v2\x11.RequestingMemberR\x11requestingMembers\x12.\n" + + "\x05title\x18\x02 \x01(\fR\x05title\x12 \n" + + "\vdescription\x18\v \x01(\fR\vdescription\x12\x1c\n" + + "\tavatarUrl\x18\x03 \x01(\tR\tavatarUrl\x12<\n" + + "\x19disappearingMessagesTimer\x18\x04 \x01(\fR\x19disappearingMessagesTimer\x12;\n" + + "\raccessControl\x18\x05 \x01(\v2\x15.signal.AccessControlR\raccessControl\x12\x18\n" + + "\aversion\x18\x06 \x01(\rR\aversion\x12(\n" + + "\amembers\x18\a \x03(\v2\x0e.signal.MemberR\amembers\x12[\n" + + "\x18membersPendingProfileKey\x18\b \x03(\v2\x1f.signal.MemberPendingProfileKeyR\x18membersPendingProfileKey\x12d\n" + + "\x1bmembersPendingAdminApproval\x18\t \x03(\v2\".signal.MemberPendingAdminApprovalR\x1bmembersPendingAdminApproval\x12.\n" + "\x12inviteLinkPassword\x18\n" + - " \x01(\fR\x12inviteLinkPassword\x12 \n" + - "\vdescription\x18\v \x01(\fR\vdescription\x12,\n" + - "\x11announcementsOnly\x18\f \x01(\bR\x11announcementsOnly\x123\n" + - "\rbannedMembers\x18\r \x03(\v2\r.BannedMemberR\rbannedMembers\"\xe6!\n" + + " \x01(\fR\x12inviteLinkPassword\x12-\n" + + "\x12announcements_only\x18\f \x01(\bR\x11announcementsOnly\x12;\n" + + "\x0emembers_banned\x18\r \x03(\v2\x14.signal.MemberBannedR\rmembersBanned\"\xc3\x01\n" + + "\x12GroupAttributeBlob\x12\x16\n" + + "\x05title\x18\x01 \x01(\tH\x00R\x05title\x12\x18\n" + + "\x06avatar\x18\x02 \x01(\fH\x00R\x06avatar\x12D\n" + + "\x1cdisappearingMessagesDuration\x18\x03 \x01(\rH\x00R\x1cdisappearingMessagesDuration\x12*\n" + + "\x0fdescriptionText\x18\x04 \x01(\tH\x00R\x0fdescriptionTextB\t\n" + + "\acontent\"\xe7\x01\n" + + "\x0fGroupInviteLink\x12S\n" + + "\n" + + "contentsV1\x18\x01 \x01(\v21.signal.GroupInviteLink.GroupInviteLinkContentsV1H\x00R\n" + + "contentsV1\x1as\n" + + "\x19GroupInviteLinkContentsV1\x12&\n" + + "\x0egroupMasterKey\x18\x01 \x01(\fR\x0egroupMasterKey\x12.\n" + + "\x12inviteLinkPassword\x18\x02 \x01(\fR\x12inviteLinkPasswordB\n" + + "\n" + + "\bcontents\"\xc1\x02\n" + + "\rGroupJoinInfo\x12\x1c\n" + + "\tpublicKey\x18\x01 \x01(\fR\tpublicKey\x12\x14\n" + + "\x05title\x18\x02 \x01(\fR\x05title\x12 \n" + + "\vdescription\x18\b \x01(\fR\vdescription\x12\x16\n" + + "\x06avatar\x18\x03 \x01(\tR\x06avatar\x12 \n" + + "\vmemberCount\x18\x04 \x01(\rR\vmemberCount\x12R\n" + + "\x11addFromInviteLink\x18\x05 \x01(\x0e2$.signal.AccessControl.AccessRequiredR\x11addFromInviteLink\x12\x18\n" + + "\aversion\x18\x06 \x01(\rR\aversion\x122\n" + + "\x14pendingAdminApproval\x18\a \x01(\bR\x14pendingAdminApproval\"\xbb'\n" + "\vGroupChange\x12\x18\n" + "\aactions\x18\x01 \x01(\fR\aactions\x12(\n" + "\x0fserverSignature\x18\x02 \x01(\fR\x0fserverSignature\x12 \n" + - "\vchangeEpoch\x18\x03 \x01(\rR\vchangeEpoch\x1a\xf0 \n" + - "\aActions\x12(\n" + - "\x0fsourceServiceId\x18\x01 \x01(\fR\x0fsourceServiceId\x12\x18\n" + - "\agroupId\x18\x19 \x01(\fR\agroupId\x12\x1a\n" + - "\brevision\x18\x02 \x01(\rR\brevision\x12D\n" + + "\vchangeEpoch\x18\x03 \x01(\rR\vchangeEpoch\x1a\xc5&\n" + + "\aActions\x12\"\n" + + "\fsourceUserId\x18\x01 \x01(\fR\fsourceUserId\x12\x19\n" + + "\bgroup_id\x18\x19 \x01(\fR\agroupId\x12\x18\n" + + "\aversion\x18\x02 \x01(\rR\aversion\x12K\n" + "\n" + - "addMembers\x18\x03 \x03(\v2$.GroupChange.Actions.AddMemberActionR\n" + - "addMembers\x12M\n" + - "\rdeleteMembers\x18\x04 \x03(\v2'.GroupChange.Actions.DeleteMemberActionR\rdeleteMembers\x12Y\n" + - "\x11modifyMemberRoles\x18\x05 \x03(\v2+.GroupChange.Actions.ModifyMemberRoleActionR\x11modifyMemberRoles\x12k\n" + - "\x17modifyMemberProfileKeys\x18\x06 \x03(\v21.GroupChange.Actions.ModifyMemberProfileKeyActionR\x17modifyMemberProfileKeys\x12Y\n" + - "\x11addPendingMembers\x18\a \x03(\v2+.GroupChange.Actions.AddPendingMemberActionR\x11addPendingMembers\x12b\n" + - "\x14deletePendingMembers\x18\b \x03(\v2..GroupChange.Actions.DeletePendingMemberActionR\x14deletePendingMembers\x12e\n" + - "\x15promotePendingMembers\x18\t \x03(\v2/.GroupChange.Actions.PromotePendingMemberActionR\x15promotePendingMembers\x12H\n" + + "addMembers\x18\x03 \x03(\v2+.signal.GroupChange.Actions.AddMemberActionR\n" + + "addMembers\x12T\n" + + "\rdeleteMembers\x18\x04 \x03(\v2..signal.GroupChange.Actions.DeleteMemberActionR\rdeleteMembers\x12`\n" + + "\x11modifyMemberRoles\x18\x05 \x03(\v22.signal.GroupChange.Actions.ModifyMemberRoleActionR\x11modifyMemberRoles\x12r\n" + + "\x17modifyMemberProfileKeys\x18\x06 \x03(\v28.signal.GroupChange.Actions.ModifyMemberProfileKeyActionR\x17modifyMemberProfileKeys\x12~\n" + + "\x1baddMembersPendingProfileKey\x18\a \x03(\v2<.signal.GroupChange.Actions.AddMemberPendingProfileKeyActionR\x1baddMembersPendingProfileKey\x12\x87\x01\n" + + "\x1edeleteMembersPendingProfileKey\x18\b \x03(\v2?.signal.GroupChange.Actions.DeleteMemberPendingProfileKeyActionR\x1edeleteMembersPendingProfileKey\x12\x8a\x01\n" + + "\x1fpromoteMembersPendingProfileKey\x18\t \x03(\v2@.signal.GroupChange.Actions.PromoteMemberPendingProfileKeyActionR\x1fpromoteMembersPendingProfileKey\x12O\n" + "\vmodifyTitle\x18\n" + - " \x01(\v2&.GroupChange.Actions.ModifyTitleActionR\vmodifyTitle\x12K\n" + - "\fmodifyAvatar\x18\v \x01(\v2'.GroupChange.Actions.ModifyAvatarActionR\fmodifyAvatar\x12\x84\x01\n" + - "\x1fmodifyDisappearingMessagesTimer\x18\f \x01(\v2:.GroupChange.Actions.ModifyDisappearingMessagesTimerActionR\x1fmodifyDisappearingMessagesTimer\x12p\n" + - "\x16modifyAttributesAccess\x18\r \x01(\v28.GroupChange.Actions.ModifyAttributesAccessControlActionR\x16modifyAttributesAccess\x12e\n" + - "\x12modifyMemberAccess\x18\x0e \x01(\v25.GroupChange.Actions.ModifyMembersAccessControlActionR\x12modifyMemberAccess\x12\x85\x01\n" + - "\x1dmodifyAddFromInviteLinkAccess\x18\x0f \x01(\v2?.GroupChange.Actions.ModifyAddFromInviteLinkAccessControlActionR\x1dmodifyAddFromInviteLinkAccess\x12b\n" + - "\x14addRequestingMembers\x18\x10 \x03(\v2..GroupChange.Actions.AddRequestingMemberActionR\x14addRequestingMembers\x12k\n" + - "\x17deleteRequestingMembers\x18\x11 \x03(\v21.GroupChange.Actions.DeleteRequestingMemberActionR\x17deleteRequestingMembers\x12n\n" + - "\x18promoteRequestingMembers\x18\x12 \x03(\v22.GroupChange.Actions.PromoteRequestingMemberActionR\x18promoteRequestingMembers\x12o\n" + - "\x18modifyInviteLinkPassword\x18\x13 \x01(\v23.GroupChange.Actions.ModifyInviteLinkPasswordActionR\x18modifyInviteLinkPassword\x12Z\n" + - "\x11modifyDescription\x18\x14 \x01(\v2,.GroupChange.Actions.ModifyDescriptionActionR\x11modifyDescription\x12l\n" + - "\x17modifyAnnouncementsOnly\x18\x15 \x01(\v22.GroupChange.Actions.ModifyAnnouncementsOnlyActionR\x17modifyAnnouncementsOnly\x12V\n" + - "\x10addBannedMembers\x18\x16 \x03(\v2*.GroupChange.Actions.AddBannedMemberActionR\x10addBannedMembers\x12_\n" + - "\x13deleteBannedMembers\x18\x17 \x03(\v2-.GroupChange.Actions.DeleteBannedMemberActionR\x13deleteBannedMembers\x12\x81\x01\n" + - "\x1bpromotePendingPniAciMembers\x18\x18 \x03(\v2?.GroupChange.Actions.PromotePendingPniAciMemberProfileKeyActionR\x1bpromotePendingPniAciMembers\x1a`\n" + - "\x0fAddMemberAction\x12\x1d\n" + - "\x05added\x18\x01 \x01(\v2\a.MemberR\x05added\x12.\n" + + " \x01(\v2-.signal.GroupChange.Actions.ModifyTitleActionR\vmodifyTitle\x12R\n" + + "\fmodifyAvatar\x18\v \x01(\v2..signal.GroupChange.Actions.ModifyAvatarActionR\fmodifyAvatar\x12\x88\x01\n" + + "\x1emodifyDisappearingMessageTimer\x18\f \x01(\v2@.signal.GroupChange.Actions.ModifyDisappearingMessageTimerActionR\x1emodifyDisappearingMessageTimer\x12w\n" + + "\x16modifyAttributesAccess\x18\r \x01(\v2?.signal.GroupChange.Actions.ModifyAttributesAccessControlActionR\x16modifyAttributesAccess\x12l\n" + + "\x12modifyMemberAccess\x18\x0e \x01(\v2<.signal.GroupChange.Actions.ModifyMembersAccessControlActionR\x12modifyMemberAccess\x12\x8c\x01\n" + + "\x1dmodifyAddFromInviteLinkAccess\x18\x0f \x01(\v2F.signal.GroupChange.Actions.ModifyAddFromInviteLinkAccessControlActionR\x1dmodifyAddFromInviteLinkAccess\x12\x87\x01\n" + + "\x1eaddMembersPendingAdminApproval\x18\x10 \x03(\v2?.signal.GroupChange.Actions.AddMemberPendingAdminApprovalActionR\x1eaddMembersPendingAdminApproval\x12\x90\x01\n" + + "!deleteMembersPendingAdminApproval\x18\x11 \x03(\v2B.signal.GroupChange.Actions.DeleteMemberPendingAdminApprovalActionR!deleteMembersPendingAdminApproval\x12\x93\x01\n" + + "\"promoteMembersPendingAdminApproval\x18\x12 \x03(\v2C.signal.GroupChange.Actions.PromoteMemberPendingAdminApprovalActionR\"promoteMembersPendingAdminApproval\x12v\n" + + "\x18modifyInviteLinkPassword\x18\x13 \x01(\v2:.signal.GroupChange.Actions.ModifyInviteLinkPasswordActionR\x18modifyInviteLinkPassword\x12a\n" + + "\x11modifyDescription\x18\x14 \x01(\v23.signal.GroupChange.Actions.ModifyDescriptionActionR\x11modifyDescription\x12u\n" + + "\x19modify_announcements_only\x18\x15 \x01(\v29.signal.GroupChange.Actions.ModifyAnnouncementsOnlyActionR\x17modifyAnnouncementsOnly\x12_\n" + + "\x12add_members_banned\x18\x16 \x03(\v21.signal.GroupChange.Actions.AddMemberBannedActionR\x10addMembersBanned\x12h\n" + + "\x15delete_members_banned\x18\x17 \x03(\v24.signal.GroupChange.Actions.DeleteMemberBannedActionR\x13deleteMembersBanned\x12\xa2\x01\n" + + "+promote_members_pending_pni_aci_profile_key\x18\x18 \x03(\v2F.signal.GroupChange.Actions.PromoteMemberPendingPniAciProfileKeyActionR%promoteMembersPendingPniAciProfileKey\x12c\n" + + "\x12modifyMemberLabels\x18\x1a \x03(\v23.signal.GroupChange.Actions.ModifyMemberLabelActionR\x12modifyMemberLabels\x1ag\n" + + "\x0fAddMemberAction\x12$\n" + + "\x05added\x18\x01 \x01(\v2\x0e.signal.MemberR\x05added\x12.\n" + "\x12joinFromInviteLink\x18\x02 \x01(\bR\x12joinFromInviteLink\x1a:\n" + "\x12DeleteMemberAction\x12$\n" + - "\rdeletedUserId\x18\x01 \x01(\fR\rdeletedUserId\x1aR\n" + + "\rdeletedUserId\x18\x01 \x01(\fR\rdeletedUserId\x1aY\n" + "\x16ModifyMemberRoleAction\x12\x16\n" + - "\x06userId\x18\x01 \x01(\fR\x06userId\x12 \n" + - "\x04role\x18\x02 \x01(\x0e2\f.Member.RoleR\x04role\x1a|\n" + + "\x06userId\x18\x01 \x01(\fR\x06userId\x12'\n" + + "\x04role\x18\x02 \x01(\x0e2\x13.signal.Member.RoleR\x04role\x1as\n" + + "\x17ModifyMemberLabelAction\x12\x16\n" + + "\x06userId\x18\x01 \x01(\fR\x06userId\x12\x1e\n" + + "\n" + + "labelEmoji\x18\x02 \x01(\fR\n" + + "labelEmoji\x12 \n" + + "\vlabelString\x18\x03 \x01(\fR\vlabelString\x1a|\n" + "\x1cModifyMemberProfileKeyAction\x12\"\n" + "\fpresentation\x18\x01 \x01(\fR\fpresentation\x12\x17\n" + "\auser_id\x18\x02 \x01(\fR\x06userId\x12\x1f\n" + "\vprofile_key\x18\x03 \x01(\fR\n" + - "profileKey\x1a>\n" + - "\x16AddPendingMemberAction\x12$\n" + - "\x05added\x18\x01 \x01(\v2\x0e.PendingMemberR\x05added\x1aA\n" + - "\x19DeletePendingMemberAction\x12$\n" + - "\rdeletedUserId\x18\x01 \x01(\fR\rdeletedUserId\x1az\n" + - "\x1aPromotePendingMemberAction\x12\"\n" + + "profileKey\x1aY\n" + + " AddMemberPendingProfileKeyAction\x125\n" + + "\x05added\x18\x01 \x01(\v2\x1f.signal.MemberPendingProfileKeyR\x05added\x1aK\n" + + "#DeleteMemberPendingProfileKeyAction\x12$\n" + + "\rdeletedUserId\x18\x01 \x01(\fR\rdeletedUserId\x1a\x84\x01\n" + + "$PromoteMemberPendingProfileKeyAction\x12\"\n" + "\fpresentation\x18\x01 \x01(\fR\fpresentation\x12\x17\n" + "\auser_id\x18\x02 \x01(\fR\x06userId\x12\x1f\n" + "\vprofile_key\x18\x03 \x01(\fR\n" + - "profileKey\x1a\x9a\x01\n" + - "*PromotePendingPniAciMemberProfileKeyAction\x12\"\n" + - "\fpresentation\x18\x01 \x01(\fR\fpresentation\x12\x16\n" + - "\x06userId\x18\x02 \x01(\fR\x06userId\x12\x10\n" + - "\x03pni\x18\x03 \x01(\fR\x03pni\x12\x1e\n" + - "\n" + - "profileKey\x18\x04 \x01(\fR\n" + - "profileKey\x1aD\n" + - "\x19AddRequestingMemberAction\x12'\n" + - "\x05added\x18\x01 \x01(\v2\x11.RequestingMemberR\x05added\x1aD\n" + - "\x1cDeleteRequestingMemberAction\x12$\n" + - "\rdeletedUserId\x18\x01 \x01(\fR\rdeletedUserId\x1aY\n" + - "\x1dPromoteRequestingMemberAction\x12\x16\n" + - "\x06userId\x18\x01 \x01(\fR\x06userId\x12 \n" + - "\x04role\x18\x02 \x01(\x0e2\f.Member.RoleR\x04role\x1a<\n" + - "\x15AddBannedMemberAction\x12#\n" + - "\x05added\x18\x01 \x01(\v2\r.BannedMemberR\x05added\x1a@\n" + - "\x18DeleteBannedMemberAction\x12$\n" + + "profileKey\x1a\x9c\x01\n" + + "*PromoteMemberPendingPniAciProfileKeyAction\x12\"\n" + + "\fpresentation\x18\x01 \x01(\fR\fpresentation\x12\x17\n" + + "\auser_id\x18\x02 \x01(\fR\x06userId\x12\x10\n" + + "\x03pni\x18\x03 \x01(\fR\x03pni\x12\x1f\n" + + "\vprofile_key\x18\x04 \x01(\fR\n" + + "profileKey\x1a_\n" + + "#AddMemberPendingAdminApprovalAction\x128\n" + + "\x05added\x18\x01 \x01(\v2\".signal.MemberPendingAdminApprovalR\x05added\x1aN\n" + + "&DeleteMemberPendingAdminApprovalAction\x12$\n" + + "\rdeletedUserId\x18\x01 \x01(\fR\rdeletedUserId\x1aj\n" + + "'PromoteMemberPendingAdminApprovalAction\x12\x16\n" + + "\x06userId\x18\x01 \x01(\fR\x06userId\x12'\n" + + "\x04role\x18\x02 \x01(\x0e2\x13.signal.Member.RoleR\x04role\x1aC\n" + + "\x15AddMemberBannedAction\x12*\n" + + "\x05added\x18\x01 \x01(\v2\x14.signal.MemberBannedR\x05added\x1a@\n" + + "\x18DeleteMemberBannedAction\x12$\n" + "\rdeletedUserId\x18\x01 \x01(\fR\rdeletedUserId\x1a)\n" + "\x11ModifyTitleAction\x12\x14\n" + "\x05title\x18\x01 \x01(\fR\x05title\x1a;\n" + "\x17ModifyDescriptionAction\x12 \n" + "\vdescription\x18\x01 \x01(\fR\vdescription\x1a,\n" + "\x12ModifyAvatarAction\x12\x16\n" + - "\x06avatar\x18\x01 \x01(\tR\x06avatar\x1a=\n" + - "%ModifyDisappearingMessagesTimerAction\x12\x14\n" + - "\x05timer\x18\x01 \x01(\fR\x05timer\x1ap\n" + - "#ModifyAttributesAccessControlAction\x12I\n" + - "\x10attributesAccess\x18\x01 \x01(\x0e2\x1d.AccessControl.AccessRequiredR\x10attributesAccess\x1ag\n" + - " ModifyMembersAccessControlAction\x12C\n" + - "\rmembersAccess\x18\x01 \x01(\x0e2\x1d.AccessControl.AccessRequiredR\rmembersAccess\x1a\x85\x01\n" + - "*ModifyAddFromInviteLinkAccessControlAction\x12W\n" + - "\x17addFromInviteLinkAccess\x18\x01 \x01(\x0e2\x1d.AccessControl.AccessRequiredR\x17addFromInviteLinkAccess\x1aP\n" + + "\x06avatar\x18\x01 \x01(\tR\x06avatar\x1a<\n" + + "$ModifyDisappearingMessageTimerAction\x12\x14\n" + + "\x05timer\x18\x01 \x01(\fR\x05timer\x1aw\n" + + "#ModifyAttributesAccessControlAction\x12P\n" + + "\x10attributesAccess\x18\x01 \x01(\x0e2$.signal.AccessControl.AccessRequiredR\x10attributesAccess\x1an\n" + + " ModifyMembersAccessControlAction\x12J\n" + + "\rmembersAccess\x18\x01 \x01(\x0e2$.signal.AccessControl.AccessRequiredR\rmembersAccess\x1a\x8c\x01\n" + + "*ModifyAddFromInviteLinkAccessControlAction\x12^\n" + + "\x17addFromInviteLinkAccess\x18\x01 \x01(\x0e2$.signal.AccessControl.AccessRequiredR\x17addFromInviteLinkAccess\x1aP\n" + "\x1eModifyInviteLinkPasswordAction\x12.\n" + - "\x12inviteLinkPassword\x18\x01 \x01(\fR\x12inviteLinkPassword\x1aM\n" + - "\x1dModifyAnnouncementsOnlyAction\x12,\n" + - "\x11announcementsOnly\x18\x01 \x01(\bR\x11announcementsOnly\"s\n" + - "\rGroupResponse\x12\x1c\n" + - "\x05group\x18\x01 \x01(\v2\x06.GroupR\x05group\x12D\n" + - "\x1dgroupSendEndorsementsResponse\x18\x02 \x01(\fR\x1dgroupSendEndorsementsResponse\"\x84\x02\n" + - "\fGroupChanges\x12B\n" + - "\fgroupChanges\x18\x01 \x03(\v2\x1e.GroupChanges.GroupChangeStateR\fgroupChanges\x12D\n" + - "\x1dgroupSendEndorsementsResponse\x18\x02 \x01(\fR\x1dgroupSendEndorsementsResponse\x1aj\n" + - "\x10GroupChangeState\x12.\n" + - "\vgroupChange\x18\x01 \x01(\v2\f.GroupChangeR\vgroupChange\x12&\n" + + "\x12inviteLinkPassword\x18\x01 \x01(\fR\x12inviteLinkPassword\x1aN\n" + + "\x1dModifyAnnouncementsOnlyAction\x12-\n" + + "\x12announcements_only\x18\x01 \x01(\bR\x11announcementsOnly\"/\n" + + "\x17ExternalGroupCredential\x12\x14\n" + + "\x05token\x18\x01 \x01(\tR\x05token\"}\n" + + "\rGroupResponse\x12#\n" + + "\x05group\x18\x01 \x01(\v2\r.signal.GroupR\x05group\x12G\n" + + " group_send_endorsements_response\x18\x02 \x01(\fR\x1dgroupSendEndorsementsResponse\"\x9c\x02\n" + + "\fGroupChanges\x12I\n" + + "\fgroupChanges\x18\x01 \x03(\v2%.signal.GroupChanges.GroupChangeStateR\fgroupChanges\x12G\n" + + " group_send_endorsements_response\x18\x02 \x01(\fR\x1dgroupSendEndorsementsResponse\x1ax\n" + + "\x10GroupChangeState\x125\n" + + "\vgroupChange\x18\x01 \x01(\v2\x13.signal.GroupChangeR\vgroupChange\x12-\n" + "\n" + - "groupState\x18\x02 \x01(\v2\x06.GroupR\n" + - "groupState\"\x8b\x01\n" + - "\x13GroupChangeResponse\x12.\n" + - "\vgroupChange\x18\x01 \x01(\v2\f.GroupChangeR\vgroupChange\x12D\n" + - "\x1dgroupSendEndorsementsResponse\x18\x02 \x01(\fR\x1dgroupSendEndorsementsResponse\"\xbb\x01\n" + - "\x12GroupAttributeBlob\x12\x16\n" + - "\x05title\x18\x01 \x01(\tH\x00R\x05title\x12\x18\n" + - "\x06avatar\x18\x02 \x01(\fH\x00R\x06avatar\x12D\n" + - "\x1cdisappearingMessagesDuration\x18\x03 \x01(\rH\x00R\x1cdisappearingMessagesDuration\x12\"\n" + - "\vdescription\x18\x04 \x01(\tH\x00R\vdescriptionB\t\n" + - "\acontent\"\xe0\x01\n" + - "\x0fGroupInviteLink\x12L\n" + - "\n" + - "v1Contents\x18\x01 \x01(\v2*.GroupInviteLink.GroupInviteLinkContentsV1H\x00R\n" + - "v1Contents\x1as\n" + - "\x19GroupInviteLinkContentsV1\x12&\n" + - "\x0egroupMasterKey\x18\x01 \x01(\fR\x0egroupMasterKey\x12.\n" + - "\x12inviteLinkPassword\x18\x02 \x01(\fR\x12inviteLinkPasswordB\n" + - "\n" + - "\bcontents\"\xbc\x02\n" + - "\rGroupJoinInfo\x12\x1c\n" + - "\tpublicKey\x18\x01 \x01(\fR\tpublicKey\x12\x14\n" + - "\x05title\x18\x02 \x01(\fR\x05title\x12\x16\n" + - "\x06avatar\x18\x03 \x01(\tR\x06avatar\x12 \n" + - "\vmemberCount\x18\x04 \x01(\rR\vmemberCount\x12K\n" + - "\x11addFromInviteLink\x18\x05 \x01(\x0e2\x1d.AccessControl.AccessRequiredR\x11addFromInviteLink\x12\x1a\n" + - "\brevision\x18\x06 \x01(\rR\brevision\x122\n" + - "\x14pendingAdminApproval\x18\a \x01(\bR\x14pendingAdminApproval\x12 \n" + - "\vdescription\x18\b \x01(\fR\vdescription\"/\n" + - "\x17GroupExternalCredential\x12\x14\n" + - "\x05token\x18\x01 \x01(\tR\x05tokenB+\n" + - "'org.signal.storageservice.protos.groupsP\x01b\x06proto3" + "groupState\x18\x02 \x01(\v2\r.signal.GroupR\n" + + "groupState\"\x96\x01\n" + + "\x13GroupChangeResponse\x126\n" + + "\fgroup_change\x18\x01 \x01(\v2\x13.signal.GroupChangeR\vgroupChange\x12G\n" + + " group_send_endorsements_response\x18\x02 \x01(\fR\x1dgroupSendEndorsementsResponseB@\n" + + "/org.signal.storageservice.storage.protos.groupsB\vGroupProtosP\x01b\x06proto3" var ( file_Groups_proto_rawDescOnce sync.Once @@ -2821,105 +2918,107 @@ func file_Groups_proto_rawDescGZIP() []byte { } var file_Groups_proto_enumTypes = make([]protoimpl.EnumInfo, 2) -var file_Groups_proto_msgTypes = make([]protoimpl.MessageInfo, 40) +var file_Groups_proto_msgTypes = make([]protoimpl.MessageInfo, 41) var file_Groups_proto_goTypes = []any{ - (Member_Role)(0), // 0: Member.Role - (AccessControl_AccessRequired)(0), // 1: AccessControl.AccessRequired - (*AvatarUploadAttributes)(nil), // 2: AvatarUploadAttributes - (*Member)(nil), // 3: Member - (*PendingMember)(nil), // 4: PendingMember - (*RequestingMember)(nil), // 5: RequestingMember - (*BannedMember)(nil), // 6: BannedMember - (*AccessControl)(nil), // 7: AccessControl - (*Group)(nil), // 8: Group - (*GroupChange)(nil), // 9: GroupChange - (*GroupResponse)(nil), // 10: GroupResponse - (*GroupChanges)(nil), // 11: GroupChanges - (*GroupChangeResponse)(nil), // 12: GroupChangeResponse - (*GroupAttributeBlob)(nil), // 13: GroupAttributeBlob - (*GroupInviteLink)(nil), // 14: GroupInviteLink - (*GroupJoinInfo)(nil), // 15: GroupJoinInfo - (*GroupExternalCredential)(nil), // 16: GroupExternalCredential - (*GroupChange_Actions)(nil), // 17: GroupChange.Actions - (*GroupChange_Actions_AddMemberAction)(nil), // 18: GroupChange.Actions.AddMemberAction - (*GroupChange_Actions_DeleteMemberAction)(nil), // 19: GroupChange.Actions.DeleteMemberAction - (*GroupChange_Actions_ModifyMemberRoleAction)(nil), // 20: GroupChange.Actions.ModifyMemberRoleAction - (*GroupChange_Actions_ModifyMemberProfileKeyAction)(nil), // 21: GroupChange.Actions.ModifyMemberProfileKeyAction - (*GroupChange_Actions_AddPendingMemberAction)(nil), // 22: GroupChange.Actions.AddPendingMemberAction - (*GroupChange_Actions_DeletePendingMemberAction)(nil), // 23: GroupChange.Actions.DeletePendingMemberAction - (*GroupChange_Actions_PromotePendingMemberAction)(nil), // 24: GroupChange.Actions.PromotePendingMemberAction - (*GroupChange_Actions_PromotePendingPniAciMemberProfileKeyAction)(nil), // 25: GroupChange.Actions.PromotePendingPniAciMemberProfileKeyAction - (*GroupChange_Actions_AddRequestingMemberAction)(nil), // 26: GroupChange.Actions.AddRequestingMemberAction - (*GroupChange_Actions_DeleteRequestingMemberAction)(nil), // 27: GroupChange.Actions.DeleteRequestingMemberAction - (*GroupChange_Actions_PromoteRequestingMemberAction)(nil), // 28: GroupChange.Actions.PromoteRequestingMemberAction - (*GroupChange_Actions_AddBannedMemberAction)(nil), // 29: GroupChange.Actions.AddBannedMemberAction - (*GroupChange_Actions_DeleteBannedMemberAction)(nil), // 30: GroupChange.Actions.DeleteBannedMemberAction - (*GroupChange_Actions_ModifyTitleAction)(nil), // 31: GroupChange.Actions.ModifyTitleAction - (*GroupChange_Actions_ModifyDescriptionAction)(nil), // 32: GroupChange.Actions.ModifyDescriptionAction - (*GroupChange_Actions_ModifyAvatarAction)(nil), // 33: GroupChange.Actions.ModifyAvatarAction - (*GroupChange_Actions_ModifyDisappearingMessagesTimerAction)(nil), // 34: GroupChange.Actions.ModifyDisappearingMessagesTimerAction - (*GroupChange_Actions_ModifyAttributesAccessControlAction)(nil), // 35: GroupChange.Actions.ModifyAttributesAccessControlAction - (*GroupChange_Actions_ModifyMembersAccessControlAction)(nil), // 36: GroupChange.Actions.ModifyMembersAccessControlAction - (*GroupChange_Actions_ModifyAddFromInviteLinkAccessControlAction)(nil), // 37: GroupChange.Actions.ModifyAddFromInviteLinkAccessControlAction - (*GroupChange_Actions_ModifyInviteLinkPasswordAction)(nil), // 38: GroupChange.Actions.ModifyInviteLinkPasswordAction - (*GroupChange_Actions_ModifyAnnouncementsOnlyAction)(nil), // 39: GroupChange.Actions.ModifyAnnouncementsOnlyAction - (*GroupChanges_GroupChangeState)(nil), // 40: GroupChanges.GroupChangeState - (*GroupInviteLink_GroupInviteLinkContentsV1)(nil), // 41: GroupInviteLink.GroupInviteLinkContentsV1 + (Member_Role)(0), // 0: signal.Member.Role + (AccessControl_AccessRequired)(0), // 1: signal.AccessControl.AccessRequired + (*AvatarUploadAttributes)(nil), // 2: signal.AvatarUploadAttributes + (*Member)(nil), // 3: signal.Member + (*MemberPendingProfileKey)(nil), // 4: signal.MemberPendingProfileKey + (*MemberPendingAdminApproval)(nil), // 5: signal.MemberPendingAdminApproval + (*MemberBanned)(nil), // 6: signal.MemberBanned + (*AccessControl)(nil), // 7: signal.AccessControl + (*Group)(nil), // 8: signal.Group + (*GroupAttributeBlob)(nil), // 9: signal.GroupAttributeBlob + (*GroupInviteLink)(nil), // 10: signal.GroupInviteLink + (*GroupJoinInfo)(nil), // 11: signal.GroupJoinInfo + (*GroupChange)(nil), // 12: signal.GroupChange + (*ExternalGroupCredential)(nil), // 13: signal.ExternalGroupCredential + (*GroupResponse)(nil), // 14: signal.GroupResponse + (*GroupChanges)(nil), // 15: signal.GroupChanges + (*GroupChangeResponse)(nil), // 16: signal.GroupChangeResponse + (*GroupInviteLink_GroupInviteLinkContentsV1)(nil), // 17: signal.GroupInviteLink.GroupInviteLinkContentsV1 + (*GroupChange_Actions)(nil), // 18: signal.GroupChange.Actions + (*GroupChange_Actions_AddMemberAction)(nil), // 19: signal.GroupChange.Actions.AddMemberAction + (*GroupChange_Actions_DeleteMemberAction)(nil), // 20: signal.GroupChange.Actions.DeleteMemberAction + (*GroupChange_Actions_ModifyMemberRoleAction)(nil), // 21: signal.GroupChange.Actions.ModifyMemberRoleAction + (*GroupChange_Actions_ModifyMemberLabelAction)(nil), // 22: signal.GroupChange.Actions.ModifyMemberLabelAction + (*GroupChange_Actions_ModifyMemberProfileKeyAction)(nil), // 23: signal.GroupChange.Actions.ModifyMemberProfileKeyAction + (*GroupChange_Actions_AddMemberPendingProfileKeyAction)(nil), // 24: signal.GroupChange.Actions.AddMemberPendingProfileKeyAction + (*GroupChange_Actions_DeleteMemberPendingProfileKeyAction)(nil), // 25: signal.GroupChange.Actions.DeleteMemberPendingProfileKeyAction + (*GroupChange_Actions_PromoteMemberPendingProfileKeyAction)(nil), // 26: signal.GroupChange.Actions.PromoteMemberPendingProfileKeyAction + (*GroupChange_Actions_PromoteMemberPendingPniAciProfileKeyAction)(nil), // 27: signal.GroupChange.Actions.PromoteMemberPendingPniAciProfileKeyAction + (*GroupChange_Actions_AddMemberPendingAdminApprovalAction)(nil), // 28: signal.GroupChange.Actions.AddMemberPendingAdminApprovalAction + (*GroupChange_Actions_DeleteMemberPendingAdminApprovalAction)(nil), // 29: signal.GroupChange.Actions.DeleteMemberPendingAdminApprovalAction + (*GroupChange_Actions_PromoteMemberPendingAdminApprovalAction)(nil), // 30: signal.GroupChange.Actions.PromoteMemberPendingAdminApprovalAction + (*GroupChange_Actions_AddMemberBannedAction)(nil), // 31: signal.GroupChange.Actions.AddMemberBannedAction + (*GroupChange_Actions_DeleteMemberBannedAction)(nil), // 32: signal.GroupChange.Actions.DeleteMemberBannedAction + (*GroupChange_Actions_ModifyTitleAction)(nil), // 33: signal.GroupChange.Actions.ModifyTitleAction + (*GroupChange_Actions_ModifyDescriptionAction)(nil), // 34: signal.GroupChange.Actions.ModifyDescriptionAction + (*GroupChange_Actions_ModifyAvatarAction)(nil), // 35: signal.GroupChange.Actions.ModifyAvatarAction + (*GroupChange_Actions_ModifyDisappearingMessageTimerAction)(nil), // 36: signal.GroupChange.Actions.ModifyDisappearingMessageTimerAction + (*GroupChange_Actions_ModifyAttributesAccessControlAction)(nil), // 37: signal.GroupChange.Actions.ModifyAttributesAccessControlAction + (*GroupChange_Actions_ModifyMembersAccessControlAction)(nil), // 38: signal.GroupChange.Actions.ModifyMembersAccessControlAction + (*GroupChange_Actions_ModifyAddFromInviteLinkAccessControlAction)(nil), // 39: signal.GroupChange.Actions.ModifyAddFromInviteLinkAccessControlAction + (*GroupChange_Actions_ModifyInviteLinkPasswordAction)(nil), // 40: signal.GroupChange.Actions.ModifyInviteLinkPasswordAction + (*GroupChange_Actions_ModifyAnnouncementsOnlyAction)(nil), // 41: signal.GroupChange.Actions.ModifyAnnouncementsOnlyAction + (*GroupChanges_GroupChangeState)(nil), // 42: signal.GroupChanges.GroupChangeState } var file_Groups_proto_depIdxs = []int32{ - 0, // 0: Member.role:type_name -> Member.Role - 3, // 1: PendingMember.member:type_name -> Member - 1, // 2: AccessControl.attributes:type_name -> AccessControl.AccessRequired - 1, // 3: AccessControl.members:type_name -> AccessControl.AccessRequired - 1, // 4: AccessControl.addFromInviteLink:type_name -> AccessControl.AccessRequired - 7, // 5: Group.accessControl:type_name -> AccessControl - 3, // 6: Group.members:type_name -> Member - 4, // 7: Group.pendingMembers:type_name -> PendingMember - 5, // 8: Group.requestingMembers:type_name -> RequestingMember - 6, // 9: Group.bannedMembers:type_name -> BannedMember - 8, // 10: GroupResponse.group:type_name -> Group - 40, // 11: GroupChanges.groupChanges:type_name -> GroupChanges.GroupChangeState - 9, // 12: GroupChangeResponse.groupChange:type_name -> GroupChange - 41, // 13: GroupInviteLink.v1Contents:type_name -> GroupInviteLink.GroupInviteLinkContentsV1 - 1, // 14: GroupJoinInfo.addFromInviteLink:type_name -> AccessControl.AccessRequired - 18, // 15: GroupChange.Actions.addMembers:type_name -> GroupChange.Actions.AddMemberAction - 19, // 16: GroupChange.Actions.deleteMembers:type_name -> GroupChange.Actions.DeleteMemberAction - 20, // 17: GroupChange.Actions.modifyMemberRoles:type_name -> GroupChange.Actions.ModifyMemberRoleAction - 21, // 18: GroupChange.Actions.modifyMemberProfileKeys:type_name -> GroupChange.Actions.ModifyMemberProfileKeyAction - 22, // 19: GroupChange.Actions.addPendingMembers:type_name -> GroupChange.Actions.AddPendingMemberAction - 23, // 20: GroupChange.Actions.deletePendingMembers:type_name -> GroupChange.Actions.DeletePendingMemberAction - 24, // 21: GroupChange.Actions.promotePendingMembers:type_name -> GroupChange.Actions.PromotePendingMemberAction - 31, // 22: GroupChange.Actions.modifyTitle:type_name -> GroupChange.Actions.ModifyTitleAction - 33, // 23: GroupChange.Actions.modifyAvatar:type_name -> GroupChange.Actions.ModifyAvatarAction - 34, // 24: GroupChange.Actions.modifyDisappearingMessagesTimer:type_name -> GroupChange.Actions.ModifyDisappearingMessagesTimerAction - 35, // 25: GroupChange.Actions.modifyAttributesAccess:type_name -> GroupChange.Actions.ModifyAttributesAccessControlAction - 36, // 26: GroupChange.Actions.modifyMemberAccess:type_name -> GroupChange.Actions.ModifyMembersAccessControlAction - 37, // 27: GroupChange.Actions.modifyAddFromInviteLinkAccess:type_name -> GroupChange.Actions.ModifyAddFromInviteLinkAccessControlAction - 26, // 28: GroupChange.Actions.addRequestingMembers:type_name -> GroupChange.Actions.AddRequestingMemberAction - 27, // 29: GroupChange.Actions.deleteRequestingMembers:type_name -> GroupChange.Actions.DeleteRequestingMemberAction - 28, // 30: GroupChange.Actions.promoteRequestingMembers:type_name -> GroupChange.Actions.PromoteRequestingMemberAction - 38, // 31: GroupChange.Actions.modifyInviteLinkPassword:type_name -> GroupChange.Actions.ModifyInviteLinkPasswordAction - 32, // 32: GroupChange.Actions.modifyDescription:type_name -> GroupChange.Actions.ModifyDescriptionAction - 39, // 33: GroupChange.Actions.modifyAnnouncementsOnly:type_name -> GroupChange.Actions.ModifyAnnouncementsOnlyAction - 29, // 34: GroupChange.Actions.addBannedMembers:type_name -> GroupChange.Actions.AddBannedMemberAction - 30, // 35: GroupChange.Actions.deleteBannedMembers:type_name -> GroupChange.Actions.DeleteBannedMemberAction - 25, // 36: GroupChange.Actions.promotePendingPniAciMembers:type_name -> GroupChange.Actions.PromotePendingPniAciMemberProfileKeyAction - 3, // 37: GroupChange.Actions.AddMemberAction.added:type_name -> Member - 0, // 38: GroupChange.Actions.ModifyMemberRoleAction.role:type_name -> Member.Role - 4, // 39: GroupChange.Actions.AddPendingMemberAction.added:type_name -> PendingMember - 5, // 40: GroupChange.Actions.AddRequestingMemberAction.added:type_name -> RequestingMember - 0, // 41: GroupChange.Actions.PromoteRequestingMemberAction.role:type_name -> Member.Role - 6, // 42: GroupChange.Actions.AddBannedMemberAction.added:type_name -> BannedMember - 1, // 43: GroupChange.Actions.ModifyAttributesAccessControlAction.attributesAccess:type_name -> AccessControl.AccessRequired - 1, // 44: GroupChange.Actions.ModifyMembersAccessControlAction.membersAccess:type_name -> AccessControl.AccessRequired - 1, // 45: GroupChange.Actions.ModifyAddFromInviteLinkAccessControlAction.addFromInviteLinkAccess:type_name -> AccessControl.AccessRequired - 9, // 46: GroupChanges.GroupChangeState.groupChange:type_name -> GroupChange - 8, // 47: GroupChanges.GroupChangeState.groupState:type_name -> Group - 48, // [48:48] is the sub-list for method output_type - 48, // [48:48] is the sub-list for method input_type - 48, // [48:48] is the sub-list for extension type_name - 48, // [48:48] is the sub-list for extension extendee - 0, // [0:48] is the sub-list for field type_name + 0, // 0: signal.Member.role:type_name -> signal.Member.Role + 3, // 1: signal.MemberPendingProfileKey.member:type_name -> signal.Member + 1, // 2: signal.AccessControl.attributes:type_name -> signal.AccessControl.AccessRequired + 1, // 3: signal.AccessControl.members:type_name -> signal.AccessControl.AccessRequired + 1, // 4: signal.AccessControl.addFromInviteLink:type_name -> signal.AccessControl.AccessRequired + 7, // 5: signal.Group.accessControl:type_name -> signal.AccessControl + 3, // 6: signal.Group.members:type_name -> signal.Member + 4, // 7: signal.Group.membersPendingProfileKey:type_name -> signal.MemberPendingProfileKey + 5, // 8: signal.Group.membersPendingAdminApproval:type_name -> signal.MemberPendingAdminApproval + 6, // 9: signal.Group.members_banned:type_name -> signal.MemberBanned + 17, // 10: signal.GroupInviteLink.contentsV1:type_name -> signal.GroupInviteLink.GroupInviteLinkContentsV1 + 1, // 11: signal.GroupJoinInfo.addFromInviteLink:type_name -> signal.AccessControl.AccessRequired + 8, // 12: signal.GroupResponse.group:type_name -> signal.Group + 42, // 13: signal.GroupChanges.groupChanges:type_name -> signal.GroupChanges.GroupChangeState + 12, // 14: signal.GroupChangeResponse.group_change:type_name -> signal.GroupChange + 19, // 15: signal.GroupChange.Actions.addMembers:type_name -> signal.GroupChange.Actions.AddMemberAction + 20, // 16: signal.GroupChange.Actions.deleteMembers:type_name -> signal.GroupChange.Actions.DeleteMemberAction + 21, // 17: signal.GroupChange.Actions.modifyMemberRoles:type_name -> signal.GroupChange.Actions.ModifyMemberRoleAction + 23, // 18: signal.GroupChange.Actions.modifyMemberProfileKeys:type_name -> signal.GroupChange.Actions.ModifyMemberProfileKeyAction + 24, // 19: signal.GroupChange.Actions.addMembersPendingProfileKey:type_name -> signal.GroupChange.Actions.AddMemberPendingProfileKeyAction + 25, // 20: signal.GroupChange.Actions.deleteMembersPendingProfileKey:type_name -> signal.GroupChange.Actions.DeleteMemberPendingProfileKeyAction + 26, // 21: signal.GroupChange.Actions.promoteMembersPendingProfileKey:type_name -> signal.GroupChange.Actions.PromoteMemberPendingProfileKeyAction + 33, // 22: signal.GroupChange.Actions.modifyTitle:type_name -> signal.GroupChange.Actions.ModifyTitleAction + 35, // 23: signal.GroupChange.Actions.modifyAvatar:type_name -> signal.GroupChange.Actions.ModifyAvatarAction + 36, // 24: signal.GroupChange.Actions.modifyDisappearingMessageTimer:type_name -> signal.GroupChange.Actions.ModifyDisappearingMessageTimerAction + 37, // 25: signal.GroupChange.Actions.modifyAttributesAccess:type_name -> signal.GroupChange.Actions.ModifyAttributesAccessControlAction + 38, // 26: signal.GroupChange.Actions.modifyMemberAccess:type_name -> signal.GroupChange.Actions.ModifyMembersAccessControlAction + 39, // 27: signal.GroupChange.Actions.modifyAddFromInviteLinkAccess:type_name -> signal.GroupChange.Actions.ModifyAddFromInviteLinkAccessControlAction + 28, // 28: signal.GroupChange.Actions.addMembersPendingAdminApproval:type_name -> signal.GroupChange.Actions.AddMemberPendingAdminApprovalAction + 29, // 29: signal.GroupChange.Actions.deleteMembersPendingAdminApproval:type_name -> signal.GroupChange.Actions.DeleteMemberPendingAdminApprovalAction + 30, // 30: signal.GroupChange.Actions.promoteMembersPendingAdminApproval:type_name -> signal.GroupChange.Actions.PromoteMemberPendingAdminApprovalAction + 40, // 31: signal.GroupChange.Actions.modifyInviteLinkPassword:type_name -> signal.GroupChange.Actions.ModifyInviteLinkPasswordAction + 34, // 32: signal.GroupChange.Actions.modifyDescription:type_name -> signal.GroupChange.Actions.ModifyDescriptionAction + 41, // 33: signal.GroupChange.Actions.modify_announcements_only:type_name -> signal.GroupChange.Actions.ModifyAnnouncementsOnlyAction + 31, // 34: signal.GroupChange.Actions.add_members_banned:type_name -> signal.GroupChange.Actions.AddMemberBannedAction + 32, // 35: signal.GroupChange.Actions.delete_members_banned:type_name -> signal.GroupChange.Actions.DeleteMemberBannedAction + 27, // 36: signal.GroupChange.Actions.promote_members_pending_pni_aci_profile_key:type_name -> signal.GroupChange.Actions.PromoteMemberPendingPniAciProfileKeyAction + 22, // 37: signal.GroupChange.Actions.modifyMemberLabels:type_name -> signal.GroupChange.Actions.ModifyMemberLabelAction + 3, // 38: signal.GroupChange.Actions.AddMemberAction.added:type_name -> signal.Member + 0, // 39: signal.GroupChange.Actions.ModifyMemberRoleAction.role:type_name -> signal.Member.Role + 4, // 40: signal.GroupChange.Actions.AddMemberPendingProfileKeyAction.added:type_name -> signal.MemberPendingProfileKey + 5, // 41: signal.GroupChange.Actions.AddMemberPendingAdminApprovalAction.added:type_name -> signal.MemberPendingAdminApproval + 0, // 42: signal.GroupChange.Actions.PromoteMemberPendingAdminApprovalAction.role:type_name -> signal.Member.Role + 6, // 43: signal.GroupChange.Actions.AddMemberBannedAction.added:type_name -> signal.MemberBanned + 1, // 44: signal.GroupChange.Actions.ModifyAttributesAccessControlAction.attributesAccess:type_name -> signal.AccessControl.AccessRequired + 1, // 45: signal.GroupChange.Actions.ModifyMembersAccessControlAction.membersAccess:type_name -> signal.AccessControl.AccessRequired + 1, // 46: signal.GroupChange.Actions.ModifyAddFromInviteLinkAccessControlAction.addFromInviteLinkAccess:type_name -> signal.AccessControl.AccessRequired + 12, // 47: signal.GroupChanges.GroupChangeState.groupChange:type_name -> signal.GroupChange + 8, // 48: signal.GroupChanges.GroupChangeState.groupState:type_name -> signal.Group + 49, // [49:49] is the sub-list for method output_type + 49, // [49:49] is the sub-list for method input_type + 49, // [49:49] is the sub-list for extension type_name + 49, // [49:49] is the sub-list for extension extendee + 0, // [0:49] is the sub-list for field type_name } func init() { file_Groups_proto_init() } @@ -2927,14 +3026,14 @@ func file_Groups_proto_init() { if File_Groups_proto != nil { return } - file_Groups_proto_msgTypes[11].OneofWrappers = []any{ + file_Groups_proto_msgTypes[7].OneofWrappers = []any{ (*GroupAttributeBlob_Title)(nil), (*GroupAttributeBlob_Avatar)(nil), (*GroupAttributeBlob_DisappearingMessagesDuration)(nil), - (*GroupAttributeBlob_Description)(nil), + (*GroupAttributeBlob_DescriptionText)(nil), } - file_Groups_proto_msgTypes[12].OneofWrappers = []any{ - (*GroupInviteLink_V1Contents)(nil), + file_Groups_proto_msgTypes[8].OneofWrappers = []any{ + (*GroupInviteLink_ContentsV1)(nil), } type x struct{} out := protoimpl.TypeBuilder{ @@ -2942,7 +3041,7 @@ func file_Groups_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: unsafe.Slice(unsafe.StringData(file_Groups_proto_rawDesc), len(file_Groups_proto_rawDesc)), NumEnums: 2, - NumMessages: 40, + NumMessages: 41, NumExtensions: 0, NumServices: 0, }, diff --git a/pkg/signalmeow/protobuf/Groups.proto b/pkg/signalmeow/protobuf/Groups.proto index e202eb2..448846a 100644 --- a/pkg/signalmeow/protobuf/Groups.proto +++ b/pkg/signalmeow/protobuf/Groups.proto @@ -1,92 +1,137 @@ -/** - * Copyright (C) 2019 Open Whisper Systems - * - * Licensed according to the LICENSE file in this repository. +/* + * Copyright 2020 Signal Messenger, LLC + * SPDX-License-Identifier: AGPL-3.0-only */ + syntax = "proto3"; -option java_package = "org.signal.storageservice.protos.groups"; +package signal; + +option java_package = "org.signal.storageservice.storage.protos.groups"; +option java_outer_classname = "GroupProtos"; option java_multiple_files = true; message AvatarUploadAttributes { - string key = 1; + string key = 1; string credential = 2; - string acl = 3; - string algorithm = 4; - string date = 5; - string policy = 6; - string signature = 7; + string acl = 3; + string algorithm = 4; + string date = 5; + string policy = 6; + string signature = 7; } +// Stored data + message Member { enum Role { - UNKNOWN = 0; - DEFAULT = 1; + UNKNOWN = 0; + DEFAULT = 1; ADMINISTRATOR = 2; } - bytes userId = 1; - Role role = 2; - bytes profileKey = 3; - bytes presentation = 4; // Only set when sending to server - uint32 joinedAtRevision = 5; + bytes userId = 1; + Role role = 2; + bytes profileKey = 3; + bytes presentation = 4; + uint32 joinedAtVersion = 5; + bytes labelEmoji = 6; // decrypts to a UTF-8 string + bytes labelString = 7; // decrypts to a UTF-8 string } -message PendingMember { - Member member = 1; - bytes addedByUserId = 2; - uint64 timestamp = 3; +message MemberPendingProfileKey { + Member member = 1; + bytes addedByUserId = 2; + uint64 timestamp = 3; // ms since epoch } -message RequestingMember { - bytes userId = 1; - bytes profileKey = 2; - bytes presentation = 3; // Only set when sending to server - uint64 timestamp = 4; +message MemberPendingAdminApproval { + bytes userId = 1; + bytes profileKey = 2; + bytes presentation = 3; + uint64 timestamp = 4; // ms since epoch } -message BannedMember { - bytes userId = 1; - uint64 timestamp = 2; +message MemberBanned { + bytes userId = 1; + uint64 timestamp = 2; // ms since epoch } message AccessControl { enum AccessRequired { - UNKNOWN = 0; - ANY = 1; - MEMBER = 2; + UNKNOWN = 0; + ANY = 1; + MEMBER = 2; ADMINISTRATOR = 3; UNSATISFIABLE = 4; } - AccessRequired attributes = 1; - AccessRequired members = 2; + AccessRequired attributes = 1; + AccessRequired members = 2; AccessRequired addFromInviteLink = 3; } message Group { - bytes publicKey = 1; - bytes title = 2; - string avatar = 3; - bytes disappearingMessagesTimer = 4; - AccessControl accessControl = 5; - uint32 revision = 6; - repeated Member members = 7; - repeated PendingMember pendingMembers = 8; - repeated RequestingMember requestingMembers = 9; - bytes inviteLinkPassword = 10; - bytes description = 11; - bool announcementsOnly = 12; - repeated BannedMember bannedMembers = 13; + bytes publicKey = 1; + bytes title = 2; + bytes description = 11; + // The URL for this group's avatar. The content at this URL can be + // decrypted/deserialized into a `GroupAttributeBlob`. + string avatarUrl = 3; + bytes disappearingMessagesTimer = 4; + AccessControl accessControl = 5; + uint32 version = 6; + repeated Member members = 7; + repeated MemberPendingProfileKey membersPendingProfileKey = 8; + repeated MemberPendingAdminApproval membersPendingAdminApproval = 9; + bytes inviteLinkPassword = 10; + bool announcements_only = 12; + repeated MemberBanned members_banned = 13; + // next: 14 } +message GroupAttributeBlob { + oneof content { + string title = 1; + bytes avatar = 2; + uint32 disappearingMessagesDuration = 3; + string descriptionText = 4; + } +} + +message GroupInviteLink { + message GroupInviteLinkContentsV1 { + bytes groupMasterKey = 1; + bytes inviteLinkPassword = 2; + } + + oneof contents { + GroupInviteLinkContentsV1 contentsV1 = 1; + } +} + +message GroupJoinInfo { + bytes publicKey = 1; + bytes title = 2; + bytes description = 8; + string avatar = 3; + uint32 memberCount = 4; + AccessControl.AccessRequired addFromInviteLink = 5; + uint32 version = 6; + bool pendingAdminApproval = 7; + // bool pendingAdminApprovalFull = 9; + // next: 10 +} + +// Deltas + message GroupChange { message Actions { message AddMemberAction { - Member added = 1; - bool joinFromInviteLink = 2; + Member added = 1; + bool joinFromInviteLink = 2; } message DeleteMemberAction { @@ -94,55 +139,61 @@ message GroupChange { } message ModifyMemberRoleAction { - bytes userId = 1; - Member.Role role = 2; + bytes userId = 1; + Member.Role role = 2; + } + + message ModifyMemberLabelAction { + bytes userId = 1; + bytes labelEmoji = 2; // decrypts to a UTF-8 string + bytes labelString = 3; // decrypts to a UTF-8 string } message ModifyMemberProfileKeyAction { - bytes presentation = 1; // Only set when sending to server - bytes user_id = 2; // Only set when receiving from server - bytes profile_key = 3; // Only set when receiving from server + bytes presentation = 1; + bytes user_id = 2; + bytes profile_key = 3; } - message AddPendingMemberAction { - PendingMember added = 1; + message AddMemberPendingProfileKeyAction { + MemberPendingProfileKey added = 1; } - message DeletePendingMemberAction { + message DeleteMemberPendingProfileKeyAction { bytes deletedUserId = 1; } - message PromotePendingMemberAction { - bytes presentation = 1; // Only set when sending to server - bytes user_id = 2; // Only set when receiving from server - bytes profile_key = 3; // Only set when receiving from server + message PromoteMemberPendingProfileKeyAction { + bytes presentation = 1; + bytes user_id = 2; + bytes profile_key = 3; } - message PromotePendingPniAciMemberProfileKeyAction { - bytes presentation = 1; // Only set when sending to server - bytes userId = 2; // Only set when receiving from server - bytes pni = 3; // Only set when receiving from server - bytes profileKey = 4; // Only set when receiving from server + message PromoteMemberPendingPniAciProfileKeyAction { + bytes presentation = 1; + bytes user_id = 2; + bytes pni = 3; + bytes profile_key = 4; } - message AddRequestingMemberAction { - RequestingMember added = 1; + message AddMemberPendingAdminApprovalAction { + MemberPendingAdminApproval added = 1; } - message DeleteRequestingMemberAction { + message DeleteMemberPendingAdminApprovalAction { bytes deletedUserId = 1; } - message PromoteRequestingMemberAction { - bytes userId = 1; - Member.Role role = 2; + message PromoteMemberPendingAdminApprovalAction { + bytes userId = 1; + Member.Role role = 2; } - message AddBannedMemberAction { - BannedMember added = 1; + message AddMemberBannedAction { + MemberBanned added = 1; } - message DeleteBannedMemberAction { + message DeleteMemberBannedAction { bytes deletedUserId = 1; } @@ -158,7 +209,7 @@ message GroupChange { string avatar = 1; } - message ModifyDisappearingMessagesTimerAction { + message ModifyDisappearingMessageTimerAction { bytes timer = 1; } @@ -179,92 +230,70 @@ message GroupChange { } message ModifyAnnouncementsOnlyAction { - bool announcementsOnly = 1; + bool announcements_only = 1; } - bytes sourceServiceId = 1; - bytes groupId = 25; // Only set when receiving from server - uint32 revision = 2; - repeated AddMemberAction addMembers = 3; - repeated DeleteMemberAction deleteMembers = 4; - repeated ModifyMemberRoleAction modifyMemberRoles = 5; - repeated ModifyMemberProfileKeyAction modifyMemberProfileKeys = 6; - repeated AddPendingMemberAction addPendingMembers = 7; - repeated DeletePendingMemberAction deletePendingMembers = 8; - repeated PromotePendingMemberAction promotePendingMembers = 9; - ModifyTitleAction modifyTitle = 10; - ModifyAvatarAction modifyAvatar = 11; - ModifyDisappearingMessagesTimerAction modifyDisappearingMessagesTimer = 12; - ModifyAttributesAccessControlAction modifyAttributesAccess = 13; - ModifyMembersAccessControlAction modifyMemberAccess = 14; - ModifyAddFromInviteLinkAccessControlAction modifyAddFromInviteLinkAccess = 15; - repeated AddRequestingMemberAction addRequestingMembers = 16; - repeated DeleteRequestingMemberAction deleteRequestingMembers = 17; - repeated PromoteRequestingMemberAction promoteRequestingMembers = 18; - ModifyInviteLinkPasswordAction modifyInviteLinkPassword = 19; - ModifyDescriptionAction modifyDescription = 20; - ModifyAnnouncementsOnlyAction modifyAnnouncementsOnly = 21; - repeated AddBannedMemberAction addBannedMembers = 22; - repeated DeleteBannedMemberAction deleteBannedMembers = 23; - repeated PromotePendingPniAciMemberProfileKeyAction promotePendingPniAciMembers = 24; + bytes sourceUserId = 1; + // clients should not provide this value; the server will provide it in the response buffer to ensure the signature is binding to a particular group + // if clients set it during a request the server will respond with 400. + bytes group_id = 25; + uint32 version = 2; + + repeated AddMemberAction addMembers = 3; + repeated DeleteMemberAction deleteMembers = 4; + repeated ModifyMemberRoleAction modifyMemberRoles = 5; + repeated ModifyMemberProfileKeyAction modifyMemberProfileKeys = 6; + repeated AddMemberPendingProfileKeyAction addMembersPendingProfileKey = 7; + repeated DeleteMemberPendingProfileKeyAction deleteMembersPendingProfileKey = 8; + repeated PromoteMemberPendingProfileKeyAction promoteMembersPendingProfileKey = 9; + ModifyTitleAction modifyTitle = 10; + ModifyAvatarAction modifyAvatar = 11; + ModifyDisappearingMessageTimerAction modifyDisappearingMessageTimer = 12; + ModifyAttributesAccessControlAction modifyAttributesAccess = 13; + ModifyMembersAccessControlAction modifyMemberAccess = 14; + ModifyAddFromInviteLinkAccessControlAction modifyAddFromInviteLinkAccess = 15; // change epoch = 1 + repeated AddMemberPendingAdminApprovalAction addMembersPendingAdminApproval = 16; // change epoch = 1 + repeated DeleteMemberPendingAdminApprovalAction deleteMembersPendingAdminApproval = 17; // change epoch = 1 + repeated PromoteMemberPendingAdminApprovalAction promoteMembersPendingAdminApproval = 18; // change epoch = 1 + ModifyInviteLinkPasswordAction modifyInviteLinkPassword = 19; // change epoch = 1 + ModifyDescriptionAction modifyDescription = 20; // change epoch = 2 + ModifyAnnouncementsOnlyAction modify_announcements_only = 21; // change epoch = 3 + repeated AddMemberBannedAction add_members_banned = 22; // change epoch = 4 + repeated DeleteMemberBannedAction delete_members_banned = 23; // change epoch = 4 + repeated PromoteMemberPendingPniAciProfileKeyAction promote_members_pending_pni_aci_profile_key = 24; // change epoch = 5 + repeated ModifyMemberLabelAction modifyMemberLabels = 26; // change epoch = 6; + // next: 27 } - bytes actions = 1; - bytes serverSignature = 2; - uint32 changeEpoch = 3; + bytes actions = 1; + bytes serverSignature = 2; + uint32 changeEpoch = 3; } +// External credentials + +message ExternalGroupCredential { + string token = 1; +} + +// API responses + message GroupResponse { - Group group = 1; - bytes groupSendEndorsementsResponse = 2; + Group group = 1; + bytes group_send_endorsements_response = 2; } message GroupChanges { message GroupChangeState { GroupChange groupChange = 1; - Group groupState = 2; + Group groupState = 2; } - repeated GroupChangeState groupChanges = 1; - bytes groupSendEndorsementsResponse = 2; + repeated GroupChangeState groupChanges = 1; + bytes group_send_endorsements_response = 2; } message GroupChangeResponse { - GroupChange groupChange = 1; - bytes groupSendEndorsementsResponse = 2; -} - -message GroupAttributeBlob { - oneof content { - string title = 1; - bytes avatar = 2; - uint32 disappearingMessagesDuration = 3; - string description = 4; - } -} - -message GroupInviteLink { - message GroupInviteLinkContentsV1 { - bytes groupMasterKey = 1; - bytes inviteLinkPassword = 2; - } - - oneof contents { - GroupInviteLinkContentsV1 v1Contents = 1; - } -} - -message GroupJoinInfo { - bytes publicKey = 1; - bytes title = 2; - string avatar = 3; - uint32 memberCount = 4; - AccessControl.AccessRequired addFromInviteLink = 5; - uint32 revision = 6; - bool pendingAdminApproval = 7; - bytes description = 8; -} - -message GroupExternalCredential { - string token = 1; + GroupChange group_change = 1; + bytes group_send_endorsements_response = 2; } diff --git a/pkg/signalmeow/protobuf/Provisioning.pb.go b/pkg/signalmeow/protobuf/Provisioning.pb.go index d2f0a4d..0231512 100644 --- a/pkg/signalmeow/protobuf/Provisioning.pb.go +++ b/pkg/signalmeow/protobuf/Provisioning.pb.go @@ -4,8 +4,8 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.36.10 -// protoc v3.21.12 +// protoc-gen-go v1.36.11 +// protoc v6.33.5 // source: Provisioning.proto package signalpb diff --git a/pkg/signalmeow/protobuf/SignalService.pb.go b/pkg/signalmeow/protobuf/SignalService.pb.go index ae5bd18..5866dbb 100644 --- a/pkg/signalmeow/protobuf/SignalService.pb.go +++ b/pkg/signalmeow/protobuf/SignalService.pb.go @@ -4,8 +4,8 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.36.10 -// protoc v3.21.12 +// protoc-gen-go v1.36.11 +// protoc v6.33.5 // source: SignalService.proto package signalpb @@ -347,7 +347,7 @@ const ( DataMessage_MENTIONS DataMessage_ProtocolVersion = 6 DataMessage_PAYMENTS DataMessage_ProtocolVersion = 7 DataMessage_POLLS DataMessage_ProtocolVersion = 8 - DataMessage_CURRENT DataMessage_ProtocolVersion = 7 + DataMessage_CURRENT DataMessage_ProtocolVersion = 8 ) // Enum value maps for DataMessage_ProtocolVersion. @@ -362,7 +362,7 @@ var ( 6: "MENTIONS", 7: "PAYMENTS", 8: "POLLS", - // Duplicate value: 7: "CURRENT", + // Duplicate value: 8: "CURRENT", } DataMessage_ProtocolVersion_value = map[string]int32{ "INITIAL": 0, @@ -374,7 +374,7 @@ var ( "MENTIONS": 6, "PAYMENTS": 7, "POLLS": 8, - "CURRENT": 7, + "CURRENT": 8, } ) @@ -1750,22 +1750,26 @@ func (BodyRange_Style) EnumDescriptor() ([]byte, []int) { } type Envelope struct { - state protoimpl.MessageState `protogen:"open.v1"` - Type *Envelope_Type `protobuf:"varint,1,opt,name=type,enum=signalservice.Envelope_Type" json:"type,omitempty"` - SourceServiceId *string `protobuf:"bytes,11,opt,name=sourceServiceId" json:"sourceServiceId,omitempty"` - SourceDevice *uint32 `protobuf:"varint,7,opt,name=sourceDevice" json:"sourceDevice,omitempty"` - DestinationServiceId *string `protobuf:"bytes,13,opt,name=destinationServiceId" json:"destinationServiceId,omitempty"` - Timestamp *uint64 `protobuf:"varint,5,opt,name=timestamp" json:"timestamp,omitempty"` - Content []byte `protobuf:"bytes,8,opt,name=content" json:"content,omitempty"` // Contains an encrypted Content - ServerGuid *string `protobuf:"bytes,9,opt,name=serverGuid" json:"serverGuid,omitempty"` - ServerTimestamp *uint64 `protobuf:"varint,10,opt,name=serverTimestamp" json:"serverTimestamp,omitempty"` - Ephemeral *bool `protobuf:"varint,12,opt,name=ephemeral" json:"ephemeral,omitempty"` // indicates that the message should not be persisted if the recipient is offline - Urgent *bool `protobuf:"varint,14,opt,name=urgent,def=1" json:"urgent,omitempty"` // indicates that the content is considered timely by the sender; defaults to true so senders have to opt-out to say something isn't time critical - UpdatedPni *string `protobuf:"bytes,15,opt,name=updatedPni" json:"updatedPni,omitempty"` // for number-change synchronization messages, provides the new server-assigned phone number identifier associated with the changed number - Story *bool `protobuf:"varint,16,opt,name=story" json:"story,omitempty"` // indicates that the content is a story. - ReportSpamToken []byte `protobuf:"bytes,17,opt,name=report_spam_token,json=reportSpamToken" json:"report_spam_token,omitempty"` // token sent when reporting spam - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` + Type *Envelope_Type `protobuf:"varint,1,opt,name=type,enum=signalservice.Envelope_Type" json:"type,omitempty"` + SourceServiceId *string `protobuf:"bytes,11,opt,name=sourceServiceId" json:"sourceServiceId,omitempty"` + SourceDevice *uint32 `protobuf:"varint,7,opt,name=sourceDevice" json:"sourceDevice,omitempty"` + DestinationServiceId *string `protobuf:"bytes,13,opt,name=destinationServiceId" json:"destinationServiceId,omitempty"` + Timestamp *uint64 `protobuf:"varint,5,opt,name=timestamp" json:"timestamp,omitempty"` + Content []byte `protobuf:"bytes,8,opt,name=content" json:"content,omitempty"` // Contains an encrypted Content + ServerGuid *string `protobuf:"bytes,9,opt,name=serverGuid" json:"serverGuid,omitempty"` + ServerTimestamp *uint64 `protobuf:"varint,10,opt,name=serverTimestamp" json:"serverTimestamp,omitempty"` + Ephemeral *bool `protobuf:"varint,12,opt,name=ephemeral" json:"ephemeral,omitempty"` // indicates that the message should not be persisted if the recipient is offline + Urgent *bool `protobuf:"varint,14,opt,name=urgent,def=1" json:"urgent,omitempty"` // indicates that the content is considered timely by the sender; defaults to true so senders have to opt-out to say something isn't time critical + UpdatedPni *string `protobuf:"bytes,15,opt,name=updatedPni" json:"updatedPni,omitempty"` // for number-change synchronization messages, provides the new server-assigned phone number identifier associated with the changed number + Story *bool `protobuf:"varint,16,opt,name=story" json:"story,omitempty"` // indicates that the content is a story. + ReportSpamToken []byte `protobuf:"bytes,17,opt,name=report_spam_token,json=reportSpamToken" json:"report_spam_token,omitempty"` // token sent when reporting spam + SourceServiceIdBinary []byte `protobuf:"bytes,19,opt,name=sourceServiceIdBinary" json:"sourceServiceIdBinary,omitempty"` // service ID binary (i.e. 16 byte UUID for ACI, 1 byte prefix + 16 byte UUID for PNI) + DestinationServiceIdBinary []byte `protobuf:"bytes,20,opt,name=destinationServiceIdBinary" json:"destinationServiceIdBinary,omitempty"` // service ID binary (i.e. 16 byte UUID for ACI, 1 byte prefix + 16 byte UUID for PNI) + ServerGuidBinary []byte `protobuf:"bytes,21,opt,name=serverGuidBinary" json:"serverGuidBinary,omitempty"` // 16-byte UUID + UpdatedPniBinary []byte `protobuf:"bytes,22,opt,name=updatedPniBinary" json:"updatedPniBinary,omitempty"` // 16-byte UUID + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } // Default values for Envelope fields. @@ -1894,6 +1898,34 @@ func (x *Envelope) GetReportSpamToken() []byte { return nil } +func (x *Envelope) GetSourceServiceIdBinary() []byte { + if x != nil { + return x.SourceServiceIdBinary + } + return nil +} + +func (x *Envelope) GetDestinationServiceIdBinary() []byte { + if x != nil { + return x.DestinationServiceIdBinary + } + return nil +} + +func (x *Envelope) GetServerGuidBinary() []byte { + if x != nil { + return x.ServerGuidBinary + } + return nil +} + +func (x *Envelope) GetUpdatedPniBinary() []byte { + if x != nil { + return x.UpdatedPniBinary + } + return nil +} + type Content struct { state protoimpl.MessageState `protogen:"open.v1"` DataMessage *DataMessage `protobuf:"bytes,1,opt,name=dataMessage" json:"dataMessage,omitempty"` @@ -2135,7 +2167,9 @@ type DataMessage struct { GiftBadge *DataMessage_GiftBadge `protobuf:"bytes,22,opt,name=giftBadge" json:"giftBadge,omitempty"` PollCreate *DataMessage_PollCreate `protobuf:"bytes,24,opt,name=pollCreate" json:"pollCreate,omitempty"` PollTerminate *DataMessage_PollTerminate `protobuf:"bytes,25,opt,name=pollTerminate" json:"pollTerminate,omitempty"` - PollVote *DataMessage_PollVote `protobuf:"bytes,26,opt,name=pollVote" json:"pollVote,omitempty"` // NEXT ID: 27 + PollVote *DataMessage_PollVote `protobuf:"bytes,26,opt,name=pollVote" json:"pollVote,omitempty"` + PinMessage *DataMessage_PinMessage `protobuf:"bytes,27,opt,name=pinMessage" json:"pinMessage,omitempty"` + UnpinMessage *DataMessage_UnpinMessage `protobuf:"bytes,28,opt,name=unpinMessage" json:"unpinMessage,omitempty"` // NEXT ID: 29 unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } @@ -2338,6 +2372,20 @@ func (x *DataMessage) GetPollVote() *DataMessage_PollVote { return nil } +func (x *DataMessage) GetPinMessage() *DataMessage_PinMessage { + if x != nil { + return x.PinMessage + } + return nil +} + +func (x *DataMessage) GetUnpinMessage() *DataMessage_UnpinMessage { + if x != nil { + return x.UnpinMessage + } + return nil +} + type NullMessage struct { state protoimpl.MessageState `protogen:"open.v1"` Padding []byte `protobuf:"bytes,1,opt,name=padding" json:"padding,omitempty"` @@ -2807,13 +2855,14 @@ func (*TextAttachment_Gradient_) isTextAttachment_Background() {} func (*TextAttachment_Color) isTextAttachment_Background() {} type Verified struct { - state protoimpl.MessageState `protogen:"open.v1"` - DestinationAci *string `protobuf:"bytes,5,opt,name=destinationAci" json:"destinationAci,omitempty"` - IdentityKey []byte `protobuf:"bytes,2,opt,name=identityKey" json:"identityKey,omitempty"` - State *Verified_State `protobuf:"varint,3,opt,name=state,enum=signalservice.Verified_State" json:"state,omitempty"` - NullMessage []byte `protobuf:"bytes,4,opt,name=nullMessage" json:"nullMessage,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` + DestinationAci *string `protobuf:"bytes,5,opt,name=destinationAci" json:"destinationAci,omitempty"` + IdentityKey []byte `protobuf:"bytes,2,opt,name=identityKey" json:"identityKey,omitempty"` + State *Verified_State `protobuf:"varint,3,opt,name=state,enum=signalservice.Verified_State" json:"state,omitempty"` + NullMessage []byte `protobuf:"bytes,4,opt,name=nullMessage" json:"nullMessage,omitempty"` + DestinationAciBinary []byte `protobuf:"bytes,6,opt,name=destinationAciBinary" json:"destinationAciBinary,omitempty"` // 16-byte UUID + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } func (x *Verified) Reset() { @@ -2874,6 +2923,13 @@ func (x *Verified) GetNullMessage() []byte { return nil } +func (x *Verified) GetDestinationAciBinary() []byte { + if x != nil { + return x.DestinationAciBinary + } + return nil +} + type SyncMessage struct { state protoimpl.MessageState `protogen:"open.v1"` Sent *SyncMessage_Sent `protobuf:"bytes,1,opt,name=sent" json:"sent,omitempty"` @@ -3370,6 +3426,7 @@ type ContactDetails struct { state protoimpl.MessageState `protogen:"open.v1"` Number *string `protobuf:"bytes,1,opt,name=number" json:"number,omitempty"` Aci *string `protobuf:"bytes,9,opt,name=aci" json:"aci,omitempty"` + AciBinary []byte `protobuf:"bytes,13,opt,name=aciBinary" json:"aciBinary,omitempty"` // 16-byte UUID Name *string `protobuf:"bytes,2,opt,name=name" json:"name,omitempty"` Avatar *ContactDetails_Avatar `protobuf:"bytes,3,opt,name=avatar" json:"avatar,omitempty"` ExpireTimer *uint32 `protobuf:"varint,8,opt,name=expireTimer" json:"expireTimer,omitempty"` @@ -3423,6 +3480,13 @@ func (x *ContactDetails) GetAci() string { return "" } +func (x *ContactDetails) GetAciBinary() []byte { + if x != nil { + return x.AciBinary + } + return nil +} + func (x *ContactDetails) GetName() string { if x != nil && x.Name != nil { return *x.Name @@ -3697,6 +3761,7 @@ type BodyRange struct { // // *BodyRange_MentionAci // *BodyRange_Style_ + // *BodyRange_MentionAciBinary AssociatedValue isBodyRange_AssociatedValue `protobuf_oneof:"associatedValue"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache @@ -3771,6 +3836,15 @@ func (x *BodyRange) GetStyle() BodyRange_Style { return BodyRange_NONE } +func (x *BodyRange) GetMentionAciBinary() []byte { + if x != nil { + if x, ok := x.AssociatedValue.(*BodyRange_MentionAciBinary); ok { + return x.MentionAciBinary + } + } + return nil +} + type isBodyRange_AssociatedValue interface { isBodyRange_AssociatedValue() } @@ -3783,16 +3857,23 @@ type BodyRange_Style_ struct { Style BodyRange_Style `protobuf:"varint,4,opt,name=style,enum=signalservice.BodyRange_Style,oneof"` } +type BodyRange_MentionAciBinary struct { + MentionAciBinary []byte `protobuf:"bytes,5,opt,name=mentionAciBinary,oneof"` // 16-byte UUID +} + func (*BodyRange_MentionAci) isBodyRange_AssociatedValue() {} func (*BodyRange_Style_) isBodyRange_AssociatedValue() {} +func (*BodyRange_MentionAciBinary) isBodyRange_AssociatedValue() {} + type AddressableMessage struct { state protoimpl.MessageState `protogen:"open.v1"` // Types that are valid to be assigned to Author: // // *AddressableMessage_AuthorServiceId // *AddressableMessage_AuthorE164 + // *AddressableMessage_AuthorServiceIdBinary Author isAddressableMessage_Author `protobuf_oneof:"author"` SentTimestamp *uint64 `protobuf:"varint,3,opt,name=sentTimestamp" json:"sentTimestamp,omitempty"` unknownFields protoimpl.UnknownFields @@ -3854,6 +3935,15 @@ func (x *AddressableMessage) GetAuthorE164() string { return "" } +func (x *AddressableMessage) GetAuthorServiceIdBinary() []byte { + if x != nil { + if x, ok := x.Author.(*AddressableMessage_AuthorServiceIdBinary); ok { + return x.AuthorServiceIdBinary + } + } + return nil +} + func (x *AddressableMessage) GetSentTimestamp() uint64 { if x != nil && x.SentTimestamp != nil { return *x.SentTimestamp @@ -3873,10 +3963,16 @@ type AddressableMessage_AuthorE164 struct { AuthorE164 string `protobuf:"bytes,2,opt,name=authorE164,oneof"` } +type AddressableMessage_AuthorServiceIdBinary struct { + AuthorServiceIdBinary []byte `protobuf:"bytes,4,opt,name=authorServiceIdBinary,oneof"` // service ID binary (i.e. 16 byte UUID for ACI, 1 byte prefix + 16 byte UUID for PNI) +} + func (*AddressableMessage_AuthorServiceId) isAddressableMessage_Author() {} func (*AddressableMessage_AuthorE164) isAddressableMessage_Author() {} +func (*AddressableMessage_AuthorServiceIdBinary) isAddressableMessage_Author() {} + type ConversationIdentifier struct { state protoimpl.MessageState `protogen:"open.v1"` // Types that are valid to be assigned to Identifier: @@ -3884,6 +3980,7 @@ type ConversationIdentifier struct { // *ConversationIdentifier_ThreadServiceId // *ConversationIdentifier_ThreadGroupId // *ConversationIdentifier_ThreadE164 + // *ConversationIdentifier_ThreadServiceIdBinary Identifier isConversationIdentifier_Identifier `protobuf_oneof:"identifier"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache @@ -3953,6 +4050,15 @@ func (x *ConversationIdentifier) GetThreadE164() string { return "" } +func (x *ConversationIdentifier) GetThreadServiceIdBinary() []byte { + if x != nil { + if x, ok := x.Identifier.(*ConversationIdentifier_ThreadServiceIdBinary); ok { + return x.ThreadServiceIdBinary + } + } + return nil +} + type isConversationIdentifier_Identifier interface { isConversationIdentifier_Identifier() } @@ -3969,12 +4075,18 @@ type ConversationIdentifier_ThreadE164 struct { ThreadE164 string `protobuf:"bytes,3,opt,name=threadE164,oneof"` } +type ConversationIdentifier_ThreadServiceIdBinary struct { + ThreadServiceIdBinary []byte `protobuf:"bytes,4,opt,name=threadServiceIdBinary,oneof"` // service ID binary (i.e. 16 byte UUID for ACI, 1 byte prefix + 16 byte UUID for PNI) +} + func (*ConversationIdentifier_ThreadServiceId) isConversationIdentifier_Identifier() {} func (*ConversationIdentifier_ThreadGroupId) isConversationIdentifier_Identifier() {} func (*ConversationIdentifier_ThreadE164) isConversationIdentifier_Identifier() {} +func (*ConversationIdentifier_ThreadServiceIdBinary) isConversationIdentifier_Identifier() {} + type CallMessage_Offer struct { state protoimpl.MessageState `protogen:"open.v1"` Id *uint64 `protobuf:"varint,1,opt,name=id" json:"id,omitempty"` @@ -4378,15 +4490,16 @@ func (*DataMessage_Payment_Notification_) isDataMessage_Payment_Item() {} func (*DataMessage_Payment_Activation_) isDataMessage_Payment_Item() {} type DataMessage_Quote struct { - state protoimpl.MessageState `protogen:"open.v1"` - Id *uint64 `protobuf:"varint,1,opt,name=id" json:"id,omitempty"` - AuthorAci *string `protobuf:"bytes,5,opt,name=authorAci" json:"authorAci,omitempty"` - Text *string `protobuf:"bytes,3,opt,name=text" json:"text,omitempty"` - Attachments []*DataMessage_Quote_QuotedAttachment `protobuf:"bytes,4,rep,name=attachments" json:"attachments,omitempty"` - BodyRanges []*BodyRange `protobuf:"bytes,6,rep,name=bodyRanges" json:"bodyRanges,omitempty"` - Type *DataMessage_Quote_Type `protobuf:"varint,7,opt,name=type,enum=signalservice.DataMessage_Quote_Type" json:"type,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` + Id *uint64 `protobuf:"varint,1,opt,name=id" json:"id,omitempty"` + AuthorAci *string `protobuf:"bytes,5,opt,name=authorAci" json:"authorAci,omitempty"` + Text *string `protobuf:"bytes,3,opt,name=text" json:"text,omitempty"` + Attachments []*DataMessage_Quote_QuotedAttachment `protobuf:"bytes,4,rep,name=attachments" json:"attachments,omitempty"` + BodyRanges []*BodyRange `protobuf:"bytes,6,rep,name=bodyRanges" json:"bodyRanges,omitempty"` + Type *DataMessage_Quote_Type `protobuf:"varint,7,opt,name=type,enum=signalservice.DataMessage_Quote_Type" json:"type,omitempty"` + AuthorAciBinary []byte `protobuf:"bytes,8,opt,name=authorAciBinary" json:"authorAciBinary,omitempty"` // 16-byte UUID + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } func (x *DataMessage_Quote) Reset() { @@ -4461,6 +4574,13 @@ func (x *DataMessage_Quote) GetType() DataMessage_Quote_Type { return DataMessage_Quote_NORMAL } +func (x *DataMessage_Quote) GetAuthorAciBinary() []byte { + if x != nil { + return x.AuthorAciBinary + } + return nil +} + type DataMessage_Contact struct { state protoimpl.MessageState `protogen:"open.v1"` Name *DataMessage_Contact_Name `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"` @@ -4622,13 +4742,14 @@ func (x *DataMessage_Sticker) GetEmoji() string { } type DataMessage_Reaction struct { - state protoimpl.MessageState `protogen:"open.v1"` - Emoji *string `protobuf:"bytes,1,opt,name=emoji" json:"emoji,omitempty"` - Remove *bool `protobuf:"varint,2,opt,name=remove" json:"remove,omitempty"` - TargetAuthorAci *string `protobuf:"bytes,4,opt,name=targetAuthorAci" json:"targetAuthorAci,omitempty"` - TargetSentTimestamp *uint64 `protobuf:"varint,5,opt,name=targetSentTimestamp" json:"targetSentTimestamp,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` + Emoji *string `protobuf:"bytes,1,opt,name=emoji" json:"emoji,omitempty"` + Remove *bool `protobuf:"varint,2,opt,name=remove" json:"remove,omitempty"` + TargetAuthorAci *string `protobuf:"bytes,4,opt,name=targetAuthorAci" json:"targetAuthorAci,omitempty"` + TargetSentTimestamp *uint64 `protobuf:"varint,5,opt,name=targetSentTimestamp" json:"targetSentTimestamp,omitempty"` + TargetAuthorAciBinary []byte `protobuf:"bytes,6,opt,name=targetAuthorAciBinary" json:"targetAuthorAciBinary,omitempty"` // 16-byte UUID + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } func (x *DataMessage_Reaction) Reset() { @@ -4689,6 +4810,13 @@ func (x *DataMessage_Reaction) GetTargetSentTimestamp() uint64 { return 0 } +func (x *DataMessage_Reaction) GetTargetAuthorAciBinary() []byte { + if x != nil { + return x.TargetAuthorAciBinary + } + return nil +} + type DataMessage_Delete struct { state protoimpl.MessageState `protogen:"open.v1"` TargetSentTimestamp *uint64 `protobuf:"varint,1,opt,name=targetSentTimestamp" json:"targetSentTimestamp,omitempty"` @@ -4778,11 +4906,12 @@ func (x *DataMessage_GroupCallUpdate) GetEraId() string { } type DataMessage_StoryContext struct { - state protoimpl.MessageState `protogen:"open.v1"` - AuthorAci *string `protobuf:"bytes,1,opt,name=authorAci" json:"authorAci,omitempty"` - SentTimestamp *uint64 `protobuf:"varint,2,opt,name=sentTimestamp" json:"sentTimestamp,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` + AuthorAci *string `protobuf:"bytes,1,opt,name=authorAci" json:"authorAci,omitempty"` + SentTimestamp *uint64 `protobuf:"varint,2,opt,name=sentTimestamp" json:"sentTimestamp,omitempty"` + AuthorAciBinary []byte `protobuf:"bytes,3,opt,name=authorAciBinary" json:"authorAciBinary,omitempty"` // 16-byte UUID + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } func (x *DataMessage_StoryContext) Reset() { @@ -4829,6 +4958,13 @@ func (x *DataMessage_StoryContext) GetSentTimestamp() uint64 { return 0 } +func (x *DataMessage_StoryContext) GetAuthorAciBinary() []byte { + if x != nil { + return x.AuthorAciBinary + } + return nil +} + type DataMessage_GiftBadge struct { state protoimpl.MessageState `protogen:"open.v1"` ReceiptCredentialPresentation []byte `protobuf:"bytes,1,opt,name=receiptCredentialPresentation" json:"receiptCredentialPresentation,omitempty"` @@ -5045,6 +5181,156 @@ func (x *DataMessage_PollVote) GetVoteCount() uint32 { return 0 } +type DataMessage_PinMessage struct { + state protoimpl.MessageState `protogen:"open.v1"` + TargetAuthorAciBinary []byte `protobuf:"bytes,1,opt,name=targetAuthorAciBinary" json:"targetAuthorAciBinary,omitempty"` // 16-byte UUID + TargetSentTimestamp *uint64 `protobuf:"varint,2,opt,name=targetSentTimestamp" json:"targetSentTimestamp,omitempty"` + // Types that are valid to be assigned to PinDuration: + // + // *DataMessage_PinMessage_PinDurationSeconds + // *DataMessage_PinMessage_PinDurationForever + PinDuration isDataMessage_PinMessage_PinDuration `protobuf_oneof:"pinDuration"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *DataMessage_PinMessage) Reset() { + *x = DataMessage_PinMessage{} + mi := &file_SignalService_proto_msgTypes[40] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *DataMessage_PinMessage) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*DataMessage_PinMessage) ProtoMessage() {} + +func (x *DataMessage_PinMessage) ProtoReflect() protoreflect.Message { + mi := &file_SignalService_proto_msgTypes[40] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use DataMessage_PinMessage.ProtoReflect.Descriptor instead. +func (*DataMessage_PinMessage) Descriptor() ([]byte, []int) { + return file_SignalService_proto_rawDescGZIP(), []int{3, 12} +} + +func (x *DataMessage_PinMessage) GetTargetAuthorAciBinary() []byte { + if x != nil { + return x.TargetAuthorAciBinary + } + return nil +} + +func (x *DataMessage_PinMessage) GetTargetSentTimestamp() uint64 { + if x != nil && x.TargetSentTimestamp != nil { + return *x.TargetSentTimestamp + } + return 0 +} + +func (x *DataMessage_PinMessage) GetPinDuration() isDataMessage_PinMessage_PinDuration { + if x != nil { + return x.PinDuration + } + return nil +} + +func (x *DataMessage_PinMessage) GetPinDurationSeconds() uint32 { + if x != nil { + if x, ok := x.PinDuration.(*DataMessage_PinMessage_PinDurationSeconds); ok { + return x.PinDurationSeconds + } + } + return 0 +} + +func (x *DataMessage_PinMessage) GetPinDurationForever() bool { + if x != nil { + if x, ok := x.PinDuration.(*DataMessage_PinMessage_PinDurationForever); ok { + return x.PinDurationForever + } + } + return false +} + +type isDataMessage_PinMessage_PinDuration interface { + isDataMessage_PinMessage_PinDuration() +} + +type DataMessage_PinMessage_PinDurationSeconds struct { + PinDurationSeconds uint32 `protobuf:"varint,3,opt,name=pinDurationSeconds,oneof"` +} + +type DataMessage_PinMessage_PinDurationForever struct { + PinDurationForever bool `protobuf:"varint,4,opt,name=pinDurationForever,oneof"` +} + +func (*DataMessage_PinMessage_PinDurationSeconds) isDataMessage_PinMessage_PinDuration() {} + +func (*DataMessage_PinMessage_PinDurationForever) isDataMessage_PinMessage_PinDuration() {} + +type DataMessage_UnpinMessage struct { + state protoimpl.MessageState `protogen:"open.v1"` + TargetAuthorAciBinary []byte `protobuf:"bytes,1,opt,name=targetAuthorAciBinary" json:"targetAuthorAciBinary,omitempty"` // 16-byte UUID + TargetSentTimestamp *uint64 `protobuf:"varint,2,opt,name=targetSentTimestamp" json:"targetSentTimestamp,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *DataMessage_UnpinMessage) Reset() { + *x = DataMessage_UnpinMessage{} + mi := &file_SignalService_proto_msgTypes[41] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *DataMessage_UnpinMessage) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*DataMessage_UnpinMessage) ProtoMessage() {} + +func (x *DataMessage_UnpinMessage) ProtoReflect() protoreflect.Message { + mi := &file_SignalService_proto_msgTypes[41] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use DataMessage_UnpinMessage.ProtoReflect.Descriptor instead. +func (*DataMessage_UnpinMessage) Descriptor() ([]byte, []int) { + return file_SignalService_proto_rawDescGZIP(), []int{3, 13} +} + +func (x *DataMessage_UnpinMessage) GetTargetAuthorAciBinary() []byte { + if x != nil { + return x.TargetAuthorAciBinary + } + return nil +} + +func (x *DataMessage_UnpinMessage) GetTargetSentTimestamp() uint64 { + if x != nil && x.TargetSentTimestamp != nil { + return *x.TargetSentTimestamp + } + return 0 +} + type DataMessage_Payment_Amount struct { state protoimpl.MessageState `protogen:"open.v1"` // Types that are valid to be assigned to Amount: @@ -5057,7 +5343,7 @@ type DataMessage_Payment_Amount struct { func (x *DataMessage_Payment_Amount) Reset() { *x = DataMessage_Payment_Amount{} - mi := &file_SignalService_proto_msgTypes[40] + mi := &file_SignalService_proto_msgTypes[42] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5069,7 +5355,7 @@ func (x *DataMessage_Payment_Amount) String() string { func (*DataMessage_Payment_Amount) ProtoMessage() {} func (x *DataMessage_Payment_Amount) ProtoReflect() protoreflect.Message { - mi := &file_SignalService_proto_msgTypes[40] + mi := &file_SignalService_proto_msgTypes[42] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5125,7 +5411,7 @@ type DataMessage_Payment_Notification struct { func (x *DataMessage_Payment_Notification) Reset() { *x = DataMessage_Payment_Notification{} - mi := &file_SignalService_proto_msgTypes[41] + mi := &file_SignalService_proto_msgTypes[43] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5137,7 +5423,7 @@ func (x *DataMessage_Payment_Notification) String() string { func (*DataMessage_Payment_Notification) ProtoMessage() {} func (x *DataMessage_Payment_Notification) ProtoReflect() protoreflect.Message { - mi := &file_SignalService_proto_msgTypes[41] + mi := &file_SignalService_proto_msgTypes[43] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5196,7 +5482,7 @@ type DataMessage_Payment_Activation struct { func (x *DataMessage_Payment_Activation) Reset() { *x = DataMessage_Payment_Activation{} - mi := &file_SignalService_proto_msgTypes[42] + mi := &file_SignalService_proto_msgTypes[44] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5208,7 +5494,7 @@ func (x *DataMessage_Payment_Activation) String() string { func (*DataMessage_Payment_Activation) ProtoMessage() {} func (x *DataMessage_Payment_Activation) ProtoReflect() protoreflect.Message { - mi := &file_SignalService_proto_msgTypes[42] + mi := &file_SignalService_proto_msgTypes[44] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5240,7 +5526,7 @@ type DataMessage_Payment_Amount_MobileCoin struct { func (x *DataMessage_Payment_Amount_MobileCoin) Reset() { *x = DataMessage_Payment_Amount_MobileCoin{} - mi := &file_SignalService_proto_msgTypes[43] + mi := &file_SignalService_proto_msgTypes[45] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5252,7 +5538,7 @@ func (x *DataMessage_Payment_Amount_MobileCoin) String() string { func (*DataMessage_Payment_Amount_MobileCoin) ProtoMessage() {} func (x *DataMessage_Payment_Amount_MobileCoin) ProtoReflect() protoreflect.Message { - mi := &file_SignalService_proto_msgTypes[43] + mi := &file_SignalService_proto_msgTypes[45] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5284,7 +5570,7 @@ type DataMessage_Payment_Notification_MobileCoin struct { func (x *DataMessage_Payment_Notification_MobileCoin) Reset() { *x = DataMessage_Payment_Notification_MobileCoin{} - mi := &file_SignalService_proto_msgTypes[44] + mi := &file_SignalService_proto_msgTypes[46] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5296,7 +5582,7 @@ func (x *DataMessage_Payment_Notification_MobileCoin) String() string { func (*DataMessage_Payment_Notification_MobileCoin) ProtoMessage() {} func (x *DataMessage_Payment_Notification_MobileCoin) ProtoReflect() protoreflect.Message { - mi := &file_SignalService_proto_msgTypes[44] + mi := &file_SignalService_proto_msgTypes[46] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5330,7 +5616,7 @@ type DataMessage_Quote_QuotedAttachment struct { func (x *DataMessage_Quote_QuotedAttachment) Reset() { *x = DataMessage_Quote_QuotedAttachment{} - mi := &file_SignalService_proto_msgTypes[45] + mi := &file_SignalService_proto_msgTypes[47] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5342,7 +5628,7 @@ func (x *DataMessage_Quote_QuotedAttachment) String() string { func (*DataMessage_Quote_QuotedAttachment) ProtoMessage() {} func (x *DataMessage_Quote_QuotedAttachment) ProtoReflect() protoreflect.Message { - mi := &file_SignalService_proto_msgTypes[45] + mi := &file_SignalService_proto_msgTypes[47] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5393,7 +5679,7 @@ type DataMessage_Contact_Name struct { func (x *DataMessage_Contact_Name) Reset() { *x = DataMessage_Contact_Name{} - mi := &file_SignalService_proto_msgTypes[46] + mi := &file_SignalService_proto_msgTypes[48] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5405,7 +5691,7 @@ func (x *DataMessage_Contact_Name) String() string { func (*DataMessage_Contact_Name) ProtoMessage() {} func (x *DataMessage_Contact_Name) ProtoReflect() protoreflect.Message { - mi := &file_SignalService_proto_msgTypes[46] + mi := &file_SignalService_proto_msgTypes[48] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5474,7 +5760,7 @@ type DataMessage_Contact_Phone struct { func (x *DataMessage_Contact_Phone) Reset() { *x = DataMessage_Contact_Phone{} - mi := &file_SignalService_proto_msgTypes[47] + mi := &file_SignalService_proto_msgTypes[49] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5486,7 +5772,7 @@ func (x *DataMessage_Contact_Phone) String() string { func (*DataMessage_Contact_Phone) ProtoMessage() {} func (x *DataMessage_Contact_Phone) ProtoReflect() protoreflect.Message { - mi := &file_SignalService_proto_msgTypes[47] + mi := &file_SignalService_proto_msgTypes[49] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5534,7 +5820,7 @@ type DataMessage_Contact_Email struct { func (x *DataMessage_Contact_Email) Reset() { *x = DataMessage_Contact_Email{} - mi := &file_SignalService_proto_msgTypes[48] + mi := &file_SignalService_proto_msgTypes[50] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5546,7 +5832,7 @@ func (x *DataMessage_Contact_Email) String() string { func (*DataMessage_Contact_Email) ProtoMessage() {} func (x *DataMessage_Contact_Email) ProtoReflect() protoreflect.Message { - mi := &file_SignalService_proto_msgTypes[48] + mi := &file_SignalService_proto_msgTypes[50] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5600,7 +5886,7 @@ type DataMessage_Contact_PostalAddress struct { func (x *DataMessage_Contact_PostalAddress) Reset() { *x = DataMessage_Contact_PostalAddress{} - mi := &file_SignalService_proto_msgTypes[49] + mi := &file_SignalService_proto_msgTypes[51] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5612,7 +5898,7 @@ func (x *DataMessage_Contact_PostalAddress) String() string { func (*DataMessage_Contact_PostalAddress) ProtoMessage() {} func (x *DataMessage_Contact_PostalAddress) ProtoReflect() protoreflect.Message { - mi := &file_SignalService_proto_msgTypes[49] + mi := &file_SignalService_proto_msgTypes[51] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5701,7 +5987,7 @@ type DataMessage_Contact_Avatar struct { func (x *DataMessage_Contact_Avatar) Reset() { *x = DataMessage_Contact_Avatar{} - mi := &file_SignalService_proto_msgTypes[50] + mi := &file_SignalService_proto_msgTypes[52] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5713,7 +5999,7 @@ func (x *DataMessage_Contact_Avatar) String() string { func (*DataMessage_Contact_Avatar) ProtoMessage() {} func (x *DataMessage_Contact_Avatar) ProtoReflect() protoreflect.Message { - mi := &file_SignalService_proto_msgTypes[50] + mi := &file_SignalService_proto_msgTypes[52] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5756,7 +6042,7 @@ type TextAttachment_Gradient struct { func (x *TextAttachment_Gradient) Reset() { *x = TextAttachment_Gradient{} - mi := &file_SignalService_proto_msgTypes[51] + mi := &file_SignalService_proto_msgTypes[53] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5768,7 +6054,7 @@ func (x *TextAttachment_Gradient) String() string { func (*TextAttachment_Gradient) ProtoMessage() {} func (x *TextAttachment_Gradient) ProtoReflect() protoreflect.Message { - mi := &file_SignalService_proto_msgTypes[51] + mi := &file_SignalService_proto_msgTypes[53] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5820,19 +6106,20 @@ func (x *TextAttachment_Gradient) GetPositions() []float32 { } type SyncMessage_Sent struct { - state protoimpl.MessageState `protogen:"open.v1"` - DestinationE164 *string `protobuf:"bytes,1,opt,name=destinationE164" json:"destinationE164,omitempty"` - DestinationServiceId *string `protobuf:"bytes,7,opt,name=destinationServiceId" json:"destinationServiceId,omitempty"` - Timestamp *uint64 `protobuf:"varint,2,opt,name=timestamp" json:"timestamp,omitempty"` - Message *DataMessage `protobuf:"bytes,3,opt,name=message" json:"message,omitempty"` - ExpirationStartTimestamp *uint64 `protobuf:"varint,4,opt,name=expirationStartTimestamp" json:"expirationStartTimestamp,omitempty"` - UnidentifiedStatus []*SyncMessage_Sent_UnidentifiedDeliveryStatus `protobuf:"bytes,5,rep,name=unidentifiedStatus" json:"unidentifiedStatus,omitempty"` - IsRecipientUpdate *bool `protobuf:"varint,6,opt,name=isRecipientUpdate,def=0" json:"isRecipientUpdate,omitempty"` - StoryMessage *StoryMessage `protobuf:"bytes,8,opt,name=storyMessage" json:"storyMessage,omitempty"` - StoryMessageRecipients []*SyncMessage_Sent_StoryMessageRecipient `protobuf:"bytes,9,rep,name=storyMessageRecipients" json:"storyMessageRecipients,omitempty"` - EditMessage *EditMessage `protobuf:"bytes,10,opt,name=editMessage" json:"editMessage,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` + DestinationE164 *string `protobuf:"bytes,1,opt,name=destinationE164" json:"destinationE164,omitempty"` + DestinationServiceId *string `protobuf:"bytes,7,opt,name=destinationServiceId" json:"destinationServiceId,omitempty"` + Timestamp *uint64 `protobuf:"varint,2,opt,name=timestamp" json:"timestamp,omitempty"` + Message *DataMessage `protobuf:"bytes,3,opt,name=message" json:"message,omitempty"` + ExpirationStartTimestamp *uint64 `protobuf:"varint,4,opt,name=expirationStartTimestamp" json:"expirationStartTimestamp,omitempty"` + UnidentifiedStatus []*SyncMessage_Sent_UnidentifiedDeliveryStatus `protobuf:"bytes,5,rep,name=unidentifiedStatus" json:"unidentifiedStatus,omitempty"` + IsRecipientUpdate *bool `protobuf:"varint,6,opt,name=isRecipientUpdate,def=0" json:"isRecipientUpdate,omitempty"` + StoryMessage *StoryMessage `protobuf:"bytes,8,opt,name=storyMessage" json:"storyMessage,omitempty"` + StoryMessageRecipients []*SyncMessage_Sent_StoryMessageRecipient `protobuf:"bytes,9,rep,name=storyMessageRecipients" json:"storyMessageRecipients,omitempty"` + EditMessage *EditMessage `protobuf:"bytes,10,opt,name=editMessage" json:"editMessage,omitempty"` + DestinationServiceIdBinary []byte `protobuf:"bytes,12,opt,name=destinationServiceIdBinary" json:"destinationServiceIdBinary,omitempty"` // service ID binary (i.e. 16 byte UUID for ACI, 1 byte prefix + 16 byte UUID for PNI) + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } // Default values for SyncMessage_Sent fields. @@ -5842,7 +6129,7 @@ const ( func (x *SyncMessage_Sent) Reset() { *x = SyncMessage_Sent{} - mi := &file_SignalService_proto_msgTypes[52] + mi := &file_SignalService_proto_msgTypes[54] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5854,7 +6141,7 @@ func (x *SyncMessage_Sent) String() string { func (*SyncMessage_Sent) ProtoMessage() {} func (x *SyncMessage_Sent) ProtoReflect() protoreflect.Message { - mi := &file_SignalService_proto_msgTypes[52] + mi := &file_SignalService_proto_msgTypes[54] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5940,6 +6227,13 @@ func (x *SyncMessage_Sent) GetEditMessage() *EditMessage { return nil } +func (x *SyncMessage_Sent) GetDestinationServiceIdBinary() []byte { + if x != nil { + return x.DestinationServiceIdBinary + } + return nil +} + type SyncMessage_Contacts struct { state protoimpl.MessageState `protogen:"open.v1"` Blob *AttachmentPointer `protobuf:"bytes,1,opt,name=blob" json:"blob,omitempty"` @@ -5955,7 +6249,7 @@ const ( func (x *SyncMessage_Contacts) Reset() { *x = SyncMessage_Contacts{} - mi := &file_SignalService_proto_msgTypes[53] + mi := &file_SignalService_proto_msgTypes[55] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5967,7 +6261,7 @@ func (x *SyncMessage_Contacts) String() string { func (*SyncMessage_Contacts) ProtoMessage() {} func (x *SyncMessage_Contacts) ProtoReflect() protoreflect.Message { - mi := &file_SignalService_proto_msgTypes[53] + mi := &file_SignalService_proto_msgTypes[55] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6002,13 +6296,14 @@ type SyncMessage_Blocked struct { Numbers []string `protobuf:"bytes,1,rep,name=numbers" json:"numbers,omitempty"` Acis []string `protobuf:"bytes,3,rep,name=acis" json:"acis,omitempty"` GroupIds [][]byte `protobuf:"bytes,2,rep,name=groupIds" json:"groupIds,omitempty"` + AcisBinary [][]byte `protobuf:"bytes,4,rep,name=acisBinary" json:"acisBinary,omitempty"` // 16-byte UUID unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } func (x *SyncMessage_Blocked) Reset() { *x = SyncMessage_Blocked{} - mi := &file_SignalService_proto_msgTypes[54] + mi := &file_SignalService_proto_msgTypes[56] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6020,7 +6315,7 @@ func (x *SyncMessage_Blocked) String() string { func (*SyncMessage_Blocked) ProtoMessage() {} func (x *SyncMessage_Blocked) ProtoReflect() protoreflect.Message { - mi := &file_SignalService_proto_msgTypes[54] + mi := &file_SignalService_proto_msgTypes[56] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6057,6 +6352,13 @@ func (x *SyncMessage_Blocked) GetGroupIds() [][]byte { return nil } +func (x *SyncMessage_Blocked) GetAcisBinary() [][]byte { + if x != nil { + return x.AcisBinary + } + return nil +} + type SyncMessage_Request struct { state protoimpl.MessageState `protogen:"open.v1"` Type *SyncMessage_Request_Type `protobuf:"varint,1,opt,name=type,enum=signalservice.SyncMessage_Request_Type" json:"type,omitempty"` @@ -6066,7 +6368,7 @@ type SyncMessage_Request struct { func (x *SyncMessage_Request) Reset() { *x = SyncMessage_Request{} - mi := &file_SignalService_proto_msgTypes[55] + mi := &file_SignalService_proto_msgTypes[57] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6078,7 +6380,7 @@ func (x *SyncMessage_Request) String() string { func (*SyncMessage_Request) ProtoMessage() {} func (x *SyncMessage_Request) ProtoReflect() protoreflect.Message { - mi := &file_SignalService_proto_msgTypes[55] + mi := &file_SignalService_proto_msgTypes[57] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6102,16 +6404,17 @@ func (x *SyncMessage_Request) GetType() SyncMessage_Request_Type { } type SyncMessage_Read struct { - state protoimpl.MessageState `protogen:"open.v1"` - SenderAci *string `protobuf:"bytes,3,opt,name=senderAci" json:"senderAci,omitempty"` - Timestamp *uint64 `protobuf:"varint,2,opt,name=timestamp" json:"timestamp,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` + SenderAci *string `protobuf:"bytes,3,opt,name=senderAci" json:"senderAci,omitempty"` + Timestamp *uint64 `protobuf:"varint,2,opt,name=timestamp" json:"timestamp,omitempty"` + SenderAciBinary []byte `protobuf:"bytes,4,opt,name=senderAciBinary" json:"senderAciBinary,omitempty"` // 16-byte UUID + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } func (x *SyncMessage_Read) Reset() { *x = SyncMessage_Read{} - mi := &file_SignalService_proto_msgTypes[56] + mi := &file_SignalService_proto_msgTypes[58] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6123,7 +6426,7 @@ func (x *SyncMessage_Read) String() string { func (*SyncMessage_Read) ProtoMessage() {} func (x *SyncMessage_Read) ProtoReflect() protoreflect.Message { - mi := &file_SignalService_proto_msgTypes[56] + mi := &file_SignalService_proto_msgTypes[58] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6153,17 +6456,25 @@ func (x *SyncMessage_Read) GetTimestamp() uint64 { return 0 } +func (x *SyncMessage_Read) GetSenderAciBinary() []byte { + if x != nil { + return x.SenderAciBinary + } + return nil +} + type SyncMessage_Viewed struct { - state protoimpl.MessageState `protogen:"open.v1"` - SenderAci *string `protobuf:"bytes,3,opt,name=senderAci" json:"senderAci,omitempty"` - Timestamp *uint64 `protobuf:"varint,2,opt,name=timestamp" json:"timestamp,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` + SenderAci *string `protobuf:"bytes,3,opt,name=senderAci" json:"senderAci,omitempty"` + Timestamp *uint64 `protobuf:"varint,2,opt,name=timestamp" json:"timestamp,omitempty"` + SenderAciBinary []byte `protobuf:"bytes,4,opt,name=senderAciBinary" json:"senderAciBinary,omitempty"` // 16-byte UUID + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } func (x *SyncMessage_Viewed) Reset() { *x = SyncMessage_Viewed{} - mi := &file_SignalService_proto_msgTypes[57] + mi := &file_SignalService_proto_msgTypes[59] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6175,7 +6486,7 @@ func (x *SyncMessage_Viewed) String() string { func (*SyncMessage_Viewed) ProtoMessage() {} func (x *SyncMessage_Viewed) ProtoReflect() protoreflect.Message { - mi := &file_SignalService_proto_msgTypes[57] + mi := &file_SignalService_proto_msgTypes[59] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6205,6 +6516,13 @@ func (x *SyncMessage_Viewed) GetTimestamp() uint64 { return 0 } +func (x *SyncMessage_Viewed) GetSenderAciBinary() []byte { + if x != nil { + return x.SenderAciBinary + } + return nil +} + type SyncMessage_Configuration struct { state protoimpl.MessageState `protogen:"open.v1"` ReadReceipts *bool `protobuf:"varint,1,opt,name=readReceipts" json:"readReceipts,omitempty"` @@ -6218,7 +6536,7 @@ type SyncMessage_Configuration struct { func (x *SyncMessage_Configuration) Reset() { *x = SyncMessage_Configuration{} - mi := &file_SignalService_proto_msgTypes[58] + mi := &file_SignalService_proto_msgTypes[60] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6230,7 +6548,7 @@ func (x *SyncMessage_Configuration) String() string { func (*SyncMessage_Configuration) ProtoMessage() {} func (x *SyncMessage_Configuration) ProtoReflect() protoreflect.Message { - mi := &file_SignalService_proto_msgTypes[58] + mi := &file_SignalService_proto_msgTypes[60] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6292,7 +6610,7 @@ type SyncMessage_StickerPackOperation struct { func (x *SyncMessage_StickerPackOperation) Reset() { *x = SyncMessage_StickerPackOperation{} - mi := &file_SignalService_proto_msgTypes[59] + mi := &file_SignalService_proto_msgTypes[61] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6304,7 +6622,7 @@ func (x *SyncMessage_StickerPackOperation) String() string { func (*SyncMessage_StickerPackOperation) ProtoMessage() {} func (x *SyncMessage_StickerPackOperation) ProtoReflect() protoreflect.Message { - mi := &file_SignalService_proto_msgTypes[59] + mi := &file_SignalService_proto_msgTypes[61] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6342,16 +6660,17 @@ func (x *SyncMessage_StickerPackOperation) GetType() SyncMessage_StickerPackOper } type SyncMessage_ViewOnceOpen struct { - state protoimpl.MessageState `protogen:"open.v1"` - SenderAci *string `protobuf:"bytes,3,opt,name=senderAci" json:"senderAci,omitempty"` - Timestamp *uint64 `protobuf:"varint,2,opt,name=timestamp" json:"timestamp,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` + SenderAci *string `protobuf:"bytes,3,opt,name=senderAci" json:"senderAci,omitempty"` + Timestamp *uint64 `protobuf:"varint,2,opt,name=timestamp" json:"timestamp,omitempty"` + SenderAciBinary []byte `protobuf:"bytes,4,opt,name=senderAciBinary" json:"senderAciBinary,omitempty"` // 16-byte UUID + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } func (x *SyncMessage_ViewOnceOpen) Reset() { *x = SyncMessage_ViewOnceOpen{} - mi := &file_SignalService_proto_msgTypes[60] + mi := &file_SignalService_proto_msgTypes[62] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6363,7 +6682,7 @@ func (x *SyncMessage_ViewOnceOpen) String() string { func (*SyncMessage_ViewOnceOpen) ProtoMessage() {} func (x *SyncMessage_ViewOnceOpen) ProtoReflect() protoreflect.Message { - mi := &file_SignalService_proto_msgTypes[60] + mi := &file_SignalService_proto_msgTypes[62] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6393,6 +6712,13 @@ func (x *SyncMessage_ViewOnceOpen) GetTimestamp() uint64 { return 0 } +func (x *SyncMessage_ViewOnceOpen) GetSenderAciBinary() []byte { + if x != nil { + return x.SenderAciBinary + } + return nil +} + type SyncMessage_FetchLatest struct { state protoimpl.MessageState `protogen:"open.v1"` Type *SyncMessage_FetchLatest_Type `protobuf:"varint,1,opt,name=type,enum=signalservice.SyncMessage_FetchLatest_Type" json:"type,omitempty"` @@ -6402,7 +6728,7 @@ type SyncMessage_FetchLatest struct { func (x *SyncMessage_FetchLatest) Reset() { *x = SyncMessage_FetchLatest{} - mi := &file_SignalService_proto_msgTypes[61] + mi := &file_SignalService_proto_msgTypes[63] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6414,7 +6740,7 @@ func (x *SyncMessage_FetchLatest) String() string { func (*SyncMessage_FetchLatest) ProtoMessage() {} func (x *SyncMessage_FetchLatest) ProtoReflect() protoreflect.Message { - mi := &file_SignalService_proto_msgTypes[61] + mi := &file_SignalService_proto_msgTypes[63] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6448,7 +6774,7 @@ type SyncMessage_Keys struct { func (x *SyncMessage_Keys) Reset() { *x = SyncMessage_Keys{} - mi := &file_SignalService_proto_msgTypes[62] + mi := &file_SignalService_proto_msgTypes[64] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6460,7 +6786,7 @@ func (x *SyncMessage_Keys) String() string { func (*SyncMessage_Keys) ProtoMessage() {} func (x *SyncMessage_Keys) ProtoReflect() protoreflect.Message { - mi := &file_SignalService_proto_msgTypes[62] + mi := &file_SignalService_proto_msgTypes[64] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6507,7 +6833,7 @@ type SyncMessage_PniIdentity struct { func (x *SyncMessage_PniIdentity) Reset() { *x = SyncMessage_PniIdentity{} - mi := &file_SignalService_proto_msgTypes[63] + mi := &file_SignalService_proto_msgTypes[65] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6519,7 +6845,7 @@ func (x *SyncMessage_PniIdentity) String() string { func (*SyncMessage_PniIdentity) ProtoMessage() {} func (x *SyncMessage_PniIdentity) ProtoReflect() protoreflect.Message { - mi := &file_SignalService_proto_msgTypes[63] + mi := &file_SignalService_proto_msgTypes[65] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6550,17 +6876,18 @@ func (x *SyncMessage_PniIdentity) GetPrivateKey() []byte { } type SyncMessage_MessageRequestResponse struct { - state protoimpl.MessageState `protogen:"open.v1"` - ThreadAci *string `protobuf:"bytes,2,opt,name=threadAci" json:"threadAci,omitempty"` - GroupId []byte `protobuf:"bytes,3,opt,name=groupId" json:"groupId,omitempty"` - Type *SyncMessage_MessageRequestResponse_Type `protobuf:"varint,4,opt,name=type,enum=signalservice.SyncMessage_MessageRequestResponse_Type" json:"type,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` + ThreadAci *string `protobuf:"bytes,2,opt,name=threadAci" json:"threadAci,omitempty"` + GroupId []byte `protobuf:"bytes,3,opt,name=groupId" json:"groupId,omitempty"` + Type *SyncMessage_MessageRequestResponse_Type `protobuf:"varint,4,opt,name=type,enum=signalservice.SyncMessage_MessageRequestResponse_Type" json:"type,omitempty"` + ThreadAciBinary []byte `protobuf:"bytes,5,opt,name=threadAciBinary" json:"threadAciBinary,omitempty"` // 16-byte UUID + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } func (x *SyncMessage_MessageRequestResponse) Reset() { *x = SyncMessage_MessageRequestResponse{} - mi := &file_SignalService_proto_msgTypes[64] + mi := &file_SignalService_proto_msgTypes[66] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6572,7 +6899,7 @@ func (x *SyncMessage_MessageRequestResponse) String() string { func (*SyncMessage_MessageRequestResponse) ProtoMessage() {} func (x *SyncMessage_MessageRequestResponse) ProtoReflect() protoreflect.Message { - mi := &file_SignalService_proto_msgTypes[64] + mi := &file_SignalService_proto_msgTypes[66] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6609,6 +6936,13 @@ func (x *SyncMessage_MessageRequestResponse) GetType() SyncMessage_MessageReques return SyncMessage_MessageRequestResponse_UNKNOWN } +func (x *SyncMessage_MessageRequestResponse) GetThreadAciBinary() []byte { + if x != nil { + return x.ThreadAciBinary + } + return nil +} + type SyncMessage_OutgoingPayment struct { state protoimpl.MessageState `protogen:"open.v1"` RecipientServiceId *string `protobuf:"bytes,1,opt,name=recipientServiceId" json:"recipientServiceId,omitempty"` @@ -6623,7 +6957,7 @@ type SyncMessage_OutgoingPayment struct { func (x *SyncMessage_OutgoingPayment) Reset() { *x = SyncMessage_OutgoingPayment{} - mi := &file_SignalService_proto_msgTypes[65] + mi := &file_SignalService_proto_msgTypes[67] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6635,7 +6969,7 @@ func (x *SyncMessage_OutgoingPayment) String() string { func (*SyncMessage_OutgoingPayment) ProtoMessage() {} func (x *SyncMessage_OutgoingPayment) ProtoReflect() protoreflect.Message { - mi := &file_SignalService_proto_msgTypes[65] + mi := &file_SignalService_proto_msgTypes[67] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6705,7 +7039,7 @@ type SyncMessage_PniChangeNumber struct { func (x *SyncMessage_PniChangeNumber) Reset() { *x = SyncMessage_PniChangeNumber{} - mi := &file_SignalService_proto_msgTypes[66] + mi := &file_SignalService_proto_msgTypes[68] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6717,7 +7051,7 @@ func (x *SyncMessage_PniChangeNumber) String() string { func (*SyncMessage_PniChangeNumber) ProtoMessage() {} func (x *SyncMessage_PniChangeNumber) ProtoReflect() protoreflect.Message { - mi := &file_SignalService_proto_msgTypes[66] + mi := &file_SignalService_proto_msgTypes[68] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6787,7 +7121,7 @@ type SyncMessage_CallEvent struct { func (x *SyncMessage_CallEvent) Reset() { *x = SyncMessage_CallEvent{} - mi := &file_SignalService_proto_msgTypes[67] + mi := &file_SignalService_proto_msgTypes[69] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6799,7 +7133,7 @@ func (x *SyncMessage_CallEvent) String() string { func (*SyncMessage_CallEvent) ProtoMessage() {} func (x *SyncMessage_CallEvent) ProtoReflect() protoreflect.Message { - mi := &file_SignalService_proto_msgTypes[67] + mi := &file_SignalService_proto_msgTypes[69] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6869,7 +7203,7 @@ type SyncMessage_CallLinkUpdate struct { func (x *SyncMessage_CallLinkUpdate) Reset() { *x = SyncMessage_CallLinkUpdate{} - mi := &file_SignalService_proto_msgTypes[68] + mi := &file_SignalService_proto_msgTypes[70] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6881,7 +7215,7 @@ func (x *SyncMessage_CallLinkUpdate) String() string { func (*SyncMessage_CallLinkUpdate) ProtoMessage() {} func (x *SyncMessage_CallLinkUpdate) ProtoReflect() protoreflect.Message { - mi := &file_SignalService_proto_msgTypes[68] + mi := &file_SignalService_proto_msgTypes[70] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6942,7 +7276,7 @@ type SyncMessage_CallLogEvent struct { func (x *SyncMessage_CallLogEvent) Reset() { *x = SyncMessage_CallLogEvent{} - mi := &file_SignalService_proto_msgTypes[69] + mi := &file_SignalService_proto_msgTypes[71] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6954,7 +7288,7 @@ func (x *SyncMessage_CallLogEvent) String() string { func (*SyncMessage_CallLogEvent) ProtoMessage() {} func (x *SyncMessage_CallLogEvent) ProtoReflect() protoreflect.Message { - mi := &file_SignalService_proto_msgTypes[69] + mi := &file_SignalService_proto_msgTypes[71] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7010,7 +7344,7 @@ type SyncMessage_DeleteForMe struct { func (x *SyncMessage_DeleteForMe) Reset() { *x = SyncMessage_DeleteForMe{} - mi := &file_SignalService_proto_msgTypes[70] + mi := &file_SignalService_proto_msgTypes[72] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7022,7 +7356,7 @@ func (x *SyncMessage_DeleteForMe) String() string { func (*SyncMessage_DeleteForMe) ProtoMessage() {} func (x *SyncMessage_DeleteForMe) ProtoReflect() protoreflect.Message { - mi := &file_SignalService_proto_msgTypes[70] + mi := &file_SignalService_proto_msgTypes[72] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7075,7 +7409,7 @@ type SyncMessage_DeviceNameChange struct { func (x *SyncMessage_DeviceNameChange) Reset() { *x = SyncMessage_DeviceNameChange{} - mi := &file_SignalService_proto_msgTypes[71] + mi := &file_SignalService_proto_msgTypes[73] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7087,7 +7421,7 @@ func (x *SyncMessage_DeviceNameChange) String() string { func (*SyncMessage_DeviceNameChange) ProtoMessage() {} func (x *SyncMessage_DeviceNameChange) ProtoReflect() protoreflect.Message { - mi := &file_SignalService_proto_msgTypes[71] + mi := &file_SignalService_proto_msgTypes[73] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7120,7 +7454,7 @@ type SyncMessage_AttachmentBackfillRequest struct { func (x *SyncMessage_AttachmentBackfillRequest) Reset() { *x = SyncMessage_AttachmentBackfillRequest{} - mi := &file_SignalService_proto_msgTypes[72] + mi := &file_SignalService_proto_msgTypes[74] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7132,7 +7466,7 @@ func (x *SyncMessage_AttachmentBackfillRequest) String() string { func (*SyncMessage_AttachmentBackfillRequest) ProtoMessage() {} func (x *SyncMessage_AttachmentBackfillRequest) ProtoReflect() protoreflect.Message { - mi := &file_SignalService_proto_msgTypes[72] + mi := &file_SignalService_proto_msgTypes[74] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7177,7 +7511,7 @@ type SyncMessage_AttachmentBackfillResponse struct { func (x *SyncMessage_AttachmentBackfillResponse) Reset() { *x = SyncMessage_AttachmentBackfillResponse{} - mi := &file_SignalService_proto_msgTypes[73] + mi := &file_SignalService_proto_msgTypes[75] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7189,7 +7523,7 @@ func (x *SyncMessage_AttachmentBackfillResponse) String() string { func (*SyncMessage_AttachmentBackfillResponse) ProtoMessage() {} func (x *SyncMessage_AttachmentBackfillResponse) ProtoReflect() protoreflect.Message { - mi := &file_SignalService_proto_msgTypes[73] + mi := &file_SignalService_proto_msgTypes[75] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7263,17 +7597,18 @@ func (*SyncMessage_AttachmentBackfillResponse_Error_) isSyncMessage_AttachmentBa } type SyncMessage_Sent_UnidentifiedDeliveryStatus struct { - state protoimpl.MessageState `protogen:"open.v1"` - DestinationServiceId *string `protobuf:"bytes,3,opt,name=destinationServiceId" json:"destinationServiceId,omitempty"` - Unidentified *bool `protobuf:"varint,2,opt,name=unidentified" json:"unidentified,omitempty"` - DestinationPniIdentityKey []byte `protobuf:"bytes,5,opt,name=destinationPniIdentityKey" json:"destinationPniIdentityKey,omitempty"` // Only set for PNI destinations - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` + DestinationServiceId *string `protobuf:"bytes,3,opt,name=destinationServiceId" json:"destinationServiceId,omitempty"` + Unidentified *bool `protobuf:"varint,2,opt,name=unidentified" json:"unidentified,omitempty"` + DestinationPniIdentityKey []byte `protobuf:"bytes,5,opt,name=destinationPniIdentityKey" json:"destinationPniIdentityKey,omitempty"` // Only set for PNI destinations + DestinationServiceIdBinary []byte `protobuf:"bytes,6,opt,name=destinationServiceIdBinary" json:"destinationServiceIdBinary,omitempty"` // service ID binary (i.e. 16 byte UUID for ACI, 1 byte prefix + 16 byte UUID for PNI) + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } func (x *SyncMessage_Sent_UnidentifiedDeliveryStatus) Reset() { *x = SyncMessage_Sent_UnidentifiedDeliveryStatus{} - mi := &file_SignalService_proto_msgTypes[74] + mi := &file_SignalService_proto_msgTypes[76] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7285,7 +7620,7 @@ func (x *SyncMessage_Sent_UnidentifiedDeliveryStatus) String() string { func (*SyncMessage_Sent_UnidentifiedDeliveryStatus) ProtoMessage() {} func (x *SyncMessage_Sent_UnidentifiedDeliveryStatus) ProtoReflect() protoreflect.Message { - mi := &file_SignalService_proto_msgTypes[74] + mi := &file_SignalService_proto_msgTypes[76] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7322,18 +7657,26 @@ func (x *SyncMessage_Sent_UnidentifiedDeliveryStatus) GetDestinationPniIdentityK return nil } +func (x *SyncMessage_Sent_UnidentifiedDeliveryStatus) GetDestinationServiceIdBinary() []byte { + if x != nil { + return x.DestinationServiceIdBinary + } + return nil +} + type SyncMessage_Sent_StoryMessageRecipient struct { - state protoimpl.MessageState `protogen:"open.v1"` - DestinationServiceId *string `protobuf:"bytes,1,opt,name=destinationServiceId" json:"destinationServiceId,omitempty"` - DistributionListIds []string `protobuf:"bytes,2,rep,name=distributionListIds" json:"distributionListIds,omitempty"` - IsAllowedToReply *bool `protobuf:"varint,3,opt,name=isAllowedToReply" json:"isAllowedToReply,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` + DestinationServiceId *string `protobuf:"bytes,1,opt,name=destinationServiceId" json:"destinationServiceId,omitempty"` + DistributionListIds []string `protobuf:"bytes,2,rep,name=distributionListIds" json:"distributionListIds,omitempty"` + IsAllowedToReply *bool `protobuf:"varint,3,opt,name=isAllowedToReply" json:"isAllowedToReply,omitempty"` + DestinationServiceIdBinary []byte `protobuf:"bytes,5,opt,name=destinationServiceIdBinary" json:"destinationServiceIdBinary,omitempty"` // service ID binary (i.e. 16 byte UUID for ACI, 1 byte prefix + 16 byte UUID for PNI) + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } func (x *SyncMessage_Sent_StoryMessageRecipient) Reset() { *x = SyncMessage_Sent_StoryMessageRecipient{} - mi := &file_SignalService_proto_msgTypes[75] + mi := &file_SignalService_proto_msgTypes[77] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7345,7 +7688,7 @@ func (x *SyncMessage_Sent_StoryMessageRecipient) String() string { func (*SyncMessage_Sent_StoryMessageRecipient) ProtoMessage() {} func (x *SyncMessage_Sent_StoryMessageRecipient) ProtoReflect() protoreflect.Message { - mi := &file_SignalService_proto_msgTypes[75] + mi := &file_SignalService_proto_msgTypes[77] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7382,6 +7725,13 @@ func (x *SyncMessage_Sent_StoryMessageRecipient) GetIsAllowedToReply() bool { return false } +func (x *SyncMessage_Sent_StoryMessageRecipient) GetDestinationServiceIdBinary() []byte { + if x != nil { + return x.DestinationServiceIdBinary + } + return nil +} + type SyncMessage_OutgoingPayment_MobileCoin struct { state protoimpl.MessageState `protogen:"open.v1"` RecipientAddress []byte `protobuf:"bytes,1,opt,name=recipientAddress" json:"recipientAddress,omitempty"` @@ -7398,7 +7748,7 @@ type SyncMessage_OutgoingPayment_MobileCoin struct { func (x *SyncMessage_OutgoingPayment_MobileCoin) Reset() { *x = SyncMessage_OutgoingPayment_MobileCoin{} - mi := &file_SignalService_proto_msgTypes[76] + mi := &file_SignalService_proto_msgTypes[78] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7410,7 +7760,7 @@ func (x *SyncMessage_OutgoingPayment_MobileCoin) String() string { func (*SyncMessage_OutgoingPayment_MobileCoin) ProtoMessage() {} func (x *SyncMessage_OutgoingPayment_MobileCoin) ProtoReflect() protoreflect.Message { - mi := &file_SignalService_proto_msgTypes[76] + mi := &file_SignalService_proto_msgTypes[78] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7492,7 +7842,7 @@ type SyncMessage_DeleteForMe_MessageDeletes struct { func (x *SyncMessage_DeleteForMe_MessageDeletes) Reset() { *x = SyncMessage_DeleteForMe_MessageDeletes{} - mi := &file_SignalService_proto_msgTypes[77] + mi := &file_SignalService_proto_msgTypes[79] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7504,7 +7854,7 @@ func (x *SyncMessage_DeleteForMe_MessageDeletes) String() string { func (*SyncMessage_DeleteForMe_MessageDeletes) ProtoMessage() {} func (x *SyncMessage_DeleteForMe_MessageDeletes) ProtoReflect() protoreflect.Message { - mi := &file_SignalService_proto_msgTypes[77] + mi := &file_SignalService_proto_msgTypes[79] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7550,7 +7900,7 @@ type SyncMessage_DeleteForMe_AttachmentDelete struct { func (x *SyncMessage_DeleteForMe_AttachmentDelete) Reset() { *x = SyncMessage_DeleteForMe_AttachmentDelete{} - mi := &file_SignalService_proto_msgTypes[78] + mi := &file_SignalService_proto_msgTypes[80] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7562,7 +7912,7 @@ func (x *SyncMessage_DeleteForMe_AttachmentDelete) String() string { func (*SyncMessage_DeleteForMe_AttachmentDelete) ProtoMessage() {} func (x *SyncMessage_DeleteForMe_AttachmentDelete) ProtoReflect() protoreflect.Message { - mi := &file_SignalService_proto_msgTypes[78] + mi := &file_SignalService_proto_msgTypes[80] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7625,7 +7975,7 @@ type SyncMessage_DeleteForMe_ConversationDelete struct { func (x *SyncMessage_DeleteForMe_ConversationDelete) Reset() { *x = SyncMessage_DeleteForMe_ConversationDelete{} - mi := &file_SignalService_proto_msgTypes[79] + mi := &file_SignalService_proto_msgTypes[81] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7637,7 +7987,7 @@ func (x *SyncMessage_DeleteForMe_ConversationDelete) String() string { func (*SyncMessage_DeleteForMe_ConversationDelete) ProtoMessage() {} func (x *SyncMessage_DeleteForMe_ConversationDelete) ProtoReflect() protoreflect.Message { - mi := &file_SignalService_proto_msgTypes[79] + mi := &file_SignalService_proto_msgTypes[81] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7690,7 +8040,7 @@ type SyncMessage_DeleteForMe_LocalOnlyConversationDelete struct { func (x *SyncMessage_DeleteForMe_LocalOnlyConversationDelete) Reset() { *x = SyncMessage_DeleteForMe_LocalOnlyConversationDelete{} - mi := &file_SignalService_proto_msgTypes[80] + mi := &file_SignalService_proto_msgTypes[82] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7702,7 +8052,7 @@ func (x *SyncMessage_DeleteForMe_LocalOnlyConversationDelete) String() string { func (*SyncMessage_DeleteForMe_LocalOnlyConversationDelete) ProtoMessage() {} func (x *SyncMessage_DeleteForMe_LocalOnlyConversationDelete) ProtoReflect() protoreflect.Message { - mi := &file_SignalService_proto_msgTypes[80] + mi := &file_SignalService_proto_msgTypes[82] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7738,7 +8088,7 @@ type SyncMessage_AttachmentBackfillResponse_AttachmentData struct { func (x *SyncMessage_AttachmentBackfillResponse_AttachmentData) Reset() { *x = SyncMessage_AttachmentBackfillResponse_AttachmentData{} - mi := &file_SignalService_proto_msgTypes[81] + mi := &file_SignalService_proto_msgTypes[83] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7750,7 +8100,7 @@ func (x *SyncMessage_AttachmentBackfillResponse_AttachmentData) String() string func (*SyncMessage_AttachmentBackfillResponse_AttachmentData) ProtoMessage() {} func (x *SyncMessage_AttachmentBackfillResponse_AttachmentData) ProtoReflect() protoreflect.Message { - mi := &file_SignalService_proto_msgTypes[81] + mi := &file_SignalService_proto_msgTypes[83] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7819,7 +8169,7 @@ type SyncMessage_AttachmentBackfillResponse_AttachmentDataList struct { func (x *SyncMessage_AttachmentBackfillResponse_AttachmentDataList) Reset() { *x = SyncMessage_AttachmentBackfillResponse_AttachmentDataList{} - mi := &file_SignalService_proto_msgTypes[82] + mi := &file_SignalService_proto_msgTypes[84] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7831,7 +8181,7 @@ func (x *SyncMessage_AttachmentBackfillResponse_AttachmentDataList) String() str func (*SyncMessage_AttachmentBackfillResponse_AttachmentDataList) ProtoMessage() {} func (x *SyncMessage_AttachmentBackfillResponse_AttachmentDataList) ProtoReflect() protoreflect.Message { - mi := &file_SignalService_proto_msgTypes[82] + mi := &file_SignalService_proto_msgTypes[84] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7871,7 +8221,7 @@ type ContactDetails_Avatar struct { func (x *ContactDetails_Avatar) Reset() { *x = ContactDetails_Avatar{} - mi := &file_SignalService_proto_msgTypes[83] + mi := &file_SignalService_proto_msgTypes[85] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7883,7 +8233,7 @@ func (x *ContactDetails_Avatar) String() string { func (*ContactDetails_Avatar) ProtoMessage() {} func (x *ContactDetails_Avatar) ProtoReflect() protoreflect.Message { - mi := &file_SignalService_proto_msgTypes[83] + mi := &file_SignalService_proto_msgTypes[85] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7923,7 +8273,7 @@ type PaymentAddress_MobileCoin struct { func (x *PaymentAddress_MobileCoin) Reset() { *x = PaymentAddress_MobileCoin{} - mi := &file_SignalService_proto_msgTypes[84] + mi := &file_SignalService_proto_msgTypes[86] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7935,7 +8285,7 @@ func (x *PaymentAddress_MobileCoin) String() string { func (*PaymentAddress_MobileCoin) ProtoMessage() {} func (x *PaymentAddress_MobileCoin) ProtoReflect() protoreflect.Message { - mi := &file_SignalService_proto_msgTypes[84] + mi := &file_SignalService_proto_msgTypes[86] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7969,7 +8319,7 @@ var File_SignalService_proto protoreflect.FileDescriptor const file_SignalService_proto_rawDesc = "" + "\n" + - "\x13SignalService.proto\x12\rsignalservice\"\xa7\x05\n" + + "\x13SignalService.proto\x12\rsignalservice\"\xf5\x06\n" + "\bEnvelope\x120\n" + "\x04type\x18\x01 \x01(\x0e2\x1c.signalservice.Envelope.TypeR\x04type\x12(\n" + "\x0fsourceServiceId\x18\v \x01(\tR\x0fsourceServiceId\x12\"\n" + @@ -7988,7 +8338,11 @@ const file_SignalService_proto_rawDesc = "" + "updatedPni\x18\x0f \x01(\tR\n" + "updatedPni\x12\x14\n" + "\x05story\x18\x10 \x01(\bR\x05story\x12*\n" + - "\x11report_spam_token\x18\x11 \x01(\fR\x0freportSpamToken\"\xae\x01\n" + + "\x11report_spam_token\x18\x11 \x01(\fR\x0freportSpamToken\x124\n" + + "\x15sourceServiceIdBinary\x18\x13 \x01(\fR\x15sourceServiceIdBinary\x12>\n" + + "\x1adestinationServiceIdBinary\x18\x14 \x01(\fR\x1adestinationServiceIdBinary\x12*\n" + + "\x10serverGuidBinary\x18\x15 \x01(\fR\x10serverGuidBinary\x12*\n" + + "\x10updatedPniBinary\x18\x16 \x01(\fR\x10updatedPniBinary\"\xae\x01\n" + "\x04Type\x12\v\n" + "\aUNKNOWN\x10\x00\x12\x0e\n" + "\n" + @@ -8050,7 +8404,7 @@ const file_SignalService_proto_rawDesc = "" + "\aurgency\x18\x02 \x01(\x0e2).signalservice.CallMessage.Opaque.UrgencyR\aurgency\"0\n" + "\aUrgency\x12\r\n" + "\tDROPPABLE\x10\x00\x12\x16\n" + - "\x12HANDLE_IMMEDIATELY\x10\x01J\x04\b\x04\x10\x05J\x04\b\x06\x10\aJ\x04\b\b\x10\t\"\xca'\n" + + "\x12HANDLE_IMMEDIATELY\x10\x01J\x04\b\x04\x10\x05J\x04\b\x06\x10\aJ\x04\b\b\x10\t\"\xca,\n" + "\vDataMessage\x12\x12\n" + "\x04body\x18\x01 \x01(\tR\x04body\x12B\n" + "\vattachments\x18\x02 \x03(\v2 .signalservice.AttachmentPointerR\vattachments\x127\n" + @@ -8084,7 +8438,11 @@ const file_SignalService_proto_rawDesc = "" + "pollCreate\x18\x18 \x01(\v2%.signalservice.DataMessage.PollCreateR\n" + "pollCreate\x12N\n" + "\rpollTerminate\x18\x19 \x01(\v2(.signalservice.DataMessage.PollTerminateR\rpollTerminate\x12?\n" + - "\bpollVote\x18\x1a \x01(\v2#.signalservice.DataMessage.PollVoteR\bpollVote\x1a\x9a\x05\n" + + "\bpollVote\x18\x1a \x01(\v2#.signalservice.DataMessage.PollVoteR\bpollVote\x12E\n" + + "\n" + + "pinMessage\x18\x1b \x01(\v2%.signalservice.DataMessage.PinMessageR\n" + + "pinMessage\x12K\n" + + "\funpinMessage\x18\x1c \x01(\v2'.signalservice.DataMessage.UnpinMessageR\funpinMessage\x1a\x9a\x05\n" + "\aPayment\x12U\n" + "\fnotification\x18\x01 \x01(\v2/.signalservice.DataMessage.Payment.NotificationH\x00R\fnotification\x12O\n" + "\n" + @@ -8113,7 +8471,7 @@ const file_SignalService_proto_rawDesc = "" + "\x04Type\x12\v\n" + "\aREQUEST\x10\x00\x12\r\n" + "\tACTIVATED\x10\x01B\x06\n" + - "\x04ItemJ\x06\b\xea\a\x10\xeb\aJ\x06\b\xeb\a\x10\xec\a\x1a\xda\x03\n" + + "\x04ItemJ\x06\b\xea\a\x10\xeb\aJ\x06\b\xeb\a\x10\xec\a\x1a\x84\x04\n" + "\x05Quote\x12\x0e\n" + "\x02id\x18\x01 \x01(\x04R\x02id\x12\x1c\n" + "\tauthorAci\x18\x05 \x01(\tR\tauthorAci\x12\x12\n" + @@ -8122,7 +8480,8 @@ const file_SignalService_proto_rawDesc = "" + "\n" + "bodyRanges\x18\x06 \x03(\v2\x18.signalservice.BodyRangeR\n" + "bodyRanges\x129\n" + - "\x04type\x18\a \x01(\x0e2%.signalservice.DataMessage.Quote.TypeR\x04type\x1a\x90\x01\n" + + "\x04type\x18\a \x01(\x0e2%.signalservice.DataMessage.Quote.TypeR\x04type\x12(\n" + + "\x0fauthorAciBinary\x18\b \x01(\fR\x0fauthorAciBinary\x1a\x90\x01\n" + "\x10QuotedAttachment\x12 \n" + "\vcontentType\x18\x01 \x01(\tR\vcontentType\x12\x1a\n" + "\bfileName\x18\x02 \x01(\tR\bfileName\x12>\n" + @@ -8197,19 +8556,21 @@ const file_SignalService_proto_rawDesc = "" + "\apackKey\x18\x02 \x01(\fR\apackKey\x12\x1c\n" + "\tstickerId\x18\x03 \x01(\rR\tstickerId\x124\n" + "\x04data\x18\x04 \x01(\v2 .signalservice.AttachmentPointerR\x04data\x12\x14\n" + - "\x05emoji\x18\x05 \x01(\tR\x05emoji\x1a\x9a\x01\n" + + "\x05emoji\x18\x05 \x01(\tR\x05emoji\x1a\xd0\x01\n" + "\bReaction\x12\x14\n" + "\x05emoji\x18\x01 \x01(\tR\x05emoji\x12\x16\n" + "\x06remove\x18\x02 \x01(\bR\x06remove\x12(\n" + "\x0ftargetAuthorAci\x18\x04 \x01(\tR\x0ftargetAuthorAci\x120\n" + - "\x13targetSentTimestamp\x18\x05 \x01(\x04R\x13targetSentTimestampJ\x04\b\x03\x10\x04\x1a:\n" + + "\x13targetSentTimestamp\x18\x05 \x01(\x04R\x13targetSentTimestamp\x124\n" + + "\x15targetAuthorAciBinary\x18\x06 \x01(\fR\x15targetAuthorAciBinaryJ\x04\b\x03\x10\x04\x1a:\n" + "\x06Delete\x120\n" + "\x13targetSentTimestamp\x18\x01 \x01(\x04R\x13targetSentTimestamp\x1a'\n" + "\x0fGroupCallUpdate\x12\x14\n" + - "\x05eraId\x18\x01 \x01(\tR\x05eraId\x1aR\n" + + "\x05eraId\x18\x01 \x01(\tR\x05eraId\x1a|\n" + "\fStoryContext\x12\x1c\n" + "\tauthorAci\x18\x01 \x01(\tR\tauthorAci\x12$\n" + - "\rsentTimestamp\x18\x02 \x01(\x04R\rsentTimestamp\x1aQ\n" + + "\rsentTimestamp\x18\x02 \x01(\x04R\rsentTimestamp\x12(\n" + + "\x0fauthorAciBinary\x18\x03 \x01(\fR\x0fauthorAciBinary\x1aQ\n" + "\tGiftBadge\x12D\n" + "\x1dreceiptCredentialPresentation\x18\x01 \x01(\fR\x1dreceiptCredentialPresentation\x1ah\n" + "\n" + @@ -8223,7 +8584,17 @@ const file_SignalService_proto_rawDesc = "" + "\x15targetAuthorAciBinary\x18\x01 \x01(\fR\x15targetAuthorAciBinary\x120\n" + "\x13targetSentTimestamp\x18\x02 \x01(\x04R\x13targetSentTimestamp\x12$\n" + "\roptionIndexes\x18\x03 \x03(\rR\roptionIndexes\x12\x1c\n" + - "\tvoteCount\x18\x04 \x01(\rR\tvoteCount\"Z\n" + + "\tvoteCount\x18\x04 \x01(\rR\tvoteCount\x1a\xe7\x01\n" + + "\n" + + "PinMessage\x124\n" + + "\x15targetAuthorAciBinary\x18\x01 \x01(\fR\x15targetAuthorAciBinary\x120\n" + + "\x13targetSentTimestamp\x18\x02 \x01(\x04R\x13targetSentTimestamp\x120\n" + + "\x12pinDurationSeconds\x18\x03 \x01(\rH\x00R\x12pinDurationSeconds\x120\n" + + "\x12pinDurationForever\x18\x04 \x01(\bH\x00R\x12pinDurationForeverB\r\n" + + "\vpinDuration\x1av\n" + + "\fUnpinMessage\x124\n" + + "\x15targetAuthorAciBinary\x18\x01 \x01(\fR\x15targetAuthorAciBinary\x120\n" + + "\x13targetSentTimestamp\x18\x02 \x01(\x04R\x13targetSentTimestamp\"Z\n" + "\x05Flags\x12\x0f\n" + "\vEND_SESSION\x10\x01\x12\x1b\n" + "\x17EXPIRATION_TIMER_UPDATE\x10\x02\x12\x16\n" + @@ -8239,7 +8610,7 @@ const file_SignalService_proto_rawDesc = "" + "\bMENTIONS\x10\x06\x12\f\n" + "\bPAYMENTS\x10\a\x12\t\n" + "\x05POLLS\x10\b\x12\v\n" + - "\aCURRENT\x10\a\x1a\x02\x10\x01J\x04\b\x03\x10\x04\"'\n" + + "\aCURRENT\x10\b\x1a\x02\x10\x01J\x04\b\x03\x10\x04\"'\n" + "\vNullMessage\x12\x18\n" + "\apadding\x18\x01 \x01(\fR\apadding\"\x92\x01\n" + "\x0eReceiptMessage\x126\n" + @@ -8301,17 +8672,18 @@ const file_SignalService_proto_rawDesc = "" + "\x06SCRIPT\x10\x04\x12\r\n" + "\tCONDENSED\x10\x05B\f\n" + "\n" + - "background\"\xe5\x01\n" + + "background\"\x99\x02\n" + "\bVerified\x12&\n" + "\x0edestinationAci\x18\x05 \x01(\tR\x0edestinationAci\x12 \n" + "\videntityKey\x18\x02 \x01(\fR\videntityKey\x123\n" + "\x05state\x18\x03 \x01(\x0e2\x1d.signalservice.Verified.StateR\x05state\x12 \n" + - "\vnullMessage\x18\x04 \x01(\fR\vnullMessage\"2\n" + + "\vnullMessage\x18\x04 \x01(\fR\vnullMessage\x122\n" + + "\x14destinationAciBinary\x18\x06 \x01(\fR\x14destinationAciBinary\"2\n" + "\x05State\x12\v\n" + "\aDEFAULT\x10\x00\x12\f\n" + "\bVERIFIED\x10\x01\x12\x0e\n" + "\n" + - "UNVERIFIED\x10\x02J\x04\b\x01\x10\x02\"\x87D\n" + + "UNVERIFIED\x10\x02J\x04\b\x01\x10\x02\"\x8fG\n" + "\vSyncMessage\x123\n" + "\x04sent\x18\x01 \x01(\v2\x1f.signalservice.SyncMessage.SentR\x04sent\x12?\n" + "\bcontacts\x18\x02 \x01(\v2#.signalservice.SyncMessage.ContactsR\bcontacts\x12<\n" + @@ -8336,7 +8708,7 @@ const file_SignalService_proto_rawDesc = "" + "\vdeleteForMe\x18\x16 \x01(\v2&.signalservice.SyncMessage.DeleteForMeR\vdeleteForMe\x12W\n" + "\x10deviceNameChange\x18\x17 \x01(\v2+.signalservice.SyncMessage.DeviceNameChangeR\x10deviceNameChange\x12r\n" + "\x19attachmentBackfillRequest\x18\x18 \x01(\v24.signalservice.SyncMessage.AttachmentBackfillRequestR\x19attachmentBackfillRequest\x12u\n" + - "\x1aattachmentBackfillResponse\x18\x19 \x01(\v25.signalservice.SyncMessage.AttachmentBackfillResponseR\x1aattachmentBackfillResponse\x1a\xfc\a\n" + + "\x1aattachmentBackfillResponse\x18\x19 \x01(\v25.signalservice.SyncMessage.AttachmentBackfillResponseR\x1aattachmentBackfillResponse\x1a\xbc\t\n" + "\x04Sent\x12(\n" + "\x0fdestinationE164\x18\x01 \x01(\tR\x0fdestinationE164\x122\n" + "\x14destinationServiceId\x18\a \x01(\tR\x14destinationServiceId\x12\x1c\n" + @@ -8348,22 +8720,28 @@ const file_SignalService_proto_rawDesc = "" + "\fstoryMessage\x18\b \x01(\v2\x1b.signalservice.StoryMessageR\fstoryMessage\x12m\n" + "\x16storyMessageRecipients\x18\t \x03(\v25.signalservice.SyncMessage.Sent.StoryMessageRecipientR\x16storyMessageRecipients\x12<\n" + "\veditMessage\x18\n" + - " \x01(\v2\x1a.signalservice.EditMessageR\veditMessage\x1a\xbe\x01\n" + + " \x01(\v2\x1a.signalservice.EditMessageR\veditMessage\x12>\n" + + "\x1adestinationServiceIdBinary\x18\f \x01(\fR\x1adestinationServiceIdBinary\x1a\xfe\x01\n" + "\x1aUnidentifiedDeliveryStatus\x122\n" + "\x14destinationServiceId\x18\x03 \x01(\tR\x14destinationServiceId\x12\"\n" + "\funidentified\x18\x02 \x01(\bR\funidentified\x12<\n" + - "\x19destinationPniIdentityKey\x18\x05 \x01(\fR\x19destinationPniIdentityKeyJ\x04\b\x01\x10\x02J\x04\b\x04\x10\x05\x1a\xaf\x01\n" + + "\x19destinationPniIdentityKey\x18\x05 \x01(\fR\x19destinationPniIdentityKey\x12>\n" + + "\x1adestinationServiceIdBinary\x18\x06 \x01(\fR\x1adestinationServiceIdBinaryJ\x04\b\x01\x10\x02J\x04\b\x04\x10\x05\x1a\xef\x01\n" + "\x15StoryMessageRecipient\x122\n" + "\x14destinationServiceId\x18\x01 \x01(\tR\x14destinationServiceId\x120\n" + "\x13distributionListIds\x18\x02 \x03(\tR\x13distributionListIds\x12*\n" + - "\x10isAllowedToReply\x18\x03 \x01(\bR\x10isAllowedToReplyJ\x04\b\x04\x10\x05J\x04\b\v\x10\f\x1ac\n" + + "\x10isAllowedToReply\x18\x03 \x01(\bR\x10isAllowedToReply\x12>\n" + + "\x1adestinationServiceIdBinary\x18\x05 \x01(\fR\x1adestinationServiceIdBinaryJ\x04\b\x04\x10\x05J\x04\b\v\x10\f\x1ac\n" + "\bContacts\x124\n" + "\x04blob\x18\x01 \x01(\v2 .signalservice.AttachmentPointerR\x04blob\x12!\n" + - "\bcomplete\x18\x02 \x01(\b:\x05falseR\bcomplete\x1aS\n" + + "\bcomplete\x18\x02 \x01(\b:\x05falseR\bcomplete\x1as\n" + "\aBlocked\x12\x18\n" + "\anumbers\x18\x01 \x03(\tR\anumbers\x12\x12\n" + "\x04acis\x18\x03 \x03(\tR\x04acis\x12\x1a\n" + - "\bgroupIds\x18\x02 \x03(\fR\bgroupIds\x1a\x9f\x01\n" + + "\bgroupIds\x18\x02 \x03(\fR\bgroupIds\x12\x1e\n" + + "\n" + + "acisBinary\x18\x04 \x03(\fR\n" + + "acisBinary\x1a\x9f\x01\n" + "\aRequest\x12;\n" + "\x04type\x18\x01 \x01(\x0e2'.signalservice.SyncMessage.Request.TypeR\x04type\"W\n" + "\x04Type\x12\v\n" + @@ -8371,13 +8749,15 @@ const file_SignalService_proto_rawDesc = "" + "\bCONTACTS\x10\x01\x12\v\n" + "\aBLOCKED\x10\x03\x12\x11\n" + "\rCONFIGURATION\x10\x04\x12\b\n" + - "\x04KEYS\x10\x05\"\x04\b\x02\x10\x02\"\x04\b\x06\x10\x06\x1aH\n" + + "\x04KEYS\x10\x05\"\x04\b\x02\x10\x02\"\x04\b\x06\x10\x06\x1ar\n" + "\x04Read\x12\x1c\n" + "\tsenderAci\x18\x03 \x01(\tR\tsenderAci\x12\x1c\n" + - "\ttimestamp\x18\x02 \x01(\x04R\ttimestampJ\x04\b\x01\x10\x02\x1aJ\n" + + "\ttimestamp\x18\x02 \x01(\x04R\ttimestamp\x12(\n" + + "\x0fsenderAciBinary\x18\x04 \x01(\fR\x0fsenderAciBinaryJ\x04\b\x01\x10\x02\x1at\n" + "\x06Viewed\x12\x1c\n" + "\tsenderAci\x18\x03 \x01(\tR\tsenderAci\x12\x1c\n" + - "\ttimestamp\x18\x02 \x01(\x04R\ttimestampJ\x04\b\x01\x10\x02\x1a\x83\x02\n" + + "\ttimestamp\x18\x02 \x01(\x04R\ttimestamp\x12(\n" + + "\x0fsenderAciBinary\x18\x04 \x01(\fR\x0fsenderAciBinaryJ\x04\b\x01\x10\x02\x1a\x83\x02\n" + "\rConfiguration\x12\"\n" + "\freadReceipts\x18\x01 \x01(\bR\freadReceipts\x12F\n" + "\x1eunidentifiedDeliveryIndicators\x18\x02 \x01(\bR\x1eunidentifiedDeliveryIndicators\x12*\n" + @@ -8391,10 +8771,11 @@ const file_SignalService_proto_rawDesc = "" + "\x04Type\x12\v\n" + "\aINSTALL\x10\x00\x12\n" + "\n" + - "\x06REMOVE\x10\x01\x1aP\n" + + "\x06REMOVE\x10\x01\x1az\n" + "\fViewOnceOpen\x12\x1c\n" + "\tsenderAci\x18\x03 \x01(\tR\tsenderAci\x12\x1c\n" + - "\ttimestamp\x18\x02 \x01(\x04R\ttimestampJ\x04\b\x01\x10\x02\x1a\xa5\x01\n" + + "\ttimestamp\x18\x02 \x01(\x04R\ttimestamp\x12(\n" + + "\x0fsenderAciBinary\x18\x04 \x01(\fR\x0fsenderAciBinaryJ\x04\b\x01\x10\x02\x1a\xa5\x01\n" + "\vFetchLatest\x12?\n" + "\x04type\x18\x01 \x01(\x0e2+.signalservice.SyncMessage.FetchLatest.TypeR\x04type\"U\n" + "\x04Type\x12\v\n" + @@ -8410,11 +8791,12 @@ const file_SignalService_proto_rawDesc = "" + "\tpublicKey\x18\x01 \x01(\fR\tpublicKey\x12\x1e\n" + "\n" + "privateKey\x18\x02 \x01(\fR\n" + - "privateKey\x1a\x8e\x02\n" + + "privateKey\x1a\xb8\x02\n" + "\x16MessageRequestResponse\x12\x1c\n" + "\tthreadAci\x18\x02 \x01(\tR\tthreadAci\x12\x18\n" + "\agroupId\x18\x03 \x01(\fR\agroupId\x12J\n" + - "\x04type\x18\x04 \x01(\x0e26.signalservice.SyncMessage.MessageRequestResponse.TypeR\x04type\"j\n" + + "\x04type\x18\x04 \x01(\x0e26.signalservice.SyncMessage.MessageRequestResponse.TypeR\x04type\x12(\n" + + "\x0fthreadAciBinary\x18\x05 \x01(\fR\x0fthreadAciBinary\"j\n" + "\x04Type\x12\v\n" + "\aUNKNOWN\x10\x00\x12\n" + "\n" + @@ -8575,10 +8957,11 @@ const file_SignalService_proto_rawDesc = "" + "\x0eGroupContextV2\x12\x1c\n" + "\tmasterKey\x18\x01 \x01(\fR\tmasterKey\x12\x1a\n" + "\brevision\x18\x02 \x01(\rR\brevision\x12 \n" + - "\vgroupChange\x18\x03 \x01(\fR\vgroupChange\"\xe6\x02\n" + + "\vgroupChange\x18\x03 \x01(\fR\vgroupChange\"\x84\x03\n" + "\x0eContactDetails\x12\x16\n" + "\x06number\x18\x01 \x01(\tR\x06number\x12\x10\n" + - "\x03aci\x18\t \x01(\tR\x03aci\x12\x12\n" + + "\x03aci\x18\t \x01(\tR\x03aci\x12\x1c\n" + + "\taciBinary\x18\r \x01(\fR\taciBinary\x12\x12\n" + "\x04name\x18\x02 \x01(\tR\x04name\x12<\n" + "\x06avatar\x18\x03 \x01(\v2$.signalservice.ContactDetails.AvatarR\x06avatar\x12 \n" + "\vexpireTimer\x18\b \x01(\rR\vexpireTimer\x12.\n" + @@ -8608,14 +8991,15 @@ const file_SignalService_proto_rawDesc = "" + "\tsignature\x18\x02 \x01(\fR\tsignature\"}\n" + "\vEditMessage\x120\n" + "\x13targetSentTimestamp\x18\x01 \x01(\x04R\x13targetSentTimestamp\x12<\n" + - "\vdataMessage\x18\x02 \x01(\v2\x1a.signalservice.DataMessageR\vdataMessage\"\xfe\x01\n" + + "\vdataMessage\x18\x02 \x01(\v2\x1a.signalservice.DataMessageR\vdataMessage\"\xac\x02\n" + "\tBodyRange\x12\x14\n" + "\x05start\x18\x01 \x01(\rR\x05start\x12\x16\n" + "\x06length\x18\x02 \x01(\rR\x06length\x12 \n" + "\n" + "mentionAci\x18\x03 \x01(\tH\x00R\n" + "mentionAci\x126\n" + - "\x05style\x18\x04 \x01(\x0e2\x1e.signalservice.BodyRange.StyleH\x00R\x05style\"V\n" + + "\x05style\x18\x04 \x01(\x0e2\x1e.signalservice.BodyRange.StyleH\x00R\x05style\x12,\n" + + "\x10mentionAciBinary\x18\x05 \x01(\fH\x00R\x10mentionAciBinary\"V\n" + "\x05Style\x12\b\n" + "\x04NONE\x10\x00\x12\b\n" + "\x04BOLD\x10\x01\x12\n" + @@ -8624,20 +9008,22 @@ const file_SignalService_proto_rawDesc = "" + "\aSPOILER\x10\x03\x12\x11\n" + "\rSTRIKETHROUGH\x10\x04\x12\r\n" + "\tMONOSPACE\x10\x05B\x11\n" + - "\x0fassociatedValue\"\x92\x01\n" + + "\x0fassociatedValue\"\xca\x01\n" + "\x12AddressableMessage\x12*\n" + "\x0fauthorServiceId\x18\x01 \x01(\tH\x00R\x0fauthorServiceId\x12 \n" + "\n" + "authorE164\x18\x02 \x01(\tH\x00R\n" + - "authorE164\x12$\n" + + "authorE164\x126\n" + + "\x15authorServiceIdBinary\x18\x04 \x01(\fH\x00R\x15authorServiceIdBinary\x12$\n" + "\rsentTimestamp\x18\x03 \x01(\x04R\rsentTimestampB\b\n" + - "\x06author\"\x9c\x01\n" + + "\x06author\"\xd4\x01\n" + "\x16ConversationIdentifier\x12*\n" + "\x0fthreadServiceId\x18\x01 \x01(\tH\x00R\x0fthreadServiceId\x12&\n" + "\rthreadGroupId\x18\x02 \x01(\fH\x00R\rthreadGroupId\x12 \n" + "\n" + "threadE164\x18\x03 \x01(\tH\x00R\n" + - "threadE164B\f\n" + + "threadE164\x126\n" + + "\x15threadServiceIdBinary\x18\x04 \x01(\fH\x00R\x15threadServiceIdBinaryB\f\n" + "\n" + "identifierBE\n" + ".org.whispersystems.signalservice.internal.pushB\x13SignalServiceProtos" @@ -8655,7 +9041,7 @@ func file_SignalService_proto_rawDescGZIP() []byte { } var file_SignalService_proto_enumTypes = make([]protoimpl.EnumInfo, 28) -var file_SignalService_proto_msgTypes = make([]protoimpl.MessageInfo, 85) +var file_SignalService_proto_msgTypes = make([]protoimpl.MessageInfo, 87) var file_SignalService_proto_goTypes = []any{ (Envelope_Type)(0), // 0: signalservice.Envelope.Type (CallMessage_Offer_Type)(0), // 1: signalservice.CallMessage.Offer.Type @@ -8725,51 +9111,53 @@ var file_SignalService_proto_goTypes = []any{ (*DataMessage_PollCreate)(nil), // 65: signalservice.DataMessage.PollCreate (*DataMessage_PollTerminate)(nil), // 66: signalservice.DataMessage.PollTerminate (*DataMessage_PollVote)(nil), // 67: signalservice.DataMessage.PollVote - (*DataMessage_Payment_Amount)(nil), // 68: signalservice.DataMessage.Payment.Amount - (*DataMessage_Payment_Notification)(nil), // 69: signalservice.DataMessage.Payment.Notification - (*DataMessage_Payment_Activation)(nil), // 70: signalservice.DataMessage.Payment.Activation - (*DataMessage_Payment_Amount_MobileCoin)(nil), // 71: signalservice.DataMessage.Payment.Amount.MobileCoin - (*DataMessage_Payment_Notification_MobileCoin)(nil), // 72: signalservice.DataMessage.Payment.Notification.MobileCoin - (*DataMessage_Quote_QuotedAttachment)(nil), // 73: signalservice.DataMessage.Quote.QuotedAttachment - (*DataMessage_Contact_Name)(nil), // 74: signalservice.DataMessage.Contact.Name - (*DataMessage_Contact_Phone)(nil), // 75: signalservice.DataMessage.Contact.Phone - (*DataMessage_Contact_Email)(nil), // 76: signalservice.DataMessage.Contact.Email - (*DataMessage_Contact_PostalAddress)(nil), // 77: signalservice.DataMessage.Contact.PostalAddress - (*DataMessage_Contact_Avatar)(nil), // 78: signalservice.DataMessage.Contact.Avatar - (*TextAttachment_Gradient)(nil), // 79: signalservice.TextAttachment.Gradient - (*SyncMessage_Sent)(nil), // 80: signalservice.SyncMessage.Sent - (*SyncMessage_Contacts)(nil), // 81: signalservice.SyncMessage.Contacts - (*SyncMessage_Blocked)(nil), // 82: signalservice.SyncMessage.Blocked - (*SyncMessage_Request)(nil), // 83: signalservice.SyncMessage.Request - (*SyncMessage_Read)(nil), // 84: signalservice.SyncMessage.Read - (*SyncMessage_Viewed)(nil), // 85: signalservice.SyncMessage.Viewed - (*SyncMessage_Configuration)(nil), // 86: signalservice.SyncMessage.Configuration - (*SyncMessage_StickerPackOperation)(nil), // 87: signalservice.SyncMessage.StickerPackOperation - (*SyncMessage_ViewOnceOpen)(nil), // 88: signalservice.SyncMessage.ViewOnceOpen - (*SyncMessage_FetchLatest)(nil), // 89: signalservice.SyncMessage.FetchLatest - (*SyncMessage_Keys)(nil), // 90: signalservice.SyncMessage.Keys - (*SyncMessage_PniIdentity)(nil), // 91: signalservice.SyncMessage.PniIdentity - (*SyncMessage_MessageRequestResponse)(nil), // 92: signalservice.SyncMessage.MessageRequestResponse - (*SyncMessage_OutgoingPayment)(nil), // 93: signalservice.SyncMessage.OutgoingPayment - (*SyncMessage_PniChangeNumber)(nil), // 94: signalservice.SyncMessage.PniChangeNumber - (*SyncMessage_CallEvent)(nil), // 95: signalservice.SyncMessage.CallEvent - (*SyncMessage_CallLinkUpdate)(nil), // 96: signalservice.SyncMessage.CallLinkUpdate - (*SyncMessage_CallLogEvent)(nil), // 97: signalservice.SyncMessage.CallLogEvent - (*SyncMessage_DeleteForMe)(nil), // 98: signalservice.SyncMessage.DeleteForMe - (*SyncMessage_DeviceNameChange)(nil), // 99: signalservice.SyncMessage.DeviceNameChange - (*SyncMessage_AttachmentBackfillRequest)(nil), // 100: signalservice.SyncMessage.AttachmentBackfillRequest - (*SyncMessage_AttachmentBackfillResponse)(nil), // 101: signalservice.SyncMessage.AttachmentBackfillResponse - (*SyncMessage_Sent_UnidentifiedDeliveryStatus)(nil), // 102: signalservice.SyncMessage.Sent.UnidentifiedDeliveryStatus - (*SyncMessage_Sent_StoryMessageRecipient)(nil), // 103: signalservice.SyncMessage.Sent.StoryMessageRecipient - (*SyncMessage_OutgoingPayment_MobileCoin)(nil), // 104: signalservice.SyncMessage.OutgoingPayment.MobileCoin - (*SyncMessage_DeleteForMe_MessageDeletes)(nil), // 105: signalservice.SyncMessage.DeleteForMe.MessageDeletes - (*SyncMessage_DeleteForMe_AttachmentDelete)(nil), // 106: signalservice.SyncMessage.DeleteForMe.AttachmentDelete - (*SyncMessage_DeleteForMe_ConversationDelete)(nil), // 107: signalservice.SyncMessage.DeleteForMe.ConversationDelete - (*SyncMessage_DeleteForMe_LocalOnlyConversationDelete)(nil), // 108: signalservice.SyncMessage.DeleteForMe.LocalOnlyConversationDelete - (*SyncMessage_AttachmentBackfillResponse_AttachmentData)(nil), // 109: signalservice.SyncMessage.AttachmentBackfillResponse.AttachmentData - (*SyncMessage_AttachmentBackfillResponse_AttachmentDataList)(nil), // 110: signalservice.SyncMessage.AttachmentBackfillResponse.AttachmentDataList - (*ContactDetails_Avatar)(nil), // 111: signalservice.ContactDetails.Avatar - (*PaymentAddress_MobileCoin)(nil), // 112: signalservice.PaymentAddress.MobileCoin + (*DataMessage_PinMessage)(nil), // 68: signalservice.DataMessage.PinMessage + (*DataMessage_UnpinMessage)(nil), // 69: signalservice.DataMessage.UnpinMessage + (*DataMessage_Payment_Amount)(nil), // 70: signalservice.DataMessage.Payment.Amount + (*DataMessage_Payment_Notification)(nil), // 71: signalservice.DataMessage.Payment.Notification + (*DataMessage_Payment_Activation)(nil), // 72: signalservice.DataMessage.Payment.Activation + (*DataMessage_Payment_Amount_MobileCoin)(nil), // 73: signalservice.DataMessage.Payment.Amount.MobileCoin + (*DataMessage_Payment_Notification_MobileCoin)(nil), // 74: signalservice.DataMessage.Payment.Notification.MobileCoin + (*DataMessage_Quote_QuotedAttachment)(nil), // 75: signalservice.DataMessage.Quote.QuotedAttachment + (*DataMessage_Contact_Name)(nil), // 76: signalservice.DataMessage.Contact.Name + (*DataMessage_Contact_Phone)(nil), // 77: signalservice.DataMessage.Contact.Phone + (*DataMessage_Contact_Email)(nil), // 78: signalservice.DataMessage.Contact.Email + (*DataMessage_Contact_PostalAddress)(nil), // 79: signalservice.DataMessage.Contact.PostalAddress + (*DataMessage_Contact_Avatar)(nil), // 80: signalservice.DataMessage.Contact.Avatar + (*TextAttachment_Gradient)(nil), // 81: signalservice.TextAttachment.Gradient + (*SyncMessage_Sent)(nil), // 82: signalservice.SyncMessage.Sent + (*SyncMessage_Contacts)(nil), // 83: signalservice.SyncMessage.Contacts + (*SyncMessage_Blocked)(nil), // 84: signalservice.SyncMessage.Blocked + (*SyncMessage_Request)(nil), // 85: signalservice.SyncMessage.Request + (*SyncMessage_Read)(nil), // 86: signalservice.SyncMessage.Read + (*SyncMessage_Viewed)(nil), // 87: signalservice.SyncMessage.Viewed + (*SyncMessage_Configuration)(nil), // 88: signalservice.SyncMessage.Configuration + (*SyncMessage_StickerPackOperation)(nil), // 89: signalservice.SyncMessage.StickerPackOperation + (*SyncMessage_ViewOnceOpen)(nil), // 90: signalservice.SyncMessage.ViewOnceOpen + (*SyncMessage_FetchLatest)(nil), // 91: signalservice.SyncMessage.FetchLatest + (*SyncMessage_Keys)(nil), // 92: signalservice.SyncMessage.Keys + (*SyncMessage_PniIdentity)(nil), // 93: signalservice.SyncMessage.PniIdentity + (*SyncMessage_MessageRequestResponse)(nil), // 94: signalservice.SyncMessage.MessageRequestResponse + (*SyncMessage_OutgoingPayment)(nil), // 95: signalservice.SyncMessage.OutgoingPayment + (*SyncMessage_PniChangeNumber)(nil), // 96: signalservice.SyncMessage.PniChangeNumber + (*SyncMessage_CallEvent)(nil), // 97: signalservice.SyncMessage.CallEvent + (*SyncMessage_CallLinkUpdate)(nil), // 98: signalservice.SyncMessage.CallLinkUpdate + (*SyncMessage_CallLogEvent)(nil), // 99: signalservice.SyncMessage.CallLogEvent + (*SyncMessage_DeleteForMe)(nil), // 100: signalservice.SyncMessage.DeleteForMe + (*SyncMessage_DeviceNameChange)(nil), // 101: signalservice.SyncMessage.DeviceNameChange + (*SyncMessage_AttachmentBackfillRequest)(nil), // 102: signalservice.SyncMessage.AttachmentBackfillRequest + (*SyncMessage_AttachmentBackfillResponse)(nil), // 103: signalservice.SyncMessage.AttachmentBackfillResponse + (*SyncMessage_Sent_UnidentifiedDeliveryStatus)(nil), // 104: signalservice.SyncMessage.Sent.UnidentifiedDeliveryStatus + (*SyncMessage_Sent_StoryMessageRecipient)(nil), // 105: signalservice.SyncMessage.Sent.StoryMessageRecipient + (*SyncMessage_OutgoingPayment_MobileCoin)(nil), // 106: signalservice.SyncMessage.OutgoingPayment.MobileCoin + (*SyncMessage_DeleteForMe_MessageDeletes)(nil), // 107: signalservice.SyncMessage.DeleteForMe.MessageDeletes + (*SyncMessage_DeleteForMe_AttachmentDelete)(nil), // 108: signalservice.SyncMessage.DeleteForMe.AttachmentDelete + (*SyncMessage_DeleteForMe_ConversationDelete)(nil), // 109: signalservice.SyncMessage.DeleteForMe.ConversationDelete + (*SyncMessage_DeleteForMe_LocalOnlyConversationDelete)(nil), // 110: signalservice.SyncMessage.DeleteForMe.LocalOnlyConversationDelete + (*SyncMessage_AttachmentBackfillResponse_AttachmentData)(nil), // 111: signalservice.SyncMessage.AttachmentBackfillResponse.AttachmentData + (*SyncMessage_AttachmentBackfillResponse_AttachmentDataList)(nil), // 112: signalservice.SyncMessage.AttachmentBackfillResponse.AttachmentDataList + (*ContactDetails_Avatar)(nil), // 113: signalservice.ContactDetails.Avatar + (*PaymentAddress_MobileCoin)(nil), // 114: signalservice.PaymentAddress.MobileCoin } var file_SignalService_proto_depIdxs = []int32{ 0, // 0: signalservice.Envelope.type:type_name -> signalservice.Envelope.Type @@ -8804,108 +9192,110 @@ var file_SignalService_proto_depIdxs = []int32{ 65, // 29: signalservice.DataMessage.pollCreate:type_name -> signalservice.DataMessage.PollCreate 66, // 30: signalservice.DataMessage.pollTerminate:type_name -> signalservice.DataMessage.PollTerminate 67, // 31: signalservice.DataMessage.pollVote:type_name -> signalservice.DataMessage.PollVote - 11, // 32: signalservice.ReceiptMessage.type:type_name -> signalservice.ReceiptMessage.Type - 12, // 33: signalservice.TypingMessage.action:type_name -> signalservice.TypingMessage.Action - 41, // 34: signalservice.StoryMessage.group:type_name -> signalservice.GroupContextV2 - 40, // 35: signalservice.StoryMessage.fileAttachment:type_name -> signalservice.AttachmentPointer - 37, // 36: signalservice.StoryMessage.textAttachment:type_name -> signalservice.TextAttachment - 47, // 37: signalservice.StoryMessage.bodyRanges:type_name -> signalservice.BodyRange - 40, // 38: signalservice.Preview.image:type_name -> signalservice.AttachmentPointer - 13, // 39: signalservice.TextAttachment.textStyle:type_name -> signalservice.TextAttachment.Style - 36, // 40: signalservice.TextAttachment.preview:type_name -> signalservice.Preview - 79, // 41: signalservice.TextAttachment.gradient:type_name -> signalservice.TextAttachment.Gradient - 14, // 42: signalservice.Verified.state:type_name -> signalservice.Verified.State - 80, // 43: signalservice.SyncMessage.sent:type_name -> signalservice.SyncMessage.Sent - 81, // 44: signalservice.SyncMessage.contacts:type_name -> signalservice.SyncMessage.Contacts - 83, // 45: signalservice.SyncMessage.request:type_name -> signalservice.SyncMessage.Request - 84, // 46: signalservice.SyncMessage.read:type_name -> signalservice.SyncMessage.Read - 82, // 47: signalservice.SyncMessage.blocked:type_name -> signalservice.SyncMessage.Blocked - 38, // 48: signalservice.SyncMessage.verified:type_name -> signalservice.Verified - 86, // 49: signalservice.SyncMessage.configuration:type_name -> signalservice.SyncMessage.Configuration - 87, // 50: signalservice.SyncMessage.stickerPackOperation:type_name -> signalservice.SyncMessage.StickerPackOperation - 88, // 51: signalservice.SyncMessage.viewOnceOpen:type_name -> signalservice.SyncMessage.ViewOnceOpen - 89, // 52: signalservice.SyncMessage.fetchLatest:type_name -> signalservice.SyncMessage.FetchLatest - 90, // 53: signalservice.SyncMessage.keys:type_name -> signalservice.SyncMessage.Keys - 92, // 54: signalservice.SyncMessage.messageRequestResponse:type_name -> signalservice.SyncMessage.MessageRequestResponse - 93, // 55: signalservice.SyncMessage.outgoingPayment:type_name -> signalservice.SyncMessage.OutgoingPayment - 85, // 56: signalservice.SyncMessage.viewed:type_name -> signalservice.SyncMessage.Viewed - 94, // 57: signalservice.SyncMessage.pniChangeNumber:type_name -> signalservice.SyncMessage.PniChangeNumber - 95, // 58: signalservice.SyncMessage.callEvent:type_name -> signalservice.SyncMessage.CallEvent - 96, // 59: signalservice.SyncMessage.callLinkUpdate:type_name -> signalservice.SyncMessage.CallLinkUpdate - 97, // 60: signalservice.SyncMessage.callLogEvent:type_name -> signalservice.SyncMessage.CallLogEvent - 98, // 61: signalservice.SyncMessage.deleteForMe:type_name -> signalservice.SyncMessage.DeleteForMe - 99, // 62: signalservice.SyncMessage.deviceNameChange:type_name -> signalservice.SyncMessage.DeviceNameChange - 100, // 63: signalservice.SyncMessage.attachmentBackfillRequest:type_name -> signalservice.SyncMessage.AttachmentBackfillRequest - 101, // 64: signalservice.SyncMessage.attachmentBackfillResponse:type_name -> signalservice.SyncMessage.AttachmentBackfillResponse - 111, // 65: signalservice.ContactDetails.avatar:type_name -> signalservice.ContactDetails.Avatar - 112, // 66: signalservice.PaymentAddress.mobileCoin:type_name -> signalservice.PaymentAddress.MobileCoin - 31, // 67: signalservice.EditMessage.dataMessage:type_name -> signalservice.DataMessage - 27, // 68: signalservice.BodyRange.style:type_name -> signalservice.BodyRange.Style - 1, // 69: signalservice.CallMessage.Offer.type:type_name -> signalservice.CallMessage.Offer.Type - 2, // 70: signalservice.CallMessage.Hangup.type:type_name -> signalservice.CallMessage.Hangup.Type - 3, // 71: signalservice.CallMessage.Opaque.urgency:type_name -> signalservice.CallMessage.Opaque.Urgency - 69, // 72: signalservice.DataMessage.Payment.notification:type_name -> signalservice.DataMessage.Payment.Notification - 70, // 73: signalservice.DataMessage.Payment.activation:type_name -> signalservice.DataMessage.Payment.Activation - 73, // 74: signalservice.DataMessage.Quote.attachments:type_name -> signalservice.DataMessage.Quote.QuotedAttachment - 47, // 75: signalservice.DataMessage.Quote.bodyRanges:type_name -> signalservice.BodyRange - 7, // 76: signalservice.DataMessage.Quote.type:type_name -> signalservice.DataMessage.Quote.Type - 74, // 77: signalservice.DataMessage.Contact.name:type_name -> signalservice.DataMessage.Contact.Name - 75, // 78: signalservice.DataMessage.Contact.number:type_name -> signalservice.DataMessage.Contact.Phone - 76, // 79: signalservice.DataMessage.Contact.email:type_name -> signalservice.DataMessage.Contact.Email - 77, // 80: signalservice.DataMessage.Contact.address:type_name -> signalservice.DataMessage.Contact.PostalAddress - 78, // 81: signalservice.DataMessage.Contact.avatar:type_name -> signalservice.DataMessage.Contact.Avatar - 40, // 82: signalservice.DataMessage.Sticker.data:type_name -> signalservice.AttachmentPointer - 71, // 83: signalservice.DataMessage.Payment.Amount.mobileCoin:type_name -> signalservice.DataMessage.Payment.Amount.MobileCoin - 72, // 84: signalservice.DataMessage.Payment.Notification.mobileCoin:type_name -> signalservice.DataMessage.Payment.Notification.MobileCoin - 6, // 85: signalservice.DataMessage.Payment.Activation.type:type_name -> signalservice.DataMessage.Payment.Activation.Type - 40, // 86: signalservice.DataMessage.Quote.QuotedAttachment.thumbnail:type_name -> signalservice.AttachmentPointer - 8, // 87: signalservice.DataMessage.Contact.Phone.type:type_name -> signalservice.DataMessage.Contact.Phone.Type - 9, // 88: signalservice.DataMessage.Contact.Email.type:type_name -> signalservice.DataMessage.Contact.Email.Type - 10, // 89: signalservice.DataMessage.Contact.PostalAddress.type:type_name -> signalservice.DataMessage.Contact.PostalAddress.Type - 40, // 90: signalservice.DataMessage.Contact.Avatar.avatar:type_name -> signalservice.AttachmentPointer - 31, // 91: signalservice.SyncMessage.Sent.message:type_name -> signalservice.DataMessage - 102, // 92: signalservice.SyncMessage.Sent.unidentifiedStatus:type_name -> signalservice.SyncMessage.Sent.UnidentifiedDeliveryStatus - 35, // 93: signalservice.SyncMessage.Sent.storyMessage:type_name -> signalservice.StoryMessage - 103, // 94: signalservice.SyncMessage.Sent.storyMessageRecipients:type_name -> signalservice.SyncMessage.Sent.StoryMessageRecipient - 46, // 95: signalservice.SyncMessage.Sent.editMessage:type_name -> signalservice.EditMessage - 40, // 96: signalservice.SyncMessage.Contacts.blob:type_name -> signalservice.AttachmentPointer - 15, // 97: signalservice.SyncMessage.Request.type:type_name -> signalservice.SyncMessage.Request.Type - 16, // 98: signalservice.SyncMessage.StickerPackOperation.type:type_name -> signalservice.SyncMessage.StickerPackOperation.Type - 17, // 99: signalservice.SyncMessage.FetchLatest.type:type_name -> signalservice.SyncMessage.FetchLatest.Type - 18, // 100: signalservice.SyncMessage.MessageRequestResponse.type:type_name -> signalservice.SyncMessage.MessageRequestResponse.Type - 104, // 101: signalservice.SyncMessage.OutgoingPayment.mobileCoin:type_name -> signalservice.SyncMessage.OutgoingPayment.MobileCoin - 19, // 102: signalservice.SyncMessage.CallEvent.type:type_name -> signalservice.SyncMessage.CallEvent.Type - 20, // 103: signalservice.SyncMessage.CallEvent.direction:type_name -> signalservice.SyncMessage.CallEvent.Direction - 21, // 104: signalservice.SyncMessage.CallEvent.event:type_name -> signalservice.SyncMessage.CallEvent.Event - 22, // 105: signalservice.SyncMessage.CallLinkUpdate.type:type_name -> signalservice.SyncMessage.CallLinkUpdate.Type - 23, // 106: signalservice.SyncMessage.CallLogEvent.type:type_name -> signalservice.SyncMessage.CallLogEvent.Type - 105, // 107: signalservice.SyncMessage.DeleteForMe.messageDeletes:type_name -> signalservice.SyncMessage.DeleteForMe.MessageDeletes - 107, // 108: signalservice.SyncMessage.DeleteForMe.conversationDeletes:type_name -> signalservice.SyncMessage.DeleteForMe.ConversationDelete - 108, // 109: signalservice.SyncMessage.DeleteForMe.localOnlyConversationDeletes:type_name -> signalservice.SyncMessage.DeleteForMe.LocalOnlyConversationDelete - 106, // 110: signalservice.SyncMessage.DeleteForMe.attachmentDeletes:type_name -> signalservice.SyncMessage.DeleteForMe.AttachmentDelete - 48, // 111: signalservice.SyncMessage.AttachmentBackfillRequest.targetMessage:type_name -> signalservice.AddressableMessage - 49, // 112: signalservice.SyncMessage.AttachmentBackfillRequest.targetConversation:type_name -> signalservice.ConversationIdentifier - 48, // 113: signalservice.SyncMessage.AttachmentBackfillResponse.targetMessage:type_name -> signalservice.AddressableMessage - 49, // 114: signalservice.SyncMessage.AttachmentBackfillResponse.targetConversation:type_name -> signalservice.ConversationIdentifier - 110, // 115: signalservice.SyncMessage.AttachmentBackfillResponse.attachments:type_name -> signalservice.SyncMessage.AttachmentBackfillResponse.AttachmentDataList - 24, // 116: signalservice.SyncMessage.AttachmentBackfillResponse.error:type_name -> signalservice.SyncMessage.AttachmentBackfillResponse.Error - 49, // 117: signalservice.SyncMessage.DeleteForMe.MessageDeletes.conversation:type_name -> signalservice.ConversationIdentifier - 48, // 118: signalservice.SyncMessage.DeleteForMe.MessageDeletes.messages:type_name -> signalservice.AddressableMessage - 49, // 119: signalservice.SyncMessage.DeleteForMe.AttachmentDelete.conversation:type_name -> signalservice.ConversationIdentifier - 48, // 120: signalservice.SyncMessage.DeleteForMe.AttachmentDelete.targetMessage:type_name -> signalservice.AddressableMessage - 49, // 121: signalservice.SyncMessage.DeleteForMe.ConversationDelete.conversation:type_name -> signalservice.ConversationIdentifier - 48, // 122: signalservice.SyncMessage.DeleteForMe.ConversationDelete.mostRecentMessages:type_name -> signalservice.AddressableMessage - 48, // 123: signalservice.SyncMessage.DeleteForMe.ConversationDelete.mostRecentNonExpiringMessages:type_name -> signalservice.AddressableMessage - 49, // 124: signalservice.SyncMessage.DeleteForMe.LocalOnlyConversationDelete.conversation:type_name -> signalservice.ConversationIdentifier - 40, // 125: signalservice.SyncMessage.AttachmentBackfillResponse.AttachmentData.attachment:type_name -> signalservice.AttachmentPointer - 25, // 126: signalservice.SyncMessage.AttachmentBackfillResponse.AttachmentData.status:type_name -> signalservice.SyncMessage.AttachmentBackfillResponse.AttachmentData.Status - 109, // 127: signalservice.SyncMessage.AttachmentBackfillResponse.AttachmentDataList.attachments:type_name -> signalservice.SyncMessage.AttachmentBackfillResponse.AttachmentData - 109, // 128: signalservice.SyncMessage.AttachmentBackfillResponse.AttachmentDataList.longText:type_name -> signalservice.SyncMessage.AttachmentBackfillResponse.AttachmentData - 129, // [129:129] is the sub-list for method output_type - 129, // [129:129] is the sub-list for method input_type - 129, // [129:129] is the sub-list for extension type_name - 129, // [129:129] is the sub-list for extension extendee - 0, // [0:129] is the sub-list for field type_name + 68, // 32: signalservice.DataMessage.pinMessage:type_name -> signalservice.DataMessage.PinMessage + 69, // 33: signalservice.DataMessage.unpinMessage:type_name -> signalservice.DataMessage.UnpinMessage + 11, // 34: signalservice.ReceiptMessage.type:type_name -> signalservice.ReceiptMessage.Type + 12, // 35: signalservice.TypingMessage.action:type_name -> signalservice.TypingMessage.Action + 41, // 36: signalservice.StoryMessage.group:type_name -> signalservice.GroupContextV2 + 40, // 37: signalservice.StoryMessage.fileAttachment:type_name -> signalservice.AttachmentPointer + 37, // 38: signalservice.StoryMessage.textAttachment:type_name -> signalservice.TextAttachment + 47, // 39: signalservice.StoryMessage.bodyRanges:type_name -> signalservice.BodyRange + 40, // 40: signalservice.Preview.image:type_name -> signalservice.AttachmentPointer + 13, // 41: signalservice.TextAttachment.textStyle:type_name -> signalservice.TextAttachment.Style + 36, // 42: signalservice.TextAttachment.preview:type_name -> signalservice.Preview + 81, // 43: signalservice.TextAttachment.gradient:type_name -> signalservice.TextAttachment.Gradient + 14, // 44: signalservice.Verified.state:type_name -> signalservice.Verified.State + 82, // 45: signalservice.SyncMessage.sent:type_name -> signalservice.SyncMessage.Sent + 83, // 46: signalservice.SyncMessage.contacts:type_name -> signalservice.SyncMessage.Contacts + 85, // 47: signalservice.SyncMessage.request:type_name -> signalservice.SyncMessage.Request + 86, // 48: signalservice.SyncMessage.read:type_name -> signalservice.SyncMessage.Read + 84, // 49: signalservice.SyncMessage.blocked:type_name -> signalservice.SyncMessage.Blocked + 38, // 50: signalservice.SyncMessage.verified:type_name -> signalservice.Verified + 88, // 51: signalservice.SyncMessage.configuration:type_name -> signalservice.SyncMessage.Configuration + 89, // 52: signalservice.SyncMessage.stickerPackOperation:type_name -> signalservice.SyncMessage.StickerPackOperation + 90, // 53: signalservice.SyncMessage.viewOnceOpen:type_name -> signalservice.SyncMessage.ViewOnceOpen + 91, // 54: signalservice.SyncMessage.fetchLatest:type_name -> signalservice.SyncMessage.FetchLatest + 92, // 55: signalservice.SyncMessage.keys:type_name -> signalservice.SyncMessage.Keys + 94, // 56: signalservice.SyncMessage.messageRequestResponse:type_name -> signalservice.SyncMessage.MessageRequestResponse + 95, // 57: signalservice.SyncMessage.outgoingPayment:type_name -> signalservice.SyncMessage.OutgoingPayment + 87, // 58: signalservice.SyncMessage.viewed:type_name -> signalservice.SyncMessage.Viewed + 96, // 59: signalservice.SyncMessage.pniChangeNumber:type_name -> signalservice.SyncMessage.PniChangeNumber + 97, // 60: signalservice.SyncMessage.callEvent:type_name -> signalservice.SyncMessage.CallEvent + 98, // 61: signalservice.SyncMessage.callLinkUpdate:type_name -> signalservice.SyncMessage.CallLinkUpdate + 99, // 62: signalservice.SyncMessage.callLogEvent:type_name -> signalservice.SyncMessage.CallLogEvent + 100, // 63: signalservice.SyncMessage.deleteForMe:type_name -> signalservice.SyncMessage.DeleteForMe + 101, // 64: signalservice.SyncMessage.deviceNameChange:type_name -> signalservice.SyncMessage.DeviceNameChange + 102, // 65: signalservice.SyncMessage.attachmentBackfillRequest:type_name -> signalservice.SyncMessage.AttachmentBackfillRequest + 103, // 66: signalservice.SyncMessage.attachmentBackfillResponse:type_name -> signalservice.SyncMessage.AttachmentBackfillResponse + 113, // 67: signalservice.ContactDetails.avatar:type_name -> signalservice.ContactDetails.Avatar + 114, // 68: signalservice.PaymentAddress.mobileCoin:type_name -> signalservice.PaymentAddress.MobileCoin + 31, // 69: signalservice.EditMessage.dataMessage:type_name -> signalservice.DataMessage + 27, // 70: signalservice.BodyRange.style:type_name -> signalservice.BodyRange.Style + 1, // 71: signalservice.CallMessage.Offer.type:type_name -> signalservice.CallMessage.Offer.Type + 2, // 72: signalservice.CallMessage.Hangup.type:type_name -> signalservice.CallMessage.Hangup.Type + 3, // 73: signalservice.CallMessage.Opaque.urgency:type_name -> signalservice.CallMessage.Opaque.Urgency + 71, // 74: signalservice.DataMessage.Payment.notification:type_name -> signalservice.DataMessage.Payment.Notification + 72, // 75: signalservice.DataMessage.Payment.activation:type_name -> signalservice.DataMessage.Payment.Activation + 75, // 76: signalservice.DataMessage.Quote.attachments:type_name -> signalservice.DataMessage.Quote.QuotedAttachment + 47, // 77: signalservice.DataMessage.Quote.bodyRanges:type_name -> signalservice.BodyRange + 7, // 78: signalservice.DataMessage.Quote.type:type_name -> signalservice.DataMessage.Quote.Type + 76, // 79: signalservice.DataMessage.Contact.name:type_name -> signalservice.DataMessage.Contact.Name + 77, // 80: signalservice.DataMessage.Contact.number:type_name -> signalservice.DataMessage.Contact.Phone + 78, // 81: signalservice.DataMessage.Contact.email:type_name -> signalservice.DataMessage.Contact.Email + 79, // 82: signalservice.DataMessage.Contact.address:type_name -> signalservice.DataMessage.Contact.PostalAddress + 80, // 83: signalservice.DataMessage.Contact.avatar:type_name -> signalservice.DataMessage.Contact.Avatar + 40, // 84: signalservice.DataMessage.Sticker.data:type_name -> signalservice.AttachmentPointer + 73, // 85: signalservice.DataMessage.Payment.Amount.mobileCoin:type_name -> signalservice.DataMessage.Payment.Amount.MobileCoin + 74, // 86: signalservice.DataMessage.Payment.Notification.mobileCoin:type_name -> signalservice.DataMessage.Payment.Notification.MobileCoin + 6, // 87: signalservice.DataMessage.Payment.Activation.type:type_name -> signalservice.DataMessage.Payment.Activation.Type + 40, // 88: signalservice.DataMessage.Quote.QuotedAttachment.thumbnail:type_name -> signalservice.AttachmentPointer + 8, // 89: signalservice.DataMessage.Contact.Phone.type:type_name -> signalservice.DataMessage.Contact.Phone.Type + 9, // 90: signalservice.DataMessage.Contact.Email.type:type_name -> signalservice.DataMessage.Contact.Email.Type + 10, // 91: signalservice.DataMessage.Contact.PostalAddress.type:type_name -> signalservice.DataMessage.Contact.PostalAddress.Type + 40, // 92: signalservice.DataMessage.Contact.Avatar.avatar:type_name -> signalservice.AttachmentPointer + 31, // 93: signalservice.SyncMessage.Sent.message:type_name -> signalservice.DataMessage + 104, // 94: signalservice.SyncMessage.Sent.unidentifiedStatus:type_name -> signalservice.SyncMessage.Sent.UnidentifiedDeliveryStatus + 35, // 95: signalservice.SyncMessage.Sent.storyMessage:type_name -> signalservice.StoryMessage + 105, // 96: signalservice.SyncMessage.Sent.storyMessageRecipients:type_name -> signalservice.SyncMessage.Sent.StoryMessageRecipient + 46, // 97: signalservice.SyncMessage.Sent.editMessage:type_name -> signalservice.EditMessage + 40, // 98: signalservice.SyncMessage.Contacts.blob:type_name -> signalservice.AttachmentPointer + 15, // 99: signalservice.SyncMessage.Request.type:type_name -> signalservice.SyncMessage.Request.Type + 16, // 100: signalservice.SyncMessage.StickerPackOperation.type:type_name -> signalservice.SyncMessage.StickerPackOperation.Type + 17, // 101: signalservice.SyncMessage.FetchLatest.type:type_name -> signalservice.SyncMessage.FetchLatest.Type + 18, // 102: signalservice.SyncMessage.MessageRequestResponse.type:type_name -> signalservice.SyncMessage.MessageRequestResponse.Type + 106, // 103: signalservice.SyncMessage.OutgoingPayment.mobileCoin:type_name -> signalservice.SyncMessage.OutgoingPayment.MobileCoin + 19, // 104: signalservice.SyncMessage.CallEvent.type:type_name -> signalservice.SyncMessage.CallEvent.Type + 20, // 105: signalservice.SyncMessage.CallEvent.direction:type_name -> signalservice.SyncMessage.CallEvent.Direction + 21, // 106: signalservice.SyncMessage.CallEvent.event:type_name -> signalservice.SyncMessage.CallEvent.Event + 22, // 107: signalservice.SyncMessage.CallLinkUpdate.type:type_name -> signalservice.SyncMessage.CallLinkUpdate.Type + 23, // 108: signalservice.SyncMessage.CallLogEvent.type:type_name -> signalservice.SyncMessage.CallLogEvent.Type + 107, // 109: signalservice.SyncMessage.DeleteForMe.messageDeletes:type_name -> signalservice.SyncMessage.DeleteForMe.MessageDeletes + 109, // 110: signalservice.SyncMessage.DeleteForMe.conversationDeletes:type_name -> signalservice.SyncMessage.DeleteForMe.ConversationDelete + 110, // 111: signalservice.SyncMessage.DeleteForMe.localOnlyConversationDeletes:type_name -> signalservice.SyncMessage.DeleteForMe.LocalOnlyConversationDelete + 108, // 112: signalservice.SyncMessage.DeleteForMe.attachmentDeletes:type_name -> signalservice.SyncMessage.DeleteForMe.AttachmentDelete + 48, // 113: signalservice.SyncMessage.AttachmentBackfillRequest.targetMessage:type_name -> signalservice.AddressableMessage + 49, // 114: signalservice.SyncMessage.AttachmentBackfillRequest.targetConversation:type_name -> signalservice.ConversationIdentifier + 48, // 115: signalservice.SyncMessage.AttachmentBackfillResponse.targetMessage:type_name -> signalservice.AddressableMessage + 49, // 116: signalservice.SyncMessage.AttachmentBackfillResponse.targetConversation:type_name -> signalservice.ConversationIdentifier + 112, // 117: signalservice.SyncMessage.AttachmentBackfillResponse.attachments:type_name -> signalservice.SyncMessage.AttachmentBackfillResponse.AttachmentDataList + 24, // 118: signalservice.SyncMessage.AttachmentBackfillResponse.error:type_name -> signalservice.SyncMessage.AttachmentBackfillResponse.Error + 49, // 119: signalservice.SyncMessage.DeleteForMe.MessageDeletes.conversation:type_name -> signalservice.ConversationIdentifier + 48, // 120: signalservice.SyncMessage.DeleteForMe.MessageDeletes.messages:type_name -> signalservice.AddressableMessage + 49, // 121: signalservice.SyncMessage.DeleteForMe.AttachmentDelete.conversation:type_name -> signalservice.ConversationIdentifier + 48, // 122: signalservice.SyncMessage.DeleteForMe.AttachmentDelete.targetMessage:type_name -> signalservice.AddressableMessage + 49, // 123: signalservice.SyncMessage.DeleteForMe.ConversationDelete.conversation:type_name -> signalservice.ConversationIdentifier + 48, // 124: signalservice.SyncMessage.DeleteForMe.ConversationDelete.mostRecentMessages:type_name -> signalservice.AddressableMessage + 48, // 125: signalservice.SyncMessage.DeleteForMe.ConversationDelete.mostRecentNonExpiringMessages:type_name -> signalservice.AddressableMessage + 49, // 126: signalservice.SyncMessage.DeleteForMe.LocalOnlyConversationDelete.conversation:type_name -> signalservice.ConversationIdentifier + 40, // 127: signalservice.SyncMessage.AttachmentBackfillResponse.AttachmentData.attachment:type_name -> signalservice.AttachmentPointer + 25, // 128: signalservice.SyncMessage.AttachmentBackfillResponse.AttachmentData.status:type_name -> signalservice.SyncMessage.AttachmentBackfillResponse.AttachmentData.Status + 111, // 129: signalservice.SyncMessage.AttachmentBackfillResponse.AttachmentDataList.attachments:type_name -> signalservice.SyncMessage.AttachmentBackfillResponse.AttachmentData + 111, // 130: signalservice.SyncMessage.AttachmentBackfillResponse.AttachmentDataList.longText:type_name -> signalservice.SyncMessage.AttachmentBackfillResponse.AttachmentData + 131, // [131:131] is the sub-list for method output_type + 131, // [131:131] is the sub-list for method input_type + 131, // [131:131] is the sub-list for extension type_name + 131, // [131:131] is the sub-list for extension extendee + 0, // [0:131] is the sub-list for field type_name } func init() { file_SignalService_proto_init() } @@ -8931,34 +9321,41 @@ func file_SignalService_proto_init() { file_SignalService_proto_msgTypes[19].OneofWrappers = []any{ (*BodyRange_MentionAci)(nil), (*BodyRange_Style_)(nil), + (*BodyRange_MentionAciBinary)(nil), } file_SignalService_proto_msgTypes[20].OneofWrappers = []any{ (*AddressableMessage_AuthorServiceId)(nil), (*AddressableMessage_AuthorE164)(nil), + (*AddressableMessage_AuthorServiceIdBinary)(nil), } file_SignalService_proto_msgTypes[21].OneofWrappers = []any{ (*ConversationIdentifier_ThreadServiceId)(nil), (*ConversationIdentifier_ThreadGroupId)(nil), (*ConversationIdentifier_ThreadE164)(nil), + (*ConversationIdentifier_ThreadServiceIdBinary)(nil), } file_SignalService_proto_msgTypes[28].OneofWrappers = []any{ (*DataMessage_Payment_Notification_)(nil), (*DataMessage_Payment_Activation_)(nil), } file_SignalService_proto_msgTypes[40].OneofWrappers = []any{ + (*DataMessage_PinMessage_PinDurationSeconds)(nil), + (*DataMessage_PinMessage_PinDurationForever)(nil), + } + file_SignalService_proto_msgTypes[42].OneofWrappers = []any{ (*DataMessage_Payment_Amount_MobileCoin_)(nil), } - file_SignalService_proto_msgTypes[41].OneofWrappers = []any{ + file_SignalService_proto_msgTypes[43].OneofWrappers = []any{ (*DataMessage_Payment_Notification_MobileCoin_)(nil), } - file_SignalService_proto_msgTypes[65].OneofWrappers = []any{ + file_SignalService_proto_msgTypes[67].OneofWrappers = []any{ (*SyncMessage_OutgoingPayment_MobileCoin_)(nil), } - file_SignalService_proto_msgTypes[73].OneofWrappers = []any{ + file_SignalService_proto_msgTypes[75].OneofWrappers = []any{ (*SyncMessage_AttachmentBackfillResponse_Attachments)(nil), (*SyncMessage_AttachmentBackfillResponse_Error_)(nil), } - file_SignalService_proto_msgTypes[81].OneofWrappers = []any{ + file_SignalService_proto_msgTypes[83].OneofWrappers = []any{ (*SyncMessage_AttachmentBackfillResponse_AttachmentData_Attachment)(nil), (*SyncMessage_AttachmentBackfillResponse_AttachmentData_Status_)(nil), } @@ -8968,7 +9365,7 @@ func file_SignalService_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: unsafe.Slice(unsafe.StringData(file_SignalService_proto_rawDesc), len(file_SignalService_proto_rawDesc)), NumEnums: 28, - NumMessages: 85, + NumMessages: 87, NumExtensions: 0, NumServices: 0, }, diff --git a/pkg/signalmeow/protobuf/SignalService.proto b/pkg/signalmeow/protobuf/SignalService.proto index 249c4eb..da4d44f 100644 --- a/pkg/signalmeow/protobuf/SignalService.proto +++ b/pkg/signalmeow/protobuf/SignalService.proto @@ -40,7 +40,11 @@ message Envelope { optional bool story = 16; // indicates that the content is a story. optional bytes report_spam_token = 17; // token sent when reporting spam reserved 18; // internal server use - // next: 19 + optional bytes sourceServiceIdBinary = 19; // service ID binary (i.e. 16 byte UUID for ACI, 1 byte prefix + 16 byte UUID for PNI) + optional bytes destinationServiceIdBinary = 20; // service ID binary (i.e. 16 byte UUID for ACI, 1 byte prefix + 16 byte UUID for PNI) + optional bytes serverGuidBinary = 21; // 16-byte UUID + optional bytes updatedPniBinary = 22; // 16-byte UUID + // next: 22 } message Content { @@ -193,6 +197,7 @@ message DataMessage { repeated QuotedAttachment attachments = 4; repeated BodyRange bodyRanges = 6; optional Type type = 7; + optional bytes authorAciBinary = 8; // 16-byte UUID } message Contact { @@ -277,6 +282,7 @@ message DataMessage { reserved /* targetAuthorE164 */ 3; optional string targetAuthorAci = 4; optional uint64 targetSentTimestamp = 5; + optional bytes targetAuthorAciBinary = 6; // 16-byte UUID } message Delete { @@ -290,6 +296,7 @@ message DataMessage { message StoryContext { optional string authorAci = 1; optional uint64 sentTimestamp = 2; + optional bytes authorAciBinary = 3; // 16-byte UUID } enum ProtocolVersion { @@ -304,7 +311,7 @@ message DataMessage { MENTIONS = 6; PAYMENTS = 7; POLLS = 8; - CURRENT = 7; + CURRENT = 8; } message GiftBadge { @@ -328,6 +335,20 @@ message DataMessage { optional uint32 voteCount = 4; // increment this by 1 each time you vote on a given poll } + message PinMessage { + optional bytes targetAuthorAciBinary = 1; // 16-byte UUID + optional uint64 targetSentTimestamp = 2; + oneof pinDuration { + uint32 pinDurationSeconds = 3; + bool pinDurationForever = 4; + } + } + + message UnpinMessage { + optional bytes targetAuthorAciBinary = 1; // 16-byte UUID + optional uint64 targetSentTimestamp = 2; + } + optional string body = 1; repeated AttachmentPointer attachments = 2; reserved /*groupV1*/ 3; @@ -353,7 +374,9 @@ message DataMessage { optional PollCreate pollCreate = 24; optional PollTerminate pollTerminate = 25; optional PollVote pollVote = 26; - // NEXT ID: 27 + optional PinMessage pinMessage = 27; + optional UnpinMessage unpinMessage = 28; + // NEXT ID: 29 } message NullMessage { @@ -442,6 +465,7 @@ message Verified { optional bytes identityKey = 2; optional State state = 3; optional bytes nullMessage = 4; + optional bytes destinationAciBinary = 6; // 16-byte UUID } message SyncMessage { @@ -452,6 +476,7 @@ message SyncMessage { optional bool unidentified = 2; reserved /*destinationPni */ 4; optional bytes destinationPniIdentityKey = 5; // Only set for PNI destinations + optional bytes destinationServiceIdBinary = 6; // service ID binary (i.e. 16 byte UUID for ACI, 1 byte prefix + 16 byte UUID for PNI) } message StoryMessageRecipient { @@ -459,6 +484,7 @@ message SyncMessage { repeated string distributionListIds = 2; optional bool isAllowedToReply = 3; reserved /*destinationPni */ 4; + optional bytes destinationServiceIdBinary = 5; // service ID binary (i.e. 16 byte UUID for ACI, 1 byte prefix + 16 byte UUID for PNI) } optional string destinationE164 = 1; @@ -472,7 +498,8 @@ message SyncMessage { repeated StoryMessageRecipient storyMessageRecipients = 9; optional EditMessage editMessage = 10; reserved /*destinationPni */ 11; - // Next ID: 12 + optional bytes destinationServiceIdBinary = 12; // service ID binary (i.e. 16 byte UUID for ACI, 1 byte prefix + 16 byte UUID for PNI) + // Next ID: 13 } message Contacts { @@ -484,6 +511,7 @@ message SyncMessage { repeated string numbers = 1; repeated string acis = 3; repeated bytes groupIds = 2; + repeated bytes acisBinary = 4; // 16-byte UUID } message Request { @@ -504,12 +532,14 @@ message SyncMessage { reserved /*senderE164*/ 1; optional string senderAci = 3; optional uint64 timestamp = 2; + optional bytes senderAciBinary = 4; // 16-byte UUID } message Viewed { reserved /*senderE164*/ 1; optional string senderAci = 3; optional uint64 timestamp = 2; + optional bytes senderAciBinary = 4; // 16-byte UUID } message Configuration { @@ -536,6 +566,7 @@ message SyncMessage { reserved /*senderE164*/ 1; optional string senderAci = 3; optional uint64 timestamp = 2; + optional bytes senderAciBinary = 4; // 16-byte UUID } message FetchLatest { @@ -576,6 +607,7 @@ message SyncMessage { optional string threadAci = 2; optional bytes groupId = 3; optional Type type = 4; + optional bytes threadAciBinary = 5; // 16-byte UUID } message OutgoingPayment { @@ -823,6 +855,7 @@ message ContactDetails { optional string number = 1; optional string aci = 9; + optional bytes aciBinary = 13; // 16-byte UUID optional string name = 2; optional Avatar avatar = 3; reserved /* color */ 4; @@ -833,7 +866,7 @@ message ContactDetails { optional uint32 expireTimerVersion = 12; optional uint32 inboxPosition = 10; reserved /* archived */ 11; - // NEXT ID: 13 + // NEXT ID: 14 } message PaymentAddress { @@ -880,6 +913,7 @@ message BodyRange { oneof associatedValue { string mentionAci = 3; Style style = 4; + bytes mentionAciBinary = 5; // 16-byte UUID } } @@ -887,6 +921,7 @@ message AddressableMessage { oneof author { string authorServiceId = 1; string authorE164 = 2; + bytes authorServiceIdBinary = 4; // service ID binary (i.e. 16 byte UUID for ACI, 1 byte prefix + 16 byte UUID for PNI) } optional uint64 sentTimestamp = 3; } @@ -896,5 +931,6 @@ message ConversationIdentifier { string threadServiceId = 1; bytes threadGroupId = 2; string threadE164 = 3; + bytes threadServiceIdBinary = 4; // service ID binary (i.e. 16 byte UUID for ACI, 1 byte prefix + 16 byte UUID for PNI) } } diff --git a/pkg/signalmeow/protobuf/StickerResources.pb.go b/pkg/signalmeow/protobuf/StickerResources.pb.go index 52905c6..e83cda1 100644 --- a/pkg/signalmeow/protobuf/StickerResources.pb.go +++ b/pkg/signalmeow/protobuf/StickerResources.pb.go @@ -5,8 +5,8 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.36.10 -// protoc v3.21.12 +// protoc-gen-go v1.36.11 +// protoc v6.33.5 // source: StickerResources.proto package signalpb diff --git a/pkg/signalmeow/protobuf/StorageService.pb.go b/pkg/signalmeow/protobuf/StorageService.pb.go index 1294a3f..9a27146 100644 --- a/pkg/signalmeow/protobuf/StorageService.pb.go +++ b/pkg/signalmeow/protobuf/StorageService.pb.go @@ -5,8 +5,8 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.36.10 -// protoc v3.21.12 +// protoc-gen-go v1.36.11 +// protoc v6.33.5 // source: StorageService.proto package signalpb @@ -1086,7 +1086,9 @@ type ContactRecord struct { PniSignatureVerified bool `protobuf:"varint,21,opt,name=pniSignatureVerified,proto3" json:"pniSignatureVerified,omitempty"` Nickname *ContactRecord_Name `protobuf:"bytes,22,opt,name=nickname,proto3" json:"nickname,omitempty"` Note string `protobuf:"bytes,23,opt,name=note,proto3" json:"note,omitempty"` - AvatarColor *AvatarColor `protobuf:"varint,24,opt,name=avatarColor,proto3,enum=signalservice.AvatarColor,oneof" json:"avatarColor,omitempty"` // Next ID: 25 + AvatarColor *AvatarColor `protobuf:"varint,24,opt,name=avatarColor,proto3,enum=signalservice.AvatarColor,oneof" json:"avatarColor,omitempty"` + AciBinary []byte `protobuf:"bytes,25,opt,name=aciBinary,proto3" json:"aciBinary,omitempty"` // 16-byte UUID + PniBinary []byte `protobuf:"bytes,26,opt,name=pniBinary,proto3" json:"pniBinary,omitempty"` // 16-byte UUID unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } @@ -1289,6 +1291,20 @@ func (x *ContactRecord) GetAvatarColor() AvatarColor { return AvatarColor_A100 } +func (x *ContactRecord) GetAciBinary() []byte { + if x != nil { + return x.AciBinary + } + return nil +} + +func (x *ContactRecord) GetPniBinary() []byte { + if x != nil { + return x.PniBinary + } + return nil +} + type GroupV1Record struct { state protoimpl.MessageState `protogen:"open.v1"` Id []byte `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` @@ -1580,6 +1596,8 @@ type AccountRecord struct { AvatarColor *AvatarColor `protobuf:"varint,42,opt,name=avatarColor,proto3,enum=signalservice.AvatarColor,oneof" json:"avatarColor,omitempty"` BackupTierHistory *AccountRecord_BackupTierHistory `protobuf:"bytes,43,opt,name=backupTierHistory,proto3" json:"backupTierHistory,omitempty"` NotificationProfileManualOverride *AccountRecord_NotificationProfileManualOverride `protobuf:"bytes,44,opt,name=notificationProfileManualOverride,proto3" json:"notificationProfileManualOverride,omitempty"` + NotificationProfileSyncDisabled bool `protobuf:"varint,45,opt,name=notificationProfileSyncDisabled,proto3" json:"notificationProfileSyncDisabled,omitempty"` + AutomaticKeyVerificationDisabled bool `protobuf:"varint,46,opt,name=automaticKeyVerificationDisabled,proto3" json:"automaticKeyVerificationDisabled,omitempty"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } @@ -1873,16 +1891,31 @@ func (x *AccountRecord) GetNotificationProfileManualOverride() *AccountRecord_No return nil } +func (x *AccountRecord) GetNotificationProfileSyncDisabled() bool { + if x != nil { + return x.NotificationProfileSyncDisabled + } + return false +} + +func (x *AccountRecord) GetAutomaticKeyVerificationDisabled() bool { + if x != nil { + return x.AutomaticKeyVerificationDisabled + } + return false +} + type StoryDistributionListRecord struct { - state protoimpl.MessageState `protogen:"open.v1"` - Identifier []byte `protobuf:"bytes,1,opt,name=identifier,proto3" json:"identifier,omitempty"` - Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` - RecipientServiceIds []string `protobuf:"bytes,3,rep,name=recipientServiceIds,proto3" json:"recipientServiceIds,omitempty"` - DeletedAtTimestamp uint64 `protobuf:"varint,4,opt,name=deletedAtTimestamp,proto3" json:"deletedAtTimestamp,omitempty"` - AllowsReplies bool `protobuf:"varint,5,opt,name=allowsReplies,proto3" json:"allowsReplies,omitempty"` - IsBlockList bool `protobuf:"varint,6,opt,name=isBlockList,proto3" json:"isBlockList,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` + Identifier []byte `protobuf:"bytes,1,opt,name=identifier,proto3" json:"identifier,omitempty"` + Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` + RecipientServiceIds []string `protobuf:"bytes,3,rep,name=recipientServiceIds,proto3" json:"recipientServiceIds,omitempty"` + DeletedAtTimestamp uint64 `protobuf:"varint,4,opt,name=deletedAtTimestamp,proto3" json:"deletedAtTimestamp,omitempty"` + AllowsReplies bool `protobuf:"varint,5,opt,name=allowsReplies,proto3" json:"allowsReplies,omitempty"` + IsBlockList bool `protobuf:"varint,6,opt,name=isBlockList,proto3" json:"isBlockList,omitempty"` + RecipientServiceIdsBinary [][]byte `protobuf:"bytes,7,rep,name=recipientServiceIdsBinary,proto3" json:"recipientServiceIdsBinary,omitempty"` // service ID binary (i.e. 16 byte UUID for ACI, 1 byte prefix + 16 byte UUID for PNI) + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } func (x *StoryDistributionListRecord) Reset() { @@ -1957,6 +1990,13 @@ func (x *StoryDistributionListRecord) GetIsBlockList() bool { return false } +func (x *StoryDistributionListRecord) GetRecipientServiceIdsBinary() [][]byte { + if x != nil { + return x.RecipientServiceIdsBinary + } + return nil +} + type CallLinkRecord struct { state protoimpl.MessageState `protogen:"open.v1"` RootKey []byte `protobuf:"bytes,1,opt,name=rootKey,proto3" json:"rootKey,omitempty"` @@ -2883,11 +2923,12 @@ func (*AccountRecord_NotificationProfileManualOverride_Enabled) isAccountRecord_ } type AccountRecord_PinnedConversation_Contact struct { - state protoimpl.MessageState `protogen:"open.v1"` - ServiceId string `protobuf:"bytes,1,opt,name=serviceId,proto3" json:"serviceId,omitempty"` - E164 string `protobuf:"bytes,2,opt,name=e164,proto3" json:"e164,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` + ServiceId string `protobuf:"bytes,1,opt,name=serviceId,proto3" json:"serviceId,omitempty"` + E164 string `protobuf:"bytes,2,opt,name=e164,proto3" json:"e164,omitempty"` + ServiceIdBinary []byte `protobuf:"bytes,3,opt,name=serviceIdBinary,proto3" json:"serviceIdBinary,omitempty"` // service ID binary (i.e. 16 byte UUID for ACI, 1 byte prefix + 16 byte UUID for PNI) + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } func (x *AccountRecord_PinnedConversation_Contact) Reset() { @@ -2934,6 +2975,13 @@ func (x *AccountRecord_PinnedConversation_Contact) GetE164() string { return "" } +func (x *AccountRecord_PinnedConversation_Contact) GetServiceIdBinary() []byte { + if x != nil { + return x.ServiceIdBinary + } + return nil +} + type AccountRecord_NotificationProfileManualOverride_ManuallyEnabled struct { state protoimpl.MessageState `protogen:"open.v1"` Id []byte `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` @@ -2988,11 +3036,12 @@ func (x *AccountRecord_NotificationProfileManualOverride_ManuallyEnabled) GetEnd } type Recipient_Contact struct { - state protoimpl.MessageState `protogen:"open.v1"` - ServiceId string `protobuf:"bytes,1,opt,name=serviceId,proto3" json:"serviceId,omitempty"` - E164 string `protobuf:"bytes,2,opt,name=e164,proto3" json:"e164,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` + ServiceId string `protobuf:"bytes,1,opt,name=serviceId,proto3" json:"serviceId,omitempty"` + E164 string `protobuf:"bytes,2,opt,name=e164,proto3" json:"e164,omitempty"` + ServiceIdBinary []byte `protobuf:"bytes,3,opt,name=serviceIdBinary,proto3" json:"serviceIdBinary,omitempty"` // service ID binary (i.e. 16 byte UUID for ACI, 1 byte prefix + 16 byte UUID for PNI) + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } func (x *Recipient_Contact) Reset() { @@ -3039,6 +3088,13 @@ func (x *Recipient_Contact) GetE164() string { return "" } +func (x *Recipient_Contact) GetServiceIdBinary() []byte { + if x != nil { + return x.ServiceIdBinary + } + return nil +} + var File_StorageService_proto protoreflect.FileDescriptor const file_StorageService_proto_rawDesc = "" + @@ -3091,7 +3147,7 @@ const file_StorageService_proto_rawDesc = "" + "chatFolder\x18\b \x01(\v2\x1f.signalservice.ChatFolderRecordH\x00R\n" + "chatFolder\x12V\n" + "\x13notificationProfile\x18\t \x01(\v2\".signalservice.NotificationProfileH\x00R\x13notificationProfileB\b\n" + - "\x06record\"\x9d\b\n" + + "\x06record\"\xd9\b\n" + "\rContactRecord\x12\x10\n" + "\x03aci\x18\x01 \x01(\tR\x03aci\x12\x12\n" + "\x04e164\x18\x02 \x01(\tR\x04e164\x12\x10\n" + @@ -3121,7 +3177,9 @@ const file_StorageService_proto_rawDesc = "" + "\x14pniSignatureVerified\x18\x15 \x01(\bR\x14pniSignatureVerified\x12=\n" + "\bnickname\x18\x16 \x01(\v2!.signalservice.ContactRecord.NameR\bnickname\x12\x12\n" + "\x04note\x18\x17 \x01(\tR\x04note\x12A\n" + - "\vavatarColor\x18\x18 \x01(\x0e2\x1a.signalservice.AvatarColorH\x00R\vavatarColor\x88\x01\x01\x1a4\n" + + "\vavatarColor\x18\x18 \x01(\x0e2\x1a.signalservice.AvatarColorH\x00R\vavatarColor\x88\x01\x01\x12\x1c\n" + + "\taciBinary\x18\x19 \x01(\fR\taciBinary\x12\x1c\n" + + "\tpniBinary\x18\x1a \x01(\fR\tpniBinary\x1a4\n" + "\x04Name\x12\x14\n" + "\x05given\x18\x01 \x01(\tR\x05given\x12\x16\n" + "\x06family\x18\x02 \x01(\tR\x06family\":\n" + @@ -3158,7 +3216,7 @@ const file_StorageService_proto_rawDesc = "" + "\">\n" + "\bPayments\x12\x18\n" + "\aenabled\x18\x01 \x01(\bR\aenabled\x12\x18\n" + - "\aentropy\x18\x02 \x01(\fR\aentropy\"\x8b\x1b\n" + + "\aentropy\x18\x02 \x01(\fR\aentropy\"\xcb\x1c\n" + "\rAccountRecord\x12\x1e\n" + "\n" + "profileKey\x18\x01 \x01(\fR\n" + @@ -3203,14 +3261,17 @@ const file_StorageService_proto_rawDesc = "" + "\x14backupSubscriberData\x18) \x01(\v2..signalservice.AccountRecord.IAPSubscriberDataR\x14backupSubscriberData\x12A\n" + "\vavatarColor\x18* \x01(\x0e2\x1a.signalservice.AvatarColorH\x02R\vavatarColor\x88\x01\x01\x12\\\n" + "\x11backupTierHistory\x18+ \x01(\v2..signalservice.AccountRecord.BackupTierHistoryR\x11backupTierHistory\x12\x8c\x01\n" + - "!notificationProfileManualOverride\x18, \x01(\v2>.signalservice.AccountRecord.NotificationProfileManualOverrideR!notificationProfileManualOverride\x1a\x86\x02\n" + + "!notificationProfileManualOverride\x18, \x01(\v2>.signalservice.AccountRecord.NotificationProfileManualOverrideR!notificationProfileManualOverride\x12H\n" + + "\x1fnotificationProfileSyncDisabled\x18- \x01(\bR\x1fnotificationProfileSyncDisabled\x12J\n" + + " automaticKeyVerificationDisabled\x18. \x01(\bR automaticKeyVerificationDisabled\x1a\xb0\x02\n" + "\x12PinnedConversation\x12S\n" + "\acontact\x18\x01 \x01(\v27.signalservice.AccountRecord.PinnedConversation.ContactH\x00R\acontact\x12&\n" + "\rlegacyGroupId\x18\x03 \x01(\fH\x00R\rlegacyGroupId\x12(\n" + - "\x0egroupMasterKey\x18\x04 \x01(\fH\x00R\x0egroupMasterKey\x1a;\n" + + "\x0egroupMasterKey\x18\x04 \x01(\fH\x00R\x0egroupMasterKey\x1ae\n" + "\aContact\x12\x1c\n" + "\tserviceId\x18\x01 \x01(\tR\tserviceId\x12\x12\n" + - "\x04e164\x18\x02 \x01(\tR\x04e164B\f\n" + + "\x04e164\x18\x02 \x01(\tR\x04e164\x12(\n" + + "\x0fserviceIdBinary\x18\x03 \x01(\fR\x0fserviceIdBinaryB\f\n" + "\n" + "identifier\x1a\xf8\x01\n" + "\fUsernameLink\x12\x18\n" + @@ -3258,7 +3319,7 @@ const file_StorageService_proto_rawDesc = "" + "_hasBackupB\r\n" + "\v_backupTierB\x0e\n" + "\f_avatarColorJ\x04\b\t\x10\n" + - "J\x04\b\x13\x10\x14J\x04\b\x1c\x10\x1dJ\x04\b\x1f\x10 J\x04\b$\x10%J\x04\b%\x10&J\x04\b&\x10'\"\xfb\x01\n" + + "J\x04\b\x13\x10\x14J\x04\b\x1c\x10\x1dJ\x04\b\x1f\x10 J\x04\b$\x10%J\x04\b%\x10&J\x04\b&\x10'\"\xb9\x02\n" + "\x1bStoryDistributionListRecord\x12\x1e\n" + "\n" + "identifier\x18\x01 \x01(\fR\n" + @@ -3267,20 +3328,22 @@ const file_StorageService_proto_rawDesc = "" + "\x13recipientServiceIds\x18\x03 \x03(\tR\x13recipientServiceIds\x12.\n" + "\x12deletedAtTimestamp\x18\x04 \x01(\x04R\x12deletedAtTimestamp\x12$\n" + "\rallowsReplies\x18\x05 \x01(\bR\rallowsReplies\x12 \n" + - "\visBlockList\x18\x06 \x01(\bR\visBlockList\"\xa7\x01\n" + + "\visBlockList\x18\x06 \x01(\bR\visBlockList\x12<\n" + + "\x19recipientServiceIdsBinary\x18\a \x03(\fR\x19recipientServiceIdsBinary\"\xa7\x01\n" + "\x0eCallLinkRecord\x12\x18\n" + "\arootKey\x18\x01 \x01(\fR\arootKey\x12\"\n" + "\fadminPasskey\x18\x02 \x01(\fR\fadminPasskey\x122\n" + "\x14deletedAtTimestampMs\x18\x03 \x01(\x04R\x14deletedAtTimestampMs\x12\x19\n" + "\x05epoch\x18\x04 \x01(\fH\x00R\x05epoch\x88\x01\x01B\b\n" + - "\x06_epoch\"\xe6\x01\n" + + "\x06_epoch\"\x90\x02\n" + "\tRecipient\x12<\n" + "\acontact\x18\x01 \x01(\v2 .signalservice.Recipient.ContactH\x00R\acontact\x12&\n" + "\rlegacyGroupId\x18\x02 \x01(\fH\x00R\rlegacyGroupId\x12(\n" + - "\x0egroupMasterKey\x18\x03 \x01(\fH\x00R\x0egroupMasterKey\x1a;\n" + + "\x0egroupMasterKey\x18\x03 \x01(\fH\x00R\x0egroupMasterKey\x1ae\n" + "\aContact\x12\x1c\n" + "\tserviceId\x18\x01 \x01(\tR\tserviceId\x12\x12\n" + - "\x04e164\x18\x02 \x01(\tR\x04e164B\f\n" + + "\x04e164\x18\x02 \x01(\tR\x04e164\x12(\n" + + "\x0fserviceIdBinary\x18\x03 \x01(\fR\x0fserviceIdBinaryB\f\n" + "\n" + "identifier\"\xe8\x04\n" + "\x10ChatFolderRecord\x12\x1e\n" + diff --git a/pkg/signalmeow/protobuf/StorageService.proto b/pkg/signalmeow/protobuf/StorageService.proto index 4258fba..95ec845 100644 --- a/pkg/signalmeow/protobuf/StorageService.proto +++ b/pkg/signalmeow/protobuf/StorageService.proto @@ -140,7 +140,9 @@ message ContactRecord { Name nickname = 22; string note = 23; optional AvatarColor avatarColor = 24; - // Next ID: 25 + bytes aciBinary = 25; // 16-byte UUID + bytes pniBinary = 26; // 16-byte UUID + // Next ID: 27 } message GroupV1Record { @@ -187,8 +189,9 @@ message AccountRecord { message PinnedConversation { message Contact { - string serviceId = 1; - string e164 = 2; + string serviceId = 1; + string e164 = 2; + bytes serviceIdBinary = 3; // service ID binary (i.e. 16 byte UUID for ACI, 1 byte prefix + 16 byte UUID for PNI) } oneof identifier { @@ -291,15 +294,18 @@ message AccountRecord { optional AvatarColor avatarColor = 42; BackupTierHistory backupTierHistory = 43; NotificationProfileManualOverride notificationProfileManualOverride = 44; + bool notificationProfileSyncDisabled = 45; + bool automaticKeyVerificationDisabled = 46; } message StoryDistributionListRecord { - bytes identifier = 1; - string name = 2; - repeated string recipientServiceIds = 3; - uint64 deletedAtTimestamp = 4; - bool allowsReplies = 5; - bool isBlockList = 6; + bytes identifier = 1; + string name = 2; + repeated string recipientServiceIds = 3; + uint64 deletedAtTimestamp = 4; + bool allowsReplies = 5; + bool isBlockList = 6; + repeated bytes recipientServiceIdsBinary = 7; // service ID binary (i.e. 16 byte UUID for ACI, 1 byte prefix + 16 byte UUID for PNI) } message CallLinkRecord { @@ -311,8 +317,9 @@ message CallLinkRecord { message Recipient { message Contact { - string serviceId = 1; - string e164 = 2; + string serviceId = 1; + string e164 = 2; + bytes serviceIdBinary = 3; // service ID binary (i.e. 16 byte UUID for ACI, 1 byte prefix + 16 byte UUID for PNI) } oneof identifier { diff --git a/pkg/signalmeow/protobuf/UnidentifiedDelivery.pb.go b/pkg/signalmeow/protobuf/UnidentifiedDelivery.pb.go index d512960..e30f6d6 100644 --- a/pkg/signalmeow/protobuf/UnidentifiedDelivery.pb.go +++ b/pkg/signalmeow/protobuf/UnidentifiedDelivery.pb.go @@ -1,7 +1,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.36.10 -// protoc v3.21.12 +// protoc-gen-go v1.36.11 +// protoc v6.33.5 // source: UnidentifiedDelivery.proto // Copyright 2018 Signal Messenger, LLC diff --git a/pkg/signalmeow/protobuf/WebSocketResources.pb.go b/pkg/signalmeow/protobuf/WebSocketResources.pb.go index ef45ba0..f35110d 100644 --- a/pkg/signalmeow/protobuf/WebSocketResources.pb.go +++ b/pkg/signalmeow/protobuf/WebSocketResources.pb.go @@ -5,8 +5,8 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.36.10 -// protoc v3.21.12 +// protoc-gen-go v1.36.11 +// protoc v6.33.5 // source: WebSocketResources.proto package signalpb diff --git a/pkg/signalmeow/protobuf/backuppb/Backup.pb.go b/pkg/signalmeow/protobuf/backuppb/Backup.pb.go index 86e176a..73930ae 100644 --- a/pkg/signalmeow/protobuf/backuppb/Backup.pb.go +++ b/pkg/signalmeow/protobuf/backuppb/Backup.pb.go @@ -1,7 +1,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.36.10 -// protoc v3.21.12 +// protoc-gen-go v1.36.11 +// protoc v6.33.5 // source: backuppb/Backup.proto package backuppb @@ -210,6 +210,159 @@ func (AccountData_PhoneNumberSharingMode) EnumDescriptor() ([]byte, []int) { return file_backuppb_Backup_proto_rawDescGZIP(), []int{2, 0} } +type AccountData_SentMediaQuality int32 + +const ( + AccountData_UNKNOWN_QUALITY AccountData_SentMediaQuality = 0 // Interpret as "Standard" + AccountData_STANDARD AccountData_SentMediaQuality = 1 + AccountData_HIGH AccountData_SentMediaQuality = 2 +) + +// Enum value maps for AccountData_SentMediaQuality. +var ( + AccountData_SentMediaQuality_name = map[int32]string{ + 0: "UNKNOWN_QUALITY", + 1: "STANDARD", + 2: "HIGH", + } + AccountData_SentMediaQuality_value = map[string]int32{ + "UNKNOWN_QUALITY": 0, + "STANDARD": 1, + "HIGH": 2, + } +) + +func (x AccountData_SentMediaQuality) Enum() *AccountData_SentMediaQuality { + p := new(AccountData_SentMediaQuality) + *p = x + return p +} + +func (x AccountData_SentMediaQuality) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (AccountData_SentMediaQuality) Descriptor() protoreflect.EnumDescriptor { + return file_backuppb_Backup_proto_enumTypes[3].Descriptor() +} + +func (AccountData_SentMediaQuality) Type() protoreflect.EnumType { + return &file_backuppb_Backup_proto_enumTypes[3] +} + +func (x AccountData_SentMediaQuality) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use AccountData_SentMediaQuality.Descriptor instead. +func (AccountData_SentMediaQuality) EnumDescriptor() ([]byte, []int) { + return file_backuppb_Backup_proto_rawDescGZIP(), []int{2, 1} +} + +type AccountData_AppTheme int32 + +const ( + AccountData_UNKNOWN_APP_THEME AccountData_AppTheme = 0 // Interpret as "System" + AccountData_SYSTEM AccountData_AppTheme = 1 + AccountData_LIGHT AccountData_AppTheme = 2 + AccountData_DARK AccountData_AppTheme = 3 +) + +// Enum value maps for AccountData_AppTheme. +var ( + AccountData_AppTheme_name = map[int32]string{ + 0: "UNKNOWN_APP_THEME", + 1: "SYSTEM", + 2: "LIGHT", + 3: "DARK", + } + AccountData_AppTheme_value = map[string]int32{ + "UNKNOWN_APP_THEME": 0, + "SYSTEM": 1, + "LIGHT": 2, + "DARK": 3, + } +) + +func (x AccountData_AppTheme) Enum() *AccountData_AppTheme { + p := new(AccountData_AppTheme) + *p = x + return p +} + +func (x AccountData_AppTheme) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (AccountData_AppTheme) Descriptor() protoreflect.EnumDescriptor { + return file_backuppb_Backup_proto_enumTypes[4].Descriptor() +} + +func (AccountData_AppTheme) Type() protoreflect.EnumType { + return &file_backuppb_Backup_proto_enumTypes[4] +} + +func (x AccountData_AppTheme) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use AccountData_AppTheme.Descriptor instead. +func (AccountData_AppTheme) EnumDescriptor() ([]byte, []int) { + return file_backuppb_Backup_proto_rawDescGZIP(), []int{2, 2} +} + +type AccountData_CallsUseLessDataSetting int32 + +const ( + AccountData_UNKNOWN_CALL_DATA_SETTING AccountData_CallsUseLessDataSetting = 0 // Interpret as "Never" + AccountData_NEVER AccountData_CallsUseLessDataSetting = 1 + AccountData_MOBILE_DATA_ONLY AccountData_CallsUseLessDataSetting = 2 + AccountData_WIFI_AND_MOBILE_DATA AccountData_CallsUseLessDataSetting = 3 +) + +// Enum value maps for AccountData_CallsUseLessDataSetting. +var ( + AccountData_CallsUseLessDataSetting_name = map[int32]string{ + 0: "UNKNOWN_CALL_DATA_SETTING", + 1: "NEVER", + 2: "MOBILE_DATA_ONLY", + 3: "WIFI_AND_MOBILE_DATA", + } + AccountData_CallsUseLessDataSetting_value = map[string]int32{ + "UNKNOWN_CALL_DATA_SETTING": 0, + "NEVER": 1, + "MOBILE_DATA_ONLY": 2, + "WIFI_AND_MOBILE_DATA": 3, + } +) + +func (x AccountData_CallsUseLessDataSetting) Enum() *AccountData_CallsUseLessDataSetting { + p := new(AccountData_CallsUseLessDataSetting) + *p = x + return p +} + +func (x AccountData_CallsUseLessDataSetting) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (AccountData_CallsUseLessDataSetting) Descriptor() protoreflect.EnumDescriptor { + return file_backuppb_Backup_proto_enumTypes[5].Descriptor() +} + +func (AccountData_CallsUseLessDataSetting) Type() protoreflect.EnumType { + return &file_backuppb_Backup_proto_enumTypes[5] +} + +func (x AccountData_CallsUseLessDataSetting) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use AccountData_CallsUseLessDataSetting.Descriptor instead. +func (AccountData_CallsUseLessDataSetting) EnumDescriptor() ([]byte, []int) { + return file_backuppb_Backup_proto_rawDescGZIP(), []int{2, 3} +} + type AccountData_UsernameLink_Color int32 const ( @@ -261,11 +414,11 @@ func (x AccountData_UsernameLink_Color) String() string { } func (AccountData_UsernameLink_Color) Descriptor() protoreflect.EnumDescriptor { - return file_backuppb_Backup_proto_enumTypes[3].Descriptor() + return file_backuppb_Backup_proto_enumTypes[6].Descriptor() } func (AccountData_UsernameLink_Color) Type() protoreflect.EnumType { - return &file_backuppb_Backup_proto_enumTypes[3] + return &file_backuppb_Backup_proto_enumTypes[6] } func (x AccountData_UsernameLink_Color) Number() protoreflect.EnumNumber { @@ -277,6 +430,107 @@ func (AccountData_UsernameLink_Color) EnumDescriptor() ([]byte, []int) { return file_backuppb_Backup_proto_rawDescGZIP(), []int{2, 0, 0} } +type AccountData_AutoDownloadSettings_AutoDownloadOption int32 + +const ( + AccountData_AutoDownloadSettings_UNKNOWN AccountData_AutoDownloadSettings_AutoDownloadOption = 0 // Interpret as "Never" + AccountData_AutoDownloadSettings_NEVER AccountData_AutoDownloadSettings_AutoDownloadOption = 1 + AccountData_AutoDownloadSettings_WIFI AccountData_AutoDownloadSettings_AutoDownloadOption = 2 + AccountData_AutoDownloadSettings_WIFI_AND_CELLULAR AccountData_AutoDownloadSettings_AutoDownloadOption = 3 +) + +// Enum value maps for AccountData_AutoDownloadSettings_AutoDownloadOption. +var ( + AccountData_AutoDownloadSettings_AutoDownloadOption_name = map[int32]string{ + 0: "UNKNOWN", + 1: "NEVER", + 2: "WIFI", + 3: "WIFI_AND_CELLULAR", + } + AccountData_AutoDownloadSettings_AutoDownloadOption_value = map[string]int32{ + "UNKNOWN": 0, + "NEVER": 1, + "WIFI": 2, + "WIFI_AND_CELLULAR": 3, + } +) + +func (x AccountData_AutoDownloadSettings_AutoDownloadOption) Enum() *AccountData_AutoDownloadSettings_AutoDownloadOption { + p := new(AccountData_AutoDownloadSettings_AutoDownloadOption) + *p = x + return p +} + +func (x AccountData_AutoDownloadSettings_AutoDownloadOption) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (AccountData_AutoDownloadSettings_AutoDownloadOption) Descriptor() protoreflect.EnumDescriptor { + return file_backuppb_Backup_proto_enumTypes[7].Descriptor() +} + +func (AccountData_AutoDownloadSettings_AutoDownloadOption) Type() protoreflect.EnumType { + return &file_backuppb_Backup_proto_enumTypes[7] +} + +func (x AccountData_AutoDownloadSettings_AutoDownloadOption) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use AccountData_AutoDownloadSettings_AutoDownloadOption.Descriptor instead. +func (AccountData_AutoDownloadSettings_AutoDownloadOption) EnumDescriptor() ([]byte, []int) { + return file_backuppb_Backup_proto_rawDescGZIP(), []int{2, 1, 0} +} + +type AccountData_AndroidSpecificSettings_NavigationBarSize int32 + +const ( + AccountData_AndroidSpecificSettings_UNKNOWN_BAR_SIZE AccountData_AndroidSpecificSettings_NavigationBarSize = 0 // Intepret as "Normal" + AccountData_AndroidSpecificSettings_NORMAL AccountData_AndroidSpecificSettings_NavigationBarSize = 1 + AccountData_AndroidSpecificSettings_COMPACT AccountData_AndroidSpecificSettings_NavigationBarSize = 2 +) + +// Enum value maps for AccountData_AndroidSpecificSettings_NavigationBarSize. +var ( + AccountData_AndroidSpecificSettings_NavigationBarSize_name = map[int32]string{ + 0: "UNKNOWN_BAR_SIZE", + 1: "NORMAL", + 2: "COMPACT", + } + AccountData_AndroidSpecificSettings_NavigationBarSize_value = map[string]int32{ + "UNKNOWN_BAR_SIZE": 0, + "NORMAL": 1, + "COMPACT": 2, + } +) + +func (x AccountData_AndroidSpecificSettings_NavigationBarSize) Enum() *AccountData_AndroidSpecificSettings_NavigationBarSize { + p := new(AccountData_AndroidSpecificSettings_NavigationBarSize) + *p = x + return p +} + +func (x AccountData_AndroidSpecificSettings_NavigationBarSize) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (AccountData_AndroidSpecificSettings_NavigationBarSize) Descriptor() protoreflect.EnumDescriptor { + return file_backuppb_Backup_proto_enumTypes[8].Descriptor() +} + +func (AccountData_AndroidSpecificSettings_NavigationBarSize) Type() protoreflect.EnumType { + return &file_backuppb_Backup_proto_enumTypes[8] +} + +func (x AccountData_AndroidSpecificSettings_NavigationBarSize) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use AccountData_AndroidSpecificSettings_NavigationBarSize.Descriptor instead. +func (AccountData_AndroidSpecificSettings_NavigationBarSize) EnumDescriptor() ([]byte, []int) { + return file_backuppb_Backup_proto_rawDescGZIP(), []int{2, 5, 0} +} + type Contact_IdentityState int32 const ( @@ -310,11 +564,11 @@ func (x Contact_IdentityState) String() string { } func (Contact_IdentityState) Descriptor() protoreflect.EnumDescriptor { - return file_backuppb_Backup_proto_enumTypes[4].Descriptor() + return file_backuppb_Backup_proto_enumTypes[9].Descriptor() } func (Contact_IdentityState) Type() protoreflect.EnumType { - return &file_backuppb_Backup_proto_enumTypes[4] + return &file_backuppb_Backup_proto_enumTypes[9] } func (x Contact_IdentityState) Number() protoreflect.EnumNumber { @@ -359,11 +613,11 @@ func (x Contact_Visibility) String() string { } func (Contact_Visibility) Descriptor() protoreflect.EnumDescriptor { - return file_backuppb_Backup_proto_enumTypes[5].Descriptor() + return file_backuppb_Backup_proto_enumTypes[10].Descriptor() } func (Contact_Visibility) Type() protoreflect.EnumType { - return &file_backuppb_Backup_proto_enumTypes[5] + return &file_backuppb_Backup_proto_enumTypes[10] } func (x Contact_Visibility) Number() protoreflect.EnumNumber { @@ -408,11 +662,11 @@ func (x Group_StorySendMode) String() string { } func (Group_StorySendMode) Descriptor() protoreflect.EnumDescriptor { - return file_backuppb_Backup_proto_enumTypes[6].Descriptor() + return file_backuppb_Backup_proto_enumTypes[11].Descriptor() } func (Group_StorySendMode) Type() protoreflect.EnumType { - return &file_backuppb_Backup_proto_enumTypes[6] + return &file_backuppb_Backup_proto_enumTypes[11] } func (x Group_StorySendMode) Number() protoreflect.EnumNumber { @@ -457,11 +711,11 @@ func (x Group_Member_Role) String() string { } func (Group_Member_Role) Descriptor() protoreflect.EnumDescriptor { - return file_backuppb_Backup_proto_enumTypes[7].Descriptor() + return file_backuppb_Backup_proto_enumTypes[12].Descriptor() } func (Group_Member_Role) Type() protoreflect.EnumType { - return &file_backuppb_Backup_proto_enumTypes[7] + return &file_backuppb_Backup_proto_enumTypes[12] } func (x Group_Member_Role) Number() protoreflect.EnumNumber { @@ -512,11 +766,11 @@ func (x Group_AccessControl_AccessRequired) String() string { } func (Group_AccessControl_AccessRequired) Descriptor() protoreflect.EnumDescriptor { - return file_backuppb_Backup_proto_enumTypes[8].Descriptor() + return file_backuppb_Backup_proto_enumTypes[13].Descriptor() } func (Group_AccessControl_AccessRequired) Type() protoreflect.EnumType { - return &file_backuppb_Backup_proto_enumTypes[8] + return &file_backuppb_Backup_proto_enumTypes[13] } func (x Group_AccessControl_AccessRequired) Number() protoreflect.EnumNumber { @@ -561,11 +815,11 @@ func (x CallLink_Restrictions) String() string { } func (CallLink_Restrictions) Descriptor() protoreflect.EnumDescriptor { - return file_backuppb_Backup_proto_enumTypes[9].Descriptor() + return file_backuppb_Backup_proto_enumTypes[14].Descriptor() } func (CallLink_Restrictions) Type() protoreflect.EnumType { - return &file_backuppb_Backup_proto_enumTypes[9] + return &file_backuppb_Backup_proto_enumTypes[14] } func (x CallLink_Restrictions) Number() protoreflect.EnumNumber { @@ -607,11 +861,11 @@ func (x AdHocCall_State) String() string { } func (AdHocCall_State) Descriptor() protoreflect.EnumDescriptor { - return file_backuppb_Backup_proto_enumTypes[10].Descriptor() + return file_backuppb_Backup_proto_enumTypes[15].Descriptor() } func (AdHocCall_State) Type() protoreflect.EnumType { - return &file_backuppb_Backup_proto_enumTypes[10] + return &file_backuppb_Backup_proto_enumTypes[15] } func (x AdHocCall_State) Number() protoreflect.EnumNumber { @@ -659,11 +913,11 @@ func (x DistributionList_PrivacyMode) String() string { } func (DistributionList_PrivacyMode) Descriptor() protoreflect.EnumDescriptor { - return file_backuppb_Backup_proto_enumTypes[11].Descriptor() + return file_backuppb_Backup_proto_enumTypes[16].Descriptor() } func (DistributionList_PrivacyMode) Type() protoreflect.EnumType { - return &file_backuppb_Backup_proto_enumTypes[11] + return &file_backuppb_Backup_proto_enumTypes[16] } func (x DistributionList_PrivacyMode) Number() protoreflect.EnumNumber { @@ -708,11 +962,11 @@ func (x SendStatus_Failed_FailureReason) String() string { } func (SendStatus_Failed_FailureReason) Descriptor() protoreflect.EnumDescriptor { - return file_backuppb_Backup_proto_enumTypes[12].Descriptor() + return file_backuppb_Backup_proto_enumTypes[17].Descriptor() } func (SendStatus_Failed_FailureReason) Type() protoreflect.EnumType { - return &file_backuppb_Backup_proto_enumTypes[12] + return &file_backuppb_Backup_proto_enumTypes[17] } func (x SendStatus_Failed_FailureReason) Number() protoreflect.EnumNumber { @@ -757,11 +1011,11 @@ func (x PaymentNotification_TransactionDetails_FailedTransaction_FailureReason) } func (PaymentNotification_TransactionDetails_FailedTransaction_FailureReason) Descriptor() protoreflect.EnumDescriptor { - return file_backuppb_Backup_proto_enumTypes[13].Descriptor() + return file_backuppb_Backup_proto_enumTypes[18].Descriptor() } func (PaymentNotification_TransactionDetails_FailedTransaction_FailureReason) Type() protoreflect.EnumType { - return &file_backuppb_Backup_proto_enumTypes[13] + return &file_backuppb_Backup_proto_enumTypes[18] } func (x PaymentNotification_TransactionDetails_FailedTransaction_FailureReason) Number() protoreflect.EnumNumber { @@ -806,11 +1060,11 @@ func (x PaymentNotification_TransactionDetails_Transaction_Status) String() stri } func (PaymentNotification_TransactionDetails_Transaction_Status) Descriptor() protoreflect.EnumDescriptor { - return file_backuppb_Backup_proto_enumTypes[14].Descriptor() + return file_backuppb_Backup_proto_enumTypes[19].Descriptor() } func (PaymentNotification_TransactionDetails_Transaction_Status) Type() protoreflect.EnumType { - return &file_backuppb_Backup_proto_enumTypes[14] + return &file_backuppb_Backup_proto_enumTypes[19] } func (x PaymentNotification_TransactionDetails_Transaction_Status) Number() protoreflect.EnumNumber { @@ -858,11 +1112,11 @@ func (x GiftBadge_State) String() string { } func (GiftBadge_State) Descriptor() protoreflect.EnumDescriptor { - return file_backuppb_Backup_proto_enumTypes[15].Descriptor() + return file_backuppb_Backup_proto_enumTypes[20].Descriptor() } func (GiftBadge_State) Type() protoreflect.EnumType { - return &file_backuppb_Backup_proto_enumTypes[15] + return &file_backuppb_Backup_proto_enumTypes[20] } func (x GiftBadge_State) Number() protoreflect.EnumNumber { @@ -913,11 +1167,11 @@ func (x ContactAttachment_Phone_Type) String() string { } func (ContactAttachment_Phone_Type) Descriptor() protoreflect.EnumDescriptor { - return file_backuppb_Backup_proto_enumTypes[16].Descriptor() + return file_backuppb_Backup_proto_enumTypes[21].Descriptor() } func (ContactAttachment_Phone_Type) Type() protoreflect.EnumType { - return &file_backuppb_Backup_proto_enumTypes[16] + return &file_backuppb_Backup_proto_enumTypes[21] } func (x ContactAttachment_Phone_Type) Number() protoreflect.EnumNumber { @@ -968,11 +1222,11 @@ func (x ContactAttachment_Email_Type) String() string { } func (ContactAttachment_Email_Type) Descriptor() protoreflect.EnumDescriptor { - return file_backuppb_Backup_proto_enumTypes[17].Descriptor() + return file_backuppb_Backup_proto_enumTypes[22].Descriptor() } func (ContactAttachment_Email_Type) Type() protoreflect.EnumType { - return &file_backuppb_Backup_proto_enumTypes[17] + return &file_backuppb_Backup_proto_enumTypes[22] } func (x ContactAttachment_Email_Type) Number() protoreflect.EnumNumber { @@ -1020,11 +1274,11 @@ func (x ContactAttachment_PostalAddress_Type) String() string { } func (ContactAttachment_PostalAddress_Type) Descriptor() protoreflect.EnumDescriptor { - return file_backuppb_Backup_proto_enumTypes[18].Descriptor() + return file_backuppb_Backup_proto_enumTypes[23].Descriptor() } func (ContactAttachment_PostalAddress_Type) Type() protoreflect.EnumType { - return &file_backuppb_Backup_proto_enumTypes[18] + return &file_backuppb_Backup_proto_enumTypes[23] } func (x ContactAttachment_PostalAddress_Type) Number() protoreflect.EnumNumber { @@ -1075,11 +1329,11 @@ func (x MessageAttachment_Flag) String() string { } func (MessageAttachment_Flag) Descriptor() protoreflect.EnumDescriptor { - return file_backuppb_Backup_proto_enumTypes[19].Descriptor() + return file_backuppb_Backup_proto_enumTypes[24].Descriptor() } func (MessageAttachment_Flag) Type() protoreflect.EnumType { - return &file_backuppb_Backup_proto_enumTypes[19] + return &file_backuppb_Backup_proto_enumTypes[24] } func (x MessageAttachment_Flag) Number() protoreflect.EnumNumber { @@ -1130,11 +1384,11 @@ func (x Quote_Type) String() string { } func (Quote_Type) Descriptor() protoreflect.EnumDescriptor { - return file_backuppb_Backup_proto_enumTypes[20].Descriptor() + return file_backuppb_Backup_proto_enumTypes[25].Descriptor() } func (Quote_Type) Type() protoreflect.EnumType { - return &file_backuppb_Backup_proto_enumTypes[20] + return &file_backuppb_Backup_proto_enumTypes[25] } func (x Quote_Type) Number() protoreflect.EnumNumber { @@ -1188,11 +1442,11 @@ func (x BodyRange_Style) String() string { } func (BodyRange_Style) Descriptor() protoreflect.EnumDescriptor { - return file_backuppb_Backup_proto_enumTypes[21].Descriptor() + return file_backuppb_Backup_proto_enumTypes[26].Descriptor() } func (BodyRange_Style) Type() protoreflect.EnumType { - return &file_backuppb_Backup_proto_enumTypes[21] + return &file_backuppb_Backup_proto_enumTypes[26] } func (x BodyRange_Style) Number() protoreflect.EnumNumber { @@ -1237,11 +1491,11 @@ func (x IndividualCall_Type) String() string { } func (IndividualCall_Type) Descriptor() protoreflect.EnumDescriptor { - return file_backuppb_Backup_proto_enumTypes[22].Descriptor() + return file_backuppb_Backup_proto_enumTypes[27].Descriptor() } func (IndividualCall_Type) Type() protoreflect.EnumType { - return &file_backuppb_Backup_proto_enumTypes[22] + return &file_backuppb_Backup_proto_enumTypes[27] } func (x IndividualCall_Type) Number() protoreflect.EnumNumber { @@ -1286,11 +1540,11 @@ func (x IndividualCall_Direction) String() string { } func (IndividualCall_Direction) Descriptor() protoreflect.EnumDescriptor { - return file_backuppb_Backup_proto_enumTypes[23].Descriptor() + return file_backuppb_Backup_proto_enumTypes[28].Descriptor() } func (IndividualCall_Direction) Type() protoreflect.EnumType { - return &file_backuppb_Backup_proto_enumTypes[23] + return &file_backuppb_Backup_proto_enumTypes[28] } func (x IndividualCall_Direction) Number() protoreflect.EnumNumber { @@ -1345,11 +1599,11 @@ func (x IndividualCall_State) String() string { } func (IndividualCall_State) Descriptor() protoreflect.EnumDescriptor { - return file_backuppb_Backup_proto_enumTypes[24].Descriptor() + return file_backuppb_Backup_proto_enumTypes[29].Descriptor() } func (IndividualCall_State) Type() protoreflect.EnumType { - return &file_backuppb_Backup_proto_enumTypes[24] + return &file_backuppb_Backup_proto_enumTypes[29] } func (x IndividualCall_State) Number() protoreflect.EnumNumber { @@ -1421,11 +1675,11 @@ func (x GroupCall_State) String() string { } func (GroupCall_State) Descriptor() protoreflect.EnumDescriptor { - return file_backuppb_Backup_proto_enumTypes[25].Descriptor() + return file_backuppb_Backup_proto_enumTypes[30].Descriptor() } func (GroupCall_State) Type() protoreflect.EnumType { - return &file_backuppb_Backup_proto_enumTypes[25] + return &file_backuppb_Backup_proto_enumTypes[30] } func (x GroupCall_State) Number() protoreflect.EnumNumber { @@ -1512,11 +1766,11 @@ func (x SimpleChatUpdate_Type) String() string { } func (SimpleChatUpdate_Type) Descriptor() protoreflect.EnumDescriptor { - return file_backuppb_Backup_proto_enumTypes[26].Descriptor() + return file_backuppb_Backup_proto_enumTypes[31].Descriptor() } func (SimpleChatUpdate_Type) Type() protoreflect.EnumType { - return &file_backuppb_Backup_proto_enumTypes[26] + return &file_backuppb_Backup_proto_enumTypes[31] } func (x SimpleChatUpdate_Type) Number() protoreflect.EnumNumber { @@ -1618,11 +1872,11 @@ func (x ChatStyle_WallpaperPreset) String() string { } func (ChatStyle_WallpaperPreset) Descriptor() protoreflect.EnumDescriptor { - return file_backuppb_Backup_proto_enumTypes[27].Descriptor() + return file_backuppb_Backup_proto_enumTypes[32].Descriptor() } func (ChatStyle_WallpaperPreset) Type() protoreflect.EnumType { - return &file_backuppb_Backup_proto_enumTypes[27] + return &file_backuppb_Backup_proto_enumTypes[32] } func (x ChatStyle_WallpaperPreset) Number() protoreflect.EnumNumber { @@ -1631,7 +1885,7 @@ func (x ChatStyle_WallpaperPreset) Number() protoreflect.EnumNumber { // Deprecated: Use ChatStyle_WallpaperPreset.Descriptor instead. func (ChatStyle_WallpaperPreset) EnumDescriptor() ([]byte, []int) { - return file_backuppb_Backup_proto_rawDescGZIP(), []int{79, 0} + return file_backuppb_Backup_proto_rawDescGZIP(), []int{80, 0} } type ChatStyle_BubbleColorPreset int32 @@ -1727,11 +1981,11 @@ func (x ChatStyle_BubbleColorPreset) String() string { } func (ChatStyle_BubbleColorPreset) Descriptor() protoreflect.EnumDescriptor { - return file_backuppb_Backup_proto_enumTypes[28].Descriptor() + return file_backuppb_Backup_proto_enumTypes[33].Descriptor() } func (ChatStyle_BubbleColorPreset) Type() protoreflect.EnumType { - return &file_backuppb_Backup_proto_enumTypes[28] + return &file_backuppb_Backup_proto_enumTypes[33] } func (x ChatStyle_BubbleColorPreset) Number() protoreflect.EnumNumber { @@ -1740,7 +1994,7 @@ func (x ChatStyle_BubbleColorPreset) Number() protoreflect.EnumNumber { // Deprecated: Use ChatStyle_BubbleColorPreset.Descriptor instead. func (ChatStyle_BubbleColorPreset) EnumDescriptor() ([]byte, []int) { - return file_backuppb_Backup_proto_rawDescGZIP(), []int{79, 1} + return file_backuppb_Backup_proto_rawDescGZIP(), []int{80, 1} } type NotificationProfile_DayOfWeek int32 @@ -1791,11 +2045,11 @@ func (x NotificationProfile_DayOfWeek) String() string { } func (NotificationProfile_DayOfWeek) Descriptor() protoreflect.EnumDescriptor { - return file_backuppb_Backup_proto_enumTypes[29].Descriptor() + return file_backuppb_Backup_proto_enumTypes[34].Descriptor() } func (NotificationProfile_DayOfWeek) Type() protoreflect.EnumType { - return &file_backuppb_Backup_proto_enumTypes[29] + return &file_backuppb_Backup_proto_enumTypes[34] } func (x NotificationProfile_DayOfWeek) Number() protoreflect.EnumNumber { @@ -1804,7 +2058,7 @@ func (x NotificationProfile_DayOfWeek) Number() protoreflect.EnumNumber { // Deprecated: Use NotificationProfile_DayOfWeek.Descriptor instead. func (NotificationProfile_DayOfWeek) EnumDescriptor() ([]byte, []int) { - return file_backuppb_Backup_proto_rawDescGZIP(), []int{80, 0} + return file_backuppb_Backup_proto_rawDescGZIP(), []int{81, 0} } // Represents the default "All chats" folder record vs all other custom folders @@ -1841,11 +2095,11 @@ func (x ChatFolder_FolderType) String() string { } func (ChatFolder_FolderType) Descriptor() protoreflect.EnumDescriptor { - return file_backuppb_Backup_proto_enumTypes[30].Descriptor() + return file_backuppb_Backup_proto_enumTypes[35].Descriptor() } func (ChatFolder_FolderType) Type() protoreflect.EnumType { - return &file_backuppb_Backup_proto_enumTypes[30] + return &file_backuppb_Backup_proto_enumTypes[35] } func (x ChatFolder_FolderType) Number() protoreflect.EnumNumber { @@ -1854,7 +2108,7 @@ func (x ChatFolder_FolderType) Number() protoreflect.EnumNumber { // Deprecated: Use ChatFolder_FolderType.Descriptor instead. func (ChatFolder_FolderType) EnumDescriptor() ([]byte, []int) { - return file_backuppb_Backup_proto_rawDescGZIP(), []int{81, 0} + return file_backuppb_Backup_proto_rawDescGZIP(), []int{82, 0} } type BackupInfo struct { @@ -2138,19 +2392,23 @@ func (*Frame_NotificationProfile) isFrame_Item() {} func (*Frame_ChatFolder) isFrame_Item() {} type AccountData struct { - state protoimpl.MessageState `protogen:"open.v1"` - ProfileKey []byte `protobuf:"bytes,1,opt,name=profileKey,proto3" json:"profileKey,omitempty"` - Username *string `protobuf:"bytes,2,opt,name=username,proto3,oneof" json:"username,omitempty"` - UsernameLink *AccountData_UsernameLink `protobuf:"bytes,3,opt,name=usernameLink,proto3" json:"usernameLink,omitempty"` - GivenName string `protobuf:"bytes,4,opt,name=givenName,proto3" json:"givenName,omitempty"` - FamilyName string `protobuf:"bytes,5,opt,name=familyName,proto3" json:"familyName,omitempty"` - AvatarUrlPath string `protobuf:"bytes,6,opt,name=avatarUrlPath,proto3" json:"avatarUrlPath,omitempty"` - DonationSubscriberData *AccountData_SubscriberData `protobuf:"bytes,7,opt,name=donationSubscriberData,proto3" json:"donationSubscriberData,omitempty"` - AccountSettings *AccountData_AccountSettings `protobuf:"bytes,9,opt,name=accountSettings,proto3" json:"accountSettings,omitempty"` - BackupsSubscriberData *AccountData_IAPSubscriberData `protobuf:"bytes,10,opt,name=backupsSubscriberData,proto3" json:"backupsSubscriberData,omitempty"` - SvrPin string `protobuf:"bytes,11,opt,name=svrPin,proto3" json:"svrPin,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` + ProfileKey []byte `protobuf:"bytes,1,opt,name=profileKey,proto3" json:"profileKey,omitempty"` + Username *string `protobuf:"bytes,2,opt,name=username,proto3,oneof" json:"username,omitempty"` + UsernameLink *AccountData_UsernameLink `protobuf:"bytes,3,opt,name=usernameLink,proto3" json:"usernameLink,omitempty"` + GivenName string `protobuf:"bytes,4,opt,name=givenName,proto3" json:"givenName,omitempty"` + FamilyName string `protobuf:"bytes,5,opt,name=familyName,proto3" json:"familyName,omitempty"` + AvatarUrlPath string `protobuf:"bytes,6,opt,name=avatarUrlPath,proto3" json:"avatarUrlPath,omitempty"` + DonationSubscriberData *AccountData_SubscriberData `protobuf:"bytes,7,opt,name=donationSubscriberData,proto3" json:"donationSubscriberData,omitempty"` + AccountSettings *AccountData_AccountSettings `protobuf:"bytes,9,opt,name=accountSettings,proto3" json:"accountSettings,omitempty"` + BackupsSubscriberData *AccountData_IAPSubscriberData `protobuf:"bytes,10,opt,name=backupsSubscriberData,proto3" json:"backupsSubscriberData,omitempty"` + SvrPin string `protobuf:"bytes,11,opt,name=svrPin,proto3" json:"svrPin,omitempty"` + AndroidSpecificSettings *AccountData_AndroidSpecificSettings `protobuf:"bytes,12,opt,name=androidSpecificSettings,proto3" json:"androidSpecificSettings,omitempty"` + BioText string `protobuf:"bytes,13,opt,name=bioText,proto3" json:"bioText,omitempty"` + BioEmoji string `protobuf:"bytes,14,opt,name=bioEmoji,proto3" json:"bioEmoji,omitempty"` + KeyTransparencyData []byte `protobuf:"bytes,15,opt,name=keyTransparencyData,proto3,oneof" json:"keyTransparencyData,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } func (x *AccountData) Reset() { @@ -2253,6 +2511,34 @@ func (x *AccountData) GetSvrPin() string { return "" } +func (x *AccountData) GetAndroidSpecificSettings() *AccountData_AndroidSpecificSettings { + if x != nil { + return x.AndroidSpecificSettings + } + return nil +} + +func (x *AccountData) GetBioText() string { + if x != nil { + return x.BioText + } + return "" +} + +func (x *AccountData) GetBioEmoji() string { + if x != nil { + return x.BioEmoji + } + return "" +} + +func (x *AccountData) GetKeyTransparencyData() []byte { + if x != nil { + return x.KeyTransparencyData + } + return nil +} + type Recipient struct { state protoimpl.MessageState `protogen:"open.v1"` Id uint64 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"` // generated id for reference only within this file @@ -2423,22 +2709,23 @@ type Contact struct { // // *Contact_Registered_ // *Contact_NotRegistered_ - Registration isContact_Registration `protobuf_oneof:"registration"` - ProfileKey []byte `protobuf:"bytes,9,opt,name=profileKey,proto3,oneof" json:"profileKey,omitempty"` - ProfileSharing bool `protobuf:"varint,10,opt,name=profileSharing,proto3" json:"profileSharing,omitempty"` - ProfileGivenName *string `protobuf:"bytes,11,opt,name=profileGivenName,proto3,oneof" json:"profileGivenName,omitempty"` - ProfileFamilyName *string `protobuf:"bytes,12,opt,name=profileFamilyName,proto3,oneof" json:"profileFamilyName,omitempty"` - HideStory bool `protobuf:"varint,13,opt,name=hideStory,proto3" json:"hideStory,omitempty"` - IdentityKey []byte `protobuf:"bytes,14,opt,name=identityKey,proto3,oneof" json:"identityKey,omitempty"` - IdentityState Contact_IdentityState `protobuf:"varint,15,opt,name=identityState,proto3,enum=signal.backup.Contact_IdentityState" json:"identityState,omitempty"` - Nickname *Contact_Name `protobuf:"bytes,16,opt,name=nickname,proto3" json:"nickname,omitempty"` // absent iff both `given` and `family` are empty - Note string `protobuf:"bytes,17,opt,name=note,proto3" json:"note,omitempty"` - SystemGivenName string `protobuf:"bytes,18,opt,name=systemGivenName,proto3" json:"systemGivenName,omitempty"` - SystemFamilyName string `protobuf:"bytes,19,opt,name=systemFamilyName,proto3" json:"systemFamilyName,omitempty"` - SystemNickname string `protobuf:"bytes,20,opt,name=systemNickname,proto3" json:"systemNickname,omitempty"` - AvatarColor *AvatarColor `protobuf:"varint,21,opt,name=avatarColor,proto3,enum=signal.backup.AvatarColor,oneof" json:"avatarColor,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache + Registration isContact_Registration `protobuf_oneof:"registration"` + ProfileKey []byte `protobuf:"bytes,9,opt,name=profileKey,proto3,oneof" json:"profileKey,omitempty"` + ProfileSharing bool `protobuf:"varint,10,opt,name=profileSharing,proto3" json:"profileSharing,omitempty"` + ProfileGivenName *string `protobuf:"bytes,11,opt,name=profileGivenName,proto3,oneof" json:"profileGivenName,omitempty"` + ProfileFamilyName *string `protobuf:"bytes,12,opt,name=profileFamilyName,proto3,oneof" json:"profileFamilyName,omitempty"` + HideStory bool `protobuf:"varint,13,opt,name=hideStory,proto3" json:"hideStory,omitempty"` + IdentityKey []byte `protobuf:"bytes,14,opt,name=identityKey,proto3,oneof" json:"identityKey,omitempty"` + IdentityState Contact_IdentityState `protobuf:"varint,15,opt,name=identityState,proto3,enum=signal.backup.Contact_IdentityState" json:"identityState,omitempty"` + Nickname *Contact_Name `protobuf:"bytes,16,opt,name=nickname,proto3" json:"nickname,omitempty"` // absent iff both `given` and `family` are empty + Note string `protobuf:"bytes,17,opt,name=note,proto3" json:"note,omitempty"` + SystemGivenName string `protobuf:"bytes,18,opt,name=systemGivenName,proto3" json:"systemGivenName,omitempty"` + SystemFamilyName string `protobuf:"bytes,19,opt,name=systemFamilyName,proto3" json:"systemFamilyName,omitempty"` + SystemNickname string `protobuf:"bytes,20,opt,name=systemNickname,proto3" json:"systemNickname,omitempty"` + AvatarColor *AvatarColor `protobuf:"varint,21,opt,name=avatarColor,proto3,enum=signal.backup.AvatarColor,oneof" json:"avatarColor,omitempty"` + KeyTransparencyData []byte `protobuf:"bytes,22,opt,name=keyTransparencyData,proto3,oneof" json:"keyTransparencyData,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } func (x *Contact) Reset() { @@ -2629,6 +2916,13 @@ func (x *Contact) GetAvatarColor() AvatarColor { return AvatarColor_A100 } +func (x *Contact) GetKeyTransparencyData() []byte { + if x != nil { + return x.KeyTransparencyData + } + return nil +} + type isContact_Registration interface { isContact_Registration() } @@ -3286,7 +3580,8 @@ type ChatItem struct { // *ChatItem_ViewOnceMessage // *ChatItem_DirectStoryReplyMessage // *ChatItem_Poll - Item isChatItem_Item `protobuf_oneof:"item"` + Item isChatItem_Item `protobuf_oneof:"item"` + PinDetails *ChatItem_PinDetails `protobuf:"bytes,21,opt,name=pinDetails,proto3" json:"pinDetails,omitempty"` // only set if message is pinned unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } @@ -3501,6 +3796,13 @@ func (x *ChatItem) GetPoll() *Poll { return nil } +func (x *ChatItem) GetPinDetails() *ChatItem_PinDetails { + if x != nil { + return x.PinDetails + } + return nil +} + type isChatItem_DirectionalDetails interface { isChatItem_DirectionalDetails() } @@ -4983,6 +5285,7 @@ type Poll struct { AllowMultiple bool `protobuf:"varint,2,opt,name=allowMultiple,proto3" json:"allowMultiple,omitempty"` Options []*Poll_PollOption `protobuf:"bytes,3,rep,name=options,proto3" json:"options,omitempty"` // At least two HasEnded bool `protobuf:"varint,4,opt,name=hasEnded,proto3" json:"hasEnded,omitempty"` + Reactions []*Reaction `protobuf:"bytes,5,rep,name=reactions,proto3" json:"reactions,omitempty"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } @@ -5045,6 +5348,13 @@ func (x *Poll) GetHasEnded() bool { return false } +func (x *Poll) GetReactions() []*Reaction { + if x != nil { + return x.Reactions + } + return nil +} + type ChatUpdateMessage struct { state protoimpl.MessageState `protogen:"open.v1"` // If unset, importers should ignore the update message without throwing an error. @@ -5061,6 +5371,7 @@ type ChatUpdateMessage struct { // *ChatUpdateMessage_GroupCall // *ChatUpdateMessage_LearnedProfileChange // *ChatUpdateMessage_PollTerminate + // *ChatUpdateMessage_PinMessage Update isChatUpdateMessage_Update `protobuf_oneof:"update"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache @@ -5193,6 +5504,15 @@ func (x *ChatUpdateMessage) GetPollTerminate() *PollTerminateUpdate { return nil } +func (x *ChatUpdateMessage) GetPinMessage() *PinMessageUpdate { + if x != nil { + if x, ok := x.Update.(*ChatUpdateMessage_PinMessage); ok { + return x.PinMessage + } + } + return nil +} + type isChatUpdateMessage_Update interface { isChatUpdateMessage_Update() } @@ -5237,6 +5557,10 @@ type ChatUpdateMessage_PollTerminate struct { PollTerminate *PollTerminateUpdate `protobuf:"bytes,10,opt,name=pollTerminate,proto3,oneof"` } +type ChatUpdateMessage_PinMessage struct { + PinMessage *PinMessageUpdate `protobuf:"bytes,11,opt,name=pinMessage,proto3,oneof"` +} + func (*ChatUpdateMessage_SimpleUpdate) isChatUpdateMessage_Update() {} func (*ChatUpdateMessage_GroupChange) isChatUpdateMessage_Update() {} @@ -5257,6 +5581,8 @@ func (*ChatUpdateMessage_LearnedProfileChange) isChatUpdateMessage_Update() {} func (*ChatUpdateMessage_PollTerminate) isChatUpdateMessage_Update() {} +func (*ChatUpdateMessage_PinMessage) isChatUpdateMessage_Update() {} + type IndividualCall struct { state protoimpl.MessageState `protogen:"open.v1"` CallId *uint64 `protobuf:"varint,1,opt,name=callId,proto3,oneof" json:"callId,omitempty"` @@ -7532,6 +7858,58 @@ func (x *PollTerminateUpdate) GetQuestion() string { return "" } +type PinMessageUpdate struct { + state protoimpl.MessageState `protogen:"open.v1"` + TargetSentTimestamp uint64 `protobuf:"varint,1,opt,name=targetSentTimestamp,proto3" json:"targetSentTimestamp,omitempty"` + AuthorId uint64 `protobuf:"varint,2,opt,name=authorId,proto3" json:"authorId,omitempty"` // recipient id + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *PinMessageUpdate) Reset() { + *x = PinMessageUpdate{} + mi := &file_backuppb_Backup_proto_msgTypes[78] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *PinMessageUpdate) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*PinMessageUpdate) ProtoMessage() {} + +func (x *PinMessageUpdate) ProtoReflect() protoreflect.Message { + mi := &file_backuppb_Backup_proto_msgTypes[78] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use PinMessageUpdate.ProtoReflect.Descriptor instead. +func (*PinMessageUpdate) Descriptor() ([]byte, []int) { + return file_backuppb_Backup_proto_rawDescGZIP(), []int{78} +} + +func (x *PinMessageUpdate) GetTargetSentTimestamp() uint64 { + if x != nil { + return x.TargetSentTimestamp + } + return 0 +} + +func (x *PinMessageUpdate) GetAuthorId() uint64 { + if x != nil { + return x.AuthorId + } + return 0 +} + type StickerPack struct { state protoimpl.MessageState `protogen:"open.v1"` PackId []byte `protobuf:"bytes,1,opt,name=packId,proto3" json:"packId,omitempty"` @@ -7542,7 +7920,7 @@ type StickerPack struct { func (x *StickerPack) Reset() { *x = StickerPack{} - mi := &file_backuppb_Backup_proto_msgTypes[78] + mi := &file_backuppb_Backup_proto_msgTypes[79] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7554,7 +7932,7 @@ func (x *StickerPack) String() string { func (*StickerPack) ProtoMessage() {} func (x *StickerPack) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[78] + mi := &file_backuppb_Backup_proto_msgTypes[79] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7567,7 +7945,7 @@ func (x *StickerPack) ProtoReflect() protoreflect.Message { // Deprecated: Use StickerPack.ProtoReflect.Descriptor instead. func (*StickerPack) Descriptor() ([]byte, []int) { - return file_backuppb_Backup_proto_rawDescGZIP(), []int{78} + return file_backuppb_Backup_proto_rawDescGZIP(), []int{79} } func (x *StickerPack) GetPackId() []byte { @@ -7608,7 +7986,7 @@ type ChatStyle struct { func (x *ChatStyle) Reset() { *x = ChatStyle{} - mi := &file_backuppb_Backup_proto_msgTypes[79] + mi := &file_backuppb_Backup_proto_msgTypes[80] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7620,7 +7998,7 @@ func (x *ChatStyle) String() string { func (*ChatStyle) ProtoMessage() {} func (x *ChatStyle) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[79] + mi := &file_backuppb_Backup_proto_msgTypes[80] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7633,7 +8011,7 @@ func (x *ChatStyle) ProtoReflect() protoreflect.Message { // Deprecated: Use ChatStyle.ProtoReflect.Descriptor instead. func (*ChatStyle) Descriptor() ([]byte, []int) { - return file_backuppb_Backup_proto_rawDescGZIP(), []int{79} + return file_backuppb_Backup_proto_rawDescGZIP(), []int{80} } func (x *ChatStyle) GetWallpaper() isChatStyle_Wallpaper { @@ -7765,7 +8143,7 @@ type NotificationProfile struct { func (x *NotificationProfile) Reset() { *x = NotificationProfile{} - mi := &file_backuppb_Backup_proto_msgTypes[80] + mi := &file_backuppb_Backup_proto_msgTypes[81] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7777,7 +8155,7 @@ func (x *NotificationProfile) String() string { func (*NotificationProfile) ProtoMessage() {} func (x *NotificationProfile) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[80] + mi := &file_backuppb_Backup_proto_msgTypes[81] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7790,7 +8168,7 @@ func (x *NotificationProfile) ProtoReflect() protoreflect.Message { // Deprecated: Use NotificationProfile.ProtoReflect.Descriptor instead. func (*NotificationProfile) Descriptor() ([]byte, []int) { - return file_backuppb_Backup_proto_rawDescGZIP(), []int{80} + return file_backuppb_Backup_proto_rawDescGZIP(), []int{81} } func (x *NotificationProfile) GetName() string { @@ -7896,7 +8274,7 @@ type ChatFolder struct { func (x *ChatFolder) Reset() { *x = ChatFolder{} - mi := &file_backuppb_Backup_proto_msgTypes[81] + mi := &file_backuppb_Backup_proto_msgTypes[82] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7908,7 +8286,7 @@ func (x *ChatFolder) String() string { func (*ChatFolder) ProtoMessage() {} func (x *ChatFolder) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[81] + mi := &file_backuppb_Backup_proto_msgTypes[82] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7921,7 +8299,7 @@ func (x *ChatFolder) ProtoReflect() protoreflect.Message { // Deprecated: Use ChatFolder.ProtoReflect.Descriptor instead. func (*ChatFolder) Descriptor() ([]byte, []int) { - return file_backuppb_Backup_proto_rawDescGZIP(), []int{81} + return file_backuppb_Backup_proto_rawDescGZIP(), []int{82} } func (x *ChatFolder) GetName() string { @@ -7998,7 +8376,7 @@ type AccountData_UsernameLink struct { func (x *AccountData_UsernameLink) Reset() { *x = AccountData_UsernameLink{} - mi := &file_backuppb_Backup_proto_msgTypes[82] + mi := &file_backuppb_Backup_proto_msgTypes[83] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8010,7 +8388,7 @@ func (x *AccountData_UsernameLink) String() string { func (*AccountData_UsernameLink) ProtoMessage() {} func (x *AccountData_UsernameLink) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[82] + mi := &file_backuppb_Backup_proto_msgTypes[83] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8047,6 +8425,74 @@ func (x *AccountData_UsernameLink) GetColor() AccountData_UsernameLink_Color { return AccountData_UsernameLink_UNKNOWN } +type AccountData_AutoDownloadSettings struct { + state protoimpl.MessageState `protogen:"open.v1"` + Images AccountData_AutoDownloadSettings_AutoDownloadOption `protobuf:"varint,1,opt,name=images,proto3,enum=signal.backup.AccountData_AutoDownloadSettings_AutoDownloadOption" json:"images,omitempty"` + Audio AccountData_AutoDownloadSettings_AutoDownloadOption `protobuf:"varint,2,opt,name=audio,proto3,enum=signal.backup.AccountData_AutoDownloadSettings_AutoDownloadOption" json:"audio,omitempty"` + Video AccountData_AutoDownloadSettings_AutoDownloadOption `protobuf:"varint,3,opt,name=video,proto3,enum=signal.backup.AccountData_AutoDownloadSettings_AutoDownloadOption" json:"video,omitempty"` + Documents AccountData_AutoDownloadSettings_AutoDownloadOption `protobuf:"varint,4,opt,name=documents,proto3,enum=signal.backup.AccountData_AutoDownloadSettings_AutoDownloadOption" json:"documents,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *AccountData_AutoDownloadSettings) Reset() { + *x = AccountData_AutoDownloadSettings{} + mi := &file_backuppb_Backup_proto_msgTypes[84] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *AccountData_AutoDownloadSettings) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*AccountData_AutoDownloadSettings) ProtoMessage() {} + +func (x *AccountData_AutoDownloadSettings) ProtoReflect() protoreflect.Message { + mi := &file_backuppb_Backup_proto_msgTypes[84] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use AccountData_AutoDownloadSettings.ProtoReflect.Descriptor instead. +func (*AccountData_AutoDownloadSettings) Descriptor() ([]byte, []int) { + return file_backuppb_Backup_proto_rawDescGZIP(), []int{2, 1} +} + +func (x *AccountData_AutoDownloadSettings) GetImages() AccountData_AutoDownloadSettings_AutoDownloadOption { + if x != nil { + return x.Images + } + return AccountData_AutoDownloadSettings_UNKNOWN +} + +func (x *AccountData_AutoDownloadSettings) GetAudio() AccountData_AutoDownloadSettings_AutoDownloadOption { + if x != nil { + return x.Audio + } + return AccountData_AutoDownloadSettings_UNKNOWN +} + +func (x *AccountData_AutoDownloadSettings) GetVideo() AccountData_AutoDownloadSettings_AutoDownloadOption { + if x != nil { + return x.Video + } + return AccountData_AutoDownloadSettings_UNKNOWN +} + +func (x *AccountData_AutoDownloadSettings) GetDocuments() AccountData_AutoDownloadSettings_AutoDownloadOption { + if x != nil { + return x.Documents + } + return AccountData_AutoDownloadSettings_UNKNOWN +} + type AccountData_AccountSettings struct { state protoimpl.MessageState `protogen:"open.v1"` ReadReceipts bool `protobuf:"varint,1,opt,name=readReceipts,proto3" json:"readReceipts,omitempty"` @@ -8070,14 +8516,22 @@ type AccountData_AccountSettings struct { CustomChatColors []*ChatStyle_CustomChatColor `protobuf:"bytes,19,rep,name=customChatColors,proto3" json:"customChatColors,omitempty"` OptimizeOnDeviceStorage bool `protobuf:"varint,20,opt,name=optimizeOnDeviceStorage,proto3" json:"optimizeOnDeviceStorage,omitempty"` // See zkgroup for integer particular values. Unset if backups are not enabled. - BackupTier *uint64 `protobuf:"varint,21,opt,name=backupTier,proto3,oneof" json:"backupTier,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache + BackupTier *uint64 `protobuf:"varint,21,opt,name=backupTier,proto3,oneof" json:"backupTier,omitempty"` + DefaultSentMediaQuality AccountData_SentMediaQuality `protobuf:"varint,23,opt,name=defaultSentMediaQuality,proto3,enum=signal.backup.AccountData_SentMediaQuality" json:"defaultSentMediaQuality,omitempty"` + AutoDownloadSettings *AccountData_AutoDownloadSettings `protobuf:"bytes,24,opt,name=autoDownloadSettings,proto3" json:"autoDownloadSettings,omitempty"` + ScreenLockTimeoutMinutes *uint32 `protobuf:"varint,26,opt,name=screenLockTimeoutMinutes,proto3,oneof" json:"screenLockTimeoutMinutes,omitempty"` // If unset, consider screen lock to be disabled. + PinReminders *bool `protobuf:"varint,27,opt,name=pinReminders,proto3,oneof" json:"pinReminders,omitempty"` // If unset, consider pin reminders to be enabled. + AppTheme AccountData_AppTheme `protobuf:"varint,28,opt,name=appTheme,proto3,enum=signal.backup.AccountData_AppTheme" json:"appTheme,omitempty"` // If unset, treat the same as "Unknown" case + CallsUseLessDataSetting AccountData_CallsUseLessDataSetting `protobuf:"varint,29,opt,name=callsUseLessDataSetting,proto3,enum=signal.backup.AccountData_CallsUseLessDataSetting" json:"callsUseLessDataSetting,omitempty"` // If unset, treat the same as "Unknown" case + AllowSealedSenderFromAnyone bool `protobuf:"varint,30,opt,name=allowSealedSenderFromAnyone,proto3" json:"allowSealedSenderFromAnyone,omitempty"` + AllowAutomaticKeyVerification bool `protobuf:"varint,31,opt,name=allowAutomaticKeyVerification,proto3" json:"allowAutomaticKeyVerification,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } func (x *AccountData_AccountSettings) Reset() { *x = AccountData_AccountSettings{} - mi := &file_backuppb_Backup_proto_msgTypes[83] + mi := &file_backuppb_Backup_proto_msgTypes[85] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8089,7 +8543,7 @@ func (x *AccountData_AccountSettings) String() string { func (*AccountData_AccountSettings) ProtoMessage() {} func (x *AccountData_AccountSettings) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[83] + mi := &file_backuppb_Backup_proto_msgTypes[85] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8102,7 +8556,7 @@ func (x *AccountData_AccountSettings) ProtoReflect() protoreflect.Message { // Deprecated: Use AccountData_AccountSettings.ProtoReflect.Descriptor instead. func (*AccountData_AccountSettings) Descriptor() ([]byte, []int) { - return file_backuppb_Backup_proto_rawDescGZIP(), []int{2, 1} + return file_backuppb_Backup_proto_rawDescGZIP(), []int{2, 2} } func (x *AccountData_AccountSettings) GetReadReceipts() bool { @@ -8252,6 +8706,62 @@ func (x *AccountData_AccountSettings) GetBackupTier() uint64 { return 0 } +func (x *AccountData_AccountSettings) GetDefaultSentMediaQuality() AccountData_SentMediaQuality { + if x != nil { + return x.DefaultSentMediaQuality + } + return AccountData_UNKNOWN_QUALITY +} + +func (x *AccountData_AccountSettings) GetAutoDownloadSettings() *AccountData_AutoDownloadSettings { + if x != nil { + return x.AutoDownloadSettings + } + return nil +} + +func (x *AccountData_AccountSettings) GetScreenLockTimeoutMinutes() uint32 { + if x != nil && x.ScreenLockTimeoutMinutes != nil { + return *x.ScreenLockTimeoutMinutes + } + return 0 +} + +func (x *AccountData_AccountSettings) GetPinReminders() bool { + if x != nil && x.PinReminders != nil { + return *x.PinReminders + } + return false +} + +func (x *AccountData_AccountSettings) GetAppTheme() AccountData_AppTheme { + if x != nil { + return x.AppTheme + } + return AccountData_UNKNOWN_APP_THEME +} + +func (x *AccountData_AccountSettings) GetCallsUseLessDataSetting() AccountData_CallsUseLessDataSetting { + if x != nil { + return x.CallsUseLessDataSetting + } + return AccountData_UNKNOWN_CALL_DATA_SETTING +} + +func (x *AccountData_AccountSettings) GetAllowSealedSenderFromAnyone() bool { + if x != nil { + return x.AllowSealedSenderFromAnyone + } + return false +} + +func (x *AccountData_AccountSettings) GetAllowAutomaticKeyVerification() bool { + if x != nil { + return x.AllowAutomaticKeyVerification + } + return false +} + type AccountData_SubscriberData struct { state protoimpl.MessageState `protogen:"open.v1"` SubscriberId []byte `protobuf:"bytes,1,opt,name=subscriberId,proto3" json:"subscriberId,omitempty"` @@ -8263,7 +8773,7 @@ type AccountData_SubscriberData struct { func (x *AccountData_SubscriberData) Reset() { *x = AccountData_SubscriberData{} - mi := &file_backuppb_Backup_proto_msgTypes[84] + mi := &file_backuppb_Backup_proto_msgTypes[86] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8275,7 +8785,7 @@ func (x *AccountData_SubscriberData) String() string { func (*AccountData_SubscriberData) ProtoMessage() {} func (x *AccountData_SubscriberData) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[84] + mi := &file_backuppb_Backup_proto_msgTypes[86] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8288,7 +8798,7 @@ func (x *AccountData_SubscriberData) ProtoReflect() protoreflect.Message { // Deprecated: Use AccountData_SubscriberData.ProtoReflect.Descriptor instead. func (*AccountData_SubscriberData) Descriptor() ([]byte, []int) { - return file_backuppb_Backup_proto_rawDescGZIP(), []int{2, 2} + return file_backuppb_Backup_proto_rawDescGZIP(), []int{2, 3} } func (x *AccountData_SubscriberData) GetSubscriberId() []byte { @@ -8328,7 +8838,7 @@ type AccountData_IAPSubscriberData struct { func (x *AccountData_IAPSubscriberData) Reset() { *x = AccountData_IAPSubscriberData{} - mi := &file_backuppb_Backup_proto_msgTypes[85] + mi := &file_backuppb_Backup_proto_msgTypes[87] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8340,7 +8850,7 @@ func (x *AccountData_IAPSubscriberData) String() string { func (*AccountData_IAPSubscriberData) ProtoMessage() {} func (x *AccountData_IAPSubscriberData) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[85] + mi := &file_backuppb_Backup_proto_msgTypes[87] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8353,7 +8863,7 @@ func (x *AccountData_IAPSubscriberData) ProtoReflect() protoreflect.Message { // Deprecated: Use AccountData_IAPSubscriberData.ProtoReflect.Descriptor instead. func (*AccountData_IAPSubscriberData) Descriptor() ([]byte, []int) { - return file_backuppb_Backup_proto_rawDescGZIP(), []int{2, 3} + return file_backuppb_Backup_proto_rawDescGZIP(), []int{2, 4} } func (x *AccountData_IAPSubscriberData) GetSubscriberId() []byte { @@ -8408,6 +8918,66 @@ func (*AccountData_IAPSubscriberData_PurchaseToken) isAccountData_IAPSubscriberD func (*AccountData_IAPSubscriberData_OriginalTransactionId) isAccountData_IAPSubscriberData_IapSubscriptionId() { } +type AccountData_AndroidSpecificSettings struct { + state protoimpl.MessageState `protogen:"open.v1"` + UseSystemEmoji bool `protobuf:"varint,1,opt,name=useSystemEmoji,proto3" json:"useSystemEmoji,omitempty"` + ScreenshotSecurity bool `protobuf:"varint,2,opt,name=screenshotSecurity,proto3" json:"screenshotSecurity,omitempty"` + NavigationBarSize AccountData_AndroidSpecificSettings_NavigationBarSize `protobuf:"varint,3,opt,name=navigationBarSize,proto3,enum=signal.backup.AccountData_AndroidSpecificSettings_NavigationBarSize" json:"navigationBarSize,omitempty"` // If unset, treat the same as "Unknown" case + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *AccountData_AndroidSpecificSettings) Reset() { + *x = AccountData_AndroidSpecificSettings{} + mi := &file_backuppb_Backup_proto_msgTypes[88] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *AccountData_AndroidSpecificSettings) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*AccountData_AndroidSpecificSettings) ProtoMessage() {} + +func (x *AccountData_AndroidSpecificSettings) ProtoReflect() protoreflect.Message { + mi := &file_backuppb_Backup_proto_msgTypes[88] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use AccountData_AndroidSpecificSettings.ProtoReflect.Descriptor instead. +func (*AccountData_AndroidSpecificSettings) Descriptor() ([]byte, []int) { + return file_backuppb_Backup_proto_rawDescGZIP(), []int{2, 5} +} + +func (x *AccountData_AndroidSpecificSettings) GetUseSystemEmoji() bool { + if x != nil { + return x.UseSystemEmoji + } + return false +} + +func (x *AccountData_AndroidSpecificSettings) GetScreenshotSecurity() bool { + if x != nil { + return x.ScreenshotSecurity + } + return false +} + +func (x *AccountData_AndroidSpecificSettings) GetNavigationBarSize() AccountData_AndroidSpecificSettings_NavigationBarSize { + if x != nil { + return x.NavigationBarSize + } + return AccountData_AndroidSpecificSettings_UNKNOWN_BAR_SIZE +} + type Contact_Registered struct { state protoimpl.MessageState `protogen:"open.v1"` unknownFields protoimpl.UnknownFields @@ -8416,7 +8986,7 @@ type Contact_Registered struct { func (x *Contact_Registered) Reset() { *x = Contact_Registered{} - mi := &file_backuppb_Backup_proto_msgTypes[86] + mi := &file_backuppb_Backup_proto_msgTypes[89] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8428,7 +8998,7 @@ func (x *Contact_Registered) String() string { func (*Contact_Registered) ProtoMessage() {} func (x *Contact_Registered) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[86] + mi := &file_backuppb_Backup_proto_msgTypes[89] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8453,7 +9023,7 @@ type Contact_NotRegistered struct { func (x *Contact_NotRegistered) Reset() { *x = Contact_NotRegistered{} - mi := &file_backuppb_Backup_proto_msgTypes[87] + mi := &file_backuppb_Backup_proto_msgTypes[90] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8465,7 +9035,7 @@ func (x *Contact_NotRegistered) String() string { func (*Contact_NotRegistered) ProtoMessage() {} func (x *Contact_NotRegistered) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[87] + mi := &file_backuppb_Backup_proto_msgTypes[90] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8498,7 +9068,7 @@ type Contact_Name struct { func (x *Contact_Name) Reset() { *x = Contact_Name{} - mi := &file_backuppb_Backup_proto_msgTypes[88] + mi := &file_backuppb_Backup_proto_msgTypes[91] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8510,7 +9080,7 @@ func (x *Contact_Name) String() string { func (*Contact_Name) ProtoMessage() {} func (x *Contact_Name) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[88] + mi := &file_backuppb_Backup_proto_msgTypes[91] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8565,7 +9135,7 @@ type Group_GroupSnapshot struct { func (x *Group_GroupSnapshot) Reset() { *x = Group_GroupSnapshot{} - mi := &file_backuppb_Backup_proto_msgTypes[89] + mi := &file_backuppb_Backup_proto_msgTypes[92] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8577,7 +9147,7 @@ func (x *Group_GroupSnapshot) String() string { func (*Group_GroupSnapshot) ProtoMessage() {} func (x *Group_GroupSnapshot) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[89] + mi := &file_backuppb_Backup_proto_msgTypes[92] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8694,7 +9264,7 @@ type Group_GroupAttributeBlob struct { func (x *Group_GroupAttributeBlob) Reset() { *x = Group_GroupAttributeBlob{} - mi := &file_backuppb_Backup_proto_msgTypes[90] + mi := &file_backuppb_Backup_proto_msgTypes[93] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8706,7 +9276,7 @@ func (x *Group_GroupAttributeBlob) String() string { func (*Group_GroupAttributeBlob) ProtoMessage() {} func (x *Group_GroupAttributeBlob) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[90] + mi := &file_backuppb_Backup_proto_msgTypes[93] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8804,7 +9374,7 @@ type Group_Member struct { func (x *Group_Member) Reset() { *x = Group_Member{} - mi := &file_backuppb_Backup_proto_msgTypes[91] + mi := &file_backuppb_Backup_proto_msgTypes[94] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8816,7 +9386,7 @@ func (x *Group_Member) String() string { func (*Group_Member) ProtoMessage() {} func (x *Group_Member) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[91] + mi := &file_backuppb_Backup_proto_msgTypes[94] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8864,7 +9434,7 @@ type Group_MemberPendingProfileKey struct { func (x *Group_MemberPendingProfileKey) Reset() { *x = Group_MemberPendingProfileKey{} - mi := &file_backuppb_Backup_proto_msgTypes[92] + mi := &file_backuppb_Backup_proto_msgTypes[95] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8876,7 +9446,7 @@ func (x *Group_MemberPendingProfileKey) String() string { func (*Group_MemberPendingProfileKey) ProtoMessage() {} func (x *Group_MemberPendingProfileKey) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[92] + mi := &file_backuppb_Backup_proto_msgTypes[95] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8923,7 +9493,7 @@ type Group_MemberPendingAdminApproval struct { func (x *Group_MemberPendingAdminApproval) Reset() { *x = Group_MemberPendingAdminApproval{} - mi := &file_backuppb_Backup_proto_msgTypes[93] + mi := &file_backuppb_Backup_proto_msgTypes[96] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8935,7 +9505,7 @@ func (x *Group_MemberPendingAdminApproval) String() string { func (*Group_MemberPendingAdminApproval) ProtoMessage() {} func (x *Group_MemberPendingAdminApproval) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[93] + mi := &file_backuppb_Backup_proto_msgTypes[96] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8975,7 +9545,7 @@ type Group_MemberBanned struct { func (x *Group_MemberBanned) Reset() { *x = Group_MemberBanned{} - mi := &file_backuppb_Backup_proto_msgTypes[94] + mi := &file_backuppb_Backup_proto_msgTypes[97] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8987,7 +9557,7 @@ func (x *Group_MemberBanned) String() string { func (*Group_MemberBanned) ProtoMessage() {} func (x *Group_MemberBanned) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[94] + mi := &file_backuppb_Backup_proto_msgTypes[97] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9028,7 +9598,7 @@ type Group_AccessControl struct { func (x *Group_AccessControl) Reset() { *x = Group_AccessControl{} - mi := &file_backuppb_Backup_proto_msgTypes[95] + mi := &file_backuppb_Backup_proto_msgTypes[98] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9040,7 +9610,7 @@ func (x *Group_AccessControl) String() string { func (*Group_AccessControl) ProtoMessage() {} func (x *Group_AccessControl) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[95] + mi := &file_backuppb_Backup_proto_msgTypes[98] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9089,7 +9659,7 @@ type ChatItem_IncomingMessageDetails struct { func (x *ChatItem_IncomingMessageDetails) Reset() { *x = ChatItem_IncomingMessageDetails{} - mi := &file_backuppb_Backup_proto_msgTypes[96] + mi := &file_backuppb_Backup_proto_msgTypes[99] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9101,7 +9671,7 @@ func (x *ChatItem_IncomingMessageDetails) String() string { func (*ChatItem_IncomingMessageDetails) ProtoMessage() {} func (x *ChatItem_IncomingMessageDetails) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[96] + mi := &file_backuppb_Backup_proto_msgTypes[99] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9155,7 +9725,7 @@ type ChatItem_OutgoingMessageDetails struct { func (x *ChatItem_OutgoingMessageDetails) Reset() { *x = ChatItem_OutgoingMessageDetails{} - mi := &file_backuppb_Backup_proto_msgTypes[97] + mi := &file_backuppb_Backup_proto_msgTypes[100] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9167,7 +9737,7 @@ func (x *ChatItem_OutgoingMessageDetails) String() string { func (*ChatItem_OutgoingMessageDetails) ProtoMessage() {} func (x *ChatItem_OutgoingMessageDetails) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[97] + mi := &file_backuppb_Backup_proto_msgTypes[100] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9205,7 +9775,7 @@ type ChatItem_DirectionlessMessageDetails struct { func (x *ChatItem_DirectionlessMessageDetails) Reset() { *x = ChatItem_DirectionlessMessageDetails{} - mi := &file_backuppb_Backup_proto_msgTypes[98] + mi := &file_backuppb_Backup_proto_msgTypes[101] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9217,7 +9787,7 @@ func (x *ChatItem_DirectionlessMessageDetails) String() string { func (*ChatItem_DirectionlessMessageDetails) ProtoMessage() {} func (x *ChatItem_DirectionlessMessageDetails) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[98] + mi := &file_backuppb_Backup_proto_msgTypes[101] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9233,6 +9803,96 @@ func (*ChatItem_DirectionlessMessageDetails) Descriptor() ([]byte, []int) { return file_backuppb_Backup_proto_rawDescGZIP(), []int{13, 2} } +type ChatItem_PinDetails struct { + state protoimpl.MessageState `protogen:"open.v1"` + PinnedAtTimestamp uint64 `protobuf:"varint,1,opt,name=pinnedAtTimestamp,proto3" json:"pinnedAtTimestamp,omitempty"` + // Types that are valid to be assigned to PinExpiry: + // + // *ChatItem_PinDetails_PinExpiresAtTimestamp + // *ChatItem_PinDetails_PinNeverExpires + PinExpiry isChatItem_PinDetails_PinExpiry `protobuf_oneof:"pinExpiry"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ChatItem_PinDetails) Reset() { + *x = ChatItem_PinDetails{} + mi := &file_backuppb_Backup_proto_msgTypes[102] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ChatItem_PinDetails) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ChatItem_PinDetails) ProtoMessage() {} + +func (x *ChatItem_PinDetails) ProtoReflect() protoreflect.Message { + mi := &file_backuppb_Backup_proto_msgTypes[102] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ChatItem_PinDetails.ProtoReflect.Descriptor instead. +func (*ChatItem_PinDetails) Descriptor() ([]byte, []int) { + return file_backuppb_Backup_proto_rawDescGZIP(), []int{13, 3} +} + +func (x *ChatItem_PinDetails) GetPinnedAtTimestamp() uint64 { + if x != nil { + return x.PinnedAtTimestamp + } + return 0 +} + +func (x *ChatItem_PinDetails) GetPinExpiry() isChatItem_PinDetails_PinExpiry { + if x != nil { + return x.PinExpiry + } + return nil +} + +func (x *ChatItem_PinDetails) GetPinExpiresAtTimestamp() uint64 { + if x != nil { + if x, ok := x.PinExpiry.(*ChatItem_PinDetails_PinExpiresAtTimestamp); ok { + return x.PinExpiresAtTimestamp + } + } + return 0 +} + +func (x *ChatItem_PinDetails) GetPinNeverExpires() bool { + if x != nil { + if x, ok := x.PinExpiry.(*ChatItem_PinDetails_PinNeverExpires); ok { + return x.PinNeverExpires + } + } + return false +} + +type isChatItem_PinDetails_PinExpiry interface { + isChatItem_PinDetails_PinExpiry() +} + +type ChatItem_PinDetails_PinExpiresAtTimestamp struct { + PinExpiresAtTimestamp uint64 `protobuf:"varint,2,opt,name=pinExpiresAtTimestamp,proto3,oneof"` // timestamp when the pin should expire +} + +type ChatItem_PinDetails_PinNeverExpires struct { + PinNeverExpires bool `protobuf:"varint,3,opt,name=pinNeverExpires,proto3,oneof"` +} + +func (*ChatItem_PinDetails_PinExpiresAtTimestamp) isChatItem_PinDetails_PinExpiry() {} + +func (*ChatItem_PinDetails_PinNeverExpires) isChatItem_PinDetails_PinExpiry() {} + type SendStatus_Pending struct { state protoimpl.MessageState `protogen:"open.v1"` unknownFields protoimpl.UnknownFields @@ -9241,7 +9901,7 @@ type SendStatus_Pending struct { func (x *SendStatus_Pending) Reset() { *x = SendStatus_Pending{} - mi := &file_backuppb_Backup_proto_msgTypes[99] + mi := &file_backuppb_Backup_proto_msgTypes[103] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9253,7 +9913,7 @@ func (x *SendStatus_Pending) String() string { func (*SendStatus_Pending) ProtoMessage() {} func (x *SendStatus_Pending) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[99] + mi := &file_backuppb_Backup_proto_msgTypes[103] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9278,7 +9938,7 @@ type SendStatus_Sent struct { func (x *SendStatus_Sent) Reset() { *x = SendStatus_Sent{} - mi := &file_backuppb_Backup_proto_msgTypes[100] + mi := &file_backuppb_Backup_proto_msgTypes[104] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9290,7 +9950,7 @@ func (x *SendStatus_Sent) String() string { func (*SendStatus_Sent) ProtoMessage() {} func (x *SendStatus_Sent) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[100] + mi := &file_backuppb_Backup_proto_msgTypes[104] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9322,7 +9982,7 @@ type SendStatus_Delivered struct { func (x *SendStatus_Delivered) Reset() { *x = SendStatus_Delivered{} - mi := &file_backuppb_Backup_proto_msgTypes[101] + mi := &file_backuppb_Backup_proto_msgTypes[105] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9334,7 +9994,7 @@ func (x *SendStatus_Delivered) String() string { func (*SendStatus_Delivered) ProtoMessage() {} func (x *SendStatus_Delivered) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[101] + mi := &file_backuppb_Backup_proto_msgTypes[105] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9366,7 +10026,7 @@ type SendStatus_Read struct { func (x *SendStatus_Read) Reset() { *x = SendStatus_Read{} - mi := &file_backuppb_Backup_proto_msgTypes[102] + mi := &file_backuppb_Backup_proto_msgTypes[106] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9378,7 +10038,7 @@ func (x *SendStatus_Read) String() string { func (*SendStatus_Read) ProtoMessage() {} func (x *SendStatus_Read) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[102] + mi := &file_backuppb_Backup_proto_msgTypes[106] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9410,7 +10070,7 @@ type SendStatus_Viewed struct { func (x *SendStatus_Viewed) Reset() { *x = SendStatus_Viewed{} - mi := &file_backuppb_Backup_proto_msgTypes[103] + mi := &file_backuppb_Backup_proto_msgTypes[107] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9422,7 +10082,7 @@ func (x *SendStatus_Viewed) String() string { func (*SendStatus_Viewed) ProtoMessage() {} func (x *SendStatus_Viewed) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[103] + mi := &file_backuppb_Backup_proto_msgTypes[107] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9454,7 +10114,7 @@ type SendStatus_Skipped struct { func (x *SendStatus_Skipped) Reset() { *x = SendStatus_Skipped{} - mi := &file_backuppb_Backup_proto_msgTypes[104] + mi := &file_backuppb_Backup_proto_msgTypes[108] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9466,7 +10126,7 @@ func (x *SendStatus_Skipped) String() string { func (*SendStatus_Skipped) ProtoMessage() {} func (x *SendStatus_Skipped) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[104] + mi := &file_backuppb_Backup_proto_msgTypes[108] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9491,7 +10151,7 @@ type SendStatus_Failed struct { func (x *SendStatus_Failed) Reset() { *x = SendStatus_Failed{} - mi := &file_backuppb_Backup_proto_msgTypes[105] + mi := &file_backuppb_Backup_proto_msgTypes[109] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9503,7 +10163,7 @@ func (x *SendStatus_Failed) String() string { func (*SendStatus_Failed) ProtoMessage() {} func (x *SendStatus_Failed) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[105] + mi := &file_backuppb_Backup_proto_msgTypes[109] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9536,7 +10196,7 @@ type DirectStoryReplyMessage_TextReply struct { func (x *DirectStoryReplyMessage_TextReply) Reset() { *x = DirectStoryReplyMessage_TextReply{} - mi := &file_backuppb_Backup_proto_msgTypes[106] + mi := &file_backuppb_Backup_proto_msgTypes[110] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9548,7 +10208,7 @@ func (x *DirectStoryReplyMessage_TextReply) String() string { func (*DirectStoryReplyMessage_TextReply) ProtoMessage() {} func (x *DirectStoryReplyMessage_TextReply) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[106] + mi := &file_backuppb_Backup_proto_msgTypes[110] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9593,7 +10253,7 @@ type PaymentNotification_TransactionDetails struct { func (x *PaymentNotification_TransactionDetails) Reset() { *x = PaymentNotification_TransactionDetails{} - mi := &file_backuppb_Backup_proto_msgTypes[107] + mi := &file_backuppb_Backup_proto_msgTypes[111] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9605,7 +10265,7 @@ func (x *PaymentNotification_TransactionDetails) String() string { func (*PaymentNotification_TransactionDetails) ProtoMessage() {} func (x *PaymentNotification_TransactionDetails) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[107] + mi := &file_backuppb_Backup_proto_msgTypes[111] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9674,7 +10334,7 @@ type PaymentNotification_TransactionDetails_MobileCoinTxoIdentification struct { func (x *PaymentNotification_TransactionDetails_MobileCoinTxoIdentification) Reset() { *x = PaymentNotification_TransactionDetails_MobileCoinTxoIdentification{} - mi := &file_backuppb_Backup_proto_msgTypes[108] + mi := &file_backuppb_Backup_proto_msgTypes[112] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9686,7 +10346,7 @@ func (x *PaymentNotification_TransactionDetails_MobileCoinTxoIdentification) Str func (*PaymentNotification_TransactionDetails_MobileCoinTxoIdentification) ProtoMessage() {} func (x *PaymentNotification_TransactionDetails_MobileCoinTxoIdentification) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[108] + mi := &file_backuppb_Backup_proto_msgTypes[112] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9725,7 +10385,7 @@ type PaymentNotification_TransactionDetails_FailedTransaction struct { func (x *PaymentNotification_TransactionDetails_FailedTransaction) Reset() { *x = PaymentNotification_TransactionDetails_FailedTransaction{} - mi := &file_backuppb_Backup_proto_msgTypes[109] + mi := &file_backuppb_Backup_proto_msgTypes[113] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9737,7 +10397,7 @@ func (x *PaymentNotification_TransactionDetails_FailedTransaction) String() stri func (*PaymentNotification_TransactionDetails_FailedTransaction) ProtoMessage() {} func (x *PaymentNotification_TransactionDetails_FailedTransaction) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[109] + mi := &file_backuppb_Backup_proto_msgTypes[113] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9778,7 +10438,7 @@ type PaymentNotification_TransactionDetails_Transaction struct { func (x *PaymentNotification_TransactionDetails_Transaction) Reset() { *x = PaymentNotification_TransactionDetails_Transaction{} - mi := &file_backuppb_Backup_proto_msgTypes[110] + mi := &file_backuppb_Backup_proto_msgTypes[114] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9790,7 +10450,7 @@ func (x *PaymentNotification_TransactionDetails_Transaction) String() string { func (*PaymentNotification_TransactionDetails_Transaction) ProtoMessage() {} func (x *PaymentNotification_TransactionDetails_Transaction) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[110] + mi := &file_backuppb_Backup_proto_msgTypes[114] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9869,7 +10529,7 @@ type ContactAttachment_Name struct { func (x *ContactAttachment_Name) Reset() { *x = ContactAttachment_Name{} - mi := &file_backuppb_Backup_proto_msgTypes[111] + mi := &file_backuppb_Backup_proto_msgTypes[115] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9881,7 +10541,7 @@ func (x *ContactAttachment_Name) String() string { func (*ContactAttachment_Name) ProtoMessage() {} func (x *ContactAttachment_Name) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[111] + mi := &file_backuppb_Backup_proto_msgTypes[115] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9950,7 +10610,7 @@ type ContactAttachment_Phone struct { func (x *ContactAttachment_Phone) Reset() { *x = ContactAttachment_Phone{} - mi := &file_backuppb_Backup_proto_msgTypes[112] + mi := &file_backuppb_Backup_proto_msgTypes[116] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9962,7 +10622,7 @@ func (x *ContactAttachment_Phone) String() string { func (*ContactAttachment_Phone) ProtoMessage() {} func (x *ContactAttachment_Phone) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[112] + mi := &file_backuppb_Backup_proto_msgTypes[116] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -10010,7 +10670,7 @@ type ContactAttachment_Email struct { func (x *ContactAttachment_Email) Reset() { *x = ContactAttachment_Email{} - mi := &file_backuppb_Backup_proto_msgTypes[113] + mi := &file_backuppb_Backup_proto_msgTypes[117] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -10022,7 +10682,7 @@ func (x *ContactAttachment_Email) String() string { func (*ContactAttachment_Email) ProtoMessage() {} func (x *ContactAttachment_Email) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[113] + mi := &file_backuppb_Backup_proto_msgTypes[117] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -10076,7 +10736,7 @@ type ContactAttachment_PostalAddress struct { func (x *ContactAttachment_PostalAddress) Reset() { *x = ContactAttachment_PostalAddress{} - mi := &file_backuppb_Backup_proto_msgTypes[114] + mi := &file_backuppb_Backup_proto_msgTypes[118] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -10088,7 +10748,7 @@ func (x *ContactAttachment_PostalAddress) String() string { func (*ContactAttachment_PostalAddress) ProtoMessage() {} func (x *ContactAttachment_PostalAddress) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[114] + mi := &file_backuppb_Backup_proto_msgTypes[118] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -10203,7 +10863,7 @@ type FilePointer_LocatorInfo struct { func (x *FilePointer_LocatorInfo) Reset() { *x = FilePointer_LocatorInfo{} - mi := &file_backuppb_Backup_proto_msgTypes[115] + mi := &file_backuppb_Backup_proto_msgTypes[119] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -10215,7 +10875,7 @@ func (x *FilePointer_LocatorInfo) String() string { func (*FilePointer_LocatorInfo) ProtoMessage() {} func (x *FilePointer_LocatorInfo) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[115] + mi := &file_backuppb_Backup_proto_msgTypes[119] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -10335,7 +10995,7 @@ type Quote_QuotedAttachment struct { func (x *Quote_QuotedAttachment) Reset() { *x = Quote_QuotedAttachment{} - mi := &file_backuppb_Backup_proto_msgTypes[116] + mi := &file_backuppb_Backup_proto_msgTypes[120] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -10347,7 +11007,7 @@ func (x *Quote_QuotedAttachment) String() string { func (*Quote_QuotedAttachment) ProtoMessage() {} func (x *Quote_QuotedAttachment) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[116] + mi := &file_backuppb_Backup_proto_msgTypes[120] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -10394,7 +11054,7 @@ type Poll_PollOption struct { func (x *Poll_PollOption) Reset() { *x = Poll_PollOption{} - mi := &file_backuppb_Backup_proto_msgTypes[117] + mi := &file_backuppb_Backup_proto_msgTypes[121] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -10406,7 +11066,7 @@ func (x *Poll_PollOption) String() string { func (*Poll_PollOption) ProtoMessage() {} func (x *Poll_PollOption) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[117] + mi := &file_backuppb_Backup_proto_msgTypes[121] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -10446,7 +11106,7 @@ type Poll_PollOption_PollVote struct { func (x *Poll_PollOption_PollVote) Reset() { *x = Poll_PollOption_PollVote{} - mi := &file_backuppb_Backup_proto_msgTypes[118] + mi := &file_backuppb_Backup_proto_msgTypes[122] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -10458,7 +11118,7 @@ func (x *Poll_PollOption_PollVote) String() string { func (*Poll_PollOption_PollVote) ProtoMessage() {} func (x *Poll_PollOption_PollVote) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[118] + mi := &file_backuppb_Backup_proto_msgTypes[122] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -10535,7 +11195,7 @@ type GroupChangeChatUpdate_Update struct { func (x *GroupChangeChatUpdate_Update) Reset() { *x = GroupChangeChatUpdate_Update{} - mi := &file_backuppb_Backup_proto_msgTypes[119] + mi := &file_backuppb_Backup_proto_msgTypes[123] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -10547,7 +11207,7 @@ func (x *GroupChangeChatUpdate_Update) String() string { func (*GroupChangeChatUpdate_Update) ProtoMessage() {} func (x *GroupChangeChatUpdate_Update) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[119] + mi := &file_backuppb_Backup_proto_msgTypes[123] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -11121,7 +11781,7 @@ type GroupInvitationRevokedUpdate_Invitee struct { func (x *GroupInvitationRevokedUpdate_Invitee) Reset() { *x = GroupInvitationRevokedUpdate_Invitee{} - mi := &file_backuppb_Backup_proto_msgTypes[120] + mi := &file_backuppb_Backup_proto_msgTypes[124] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -11133,7 +11793,7 @@ func (x *GroupInvitationRevokedUpdate_Invitee) String() string { func (*GroupInvitationRevokedUpdate_Invitee) ProtoMessage() {} func (x *GroupInvitationRevokedUpdate_Invitee) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[120] + mi := &file_backuppb_Backup_proto_msgTypes[124] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -11181,7 +11841,7 @@ type ChatStyle_Gradient struct { func (x *ChatStyle_Gradient) Reset() { *x = ChatStyle_Gradient{} - mi := &file_backuppb_Backup_proto_msgTypes[121] + mi := &file_backuppb_Backup_proto_msgTypes[125] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -11193,7 +11853,7 @@ func (x *ChatStyle_Gradient) String() string { func (*ChatStyle_Gradient) ProtoMessage() {} func (x *ChatStyle_Gradient) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[121] + mi := &file_backuppb_Backup_proto_msgTypes[125] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -11206,7 +11866,7 @@ func (x *ChatStyle_Gradient) ProtoReflect() protoreflect.Message { // Deprecated: Use ChatStyle_Gradient.ProtoReflect.Descriptor instead. func (*ChatStyle_Gradient) Descriptor() ([]byte, []int) { - return file_backuppb_Backup_proto_rawDescGZIP(), []int{79, 0} + return file_backuppb_Backup_proto_rawDescGZIP(), []int{80, 0} } func (x *ChatStyle_Gradient) GetAngle() uint32 { @@ -11246,7 +11906,7 @@ type ChatStyle_CustomChatColor struct { func (x *ChatStyle_CustomChatColor) Reset() { *x = ChatStyle_CustomChatColor{} - mi := &file_backuppb_Backup_proto_msgTypes[122] + mi := &file_backuppb_Backup_proto_msgTypes[126] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -11258,7 +11918,7 @@ func (x *ChatStyle_CustomChatColor) String() string { func (*ChatStyle_CustomChatColor) ProtoMessage() {} func (x *ChatStyle_CustomChatColor) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[122] + mi := &file_backuppb_Backup_proto_msgTypes[126] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -11271,7 +11931,7 @@ func (x *ChatStyle_CustomChatColor) ProtoReflect() protoreflect.Message { // Deprecated: Use ChatStyle_CustomChatColor.ProtoReflect.Descriptor instead. func (*ChatStyle_CustomChatColor) Descriptor() ([]byte, []int) { - return file_backuppb_Backup_proto_rawDescGZIP(), []int{79, 1} + return file_backuppb_Backup_proto_rawDescGZIP(), []int{80, 1} } func (x *ChatStyle_CustomChatColor) GetId() uint64 { @@ -11330,7 +11990,7 @@ type ChatStyle_AutomaticBubbleColor struct { func (x *ChatStyle_AutomaticBubbleColor) Reset() { *x = ChatStyle_AutomaticBubbleColor{} - mi := &file_backuppb_Backup_proto_msgTypes[123] + mi := &file_backuppb_Backup_proto_msgTypes[127] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -11342,7 +12002,7 @@ func (x *ChatStyle_AutomaticBubbleColor) String() string { func (*ChatStyle_AutomaticBubbleColor) ProtoMessage() {} func (x *ChatStyle_AutomaticBubbleColor) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[123] + mi := &file_backuppb_Backup_proto_msgTypes[127] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -11355,7 +12015,7 @@ func (x *ChatStyle_AutomaticBubbleColor) ProtoReflect() protoreflect.Message { // Deprecated: Use ChatStyle_AutomaticBubbleColor.ProtoReflect.Descriptor instead. func (*ChatStyle_AutomaticBubbleColor) Descriptor() ([]byte, []int) { - return file_backuppb_Backup_proto_rawDescGZIP(), []int{79, 2} + return file_backuppb_Backup_proto_rawDescGZIP(), []int{80, 2} } var File_backuppb_Backup_proto protoreflect.FileDescriptor @@ -11382,7 +12042,7 @@ const file_backuppb_Backup_proto_rawDesc = "" + "\n" + "chatFolder\x18\b \x01(\v2\x19.signal.backup.ChatFolderH\x00R\n" + "chatFolderB\x06\n" + - "\x04item\"\xdf\x13\n" + + "\x04item\"\xf9\"\n" + "\vAccountData\x12\x1e\n" + "\n" + "profileKey\x18\x01 \x01(\fR\n" + @@ -11398,7 +12058,11 @@ const file_backuppb_Backup_proto_rawDesc = "" + "\x0faccountSettings\x18\t \x01(\v2*.signal.backup.AccountData.AccountSettingsR\x0faccountSettings\x12b\n" + "\x15backupsSubscriberData\x18\n" + " \x01(\v2,.signal.backup.AccountData.IAPSubscriberDataR\x15backupsSubscriberData\x12\x16\n" + - "\x06svrPin\x18\v \x01(\tR\x06svrPin\x1a\xf6\x01\n" + + "\x06svrPin\x18\v \x01(\tR\x06svrPin\x12l\n" + + "\x17androidSpecificSettings\x18\f \x01(\v22.signal.backup.AccountData.AndroidSpecificSettingsR\x17androidSpecificSettings\x12\x18\n" + + "\abioText\x18\r \x01(\tR\abioText\x12\x1a\n" + + "\bbioEmoji\x18\x0e \x01(\tR\bbioEmoji\x125\n" + + "\x13keyTransparencyData\x18\x0f \x01(\fH\x01R\x13keyTransparencyData\x88\x01\x01\x1a\xf6\x01\n" + "\fUsernameLink\x12\x18\n" + "\aentropy\x18\x01 \x01(\fR\aentropy\x12\x1a\n" + "\bserverId\x18\x02 \x01(\fR\bserverId\x12C\n" + @@ -11414,8 +12078,17 @@ const file_backuppb_Backup_proto_rawDesc = "" + "\x06ORANGE\x10\x06\x12\b\n" + "\x04PINK\x10\a\x12\n" + "\n" + - "\x06PURPLE\x10\b\x1a\xa2\n" + - "\n" + + "\x06PURPLE\x10\b\x1a\xd7\x03\n" + + "\x14AutoDownloadSettings\x12Z\n" + + "\x06images\x18\x01 \x01(\x0e2B.signal.backup.AccountData.AutoDownloadSettings.AutoDownloadOptionR\x06images\x12X\n" + + "\x05audio\x18\x02 \x01(\x0e2B.signal.backup.AccountData.AutoDownloadSettings.AutoDownloadOptionR\x05audio\x12X\n" + + "\x05video\x18\x03 \x01(\x0e2B.signal.backup.AccountData.AutoDownloadSettings.AutoDownloadOptionR\x05video\x12`\n" + + "\tdocuments\x18\x04 \x01(\x0e2B.signal.backup.AccountData.AutoDownloadSettings.AutoDownloadOptionR\tdocuments\"M\n" + + "\x12AutoDownloadOption\x12\v\n" + + "\aUNKNOWN\x10\x00\x12\t\n" + + "\x05NEVER\x10\x01\x12\b\n" + + "\x04WIFI\x10\x02\x12\x15\n" + + "\x11WIFI_AND_CELLULAR\x10\x03\x1a\xc9\x0f\n" + "\x0fAccountSettings\x12\"\n" + "\freadReceipts\x18\x01 \x01(\bR\freadReceipts\x126\n" + "\x16sealedSenderIndicators\x18\x02 \x01(\bR\x16sealedSenderIndicators\x12*\n" + @@ -11440,9 +12113,19 @@ const file_backuppb_Backup_proto_rawDesc = "" + "\x17optimizeOnDeviceStorage\x18\x14 \x01(\bR\x17optimizeOnDeviceStorage\x12#\n" + "\n" + "backupTier\x18\x15 \x01(\x04H\x01R\n" + - "backupTier\x88\x01\x01B\x1b\n" + + "backupTier\x88\x01\x01\x12e\n" + + "\x17defaultSentMediaQuality\x18\x17 \x01(\x0e2+.signal.backup.AccountData.SentMediaQualityR\x17defaultSentMediaQuality\x12c\n" + + "\x14autoDownloadSettings\x18\x18 \x01(\v2/.signal.backup.AccountData.AutoDownloadSettingsR\x14autoDownloadSettings\x12?\n" + + "\x18screenLockTimeoutMinutes\x18\x1a \x01(\rH\x02R\x18screenLockTimeoutMinutes\x88\x01\x01\x12'\n" + + "\fpinReminders\x18\x1b \x01(\bH\x03R\fpinReminders\x88\x01\x01\x12?\n" + + "\bappTheme\x18\x1c \x01(\x0e2#.signal.backup.AccountData.AppThemeR\bappTheme\x12l\n" + + "\x17callsUseLessDataSetting\x18\x1d \x01(\x0e22.signal.backup.AccountData.CallsUseLessDataSettingR\x17callsUseLessDataSetting\x12@\n" + + "\x1ballowSealedSenderFromAnyone\x18\x1e \x01(\bR\x1ballowSealedSenderFromAnyone\x12D\n" + + "\x1dallowAutomaticKeyVerification\x18\x1f \x01(\bR\x1dallowAutomaticKeyVerificationB\x1b\n" + "\x19_storyViewReceiptsEnabledB\r\n" + - "\v_backupTier\x1a\x86\x01\n" + + "\v_backupTierB\x1b\n" + + "\x19_screenLockTimeoutMinutesB\x0f\n" + + "\r_pinRemindersJ\x04\b\x16\x10\x17J\x04\b\x19\x10\x1a\x1a\x86\x01\n" + "\x0eSubscriberData\x12\"\n" + "\fsubscriberId\x18\x01 \x01(\fR\fsubscriberId\x12\"\n" + "\fcurrencyCode\x18\x02 \x01(\tR\fcurrencyCode\x12,\n" + @@ -11451,13 +12134,38 @@ const file_backuppb_Backup_proto_rawDesc = "" + "\fsubscriberId\x18\x01 \x01(\fR\fsubscriberId\x12&\n" + "\rpurchaseToken\x18\x02 \x01(\tH\x00R\rpurchaseToken\x126\n" + "\x15originalTransactionId\x18\x03 \x01(\x04H\x00R\x15originalTransactionIdB\x13\n" + - "\x11iapSubscriptionId\"@\n" + + "\x11iapSubscriptionId\x1a\xa9\x02\n" + + "\x17AndroidSpecificSettings\x12&\n" + + "\x0euseSystemEmoji\x18\x01 \x01(\bR\x0euseSystemEmoji\x12.\n" + + "\x12screenshotSecurity\x18\x02 \x01(\bR\x12screenshotSecurity\x12r\n" + + "\x11navigationBarSize\x18\x03 \x01(\x0e2D.signal.backup.AccountData.AndroidSpecificSettings.NavigationBarSizeR\x11navigationBarSize\"B\n" + + "\x11NavigationBarSize\x12\x14\n" + + "\x10UNKNOWN_BAR_SIZE\x10\x00\x12\n" + + "\n" + + "\x06NORMAL\x10\x01\x12\v\n" + + "\aCOMPACT\x10\x02\"@\n" + "\x16PhoneNumberSharingMode\x12\v\n" + "\aUNKNOWN\x10\x00\x12\r\n" + "\tEVERYBODY\x10\x01\x12\n" + "\n" + - "\x06NOBODY\x10\x02B\v\n" + - "\t_usernameJ\x04\b\b\x10\t\"\x84\x03\n" + + "\x06NOBODY\x10\x02\"?\n" + + "\x10SentMediaQuality\x12\x13\n" + + "\x0fUNKNOWN_QUALITY\x10\x00\x12\f\n" + + "\bSTANDARD\x10\x01\x12\b\n" + + "\x04HIGH\x10\x02\"B\n" + + "\bAppTheme\x12\x15\n" + + "\x11UNKNOWN_APP_THEME\x10\x00\x12\n" + + "\n" + + "\x06SYSTEM\x10\x01\x12\t\n" + + "\x05LIGHT\x10\x02\x12\b\n" + + "\x04DARK\x10\x03\"s\n" + + "\x17CallsUseLessDataSetting\x12\x1d\n" + + "\x19UNKNOWN_CALL_DATA_SETTING\x10\x00\x12\t\n" + + "\x05NEVER\x10\x01\x12\x14\n" + + "\x10MOBILE_DATA_ONLY\x10\x02\x12\x18\n" + + "\x14WIFI_AND_MOBILE_DATA\x10\x03B\v\n" + + "\t_usernameB\x16\n" + + "\x14_keyTransparencyDataJ\x04\b\b\x10\t\"\x84\x03\n" + "\tRecipient\x12\x0e\n" + "\x02id\x18\x01 \x01(\x04R\x02id\x122\n" + "\acontact\x18\x02 \x01(\v2\x16.signal.backup.ContactH\x00R\acontact\x12,\n" + @@ -11466,8 +12174,7 @@ const file_backuppb_Backup_proto_rawDesc = "" + "\x04self\x18\x05 \x01(\v2\x13.signal.backup.SelfH\x00R\x04self\x12A\n" + "\freleaseNotes\x18\x06 \x01(\v2\x1b.signal.backup.ReleaseNotesH\x00R\freleaseNotes\x125\n" + "\bcallLink\x18\a \x01(\v2\x17.signal.backup.CallLinkH\x00R\bcallLinkB\r\n" + - "\vdestination\"\xcb\n" + - "\n" + + "\vdestination\"\x9a\v\n" + "\aContact\x12\x15\n" + "\x03aci\x18\x01 \x01(\fH\x01R\x03aci\x88\x01\x01\x12\x15\n" + "\x03pni\x18\x02 \x01(\fH\x02R\x03pni\x88\x01\x01\x12\x1f\n" + @@ -11496,7 +12203,9 @@ const file_backuppb_Backup_proto_rawDesc = "" + "\x0fsystemGivenName\x18\x12 \x01(\tR\x0fsystemGivenName\x12*\n" + "\x10systemFamilyName\x18\x13 \x01(\tR\x10systemFamilyName\x12&\n" + "\x0esystemNickname\x18\x14 \x01(\tR\x0esystemNickname\x12A\n" + - "\vavatarColor\x18\x15 \x01(\x0e2\x1a.signal.backup.AvatarColorH\tR\vavatarColor\x88\x01\x01\x1a\f\n" + + "\vavatarColor\x18\x15 \x01(\x0e2\x1a.signal.backup.AvatarColorH\tR\vavatarColor\x88\x01\x01\x125\n" + + "\x13keyTransparencyData\x18\x16 \x01(\fH\n" + + "R\x13keyTransparencyData\x88\x01\x01\x1a\f\n" + "\n" + "Registered\x1aE\n" + "\rNotRegistered\x124\n" + @@ -11524,7 +12233,8 @@ const file_backuppb_Backup_proto_rawDesc = "" + "\x11_profileGivenNameB\x14\n" + "\x12_profileFamilyNameB\x0e\n" + "\f_identityKeyB\x0e\n" + - "\f_avatarColor\"\x8f\x12\n" + + "\f_avatarColorB\x16\n" + + "\x14_keyTransparencyData\"\x8f\x12\n" + "\x05Group\x12\x1c\n" + "\tmasterKey\x18\x01 \x01(\fR\tmasterKey\x12 \n" + "\vwhitelisted\x18\x02 \x01(\bR\vwhitelisted\x12\x1c\n" + @@ -11644,7 +12354,7 @@ const file_backuppb_Backup_proto_rawDesc = "" + "\tONLY_WITH\x10\x01\x12\x0e\n" + "\n" + "ALL_EXCEPT\x10\x02\x12\a\n" + - "\x03ALL\x10\x03\"\xf3\f\n" + + "\x03ALL\x10\x03\"\xe5\x0e\n" + "\bChatItem\x12\x16\n" + "\x06chatId\x18\x01 \x01(\x04R\x06chatId\x12\x1a\n" + "\bauthorId\x18\x02 \x01(\x04R\bauthorId\x12\x1a\n" + @@ -11666,7 +12376,10 @@ const file_backuppb_Backup_proto_rawDesc = "" + "\tgiftBadge\x18\x11 \x01(\v2\x18.signal.backup.GiftBadgeH\x01R\tgiftBadge\x12J\n" + "\x0fviewOnceMessage\x18\x12 \x01(\v2\x1e.signal.backup.ViewOnceMessageH\x01R\x0fviewOnceMessage\x12b\n" + "\x17directStoryReplyMessage\x18\x13 \x01(\v2&.signal.backup.DirectStoryReplyMessageH\x01R\x17directStoryReplyMessage\x12)\n" + - "\x04poll\x18\x14 \x01(\v2\x13.signal.backup.PollH\x01R\x04poll\x1a\xb4\x01\n" + + "\x04poll\x18\x14 \x01(\v2\x13.signal.backup.PollH\x01R\x04poll\x12B\n" + + "\n" + + "pinDetails\x18\x15 \x01(\v2\".signal.backup.ChatItem.PinDetailsR\n" + + "pinDetails\x1a\xb4\x01\n" + "\x16IncomingMessageDetails\x12\"\n" + "\fdateReceived\x18\x01 \x01(\x04R\fdateReceived\x12+\n" + "\x0edateServerSent\x18\x02 \x01(\x04H\x00R\x0edateServerSent\x88\x01\x01\x12\x12\n" + @@ -11678,7 +12391,13 @@ const file_backuppb_Backup_proto_rawDesc = "" + "sendStatus\x18\x01 \x03(\v2\x19.signal.backup.SendStatusR\n" + "sendStatus\x12\"\n" + "\fdateReceived\x18\x02 \x01(\x04R\fdateReceived\x1a\x1d\n" + - "\x1bDirectionlessMessageDetailsB\x14\n" + + "\x1bDirectionlessMessageDetails\x1a\xab\x01\n" + + "\n" + + "PinDetails\x12,\n" + + "\x11pinnedAtTimestamp\x18\x01 \x01(\x04R\x11pinnedAtTimestamp\x126\n" + + "\x15pinExpiresAtTimestamp\x18\x02 \x01(\x04H\x00R\x15pinExpiresAtTimestamp\x12*\n" + + "\x0fpinNeverExpires\x18\x03 \x01(\bH\x00R\x0fpinNeverExpiresB\v\n" + + "\tpinExpiryB\x14\n" + "\x12directionalDetailsB\x06\n" + "\x04itemB\x12\n" + "\x10_expireStartDateB\x0e\n" + @@ -11974,19 +12693,20 @@ const file_backuppb_Backup_proto_rawDesc = "" + "\x05emoji\x18\x01 \x01(\tR\x05emoji\x12\x1a\n" + "\bauthorId\x18\x02 \x01(\x04R\bauthorId\x12$\n" + "\rsentTimestamp\x18\x03 \x01(\x04R\rsentTimestamp\x12\x1c\n" + - "\tsortOrder\x18\x04 \x01(\x04R\tsortOrder\"\xc8\x02\n" + + "\tsortOrder\x18\x04 \x01(\x04R\tsortOrder\"\xff\x02\n" + "\x04Poll\x12\x1a\n" + "\bquestion\x18\x01 \x01(\tR\bquestion\x12$\n" + "\rallowMultiple\x18\x02 \x01(\bR\rallowMultiple\x128\n" + "\aoptions\x18\x03 \x03(\v2\x1e.signal.backup.Poll.PollOptionR\aoptions\x12\x1a\n" + - "\bhasEnded\x18\x04 \x01(\bR\bhasEnded\x1a\xa7\x01\n" + + "\bhasEnded\x18\x04 \x01(\bR\bhasEnded\x125\n" + + "\treactions\x18\x05 \x03(\v2\x17.signal.backup.ReactionR\treactions\x1a\xa7\x01\n" + "\n" + "PollOption\x12\x16\n" + "\x06option\x18\x01 \x01(\tR\x06option\x12=\n" + "\x05votes\x18\x02 \x03(\v2'.signal.backup.Poll.PollOption.PollVoteR\x05votes\x1aB\n" + "\bPollVote\x12\x18\n" + "\avoterId\x18\x01 \x01(\x04R\avoterId\x12\x1c\n" + - "\tvoteCount\x18\x02 \x01(\rR\tvoteCount\"\xb4\x06\n" + + "\tvoteCount\x18\x02 \x01(\rR\tvoteCount\"\xf7\x06\n" + "\x11ChatUpdateMessage\x12E\n" + "\fsimpleUpdate\x18\x01 \x01(\v2\x1f.signal.backup.SimpleChatUpdateH\x00R\fsimpleUpdate\x12H\n" + "\vgroupChange\x18\x02 \x01(\v2$.signal.backup.GroupChangeChatUpdateH\x00R\vgroupChange\x12`\n" + @@ -11998,7 +12718,10 @@ const file_backuppb_Backup_proto_rawDesc = "" + "\tgroupCall\x18\b \x01(\v2\x18.signal.backup.GroupCallH\x00R\tgroupCall\x12]\n" + "\x14learnedProfileChange\x18\t \x01(\v2'.signal.backup.LearnedProfileChatUpdateH\x00R\x14learnedProfileChange\x12J\n" + "\rpollTerminate\x18\n" + - " \x01(\v2\".signal.backup.PollTerminateUpdateH\x00R\rpollTerminateB\b\n" + + " \x01(\v2\".signal.backup.PollTerminateUpdateH\x00R\rpollTerminate\x12A\n" + + "\n" + + "pinMessage\x18\v \x01(\v2\x1f.signal.backup.PinMessageUpdateH\x00R\n" + + "pinMessageB\b\n" + "\x06update\"\x9d\x04\n" + "\x0eIndividualCall\x12\x1b\n" + "\x06callId\x18\x01 \x01(\x04H\x00R\x06callId\x88\x01\x01\x126\n" + @@ -12306,7 +13029,10 @@ const file_backuppb_Backup_proto_rawDesc = "" + "\v_updaterAci\"c\n" + "\x13PollTerminateUpdate\x120\n" + "\x13targetSentTimestamp\x18\x01 \x01(\x04R\x13targetSentTimestamp\x12\x1a\n" + - "\bquestion\x18\x02 \x01(\tR\bquestion\"?\n" + + "\bquestion\x18\x02 \x01(\tR\bquestion\"`\n" + + "\x10PinMessageUpdate\x120\n" + + "\x13targetSentTimestamp\x18\x01 \x01(\x04R\x13targetSentTimestamp\x12\x1a\n" + + "\bauthorId\x18\x02 \x01(\x04R\bauthorId\"?\n" + "\vStickerPack\x12\x16\n" + "\x06packId\x18\x01 \x01(\fR\x06packId\x12\x18\n" + "\apackKey\x18\x02 \x01(\fR\apackKey\"\x80\r\n" + @@ -12465,348 +13191,370 @@ func file_backuppb_Backup_proto_rawDescGZIP() []byte { return file_backuppb_Backup_proto_rawDescData } -var file_backuppb_Backup_proto_enumTypes = make([]protoimpl.EnumInfo, 31) -var file_backuppb_Backup_proto_msgTypes = make([]protoimpl.MessageInfo, 124) +var file_backuppb_Backup_proto_enumTypes = make([]protoimpl.EnumInfo, 36) +var file_backuppb_Backup_proto_msgTypes = make([]protoimpl.MessageInfo, 128) var file_backuppb_Backup_proto_goTypes = []any{ - (AvatarColor)(0), // 0: signal.backup.AvatarColor - (GroupV2AccessLevel)(0), // 1: signal.backup.GroupV2AccessLevel - (AccountData_PhoneNumberSharingMode)(0), // 2: signal.backup.AccountData.PhoneNumberSharingMode - (AccountData_UsernameLink_Color)(0), // 3: signal.backup.AccountData.UsernameLink.Color - (Contact_IdentityState)(0), // 4: signal.backup.Contact.IdentityState - (Contact_Visibility)(0), // 5: signal.backup.Contact.Visibility - (Group_StorySendMode)(0), // 6: signal.backup.Group.StorySendMode - (Group_Member_Role)(0), // 7: signal.backup.Group.Member.Role - (Group_AccessControl_AccessRequired)(0), // 8: signal.backup.Group.AccessControl.AccessRequired - (CallLink_Restrictions)(0), // 9: signal.backup.CallLink.Restrictions - (AdHocCall_State)(0), // 10: signal.backup.AdHocCall.State - (DistributionList_PrivacyMode)(0), // 11: signal.backup.DistributionList.PrivacyMode - (SendStatus_Failed_FailureReason)(0), // 12: signal.backup.SendStatus.Failed.FailureReason - (PaymentNotification_TransactionDetails_FailedTransaction_FailureReason)(0), // 13: signal.backup.PaymentNotification.TransactionDetails.FailedTransaction.FailureReason - (PaymentNotification_TransactionDetails_Transaction_Status)(0), // 14: signal.backup.PaymentNotification.TransactionDetails.Transaction.Status - (GiftBadge_State)(0), // 15: signal.backup.GiftBadge.State - (ContactAttachment_Phone_Type)(0), // 16: signal.backup.ContactAttachment.Phone.Type - (ContactAttachment_Email_Type)(0), // 17: signal.backup.ContactAttachment.Email.Type - (ContactAttachment_PostalAddress_Type)(0), // 18: signal.backup.ContactAttachment.PostalAddress.Type - (MessageAttachment_Flag)(0), // 19: signal.backup.MessageAttachment.Flag - (Quote_Type)(0), // 20: signal.backup.Quote.Type - (BodyRange_Style)(0), // 21: signal.backup.BodyRange.Style - (IndividualCall_Type)(0), // 22: signal.backup.IndividualCall.Type - (IndividualCall_Direction)(0), // 23: signal.backup.IndividualCall.Direction - (IndividualCall_State)(0), // 24: signal.backup.IndividualCall.State - (GroupCall_State)(0), // 25: signal.backup.GroupCall.State - (SimpleChatUpdate_Type)(0), // 26: signal.backup.SimpleChatUpdate.Type - (ChatStyle_WallpaperPreset)(0), // 27: signal.backup.ChatStyle.WallpaperPreset - (ChatStyle_BubbleColorPreset)(0), // 28: signal.backup.ChatStyle.BubbleColorPreset - (NotificationProfile_DayOfWeek)(0), // 29: signal.backup.NotificationProfile.DayOfWeek - (ChatFolder_FolderType)(0), // 30: signal.backup.ChatFolder.FolderType - (*BackupInfo)(nil), // 31: signal.backup.BackupInfo - (*Frame)(nil), // 32: signal.backup.Frame - (*AccountData)(nil), // 33: signal.backup.AccountData - (*Recipient)(nil), // 34: signal.backup.Recipient - (*Contact)(nil), // 35: signal.backup.Contact - (*Group)(nil), // 36: signal.backup.Group - (*Self)(nil), // 37: signal.backup.Self - (*ReleaseNotes)(nil), // 38: signal.backup.ReleaseNotes - (*Chat)(nil), // 39: signal.backup.Chat - (*CallLink)(nil), // 40: signal.backup.CallLink - (*AdHocCall)(nil), // 41: signal.backup.AdHocCall - (*DistributionListItem)(nil), // 42: signal.backup.DistributionListItem - (*DistributionList)(nil), // 43: signal.backup.DistributionList - (*ChatItem)(nil), // 44: signal.backup.ChatItem - (*SendStatus)(nil), // 45: signal.backup.SendStatus - (*Text)(nil), // 46: signal.backup.Text - (*StandardMessage)(nil), // 47: signal.backup.StandardMessage - (*ContactMessage)(nil), // 48: signal.backup.ContactMessage - (*DirectStoryReplyMessage)(nil), // 49: signal.backup.DirectStoryReplyMessage - (*PaymentNotification)(nil), // 50: signal.backup.PaymentNotification - (*GiftBadge)(nil), // 51: signal.backup.GiftBadge - (*ViewOnceMessage)(nil), // 52: signal.backup.ViewOnceMessage - (*ContactAttachment)(nil), // 53: signal.backup.ContactAttachment - (*StickerMessage)(nil), // 54: signal.backup.StickerMessage - (*RemoteDeletedMessage)(nil), // 55: signal.backup.RemoteDeletedMessage - (*Sticker)(nil), // 56: signal.backup.Sticker - (*LinkPreview)(nil), // 57: signal.backup.LinkPreview - (*MessageAttachment)(nil), // 58: signal.backup.MessageAttachment - (*FilePointer)(nil), // 59: signal.backup.FilePointer - (*Quote)(nil), // 60: signal.backup.Quote - (*BodyRange)(nil), // 61: signal.backup.BodyRange - (*Reaction)(nil), // 62: signal.backup.Reaction - (*Poll)(nil), // 63: signal.backup.Poll - (*ChatUpdateMessage)(nil), // 64: signal.backup.ChatUpdateMessage - (*IndividualCall)(nil), // 65: signal.backup.IndividualCall - (*GroupCall)(nil), // 66: signal.backup.GroupCall - (*SimpleChatUpdate)(nil), // 67: signal.backup.SimpleChatUpdate - (*ExpirationTimerChatUpdate)(nil), // 68: signal.backup.ExpirationTimerChatUpdate - (*ProfileChangeChatUpdate)(nil), // 69: signal.backup.ProfileChangeChatUpdate - (*LearnedProfileChatUpdate)(nil), // 70: signal.backup.LearnedProfileChatUpdate - (*ThreadMergeChatUpdate)(nil), // 71: signal.backup.ThreadMergeChatUpdate - (*SessionSwitchoverChatUpdate)(nil), // 72: signal.backup.SessionSwitchoverChatUpdate - (*GroupChangeChatUpdate)(nil), // 73: signal.backup.GroupChangeChatUpdate - (*GenericGroupUpdate)(nil), // 74: signal.backup.GenericGroupUpdate - (*GroupCreationUpdate)(nil), // 75: signal.backup.GroupCreationUpdate - (*GroupNameUpdate)(nil), // 76: signal.backup.GroupNameUpdate - (*GroupAvatarUpdate)(nil), // 77: signal.backup.GroupAvatarUpdate - (*GroupDescriptionUpdate)(nil), // 78: signal.backup.GroupDescriptionUpdate - (*GroupMembershipAccessLevelChangeUpdate)(nil), // 79: signal.backup.GroupMembershipAccessLevelChangeUpdate - (*GroupAttributesAccessLevelChangeUpdate)(nil), // 80: signal.backup.GroupAttributesAccessLevelChangeUpdate - (*GroupAnnouncementOnlyChangeUpdate)(nil), // 81: signal.backup.GroupAnnouncementOnlyChangeUpdate - (*GroupAdminStatusUpdate)(nil), // 82: signal.backup.GroupAdminStatusUpdate - (*GroupMemberLeftUpdate)(nil), // 83: signal.backup.GroupMemberLeftUpdate - (*GroupMemberRemovedUpdate)(nil), // 84: signal.backup.GroupMemberRemovedUpdate - (*SelfInvitedToGroupUpdate)(nil), // 85: signal.backup.SelfInvitedToGroupUpdate - (*SelfInvitedOtherUserToGroupUpdate)(nil), // 86: signal.backup.SelfInvitedOtherUserToGroupUpdate - (*GroupUnknownInviteeUpdate)(nil), // 87: signal.backup.GroupUnknownInviteeUpdate - (*GroupInvitationAcceptedUpdate)(nil), // 88: signal.backup.GroupInvitationAcceptedUpdate - (*GroupInvitationDeclinedUpdate)(nil), // 89: signal.backup.GroupInvitationDeclinedUpdate - (*GroupMemberJoinedUpdate)(nil), // 90: signal.backup.GroupMemberJoinedUpdate - (*GroupMemberAddedUpdate)(nil), // 91: signal.backup.GroupMemberAddedUpdate - (*GroupSelfInvitationRevokedUpdate)(nil), // 92: signal.backup.GroupSelfInvitationRevokedUpdate - (*GroupInvitationRevokedUpdate)(nil), // 93: signal.backup.GroupInvitationRevokedUpdate - (*GroupJoinRequestUpdate)(nil), // 94: signal.backup.GroupJoinRequestUpdate - (*GroupJoinRequestApprovalUpdate)(nil), // 95: signal.backup.GroupJoinRequestApprovalUpdate - (*GroupJoinRequestCanceledUpdate)(nil), // 96: signal.backup.GroupJoinRequestCanceledUpdate - (*GroupSequenceOfRequestsAndCancelsUpdate)(nil), // 97: signal.backup.GroupSequenceOfRequestsAndCancelsUpdate - (*GroupInviteLinkResetUpdate)(nil), // 98: signal.backup.GroupInviteLinkResetUpdate - (*GroupInviteLinkEnabledUpdate)(nil), // 99: signal.backup.GroupInviteLinkEnabledUpdate - (*GroupInviteLinkAdminApprovalUpdate)(nil), // 100: signal.backup.GroupInviteLinkAdminApprovalUpdate - (*GroupInviteLinkDisabledUpdate)(nil), // 101: signal.backup.GroupInviteLinkDisabledUpdate - (*GroupMemberJoinedByLinkUpdate)(nil), // 102: signal.backup.GroupMemberJoinedByLinkUpdate - (*GroupV2MigrationUpdate)(nil), // 103: signal.backup.GroupV2MigrationUpdate - (*GroupV2MigrationSelfInvitedUpdate)(nil), // 104: signal.backup.GroupV2MigrationSelfInvitedUpdate - (*GroupV2MigrationInvitedMembersUpdate)(nil), // 105: signal.backup.GroupV2MigrationInvitedMembersUpdate - (*GroupV2MigrationDroppedMembersUpdate)(nil), // 106: signal.backup.GroupV2MigrationDroppedMembersUpdate - (*GroupExpirationTimerUpdate)(nil), // 107: signal.backup.GroupExpirationTimerUpdate - (*PollTerminateUpdate)(nil), // 108: signal.backup.PollTerminateUpdate - (*StickerPack)(nil), // 109: signal.backup.StickerPack - (*ChatStyle)(nil), // 110: signal.backup.ChatStyle - (*NotificationProfile)(nil), // 111: signal.backup.NotificationProfile - (*ChatFolder)(nil), // 112: signal.backup.ChatFolder - (*AccountData_UsernameLink)(nil), // 113: signal.backup.AccountData.UsernameLink - (*AccountData_AccountSettings)(nil), // 114: signal.backup.AccountData.AccountSettings - (*AccountData_SubscriberData)(nil), // 115: signal.backup.AccountData.SubscriberData - (*AccountData_IAPSubscriberData)(nil), // 116: signal.backup.AccountData.IAPSubscriberData - (*Contact_Registered)(nil), // 117: signal.backup.Contact.Registered - (*Contact_NotRegistered)(nil), // 118: signal.backup.Contact.NotRegistered - (*Contact_Name)(nil), // 119: signal.backup.Contact.Name - (*Group_GroupSnapshot)(nil), // 120: signal.backup.Group.GroupSnapshot - (*Group_GroupAttributeBlob)(nil), // 121: signal.backup.Group.GroupAttributeBlob - (*Group_Member)(nil), // 122: signal.backup.Group.Member - (*Group_MemberPendingProfileKey)(nil), // 123: signal.backup.Group.MemberPendingProfileKey - (*Group_MemberPendingAdminApproval)(nil), // 124: signal.backup.Group.MemberPendingAdminApproval - (*Group_MemberBanned)(nil), // 125: signal.backup.Group.MemberBanned - (*Group_AccessControl)(nil), // 126: signal.backup.Group.AccessControl - (*ChatItem_IncomingMessageDetails)(nil), // 127: signal.backup.ChatItem.IncomingMessageDetails - (*ChatItem_OutgoingMessageDetails)(nil), // 128: signal.backup.ChatItem.OutgoingMessageDetails - (*ChatItem_DirectionlessMessageDetails)(nil), // 129: signal.backup.ChatItem.DirectionlessMessageDetails - (*SendStatus_Pending)(nil), // 130: signal.backup.SendStatus.Pending - (*SendStatus_Sent)(nil), // 131: signal.backup.SendStatus.Sent - (*SendStatus_Delivered)(nil), // 132: signal.backup.SendStatus.Delivered - (*SendStatus_Read)(nil), // 133: signal.backup.SendStatus.Read - (*SendStatus_Viewed)(nil), // 134: signal.backup.SendStatus.Viewed - (*SendStatus_Skipped)(nil), // 135: signal.backup.SendStatus.Skipped - (*SendStatus_Failed)(nil), // 136: signal.backup.SendStatus.Failed - (*DirectStoryReplyMessage_TextReply)(nil), // 137: signal.backup.DirectStoryReplyMessage.TextReply - (*PaymentNotification_TransactionDetails)(nil), // 138: signal.backup.PaymentNotification.TransactionDetails - (*PaymentNotification_TransactionDetails_MobileCoinTxoIdentification)(nil), // 139: signal.backup.PaymentNotification.TransactionDetails.MobileCoinTxoIdentification - (*PaymentNotification_TransactionDetails_FailedTransaction)(nil), // 140: signal.backup.PaymentNotification.TransactionDetails.FailedTransaction - (*PaymentNotification_TransactionDetails_Transaction)(nil), // 141: signal.backup.PaymentNotification.TransactionDetails.Transaction - (*ContactAttachment_Name)(nil), // 142: signal.backup.ContactAttachment.Name - (*ContactAttachment_Phone)(nil), // 143: signal.backup.ContactAttachment.Phone - (*ContactAttachment_Email)(nil), // 144: signal.backup.ContactAttachment.Email - (*ContactAttachment_PostalAddress)(nil), // 145: signal.backup.ContactAttachment.PostalAddress - (*FilePointer_LocatorInfo)(nil), // 146: signal.backup.FilePointer.LocatorInfo - (*Quote_QuotedAttachment)(nil), // 147: signal.backup.Quote.QuotedAttachment - (*Poll_PollOption)(nil), // 148: signal.backup.Poll.PollOption - (*Poll_PollOption_PollVote)(nil), // 149: signal.backup.Poll.PollOption.PollVote - (*GroupChangeChatUpdate_Update)(nil), // 150: signal.backup.GroupChangeChatUpdate.Update - (*GroupInvitationRevokedUpdate_Invitee)(nil), // 151: signal.backup.GroupInvitationRevokedUpdate.Invitee - (*ChatStyle_Gradient)(nil), // 152: signal.backup.ChatStyle.Gradient - (*ChatStyle_CustomChatColor)(nil), // 153: signal.backup.ChatStyle.CustomChatColor - (*ChatStyle_AutomaticBubbleColor)(nil), // 154: signal.backup.ChatStyle.AutomaticBubbleColor + (AvatarColor)(0), // 0: signal.backup.AvatarColor + (GroupV2AccessLevel)(0), // 1: signal.backup.GroupV2AccessLevel + (AccountData_PhoneNumberSharingMode)(0), // 2: signal.backup.AccountData.PhoneNumberSharingMode + (AccountData_SentMediaQuality)(0), // 3: signal.backup.AccountData.SentMediaQuality + (AccountData_AppTheme)(0), // 4: signal.backup.AccountData.AppTheme + (AccountData_CallsUseLessDataSetting)(0), // 5: signal.backup.AccountData.CallsUseLessDataSetting + (AccountData_UsernameLink_Color)(0), // 6: signal.backup.AccountData.UsernameLink.Color + (AccountData_AutoDownloadSettings_AutoDownloadOption)(0), // 7: signal.backup.AccountData.AutoDownloadSettings.AutoDownloadOption + (AccountData_AndroidSpecificSettings_NavigationBarSize)(0), // 8: signal.backup.AccountData.AndroidSpecificSettings.NavigationBarSize + (Contact_IdentityState)(0), // 9: signal.backup.Contact.IdentityState + (Contact_Visibility)(0), // 10: signal.backup.Contact.Visibility + (Group_StorySendMode)(0), // 11: signal.backup.Group.StorySendMode + (Group_Member_Role)(0), // 12: signal.backup.Group.Member.Role + (Group_AccessControl_AccessRequired)(0), // 13: signal.backup.Group.AccessControl.AccessRequired + (CallLink_Restrictions)(0), // 14: signal.backup.CallLink.Restrictions + (AdHocCall_State)(0), // 15: signal.backup.AdHocCall.State + (DistributionList_PrivacyMode)(0), // 16: signal.backup.DistributionList.PrivacyMode + (SendStatus_Failed_FailureReason)(0), // 17: signal.backup.SendStatus.Failed.FailureReason + (PaymentNotification_TransactionDetails_FailedTransaction_FailureReason)(0), // 18: signal.backup.PaymentNotification.TransactionDetails.FailedTransaction.FailureReason + (PaymentNotification_TransactionDetails_Transaction_Status)(0), // 19: signal.backup.PaymentNotification.TransactionDetails.Transaction.Status + (GiftBadge_State)(0), // 20: signal.backup.GiftBadge.State + (ContactAttachment_Phone_Type)(0), // 21: signal.backup.ContactAttachment.Phone.Type + (ContactAttachment_Email_Type)(0), // 22: signal.backup.ContactAttachment.Email.Type + (ContactAttachment_PostalAddress_Type)(0), // 23: signal.backup.ContactAttachment.PostalAddress.Type + (MessageAttachment_Flag)(0), // 24: signal.backup.MessageAttachment.Flag + (Quote_Type)(0), // 25: signal.backup.Quote.Type + (BodyRange_Style)(0), // 26: signal.backup.BodyRange.Style + (IndividualCall_Type)(0), // 27: signal.backup.IndividualCall.Type + (IndividualCall_Direction)(0), // 28: signal.backup.IndividualCall.Direction + (IndividualCall_State)(0), // 29: signal.backup.IndividualCall.State + (GroupCall_State)(0), // 30: signal.backup.GroupCall.State + (SimpleChatUpdate_Type)(0), // 31: signal.backup.SimpleChatUpdate.Type + (ChatStyle_WallpaperPreset)(0), // 32: signal.backup.ChatStyle.WallpaperPreset + (ChatStyle_BubbleColorPreset)(0), // 33: signal.backup.ChatStyle.BubbleColorPreset + (NotificationProfile_DayOfWeek)(0), // 34: signal.backup.NotificationProfile.DayOfWeek + (ChatFolder_FolderType)(0), // 35: signal.backup.ChatFolder.FolderType + (*BackupInfo)(nil), // 36: signal.backup.BackupInfo + (*Frame)(nil), // 37: signal.backup.Frame + (*AccountData)(nil), // 38: signal.backup.AccountData + (*Recipient)(nil), // 39: signal.backup.Recipient + (*Contact)(nil), // 40: signal.backup.Contact + (*Group)(nil), // 41: signal.backup.Group + (*Self)(nil), // 42: signal.backup.Self + (*ReleaseNotes)(nil), // 43: signal.backup.ReleaseNotes + (*Chat)(nil), // 44: signal.backup.Chat + (*CallLink)(nil), // 45: signal.backup.CallLink + (*AdHocCall)(nil), // 46: signal.backup.AdHocCall + (*DistributionListItem)(nil), // 47: signal.backup.DistributionListItem + (*DistributionList)(nil), // 48: signal.backup.DistributionList + (*ChatItem)(nil), // 49: signal.backup.ChatItem + (*SendStatus)(nil), // 50: signal.backup.SendStatus + (*Text)(nil), // 51: signal.backup.Text + (*StandardMessage)(nil), // 52: signal.backup.StandardMessage + (*ContactMessage)(nil), // 53: signal.backup.ContactMessage + (*DirectStoryReplyMessage)(nil), // 54: signal.backup.DirectStoryReplyMessage + (*PaymentNotification)(nil), // 55: signal.backup.PaymentNotification + (*GiftBadge)(nil), // 56: signal.backup.GiftBadge + (*ViewOnceMessage)(nil), // 57: signal.backup.ViewOnceMessage + (*ContactAttachment)(nil), // 58: signal.backup.ContactAttachment + (*StickerMessage)(nil), // 59: signal.backup.StickerMessage + (*RemoteDeletedMessage)(nil), // 60: signal.backup.RemoteDeletedMessage + (*Sticker)(nil), // 61: signal.backup.Sticker + (*LinkPreview)(nil), // 62: signal.backup.LinkPreview + (*MessageAttachment)(nil), // 63: signal.backup.MessageAttachment + (*FilePointer)(nil), // 64: signal.backup.FilePointer + (*Quote)(nil), // 65: signal.backup.Quote + (*BodyRange)(nil), // 66: signal.backup.BodyRange + (*Reaction)(nil), // 67: signal.backup.Reaction + (*Poll)(nil), // 68: signal.backup.Poll + (*ChatUpdateMessage)(nil), // 69: signal.backup.ChatUpdateMessage + (*IndividualCall)(nil), // 70: signal.backup.IndividualCall + (*GroupCall)(nil), // 71: signal.backup.GroupCall + (*SimpleChatUpdate)(nil), // 72: signal.backup.SimpleChatUpdate + (*ExpirationTimerChatUpdate)(nil), // 73: signal.backup.ExpirationTimerChatUpdate + (*ProfileChangeChatUpdate)(nil), // 74: signal.backup.ProfileChangeChatUpdate + (*LearnedProfileChatUpdate)(nil), // 75: signal.backup.LearnedProfileChatUpdate + (*ThreadMergeChatUpdate)(nil), // 76: signal.backup.ThreadMergeChatUpdate + (*SessionSwitchoverChatUpdate)(nil), // 77: signal.backup.SessionSwitchoverChatUpdate + (*GroupChangeChatUpdate)(nil), // 78: signal.backup.GroupChangeChatUpdate + (*GenericGroupUpdate)(nil), // 79: signal.backup.GenericGroupUpdate + (*GroupCreationUpdate)(nil), // 80: signal.backup.GroupCreationUpdate + (*GroupNameUpdate)(nil), // 81: signal.backup.GroupNameUpdate + (*GroupAvatarUpdate)(nil), // 82: signal.backup.GroupAvatarUpdate + (*GroupDescriptionUpdate)(nil), // 83: signal.backup.GroupDescriptionUpdate + (*GroupMembershipAccessLevelChangeUpdate)(nil), // 84: signal.backup.GroupMembershipAccessLevelChangeUpdate + (*GroupAttributesAccessLevelChangeUpdate)(nil), // 85: signal.backup.GroupAttributesAccessLevelChangeUpdate + (*GroupAnnouncementOnlyChangeUpdate)(nil), // 86: signal.backup.GroupAnnouncementOnlyChangeUpdate + (*GroupAdminStatusUpdate)(nil), // 87: signal.backup.GroupAdminStatusUpdate + (*GroupMemberLeftUpdate)(nil), // 88: signal.backup.GroupMemberLeftUpdate + (*GroupMemberRemovedUpdate)(nil), // 89: signal.backup.GroupMemberRemovedUpdate + (*SelfInvitedToGroupUpdate)(nil), // 90: signal.backup.SelfInvitedToGroupUpdate + (*SelfInvitedOtherUserToGroupUpdate)(nil), // 91: signal.backup.SelfInvitedOtherUserToGroupUpdate + (*GroupUnknownInviteeUpdate)(nil), // 92: signal.backup.GroupUnknownInviteeUpdate + (*GroupInvitationAcceptedUpdate)(nil), // 93: signal.backup.GroupInvitationAcceptedUpdate + (*GroupInvitationDeclinedUpdate)(nil), // 94: signal.backup.GroupInvitationDeclinedUpdate + (*GroupMemberJoinedUpdate)(nil), // 95: signal.backup.GroupMemberJoinedUpdate + (*GroupMemberAddedUpdate)(nil), // 96: signal.backup.GroupMemberAddedUpdate + (*GroupSelfInvitationRevokedUpdate)(nil), // 97: signal.backup.GroupSelfInvitationRevokedUpdate + (*GroupInvitationRevokedUpdate)(nil), // 98: signal.backup.GroupInvitationRevokedUpdate + (*GroupJoinRequestUpdate)(nil), // 99: signal.backup.GroupJoinRequestUpdate + (*GroupJoinRequestApprovalUpdate)(nil), // 100: signal.backup.GroupJoinRequestApprovalUpdate + (*GroupJoinRequestCanceledUpdate)(nil), // 101: signal.backup.GroupJoinRequestCanceledUpdate + (*GroupSequenceOfRequestsAndCancelsUpdate)(nil), // 102: signal.backup.GroupSequenceOfRequestsAndCancelsUpdate + (*GroupInviteLinkResetUpdate)(nil), // 103: signal.backup.GroupInviteLinkResetUpdate + (*GroupInviteLinkEnabledUpdate)(nil), // 104: signal.backup.GroupInviteLinkEnabledUpdate + (*GroupInviteLinkAdminApprovalUpdate)(nil), // 105: signal.backup.GroupInviteLinkAdminApprovalUpdate + (*GroupInviteLinkDisabledUpdate)(nil), // 106: signal.backup.GroupInviteLinkDisabledUpdate + (*GroupMemberJoinedByLinkUpdate)(nil), // 107: signal.backup.GroupMemberJoinedByLinkUpdate + (*GroupV2MigrationUpdate)(nil), // 108: signal.backup.GroupV2MigrationUpdate + (*GroupV2MigrationSelfInvitedUpdate)(nil), // 109: signal.backup.GroupV2MigrationSelfInvitedUpdate + (*GroupV2MigrationInvitedMembersUpdate)(nil), // 110: signal.backup.GroupV2MigrationInvitedMembersUpdate + (*GroupV2MigrationDroppedMembersUpdate)(nil), // 111: signal.backup.GroupV2MigrationDroppedMembersUpdate + (*GroupExpirationTimerUpdate)(nil), // 112: signal.backup.GroupExpirationTimerUpdate + (*PollTerminateUpdate)(nil), // 113: signal.backup.PollTerminateUpdate + (*PinMessageUpdate)(nil), // 114: signal.backup.PinMessageUpdate + (*StickerPack)(nil), // 115: signal.backup.StickerPack + (*ChatStyle)(nil), // 116: signal.backup.ChatStyle + (*NotificationProfile)(nil), // 117: signal.backup.NotificationProfile + (*ChatFolder)(nil), // 118: signal.backup.ChatFolder + (*AccountData_UsernameLink)(nil), // 119: signal.backup.AccountData.UsernameLink + (*AccountData_AutoDownloadSettings)(nil), // 120: signal.backup.AccountData.AutoDownloadSettings + (*AccountData_AccountSettings)(nil), // 121: signal.backup.AccountData.AccountSettings + (*AccountData_SubscriberData)(nil), // 122: signal.backup.AccountData.SubscriberData + (*AccountData_IAPSubscriberData)(nil), // 123: signal.backup.AccountData.IAPSubscriberData + (*AccountData_AndroidSpecificSettings)(nil), // 124: signal.backup.AccountData.AndroidSpecificSettings + (*Contact_Registered)(nil), // 125: signal.backup.Contact.Registered + (*Contact_NotRegistered)(nil), // 126: signal.backup.Contact.NotRegistered + (*Contact_Name)(nil), // 127: signal.backup.Contact.Name + (*Group_GroupSnapshot)(nil), // 128: signal.backup.Group.GroupSnapshot + (*Group_GroupAttributeBlob)(nil), // 129: signal.backup.Group.GroupAttributeBlob + (*Group_Member)(nil), // 130: signal.backup.Group.Member + (*Group_MemberPendingProfileKey)(nil), // 131: signal.backup.Group.MemberPendingProfileKey + (*Group_MemberPendingAdminApproval)(nil), // 132: signal.backup.Group.MemberPendingAdminApproval + (*Group_MemberBanned)(nil), // 133: signal.backup.Group.MemberBanned + (*Group_AccessControl)(nil), // 134: signal.backup.Group.AccessControl + (*ChatItem_IncomingMessageDetails)(nil), // 135: signal.backup.ChatItem.IncomingMessageDetails + (*ChatItem_OutgoingMessageDetails)(nil), // 136: signal.backup.ChatItem.OutgoingMessageDetails + (*ChatItem_DirectionlessMessageDetails)(nil), // 137: signal.backup.ChatItem.DirectionlessMessageDetails + (*ChatItem_PinDetails)(nil), // 138: signal.backup.ChatItem.PinDetails + (*SendStatus_Pending)(nil), // 139: signal.backup.SendStatus.Pending + (*SendStatus_Sent)(nil), // 140: signal.backup.SendStatus.Sent + (*SendStatus_Delivered)(nil), // 141: signal.backup.SendStatus.Delivered + (*SendStatus_Read)(nil), // 142: signal.backup.SendStatus.Read + (*SendStatus_Viewed)(nil), // 143: signal.backup.SendStatus.Viewed + (*SendStatus_Skipped)(nil), // 144: signal.backup.SendStatus.Skipped + (*SendStatus_Failed)(nil), // 145: signal.backup.SendStatus.Failed + (*DirectStoryReplyMessage_TextReply)(nil), // 146: signal.backup.DirectStoryReplyMessage.TextReply + (*PaymentNotification_TransactionDetails)(nil), // 147: signal.backup.PaymentNotification.TransactionDetails + (*PaymentNotification_TransactionDetails_MobileCoinTxoIdentification)(nil), // 148: signal.backup.PaymentNotification.TransactionDetails.MobileCoinTxoIdentification + (*PaymentNotification_TransactionDetails_FailedTransaction)(nil), // 149: signal.backup.PaymentNotification.TransactionDetails.FailedTransaction + (*PaymentNotification_TransactionDetails_Transaction)(nil), // 150: signal.backup.PaymentNotification.TransactionDetails.Transaction + (*ContactAttachment_Name)(nil), // 151: signal.backup.ContactAttachment.Name + (*ContactAttachment_Phone)(nil), // 152: signal.backup.ContactAttachment.Phone + (*ContactAttachment_Email)(nil), // 153: signal.backup.ContactAttachment.Email + (*ContactAttachment_PostalAddress)(nil), // 154: signal.backup.ContactAttachment.PostalAddress + (*FilePointer_LocatorInfo)(nil), // 155: signal.backup.FilePointer.LocatorInfo + (*Quote_QuotedAttachment)(nil), // 156: signal.backup.Quote.QuotedAttachment + (*Poll_PollOption)(nil), // 157: signal.backup.Poll.PollOption + (*Poll_PollOption_PollVote)(nil), // 158: signal.backup.Poll.PollOption.PollVote + (*GroupChangeChatUpdate_Update)(nil), // 159: signal.backup.GroupChangeChatUpdate.Update + (*GroupInvitationRevokedUpdate_Invitee)(nil), // 160: signal.backup.GroupInvitationRevokedUpdate.Invitee + (*ChatStyle_Gradient)(nil), // 161: signal.backup.ChatStyle.Gradient + (*ChatStyle_CustomChatColor)(nil), // 162: signal.backup.ChatStyle.CustomChatColor + (*ChatStyle_AutomaticBubbleColor)(nil), // 163: signal.backup.ChatStyle.AutomaticBubbleColor } var file_backuppb_Backup_proto_depIdxs = []int32{ - 33, // 0: signal.backup.Frame.account:type_name -> signal.backup.AccountData - 34, // 1: signal.backup.Frame.recipient:type_name -> signal.backup.Recipient - 39, // 2: signal.backup.Frame.chat:type_name -> signal.backup.Chat - 44, // 3: signal.backup.Frame.chatItem:type_name -> signal.backup.ChatItem - 109, // 4: signal.backup.Frame.stickerPack:type_name -> signal.backup.StickerPack - 41, // 5: signal.backup.Frame.adHocCall:type_name -> signal.backup.AdHocCall - 111, // 6: signal.backup.Frame.notificationProfile:type_name -> signal.backup.NotificationProfile - 112, // 7: signal.backup.Frame.chatFolder:type_name -> signal.backup.ChatFolder - 113, // 8: signal.backup.AccountData.usernameLink:type_name -> signal.backup.AccountData.UsernameLink - 115, // 9: signal.backup.AccountData.donationSubscriberData:type_name -> signal.backup.AccountData.SubscriberData - 114, // 10: signal.backup.AccountData.accountSettings:type_name -> signal.backup.AccountData.AccountSettings - 116, // 11: signal.backup.AccountData.backupsSubscriberData:type_name -> signal.backup.AccountData.IAPSubscriberData - 35, // 12: signal.backup.Recipient.contact:type_name -> signal.backup.Contact - 36, // 13: signal.backup.Recipient.group:type_name -> signal.backup.Group - 42, // 14: signal.backup.Recipient.distributionList:type_name -> signal.backup.DistributionListItem - 37, // 15: signal.backup.Recipient.self:type_name -> signal.backup.Self - 38, // 16: signal.backup.Recipient.releaseNotes:type_name -> signal.backup.ReleaseNotes - 40, // 17: signal.backup.Recipient.callLink:type_name -> signal.backup.CallLink - 5, // 18: signal.backup.Contact.visibility:type_name -> signal.backup.Contact.Visibility - 117, // 19: signal.backup.Contact.registered:type_name -> signal.backup.Contact.Registered - 118, // 20: signal.backup.Contact.notRegistered:type_name -> signal.backup.Contact.NotRegistered - 4, // 21: signal.backup.Contact.identityState:type_name -> signal.backup.Contact.IdentityState - 119, // 22: signal.backup.Contact.nickname:type_name -> signal.backup.Contact.Name - 0, // 23: signal.backup.Contact.avatarColor:type_name -> signal.backup.AvatarColor - 6, // 24: signal.backup.Group.storySendMode:type_name -> signal.backup.Group.StorySendMode - 120, // 25: signal.backup.Group.snapshot:type_name -> signal.backup.Group.GroupSnapshot - 0, // 26: signal.backup.Group.avatarColor:type_name -> signal.backup.AvatarColor - 0, // 27: signal.backup.Self.avatarColor:type_name -> signal.backup.AvatarColor - 110, // 28: signal.backup.Chat.style:type_name -> signal.backup.ChatStyle - 9, // 29: signal.backup.CallLink.restrictions:type_name -> signal.backup.CallLink.Restrictions - 10, // 30: signal.backup.AdHocCall.state:type_name -> signal.backup.AdHocCall.State - 43, // 31: signal.backup.DistributionListItem.distributionList:type_name -> signal.backup.DistributionList - 11, // 32: signal.backup.DistributionList.privacyMode:type_name -> signal.backup.DistributionList.PrivacyMode - 44, // 33: signal.backup.ChatItem.revisions:type_name -> signal.backup.ChatItem - 127, // 34: signal.backup.ChatItem.incoming:type_name -> signal.backup.ChatItem.IncomingMessageDetails - 128, // 35: signal.backup.ChatItem.outgoing:type_name -> signal.backup.ChatItem.OutgoingMessageDetails - 129, // 36: signal.backup.ChatItem.directionless:type_name -> signal.backup.ChatItem.DirectionlessMessageDetails - 47, // 37: signal.backup.ChatItem.standardMessage:type_name -> signal.backup.StandardMessage - 48, // 38: signal.backup.ChatItem.contactMessage:type_name -> signal.backup.ContactMessage - 54, // 39: signal.backup.ChatItem.stickerMessage:type_name -> signal.backup.StickerMessage - 55, // 40: signal.backup.ChatItem.remoteDeletedMessage:type_name -> signal.backup.RemoteDeletedMessage - 64, // 41: signal.backup.ChatItem.updateMessage:type_name -> signal.backup.ChatUpdateMessage - 50, // 42: signal.backup.ChatItem.paymentNotification:type_name -> signal.backup.PaymentNotification - 51, // 43: signal.backup.ChatItem.giftBadge:type_name -> signal.backup.GiftBadge - 52, // 44: signal.backup.ChatItem.viewOnceMessage:type_name -> signal.backup.ViewOnceMessage - 49, // 45: signal.backup.ChatItem.directStoryReplyMessage:type_name -> signal.backup.DirectStoryReplyMessage - 63, // 46: signal.backup.ChatItem.poll:type_name -> signal.backup.Poll - 130, // 47: signal.backup.SendStatus.pending:type_name -> signal.backup.SendStatus.Pending - 131, // 48: signal.backup.SendStatus.sent:type_name -> signal.backup.SendStatus.Sent - 132, // 49: signal.backup.SendStatus.delivered:type_name -> signal.backup.SendStatus.Delivered - 133, // 50: signal.backup.SendStatus.read:type_name -> signal.backup.SendStatus.Read - 134, // 51: signal.backup.SendStatus.viewed:type_name -> signal.backup.SendStatus.Viewed - 135, // 52: signal.backup.SendStatus.skipped:type_name -> signal.backup.SendStatus.Skipped - 136, // 53: signal.backup.SendStatus.failed:type_name -> signal.backup.SendStatus.Failed - 61, // 54: signal.backup.Text.bodyRanges:type_name -> signal.backup.BodyRange - 60, // 55: signal.backup.StandardMessage.quote:type_name -> signal.backup.Quote - 46, // 56: signal.backup.StandardMessage.text:type_name -> signal.backup.Text - 58, // 57: signal.backup.StandardMessage.attachments:type_name -> signal.backup.MessageAttachment - 57, // 58: signal.backup.StandardMessage.linkPreview:type_name -> signal.backup.LinkPreview - 59, // 59: signal.backup.StandardMessage.longText:type_name -> signal.backup.FilePointer - 62, // 60: signal.backup.StandardMessage.reactions:type_name -> signal.backup.Reaction - 53, // 61: signal.backup.ContactMessage.contact:type_name -> signal.backup.ContactAttachment - 62, // 62: signal.backup.ContactMessage.reactions:type_name -> signal.backup.Reaction - 137, // 63: signal.backup.DirectStoryReplyMessage.textReply:type_name -> signal.backup.DirectStoryReplyMessage.TextReply - 62, // 64: signal.backup.DirectStoryReplyMessage.reactions:type_name -> signal.backup.Reaction - 138, // 65: signal.backup.PaymentNotification.transactionDetails:type_name -> signal.backup.PaymentNotification.TransactionDetails - 15, // 66: signal.backup.GiftBadge.state:type_name -> signal.backup.GiftBadge.State - 58, // 67: signal.backup.ViewOnceMessage.attachment:type_name -> signal.backup.MessageAttachment - 62, // 68: signal.backup.ViewOnceMessage.reactions:type_name -> signal.backup.Reaction - 142, // 69: signal.backup.ContactAttachment.name:type_name -> signal.backup.ContactAttachment.Name - 143, // 70: signal.backup.ContactAttachment.number:type_name -> signal.backup.ContactAttachment.Phone - 144, // 71: signal.backup.ContactAttachment.email:type_name -> signal.backup.ContactAttachment.Email - 145, // 72: signal.backup.ContactAttachment.address:type_name -> signal.backup.ContactAttachment.PostalAddress - 59, // 73: signal.backup.ContactAttachment.avatar:type_name -> signal.backup.FilePointer - 56, // 74: signal.backup.StickerMessage.sticker:type_name -> signal.backup.Sticker - 62, // 75: signal.backup.StickerMessage.reactions:type_name -> signal.backup.Reaction - 59, // 76: signal.backup.Sticker.data:type_name -> signal.backup.FilePointer - 59, // 77: signal.backup.LinkPreview.image:type_name -> signal.backup.FilePointer - 59, // 78: signal.backup.MessageAttachment.pointer:type_name -> signal.backup.FilePointer - 19, // 79: signal.backup.MessageAttachment.flag:type_name -> signal.backup.MessageAttachment.Flag - 146, // 80: signal.backup.FilePointer.locatorInfo:type_name -> signal.backup.FilePointer.LocatorInfo - 46, // 81: signal.backup.Quote.text:type_name -> signal.backup.Text - 147, // 82: signal.backup.Quote.attachments:type_name -> signal.backup.Quote.QuotedAttachment - 20, // 83: signal.backup.Quote.type:type_name -> signal.backup.Quote.Type - 21, // 84: signal.backup.BodyRange.style:type_name -> signal.backup.BodyRange.Style - 148, // 85: signal.backup.Poll.options:type_name -> signal.backup.Poll.PollOption - 67, // 86: signal.backup.ChatUpdateMessage.simpleUpdate:type_name -> signal.backup.SimpleChatUpdate - 73, // 87: signal.backup.ChatUpdateMessage.groupChange:type_name -> signal.backup.GroupChangeChatUpdate - 68, // 88: signal.backup.ChatUpdateMessage.expirationTimerChange:type_name -> signal.backup.ExpirationTimerChatUpdate - 69, // 89: signal.backup.ChatUpdateMessage.profileChange:type_name -> signal.backup.ProfileChangeChatUpdate - 71, // 90: signal.backup.ChatUpdateMessage.threadMerge:type_name -> signal.backup.ThreadMergeChatUpdate - 72, // 91: signal.backup.ChatUpdateMessage.sessionSwitchover:type_name -> signal.backup.SessionSwitchoverChatUpdate - 65, // 92: signal.backup.ChatUpdateMessage.individualCall:type_name -> signal.backup.IndividualCall - 66, // 93: signal.backup.ChatUpdateMessage.groupCall:type_name -> signal.backup.GroupCall - 70, // 94: signal.backup.ChatUpdateMessage.learnedProfileChange:type_name -> signal.backup.LearnedProfileChatUpdate - 108, // 95: signal.backup.ChatUpdateMessage.pollTerminate:type_name -> signal.backup.PollTerminateUpdate - 22, // 96: signal.backup.IndividualCall.type:type_name -> signal.backup.IndividualCall.Type - 23, // 97: signal.backup.IndividualCall.direction:type_name -> signal.backup.IndividualCall.Direction - 24, // 98: signal.backup.IndividualCall.state:type_name -> signal.backup.IndividualCall.State - 25, // 99: signal.backup.GroupCall.state:type_name -> signal.backup.GroupCall.State - 26, // 100: signal.backup.SimpleChatUpdate.type:type_name -> signal.backup.SimpleChatUpdate.Type - 150, // 101: signal.backup.GroupChangeChatUpdate.updates:type_name -> signal.backup.GroupChangeChatUpdate.Update - 1, // 102: signal.backup.GroupMembershipAccessLevelChangeUpdate.accessLevel:type_name -> signal.backup.GroupV2AccessLevel - 1, // 103: signal.backup.GroupAttributesAccessLevelChangeUpdate.accessLevel:type_name -> signal.backup.GroupV2AccessLevel - 151, // 104: signal.backup.GroupInvitationRevokedUpdate.invitees:type_name -> signal.backup.GroupInvitationRevokedUpdate.Invitee - 27, // 105: signal.backup.ChatStyle.wallpaperPreset:type_name -> signal.backup.ChatStyle.WallpaperPreset - 59, // 106: signal.backup.ChatStyle.wallpaperPhoto:type_name -> signal.backup.FilePointer - 154, // 107: signal.backup.ChatStyle.autoBubbleColor:type_name -> signal.backup.ChatStyle.AutomaticBubbleColor - 28, // 108: signal.backup.ChatStyle.bubbleColorPreset:type_name -> signal.backup.ChatStyle.BubbleColorPreset - 29, // 109: signal.backup.NotificationProfile.scheduleDaysEnabled:type_name -> signal.backup.NotificationProfile.DayOfWeek - 30, // 110: signal.backup.ChatFolder.folderType:type_name -> signal.backup.ChatFolder.FolderType - 3, // 111: signal.backup.AccountData.UsernameLink.color:type_name -> signal.backup.AccountData.UsernameLink.Color - 2, // 112: signal.backup.AccountData.AccountSettings.phoneNumberSharingMode:type_name -> signal.backup.AccountData.PhoneNumberSharingMode - 110, // 113: signal.backup.AccountData.AccountSettings.defaultChatStyle:type_name -> signal.backup.ChatStyle - 153, // 114: signal.backup.AccountData.AccountSettings.customChatColors:type_name -> signal.backup.ChatStyle.CustomChatColor - 121, // 115: signal.backup.Group.GroupSnapshot.title:type_name -> signal.backup.Group.GroupAttributeBlob - 121, // 116: signal.backup.Group.GroupSnapshot.description:type_name -> signal.backup.Group.GroupAttributeBlob - 121, // 117: signal.backup.Group.GroupSnapshot.disappearingMessagesTimer:type_name -> signal.backup.Group.GroupAttributeBlob - 126, // 118: signal.backup.Group.GroupSnapshot.accessControl:type_name -> signal.backup.Group.AccessControl - 122, // 119: signal.backup.Group.GroupSnapshot.members:type_name -> signal.backup.Group.Member - 123, // 120: signal.backup.Group.GroupSnapshot.membersPendingProfileKey:type_name -> signal.backup.Group.MemberPendingProfileKey - 124, // 121: signal.backup.Group.GroupSnapshot.membersPendingAdminApproval:type_name -> signal.backup.Group.MemberPendingAdminApproval - 125, // 122: signal.backup.Group.GroupSnapshot.members_banned:type_name -> signal.backup.Group.MemberBanned - 7, // 123: signal.backup.Group.Member.role:type_name -> signal.backup.Group.Member.Role - 122, // 124: signal.backup.Group.MemberPendingProfileKey.member:type_name -> signal.backup.Group.Member - 8, // 125: signal.backup.Group.AccessControl.attributes:type_name -> signal.backup.Group.AccessControl.AccessRequired - 8, // 126: signal.backup.Group.AccessControl.members:type_name -> signal.backup.Group.AccessControl.AccessRequired - 8, // 127: signal.backup.Group.AccessControl.addFromInviteLink:type_name -> signal.backup.Group.AccessControl.AccessRequired - 45, // 128: signal.backup.ChatItem.OutgoingMessageDetails.sendStatus:type_name -> signal.backup.SendStatus - 12, // 129: signal.backup.SendStatus.Failed.reason:type_name -> signal.backup.SendStatus.Failed.FailureReason - 46, // 130: signal.backup.DirectStoryReplyMessage.TextReply.text:type_name -> signal.backup.Text - 59, // 131: signal.backup.DirectStoryReplyMessage.TextReply.longText:type_name -> signal.backup.FilePointer - 141, // 132: signal.backup.PaymentNotification.TransactionDetails.transaction:type_name -> signal.backup.PaymentNotification.TransactionDetails.Transaction - 140, // 133: signal.backup.PaymentNotification.TransactionDetails.failedTransaction:type_name -> signal.backup.PaymentNotification.TransactionDetails.FailedTransaction - 13, // 134: signal.backup.PaymentNotification.TransactionDetails.FailedTransaction.reason:type_name -> signal.backup.PaymentNotification.TransactionDetails.FailedTransaction.FailureReason - 14, // 135: signal.backup.PaymentNotification.TransactionDetails.Transaction.status:type_name -> signal.backup.PaymentNotification.TransactionDetails.Transaction.Status - 139, // 136: signal.backup.PaymentNotification.TransactionDetails.Transaction.mobileCoinIdentification:type_name -> signal.backup.PaymentNotification.TransactionDetails.MobileCoinTxoIdentification - 16, // 137: signal.backup.ContactAttachment.Phone.type:type_name -> signal.backup.ContactAttachment.Phone.Type - 17, // 138: signal.backup.ContactAttachment.Email.type:type_name -> signal.backup.ContactAttachment.Email.Type - 18, // 139: signal.backup.ContactAttachment.PostalAddress.type:type_name -> signal.backup.ContactAttachment.PostalAddress.Type - 58, // 140: signal.backup.Quote.QuotedAttachment.thumbnail:type_name -> signal.backup.MessageAttachment - 149, // 141: signal.backup.Poll.PollOption.votes:type_name -> signal.backup.Poll.PollOption.PollVote - 74, // 142: signal.backup.GroupChangeChatUpdate.Update.genericGroupUpdate:type_name -> signal.backup.GenericGroupUpdate - 75, // 143: signal.backup.GroupChangeChatUpdate.Update.groupCreationUpdate:type_name -> signal.backup.GroupCreationUpdate - 76, // 144: signal.backup.GroupChangeChatUpdate.Update.groupNameUpdate:type_name -> signal.backup.GroupNameUpdate - 77, // 145: signal.backup.GroupChangeChatUpdate.Update.groupAvatarUpdate:type_name -> signal.backup.GroupAvatarUpdate - 78, // 146: signal.backup.GroupChangeChatUpdate.Update.groupDescriptionUpdate:type_name -> signal.backup.GroupDescriptionUpdate - 79, // 147: signal.backup.GroupChangeChatUpdate.Update.groupMembershipAccessLevelChangeUpdate:type_name -> signal.backup.GroupMembershipAccessLevelChangeUpdate - 80, // 148: signal.backup.GroupChangeChatUpdate.Update.groupAttributesAccessLevelChangeUpdate:type_name -> signal.backup.GroupAttributesAccessLevelChangeUpdate - 81, // 149: signal.backup.GroupChangeChatUpdate.Update.groupAnnouncementOnlyChangeUpdate:type_name -> signal.backup.GroupAnnouncementOnlyChangeUpdate - 82, // 150: signal.backup.GroupChangeChatUpdate.Update.groupAdminStatusUpdate:type_name -> signal.backup.GroupAdminStatusUpdate - 83, // 151: signal.backup.GroupChangeChatUpdate.Update.groupMemberLeftUpdate:type_name -> signal.backup.GroupMemberLeftUpdate - 84, // 152: signal.backup.GroupChangeChatUpdate.Update.groupMemberRemovedUpdate:type_name -> signal.backup.GroupMemberRemovedUpdate - 85, // 153: signal.backup.GroupChangeChatUpdate.Update.selfInvitedToGroupUpdate:type_name -> signal.backup.SelfInvitedToGroupUpdate - 86, // 154: signal.backup.GroupChangeChatUpdate.Update.selfInvitedOtherUserToGroupUpdate:type_name -> signal.backup.SelfInvitedOtherUserToGroupUpdate - 87, // 155: signal.backup.GroupChangeChatUpdate.Update.groupUnknownInviteeUpdate:type_name -> signal.backup.GroupUnknownInviteeUpdate - 88, // 156: signal.backup.GroupChangeChatUpdate.Update.groupInvitationAcceptedUpdate:type_name -> signal.backup.GroupInvitationAcceptedUpdate - 89, // 157: signal.backup.GroupChangeChatUpdate.Update.groupInvitationDeclinedUpdate:type_name -> signal.backup.GroupInvitationDeclinedUpdate - 90, // 158: signal.backup.GroupChangeChatUpdate.Update.groupMemberJoinedUpdate:type_name -> signal.backup.GroupMemberJoinedUpdate - 91, // 159: signal.backup.GroupChangeChatUpdate.Update.groupMemberAddedUpdate:type_name -> signal.backup.GroupMemberAddedUpdate - 92, // 160: signal.backup.GroupChangeChatUpdate.Update.groupSelfInvitationRevokedUpdate:type_name -> signal.backup.GroupSelfInvitationRevokedUpdate - 93, // 161: signal.backup.GroupChangeChatUpdate.Update.groupInvitationRevokedUpdate:type_name -> signal.backup.GroupInvitationRevokedUpdate - 94, // 162: signal.backup.GroupChangeChatUpdate.Update.groupJoinRequestUpdate:type_name -> signal.backup.GroupJoinRequestUpdate - 95, // 163: signal.backup.GroupChangeChatUpdate.Update.groupJoinRequestApprovalUpdate:type_name -> signal.backup.GroupJoinRequestApprovalUpdate - 96, // 164: signal.backup.GroupChangeChatUpdate.Update.groupJoinRequestCanceledUpdate:type_name -> signal.backup.GroupJoinRequestCanceledUpdate - 98, // 165: signal.backup.GroupChangeChatUpdate.Update.groupInviteLinkResetUpdate:type_name -> signal.backup.GroupInviteLinkResetUpdate - 99, // 166: signal.backup.GroupChangeChatUpdate.Update.groupInviteLinkEnabledUpdate:type_name -> signal.backup.GroupInviteLinkEnabledUpdate - 100, // 167: signal.backup.GroupChangeChatUpdate.Update.groupInviteLinkAdminApprovalUpdate:type_name -> signal.backup.GroupInviteLinkAdminApprovalUpdate - 101, // 168: signal.backup.GroupChangeChatUpdate.Update.groupInviteLinkDisabledUpdate:type_name -> signal.backup.GroupInviteLinkDisabledUpdate - 102, // 169: signal.backup.GroupChangeChatUpdate.Update.groupMemberJoinedByLinkUpdate:type_name -> signal.backup.GroupMemberJoinedByLinkUpdate - 103, // 170: signal.backup.GroupChangeChatUpdate.Update.groupV2MigrationUpdate:type_name -> signal.backup.GroupV2MigrationUpdate - 104, // 171: signal.backup.GroupChangeChatUpdate.Update.groupV2MigrationSelfInvitedUpdate:type_name -> signal.backup.GroupV2MigrationSelfInvitedUpdate - 105, // 172: signal.backup.GroupChangeChatUpdate.Update.groupV2MigrationInvitedMembersUpdate:type_name -> signal.backup.GroupV2MigrationInvitedMembersUpdate - 106, // 173: signal.backup.GroupChangeChatUpdate.Update.groupV2MigrationDroppedMembersUpdate:type_name -> signal.backup.GroupV2MigrationDroppedMembersUpdate - 97, // 174: signal.backup.GroupChangeChatUpdate.Update.groupSequenceOfRequestsAndCancelsUpdate:type_name -> signal.backup.GroupSequenceOfRequestsAndCancelsUpdate - 107, // 175: signal.backup.GroupChangeChatUpdate.Update.groupExpirationTimerUpdate:type_name -> signal.backup.GroupExpirationTimerUpdate - 152, // 176: signal.backup.ChatStyle.CustomChatColor.gradient:type_name -> signal.backup.ChatStyle.Gradient - 177, // [177:177] is the sub-list for method output_type - 177, // [177:177] is the sub-list for method input_type - 177, // [177:177] is the sub-list for extension type_name - 177, // [177:177] is the sub-list for extension extendee - 0, // [0:177] is the sub-list for field type_name + 38, // 0: signal.backup.Frame.account:type_name -> signal.backup.AccountData + 39, // 1: signal.backup.Frame.recipient:type_name -> signal.backup.Recipient + 44, // 2: signal.backup.Frame.chat:type_name -> signal.backup.Chat + 49, // 3: signal.backup.Frame.chatItem:type_name -> signal.backup.ChatItem + 115, // 4: signal.backup.Frame.stickerPack:type_name -> signal.backup.StickerPack + 46, // 5: signal.backup.Frame.adHocCall:type_name -> signal.backup.AdHocCall + 117, // 6: signal.backup.Frame.notificationProfile:type_name -> signal.backup.NotificationProfile + 118, // 7: signal.backup.Frame.chatFolder:type_name -> signal.backup.ChatFolder + 119, // 8: signal.backup.AccountData.usernameLink:type_name -> signal.backup.AccountData.UsernameLink + 122, // 9: signal.backup.AccountData.donationSubscriberData:type_name -> signal.backup.AccountData.SubscriberData + 121, // 10: signal.backup.AccountData.accountSettings:type_name -> signal.backup.AccountData.AccountSettings + 123, // 11: signal.backup.AccountData.backupsSubscriberData:type_name -> signal.backup.AccountData.IAPSubscriberData + 124, // 12: signal.backup.AccountData.androidSpecificSettings:type_name -> signal.backup.AccountData.AndroidSpecificSettings + 40, // 13: signal.backup.Recipient.contact:type_name -> signal.backup.Contact + 41, // 14: signal.backup.Recipient.group:type_name -> signal.backup.Group + 47, // 15: signal.backup.Recipient.distributionList:type_name -> signal.backup.DistributionListItem + 42, // 16: signal.backup.Recipient.self:type_name -> signal.backup.Self + 43, // 17: signal.backup.Recipient.releaseNotes:type_name -> signal.backup.ReleaseNotes + 45, // 18: signal.backup.Recipient.callLink:type_name -> signal.backup.CallLink + 10, // 19: signal.backup.Contact.visibility:type_name -> signal.backup.Contact.Visibility + 125, // 20: signal.backup.Contact.registered:type_name -> signal.backup.Contact.Registered + 126, // 21: signal.backup.Contact.notRegistered:type_name -> signal.backup.Contact.NotRegistered + 9, // 22: signal.backup.Contact.identityState:type_name -> signal.backup.Contact.IdentityState + 127, // 23: signal.backup.Contact.nickname:type_name -> signal.backup.Contact.Name + 0, // 24: signal.backup.Contact.avatarColor:type_name -> signal.backup.AvatarColor + 11, // 25: signal.backup.Group.storySendMode:type_name -> signal.backup.Group.StorySendMode + 128, // 26: signal.backup.Group.snapshot:type_name -> signal.backup.Group.GroupSnapshot + 0, // 27: signal.backup.Group.avatarColor:type_name -> signal.backup.AvatarColor + 0, // 28: signal.backup.Self.avatarColor:type_name -> signal.backup.AvatarColor + 116, // 29: signal.backup.Chat.style:type_name -> signal.backup.ChatStyle + 14, // 30: signal.backup.CallLink.restrictions:type_name -> signal.backup.CallLink.Restrictions + 15, // 31: signal.backup.AdHocCall.state:type_name -> signal.backup.AdHocCall.State + 48, // 32: signal.backup.DistributionListItem.distributionList:type_name -> signal.backup.DistributionList + 16, // 33: signal.backup.DistributionList.privacyMode:type_name -> signal.backup.DistributionList.PrivacyMode + 49, // 34: signal.backup.ChatItem.revisions:type_name -> signal.backup.ChatItem + 135, // 35: signal.backup.ChatItem.incoming:type_name -> signal.backup.ChatItem.IncomingMessageDetails + 136, // 36: signal.backup.ChatItem.outgoing:type_name -> signal.backup.ChatItem.OutgoingMessageDetails + 137, // 37: signal.backup.ChatItem.directionless:type_name -> signal.backup.ChatItem.DirectionlessMessageDetails + 52, // 38: signal.backup.ChatItem.standardMessage:type_name -> signal.backup.StandardMessage + 53, // 39: signal.backup.ChatItem.contactMessage:type_name -> signal.backup.ContactMessage + 59, // 40: signal.backup.ChatItem.stickerMessage:type_name -> signal.backup.StickerMessage + 60, // 41: signal.backup.ChatItem.remoteDeletedMessage:type_name -> signal.backup.RemoteDeletedMessage + 69, // 42: signal.backup.ChatItem.updateMessage:type_name -> signal.backup.ChatUpdateMessage + 55, // 43: signal.backup.ChatItem.paymentNotification:type_name -> signal.backup.PaymentNotification + 56, // 44: signal.backup.ChatItem.giftBadge:type_name -> signal.backup.GiftBadge + 57, // 45: signal.backup.ChatItem.viewOnceMessage:type_name -> signal.backup.ViewOnceMessage + 54, // 46: signal.backup.ChatItem.directStoryReplyMessage:type_name -> signal.backup.DirectStoryReplyMessage + 68, // 47: signal.backup.ChatItem.poll:type_name -> signal.backup.Poll + 138, // 48: signal.backup.ChatItem.pinDetails:type_name -> signal.backup.ChatItem.PinDetails + 139, // 49: signal.backup.SendStatus.pending:type_name -> signal.backup.SendStatus.Pending + 140, // 50: signal.backup.SendStatus.sent:type_name -> signal.backup.SendStatus.Sent + 141, // 51: signal.backup.SendStatus.delivered:type_name -> signal.backup.SendStatus.Delivered + 142, // 52: signal.backup.SendStatus.read:type_name -> signal.backup.SendStatus.Read + 143, // 53: signal.backup.SendStatus.viewed:type_name -> signal.backup.SendStatus.Viewed + 144, // 54: signal.backup.SendStatus.skipped:type_name -> signal.backup.SendStatus.Skipped + 145, // 55: signal.backup.SendStatus.failed:type_name -> signal.backup.SendStatus.Failed + 66, // 56: signal.backup.Text.bodyRanges:type_name -> signal.backup.BodyRange + 65, // 57: signal.backup.StandardMessage.quote:type_name -> signal.backup.Quote + 51, // 58: signal.backup.StandardMessage.text:type_name -> signal.backup.Text + 63, // 59: signal.backup.StandardMessage.attachments:type_name -> signal.backup.MessageAttachment + 62, // 60: signal.backup.StandardMessage.linkPreview:type_name -> signal.backup.LinkPreview + 64, // 61: signal.backup.StandardMessage.longText:type_name -> signal.backup.FilePointer + 67, // 62: signal.backup.StandardMessage.reactions:type_name -> signal.backup.Reaction + 58, // 63: signal.backup.ContactMessage.contact:type_name -> signal.backup.ContactAttachment + 67, // 64: signal.backup.ContactMessage.reactions:type_name -> signal.backup.Reaction + 146, // 65: signal.backup.DirectStoryReplyMessage.textReply:type_name -> signal.backup.DirectStoryReplyMessage.TextReply + 67, // 66: signal.backup.DirectStoryReplyMessage.reactions:type_name -> signal.backup.Reaction + 147, // 67: signal.backup.PaymentNotification.transactionDetails:type_name -> signal.backup.PaymentNotification.TransactionDetails + 20, // 68: signal.backup.GiftBadge.state:type_name -> signal.backup.GiftBadge.State + 63, // 69: signal.backup.ViewOnceMessage.attachment:type_name -> signal.backup.MessageAttachment + 67, // 70: signal.backup.ViewOnceMessage.reactions:type_name -> signal.backup.Reaction + 151, // 71: signal.backup.ContactAttachment.name:type_name -> signal.backup.ContactAttachment.Name + 152, // 72: signal.backup.ContactAttachment.number:type_name -> signal.backup.ContactAttachment.Phone + 153, // 73: signal.backup.ContactAttachment.email:type_name -> signal.backup.ContactAttachment.Email + 154, // 74: signal.backup.ContactAttachment.address:type_name -> signal.backup.ContactAttachment.PostalAddress + 64, // 75: signal.backup.ContactAttachment.avatar:type_name -> signal.backup.FilePointer + 61, // 76: signal.backup.StickerMessage.sticker:type_name -> signal.backup.Sticker + 67, // 77: signal.backup.StickerMessage.reactions:type_name -> signal.backup.Reaction + 64, // 78: signal.backup.Sticker.data:type_name -> signal.backup.FilePointer + 64, // 79: signal.backup.LinkPreview.image:type_name -> signal.backup.FilePointer + 64, // 80: signal.backup.MessageAttachment.pointer:type_name -> signal.backup.FilePointer + 24, // 81: signal.backup.MessageAttachment.flag:type_name -> signal.backup.MessageAttachment.Flag + 155, // 82: signal.backup.FilePointer.locatorInfo:type_name -> signal.backup.FilePointer.LocatorInfo + 51, // 83: signal.backup.Quote.text:type_name -> signal.backup.Text + 156, // 84: signal.backup.Quote.attachments:type_name -> signal.backup.Quote.QuotedAttachment + 25, // 85: signal.backup.Quote.type:type_name -> signal.backup.Quote.Type + 26, // 86: signal.backup.BodyRange.style:type_name -> signal.backup.BodyRange.Style + 157, // 87: signal.backup.Poll.options:type_name -> signal.backup.Poll.PollOption + 67, // 88: signal.backup.Poll.reactions:type_name -> signal.backup.Reaction + 72, // 89: signal.backup.ChatUpdateMessage.simpleUpdate:type_name -> signal.backup.SimpleChatUpdate + 78, // 90: signal.backup.ChatUpdateMessage.groupChange:type_name -> signal.backup.GroupChangeChatUpdate + 73, // 91: signal.backup.ChatUpdateMessage.expirationTimerChange:type_name -> signal.backup.ExpirationTimerChatUpdate + 74, // 92: signal.backup.ChatUpdateMessage.profileChange:type_name -> signal.backup.ProfileChangeChatUpdate + 76, // 93: signal.backup.ChatUpdateMessage.threadMerge:type_name -> signal.backup.ThreadMergeChatUpdate + 77, // 94: signal.backup.ChatUpdateMessage.sessionSwitchover:type_name -> signal.backup.SessionSwitchoverChatUpdate + 70, // 95: signal.backup.ChatUpdateMessage.individualCall:type_name -> signal.backup.IndividualCall + 71, // 96: signal.backup.ChatUpdateMessage.groupCall:type_name -> signal.backup.GroupCall + 75, // 97: signal.backup.ChatUpdateMessage.learnedProfileChange:type_name -> signal.backup.LearnedProfileChatUpdate + 113, // 98: signal.backup.ChatUpdateMessage.pollTerminate:type_name -> signal.backup.PollTerminateUpdate + 114, // 99: signal.backup.ChatUpdateMessage.pinMessage:type_name -> signal.backup.PinMessageUpdate + 27, // 100: signal.backup.IndividualCall.type:type_name -> signal.backup.IndividualCall.Type + 28, // 101: signal.backup.IndividualCall.direction:type_name -> signal.backup.IndividualCall.Direction + 29, // 102: signal.backup.IndividualCall.state:type_name -> signal.backup.IndividualCall.State + 30, // 103: signal.backup.GroupCall.state:type_name -> signal.backup.GroupCall.State + 31, // 104: signal.backup.SimpleChatUpdate.type:type_name -> signal.backup.SimpleChatUpdate.Type + 159, // 105: signal.backup.GroupChangeChatUpdate.updates:type_name -> signal.backup.GroupChangeChatUpdate.Update + 1, // 106: signal.backup.GroupMembershipAccessLevelChangeUpdate.accessLevel:type_name -> signal.backup.GroupV2AccessLevel + 1, // 107: signal.backup.GroupAttributesAccessLevelChangeUpdate.accessLevel:type_name -> signal.backup.GroupV2AccessLevel + 160, // 108: signal.backup.GroupInvitationRevokedUpdate.invitees:type_name -> signal.backup.GroupInvitationRevokedUpdate.Invitee + 32, // 109: signal.backup.ChatStyle.wallpaperPreset:type_name -> signal.backup.ChatStyle.WallpaperPreset + 64, // 110: signal.backup.ChatStyle.wallpaperPhoto:type_name -> signal.backup.FilePointer + 163, // 111: signal.backup.ChatStyle.autoBubbleColor:type_name -> signal.backup.ChatStyle.AutomaticBubbleColor + 33, // 112: signal.backup.ChatStyle.bubbleColorPreset:type_name -> signal.backup.ChatStyle.BubbleColorPreset + 34, // 113: signal.backup.NotificationProfile.scheduleDaysEnabled:type_name -> signal.backup.NotificationProfile.DayOfWeek + 35, // 114: signal.backup.ChatFolder.folderType:type_name -> signal.backup.ChatFolder.FolderType + 6, // 115: signal.backup.AccountData.UsernameLink.color:type_name -> signal.backup.AccountData.UsernameLink.Color + 7, // 116: signal.backup.AccountData.AutoDownloadSettings.images:type_name -> signal.backup.AccountData.AutoDownloadSettings.AutoDownloadOption + 7, // 117: signal.backup.AccountData.AutoDownloadSettings.audio:type_name -> signal.backup.AccountData.AutoDownloadSettings.AutoDownloadOption + 7, // 118: signal.backup.AccountData.AutoDownloadSettings.video:type_name -> signal.backup.AccountData.AutoDownloadSettings.AutoDownloadOption + 7, // 119: signal.backup.AccountData.AutoDownloadSettings.documents:type_name -> signal.backup.AccountData.AutoDownloadSettings.AutoDownloadOption + 2, // 120: signal.backup.AccountData.AccountSettings.phoneNumberSharingMode:type_name -> signal.backup.AccountData.PhoneNumberSharingMode + 116, // 121: signal.backup.AccountData.AccountSettings.defaultChatStyle:type_name -> signal.backup.ChatStyle + 162, // 122: signal.backup.AccountData.AccountSettings.customChatColors:type_name -> signal.backup.ChatStyle.CustomChatColor + 3, // 123: signal.backup.AccountData.AccountSettings.defaultSentMediaQuality:type_name -> signal.backup.AccountData.SentMediaQuality + 120, // 124: signal.backup.AccountData.AccountSettings.autoDownloadSettings:type_name -> signal.backup.AccountData.AutoDownloadSettings + 4, // 125: signal.backup.AccountData.AccountSettings.appTheme:type_name -> signal.backup.AccountData.AppTheme + 5, // 126: signal.backup.AccountData.AccountSettings.callsUseLessDataSetting:type_name -> signal.backup.AccountData.CallsUseLessDataSetting + 8, // 127: signal.backup.AccountData.AndroidSpecificSettings.navigationBarSize:type_name -> signal.backup.AccountData.AndroidSpecificSettings.NavigationBarSize + 129, // 128: signal.backup.Group.GroupSnapshot.title:type_name -> signal.backup.Group.GroupAttributeBlob + 129, // 129: signal.backup.Group.GroupSnapshot.description:type_name -> signal.backup.Group.GroupAttributeBlob + 129, // 130: signal.backup.Group.GroupSnapshot.disappearingMessagesTimer:type_name -> signal.backup.Group.GroupAttributeBlob + 134, // 131: signal.backup.Group.GroupSnapshot.accessControl:type_name -> signal.backup.Group.AccessControl + 130, // 132: signal.backup.Group.GroupSnapshot.members:type_name -> signal.backup.Group.Member + 131, // 133: signal.backup.Group.GroupSnapshot.membersPendingProfileKey:type_name -> signal.backup.Group.MemberPendingProfileKey + 132, // 134: signal.backup.Group.GroupSnapshot.membersPendingAdminApproval:type_name -> signal.backup.Group.MemberPendingAdminApproval + 133, // 135: signal.backup.Group.GroupSnapshot.members_banned:type_name -> signal.backup.Group.MemberBanned + 12, // 136: signal.backup.Group.Member.role:type_name -> signal.backup.Group.Member.Role + 130, // 137: signal.backup.Group.MemberPendingProfileKey.member:type_name -> signal.backup.Group.Member + 13, // 138: signal.backup.Group.AccessControl.attributes:type_name -> signal.backup.Group.AccessControl.AccessRequired + 13, // 139: signal.backup.Group.AccessControl.members:type_name -> signal.backup.Group.AccessControl.AccessRequired + 13, // 140: signal.backup.Group.AccessControl.addFromInviteLink:type_name -> signal.backup.Group.AccessControl.AccessRequired + 50, // 141: signal.backup.ChatItem.OutgoingMessageDetails.sendStatus:type_name -> signal.backup.SendStatus + 17, // 142: signal.backup.SendStatus.Failed.reason:type_name -> signal.backup.SendStatus.Failed.FailureReason + 51, // 143: signal.backup.DirectStoryReplyMessage.TextReply.text:type_name -> signal.backup.Text + 64, // 144: signal.backup.DirectStoryReplyMessage.TextReply.longText:type_name -> signal.backup.FilePointer + 150, // 145: signal.backup.PaymentNotification.TransactionDetails.transaction:type_name -> signal.backup.PaymentNotification.TransactionDetails.Transaction + 149, // 146: signal.backup.PaymentNotification.TransactionDetails.failedTransaction:type_name -> signal.backup.PaymentNotification.TransactionDetails.FailedTransaction + 18, // 147: signal.backup.PaymentNotification.TransactionDetails.FailedTransaction.reason:type_name -> signal.backup.PaymentNotification.TransactionDetails.FailedTransaction.FailureReason + 19, // 148: signal.backup.PaymentNotification.TransactionDetails.Transaction.status:type_name -> signal.backup.PaymentNotification.TransactionDetails.Transaction.Status + 148, // 149: signal.backup.PaymentNotification.TransactionDetails.Transaction.mobileCoinIdentification:type_name -> signal.backup.PaymentNotification.TransactionDetails.MobileCoinTxoIdentification + 21, // 150: signal.backup.ContactAttachment.Phone.type:type_name -> signal.backup.ContactAttachment.Phone.Type + 22, // 151: signal.backup.ContactAttachment.Email.type:type_name -> signal.backup.ContactAttachment.Email.Type + 23, // 152: signal.backup.ContactAttachment.PostalAddress.type:type_name -> signal.backup.ContactAttachment.PostalAddress.Type + 63, // 153: signal.backup.Quote.QuotedAttachment.thumbnail:type_name -> signal.backup.MessageAttachment + 158, // 154: signal.backup.Poll.PollOption.votes:type_name -> signal.backup.Poll.PollOption.PollVote + 79, // 155: signal.backup.GroupChangeChatUpdate.Update.genericGroupUpdate:type_name -> signal.backup.GenericGroupUpdate + 80, // 156: signal.backup.GroupChangeChatUpdate.Update.groupCreationUpdate:type_name -> signal.backup.GroupCreationUpdate + 81, // 157: signal.backup.GroupChangeChatUpdate.Update.groupNameUpdate:type_name -> signal.backup.GroupNameUpdate + 82, // 158: signal.backup.GroupChangeChatUpdate.Update.groupAvatarUpdate:type_name -> signal.backup.GroupAvatarUpdate + 83, // 159: signal.backup.GroupChangeChatUpdate.Update.groupDescriptionUpdate:type_name -> signal.backup.GroupDescriptionUpdate + 84, // 160: signal.backup.GroupChangeChatUpdate.Update.groupMembershipAccessLevelChangeUpdate:type_name -> signal.backup.GroupMembershipAccessLevelChangeUpdate + 85, // 161: signal.backup.GroupChangeChatUpdate.Update.groupAttributesAccessLevelChangeUpdate:type_name -> signal.backup.GroupAttributesAccessLevelChangeUpdate + 86, // 162: signal.backup.GroupChangeChatUpdate.Update.groupAnnouncementOnlyChangeUpdate:type_name -> signal.backup.GroupAnnouncementOnlyChangeUpdate + 87, // 163: signal.backup.GroupChangeChatUpdate.Update.groupAdminStatusUpdate:type_name -> signal.backup.GroupAdminStatusUpdate + 88, // 164: signal.backup.GroupChangeChatUpdate.Update.groupMemberLeftUpdate:type_name -> signal.backup.GroupMemberLeftUpdate + 89, // 165: signal.backup.GroupChangeChatUpdate.Update.groupMemberRemovedUpdate:type_name -> signal.backup.GroupMemberRemovedUpdate + 90, // 166: signal.backup.GroupChangeChatUpdate.Update.selfInvitedToGroupUpdate:type_name -> signal.backup.SelfInvitedToGroupUpdate + 91, // 167: signal.backup.GroupChangeChatUpdate.Update.selfInvitedOtherUserToGroupUpdate:type_name -> signal.backup.SelfInvitedOtherUserToGroupUpdate + 92, // 168: signal.backup.GroupChangeChatUpdate.Update.groupUnknownInviteeUpdate:type_name -> signal.backup.GroupUnknownInviteeUpdate + 93, // 169: signal.backup.GroupChangeChatUpdate.Update.groupInvitationAcceptedUpdate:type_name -> signal.backup.GroupInvitationAcceptedUpdate + 94, // 170: signal.backup.GroupChangeChatUpdate.Update.groupInvitationDeclinedUpdate:type_name -> signal.backup.GroupInvitationDeclinedUpdate + 95, // 171: signal.backup.GroupChangeChatUpdate.Update.groupMemberJoinedUpdate:type_name -> signal.backup.GroupMemberJoinedUpdate + 96, // 172: signal.backup.GroupChangeChatUpdate.Update.groupMemberAddedUpdate:type_name -> signal.backup.GroupMemberAddedUpdate + 97, // 173: signal.backup.GroupChangeChatUpdate.Update.groupSelfInvitationRevokedUpdate:type_name -> signal.backup.GroupSelfInvitationRevokedUpdate + 98, // 174: signal.backup.GroupChangeChatUpdate.Update.groupInvitationRevokedUpdate:type_name -> signal.backup.GroupInvitationRevokedUpdate + 99, // 175: signal.backup.GroupChangeChatUpdate.Update.groupJoinRequestUpdate:type_name -> signal.backup.GroupJoinRequestUpdate + 100, // 176: signal.backup.GroupChangeChatUpdate.Update.groupJoinRequestApprovalUpdate:type_name -> signal.backup.GroupJoinRequestApprovalUpdate + 101, // 177: signal.backup.GroupChangeChatUpdate.Update.groupJoinRequestCanceledUpdate:type_name -> signal.backup.GroupJoinRequestCanceledUpdate + 103, // 178: signal.backup.GroupChangeChatUpdate.Update.groupInviteLinkResetUpdate:type_name -> signal.backup.GroupInviteLinkResetUpdate + 104, // 179: signal.backup.GroupChangeChatUpdate.Update.groupInviteLinkEnabledUpdate:type_name -> signal.backup.GroupInviteLinkEnabledUpdate + 105, // 180: signal.backup.GroupChangeChatUpdate.Update.groupInviteLinkAdminApprovalUpdate:type_name -> signal.backup.GroupInviteLinkAdminApprovalUpdate + 106, // 181: signal.backup.GroupChangeChatUpdate.Update.groupInviteLinkDisabledUpdate:type_name -> signal.backup.GroupInviteLinkDisabledUpdate + 107, // 182: signal.backup.GroupChangeChatUpdate.Update.groupMemberJoinedByLinkUpdate:type_name -> signal.backup.GroupMemberJoinedByLinkUpdate + 108, // 183: signal.backup.GroupChangeChatUpdate.Update.groupV2MigrationUpdate:type_name -> signal.backup.GroupV2MigrationUpdate + 109, // 184: signal.backup.GroupChangeChatUpdate.Update.groupV2MigrationSelfInvitedUpdate:type_name -> signal.backup.GroupV2MigrationSelfInvitedUpdate + 110, // 185: signal.backup.GroupChangeChatUpdate.Update.groupV2MigrationInvitedMembersUpdate:type_name -> signal.backup.GroupV2MigrationInvitedMembersUpdate + 111, // 186: signal.backup.GroupChangeChatUpdate.Update.groupV2MigrationDroppedMembersUpdate:type_name -> signal.backup.GroupV2MigrationDroppedMembersUpdate + 102, // 187: signal.backup.GroupChangeChatUpdate.Update.groupSequenceOfRequestsAndCancelsUpdate:type_name -> signal.backup.GroupSequenceOfRequestsAndCancelsUpdate + 112, // 188: signal.backup.GroupChangeChatUpdate.Update.groupExpirationTimerUpdate:type_name -> signal.backup.GroupExpirationTimerUpdate + 161, // 189: signal.backup.ChatStyle.CustomChatColor.gradient:type_name -> signal.backup.ChatStyle.Gradient + 190, // [190:190] is the sub-list for method output_type + 190, // [190:190] is the sub-list for method input_type + 190, // [190:190] is the sub-list for extension type_name + 190, // [190:190] is the sub-list for extension extendee + 0, // [0:190] is the sub-list for field type_name } func init() { file_backuppb_Backup_proto_init() } @@ -12896,6 +13644,7 @@ func file_backuppb_Backup_proto_init() { (*ChatUpdateMessage_GroupCall)(nil), (*ChatUpdateMessage_LearnedProfileChange)(nil), (*ChatUpdateMessage_PollTerminate)(nil), + (*ChatUpdateMessage_PinMessage)(nil), } file_backuppb_Backup_proto_msgTypes[34].OneofWrappers = []any{} file_backuppb_Backup_proto_msgTypes[35].OneofWrappers = []any{} @@ -12926,37 +13675,41 @@ func file_backuppb_Backup_proto_init() { file_backuppb_Backup_proto_msgTypes[69].OneofWrappers = []any{} file_backuppb_Backup_proto_msgTypes[70].OneofWrappers = []any{} file_backuppb_Backup_proto_msgTypes[76].OneofWrappers = []any{} - file_backuppb_Backup_proto_msgTypes[79].OneofWrappers = []any{ + file_backuppb_Backup_proto_msgTypes[80].OneofWrappers = []any{ (*ChatStyle_WallpaperPreset_)(nil), (*ChatStyle_WallpaperPhoto)(nil), (*ChatStyle_AutoBubbleColor)(nil), (*ChatStyle_BubbleColorPreset_)(nil), (*ChatStyle_CustomColorId)(nil), } - file_backuppb_Backup_proto_msgTypes[80].OneofWrappers = []any{} - file_backuppb_Backup_proto_msgTypes[83].OneofWrappers = []any{} - file_backuppb_Backup_proto_msgTypes[85].OneofWrappers = []any{ + file_backuppb_Backup_proto_msgTypes[81].OneofWrappers = []any{} + file_backuppb_Backup_proto_msgTypes[85].OneofWrappers = []any{} + file_backuppb_Backup_proto_msgTypes[87].OneofWrappers = []any{ (*AccountData_IAPSubscriberData_PurchaseToken)(nil), (*AccountData_IAPSubscriberData_OriginalTransactionId)(nil), } - file_backuppb_Backup_proto_msgTypes[90].OneofWrappers = []any{ + file_backuppb_Backup_proto_msgTypes[93].OneofWrappers = []any{ (*Group_GroupAttributeBlob_Title)(nil), (*Group_GroupAttributeBlob_Avatar)(nil), (*Group_GroupAttributeBlob_DisappearingMessagesDuration)(nil), (*Group_GroupAttributeBlob_DescriptionText)(nil), } - file_backuppb_Backup_proto_msgTypes[96].OneofWrappers = []any{} - file_backuppb_Backup_proto_msgTypes[107].OneofWrappers = []any{ + file_backuppb_Backup_proto_msgTypes[99].OneofWrappers = []any{} + file_backuppb_Backup_proto_msgTypes[102].OneofWrappers = []any{ + (*ChatItem_PinDetails_PinExpiresAtTimestamp)(nil), + (*ChatItem_PinDetails_PinNeverExpires)(nil), + } + file_backuppb_Backup_proto_msgTypes[111].OneofWrappers = []any{ (*PaymentNotification_TransactionDetails_Transaction_)(nil), (*PaymentNotification_TransactionDetails_FailedTransaction_)(nil), } - file_backuppb_Backup_proto_msgTypes[110].OneofWrappers = []any{} - file_backuppb_Backup_proto_msgTypes[115].OneofWrappers = []any{ + file_backuppb_Backup_proto_msgTypes[114].OneofWrappers = []any{} + file_backuppb_Backup_proto_msgTypes[119].OneofWrappers = []any{ (*FilePointer_LocatorInfo_PlaintextHash)(nil), (*FilePointer_LocatorInfo_EncryptedDigest)(nil), } - file_backuppb_Backup_proto_msgTypes[116].OneofWrappers = []any{} - file_backuppb_Backup_proto_msgTypes[119].OneofWrappers = []any{ + file_backuppb_Backup_proto_msgTypes[120].OneofWrappers = []any{} + file_backuppb_Backup_proto_msgTypes[123].OneofWrappers = []any{ (*GroupChangeChatUpdate_Update_GenericGroupUpdate)(nil), (*GroupChangeChatUpdate_Update_GroupCreationUpdate)(nil), (*GroupChangeChatUpdate_Update_GroupNameUpdate)(nil), @@ -12992,8 +13745,8 @@ func file_backuppb_Backup_proto_init() { (*GroupChangeChatUpdate_Update_GroupSequenceOfRequestsAndCancelsUpdate)(nil), (*GroupChangeChatUpdate_Update_GroupExpirationTimerUpdate)(nil), } - file_backuppb_Backup_proto_msgTypes[120].OneofWrappers = []any{} - file_backuppb_Backup_proto_msgTypes[122].OneofWrappers = []any{ + file_backuppb_Backup_proto_msgTypes[124].OneofWrappers = []any{} + file_backuppb_Backup_proto_msgTypes[126].OneofWrappers = []any{ (*ChatStyle_CustomChatColor_Solid)(nil), (*ChatStyle_CustomChatColor_Gradient)(nil), } @@ -13002,8 +13755,8 @@ func file_backuppb_Backup_proto_init() { File: protoimpl.DescBuilder{ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: unsafe.Slice(unsafe.StringData(file_backuppb_Backup_proto_rawDesc), len(file_backuppb_Backup_proto_rawDesc)), - NumEnums: 31, - NumMessages: 124, + NumEnums: 36, + NumMessages: 128, NumExtensions: 0, NumServices: 0, }, diff --git a/pkg/signalmeow/protobuf/backuppb/Backup.proto b/pkg/signalmeow/protobuf/backuppb/Backup.proto index 66125fc..1b70167 100644 --- a/pkg/signalmeow/protobuf/backuppb/Backup.proto +++ b/pkg/signalmeow/protobuf/backuppb/Backup.proto @@ -68,6 +68,40 @@ message AccountData { Color color = 3; } + enum SentMediaQuality { + UNKNOWN_QUALITY = 0; // Interpret as "Standard" + STANDARD = 1; + HIGH = 2; + } + + message AutoDownloadSettings { + enum AutoDownloadOption { + UNKNOWN = 0; // Interpret as "Never" + NEVER = 1; + WIFI = 2; + WIFI_AND_CELLULAR = 3; + } + + AutoDownloadOption images = 1; + AutoDownloadOption audio = 2; + AutoDownloadOption video = 3; + AutoDownloadOption documents = 4; + } + + enum AppTheme { + UNKNOWN_APP_THEME = 0; // Interpret as "System" + SYSTEM = 1; + LIGHT = 2; + DARK = 3; + } + + enum CallsUseLessDataSetting { + UNKNOWN_CALL_DATA_SETTING = 0; // Interpret as "Never" + NEVER = 1; + MOBILE_DATA_ONLY = 2; + WIFI_AND_MOBILE_DATA = 3; + } + message AccountSettings { bool readReceipts = 1; bool sealedSenderIndicators = 2; @@ -91,6 +125,16 @@ message AccountData { bool optimizeOnDeviceStorage = 20; // See zkgroup for integer particular values. Unset if backups are not enabled. optional uint64 backupTier = 21; + reserved /* showSealedSenderIndicators */ 22; + SentMediaQuality defaultSentMediaQuality = 23; + AutoDownloadSettings autoDownloadSettings = 24; + reserved /* wifiAutoDownloadSettings */ 25; + optional uint32 screenLockTimeoutMinutes = 26; // If unset, consider screen lock to be disabled. + optional bool pinReminders = 27; // If unset, consider pin reminders to be enabled. + AppTheme appTheme = 28; // If unset, treat the same as "Unknown" case + CallsUseLessDataSetting callsUseLessDataSetting = 29; // If unset, treat the same as "Unknown" case + bool allowSealedSenderFromAnyone = 30; + bool allowAutomaticKeyVerification = 31; } message SubscriberData { @@ -111,6 +155,18 @@ message AccountData { } } + message AndroidSpecificSettings { + enum NavigationBarSize { + UNKNOWN_BAR_SIZE = 0; // Intepret as "Normal" + NORMAL = 1; + COMPACT = 2; + } + + bool useSystemEmoji = 1; + bool screenshotSecurity = 2; + NavigationBarSize navigationBarSize = 3; // If unset, treat the same as "Unknown" case + } + bytes profileKey = 1; optional string username = 2; UsernameLink usernameLink = 3; @@ -122,6 +178,10 @@ message AccountData { AccountSettings accountSettings = 9; IAPSubscriberData backupsSubscriberData = 10; string svrPin = 11; + AndroidSpecificSettings androidSpecificSettings = 12; + string bioText = 13; + string bioEmoji = 14; + optional bytes keyTransparencyData = 15; } message Recipient { @@ -210,6 +270,7 @@ message Contact { string systemFamilyName = 19; string systemNickname = 20; optional AvatarColor avatarColor = 21; + optional bytes keyTransparencyData = 22; } message Group { @@ -402,6 +463,14 @@ message ChatItem { message DirectionlessMessageDetails { } + message PinDetails { + uint64 pinnedAtTimestamp = 1; + oneof pinExpiry { + uint64 pinExpiresAtTimestamp = 2; // timestamp when the pin should expire + bool pinNeverExpires = 3; + } + } + uint64 chatId = 1; // conversation id uint64 authorId = 2; // recipient id uint64 dateSent = 3; @@ -430,6 +499,8 @@ message ChatItem { DirectStoryReplyMessage directStoryReplyMessage = 19; // group story reply messages are not backed up Poll poll = 20; } + + PinDetails pinDetails = 21; // only set if message is pinned } message SendStatus { @@ -824,6 +895,7 @@ message Poll { bool allowMultiple = 2; repeated PollOption options = 3; // At least two bool hasEnded = 4; + repeated Reaction reactions = 5; } message ChatUpdateMessage { @@ -839,6 +911,7 @@ message ChatUpdateMessage { GroupCall groupCall = 8; LearnedProfileChatUpdate learnedProfileChange = 9; PollTerminateUpdate pollTerminate = 10; + PinMessageUpdate pinMessage = 11; } } @@ -1209,6 +1282,11 @@ message PollTerminateUpdate { string question = 2; // Between 1-100 characters } +message PinMessageUpdate { + uint64 targetSentTimestamp = 1; + uint64 authorId = 2; // recipient id +} + message StickerPack { bytes packId = 1; bytes packKey = 2; diff --git a/pkg/signalmeow/protobuf/update-protos.sh b/pkg/signalmeow/protobuf/update-protos.sh index d8fea17..d65567c 100755 --- a/pkg/signalmeow/protobuf/update-protos.sh +++ b/pkg/signalmeow/protobuf/update-protos.sh @@ -1,14 +1,14 @@ #!/bin/bash set -euo pipefail -ANDROID_GIT_REVISION=${1:-d261f3ebf51864da067b968ee3366ed3e7369c78} -DESKTOP_GIT_REVISION=${1:-fb566c48e0fa146dfe0bea077ecdb3ff846ef80a} +ANDROID_GIT_REVISION=${1:-bc6114f6e0d3a4b1dcdc472331505f2644185264} +DESKTOP_GIT_REVISION=${1:-a9063ec0c3c1079072c1e30e0749c1ae8be5500a} update_proto() { case "$1" in Signal-Android) REPO="Signal-Android" - prefix="libsignal-service/src/main/protowire/" + prefix="lib/libsignal-service/src/main/protowire/" GIT_REVISION=$ANDROID_GIT_REVISION ;; Signal-Android-App) From 28af2ed551dcd614be32a9e81b38bd34dbf661ef Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Fri, 13 Feb 2026 16:17:43 +0200 Subject: [PATCH 520/580] signalmeow/store: add missing signalmeow_device foreign keys --- pkg/signalmeow/store/upgrades/00-latest.sql | 10 ++++-- ...7-sender-key-info-foreign-key.postgres.sql | 10 ++++++ .../27-sender-key-info-foreign-key.sqlite.sql | 32 +++++++++++++++++++ 3 files changed, 49 insertions(+), 3 deletions(-) create mode 100644 pkg/signalmeow/store/upgrades/27-sender-key-info-foreign-key.postgres.sql create mode 100644 pkg/signalmeow/store/upgrades/27-sender-key-info-foreign-key.sqlite.sql diff --git a/pkg/signalmeow/store/upgrades/00-latest.sql b/pkg/signalmeow/store/upgrades/00-latest.sql index 8f54eac..fbb44ad 100644 --- a/pkg/signalmeow/store/upgrades/00-latest.sql +++ b/pkg/signalmeow/store/upgrades/00-latest.sql @@ -1,4 +1,4 @@ --- v0 -> v26 (compatible with v13+): Latest revision +-- v0 -> v27 (compatible with v13+): Latest revision CREATE TABLE signalmeow_device ( aci_uuid TEXT PRIMARY KEY, @@ -100,7 +100,9 @@ CREATE TABLE signalmeow_outbound_sender_key_info ( distribution_id TEXT NOT NULL, shared_with jsonb NOT NULL, - PRIMARY KEY (account_id, group_id) + PRIMARY KEY (account_id, group_id), + CONSTRAINT signalmeow_outbound_sender_key_info_device_fkey + FOREIGN KEY (account_id) REFERENCES signalmeow_device (aci_uuid) ON DELETE CASCADE ON UPDATE CASCADE ); CREATE TABLE signalmeow_groups ( @@ -108,7 +110,9 @@ CREATE TABLE signalmeow_groups ( group_identifier TEXT NOT NULL, master_key TEXT NOT NULL, - PRIMARY KEY (account_id, group_identifier) + PRIMARY KEY (account_id, group_identifier), + CONSTRAINT signalmeow_groups_device_fkey + FOREIGN KEY (account_id) REFERENCES signalmeow_device (aci_uuid) ON DELETE CASCADE ON UPDATE CASCADE ); CREATE TABLE signalmeow_recipients ( diff --git a/pkg/signalmeow/store/upgrades/27-sender-key-info-foreign-key.postgres.sql b/pkg/signalmeow/store/upgrades/27-sender-key-info-foreign-key.postgres.sql new file mode 100644 index 0000000..e9c0ee5 --- /dev/null +++ b/pkg/signalmeow/store/upgrades/27-sender-key-info-foreign-key.postgres.sql @@ -0,0 +1,10 @@ +-- v27 (compatible with v13+): Add missing foreign key for outbound sender key info and groups +DELETE FROM signalmeow_outbound_sender_key_info +WHERE NOT EXISTS(SELECT 1 FROM signalmeow_device WHERE aci_uuid=account_id); +ALTER TABLE signalmeow_outbound_sender_key_info ADD CONSTRAINT signalmeow_outbound_sender_key_info_device_fkey + FOREIGN KEY (account_id) REFERENCES signalmeow_device (aci_uuid) ON DELETE CASCADE ON UPDATE CASCADE; + +DELETE FROM signalmeow_groups +WHERE NOT EXISTS(SELECT 1 FROM signalmeow_device WHERE aci_uuid=account_id); +ALTER TABLE signalmeow_groups ADD CONSTRAINT signalmeow_groups_device_fkey + FOREIGN KEY (account_id) REFERENCES signalmeow_device (aci_uuid) ON DELETE CASCADE ON UPDATE CASCADE; diff --git a/pkg/signalmeow/store/upgrades/27-sender-key-info-foreign-key.sqlite.sql b/pkg/signalmeow/store/upgrades/27-sender-key-info-foreign-key.sqlite.sql new file mode 100644 index 0000000..b6017ba --- /dev/null +++ b/pkg/signalmeow/store/upgrades/27-sender-key-info-foreign-key.sqlite.sql @@ -0,0 +1,32 @@ +-- v27 (compatible with v13+): Add missing foreign key for outbound sender key info and groups + +CREATE TABLE new_signalmeow_outbound_sender_key_info ( + account_id TEXT NOT NULL, + group_id TEXT NOT NULL, + distribution_id TEXT NOT NULL, + shared_with jsonb NOT NULL, + + PRIMARY KEY (account_id, group_id), + CONSTRAINT signalmeow_outbound_sender_key_info_device_fkey + FOREIGN KEY (account_id) REFERENCES signalmeow_device (aci_uuid) ON DELETE CASCADE ON UPDATE CASCADE +); +INSERT INTO new_signalmeow_outbound_sender_key_info +SELECT * FROM signalmeow_outbound_sender_key_info +WHERE EXISTS(SELECT 1 FROM signalmeow_device WHERE aci_uuid=account_id); +DROP TABLE signalmeow_outbound_sender_key_info; +ALTER TABLE new_signalmeow_outbound_sender_key_info RENAME TO signalmeow_outbound_sender_key_info; + +CREATE TABLE new_signalmeow_groups ( + account_id TEXT NOT NULL, + group_identifier TEXT NOT NULL, + master_key TEXT NOT NULL, + + PRIMARY KEY (account_id, group_identifier), + CONSTRAINT signalmeow_groups_device_fkey + FOREIGN KEY (account_id) REFERENCES signalmeow_device (aci_uuid) ON DELETE CASCADE ON UPDATE CASCADE +); +INSERT INTO new_signalmeow_groups +SELECT * FROM signalmeow_groups +WHERE EXISTS(SELECT 1 FROM signalmeow_device WHERE aci_uuid=account_id); +DROP TABLE signalmeow_groups; +ALTER TABLE new_signalmeow_groups RENAME TO signalmeow_groups; From 3faa0d4f3091c462b447d9cc1f16d8a27d5c643e Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Sun, 15 Feb 2026 13:08:11 +0200 Subject: [PATCH 521/580] main: bump minimum Go version to 1.25 --- .github/workflows/go.yml | 8 ++++---- go.mod | 4 ++-- pkg/signalmeow/groups.go | 3 +-- 3 files changed, 7 insertions(+), 8 deletions(-) diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml index 767c119..ebd9186 100644 --- a/.github/workflows/go.yml +++ b/.github/workflows/go.yml @@ -11,8 +11,8 @@ jobs: strategy: fail-fast: false matrix: - go-version: ["1.24", "1.25"] - name: Lint ${{ matrix.go-version == '1.25' && '(latest)' || '(old)' }} + go-version: ["1.25", "1.26"] + name: Lint ${{ matrix.go-version == '1.26' && '(latest)' || '(old)' }} steps: - uses: actions/checkout@v6 @@ -40,8 +40,8 @@ jobs: strategy: fail-fast: false matrix: - go-version: ["1.24", "1.25"] - name: Test ${{ matrix.go-version == '1.25' && '(latest)' || '(old)' }} + go-version: ["1.25", "1.26"] + name: Test ${{ matrix.go-version == '1.26' && '(latest)' || '(old)' }} steps: - uses: actions/checkout@v6 diff --git a/go.mod b/go.mod index 728ffb7..340f05c 100644 --- a/go.mod +++ b/go.mod @@ -1,8 +1,8 @@ module go.mau.fi/mautrix-signal -go 1.24.0 +go 1.25.0 -toolchain go1.25.6 +toolchain go1.26.0 tool go.mau.fi/util/cmd/maubuild diff --git a/pkg/signalmeow/groups.go b/pkg/signalmeow/groups.go index dcdfe7d..b02687b 100644 --- a/pkg/signalmeow/groups.go +++ b/pkg/signalmeow/groups.go @@ -226,8 +226,7 @@ func (groupChange *GroupChange) isEmpty() bool { len(groupChange.PromoteRequestingMembers) == 0 && groupChange.ModifyDescription == nil && groupChange.ModifyAnnouncementsOnly == nil && - len(groupChange.AddBannedMembers) == 0 && - len(groupChange.DeleteMembers) == 0 + len(groupChange.AddBannedMembers) == 0 } func (groupChange *GroupChange) resolveConflict(group *Group) { From 634f7c21caf96913a4b7cf93f5335d8ad25ecbb9 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Mon, 16 Feb 2026 15:02:53 +0200 Subject: [PATCH 522/580] Bump version to v26.02 --- CHANGELOG.md | 7 +++++++ cmd/mautrix-signal/main.go | 2 +- go.mod | 20 +++++++++---------- go.sum | 40 +++++++++++++++++++------------------- 4 files changed, 38 insertions(+), 31 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 29f2299..f18590b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +# v26.02 + +* Bumped minimum Go version to 1.25. +* Updated libsignal to v0.87.1. +* Added automatic recovery for the session not found error from libsignal. +* Fixed sender key state not being cleared on logout properly. + # v26.01 * Updated libsignal to v0.86.12. diff --git a/cmd/mautrix-signal/main.go b/cmd/mautrix-signal/main.go index 5391084..064b1e0 100644 --- a/cmd/mautrix-signal/main.go +++ b/cmd/mautrix-signal/main.go @@ -37,7 +37,7 @@ var m = mxmain.BridgeMain{ Name: "mautrix-signal", URL: "https://github.com/mautrix/signal", Description: "A Matrix-Signal puppeting bridge.", - Version: "26.01", + Version: "26.02", SemCalVer: true, Connector: &connector.SignalConnector{}, diff --git a/go.mod b/go.mod index 340f05c..3b6cc07 100644 --- a/go.mod +++ b/go.mod @@ -14,13 +14,13 @@ require ( github.com/rs/zerolog v1.34.0 github.com/stretchr/testify v1.11.1 github.com/tidwall/gjson v1.18.0 - go.mau.fi/util v0.9.5 - golang.org/x/crypto v0.47.0 - golang.org/x/exp v0.0.0-20260112195511-716be5621a96 - golang.org/x/net v0.49.0 + go.mau.fi/util v0.9.6 + golang.org/x/crypto v0.48.0 + golang.org/x/exp v0.0.0-20260212183809-81e46e3db34a + golang.org/x/net v0.50.0 google.golang.org/protobuf v1.36.11 gopkg.in/yaml.v3 v3.0.1 - maunium.net/go/mautrix v0.26.3-0.20260129174719-d2364b382275 + maunium.net/go/mautrix v0.26.3 ) require ( @@ -28,10 +28,10 @@ require ( github.com/coreos/go-systemd/v22 v22.6.0 // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/kr/pretty v0.3.1 // indirect - github.com/lib/pq v1.10.9 // indirect + github.com/lib/pq v1.11.2 // indirect github.com/mattn/go-colorable v0.1.14 // indirect github.com/mattn/go-isatty v0.0.20 // indirect - github.com/mattn/go-sqlite3 v1.14.33 // indirect + github.com/mattn/go-sqlite3 v1.14.34 // indirect github.com/petermattis/goid v0.0.0-20260113132338-7c7de50cc741 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/rogpeppe/go-internal v1.10.0 // indirect @@ -42,10 +42,10 @@ require ( github.com/tidwall/sjson v1.2.5 // indirect github.com/yuin/goldmark v1.7.16 // indirect go.mau.fi/zeroconfig v0.2.0 // indirect - golang.org/x/mod v0.32.0 // indirect + golang.org/x/mod v0.33.0 // indirect golang.org/x/sync v0.19.0 // indirect - golang.org/x/sys v0.40.0 // indirect - golang.org/x/text v0.33.0 // indirect + golang.org/x/sys v0.41.0 // indirect + golang.org/x/text v0.34.0 // indirect gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect gopkg.in/natefinch/lumberjack.v2 v2.2.1 // indirect maunium.net/go/mauflag v1.0.0 // indirect diff --git a/go.sum b/go.sum index 8dba58f..26c13e2 100644 --- a/go.sum +++ b/go.sum @@ -24,8 +24,8 @@ github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= -github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw= -github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= +github.com/lib/pq v1.11.2 h1:x6gxUeu39V0BHZiugWe8LXZYZ+Utk7hSJGThs8sdzfs= +github.com/lib/pq v1.11.2/go.mod h1:/p+8NSbOcwzAEI7wiMXFlgydTwcgTr3OSKMsD2BitpA= github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= github.com/mattn/go-colorable v0.1.14 h1:9A9LHSqF/7dyVVX6g0U9cwm9pG3kP9gSzcuIPHPsaIE= github.com/mattn/go-colorable v0.1.14/go.mod h1:6LmQG8QLFO4G5z1gPvYEzlUgJ2wF+stgPZH1UqBm1s8= @@ -35,8 +35,8 @@ github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWE github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mattn/go-pointer v0.0.1 h1:n+XhsuGeVO6MEAp7xyEukFINEa+Quek5psIR/ylA6o0= github.com/mattn/go-pointer v0.0.1/go.mod h1:2zXcozF6qYGgmsG+SeTZz3oAbFLdD3OWqnUbNvJZAlc= -github.com/mattn/go-sqlite3 v1.14.33 h1:A5blZ5ulQo2AtayQ9/limgHEkFreKj1Dv226a1K73s0= -github.com/mattn/go-sqlite3 v1.14.33/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y= +github.com/mattn/go-sqlite3 v1.14.34 h1:3NtcvcUnFBPsuRcno8pUtupspG/GM+9nZ88zgJcp6Zk= +github.com/mattn/go-sqlite3 v1.14.34/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y= github.com/petermattis/goid v0.0.0-20260113132338-7c7de50cc741 h1:KPpdlQLZcHfTMQRi6bFQ7ogNO0ltFT4PmtwTLW4W+14= github.com/petermattis/goid v0.0.0-20260113132338-7c7de50cc741/go.mod h1:pxMtw7cyUw6B2bRH0ZBANSPg+AoSud1I1iyJHI69jH4= github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= @@ -67,27 +67,27 @@ github.com/tidwall/sjson v1.2.5 h1:kLy8mja+1c9jlljvWTlSazM7cKDRfJuR/bOJhcY5NcY= github.com/tidwall/sjson v1.2.5/go.mod h1:Fvgq9kS/6ociJEDnK0Fk1cpYF4FIW6ZF7LAe+6jwd28= github.com/yuin/goldmark v1.7.16 h1:n+CJdUxaFMiDUNnWC3dMWCIQJSkxH4uz3ZwQBkAlVNE= github.com/yuin/goldmark v1.7.16/go.mod h1:ip/1k0VRfGynBgxOz0yCqHrbZXhcjxyuS66Brc7iBKg= -go.mau.fi/util v0.9.5 h1:7AoWPCIZJGv4jvtFEuCe3GhAbI7uF9ckIooaXvwlIR4= -go.mau.fi/util v0.9.5/go.mod h1:g1uvZ03VQhtTt2BgaRGVytS/Zj67NV0YNIECch0sQCQ= +go.mau.fi/util v0.9.6 h1:2nsvxm49KhI3wrFltr0+wSUBlnQ4CMtykuELjpIU+ts= +go.mau.fi/util v0.9.6/go.mod h1:sIJpRH7Iy5Ad1SBuxQoatxtIeErgzxCtjd/2hCMkYMI= go.mau.fi/zeroconfig v0.2.0 h1:e/OGEERqVRRKlgaro7E6bh8xXiKFSXB3eNNIud7FUjU= go.mau.fi/zeroconfig v0.2.0/go.mod h1:J0Vn0prHNOm493oZoQ84kq83ZaNCYZnq+noI1b1eN8w= -golang.org/x/crypto v0.47.0 h1:V6e3FRj+n4dbpw86FJ8Fv7XVOql7TEwpHapKoMJ/GO8= -golang.org/x/crypto v0.47.0/go.mod h1:ff3Y9VzzKbwSSEzWqJsJVBnWmRwRSHt/6Op5n9bQc4A= -golang.org/x/exp v0.0.0-20260112195511-716be5621a96 h1:Z/6YuSHTLOHfNFdb8zVZomZr7cqNgTJvA8+Qz75D8gU= -golang.org/x/exp v0.0.0-20260112195511-716be5621a96/go.mod h1:nzimsREAkjBCIEFtHiYkrJyT+2uy9YZJB7H1k68CXZU= -golang.org/x/mod v0.32.0 h1:9F4d3PHLljb6x//jOyokMv3eX+YDeepZSEo3mFJy93c= -golang.org/x/mod v0.32.0/go.mod h1:SgipZ/3h2Ci89DlEtEXWUk/HteuRin+HHhN+WbNhguU= -golang.org/x/net v0.49.0 h1:eeHFmOGUTtaaPSGNmjBKpbng9MulQsJURQUAfUwY++o= -golang.org/x/net v0.49.0/go.mod h1:/ysNB2EvaqvesRkuLAyjI1ycPZlQHM3q01F02UY/MV8= +golang.org/x/crypto v0.48.0 h1:/VRzVqiRSggnhY7gNRxPauEQ5Drw9haKdM0jqfcCFts= +golang.org/x/crypto v0.48.0/go.mod h1:r0kV5h3qnFPlQnBSrULhlsRfryS2pmewsg+XfMgkVos= +golang.org/x/exp v0.0.0-20260212183809-81e46e3db34a h1:ovFr6Z0MNmU7nH8VaX5xqw+05ST2uO1exVfZPVqRC5o= +golang.org/x/exp v0.0.0-20260212183809-81e46e3db34a/go.mod h1:K79w1Vqn7PoiZn+TkNpx3BUWUQksGO3JcVX6qIjytmA= +golang.org/x/mod v0.33.0 h1:tHFzIWbBifEmbwtGz65eaWyGiGZatSrT9prnU8DbVL8= +golang.org/x/mod v0.33.0/go.mod h1:swjeQEj+6r7fODbD2cqrnje9PnziFuw4bmLbBZFrQ5w= +golang.org/x/net v0.50.0 h1:ucWh9eiCGyDR3vtzso0WMQinm2Dnt8cFMuQa9K33J60= +golang.org/x/net v0.50.0/go.mod h1:UgoSli3F/pBgdJBHCTc+tp3gmrU4XswgGRgtnwWTfyM= golang.org/x/sync v0.19.0 h1:vV+1eWNmZ5geRlYjzm2adRgW2/mcpevXNg50YZtPCE4= golang.org/x/sync v0.19.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.40.0 h1:DBZZqJ2Rkml6QMQsZywtnjnnGvHza6BTfYFWY9kjEWQ= -golang.org/x/sys v0.40.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= -golang.org/x/text v0.33.0 h1:B3njUFyqtHDUI5jMn1YIr5B0IE2U0qck04r6d4KPAxE= -golang.org/x/text v0.33.0/go.mod h1:LuMebE6+rBincTi9+xWTY8TztLzKHc/9C1uBCG27+q8= +golang.org/x/sys v0.41.0 h1:Ivj+2Cp/ylzLiEU89QhWblYnOE9zerudt9Ftecq2C6k= +golang.org/x/sys v0.41.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= +golang.org/x/text v0.34.0 h1:oL/Qq0Kdaqxa1KbNeMKwQq0reLCCaFtqu2eNuSeNHbk= +golang.org/x/text v0.34.0/go.mod h1:homfLqTYRFyVYemLBFl5GgL/DWEiH5wcsQ5gSh1yziA= google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE= google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= @@ -99,5 +99,5 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= maunium.net/go/mauflag v1.0.0 h1:YiaRc0tEI3toYtJMRIfjP+jklH45uDHtT80nUamyD4M= maunium.net/go/mauflag v1.0.0/go.mod h1:nLivPOpTpHnpzEh8jEdSL9UqO9+/KBJFmNRlwKfkPeA= -maunium.net/go/mautrix v0.26.3-0.20260129174719-d2364b382275 h1:r8BL0+HW4Dar1xV7Fc7NV/LxGH6VCvffkCUGe9ZfJg8= -maunium.net/go/mautrix v0.26.3-0.20260129174719-d2364b382275/go.mod h1:CUxSZcjPtQNxsZLRQqETAxg2hiz7bjWT+L1HCYoMMKo= +maunium.net/go/mautrix v0.26.3 h1:tWZih6Vjw0qGTWuPmg9JUrQPzViTNDPGQLVc5UXC4nk= +maunium.net/go/mautrix v0.26.3/go.mod h1:v5ZdDoCwUpNqEj5OrhEoUa3L1kEddKPaAya9TgGXN38= From 375c51e7b884f742d526c167418c71750d827398 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Mon, 23 Feb 2026 15:11:56 +0200 Subject: [PATCH 523/580] handle*,msgconv,signalmeow: add support for binary ACI fields Fixes #635 --- pkg/connector/handlematrix.go | 20 ++++++++++++-------- pkg/connector/handlesignal.go | 28 ++++++++++++++++++++++------ pkg/libsignalgo/serviceid.go | 15 +++++++++++++++ pkg/msgconv/from-matrix.go | 4 +++- pkg/msgconv/from-signal.go | 2 +- pkg/signalmeow/misc.go | 28 ++++++++++++++++++++++++++++ pkg/signalmeow/receiving.go | 8 ++++++-- pkg/signalmeow/receiving_decrypt.go | 16 +++++----------- 8 files changed, 92 insertions(+), 29 deletions(-) diff --git a/pkg/connector/handlematrix.go b/pkg/connector/handlematrix.go index 610dd81..8819d69 100644 --- a/pkg/connector/handlematrix.go +++ b/pkg/connector/handlematrix.go @@ -205,9 +205,11 @@ func (s *SignalClient) HandleMatrixReaction(ctx context.Context, msg *bridgev2.M Timestamp: proto.Uint64(ts), RequiredProtocolVersion: proto.Uint32(uint32(signalpb.DataMessage_REACTIONS)), Reaction: &signalpb.DataMessage_Reaction{ - Emoji: proto.String(msg.PreHandleResp.Emoji), - Remove: proto.Bool(false), - TargetAuthorAci: proto.String(targetAuthorACI.String()), + Emoji: proto.String(msg.PreHandleResp.Emoji), + Remove: proto.Bool(false), + TargetAuthorAci: proto.String(targetAuthorACI.String()), + // TODO update aci format + //TargetAuthorAciBinary: targetAuthorACI[:], TargetSentTimestamp: proto.Uint64(targetSentTimestamp), }, }, @@ -230,9 +232,11 @@ func (s *SignalClient) HandleMatrixReactionRemove(ctx context.Context, msg *brid Timestamp: proto.Uint64(ts), RequiredProtocolVersion: proto.Uint32(uint32(signalpb.DataMessage_REACTIONS)), Reaction: &signalpb.DataMessage_Reaction{ - Emoji: proto.String(msg.TargetReaction.Emoji), - Remove: proto.Bool(true), - TargetAuthorAci: proto.String(targetAuthorACI.String()), + Emoji: proto.String(msg.TargetReaction.Emoji), + Remove: proto.Bool(true), + TargetAuthorAci: proto.String(targetAuthorACI.String()), + // TODO update aci format + //TargetAuthorAciBinary: targetAuthorACI[:], TargetSentTimestamp: proto.Uint64(targetSentTimestamp), }, }, @@ -760,8 +764,8 @@ func (s *SignalClient) HandleMatrixDeleteChat(ctx context.Context, msg *bridgev2 } mostRecentMessages = append(mostRecentMessages, &signalpb.AddressableMessage{ - Author: &signalpb.AddressableMessage_AuthorServiceId{ - AuthorServiceId: senderACI.String(), + Author: &signalpb.AddressableMessage_AuthorServiceIdBinary{ + AuthorServiceIdBinary: senderACI[:], }, SentTimestamp: proto.Uint64(timestamp), }) diff --git a/pkg/connector/handlesignal.go b/pkg/connector/handlesignal.go index fb1a3ce..f248d48 100644 --- a/pkg/connector/handlesignal.go +++ b/pkg/connector/handlesignal.go @@ -37,6 +37,7 @@ import ( "go.mau.fi/mautrix-signal/pkg/libsignalgo" "go.mau.fi/mautrix-signal/pkg/signalid" + "go.mau.fi/mautrix-signal/pkg/signalmeow" "go.mau.fi/mautrix-signal/pkg/signalmeow/events" signalpb "go.mau.fi/mautrix-signal/pkg/signalmeow/protobuf" "go.mau.fi/mautrix-signal/pkg/signalmeow/types" @@ -292,13 +293,13 @@ func (evt *Bv2ChatEvent) GetTimestamp() time.Time { } func (evt *Bv2ChatEvent) GetTargetMessage() networkid.MessageID { - var targetAuthorACI string + var targetAuthorACI uuid.UUID var targetSentTS uint64 switch innerEvt := evt.Event.(type) { case *signalpb.DataMessage: switch { case innerEvt.Reaction != nil: - targetAuthorACI = innerEvt.Reaction.GetTargetAuthorAci() + targetAuthorACI, _ = signalmeow.ParseStringOrBinaryUUID(innerEvt.Reaction.GetTargetAuthorAci(), innerEvt.Reaction.GetTargetAuthorAciBinary()) targetSentTS = innerEvt.Reaction.GetTargetSentTimestamp() case innerEvt.Delete != nil: targetSentTS = innerEvt.Delete.GetTargetSentTimestamp() @@ -310,11 +311,10 @@ func (evt *Bv2ChatEvent) GetTargetMessage() networkid.MessageID { default: return "" } - targetAuthorUUID := evt.Info.Sender - if targetAuthorACI != "" { - targetAuthorUUID, _ = uuid.Parse(targetAuthorACI) + if targetAuthorACI == uuid.Nil { + targetAuthorACI = evt.Info.Sender } - return signalid.MakeMessageID(targetAuthorUUID, targetSentTS) + return signalid.MakeMessageID(targetAuthorACI, targetSentTS) } func (evt *Bv2ChatEvent) GetReactionEmoji() (string, networkid.EmojiID) { @@ -537,6 +537,22 @@ func (s *SignalClient) addressableMessageToID(ctx context.Context, portalKey net return "" } return signalid.MakeMessageID(serviceID.UUID, am.GetSentTimestamp()) + case *signalpb.AddressableMessage_AuthorServiceIdBinary: + serviceID, err := libsignalgo.ServiceIDFromBytes(typedAuthor.AuthorServiceIdBinary) + if err != nil { + log.Err(err). + Object("portal_key", portalKey). + Hex("author_service_id_binary", typedAuthor.AuthorServiceIdBinary). + Msg("Failed to parse delete for me message author service ID") + return "" + } else if serviceID.Type != libsignalgo.ServiceIDTypeACI { + log.Warn(). + Object("portal_key", portalKey). + Hex("author_service_id_binary", typedAuthor.AuthorServiceIdBinary). + Msg("Dropping delete for me message with unsupported service ID type") + return "" + } + return signalid.MakeMessageID(serviceID.UUID, am.GetSentTimestamp()) case *signalpb.AddressableMessage_AuthorE164: log.Warn(). Object("portal_key", portalKey). diff --git a/pkg/libsignalgo/serviceid.go b/pkg/libsignalgo/serviceid.go index ae7cea7..21d64b2 100644 --- a/pkg/libsignalgo/serviceid.go +++ b/pkg/libsignalgo/serviceid.go @@ -87,6 +87,9 @@ func (s ServiceID) IsEmpty() bool { } func (s ServiceID) Address(deviceID uint) (*Address, error) { + if s.IsEmpty() { + return nil, fmt.Errorf("cannot create address from empty ServiceID") + } return newAddress(s.String(), deviceID) } @@ -158,6 +161,18 @@ func ServiceIDFromString(val string) (ServiceID, error) { } } +func ServiceIDFromBytes(bytes []byte) (ServiceID, error) { + if len(bytes) == 16 { + return NewACIServiceID(uuid.UUID(bytes)), nil + } else if len(bytes) == 17 { + return ServiceID{ + Type: ServiceIDType(bytes[0]), + UUID: uuid.UUID(bytes[1:]), + }, nil + } + return EmptyServiceID, fmt.Errorf("invalid ServiceID byte length: %d (expected 16 or 17)", len(bytes)) +} + func ServiceIDFromCFixedBytes(serviceID *C.SignalServiceIdFixedWidthBinaryBytes) ServiceID { var id ServiceID fixedBytes := (*ServiceIDFixedBytes)(unsafe.Pointer(serviceID)) diff --git a/pkg/msgconv/from-matrix.go b/pkg/msgconv/from-matrix.go index 67352f1..fa5deb4 100644 --- a/pkg/msgconv/from-matrix.go +++ b/pkg/msgconv/from-matrix.go @@ -62,7 +62,9 @@ func (mc *MessageConverter) ToSignal( dm.Quote = &signalpb.DataMessage_Quote{ Id: proto.Uint64(messageID), AuthorAci: proto.String(authorACI.String()), - Type: signalpb.DataMessage_Quote_NORMAL.Enum(), + // TODO update aci format + //AuthorAciBinary: authorACI[:], + Type: signalpb.DataMessage_Quote_NORMAL.Enum(), } if replyTo.Metadata.(*signalid.MessageMetadata).ContainsAttachments { dm.Quote.Attachments = make([]*signalpb.DataMessage_Quote_QuotedAttachment, 1) diff --git a/pkg/msgconv/from-signal.go b/pkg/msgconv/from-signal.go index c8ac40e..dadfe3f 100644 --- a/pkg/msgconv/from-signal.go +++ b/pkg/msgconv/from-signal.go @@ -174,7 +174,7 @@ func (mc *MessageConverter) ToMatrix( } } if dm.Quote != nil { - authorACI, err := uuid.Parse(dm.Quote.GetAuthorAci()) + authorACI, err := signalmeow.ParseStringOrBinaryUUID(dm.Quote.GetAuthorAci(), dm.Quote.GetAuthorAciBinary()) if err != nil { zerolog.Ctx(ctx).Err(err).Str("author_aci", dm.Quote.GetAuthorAci()).Msg("Failed to parse quote author ACI") } else { diff --git a/pkg/signalmeow/misc.go b/pkg/signalmeow/misc.go index 1bf88a3..467f646 100644 --- a/pkg/signalmeow/misc.go +++ b/pkg/signalmeow/misc.go @@ -18,7 +18,10 @@ package signalmeow import ( _ "embed" + "errors" + "fmt" + "github.com/google/uuid" "github.com/rs/zerolog" "go.mau.fi/util/exerrors" @@ -76,3 +79,28 @@ var prodServerPublicParams *libsignalgo.ServerPublicParams func init() { prodServerPublicParams = exerrors.Must(libsignalgo.DeserializeServerPublicParams(prodServerPublicParamsSlice)) } + +var ErrEmptyUUIDInput = errors.New("both input variables are empty") + +func ParseStringOrBinaryServiceID(str string, bytes []byte) (libsignalgo.ServiceID, error) { + if str != "" { + return libsignalgo.ServiceIDFromString(str) + } + if bytes != nil { + return libsignalgo.ServiceIDFromBytes(bytes) + } + return libsignalgo.EmptyServiceID, ErrEmptyUUIDInput +} + +func ParseStringOrBinaryUUID(str string, bytes []byte) (uuid.UUID, error) { + if str != "" { + return uuid.Parse(str) + } + if bytes != nil { + if len(bytes) != 16 { + return uuid.Nil, fmt.Errorf("invalid UUID length %d (expected 16)", len(bytes)) + } + return uuid.UUID(bytes), nil + } + return uuid.Nil, ErrEmptyUUIDInput +} diff --git a/pkg/signalmeow/receiving.go b/pkg/signalmeow/receiving.go index b802e06..2dd1d64 100644 --- a/pkg/signalmeow/receiving.go +++ b/pkg/signalmeow/receiving.go @@ -361,17 +361,21 @@ func (cli *Client) incomingAPIMessageHandler(ctx context.Context, req *signalpb. Uint64("server_timestamp", envelope.GetServerTimestamp()). Logger() ctx = log.WithContext(ctx) - destinationServiceID, err := libsignalgo.ServiceIDFromString(envelope.GetDestinationServiceId()) + destinationServiceID, _ := ParseStringOrBinaryServiceID(envelope.GetDestinationServiceId(), envelope.GetDestinationServiceIdBinary()) + sourceServiceID, _ := ParseStringOrBinaryServiceID(envelope.GetSourceServiceId(), envelope.GetSourceServiceIdBinary()) log.Debug(). Str("destination_service_id", envelope.GetDestinationServiceId()). Str("source_service_id", envelope.GetSourceServiceId()). + Hex("destination_service_id_bytes", envelope.GetDestinationServiceIdBinary()). + Hex("source_service_id_bytes", envelope.GetSourceServiceIdBinary()). Uint32("source_device_id", envelope.GetSourceDevice()). Object("parsed_destination_service_id", destinationServiceID). + Object("parsed_source_service_id", sourceServiceID). Int32("envelope_type_id", int32(envelope.GetType())). Str("envelope_type", signalpb.Envelope_Type_name[int32(envelope.GetType())]). Msg("Received envelope") - result := cli.decryptEnvelope(ctx, envelope) + result := cli.decryptEnvelope(ctx, envelope, sourceServiceID, destinationServiceID) err = cli.handleDecryptedResult(ctx, result, envelope, destinationServiceID) if err != nil { diff --git a/pkg/signalmeow/receiving_decrypt.go b/pkg/signalmeow/receiving_decrypt.go index 5c8da08..958f84f 100644 --- a/pkg/signalmeow/receiving_decrypt.go +++ b/pkg/signalmeow/receiving_decrypt.go @@ -50,13 +50,10 @@ type DecryptionResult struct { func (cli *Client) decryptEnvelope( ctx context.Context, envelope *signalpb.Envelope, + sourceServiceID, destinationServiceID libsignalgo.ServiceID, ) DecryptionResult { - log := zerolog.Ctx(ctx) - - destinationServiceID, err := libsignalgo.ServiceIDFromString(envelope.GetDestinationServiceId()) - if err != nil { - log.Err(err).Str("destination_service_id", envelope.GetDestinationServiceId()).Msg("Failed to parse destination service ID") - return DecryptionResult{Err: fmt.Errorf("failed to parse destination service ID: %w", err)} + if destinationServiceID.IsEmpty() { + return DecryptionResult{Err: fmt.Errorf("envelope missing destination service ID")} } switch *envelope.Type { @@ -68,10 +65,7 @@ func (cli *Client) decryptEnvelope( return result case signalpb.Envelope_PREKEY_BUNDLE, signalpb.Envelope_CIPHERTEXT: - sender, err := libsignalgo.NewUUIDAddressFromString( - *envelope.SourceServiceId, - uint(*envelope.SourceDevice), - ) + sender, err := sourceServiceID.Address(uint(envelope.GetSourceDevice())) if err != nil { return DecryptionResult{Err: fmt.Errorf("failed to wrap address: %v", err)} } @@ -96,7 +90,7 @@ func (cli *Client) decryptEnvelope( return *result case signalpb.Envelope_PLAINTEXT_CONTENT: - addr, err := libsignalgo.NewUUIDAddressFromString(envelope.GetSourceServiceId(), uint(envelope.GetSourceDevice())) + addr, err := sourceServiceID.Address(uint(envelope.GetSourceDevice())) if err != nil { return DecryptionResult{Err: fmt.Errorf("failed to wrap address: %v", err)} } From af5f936d3e9de27f0d4e7091e10fdb855eb28ae7 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Tue, 24 Feb 2026 13:48:39 +0200 Subject: [PATCH 524/580] signalmeow: add support for binary ACI field in sync messages --- pkg/signalmeow/receiving.go | 24 +++++++++--------------- pkg/signalmeow/sending.go | 32 ++++++++++++++++++++++---------- 2 files changed, 31 insertions(+), 25 deletions(-) diff --git a/pkg/signalmeow/receiving.go b/pkg/signalmeow/receiving.go index 2dd1d64..d3d039c 100644 --- a/pkg/signalmeow/receiving.go +++ b/pkg/signalmeow/receiving.go @@ -714,21 +714,15 @@ func (cli *Client) handleSyncMessage(ctx context.Context, msg *signalpb.SyncMess } syncSent := msg.GetSent() if syncSent.GetMessage() != nil || syncSent.GetEditMessage() != nil { - destination := syncSent.DestinationServiceId - var syncDestinationServiceID libsignalgo.ServiceID - if destination != nil { - var err error - syncDestinationServiceID, err = libsignalgo.ServiceIDFromString(*destination) + syncDestinationServiceID, err := ParseStringOrBinaryServiceID(syncSent.GetDestinationServiceId(), syncSent.GetDestinationServiceIdBinary()) + if err != nil && !errors.Is(err, ErrEmptyUUIDInput) { + log.Err(err).Msg("Sync message destination parse error") + } + if syncSent.GetDestinationE164() != "" && !syncDestinationServiceID.IsEmpty() { + aci, pni := syncDestinationServiceID.ToACIAndPNI() + _, err = cli.Store.RecipientStore.UpdateRecipientE164(ctx, aci, pni, syncSent.GetDestinationE164()) if err != nil { - log.Err(err).Msg("Sync message destination parse error") - return - } - if syncSent.GetDestinationE164() != "" { - aci, pni := syncDestinationServiceID.ToACIAndPNI() - _, err = cli.Store.RecipientStore.UpdateRecipientE164(ctx, aci, pni, syncSent.GetDestinationE164()) - if err != nil { - log.Err(err).Msg("Failed to update recipient E164 after receiving sync message") - } + log.Err(err).Msg("Failed to update recipient E164 after receiving sync message") } } for _, unident := range syncSent.GetUnidentifiedStatus() { @@ -744,7 +738,7 @@ func (cli *Client) handleSyncMessage(ctx context.Context, msg *signalpb.SyncMess } } - if destination == nil && syncSent.GetMessage().GetGroupV2() == nil && syncSent.GetEditMessage().GetDataMessage().GetGroupV2() == nil { + if syncDestinationServiceID.IsEmpty() && syncSent.GetMessage().GetGroupV2() == nil && syncSent.GetEditMessage().GetDataMessage().GetGroupV2() == nil { log.Warn().Msg("sync message sent destination is nil") } else if msg.Sent.Message != nil { // TODO handle expiration start ts, and maybe the sync message ts? diff --git a/pkg/signalmeow/sending.go b/pkg/signalmeow/sending.go index 8e6b892..86bc1db 100644 --- a/pkg/signalmeow/sending.go +++ b/pkg/signalmeow/sending.go @@ -307,7 +307,9 @@ func syncMessageFromGroupDataMessage(dataMessage *signalpb.DataMessage, results for _, result := range results { unidentifiedStatuses = append(unidentifiedStatuses, &signalpb.SyncMessage_Sent_UnidentifiedDeliveryStatus{ DestinationServiceId: proto.String(result.Recipient.String()), - Unidentified: &result.Unidentified, + // TODO update aci format + //DestinationServiceIdBinary: result.Recipient.Bytes(), + Unidentified: &result.Unidentified, }) } return &signalpb.Content{ @@ -326,7 +328,9 @@ func syncMessageFromGroupEditMessage(editMessage *signalpb.EditMessage, results for _, result := range results { unidentifiedStatuses = append(unidentifiedStatuses, &signalpb.SyncMessage_Sent_UnidentifiedDeliveryStatus{ DestinationServiceId: proto.String(result.Recipient.String()), - Unidentified: &result.Unidentified, + // TODO update aci format + //DestinationServiceIdBinary: result.Recipient.Bytes(), + Unidentified: &result.Unidentified, }) } return &signalpb.Content{ @@ -345,14 +349,18 @@ func syncMessageFromSoloDataMessage(dataMessage *signalpb.DataMessage, result Su return &signalpb.Content{ SyncMessage: &signalpb.SyncMessage{ Sent: &signalpb.SyncMessage_Sent{ - Message: dataMessage, - DestinationE164: result.RecipientE164, - DestinationServiceId: proto.String(result.Recipient.String()), + Message: dataMessage, + DestinationE164: result.RecipientE164, + DestinationServiceId: proto.String(result.Recipient.String()), + // TODO update aci format + //DestinationServiceIdBinary: result.Recipient.Bytes(), Timestamp: dataMessage.Timestamp, ExpirationStartTimestamp: ptr.Ptr(uint64(time.Now().UnixMilli())), UnidentifiedStatus: []*signalpb.SyncMessage_Sent_UnidentifiedDeliveryStatus{ { - DestinationServiceId: proto.String(result.Recipient.String()), + DestinationServiceId: proto.String(result.Recipient.String()), + // TODO update aci format + //DestinationServiceIdBinary: result.Recipient.Bytes(), Unidentified: &result.Unidentified, DestinationPniIdentityKey: result.DestinationPNIIdentityKey.TrySerialize(), }, @@ -366,14 +374,18 @@ func syncMessageFromSoloEditMessage(editMessage *signalpb.EditMessage, result Su return &signalpb.Content{ SyncMessage: &signalpb.SyncMessage{ Sent: &signalpb.SyncMessage_Sent{ - EditMessage: editMessage, - DestinationE164: result.RecipientE164, - DestinationServiceId: proto.String(result.Recipient.String()), + EditMessage: editMessage, + DestinationE164: result.RecipientE164, + DestinationServiceId: proto.String(result.Recipient.String()), + // TODO update aci format + //DestinationServiceIdBinary: result.Recipient.Bytes(), Timestamp: editMessage.DataMessage.Timestamp, ExpirationStartTimestamp: ptr.Ptr(uint64(time.Now().UnixMilli())), UnidentifiedStatus: []*signalpb.SyncMessage_Sent_UnidentifiedDeliveryStatus{ { - DestinationServiceId: proto.String(result.Recipient.String()), + DestinationServiceId: proto.String(result.Recipient.String()), + // TODO update aci format + //DestinationServiceIdBinary: result.Recipient.Bytes(), Unidentified: &result.Unidentified, DestinationPniIdentityKey: result.DestinationPNIIdentityKey.TrySerialize(), }, From 09ba9d04b2b1f9e6d44fa93cbabc009ec8851962 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Tue, 24 Feb 2026 14:05:11 +0200 Subject: [PATCH 525/580] signalmeow/receiving: add support for binary ACI field in unidentified send statuses --- pkg/signalmeow/receiving.go | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/pkg/signalmeow/receiving.go b/pkg/signalmeow/receiving.go index d3d039c..3d81259 100644 --- a/pkg/signalmeow/receiving.go +++ b/pkg/signalmeow/receiving.go @@ -726,14 +726,22 @@ func (cli *Client) handleSyncMessage(ctx context.Context, msg *signalpb.SyncMess } } for _, unident := range syncSent.GetUnidentifiedStatus() { - changed, err := cli.saveSyncPNIIdentityKey(ctx, unident.GetDestinationServiceId(), unident.GetDestinationPniIdentityKey()) + serviceID, err := ParseStringOrBinaryServiceID(unident.GetDestinationServiceId(), unident.GetDestinationServiceIdBinary()) if err != nil { log.Err(err). Str("destination_service_id", unident.GetDestinationServiceId()). + Hex("destination_service_id_bytes", unident.GetDestinationServiceIdBinary()). + Msg("Failed to parse destination service ID of unidentified send") + continue + } + changed, err := cli.saveSyncPNIIdentityKey(ctx, serviceID, unident.GetDestinationPniIdentityKey()) + if err != nil { + log.Err(err). + Stringer("destination_service_id", serviceID). Msg("Failed to save PNI identity key from sync message") } else if changed { log.Debug(). - Str("destination_service_id", unident.GetDestinationServiceId()). + Stringer("destination_service_id", serviceID). Msg("Saved new PNI identity key from sync message") } } @@ -828,20 +836,14 @@ func (cli *Client) handleSyncMessage(ctx context.Context, msg *signalpb.SyncMess return } -func (cli *Client) saveSyncPNIIdentityKey(ctx context.Context, serviceIDString string, identityKeyBytes []byte) (bool, error) { - if identityKeyBytes == nil { +func (cli *Client) saveSyncPNIIdentityKey(ctx context.Context, serviceID libsignalgo.ServiceID, identityKeyBytes []byte) (bool, error) { + if identityKeyBytes == nil || serviceID.Type != libsignalgo.ServiceIDTypePNI { return false, nil } identityKey, err := libsignalgo.DeserializeIdentityKey(identityKeyBytes) if err != nil { return false, fmt.Errorf("failed to deserialize PNI identity key: %w", err) } - serviceID, err := libsignalgo.ServiceIDFromString(serviceIDString) - if err != nil { - return false, fmt.Errorf("failed to parse PNI service ID: %w", err) - } else if serviceID.Type != libsignalgo.ServiceIDTypePNI { - return false, nil - } changed, err := cli.Store.IdentityKeyStore.SaveIdentityKey(ctx, serviceID, identityKey) if err != nil { return false, fmt.Errorf("failed to save PNI identity key: %w", err) From ee306f5221ad9d259d94532c35b20dc372a8c82a Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Fri, 27 Feb 2026 14:52:27 +0200 Subject: [PATCH 526/580] libsignal: update to v0.87.5 --- pkg/libsignalgo/libsignal | 2 +- pkg/libsignalgo/version.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pkg/libsignalgo/libsignal b/pkg/libsignalgo/libsignal index f08390b..ffaa9f0 160000 --- a/pkg/libsignalgo/libsignal +++ b/pkg/libsignalgo/libsignal @@ -1 +1 @@ -Subproject commit f08390b0e2f67d5faf47bb9d1a3db191314db93c +Subproject commit ffaa9f0435569d6775d8be636f268f882ed67ce3 diff --git a/pkg/libsignalgo/version.go b/pkg/libsignalgo/version.go index 8f445ad..bb1774c 100644 --- a/pkg/libsignalgo/version.go +++ b/pkg/libsignalgo/version.go @@ -2,4 +2,4 @@ package libsignalgo -const Version = "v0.87.1" +const Version = "v0.87.5" From 2447903e036c1e77ccf0ccf8c5d541d931d7220a Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Fri, 27 Feb 2026 15:26:42 +0200 Subject: [PATCH 527/580] libsignalgo: add -lstdc++ to cflags --- pkg/libsignalgo/cflags.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/libsignalgo/cflags.go b/pkg/libsignalgo/cflags.go index 12c1e0c..e1bb7d5 100644 --- a/pkg/libsignalgo/cflags.go +++ b/pkg/libsignalgo/cflags.go @@ -1,6 +1,6 @@ package libsignalgo /* -#cgo LDFLAGS: -lsignal_ffi -ldl -lm -lz +#cgo LDFLAGS: -lsignal_ffi -ldl -lm -lz -lstdc++ */ import "C" From 6a6e5d50dfe7416cf56874baa41b5d76b053295b Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Fri, 27 Feb 2026 17:36:33 +0200 Subject: [PATCH 528/580] Bump version to v26.02.1 --- CHANGELOG.md | 5 +++++ cmd/mautrix-signal/main.go | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f18590b..7c6869c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,8 @@ +# v26.02.1 + +* Updated libsignal to v0.87.5. +* Added support for new binary service ID fields that Signal 8.0 switched to. + # v26.02 * Bumped minimum Go version to 1.25. diff --git a/cmd/mautrix-signal/main.go b/cmd/mautrix-signal/main.go index 064b1e0..ab7fd46 100644 --- a/cmd/mautrix-signal/main.go +++ b/cmd/mautrix-signal/main.go @@ -37,7 +37,7 @@ var m = mxmain.BridgeMain{ Name: "mautrix-signal", URL: "https://github.com/mautrix/signal", Description: "A Matrix-Signal puppeting bridge.", - Version: "26.02", + Version: "26.02.1", SemCalVer: true, Connector: &connector.SignalConnector{}, From cc4b81da6c760f204df7dc57094b6d22c13b80bb Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Sat, 28 Feb 2026 12:08:26 +0200 Subject: [PATCH 529/580] handlesignal: add support for binary service IDs in delete for me events Fixes #638 --- pkg/connector/handlesignal.go | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/pkg/connector/handlesignal.go b/pkg/connector/handlesignal.go index f248d48..843dd10 100644 --- a/pkg/connector/handlesignal.go +++ b/pkg/connector/handlesignal.go @@ -499,6 +499,13 @@ func (s *SignalClient) conversationIDToPortalKey(ctx context.Context, cid *signa return networkid.PortalKey{}, false } return s.makeDMPortalKey(serviceID), true + case *signalpb.ConversationIdentifier_ThreadServiceIdBinary: + serviceID, err := libsignalgo.ServiceIDFromBytes(ident.ThreadServiceIdBinary) + if err != nil { + log.Err(err).Hex("chat_id", ident.ThreadServiceIdBinary).Msg("Failed to parse delete for me conversation ID") + return networkid.PortalKey{}, false + } + return s.makeDMPortalKey(serviceID), true case *signalpb.ConversationIdentifier_ThreadGroupId: if len(ident.ThreadGroupId) != libsignalgo.GroupIdentifierLength { log.Error(). From 0442a32f6816cead7cc91f8f8d36c5b8f2006a47 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Sat, 28 Feb 2026 12:27:46 +0200 Subject: [PATCH 530/580] handlesignal,msgconv,signalmeow: add support for remaining binary ACI fields --- pkg/connector/handlesignal.go | 2 +- pkg/msgconv/msgconv.go | 4 ++-- pkg/msgconv/signalfmt/convert.go | 15 ++++++++++++--- pkg/signalmeow/contact.go | 2 +- pkg/signalmeow/receiving.go | 2 +- 5 files changed, 17 insertions(+), 8 deletions(-) diff --git a/pkg/connector/handlesignal.go b/pkg/connector/handlesignal.go index 843dd10..bc0dbe3 100644 --- a/pkg/connector/handlesignal.go +++ b/pkg/connector/handlesignal.go @@ -480,7 +480,7 @@ func (s *SignalClient) handleSignalReadSelf(evt *events.ReadSelf) bool { Logger() ctx := log.WithContext(context.TODO()) receipts := convertReceipts(ctx, evt.Messages, func(ctx context.Context, msgInfo *signalpb.SyncMessage_Read) (*database.Message, error) { - aciUUID, err := uuid.Parse(msgInfo.GetSenderAci()) + aciUUID, err := signalmeow.ParseStringOrBinaryUUID(msgInfo.GetSenderAci(), msgInfo.GetSenderAciBinary()) if err != nil { return nil, err } diff --git a/pkg/msgconv/msgconv.go b/pkg/msgconv/msgconv.go index 1b8564a..e312a1f 100644 --- a/pkg/msgconv/msgconv.go +++ b/pkg/msgconv/msgconv.go @@ -78,7 +78,7 @@ func NewMessageConverter(br *bridgev2.Bridge) *MessageConverter { GetUUIDFromMXID: func(ctx context.Context, userID id.UserID) uuid.UUID { parsed, ok := br.Matrix.ParseGhostMXID(userID) if ok { - u, _ := uuid.Parse(string(parsed)) + u, _ := signalid.ParseUserID(parsed) return u } user, _ := br.GetExistingUserByMXID(ctx, userID) @@ -86,7 +86,7 @@ func NewMessageConverter(br *bridgev2.Bridge) *MessageConverter { if user != nil { preferredLogin, _, _ := getPortal(ctx).FindPreferredLogin(ctx, user, true) if preferredLogin != nil { - u, _ := uuid.Parse(string(preferredLogin.ID)) + u, _ := signalid.ParseUserLoginID(preferredLogin.ID) return u } } diff --git a/pkg/msgconv/signalfmt/convert.go b/pkg/msgconv/signalfmt/convert.go index f950a59..5a9b520 100644 --- a/pkg/msgconv/signalfmt/convert.go +++ b/pkg/msgconv/signalfmt/convert.go @@ -85,15 +85,24 @@ func Parse(ctx context.Context, message string, ranges []*signalpb.BodyRange, pa Start: int(*r.Start), Length: int(*r.Length), }.TruncateEnd(maxLength) + var mentionACI uuid.UUID switch rv := r.GetAssociatedValue().(type) { case *signalpb.BodyRange_Style_: br.Value = Style(rv.Style) case *signalpb.BodyRange_MentionAci: - parsed, err := uuid.Parse(rv.MentionAci) + var err error + mentionACI, err = uuid.Parse(rv.MentionAci) if err != nil { continue } - userInfo := params.GetUserInfo(ctx, parsed) + case *signalpb.BodyRange_MentionAciBinary: + if len(rv.MentionAciBinary) != 16 { + continue + } + mentionACI = uuid.UUID(rv.MentionAciBinary) + } + if mentionACI != uuid.Nil { + userInfo := params.GetUserInfo(ctx, mentionACI) if userInfo.MXID == "" { continue } @@ -102,7 +111,7 @@ func Parse(ctx context.Context, message string, ranges []*signalpb.BodyRange, pa // Maybe use NewUTF16String and do index replacements for the plaintext body too, // or just replace the plaintext body by parsing the generated HTML. content.Body = strings.Replace(content.Body, "\uFFFC", userInfo.Name, 1) - br.Value = Mention{UserInfo: userInfo, UUID: parsed} + br.Value = Mention{UserInfo: userInfo, UUID: mentionACI} } lrt.Add(br) } diff --git a/pkg/signalmeow/contact.go b/pkg/signalmeow/contact.go index 8407b74..f30f54f 100644 --- a/pkg/signalmeow/contact.go +++ b/pkg/signalmeow/contact.go @@ -36,7 +36,7 @@ import ( ) func (cli *Client) StoreContactDetailsAsContact(ctx context.Context, contactDetails *signalpb.ContactDetails, avatar *[]byte) (*types.Recipient, error) { - parsedUUID, err := uuid.Parse(contactDetails.GetAci()) + parsedUUID, err := ParseStringOrBinaryUUID(contactDetails.GetAci(), contactDetails.GetAciBinary()) if err != nil { return nil, err } diff --git a/pkg/signalmeow/receiving.go b/pkg/signalmeow/receiving.go index 3d81259..142bc0f 100644 --- a/pkg/signalmeow/receiving.go +++ b/pkg/signalmeow/receiving.go @@ -809,7 +809,7 @@ func (cli *Client) handleSyncMessage(ctx context.Context, msg *signalpb.SyncMess }) } if msg.MessageRequestResponse != nil { - aciUUID, _ := uuid.Parse(msg.MessageRequestResponse.GetThreadAci()) + aciUUID, _ := ParseStringOrBinaryUUID(msg.MessageRequestResponse.GetThreadAci(), msg.MessageRequestResponse.GetThreadAciBinary()) if aciUUID != uuid.Nil && msg.MessageRequestResponse.GetType() == signalpb.SyncMessage_MessageRequestResponse_ACCEPT { _, err := cli.Store.RecipientStore.LoadAndUpdateRecipient(ctx, aciUUID, uuid.Nil, func(recipient *types.Recipient) (changed bool, err error) { changed = !ptr.Val(recipient.Whitelisted) || recipient.NeedsPNISignature From d9dc134b9640bd1ec432f43254e7afcfcf635287 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Sat, 28 Feb 2026 12:35:29 +0200 Subject: [PATCH 531/580] login: fix context used for background connection --- pkg/connector/login.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/connector/login.go b/pkg/connector/login.go index 5cfdae1..9116390 100644 --- a/pkg/connector/login.go +++ b/pkg/connector/login.go @@ -75,7 +75,7 @@ func (qr *QRLogin) Start(ctx context.Context) (*bridgev2.LoginStep, error) { Str("action", "login"). Stringer("user_id", qr.User.MXID). Logger() - provCtx, cancel := context.WithCancel(log.WithContext(context.Background())) + provCtx, cancel := context.WithCancel(log.WithContext(qr.Main.Bridge.BackgroundCtx)) qr.cancelChan = cancel // Don't use the start context here: the channel will outlive the start request. qr.ProvChan = signalmeow.PerformProvisioning( From 7e72153efb6cb26f8bf2b3c3a434a0927fdc0717 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Mon, 2 Mar 2026 14:25:40 +0200 Subject: [PATCH 532/580] msgconv/signalfmt: ignore unsupported body ranges --- pkg/msgconv/signalfmt/convert.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/pkg/msgconv/signalfmt/convert.go b/pkg/msgconv/signalfmt/convert.go index 5a9b520..412af36 100644 --- a/pkg/msgconv/signalfmt/convert.go +++ b/pkg/msgconv/signalfmt/convert.go @@ -23,6 +23,7 @@ import ( "strings" "github.com/google/uuid" + "github.com/rs/zerolog" "golang.org/x/exp/maps" "maunium.net/go/mautrix/event" "maunium.net/go/mautrix/id" @@ -100,6 +101,9 @@ func Parse(ctx context.Context, message string, ranges []*signalpb.BodyRange, pa continue } mentionACI = uuid.UUID(rv.MentionAciBinary) + default: + zerolog.Ctx(ctx).Warn().Type("value_type", rv).Msg("Unsupported body range type") + continue } if mentionACI != uuid.Nil { userInfo := params.GetUserInfo(ctx, mentionACI) From 509dfbde0a96813d837bd7bb54140dc84ce893d6 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Mon, 2 Mar 2026 14:30:01 +0200 Subject: [PATCH 533/580] Bump version to v26.02.2 --- CHANGELOG.md | 4 ++++ cmd/mautrix-signal/main.go | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7c6869c..dd0a2d4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +# v26.02.2 + +* Added support for more new binary service ID fields. + # v26.02.1 * Updated libsignal to v0.87.5. diff --git a/cmd/mautrix-signal/main.go b/cmd/mautrix-signal/main.go index ab7fd46..7f1d5fe 100644 --- a/cmd/mautrix-signal/main.go +++ b/cmd/mautrix-signal/main.go @@ -37,7 +37,7 @@ var m = mxmain.BridgeMain{ Name: "mautrix-signal", URL: "https://github.com/mautrix/signal", Description: "A Matrix-Signal puppeting bridge.", - Version: "26.02.1", + Version: "26.02.2", SemCalVer: true, Connector: &connector.SignalConnector{}, From cb7849efd6b1918f07faf4129b58588160941b46 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Fri, 6 Mar 2026 00:12:23 +0200 Subject: [PATCH 534/580] signalmeow,msgconv/from-signal: add support for transferring attachments via disk --- go.mod | 6 +- go.sum | 12 +-- pkg/connector/directmedia.go | 16 ++-- pkg/msgconv/from-signal.go | 108 +++++++++++++++++-------- pkg/signalmeow/attachments.go | 143 ++++++++++++++++++++++++++++++++-- pkg/signalmeow/receiving.go | 3 +- 6 files changed, 229 insertions(+), 59 deletions(-) diff --git a/go.mod b/go.mod index 3b6cc07..6758d92 100644 --- a/go.mod +++ b/go.mod @@ -16,15 +16,15 @@ require ( github.com/tidwall/gjson v1.18.0 go.mau.fi/util v0.9.6 golang.org/x/crypto v0.48.0 - golang.org/x/exp v0.0.0-20260212183809-81e46e3db34a + golang.org/x/exp v0.0.0-20260218203240-3dfff04db8fa golang.org/x/net v0.50.0 google.golang.org/protobuf v1.36.11 gopkg.in/yaml.v3 v3.0.1 - maunium.net/go/mautrix v0.26.3 + maunium.net/go/mautrix v0.26.4-0.20260305215735-7836f35a1a74 ) require ( - filippo.io/edwards25519 v1.1.0 // indirect + filippo.io/edwards25519 v1.2.0 // indirect github.com/coreos/go-systemd/v22 v22.6.0 // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/kr/pretty v0.3.1 // indirect diff --git a/go.sum b/go.sum index 26c13e2..78bfb4e 100644 --- a/go.sum +++ b/go.sum @@ -1,5 +1,5 @@ -filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA= -filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4= +filippo.io/edwards25519 v1.2.0 h1:crnVqOiS4jqYleHd9vaKZ+HKtHfllngJIiOpNpoJsjo= +filippo.io/edwards25519 v1.2.0/go.mod h1:xzAOLCNug/yB62zG1bQ8uziwrIqIuxhctzJT18Q77mc= github.com/DATA-DOG/go-sqlmock v1.5.2 h1:OcvFkGmslmlZibjAjaHm3L//6LiuBgolP7OputlJIzU= github.com/DATA-DOG/go-sqlmock v1.5.2/go.mod h1:88MAG/4G7SMwSE3CeA0ZKzrT5CiOU3OJ+JlNzwDqpNU= github.com/coder/websocket v1.8.14 h1:9L0p0iKiNOibykf283eHkKUHHrpG7f65OE3BhhO7v9g= @@ -73,8 +73,8 @@ go.mau.fi/zeroconfig v0.2.0 h1:e/OGEERqVRRKlgaro7E6bh8xXiKFSXB3eNNIud7FUjU= go.mau.fi/zeroconfig v0.2.0/go.mod h1:J0Vn0prHNOm493oZoQ84kq83ZaNCYZnq+noI1b1eN8w= golang.org/x/crypto v0.48.0 h1:/VRzVqiRSggnhY7gNRxPauEQ5Drw9haKdM0jqfcCFts= golang.org/x/crypto v0.48.0/go.mod h1:r0kV5h3qnFPlQnBSrULhlsRfryS2pmewsg+XfMgkVos= -golang.org/x/exp v0.0.0-20260212183809-81e46e3db34a h1:ovFr6Z0MNmU7nH8VaX5xqw+05ST2uO1exVfZPVqRC5o= -golang.org/x/exp v0.0.0-20260212183809-81e46e3db34a/go.mod h1:K79w1Vqn7PoiZn+TkNpx3BUWUQksGO3JcVX6qIjytmA= +golang.org/x/exp v0.0.0-20260218203240-3dfff04db8fa h1:Zt3DZoOFFYkKhDT3v7Lm9FDMEV06GpzjG2jrqW+QTE0= +golang.org/x/exp v0.0.0-20260218203240-3dfff04db8fa/go.mod h1:K79w1Vqn7PoiZn+TkNpx3BUWUQksGO3JcVX6qIjytmA= golang.org/x/mod v0.33.0 h1:tHFzIWbBifEmbwtGz65eaWyGiGZatSrT9prnU8DbVL8= golang.org/x/mod v0.33.0/go.mod h1:swjeQEj+6r7fODbD2cqrnje9PnziFuw4bmLbBZFrQ5w= golang.org/x/net v0.50.0 h1:ucWh9eiCGyDR3vtzso0WMQinm2Dnt8cFMuQa9K33J60= @@ -99,5 +99,5 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= maunium.net/go/mauflag v1.0.0 h1:YiaRc0tEI3toYtJMRIfjP+jklH45uDHtT80nUamyD4M= maunium.net/go/mauflag v1.0.0/go.mod h1:nLivPOpTpHnpzEh8jEdSL9UqO9+/KBJFmNRlwKfkPeA= -maunium.net/go/mautrix v0.26.3 h1:tWZih6Vjw0qGTWuPmg9JUrQPzViTNDPGQLVc5UXC4nk= -maunium.net/go/mautrix v0.26.3/go.mod h1:v5ZdDoCwUpNqEj5OrhEoUa3L1kEddKPaAya9TgGXN38= +maunium.net/go/mautrix v0.26.4-0.20260305215735-7836f35a1a74 h1:kHlana4CKRoAzPGbagU82y+uN4k5Tvfwt1nyj3cJHEw= +maunium.net/go/mautrix v0.26.4-0.20260305215735-7836f35a1a74/go.mod h1:lJvXCZya2dGT2KW7LUO7Ucna7Ohs6hl2+7v8Ji6R3iM= diff --git a/pkg/connector/directmedia.go b/pkg/connector/directmedia.go index 6f31e15..0877d66 100644 --- a/pkg/connector/directmedia.go +++ b/pkg/connector/directmedia.go @@ -5,6 +5,7 @@ import ( "encoding/base64" "fmt" "io" + "os" "maunium.net/go/mautrix/bridgev2" "maunium.net/go/mautrix/bridgev2/networkid" @@ -41,18 +42,15 @@ func (s *SignalConnector) Download(ctx context.Context, mediaID networkid.MediaI Uint32("size", info.Size). Msg("Direct downloading attachment") - return &mediaproxy.GetMediaResponseCallback{ - Callback: func(w io.Writer) (int64, error) { - data, err := signalmeow.DownloadAttachment( - ctx, info.CDNID, info.CDNKey, info.CDNNumber, info.Key, info.Digest, info.PlaintextDigest, info.Size, + return &mediaproxy.GetMediaResponseFile{ + Callback: func(w *os.File) (*mediaproxy.FileMeta, error) { + _, err := signalmeow.DownloadAttachment( + ctx, info.CDNID, info.CDNKey, info.CDNNumber, info.Key, info.Digest, info.PlaintextDigest, info.Size, w, ) if err != nil { - log.Err(err).Msg("Direct download failed") - return 0, err + return nil, err } - - _, err = w.Write(data) - return int64(info.Size), err + return &mediaproxy.FileMeta{}, nil }, }, nil case *signalid.DirectMediaGroupAvatar: diff --git a/pkg/msgconv/from-signal.go b/pkg/msgconv/from-signal.go index dadfe3f..4119cc5 100644 --- a/pkg/msgconv/from-signal.go +++ b/pkg/msgconv/from-signal.go @@ -22,7 +22,9 @@ import ( "encoding/base64" "errors" "fmt" + "io" "net/http" + "os" "strconv" "strings" "time" @@ -76,6 +78,7 @@ func CanConvertSignal(dm *signalpb.DataMessage) bool { } const ViewOnceDisappearTimer = 5 * time.Minute +const matrixTextMaxLength = 30000 // approximate value to avoid hitting 64 KiB PDU size limit with HTML duplication func (mc *MessageConverter) ToMatrix( ctx context.Context, @@ -123,7 +126,7 @@ func (mc *MessageConverter) ToMatrix( return cm } for i, att := range dm.GetAttachments() { - if att.GetContentType() != "text/x-signal-plain" { + if att.GetContentType() != "text/x-signal-plain" || att.GetSize() > matrixTextMaxLength { cm.Parts = append(cm.Parts, mc.convertAttachmentToMatrix(ctx, i, att, attMap)) } else { longBody, err := mc.downloadSignalLongText(ctx, att, attMap) @@ -337,7 +340,7 @@ func (mc *MessageConverter) convertContactToVCard(ctx context.Context, contact * card.Add(vcard.FieldTelephone, &field) } if contact.GetAvatar().GetAvatar() != nil { - avatarData, err := mc.downloadAttachment(ctx, contact.GetAvatar().GetAvatar(), attMap) + avatarData, err := mc.downloadAttachment(ctx, contact.GetAvatar().GetAvatar(), attMap, nil) if err != nil { zerolog.Ctx(ctx).Err(err).Msg("Failed to download contact avatar") } else { @@ -480,7 +483,7 @@ func (mc *MessageConverter) convertStickerToMatrix(ctx context.Context, sticker } func (mc *MessageConverter) downloadSignalLongText(ctx context.Context, att *signalpb.AttachmentPointer, attMap AttachmentMap) (*string, error) { - data, err := mc.downloadAttachment(ctx, att, attMap) + data, err := mc.downloadAttachment(ctx, att, attMap, nil) if err != nil { return nil, err } @@ -506,7 +509,9 @@ func checkIfAttachmentExists(att *signalpb.AttachmentPointer, attMap AttachmentM return nil } -func (mc *MessageConverter) downloadAttachment(ctx context.Context, att *signalpb.AttachmentPointer, attMap AttachmentMap) ([]byte, error) { +func (mc *MessageConverter) downloadAttachment( + ctx context.Context, att *signalpb.AttachmentPointer, attMap AttachmentMap, into *os.File, +) ([]byte, error) { if err := checkIfAttachmentExists(att, attMap); err != nil { return nil, err } @@ -517,19 +522,19 @@ func (mc *MessageConverter) downloadAttachment(ctx context.Context, att *signalp plaintextHash = target.GetPlaintextHash() } } - return signalmeow.DownloadAttachmentWithPointer(ctx, att, plaintextHash) + return signalmeow.DownloadAttachmentWithPointer(ctx, att, plaintextHash, into) } func (mc *MessageConverter) reuploadAttachment(ctx context.Context, att *signalpb.AttachmentPointer, attMap AttachmentMap) (*bridgev2.ConvertedMessagePart, error) { - fileName := att.GetFileName() content := &event.MessageEventContent{ + Body: att.GetFileName(), Info: &event.FileInfo{ - Width: int(att.GetWidth()), - Height: int(att.GetHeight()), - Size: int(att.GetSize()), + MimeType: att.GetContentType(), + Width: int(att.GetWidth()), + Height: int(att.GetHeight()), + Size: int(att.GetSize()), }, } - mimeType := att.GetContentType() if err := checkIfAttachmentExists(att, attMap); err != nil { return nil, err } else if mc.DirectMedia { @@ -556,25 +561,7 @@ func (mc *MessageConverter) reuploadAttachment(ctx context.Context, att *signalp } content.URL, err = mc.Bridge.Matrix.GenerateContentURI(ctx, mediaID) } else { - data, err := mc.downloadAttachment(ctx, att, attMap) - if err != nil { - return nil, err - } - if mimeType == "" { - mimeType = http.DetectContentType(data) - } - if att.GetFlags()&uint32(signalpb.AttachmentPointer_VOICE_MESSAGE) != 0 && ffmpeg.Supported() { - data, err = ffmpeg.ConvertBytes(ctx, data, ".ogg", []string{}, []string{"-c:a", "libopus"}, mimeType) - if err != nil { - return nil, fmt.Errorf("failed to convert audio to ogg/opus: %w", err) - } - fileName += ".ogg" - mimeType = "audio/ogg" - content.MSC3245Voice = &event.MSC3245Voice{} - // TODO include duration here (and in info) if there's some easy way to extract it with ffmpeg - //content.MSC1767Audio = &event.MSC1767Audio{} - } - content.URL, content.File, err = getIntent(ctx).UploadMedia(ctx, getPortal(ctx).MXID, data, fileName, mimeType) + err = mc.actuallyReuploadAttachment(ctx, content, att, attMap) if err != nil { return nil, err } @@ -583,7 +570,7 @@ func (mc *MessageConverter) reuploadAttachment(ctx context.Context, att *signalp content.Info.Blurhash = att.GetBlurHash() content.Info.AnoaBlurhash = att.GetBlurHash() } - switch strings.Split(mimeType, "/")[0] { + switch strings.Split(content.Info.MimeType, "/")[0] { case "image": content.MsgType = event.MsgImage case "video": @@ -605,10 +592,8 @@ func (mc *MessageConverter) reuploadAttachment(ctx context.Context, att *signalp }, } } - content.Body = fileName - content.Info.MimeType = mimeType if content.Body == "" { - content.Body = strings.TrimPrefix(string(content.MsgType), "m.") + exmime.ExtensionFromMimetype(mimeType) + content.Body = strings.TrimPrefix(string(content.MsgType), "m.") + exmime.ExtensionFromMimetype(content.Info.MimeType) } return &bridgev2.ConvertedMessagePart{ Type: event.EventMessage, @@ -617,6 +602,63 @@ func (mc *MessageConverter) reuploadAttachment(ctx context.Context, att *signalp }, nil } +func (mc *MessageConverter) actuallyReuploadAttachment( + ctx context.Context, + content *event.MessageEventContent, + att *signalpb.AttachmentPointer, + attMap AttachmentMap, +) (err error) { + convertVoice := att.GetFlags()&uint32(signalpb.AttachmentPointer_VOICE_MESSAGE) != 0 && ffmpeg.Supported() + requireFile := convertVoice + content.URL, content.File, err = getIntent(ctx).UploadMediaStream(ctx, getPortal(ctx).MXID, int64(att.GetSize()), requireFile, func(file io.Writer) (*bridgev2.FileStreamResult, error) { + osFile, ok := file.(*os.File) + inMemData, err := mc.downloadAttachment(ctx, att, attMap, osFile) + if err != nil { + return nil, err + } else if !ok { + if content.Info.MimeType == "" { + content.Info.MimeType = http.DetectContentType(inMemData) + } + _, err = file.Write(inMemData) + return &bridgev2.FileStreamResult{ + FileName: content.Body, + MimeType: content.Info.MimeType, + }, err + } + if content.Info.MimeType == "" { + header := make([]byte, 512) + _, err = osFile.ReadAt(header, 0) + if err != nil { + return nil, fmt.Errorf("failed to read file header for MIME type detection: %w", err) + } else { + content.Info.MimeType = http.DetectContentType(header) + } + } + var replFile string + if att.GetFlags()&uint32(signalpb.AttachmentPointer_VOICE_MESSAGE) != 0 && ffmpeg.Supported() { + replFile, err = ffmpeg.ConvertPath(ctx, osFile.Name(), ".ogg", []string{}, []string{"-c:a", "libopus"}, true) + if err != nil { + return nil, fmt.Errorf("failed to convert audio to ogg/opus: %w", err) + } + if content.Body == "" { + content.Body = "Voice message.ogg" + } else { + content.Body += ".ogg" + } + content.Info.MimeType = "audio/ogg" + content.MSC3245Voice = &event.MSC3245Voice{} + // TODO include duration here (and in info) if there's some easy way to extract it with ffmpeg + //content.MSC1767Audio = &event.MSC1767Audio{} + } + return &bridgev2.FileStreamResult{ + ReplacementFile: replFile, + FileName: content.Body, + MimeType: content.Info.MimeType, + }, nil + }) + return +} + func (mc *MessageConverter) convertPollCreateToMatrix(create *signalpb.DataMessage_PollCreate) *bridgev2.ConvertedMessagePart { evtType := event.EventMessage if mc.ExtEvPolls { diff --git a/pkg/signalmeow/attachments.go b/pkg/signalmeow/attachments.go index 6b78c68..2c8f1ea 100644 --- a/pkg/signalmeow/attachments.go +++ b/pkg/signalmeow/attachments.go @@ -31,8 +31,10 @@ import ( "math" "mime/multipart" "net/http" + "os" "github.com/rs/zerolog" + "go.mau.fi/util/fallocate" "go.mau.fi/util/random" "google.golang.org/protobuf/proto" @@ -59,25 +61,48 @@ var ErrInvalidMACForAttachment = errors.New("invalid MAC for attachment") var ErrInvalidDigestForAttachment = errors.New("invalid digest for attachment") var ErrAttachmentNotFound = errors.New("attachment not found on server") -func DownloadAttachmentWithPointer(ctx context.Context, a *signalpb.AttachmentPointer, plaintextHash []byte) ([]byte, error) { +func DownloadAttachmentWithPointer(ctx context.Context, a *signalpb.AttachmentPointer, plaintextHash []byte, into *os.File) ([]byte, error) { digest := a.GetDigest() plaintextDigest := false if digest == nil && plaintextHash != nil { digest = plaintextHash plaintextDigest = true } - return DownloadAttachment(ctx, a.GetCdnId(), a.GetCdnKey(), a.GetCdnNumber(), a.Key, digest, plaintextDigest, a.GetSize()) + return DownloadAttachment( + ctx, a.GetCdnId(), a.GetCdnKey(), a.GetCdnNumber(), a.Key, digest, plaintextDigest, a.GetSize(), into, + ) } -func DownloadAttachment(ctx context.Context, cdnID uint64, cdnKey string, cdnNumber uint32, key, digest []byte, plaintextDigest bool, size uint32) ([]byte, error) { +func DownloadAttachment( + ctx context.Context, + cdnID uint64, + cdnKey string, + cdnNumber uint32, + key, digest []byte, + plaintextDigest bool, + size uint32, + into *os.File, +) ([]byte, error) { resp, err := web.GetAttachment(ctx, getAttachmentPath(cdnID, cdnKey), cdnNumber) if err != nil { return nil, err } - bodyReader := resp.Body - defer bodyReader.Close() + defer func() { + _ = resp.Body.Close() + }() - body, err := io.ReadAll(bodyReader) + var body []byte + var downloadedSize int64 + if into == nil || resp.StatusCode > 400 { + body = make([]byte, resp.ContentLength) + _, err = io.ReadFull(resp.Body, body) + } else { + err = fallocate.Fallocate(into, int(resp.ContentLength)) + if err != nil { + return nil, fmt.Errorf("failed to pre-allocate file for attachment: %w", err) + } + downloadedSize, err = io.Copy(into, resp.Body) + } if err != nil { return nil, err } @@ -93,6 +118,12 @@ func DownloadAttachment(ctx context.Context, cdnID uint64, cdnKey string, cdnNum return nil, fmt.Errorf("unexpected status code %d", resp.StatusCode) } + if into != nil { + if _, err = into.Seek(0, io.SeekStart); err != nil { + return nil, fmt.Errorf("failed to seek attachment file after downloading: %w", err) + } + return nil, decryptAttachmentFile(into, downloadedSize, key, digest, plaintextDigest, size) + } return decryptAttachment(body, key, digest, plaintextDigest, size) } @@ -128,6 +159,59 @@ func decryptAttachment(body, key, digest []byte, plaintextDigest bool, size uint return decrypted, nil } +func decryptAttachmentFile(file *os.File, downloadedSize int64, key, digest []byte, plaintextDigest bool, size uint32) error { + if !plaintextDigest { + hasher := sha256.New() + if _, err := io.Copy(hasher, file); err != nil { + return fmt.Errorf("failed to hash attachment file: %w", err) + } else if !hmac.Equal(hasher.Sum(nil), digest) { + return ErrInvalidDigestForAttachment + } else if _, err = file.Seek(0, io.SeekStart); err != nil { + return fmt.Errorf("failed to seek attachment file after hashing: %w", err) + } + } + mac := make([]byte, MACLength) + n, err := file.ReadAt(mac, downloadedSize-MACLength) + if err != nil { + return fmt.Errorf("failed to read MAC from attachment file: %w", err) + } else if n != MACLength { + return fmt.Errorf("unexpected MAC length read from attachment file: %d", n) + } + hasher := hmac.New(sha256.New, key[MACLength:]) + _, err = io.CopyN(hasher, file, downloadedSize-MACLength) + if err != nil { + return fmt.Errorf("failed to hash attachment file for MAC verification: %w", err) + } else if !hmac.Equal(hasher.Sum(nil), mac) { + return ErrInvalidMACForAttachment + } else if _, err = file.Seek(0, io.SeekStart); err != nil { + return fmt.Errorf("failed to seek attachment file after verifying mac: %w", err) + } + + decryptedSize, err := aesDecryptFile(key[:MACLength], file, downloadedSize-MACLength) + if err != nil { + return err + } else if decryptedSize < int64(size) { + return fmt.Errorf("decrypted attachment length %d < expected %d", decryptedSize, size) + } else if _, err = file.Seek(0, io.SeekStart); err != nil { + return fmt.Errorf("failed to seek attachment file after decrypting: %w", err) + } + err = file.Truncate(int64(size)) + if err != nil { + return fmt.Errorf("failed to truncate attachment file to expected size: %w", err) + } + if plaintextDigest { + hasher = sha256.New() + if _, err = io.Copy(hasher, file); err != nil { + return fmt.Errorf("failed to hash decrypted attachment file: %w", err) + } else if !hmac.Equal(hasher.Sum(nil), digest) { + return fmt.Errorf("%w (plaintext hash)", ErrInvalidDigestForAttachment) + } else if _, err = file.Seek(0, io.SeekStart); err != nil { + return fmt.Errorf("failed to seek attachment file after hashing plaintext: %w", err) + } + } + return nil +} + type attachmentV4UploadAttributes struct { Cdn uint32 `json:"cdn"` Key string `json:"key"` @@ -371,7 +455,7 @@ func aesDecrypt(key, ciphertext []byte) ([]byte, error) { return nil, fmt.Errorf("ciphertext not multiple of AES blocksize (%d extra bytes)", len(ciphertext)%aes.BlockSize) } - iv := ciphertext[:aes.BlockSize] + iv := ciphertext[:IVLength] mode := cipher.NewCBCDecrypter(block, iv) mode.CryptBlocks(ciphertext, ciphertext) pad := ciphertext[len(ciphertext)-1] @@ -381,6 +465,51 @@ func aesDecrypt(key, ciphertext []byte) ([]byte, error) { return ciphertext[aes.BlockSize : len(ciphertext)-int(pad)], nil } +func aesDecryptFile(key []byte, file *os.File, downloadedSize int64) (int64, error) { + block, err := aes.NewCipher(key) + if err != nil { + return 0, err + } + fileReader := io.LimitReader(file, downloadedSize) + + if downloadedSize%aes.BlockSize != 0 { + return 0, fmt.Errorf("ciphertext not multiple of AES blocksize (%d extra bytes)", downloadedSize%aes.BlockSize) + } + + iv := make([]byte, IVLength) + n, err := fileReader.Read(iv) + if err != nil { + return 0, fmt.Errorf("failed to read IV from attachment file: %w", err) + } else if n != IVLength { + return 0, fmt.Errorf("unexpected IV length read from attachment file: %d", n) + } + mode := cipher.NewCBCDecrypter(block, iv) + buf := make([]byte, 4096) + var offset int64 + var pad byte + for { + n, err = fileReader.Read(buf) + if err != nil && !errors.Is(err, io.EOF) { + return 0, fmt.Errorf("failed to read from attachment file: %w", err) + } + if n > 0 { + mode.CryptBlocks(buf[:n], buf[:n]) + if _, err = file.WriteAt(buf[:n], offset); err != nil { + return 0, fmt.Errorf("failed to write decrypted data to attachment file: %w", err) + } + offset += int64(n) + pad = buf[n-1] + } + if errors.Is(err, io.EOF) { + break + } + } + if pad > aes.BlockSize { + return 0, fmt.Errorf("pad value (%d) larger than AES blocksize (%d)", pad, aes.BlockSize) + } + return downloadedSize - int64(pad), nil +} + func appendMAC(key, body []byte) []byte { m := hmac.New(sha256.New, key) m.Write(body) diff --git a/pkg/signalmeow/receiving.go b/pkg/signalmeow/receiving.go index 142bc0f..45fafa5 100644 --- a/pkg/signalmeow/receiving.go +++ b/pkg/signalmeow/receiving.go @@ -759,7 +759,8 @@ func (cli *Client) handleSyncMessage(ctx context.Context, msg *signalpb.SyncMess log.Debug().Msg("Recieved sync message contacts") blob := msg.Contacts.Blob if blob != nil { - contactsBytes, err := DownloadAttachmentWithPointer(ctx, blob, nil) + // TODO roundtrip via disk to save memory + contactsBytes, err := DownloadAttachmentWithPointer(ctx, blob, nil, nil) if err != nil { log.Err(err).Msg("Contacts Sync DownloadAttachment error") } From 37a0199f79781ea1f4ba0427383e2dcc10e64fea Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Sat, 28 Feb 2026 12:33:08 +0200 Subject: [PATCH 535/580] handlematrix,msgconv,signalmeow: switch to sending binary ID fields --- pkg/connector/handlematrix.go | 26 +++++++--------- pkg/msgconv/from-matrix.go | 8 ++--- pkg/msgconv/from-signal-backup.go | 6 +--- pkg/msgconv/signalfmt/tags.go | 4 +-- pkg/signalmeow/sending.go | 52 ++++++++++++------------------- 5 files changed, 37 insertions(+), 59 deletions(-) diff --git a/pkg/connector/handlematrix.go b/pkg/connector/handlematrix.go index 8819d69..0ef84f6 100644 --- a/pkg/connector/handlematrix.go +++ b/pkg/connector/handlematrix.go @@ -205,12 +205,10 @@ func (s *SignalClient) HandleMatrixReaction(ctx context.Context, msg *bridgev2.M Timestamp: proto.Uint64(ts), RequiredProtocolVersion: proto.Uint32(uint32(signalpb.DataMessage_REACTIONS)), Reaction: &signalpb.DataMessage_Reaction{ - Emoji: proto.String(msg.PreHandleResp.Emoji), - Remove: proto.Bool(false), - TargetAuthorAci: proto.String(targetAuthorACI.String()), - // TODO update aci format - //TargetAuthorAciBinary: targetAuthorACI[:], - TargetSentTimestamp: proto.Uint64(targetSentTimestamp), + Emoji: proto.String(msg.PreHandleResp.Emoji), + Remove: proto.Bool(false), + TargetAuthorAciBinary: targetAuthorACI[:], + TargetSentTimestamp: proto.Uint64(targetSentTimestamp), }, }, } @@ -232,12 +230,10 @@ func (s *SignalClient) HandleMatrixReactionRemove(ctx context.Context, msg *brid Timestamp: proto.Uint64(ts), RequiredProtocolVersion: proto.Uint32(uint32(signalpb.DataMessage_REACTIONS)), Reaction: &signalpb.DataMessage_Reaction{ - Emoji: proto.String(msg.TargetReaction.Emoji), - Remove: proto.Bool(true), - TargetAuthorAci: proto.String(targetAuthorACI.String()), - // TODO update aci format - //TargetAuthorAciBinary: targetAuthorACI[:], - TargetSentTimestamp: proto.Uint64(targetSentTimestamp), + Emoji: proto.String(msg.TargetReaction.Emoji), + Remove: proto.Bool(true), + TargetAuthorAciBinary: targetAuthorACI[:], + TargetSentTimestamp: proto.Uint64(targetSentTimestamp), }, }, } @@ -722,8 +718,8 @@ func (s *SignalClient) HandleMatrixDeleteChat(ctx context.Context, msg *bridgev2 var conversationID *signalpb.ConversationIdentifier if groupID == "" { conversationID = &signalpb.ConversationIdentifier{ - Identifier: &signalpb.ConversationIdentifier_ThreadServiceId{ - ThreadServiceId: userID.String(), + Identifier: &signalpb.ConversationIdentifier_ThreadServiceIdBinary{ + ThreadServiceIdBinary: userID.Bytes(), }, } } else { @@ -865,7 +861,7 @@ func (s *SignalClient) syncMessageRequestResponse( } accept.GroupId = gidBytes[:] } else if userID.Type == libsignalgo.ServiceIDTypeACI { - accept.ThreadAci = ptr.Ptr(userID.UUID.String()) + accept.ThreadAciBinary = userID.UUID[:] } else { return fmt.Errorf("invalid portal ID for message request response: %s", portal.ID) } diff --git a/pkg/msgconv/from-matrix.go b/pkg/msgconv/from-matrix.go index fa5deb4..89b0181 100644 --- a/pkg/msgconv/from-matrix.go +++ b/pkg/msgconv/from-matrix.go @@ -60,11 +60,9 @@ func (mc *MessageConverter) ToSignal( authorACI, messageID, err := signalid.ParseMessageID(replyTo.ID) if err == nil { dm.Quote = &signalpb.DataMessage_Quote{ - Id: proto.Uint64(messageID), - AuthorAci: proto.String(authorACI.String()), - // TODO update aci format - //AuthorAciBinary: authorACI[:], - Type: signalpb.DataMessage_Quote_NORMAL.Enum(), + Id: proto.Uint64(messageID), + AuthorAciBinary: authorACI[:], + Type: signalpb.DataMessage_Quote_NORMAL.Enum(), } if replyTo.Metadata.(*signalid.MessageMetadata).ContainsAttachments { dm.Quote.Attachments = make([]*signalpb.DataMessage_Quote_QuotedAttachment, 1) diff --git a/pkg/msgconv/from-signal-backup.go b/pkg/msgconv/from-signal-backup.go index 97f756c..978c6a6 100644 --- a/pkg/msgconv/from-signal-backup.go +++ b/pkg/msgconv/from-signal-backup.go @@ -248,11 +248,7 @@ func backupToSignalBodyRange(from *backuppb.BodyRange) *signalpb.BodyRange { out.Length = &from.Length switch av := from.AssociatedValue.(type) { case *backuppb.BodyRange_MentionAci: - // TODO confirm this is correct - if len(av.MentionAci) != 16 { - return nil - } - out.AssociatedValue = &signalpb.BodyRange_MentionAci{MentionAci: uuid.UUID(av.MentionAci).String()} + out.AssociatedValue = &signalpb.BodyRange_MentionAciBinary{MentionAciBinary: av.MentionAci} case *backuppb.BodyRange_Style_: out.AssociatedValue = &signalpb.BodyRange_Style_{Style: signalpb.BodyRange_Style(av.Style)} } diff --git a/pkg/msgconv/signalfmt/tags.go b/pkg/msgconv/signalfmt/tags.go index 043bb43..b273e0e 100644 --- a/pkg/msgconv/signalfmt/tags.go +++ b/pkg/msgconv/signalfmt/tags.go @@ -40,8 +40,8 @@ func (m Mention) String() string { } func (m Mention) Proto() signalpb.BodyRangeAssociatedValue { - return &signalpb.BodyRange_MentionAci{ - MentionAci: m.UUID.String(), + return &signalpb.BodyRange_MentionAciBinary{ + MentionAciBinary: m.UUID[:], } } diff --git a/pkg/signalmeow/sending.go b/pkg/signalmeow/sending.go index 86bc1db..568b4d4 100644 --- a/pkg/signalmeow/sending.go +++ b/pkg/signalmeow/sending.go @@ -306,10 +306,8 @@ func syncMessageFromGroupDataMessage(dataMessage *signalpb.DataMessage, results unidentifiedStatuses := []*signalpb.SyncMessage_Sent_UnidentifiedDeliveryStatus{} for _, result := range results { unidentifiedStatuses = append(unidentifiedStatuses, &signalpb.SyncMessage_Sent_UnidentifiedDeliveryStatus{ - DestinationServiceId: proto.String(result.Recipient.String()), - // TODO update aci format - //DestinationServiceIdBinary: result.Recipient.Bytes(), - Unidentified: &result.Unidentified, + DestinationServiceIdBinary: result.Recipient.Bytes(), + Unidentified: &result.Unidentified, }) } return &signalpb.Content{ @@ -327,10 +325,8 @@ func syncMessageFromGroupEditMessage(editMessage *signalpb.EditMessage, results unidentifiedStatuses := []*signalpb.SyncMessage_Sent_UnidentifiedDeliveryStatus{} for _, result := range results { unidentifiedStatuses = append(unidentifiedStatuses, &signalpb.SyncMessage_Sent_UnidentifiedDeliveryStatus{ - DestinationServiceId: proto.String(result.Recipient.String()), - // TODO update aci format - //DestinationServiceIdBinary: result.Recipient.Bytes(), - Unidentified: &result.Unidentified, + DestinationServiceIdBinary: result.Recipient.Bytes(), + Unidentified: &result.Unidentified, }) } return &signalpb.Content{ @@ -349,20 +345,16 @@ func syncMessageFromSoloDataMessage(dataMessage *signalpb.DataMessage, result Su return &signalpb.Content{ SyncMessage: &signalpb.SyncMessage{ Sent: &signalpb.SyncMessage_Sent{ - Message: dataMessage, - DestinationE164: result.RecipientE164, - DestinationServiceId: proto.String(result.Recipient.String()), - // TODO update aci format - //DestinationServiceIdBinary: result.Recipient.Bytes(), - Timestamp: dataMessage.Timestamp, - ExpirationStartTimestamp: ptr.Ptr(uint64(time.Now().UnixMilli())), + Message: dataMessage, + DestinationE164: result.RecipientE164, + DestinationServiceIdBinary: result.Recipient.Bytes(), + Timestamp: dataMessage.Timestamp, + ExpirationStartTimestamp: ptr.Ptr(uint64(time.Now().UnixMilli())), UnidentifiedStatus: []*signalpb.SyncMessage_Sent_UnidentifiedDeliveryStatus{ { - DestinationServiceId: proto.String(result.Recipient.String()), - // TODO update aci format - //DestinationServiceIdBinary: result.Recipient.Bytes(), - Unidentified: &result.Unidentified, - DestinationPniIdentityKey: result.DestinationPNIIdentityKey.TrySerialize(), + DestinationServiceIdBinary: result.Recipient.Bytes(), + Unidentified: &result.Unidentified, + DestinationPniIdentityKey: result.DestinationPNIIdentityKey.TrySerialize(), }, }, }, @@ -374,20 +366,16 @@ func syncMessageFromSoloEditMessage(editMessage *signalpb.EditMessage, result Su return &signalpb.Content{ SyncMessage: &signalpb.SyncMessage{ Sent: &signalpb.SyncMessage_Sent{ - EditMessage: editMessage, - DestinationE164: result.RecipientE164, - DestinationServiceId: proto.String(result.Recipient.String()), - // TODO update aci format - //DestinationServiceIdBinary: result.Recipient.Bytes(), - Timestamp: editMessage.DataMessage.Timestamp, - ExpirationStartTimestamp: ptr.Ptr(uint64(time.Now().UnixMilli())), + EditMessage: editMessage, + DestinationE164: result.RecipientE164, + DestinationServiceIdBinary: result.Recipient.Bytes(), + Timestamp: editMessage.DataMessage.Timestamp, + ExpirationStartTimestamp: ptr.Ptr(uint64(time.Now().UnixMilli())), UnidentifiedStatus: []*signalpb.SyncMessage_Sent_UnidentifiedDeliveryStatus{ { - DestinationServiceId: proto.String(result.Recipient.String()), - // TODO update aci format - //DestinationServiceIdBinary: result.Recipient.Bytes(), - Unidentified: &result.Unidentified, - DestinationPniIdentityKey: result.DestinationPNIIdentityKey.TrySerialize(), + DestinationServiceIdBinary: result.Recipient.Bytes(), + Unidentified: &result.Unidentified, + DestinationPniIdentityKey: result.DestinationPNIIdentityKey.TrySerialize(), }, }, }, From 01b06408ab5d36a1fc2e69a370acfe13251ccf07 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Mon, 9 Mar 2026 11:48:10 +0200 Subject: [PATCH 536/580] dependencies: update mautrix-go --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 6758d92..a97408d 100644 --- a/go.mod +++ b/go.mod @@ -20,7 +20,7 @@ require ( golang.org/x/net v0.50.0 google.golang.org/protobuf v1.36.11 gopkg.in/yaml.v3 v3.0.1 - maunium.net/go/mautrix v0.26.4-0.20260305215735-7836f35a1a74 + maunium.net/go/mautrix v0.26.4-0.20260307142642-c107c25d078e ) require ( diff --git a/go.sum b/go.sum index 78bfb4e..239a198 100644 --- a/go.sum +++ b/go.sum @@ -99,5 +99,5 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= maunium.net/go/mauflag v1.0.0 h1:YiaRc0tEI3toYtJMRIfjP+jklH45uDHtT80nUamyD4M= maunium.net/go/mauflag v1.0.0/go.mod h1:nLivPOpTpHnpzEh8jEdSL9UqO9+/KBJFmNRlwKfkPeA= -maunium.net/go/mautrix v0.26.4-0.20260305215735-7836f35a1a74 h1:kHlana4CKRoAzPGbagU82y+uN4k5Tvfwt1nyj3cJHEw= -maunium.net/go/mautrix v0.26.4-0.20260305215735-7836f35a1a74/go.mod h1:lJvXCZya2dGT2KW7LUO7Ucna7Ohs6hl2+7v8Ji6R3iM= +maunium.net/go/mautrix v0.26.4-0.20260307142642-c107c25d078e h1:R1ebuJojcAFo14HKB6Kz2q6FWWIQPc2XRMkuRUq7BVY= +maunium.net/go/mautrix v0.26.4-0.20260307142642-c107c25d078e/go.mod h1:lJvXCZya2dGT2KW7LUO7Ucna7Ohs6hl2+7v8Ji6R3iM= From f4b6d0641ffef16e0d79a8ba17c6ec4ca29de821 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Mon, 16 Mar 2026 17:32:08 +0200 Subject: [PATCH 537/580] Bump version to v26.03 --- CHANGELOG.md | 6 ++++++ cmd/mautrix-signal/main.go | 2 +- go.mod | 22 ++++++++++----------- go.sum | 40 +++++++++++++++++++------------------- 4 files changed, 38 insertions(+), 32 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index dd0a2d4..d992cab 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,9 @@ +# v26.03 + +* Switched to sending binary service ID fields in outgoing messages. +* Added support for roundtripping large attachments via disk to avoid keeping + the entire file in memory during en/decryption. + # v26.02.2 * Added support for more new binary service ID fields. diff --git a/cmd/mautrix-signal/main.go b/cmd/mautrix-signal/main.go index 7f1d5fe..cc1ec10 100644 --- a/cmd/mautrix-signal/main.go +++ b/cmd/mautrix-signal/main.go @@ -37,7 +37,7 @@ var m = mxmain.BridgeMain{ Name: "mautrix-signal", URL: "https://github.com/mautrix/signal", Description: "A Matrix-Signal puppeting bridge.", - Version: "26.02.2", + Version: "26.03", SemCalVer: true, Connector: &connector.SignalConnector{}, diff --git a/go.mod b/go.mod index a97408d..b0be4f5 100644 --- a/go.mod +++ b/go.mod @@ -2,7 +2,7 @@ module go.mau.fi/mautrix-signal go 1.25.0 -toolchain go1.26.0 +toolchain go1.26.1 tool go.mau.fi/util/cmd/maubuild @@ -14,13 +14,13 @@ require ( github.com/rs/zerolog v1.34.0 github.com/stretchr/testify v1.11.1 github.com/tidwall/gjson v1.18.0 - go.mau.fi/util v0.9.6 - golang.org/x/crypto v0.48.0 - golang.org/x/exp v0.0.0-20260218203240-3dfff04db8fa - golang.org/x/net v0.50.0 + go.mau.fi/util v0.9.7 + golang.org/x/crypto v0.49.0 + golang.org/x/exp v0.0.0-20260312153236-7ab1446f8b90 + golang.org/x/net v0.52.0 google.golang.org/protobuf v1.36.11 gopkg.in/yaml.v3 v3.0.1 - maunium.net/go/mautrix v0.26.4-0.20260307142642-c107c25d078e + maunium.net/go/mautrix v0.26.4 ) require ( @@ -32,7 +32,7 @@ require ( github.com/mattn/go-colorable v0.1.14 // indirect github.com/mattn/go-isatty v0.0.20 // indirect github.com/mattn/go-sqlite3 v1.14.34 // indirect - github.com/petermattis/goid v0.0.0-20260113132338-7c7de50cc741 // indirect + github.com/petermattis/goid v0.0.0-20260226131333-17d1149c6ac6 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/rogpeppe/go-internal v1.10.0 // indirect github.com/rs/xid v1.6.0 // indirect @@ -42,10 +42,10 @@ require ( github.com/tidwall/sjson v1.2.5 // indirect github.com/yuin/goldmark v1.7.16 // indirect go.mau.fi/zeroconfig v0.2.0 // indirect - golang.org/x/mod v0.33.0 // indirect - golang.org/x/sync v0.19.0 // indirect - golang.org/x/sys v0.41.0 // indirect - golang.org/x/text v0.34.0 // indirect + golang.org/x/mod v0.34.0 // indirect + golang.org/x/sync v0.20.0 // indirect + golang.org/x/sys v0.42.0 // indirect + golang.org/x/text v0.35.0 // indirect gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect gopkg.in/natefinch/lumberjack.v2 v2.2.1 // indirect maunium.net/go/mauflag v1.0.0 // indirect diff --git a/go.sum b/go.sum index 239a198..ec06d77 100644 --- a/go.sum +++ b/go.sum @@ -37,8 +37,8 @@ github.com/mattn/go-pointer v0.0.1 h1:n+XhsuGeVO6MEAp7xyEukFINEa+Quek5psIR/ylA6o github.com/mattn/go-pointer v0.0.1/go.mod h1:2zXcozF6qYGgmsG+SeTZz3oAbFLdD3OWqnUbNvJZAlc= github.com/mattn/go-sqlite3 v1.14.34 h1:3NtcvcUnFBPsuRcno8pUtupspG/GM+9nZ88zgJcp6Zk= github.com/mattn/go-sqlite3 v1.14.34/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y= -github.com/petermattis/goid v0.0.0-20260113132338-7c7de50cc741 h1:KPpdlQLZcHfTMQRi6bFQ7ogNO0ltFT4PmtwTLW4W+14= -github.com/petermattis/goid v0.0.0-20260113132338-7c7de50cc741/go.mod h1:pxMtw7cyUw6B2bRH0ZBANSPg+AoSud1I1iyJHI69jH4= +github.com/petermattis/goid v0.0.0-20260226131333-17d1149c6ac6 h1:rh2lKw/P/EqHa724vYH2+VVQ1YnW4u6EOXl0PMAovZE= +github.com/petermattis/goid v0.0.0-20260226131333-17d1149c6ac6/go.mod h1:pxMtw7cyUw6B2bRH0ZBANSPg+AoSud1I1iyJHI69jH4= github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= @@ -67,27 +67,27 @@ github.com/tidwall/sjson v1.2.5 h1:kLy8mja+1c9jlljvWTlSazM7cKDRfJuR/bOJhcY5NcY= github.com/tidwall/sjson v1.2.5/go.mod h1:Fvgq9kS/6ociJEDnK0Fk1cpYF4FIW6ZF7LAe+6jwd28= github.com/yuin/goldmark v1.7.16 h1:n+CJdUxaFMiDUNnWC3dMWCIQJSkxH4uz3ZwQBkAlVNE= github.com/yuin/goldmark v1.7.16/go.mod h1:ip/1k0VRfGynBgxOz0yCqHrbZXhcjxyuS66Brc7iBKg= -go.mau.fi/util v0.9.6 h1:2nsvxm49KhI3wrFltr0+wSUBlnQ4CMtykuELjpIU+ts= -go.mau.fi/util v0.9.6/go.mod h1:sIJpRH7Iy5Ad1SBuxQoatxtIeErgzxCtjd/2hCMkYMI= +go.mau.fi/util v0.9.7 h1:AWGNbJfz1zRcQOKeOEYhKUG2fT+/26Gy6kyqcH8tnBg= +go.mau.fi/util v0.9.7/go.mod h1:5T2f3ZWZFAGgmFwg3dGw7YK6kIsb9lryDzvynoR98pE= go.mau.fi/zeroconfig v0.2.0 h1:e/OGEERqVRRKlgaro7E6bh8xXiKFSXB3eNNIud7FUjU= go.mau.fi/zeroconfig v0.2.0/go.mod h1:J0Vn0prHNOm493oZoQ84kq83ZaNCYZnq+noI1b1eN8w= -golang.org/x/crypto v0.48.0 h1:/VRzVqiRSggnhY7gNRxPauEQ5Drw9haKdM0jqfcCFts= -golang.org/x/crypto v0.48.0/go.mod h1:r0kV5h3qnFPlQnBSrULhlsRfryS2pmewsg+XfMgkVos= -golang.org/x/exp v0.0.0-20260218203240-3dfff04db8fa h1:Zt3DZoOFFYkKhDT3v7Lm9FDMEV06GpzjG2jrqW+QTE0= -golang.org/x/exp v0.0.0-20260218203240-3dfff04db8fa/go.mod h1:K79w1Vqn7PoiZn+TkNpx3BUWUQksGO3JcVX6qIjytmA= -golang.org/x/mod v0.33.0 h1:tHFzIWbBifEmbwtGz65eaWyGiGZatSrT9prnU8DbVL8= -golang.org/x/mod v0.33.0/go.mod h1:swjeQEj+6r7fODbD2cqrnje9PnziFuw4bmLbBZFrQ5w= -golang.org/x/net v0.50.0 h1:ucWh9eiCGyDR3vtzso0WMQinm2Dnt8cFMuQa9K33J60= -golang.org/x/net v0.50.0/go.mod h1:UgoSli3F/pBgdJBHCTc+tp3gmrU4XswgGRgtnwWTfyM= -golang.org/x/sync v0.19.0 h1:vV+1eWNmZ5geRlYjzm2adRgW2/mcpevXNg50YZtPCE4= -golang.org/x/sync v0.19.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= +golang.org/x/crypto v0.49.0 h1:+Ng2ULVvLHnJ/ZFEq4KdcDd/cfjrrjjNSXNzxg0Y4U4= +golang.org/x/crypto v0.49.0/go.mod h1:ErX4dUh2UM+CFYiXZRTcMpEcN8b/1gxEuv3nODoYtCA= +golang.org/x/exp v0.0.0-20260312153236-7ab1446f8b90 h1:jiDhWWeC7jfWqR9c/uplMOqJ0sbNlNWv0UkzE0vX1MA= +golang.org/x/exp v0.0.0-20260312153236-7ab1446f8b90/go.mod h1:xE1HEv6b+1SCZ5/uscMRjUBKtIxworgEcEi+/n9NQDQ= +golang.org/x/mod v0.34.0 h1:xIHgNUUnW6sYkcM5Jleh05DvLOtwc6RitGHbDk4akRI= +golang.org/x/mod v0.34.0/go.mod h1:ykgH52iCZe79kzLLMhyCUzhMci+nQj+0XkbXpNYtVjY= +golang.org/x/net v0.52.0 h1:He/TN1l0e4mmR3QqHMT2Xab3Aj3L9qjbhRm78/6jrW0= +golang.org/x/net v0.52.0/go.mod h1:R1MAz7uMZxVMualyPXb+VaqGSa3LIaUqk0eEt3w36Sw= +golang.org/x/sync v0.20.0 h1:e0PTpb7pjO8GAtTs2dQ6jYa5BWYlMuX047Dco/pItO4= +golang.org/x/sync v0.20.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.41.0 h1:Ivj+2Cp/ylzLiEU89QhWblYnOE9zerudt9Ftecq2C6k= -golang.org/x/sys v0.41.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= -golang.org/x/text v0.34.0 h1:oL/Qq0Kdaqxa1KbNeMKwQq0reLCCaFtqu2eNuSeNHbk= -golang.org/x/text v0.34.0/go.mod h1:homfLqTYRFyVYemLBFl5GgL/DWEiH5wcsQ5gSh1yziA= +golang.org/x/sys v0.42.0 h1:omrd2nAlyT5ESRdCLYdm3+fMfNFE/+Rf4bDIQImRJeo= +golang.org/x/sys v0.42.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= +golang.org/x/text v0.35.0 h1:JOVx6vVDFokkpaq1AEptVzLTpDe9KGpj5tR4/X+ybL8= +golang.org/x/text v0.35.0/go.mod h1:khi/HExzZJ2pGnjenulevKNX1W67CUy0AsXcNubPGCA= google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE= google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= @@ -99,5 +99,5 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= maunium.net/go/mauflag v1.0.0 h1:YiaRc0tEI3toYtJMRIfjP+jklH45uDHtT80nUamyD4M= maunium.net/go/mauflag v1.0.0/go.mod h1:nLivPOpTpHnpzEh8jEdSL9UqO9+/KBJFmNRlwKfkPeA= -maunium.net/go/mautrix v0.26.4-0.20260307142642-c107c25d078e h1:R1ebuJojcAFo14HKB6Kz2q6FWWIQPc2XRMkuRUq7BVY= -maunium.net/go/mautrix v0.26.4-0.20260307142642-c107c25d078e/go.mod h1:lJvXCZya2dGT2KW7LUO7Ucna7Ohs6hl2+7v8Ji6R3iM= +maunium.net/go/mautrix v0.26.4 h1:enHSnkf0L2V9+VnfJfNhKSReSW6pBKS/x3Su+v+Vovs= +maunium.net/go/mautrix v0.26.4/go.mod h1:YWw8NWTszsbyFAznboicBObwHPgTSLcuTbVX2kY7U2M= From 09bb6d71608cde2e3781b827a1a20aad5f50f279 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Thu, 19 Mar 2026 17:58:19 +0200 Subject: [PATCH 538/580] libsignal: update to v0.89.1 --- pkg/libsignalgo/identitykeystore.go | 41 ++++++++++-------- pkg/libsignalgo/libsignal | 2 +- pkg/libsignalgo/libsignal-ffi.h | 66 +++++++++++++++++++++++++---- pkg/libsignalgo/version.go | 2 +- 4 files changed, 83 insertions(+), 28 deletions(-) diff --git a/pkg/libsignalgo/identitykeystore.go b/pkg/libsignalgo/identitykeystore.go index 6a425e8..43941da 100644 --- a/pkg/libsignalgo/identitykeystore.go +++ b/pkg/libsignalgo/identitykeystore.go @@ -20,7 +20,7 @@ package libsignalgo /* #include "./libsignal-ffi.h" -extern int signal_get_identity_key_pair_callback(void *store_ctx, SignalMutPointerPrivateKey *keyp); +extern int signal_get_identity_key_pair_callback(void *store_ctx, SignalPairOfMutPointerPrivateKeyMutPointerPublicKey *keyp); extern int signal_get_local_registration_id_callback(void *store_ctx, uint32_t *idp); extern int signal_save_identity_key_callback(void *store_ctx, uint8_t *out, SignalMutPointerProtocolAddress address, SignalMutPointerPublicKey public_key); extern int signal_get_identity_key_callback(void *store_ctx, SignalMutPointerPublicKey *public_keyp, SignalMutPointerProtocolAddress address); @@ -49,22 +49,29 @@ type IdentityKeyStore interface { } //export signal_get_identity_key_pair_callback -func signal_get_identity_key_pair_callback(storeCtx unsafe.Pointer, keyp *C.SignalMutPointerPrivateKey) C.int { +func signal_get_identity_key_pair_callback(storeCtx unsafe.Pointer, keyp *C.SignalPairOfMutPointerPrivateKeyMutPointerPublicKey) C.int { return wrapStoreCallback(storeCtx, func(store IdentityKeyStore, ctx context.Context) error { key, err := store.GetIdentityKeyPair(ctx) if err != nil { return err } if key == nil { - keyp.raw = nil - } else { - clone, err := key.privateKey.Clone() - if err != nil { - return err - } - clone.CancelFinalizer() - keyp.raw = clone.ptr + keyp.first.raw = nil + keyp.second.raw = nil + return nil } + privClone, err := key.privateKey.Clone() + if err != nil { + return err + } + pubClone, err := key.publicKey.Clone() + if err != nil { + return err + } + privClone.CancelFinalizer() + pubClone.CancelFinalizer() + keyp.first.raw = privClone.ptr + keyp.second.raw = pubClone.ptr return err }) } @@ -151,12 +158,12 @@ func signal_destroy_identity_key_store_callback(storeCtx unsafe.Pointer) { func (ctx *CallbackContext) wrapIdentityKeyStore(store IdentityKeyStore) C.SignalConstPointerFfiIdentityKeyStoreStruct { return C.SignalConstPointerFfiIdentityKeyStoreStruct{&C.SignalIdentityKeyStore{ - ctx: wrapStore(ctx, store), - get_local_identity_private_key: C.SignalFfiBridgeIdentityKeyStoreGetLocalIdentityPrivateKey(C.signal_get_identity_key_pair_callback), - get_local_registration_id: C.SignalFfiBridgeIdentityKeyStoreGetLocalRegistrationId(C.signal_get_local_registration_id_callback), - get_identity_key: C.SignalFfiBridgeIdentityKeyStoreGetIdentityKey(C.signal_get_identity_key_callback), - save_identity_key: C.SignalFfiBridgeIdentityKeyStoreSaveIdentityKey(C.signal_save_identity_key_callback), - is_trusted_identity: C.SignalFfiBridgeIdentityKeyStoreIsTrustedIdentity(C.signal_is_trusted_identity_callback), - destroy: C.SignalFfiBridgeIdentityKeyStoreDestroy(C.signal_destroy_identity_key_store_callback), + ctx: wrapStore(ctx, store), + get_local_identity_key_pair: C.SignalFfiBridgeIdentityKeyStoreGetLocalIdentityKeyPair(C.signal_get_identity_key_pair_callback), + get_local_registration_id: C.SignalFfiBridgeIdentityKeyStoreGetLocalRegistrationId(C.signal_get_local_registration_id_callback), + get_identity_key: C.SignalFfiBridgeIdentityKeyStoreGetIdentityKey(C.signal_get_identity_key_callback), + save_identity_key: C.SignalFfiBridgeIdentityKeyStoreSaveIdentityKey(C.signal_save_identity_key_callback), + is_trusted_identity: C.SignalFfiBridgeIdentityKeyStoreIsTrustedIdentity(C.signal_is_trusted_identity_callback), + destroy: C.SignalFfiBridgeIdentityKeyStoreDestroy(C.signal_destroy_identity_key_store_callback), }} } diff --git a/pkg/libsignalgo/libsignal b/pkg/libsignalgo/libsignal index ffaa9f0..a5e7667 160000 --- a/pkg/libsignalgo/libsignal +++ b/pkg/libsignalgo/libsignal @@ -1 +1 @@ -Subproject commit ffaa9f0435569d6775d8be636f268f882ed67ce3 +Subproject commit a5e76674882a89bac1ed3f4a982120652966d21e diff --git a/pkg/libsignalgo/libsignal-ffi.h b/pkg/libsignalgo/libsignal-ffi.h index deb72cd..59409c8 100644 --- a/pkg/libsignalgo/libsignal-ffi.h +++ b/pkg/libsignalgo/libsignal-ffi.h @@ -260,6 +260,7 @@ typedef enum { SignalErrorCodeKeyTransparencyVerificationFailed = 211, SignalErrorCodeRequestUnauthorized = 220, SignalErrorCodeMismatchedDevices = 221, + SignalErrorCodeServiceIdNotFound = 222, } SignalErrorCode; enum SignalSvr2CredentialsResult { @@ -776,14 +777,19 @@ typedef struct { const SignalSessionStore *raw; } SignalConstPointerFfiSessionStoreStruct; -typedef int (*SignalFfiBridgeIdentityKeyStoreGetLocalIdentityPrivateKey)(void *ctx, SignalMutPointerPrivateKey *out); - -typedef int (*SignalFfiBridgeIdentityKeyStoreGetLocalRegistrationId)(void *ctx, uint32_t *out); - typedef struct { SignalPublicKey *raw; } SignalMutPointerPublicKey; +typedef struct { + SignalMutPointerPrivateKey first; + SignalMutPointerPublicKey second; +} SignalPairOfMutPointerPrivateKeyMutPointerPublicKey; + +typedef int (*SignalFfiBridgeIdentityKeyStoreGetLocalIdentityKeyPair)(void *ctx, SignalPairOfMutPointerPrivateKeyMutPointerPublicKey *out); + +typedef int (*SignalFfiBridgeIdentityKeyStoreGetLocalRegistrationId)(void *ctx, uint32_t *out); + typedef int (*SignalFfiBridgeIdentityKeyStoreGetIdentityKey)(void *ctx, SignalMutPointerPublicKey *out, SignalMutPointerProtocolAddress address); typedef int (*SignalFfiBridgeIdentityKeyStoreSaveIdentityKey)(void *ctx, uint8_t *out, SignalMutPointerProtocolAddress address, SignalMutPointerPublicKey public_key); @@ -794,7 +800,7 @@ typedef void (*SignalFfiBridgeIdentityKeyStoreDestroy)(void *ctx); typedef struct { void *ctx; - SignalFfiBridgeIdentityKeyStoreGetLocalIdentityPrivateKey get_local_identity_private_key; + SignalFfiBridgeIdentityKeyStoreGetLocalIdentityKeyPair get_local_identity_key_pair; SignalFfiBridgeIdentityKeyStoreGetLocalRegistrationId get_local_registration_id; SignalFfiBridgeIdentityKeyStoreGetIdentityKey get_identity_key; SignalFfiBridgeIdentityKeyStoreSaveIdentityKey save_identity_key; @@ -993,6 +999,21 @@ typedef struct { size_t length; } SignalOwnedBufferOfServiceIdFixedWidthBinaryBytes; +typedef struct { + SignalPreKeyBundle *raw; +} SignalMutPointerPreKeyBundle; + +/** + * A representation of a array allocated on the Rust heap for use in C code. + */ +typedef struct { + SignalMutPointerPreKeyBundle *base; + /** + * The number of elements in the buffer (not necessarily the number of bytes). + */ + size_t length; +} SignalOwnedBufferOfMutPointerPreKeyBundle; + typedef struct { SignalSenderKeyRecord *raw; } SignalMutPointerSenderKeyRecord; @@ -1190,10 +1211,6 @@ typedef struct { SignalPlaintextContent *raw; } SignalMutPointerPlaintextContent; -typedef struct { - SignalPreKeyBundle *raw; -} SignalMutPointerPreKeyBundle; - typedef struct { const SignalPreKeyBundle *raw; } SignalConstPointerPreKeyBundle; @@ -1523,6 +1540,26 @@ typedef struct { SignalCancellationId cancellation_id; } SignalCPromiseMutPointerUnauthenticatedChatConnection; +typedef struct { + SignalMutPointerPublicKey identity_key; + SignalOwnedBufferOfMutPointerPreKeyBundle pre_key_bundles; +} SignalFfiPreKeysResponse; + +/** + * A C callback used to report the results of Rust futures. + * + * cbindgen will produce independent C types like `SignalCPromisei32` and + * `SignalCPromiseProtocolAddress`. + * + * This derives Copy because it behaves like a C type; nevertheless, a promise should still only be + * completed once. + */ +typedef struct { + void (*complete)(SignalFfiError *error, const SignalFfiPreKeysResponse *result, const void *context); + const void *context; + SignalCancellationId cancellation_id; +} SignalCPromiseFfiPreKeysResponse; + /** * A C callback used to report the results of Rust futures. * @@ -1918,6 +1955,13 @@ void signal_free_list_of_strings(SignalOwnedBufferOfCStringPtr buffer); void signal_free_lookup_response_entry_list(SignalOwnedBufferOfFfiCdsiLookupResponseEntry buffer); +/** + * This frees a buffer of PreKeyBundle pointers, and _does not_ free the + * pointers within the buffer. This _only_ frees the buffer containing + * the pointers. + */ +void signal_free_outer_buffer_list_of_prekey_bundles(SignalOwnedBufferOfMutPointerPreKeyBundle buffer); + void signal_free_string(const char *buf); SignalFfiError *signal_generic_server_public_params_check_valid_contents(SignalBorrowedBuffer params_bytes); @@ -2686,6 +2730,10 @@ SignalFfiError *signal_unauthenticated_chat_connection_destroy(SignalMutPointerU SignalFfiError *signal_unauthenticated_chat_connection_disconnect(SignalCPromisebool *promise, SignalConstPointerTokioAsyncContext async_runtime, SignalConstPointerUnauthenticatedChatConnection chat); +SignalFfiError *signal_unauthenticated_chat_connection_get_pre_keys_access_group_auth(SignalCPromiseFfiPreKeysResponse *promise, SignalConstPointerTokioAsyncContext async_runtime, SignalConstPointerUnauthenticatedChatConnection chat, SignalBorrowedBuffer auth, const SignalServiceIdFixedWidthBinaryBytes *target, int32_t device); + +SignalFfiError *signal_unauthenticated_chat_connection_get_pre_keys_access_key_auth(SignalCPromiseFfiPreKeysResponse *promise, SignalConstPointerTokioAsyncContext async_runtime, SignalConstPointerUnauthenticatedChatConnection chat, const uint8_t (*auth)[16], const SignalServiceIdFixedWidthBinaryBytes *target, int32_t device); + SignalFfiError *signal_unauthenticated_chat_connection_info(SignalMutPointerChatConnectionInfo *out, SignalConstPointerUnauthenticatedChatConnection chat); SignalFfiError *signal_unauthenticated_chat_connection_init_listener(SignalConstPointerUnauthenticatedChatConnection chat, SignalConstPointerFfiChatListenerStruct listener); diff --git a/pkg/libsignalgo/version.go b/pkg/libsignalgo/version.go index bb1774c..ccd0d51 100644 --- a/pkg/libsignalgo/version.go +++ b/pkg/libsignalgo/version.go @@ -2,4 +2,4 @@ package libsignalgo -const Version = "v0.87.5" +const Version = "v0.89.1" From 4842b35ab4a9a500a1cfbbc863687eb5c4236cc9 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Thu, 19 Mar 2026 17:59:15 +0200 Subject: [PATCH 539/580] msgconv/from-signal: add more details to quote aci parse error log --- pkg/msgconv/from-signal.go | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/pkg/msgconv/from-signal.go b/pkg/msgconv/from-signal.go index 4119cc5..96b4f10 100644 --- a/pkg/msgconv/from-signal.go +++ b/pkg/msgconv/from-signal.go @@ -179,7 +179,10 @@ func (mc *MessageConverter) ToMatrix( if dm.Quote != nil { authorACI, err := signalmeow.ParseStringOrBinaryUUID(dm.Quote.GetAuthorAci(), dm.Quote.GetAuthorAciBinary()) if err != nil { - zerolog.Ctx(ctx).Err(err).Str("author_aci", dm.Quote.GetAuthorAci()).Msg("Failed to parse quote author ACI") + zerolog.Ctx(ctx).Err(err). + Str("author_aci", dm.Quote.GetAuthorAci()). + Hex("author_aci_binary", dm.Quote.GetAuthorAciBinary()). + Msg("Failed to parse quote author ACI") } else { cm.ReplyTo = &networkid.MessageOptionalPartID{ MessageID: signalid.MakeMessageID(authorACI, dm.Quote.GetId()), From 69f9b48e356a76c978e6f67cc49cdcd5aedf4f4e Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Thu, 19 Mar 2026 20:57:46 +0200 Subject: [PATCH 540/580] signalmeow/attachments: handle unknown content length in downloads Closes #644 --- pkg/signalmeow/attachments.go | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/pkg/signalmeow/attachments.go b/pkg/signalmeow/attachments.go index 2c8f1ea..e09dd7e 100644 --- a/pkg/signalmeow/attachments.go +++ b/pkg/signalmeow/attachments.go @@ -93,9 +93,15 @@ func DownloadAttachment( var body []byte var downloadedSize int64 - if into == nil || resp.StatusCode > 400 { - body = make([]byte, resp.ContentLength) - _, err = io.ReadFull(resp.Body, body) + if resp.StatusCode > 400 { + body, err = io.ReadAll(io.LimitReader(resp.Body, 4096)) + } else if into == nil { + if resp.ContentLength > 0 { + body = make([]byte, resp.ContentLength) + _, err = io.ReadFull(resp.Body, body) + } else { + body, err = io.ReadAll(http.MaxBytesReader(nil, resp.Body, max(int64(size), 32*1024)*2)) + } } else { err = fallocate.Fallocate(into, int(resp.ContentLength)) if err != nil { From f49b11c4cbbb46447e8aba055704ef973870ca27 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Sun, 22 Mar 2026 12:26:01 +0200 Subject: [PATCH 541/580] dependencies: update mautrix-go --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index b0be4f5..99019d5 100644 --- a/go.mod +++ b/go.mod @@ -20,7 +20,7 @@ require ( golang.org/x/net v0.52.0 google.golang.org/protobuf v1.36.11 gopkg.in/yaml.v3 v3.0.1 - maunium.net/go/mautrix v0.26.4 + maunium.net/go/mautrix v0.26.5-0.20260322102453-0c955c396df7 ) require ( diff --git a/go.sum b/go.sum index ec06d77..0ec9eec 100644 --- a/go.sum +++ b/go.sum @@ -99,5 +99,5 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= maunium.net/go/mauflag v1.0.0 h1:YiaRc0tEI3toYtJMRIfjP+jklH45uDHtT80nUamyD4M= maunium.net/go/mauflag v1.0.0/go.mod h1:nLivPOpTpHnpzEh8jEdSL9UqO9+/KBJFmNRlwKfkPeA= -maunium.net/go/mautrix v0.26.4 h1:enHSnkf0L2V9+VnfJfNhKSReSW6pBKS/x3Su+v+Vovs= -maunium.net/go/mautrix v0.26.4/go.mod h1:YWw8NWTszsbyFAznboicBObwHPgTSLcuTbVX2kY7U2M= +maunium.net/go/mautrix v0.26.5-0.20260322102453-0c955c396df7 h1:KUhlBHWGgknqYC2V8di4DFNh73atDtgPlqqO5FoLmPc= +maunium.net/go/mautrix v0.26.5-0.20260322102453-0c955c396df7/go.mod h1:YWw8NWTszsbyFAznboicBObwHPgTSLcuTbVX2kY7U2M= From 73a8a77e8855419894704402d47ccd9ba338fd3a Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Tue, 24 Mar 2026 15:24:03 +0200 Subject: [PATCH 542/580] signalmeow: don't drop valid contact entries --- pkg/signalmeow/receiving.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/signalmeow/receiving.go b/pkg/signalmeow/receiving.go index 45fafa5..9fa4b84 100644 --- a/pkg/signalmeow/receiving.go +++ b/pkg/signalmeow/receiving.go @@ -773,7 +773,7 @@ func (cli *Client) handleSyncMessage(ctx context.Context, msg *signalpb.SyncMess convertedContacts := make([]*types.Recipient, 0, len(contacts)) err = cli.Store.DoContactTxn(ctx, func(ctx context.Context) error { for i, signalContact := range contacts { - if signalContact.Aci == nil || *signalContact.Aci == "" { + if (signalContact.Aci == nil || *signalContact.Aci == "") && len(signalContact.AciBinary) != 16 { // TODO lookup PNI via CDSI and store that when ACI is missing? log.Info(). Any("contact", signalContact). From 40f320061c1d09691a7f15f901b814f5b58e27f3 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Tue, 31 Mar 2026 19:56:36 +0300 Subject: [PATCH 543/580] dependencies: update mautrix-go --- go.mod | 12 ++++++------ go.sum | 32 ++++++++++++-------------------- pkg/connector/handlematrix.go | 3 +++ 3 files changed, 21 insertions(+), 26 deletions(-) diff --git a/go.mod b/go.mod index 99019d5..c2ff042 100644 --- a/go.mod +++ b/go.mod @@ -11,7 +11,7 @@ require ( github.com/emersion/go-vcard v0.0.0-20241024213814-c9703dde27ff github.com/google/uuid v1.6.0 github.com/mattn/go-pointer v0.0.1 - github.com/rs/zerolog v1.34.0 + github.com/rs/zerolog v1.35.0 github.com/stretchr/testify v1.11.1 github.com/tidwall/gjson v1.18.0 go.mau.fi/util v0.9.7 @@ -20,18 +20,18 @@ require ( golang.org/x/net v0.52.0 google.golang.org/protobuf v1.36.11 gopkg.in/yaml.v3 v3.0.1 - maunium.net/go/mautrix v0.26.5-0.20260322102453-0c955c396df7 + maunium.net/go/mautrix v0.26.5-0.20260331163037-18917f3bdc14 ) require ( filippo.io/edwards25519 v1.2.0 // indirect - github.com/coreos/go-systemd/v22 v22.6.0 // indirect + github.com/coreos/go-systemd/v22 v22.7.0 // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/kr/pretty v0.3.1 // indirect - github.com/lib/pq v1.11.2 // indirect + github.com/lib/pq v1.12.0 // indirect github.com/mattn/go-colorable v0.1.14 // indirect github.com/mattn/go-isatty v0.0.20 // indirect - github.com/mattn/go-sqlite3 v1.14.34 // indirect + github.com/mattn/go-sqlite3 v1.14.37 // indirect github.com/petermattis/goid v0.0.0-20260226131333-17d1149c6ac6 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/rogpeppe/go-internal v1.10.0 // indirect @@ -40,7 +40,7 @@ require ( github.com/tidwall/match v1.2.0 // indirect github.com/tidwall/pretty v1.2.1 // indirect github.com/tidwall/sjson v1.2.5 // indirect - github.com/yuin/goldmark v1.7.16 // indirect + github.com/yuin/goldmark v1.8.2 // indirect go.mau.fi/zeroconfig v0.2.0 // indirect golang.org/x/mod v0.34.0 // indirect golang.org/x/sync v0.20.0 // indirect diff --git a/go.sum b/go.sum index 0ec9eec..44ce4a1 100644 --- a/go.sum +++ b/go.sum @@ -4,15 +4,13 @@ github.com/DATA-DOG/go-sqlmock v1.5.2 h1:OcvFkGmslmlZibjAjaHm3L//6LiuBgolP7Oputl github.com/DATA-DOG/go-sqlmock v1.5.2/go.mod h1:88MAG/4G7SMwSE3CeA0ZKzrT5CiOU3OJ+JlNzwDqpNU= github.com/coder/websocket v1.8.14 h1:9L0p0iKiNOibykf283eHkKUHHrpG7f65OE3BhhO7v9g= github.com/coder/websocket v1.8.14/go.mod h1:NX3SzP+inril6yawo5CQXx8+fk145lPDC6pumgx0mVg= -github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= -github.com/coreos/go-systemd/v22 v22.6.0 h1:aGVa/v8B7hpb0TKl0MWoAavPDmHvobFe5R5zn0bCJWo= -github.com/coreos/go-systemd/v22 v22.6.0/go.mod h1:iG+pp635Fo7ZmV/j14KUcmEyWF+0X7Lua8rrTWzYgWU= +github.com/coreos/go-systemd/v22 v22.7.0 h1:LAEzFkke61DFROc7zNLX/WA2i5J8gYqe0rSj9KI28KA= +github.com/coreos/go-systemd/v22 v22.7.0/go.mod h1:xNUYtjHu2EDXbsxz1i41wouACIwT7Ybq9o0BQhMwD0w= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/emersion/go-vcard v0.0.0-20241024213814-c9703dde27ff h1:4N8wnS3f1hNHSmFD5zgFkWCyA4L1kCDkImPAtK7D6tg= github.com/emersion/go-vcard v0.0.0-20241024213814-c9703dde27ff/go.mod h1:HMJKR5wlh/ziNp+sHEDV2ltblO4JD2+IdDOWtGcQBTM= -github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= @@ -24,23 +22,19 @@ github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= -github.com/lib/pq v1.11.2 h1:x6gxUeu39V0BHZiugWe8LXZYZ+Utk7hSJGThs8sdzfs= -github.com/lib/pq v1.11.2/go.mod h1:/p+8NSbOcwzAEI7wiMXFlgydTwcgTr3OSKMsD2BitpA= -github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= +github.com/lib/pq v1.12.0 h1:mC1zeiNamwKBecjHarAr26c/+d8V5w/u4J0I/yASbJo= +github.com/lib/pq v1.12.0/go.mod h1:/p+8NSbOcwzAEI7wiMXFlgydTwcgTr3OSKMsD2BitpA= github.com/mattn/go-colorable v0.1.14 h1:9A9LHSqF/7dyVVX6g0U9cwm9pG3kP9gSzcuIPHPsaIE= github.com/mattn/go-colorable v0.1.14/go.mod h1:6LmQG8QLFO4G5z1gPvYEzlUgJ2wF+stgPZH1UqBm1s8= -github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= -github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mattn/go-pointer v0.0.1 h1:n+XhsuGeVO6MEAp7xyEukFINEa+Quek5psIR/ylA6o0= github.com/mattn/go-pointer v0.0.1/go.mod h1:2zXcozF6qYGgmsG+SeTZz3oAbFLdD3OWqnUbNvJZAlc= -github.com/mattn/go-sqlite3 v1.14.34 h1:3NtcvcUnFBPsuRcno8pUtupspG/GM+9nZ88zgJcp6Zk= -github.com/mattn/go-sqlite3 v1.14.34/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y= +github.com/mattn/go-sqlite3 v1.14.37 h1:3DOZp4cXis1cUIpCfXLtmlGolNLp2VEqhiB/PARNBIg= +github.com/mattn/go-sqlite3 v1.14.37/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y= github.com/petermattis/goid v0.0.0-20260226131333-17d1149c6ac6 h1:rh2lKw/P/EqHa724vYH2+VVQ1YnW4u6EOXl0PMAovZE= github.com/petermattis/goid v0.0.0-20260226131333-17d1149c6ac6/go.mod h1:pxMtw7cyUw6B2bRH0ZBANSPg+AoSud1I1iyJHI69jH4= github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= -github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= @@ -48,8 +42,8 @@ github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjR github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog= github.com/rs/xid v1.6.0 h1:fV591PaemRlL6JfRxGDEPl69wICngIQ3shQtzfy2gxU= github.com/rs/xid v1.6.0/go.mod h1:7XoLgs4eV+QndskICGsho+ADou8ySMSjJKDIan90Nz0= -github.com/rs/zerolog v1.34.0 h1:k43nTLIwcTVQAncfCw4KZ2VY6ukYoZaBPNOE8txlOeY= -github.com/rs/zerolog v1.34.0/go.mod h1:bJsvje4Z08ROH4Nhs5iH600c3IkWhwp44iRc54W6wYQ= +github.com/rs/zerolog v1.35.0 h1:VD0ykx7HMiMJytqINBsKcbLS+BJ4WYjz+05us+LRTdI= +github.com/rs/zerolog v1.35.0/go.mod h1:EjML9kdfa/RMA7h/6z6pYmq1ykOuA8/mjWaEvGI+jcw= github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e h1:MRM5ITcdelLK2j1vwZ3Je0FKVCfqOLp5zO6trqMLYs0= github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e/go.mod h1:XV66xRDqSt+GTGFMVlhk3ULuV0y9ZmzeVGR4mloJI3M= github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= @@ -65,8 +59,8 @@ github.com/tidwall/pretty v1.2.1 h1:qjsOFOWWQl+N3RsoF5/ssm1pHmJJwhjlSbZ51I6wMl4= github.com/tidwall/pretty v1.2.1/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU= github.com/tidwall/sjson v1.2.5 h1:kLy8mja+1c9jlljvWTlSazM7cKDRfJuR/bOJhcY5NcY= github.com/tidwall/sjson v1.2.5/go.mod h1:Fvgq9kS/6ociJEDnK0Fk1cpYF4FIW6ZF7LAe+6jwd28= -github.com/yuin/goldmark v1.7.16 h1:n+CJdUxaFMiDUNnWC3dMWCIQJSkxH4uz3ZwQBkAlVNE= -github.com/yuin/goldmark v1.7.16/go.mod h1:ip/1k0VRfGynBgxOz0yCqHrbZXhcjxyuS66Brc7iBKg= +github.com/yuin/goldmark v1.8.2 h1:kEGpgqJXdgbkhcOgBxkC0X0PmoPG1ZyoZ117rDVp4zE= +github.com/yuin/goldmark v1.8.2/go.mod h1:ip/1k0VRfGynBgxOz0yCqHrbZXhcjxyuS66Brc7iBKg= go.mau.fi/util v0.9.7 h1:AWGNbJfz1zRcQOKeOEYhKUG2fT+/26Gy6kyqcH8tnBg= go.mau.fi/util v0.9.7/go.mod h1:5T2f3ZWZFAGgmFwg3dGw7YK6kIsb9lryDzvynoR98pE= go.mau.fi/zeroconfig v0.2.0 h1:e/OGEERqVRRKlgaro7E6bh8xXiKFSXB3eNNIud7FUjU= @@ -81,9 +75,7 @@ golang.org/x/net v0.52.0 h1:He/TN1l0e4mmR3QqHMT2Xab3Aj3L9qjbhRm78/6jrW0= golang.org/x/net v0.52.0/go.mod h1:R1MAz7uMZxVMualyPXb+VaqGSa3LIaUqk0eEt3w36Sw= golang.org/x/sync v0.20.0 h1:e0PTpb7pjO8GAtTs2dQ6jYa5BWYlMuX047Dco/pItO4= golang.org/x/sync v0.20.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0= -golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.42.0 h1:omrd2nAlyT5ESRdCLYdm3+fMfNFE/+Rf4bDIQImRJeo= golang.org/x/sys v0.42.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= golang.org/x/text v0.35.0 h1:JOVx6vVDFokkpaq1AEptVzLTpDe9KGpj5tR4/X+ybL8= @@ -99,5 +91,5 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= maunium.net/go/mauflag v1.0.0 h1:YiaRc0tEI3toYtJMRIfjP+jklH45uDHtT80nUamyD4M= maunium.net/go/mauflag v1.0.0/go.mod h1:nLivPOpTpHnpzEh8jEdSL9UqO9+/KBJFmNRlwKfkPeA= -maunium.net/go/mautrix v0.26.5-0.20260322102453-0c955c396df7 h1:KUhlBHWGgknqYC2V8di4DFNh73atDtgPlqqO5FoLmPc= -maunium.net/go/mautrix v0.26.5-0.20260322102453-0c955c396df7/go.mod h1:YWw8NWTszsbyFAznboicBObwHPgTSLcuTbVX2kY7U2M= +maunium.net/go/mautrix v0.26.5-0.20260331163037-18917f3bdc14 h1:y+4gtqKBMTtcVUiAeWJnvp88JLo/h3myQPsz1rZfNOY= +maunium.net/go/mautrix v0.26.5-0.20260331163037-18917f3bdc14/go.mod h1:RUSMBPky3jhXB7Ux+AptfkEvFlJ4ajZKCYiXI8YzxVE= diff --git a/pkg/connector/handlematrix.go b/pkg/connector/handlematrix.go index 0ef84f6..89b7d45 100644 --- a/pkg/connector/handlematrix.go +++ b/pkg/connector/handlematrix.go @@ -407,6 +407,9 @@ func (s *SignalClient) HandleMatrixRoomTopic(ctx context.Context, msg *bridgev2. } func (s *SignalClient) HandleMatrixMembership(ctx context.Context, msg *bridgev2.MatrixMembershipChange) (*bridgev2.MatrixMembershipResult, error) { + if msg.Type.IsSelf && msg.OrigSender != nil { + return nil, nil + } var targetIntent bridgev2.MatrixAPI var targetSignalID libsignalgo.ServiceID var err error From e9da747f37d21b5ddadb88a190b508436c0b27de Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Tue, 7 Apr 2026 00:50:21 +0300 Subject: [PATCH 544/580] .github: add checklist to bug report template --- .github/ISSUE_TEMPLATE/bug.md | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/bug.md b/.github/ISSUE_TEMPLATE/bug.md index 3703df9..c10630f 100644 --- a/.github/ISSUE_TEMPLATE/bug.md +++ b/.github/ISSUE_TEMPLATE/bug.md @@ -7,10 +7,11 @@ type: Bug --- - -It's always best to ask in the Matrix room first, especially if you aren't sure -what details are needed. Issues with insufficient detail will likely just be -ignored or closed immediately. ---> +### Checklist + + + +* [ ] This is an actual bug, not just a setup issue (see the [troubleshooting docs](https://docs.mau.fi/bridges/general/troubleshooting.html) or ask in the Matrix room for setup help). +* [ ] I am certain that sufficient information is included. Ask in the Matrix room first if not. From 426b1f82669e8ba4690006016471b52b416f9db0 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Tue, 7 Apr 2026 00:50:47 +0300 Subject: [PATCH 545/580] chatinfo: fix room name in DMs --- pkg/connector/chatinfo.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/pkg/connector/chatinfo.go b/pkg/connector/chatinfo.go index 4ce1f9d..87f1f6f 100644 --- a/pkg/connector/chatinfo.go +++ b/pkg/connector/chatinfo.go @@ -414,7 +414,7 @@ func (s *SignalClient) GetContactList(ctx context.Context) ([]*bridgev2.ResolveI } func (s *SignalClient) makeCreateDMResponse(ctx context.Context, recipient *types.Recipient, backupChat *store.BackupChat) *bridgev2.CreateChatResponse { - name := "" + namePtr := bridgev2.DefaultChatName topic := PrivateChatTopic selfUser := s.makeEventSender(s.Client.Store.ACI) members := &bridgev2.ChatMemberList{ @@ -441,7 +441,7 @@ func (s *SignalClient) makeCreateDMResponse(ctx context.Context, recipient *type var serviceID libsignalgo.ServiceID var avatar *bridgev2.Avatar if recipient.ACI == uuid.Nil { - name = s.Main.Config.FormatDisplayname(recipient) + namePtr = ptr.Ptr(s.Main.Config.FormatDisplayname(recipient)) serviceID = libsignalgo.NewPNIServiceID(recipient.PNI) } else { if backupChat == nil { @@ -453,7 +453,7 @@ func (s *SignalClient) makeCreateDMResponse(ctx context.Context, recipient *type } members.OtherUserID = signalid.MakeUserID(recipient.ACI) if recipient.ACI == s.Client.Store.ACI { - name = NoteToSelfName + namePtr = ptr.Ptr(NoteToSelfName) avatar = &bridgev2.Avatar{ ID: networkid.AvatarID(s.Main.Config.NoteToSelfAvatar), Remove: len(s.Main.Config.NoteToSelfAvatar) == 0, @@ -474,7 +474,7 @@ func (s *SignalClient) makeCreateDMResponse(ctx context.Context, recipient *type return &bridgev2.CreateChatResponse{ PortalKey: s.makeDMPortalKey(serviceID), PortalInfo: &bridgev2.ChatInfo{ - Name: &name, + Name: namePtr, Avatar: avatar, Topic: &topic, Members: members, From 9257116792a818485859627ed1db857977d98b8f Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Thu, 9 Apr 2026 13:58:06 +0300 Subject: [PATCH 546/580] client: ensure connection is cancelled when bridge is stopped --- pkg/connector/client.go | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/pkg/connector/client.go b/pkg/connector/client.go index e224c17..186ab4d 100644 --- a/pkg/connector/client.go +++ b/pkg/connector/client.go @@ -281,7 +281,7 @@ func (s *SignalClient) Disconnect() { } func (s *SignalClient) postLoginConnect() { - ctx := s.UserLogin.Log.WithContext(context.Background()) + ctx := s.UserLogin.Log.WithContext(s.Main.Bridge.BackgroundCtx) // TODO it would be more proper to only connect after syncing, // but currently syncing will fetch group info online, so it has to be connected. s.tryConnect(ctx, 0, false) @@ -300,6 +300,13 @@ func (s *SignalClient) postLoginConnect() { } func (s *SignalClient) tryConnect(ctx context.Context, retryCount int, doSync bool) { + if ctx.Err() != nil { + zerolog.Ctx(ctx).Debug(). + Int("retry_count", retryCount). + AnErr("ctx_err", ctx.Err()). + Msg("Context is canceled, not trying to connect") + return + } if retryCount == 0 { s.UserLogin.BridgeState.Send(status.BridgeState{StateEvent: status.StateConnecting}) } From e5a4f55e83749f25c153c6bea02f2c89c4fa932d Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Thu, 9 Apr 2026 13:58:24 +0300 Subject: [PATCH 547/580] signalmeow/backup: return early if WaitForTransfer is cancelled --- pkg/signalmeow/backup.go | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/pkg/signalmeow/backup.go b/pkg/signalmeow/backup.go index fcbfff0..f003e19 100644 --- a/pkg/signalmeow/backup.go +++ b/pkg/signalmeow/backup.go @@ -282,7 +282,11 @@ func (cli *Client) WaitForTransfer(ctx context.Context) (*TransferArchiveMetadat } reqDuration := time.Since(reqStart) if reqDuration < reqTimeout-10*time.Second { - time.Sleep(15 * time.Second) + select { + case <-time.After(15 * time.Second): + case <-ctx.Done(): + return nil, ctx.Err() + } } } } From 9d34e0d7fac468be20b6b451092b58aad36624dd Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Thu, 9 Apr 2026 13:58:58 +0300 Subject: [PATCH 548/580] chatsync: catch missing recipients for backup chats --- pkg/connector/chatsync.go | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/pkg/connector/chatsync.go b/pkg/connector/chatsync.go index 5211270..7c891aa 100644 --- a/pkg/connector/chatsync.go +++ b/pkg/connector/chatsync.go @@ -69,6 +69,12 @@ func (s *SignalClient) syncChats(ctx context.Context) { if err != nil { zerolog.Ctx(ctx).Err(err).Msg("Failed to get recipient for chat") continue + } else if recipient == nil { + zerolog.Ctx(ctx).Warn(). + Uint64("backup_chat_id", chat.Id). + Uint64("backup_recipient_id", chat.RecipientId). + Msg("No recipient found for chat") + continue } resyncEvt := &simplevent.ChatResync{ EventMeta: simplevent.EventMeta{ From 59eaa364159c4910575e635cb9d78fd59077f7ff Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Thu, 9 Apr 2026 13:59:21 +0300 Subject: [PATCH 549/580] chatsync: stop syncing if client is logged out Closes #645 --- pkg/connector/chatsync.go | 17 ++++++++++++- pkg/connector/client.go | 51 ++++++++++++++++++++++++--------------- 2 files changed, 48 insertions(+), 20 deletions(-) diff --git a/pkg/connector/chatsync.go b/pkg/connector/chatsync.go index 7c891aa..636cad7 100644 --- a/pkg/connector/chatsync.go +++ b/pkg/connector/chatsync.go @@ -32,10 +32,19 @@ import ( "go.mau.fi/mautrix-signal/pkg/signalmeow/types" ) -func (s *SignalClient) syncChats(ctx context.Context) { +func (s *SignalClient) stopChatSync() { + if cancel := s.cancelChatSync.Swap(nil); cancel != nil { + (*cancel)() + } +} + +func (s *SignalClient) syncChats(ctx context.Context, cancel context.CancelFunc) { + defer cancel() + if s.UserLogin.Metadata.(*signalid.UserLoginMetadata).ChatsSynced { return } + if s.Client.Store.EphemeralBackupKey != nil { zerolog.Ctx(ctx).Info().Msg("Fetching transfer archive before syncing chats") meta, err := s.Client.WaitForTransfer(ctx) @@ -65,6 +74,12 @@ func (s *SignalClient) syncChats(ctx context.Context) { } zerolog.Ctx(ctx).Info().Int("chat_count", len(chats)).Msg("Fetched chats to sync from database") for _, chat := range chats { + if ctx.Err() != nil { + zerolog.Ctx(ctx).Debug(). + AnErr("ctx_err", ctx.Err()). + Msg("Context cancelled while syncing chats, stopping") + return + } recipient, err := s.Client.Store.BackupStore.GetBackupRecipient(ctx, chat.RecipientId) if err != nil { zerolog.Ctx(ctx).Err(err).Msg("Failed to get recipient for chat") diff --git a/pkg/connector/client.go b/pkg/connector/client.go index 186ab4d..17ee216 100644 --- a/pkg/connector/client.go +++ b/pkg/connector/client.go @@ -19,6 +19,7 @@ package connector import ( "context" "fmt" + "sync/atomic" "time" "github.com/rs/zerolog" @@ -39,6 +40,7 @@ type SignalClient struct { Ghost *bridgev2.Ghost queueEmptyWaiter *exsync.Event + cancelChatSync atomic.Pointer[context.CancelFunc] } var ( @@ -78,6 +80,7 @@ func (s *SignalClient) LogoutRemote(ctx context.Context) { if s.Client == nil { return } + s.stopChatSync() err := s.Client.Unlink(ctx) if err != nil { zerolog.Ctx(ctx).Err(err).Msg("Failed to unlink device") @@ -176,6 +179,7 @@ func (s *SignalClient) bridgeStateLoop(statusChan <-chan signalmeow.SignalConnec } case signalmeow.SignalConnectionEventLoggedOut: + s.stopChatSync() s.UserLogin.Log.Debug().Msg("Sending BadCredentials BridgeState") if err == nil { s.UserLogin.BridgeState.Send(status.BridgeState{StateEvent: status.StateBadCredentials, Message: "You have been logged out of Signal, please reconnect"}) @@ -274,6 +278,7 @@ func (s *SignalClient) Disconnect() { if s.Client == nil { return } + s.stopChatSync() err := s.Client.StopReceiveLoops() if err != nil { s.UserLogin.Log.Err(err).Msg("Failed to stop receive loops") @@ -282,24 +287,10 @@ func (s *SignalClient) Disconnect() { func (s *SignalClient) postLoginConnect() { ctx := s.UserLogin.Log.WithContext(s.Main.Bridge.BackgroundCtx) - // TODO it would be more proper to only connect after syncing, - // but currently syncing will fetch group info online, so it has to be connected. s.tryConnect(ctx, 0, false) - if s.Client.Store.EphemeralBackupKey != nil { - go func() { - if s.Client.Store.MasterKey != nil { - s.Client.SyncStorage(ctx) - } else { - s.UserLogin.Log.Warn().Msg("No master key for storage sync before backup sync") - } - s.syncChats(ctx) - }() - } else if s.Client.Store.MasterKey != nil { - go s.Client.SyncStorage(ctx) - } } -func (s *SignalClient) tryConnect(ctx context.Context, retryCount int, doSync bool) { +func (s *SignalClient) tryConnect(ctx context.Context, retryCount int, noLoginSync bool) { if ctx.Err() != nil { zerolog.Ctx(ctx).Debug(). Int("retry_count", retryCount). @@ -325,11 +316,33 @@ func (s *SignalClient) tryConnect(ctx context.Context, retryCount int, doSync bo zerolog.Ctx(ctx).Info().Msg("Context canceled, exit tryConnect") return } - s.tryConnect(ctx, retryCount+1, doSync) + s.tryConnect(ctx, retryCount+1, noLoginSync) + return + } + syncCtx, cancel := context.WithCancel(ctx) + if oldCancel := s.cancelChatSync.Swap(&cancel); oldCancel != nil { + (*oldCancel)() + } + go s.bridgeStateLoop(ch) + if noLoginSync { + go s.syncChats(syncCtx, cancel) } else { - go s.bridgeStateLoop(ch) - if doSync { - go s.syncChats(ctx) + // TODO it would be more proper to only connect after syncing, + // but currently syncing will fetch group info online, so it has to be connected. + if s.Client.Store.EphemeralBackupKey != nil { + go func() { + if s.Client.Store.MasterKey != nil { + s.Client.SyncStorage(ctx) + } else { + s.UserLogin.Log.Warn().Msg("No master key for storage sync before backup sync") + } + s.syncChats(syncCtx, cancel) + }() + } else { + cancel() + if s.Client.Store.MasterKey != nil { + go s.Client.SyncStorage(ctx) + } } } } From c2f0a1bbf78848ac5379c01c2656e82028020d9b Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Thu, 9 Apr 2026 13:59:37 +0300 Subject: [PATCH 550/580] handlesignal: use bridge background context instead of todo --- pkg/connector/handlesignal.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/pkg/connector/handlesignal.go b/pkg/connector/handlesignal.go index bc0dbe3..4438cb0 100644 --- a/pkg/connector/handlesignal.go +++ b/pkg/connector/handlesignal.go @@ -467,7 +467,7 @@ func (s *SignalClient) handleSignalReceipt(evt *events.Receipt) bool { Stringer("sender_id", evt.Sender). Stringer("receipt_type", evt.Content.GetType()). Logger() - ctx := log.WithContext(context.TODO()) + ctx := log.WithContext(s.Main.Bridge.BackgroundCtx) receipts := convertReceipts(ctx, evt.Content.Timestamp, func(ctx context.Context, msgTS uint64) (*database.Message, error) { return s.Main.Bridge.DB.Message.GetFirstPartByID(ctx, s.UserLogin.ID, signalid.MakeMessageID(s.Client.Store.ACI, msgTS)) }) @@ -478,7 +478,7 @@ func (s *SignalClient) handleSignalReadSelf(evt *events.ReadSelf) bool { log := s.UserLogin.Log.With(). Str("action", "handle signal read self"). Logger() - ctx := log.WithContext(context.TODO()) + ctx := log.WithContext(s.Main.Bridge.BackgroundCtx) receipts := convertReceipts(ctx, evt.Messages, func(ctx context.Context, msgInfo *signalpb.SyncMessage_Read) (*database.Message, error) { aciUUID, err := signalmeow.ParseStringOrBinaryUUID(msgInfo.GetSenderAci(), msgInfo.GetSenderAciBinary()) if err != nil { @@ -688,7 +688,7 @@ func (s *SignalClient) handleSignalACIFound(evt *events.ACIFound) { Stringer("aci", evt.ACI). Stringer("pni", evt.PNI). Logger() - ctx := log.WithContext(context.TODO()) + ctx := log.WithContext(s.Main.Bridge.BackgroundCtx) pniPortalKey := s.makeDMPortalKey(evt.PNI) aciPortalKey := s.makeDMPortalKey(evt.ACI) result, portal, err := s.Main.Bridge.ReIDPortal(ctx, pniPortalKey, aciPortalKey) @@ -708,7 +708,7 @@ func (s *SignalClient) handleSignalACIFound(evt *events.ACIFound) { func (s *SignalClient) handleSignalContactList(evt *events.ContactList) { log := s.UserLogin.Log.With().Str("action", "handle contact list").Logger() - ctx := log.WithContext(context.TODO()) + ctx := log.WithContext(s.Main.Bridge.BackgroundCtx) for _, contact := range evt.Contacts { if contact.ACI == uuid.Nil { continue From 53a3faa969ad6c58216a59e0e4a36aef65678d54 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Fri, 10 Apr 2026 20:46:03 +0300 Subject: [PATCH 551/580] chatinfo: fix uploading avatar when creating group --- pkg/connector/chatinfo.go | 4 ++-- pkg/connector/handlematrix.go | 2 +- pkg/signalmeow/attachments.go | 15 ++++++++++----- pkg/signalmeow/groups.go | 14 +++----------- 4 files changed, 16 insertions(+), 19 deletions(-) diff --git a/pkg/connector/chatinfo.go b/pkg/connector/chatinfo.go index 87f1f6f..0d48c45 100644 --- a/pkg/connector/chatinfo.go +++ b/pkg/connector/chatinfo.go @@ -332,7 +332,7 @@ func (s *SignalClient) CreateGroup(ctx context.Context, params *bridgev2.GroupCr if err != nil { return nil, fmt.Errorf("failed to download avatar: %w", err) } - group.AvatarPath, err = s.Client.UploadGroupAvatar(ctx, avatarBytes, group.GroupIdentifier) + group.AvatarPath, err = s.Client.UploadGroupAvatar(ctx, avatarBytes, group.GroupIdentifier, group.GroupMasterKey) if err != nil { return nil, fmt.Errorf("failed to upload avatar: %w", err) } @@ -362,7 +362,7 @@ func (s *SignalClient) CreateGroup(ctx context.Context, params *bridgev2.GroupCr return nil, fmt.Errorf("failed to set portal room ID: %w", err) } } - resp, err := s.Client.CreateGroup(ctx, group, avatarBytes) + resp, err := s.Client.CreateGroup(ctx, group) if err != nil { return nil, fmt.Errorf("failed to create group: %w", err) } diff --git a/pkg/connector/handlematrix.go b/pkg/connector/handlematrix.go index 89b7d45..0f63de2 100644 --- a/pkg/connector/handlematrix.go +++ b/pkg/connector/handlematrix.go @@ -387,7 +387,7 @@ func (s *SignalClient) HandleMatrixRoomAvatar(ctx context.Context, msg *bridgev2 return false, fmt.Errorf("failed to download avatar: %w", err) } avatarHash = sha256.Sum256(data) - avatarPath, err = s.Client.UploadGroupAvatar(ctx, data, groupID) + avatarPath, err = s.Client.UploadGroupAvatar(ctx, data, groupID, "") if err != nil { return false, fmt.Errorf("failed to reupload avatar: %w", err) } diff --git a/pkg/signalmeow/attachments.go b/pkg/signalmeow/attachments.go index e09dd7e..a48414e 100644 --- a/pkg/signalmeow/attachments.go +++ b/pkg/signalmeow/attachments.go @@ -369,12 +369,17 @@ func (cli *Client) uploadAttachmentTUS( return nil } -func (cli *Client) UploadGroupAvatar(ctx context.Context, avatarBytes []byte, gid types.GroupIdentifier) (string, error) { +func (cli *Client) UploadGroupAvatar(ctx context.Context, avatarBytes []byte, gid types.GroupIdentifier, groupMasterKey types.SerializedGroupMasterKey) (string, error) { log := zerolog.Ctx(ctx) - groupMasterKey, err := cli.Store.GroupStore.MasterKeyFromGroupIdentifier(ctx, gid) - if err != nil { - log.Err(err).Msg("Could not get master key from group id") - return "", err + if groupMasterKey == "" { + var err error + groupMasterKey, err = cli.Store.GroupStore.MasterKeyFromGroupIdentifier(ctx, gid) + if err != nil { + log.Err(err).Msg("Could not get master key from group id") + return "", err + } else if groupMasterKey == "" { + return "", fmt.Errorf("no master key found for group %s", gid) + } } groupAuth, err := cli.GetAuthorizationForToday(ctx, masterKeyToBytes(groupMasterKey)) if err != nil { diff --git a/pkg/signalmeow/groups.go b/pkg/signalmeow/groups.go index b02687b..b9b9db5 100644 --- a/pkg/signalmeow/groups.go +++ b/pkg/signalmeow/groups.go @@ -1662,7 +1662,7 @@ func PrepareGroupCreation(decryptedGroup *Group) (libsignalgo.GroupMasterKey, er return masterKeyBytes, nil } -func (cli *Client) createGroupOnServer(ctx context.Context, decryptedGroup *Group, avatarBytes []byte) (*Group, error) { +func (cli *Client) createGroupOnServer(ctx context.Context, decryptedGroup *Group) (*Group, error) { log := zerolog.Ctx(ctx).With().Str("action", "CreateGroupOnServer").Logger() masterKeyBytes, err := PrepareGroupCreation(decryptedGroup) if err != nil { @@ -1677,14 +1677,6 @@ func (cli *Client) createGroupOnServer(ctx context.Context, decryptedGroup *Grou log.Err(err).Msg("DeriveGroupSecretParamsFromMasterKey error") return nil, err } - if len(avatarBytes) > 0 { - avatarPath, err := cli.UploadGroupAvatar(ctx, avatarBytes, decryptedGroup.GroupIdentifier) - if err != nil { - log.Err(err).Msg("Failed to upload group avatar") - return nil, err - } - decryptedGroup.AvatarPath = avatarPath - } encryptedGroup, err := cli.EncryptGroup(ctx, decryptedGroup, groupSecretParams) if err != nil { log.Err(err).Msg("Failed to encrypt group") @@ -1735,9 +1727,9 @@ func GenerateInviteLinkPassword() types.SerializedInviteLinkPassword { return InviteLinkPasswordFromBytes(random.Bytes(16)) } -func (cli *Client) CreateGroup(ctx context.Context, decryptedGroup *Group, avatarBytes []byte) (*Group, error) { +func (cli *Client) CreateGroup(ctx context.Context, decryptedGroup *Group) (*Group, error) { log := zerolog.Ctx(ctx).With().Str("action", "CreateGroup").Logger() - group, err := cli.createGroupOnServer(ctx, decryptedGroup, avatarBytes) + group, err := cli.createGroupOnServer(ctx, decryptedGroup) if err != nil { log.Err(err).Msg("Error creating group on server") return nil, err From aad72ca39bcc3d11ad5877c28d43906d2313cb7d Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Sat, 11 Apr 2026 01:06:38 +0300 Subject: [PATCH 552/580] dependencies: update mautrix-go --- go.mod | 4 ++-- go.sum | 8 ++++---- pkg/connector/backfill.go | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/go.mod b/go.mod index c2ff042..78ca5a0 100644 --- a/go.mod +++ b/go.mod @@ -14,13 +14,13 @@ require ( github.com/rs/zerolog v1.35.0 github.com/stretchr/testify v1.11.1 github.com/tidwall/gjson v1.18.0 - go.mau.fi/util v0.9.7 + go.mau.fi/util v0.9.8-0.20260406161447-0300c476893a golang.org/x/crypto v0.49.0 golang.org/x/exp v0.0.0-20260312153236-7ab1446f8b90 golang.org/x/net v0.52.0 google.golang.org/protobuf v1.36.11 gopkg.in/yaml.v3 v3.0.1 - maunium.net/go/mautrix v0.26.5-0.20260331163037-18917f3bdc14 + maunium.net/go/mautrix v0.26.5-0.20260410220226-744570e6f1f5 ) require ( diff --git a/go.sum b/go.sum index 44ce4a1..57a3b8d 100644 --- a/go.sum +++ b/go.sum @@ -61,8 +61,8 @@ github.com/tidwall/sjson v1.2.5 h1:kLy8mja+1c9jlljvWTlSazM7cKDRfJuR/bOJhcY5NcY= github.com/tidwall/sjson v1.2.5/go.mod h1:Fvgq9kS/6ociJEDnK0Fk1cpYF4FIW6ZF7LAe+6jwd28= github.com/yuin/goldmark v1.8.2 h1:kEGpgqJXdgbkhcOgBxkC0X0PmoPG1ZyoZ117rDVp4zE= github.com/yuin/goldmark v1.8.2/go.mod h1:ip/1k0VRfGynBgxOz0yCqHrbZXhcjxyuS66Brc7iBKg= -go.mau.fi/util v0.9.7 h1:AWGNbJfz1zRcQOKeOEYhKUG2fT+/26Gy6kyqcH8tnBg= -go.mau.fi/util v0.9.7/go.mod h1:5T2f3ZWZFAGgmFwg3dGw7YK6kIsb9lryDzvynoR98pE= +go.mau.fi/util v0.9.8-0.20260406161447-0300c476893a h1:OQQF3rTJH10l6+dcP0OKnYbNDMBTGoIZZINNJm8QBG8= +go.mau.fi/util v0.9.8-0.20260406161447-0300c476893a/go.mod h1:5T2f3ZWZFAGgmFwg3dGw7YK6kIsb9lryDzvynoR98pE= go.mau.fi/zeroconfig v0.2.0 h1:e/OGEERqVRRKlgaro7E6bh8xXiKFSXB3eNNIud7FUjU= go.mau.fi/zeroconfig v0.2.0/go.mod h1:J0Vn0prHNOm493oZoQ84kq83ZaNCYZnq+noI1b1eN8w= golang.org/x/crypto v0.49.0 h1:+Ng2ULVvLHnJ/ZFEq4KdcDd/cfjrrjjNSXNzxg0Y4U4= @@ -91,5 +91,5 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= maunium.net/go/mauflag v1.0.0 h1:YiaRc0tEI3toYtJMRIfjP+jklH45uDHtT80nUamyD4M= maunium.net/go/mauflag v1.0.0/go.mod h1:nLivPOpTpHnpzEh8jEdSL9UqO9+/KBJFmNRlwKfkPeA= -maunium.net/go/mautrix v0.26.5-0.20260331163037-18917f3bdc14 h1:y+4gtqKBMTtcVUiAeWJnvp88JLo/h3myQPsz1rZfNOY= -maunium.net/go/mautrix v0.26.5-0.20260331163037-18917f3bdc14/go.mod h1:RUSMBPky3jhXB7Ux+AptfkEvFlJ4ajZKCYiXI8YzxVE= +maunium.net/go/mautrix v0.26.5-0.20260410220226-744570e6f1f5 h1:icMEYdJZfRKWXf5AyPk/2jncA84DmfxzrjhCZ4Mm/PE= +maunium.net/go/mautrix v0.26.5-0.20260410220226-744570e6f1f5/go.mod h1:MX4DQLiBe0c7sI/wizruqdxHinSOWs42/DYsP9GH7Q4= diff --git a/pkg/connector/backfill.go b/pkg/connector/backfill.go index 3f9a611..b7b2a23 100644 --- a/pkg/connector/backfill.go +++ b/pkg/connector/backfill.go @@ -187,7 +187,7 @@ func (s *SignalClient) FetchMessages(ctx context.Context, params bridgev2.FetchM CompleteCallback: func() { // When reaching the last backwards backfill batch, delete the chat from the backup store. // If backwards backfilling isn't enabled, delete immediately after the first backfill request. - if (!params.Forward && len(items) < params.Count) || (!s.Main.Bridge.Config.Backfill.Queue.Enabled && !s.Main.Bridge.Config.Backfill.WillPaginateManually) { + if (!params.Forward && len(items) < params.Count) || !s.Main.Bridge.Config.Backfill.Queue.AnyEnabled() { err := s.Client.Store.BackupStore.DeleteBackupChat(ctx, chat.Id) if err != nil { zerolog.Ctx(ctx).Err(err).Msg("Failed to delete chat from backup store") From 1c531e03daf1b43cf3f3dc640c9361b3d0be0eb8 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Sun, 12 Apr 2026 23:15:42 +0300 Subject: [PATCH 553/580] signalmeow/groups: catch missing group master key --- pkg/signalmeow/groups.go | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/pkg/signalmeow/groups.go b/pkg/signalmeow/groups.go index b9b9db5..6dcd4ea 100644 --- a/pkg/signalmeow/groups.go +++ b/pkg/signalmeow/groups.go @@ -1513,11 +1513,15 @@ func (cli *Client) patchGroup(ctx context.Context, groupChange *signalpb.GroupCh return &changeResp, nil } +var ErrGroupMasterKeyNotFound = errors.New("group master key not found in store") + func (cli *Client) UpdateGroup(ctx context.Context, groupChange *GroupChange, gid types.GroupIdentifier) (uint32, error) { log := zerolog.Ctx(ctx).With().Str("action", "UpdateGroup").Logger() groupMasterKey, err := cli.Store.GroupStore.MasterKeyFromGroupIdentifier(ctx, gid) if err != nil { return 0, fmt.Errorf("failed to get master key for group: %w", err) + } else if groupMasterKey == "" { + return 0, ErrGroupMasterKeyNotFound } groupChange.GroupMasterKey = groupMasterKey masterKeyBytes := masterKeyToBytes(groupMasterKey) @@ -1752,7 +1756,7 @@ func (cli *Client) GetGroupHistoryPage(ctx context.Context, gid types.GroupIdent return nil, err } if groupMasterKey == "" { - return nil, fmt.Errorf("No group master key found for group identifier %s", gid) + return nil, ErrGroupMasterKeyNotFound } masterKeyBytes := masterKeyToBytes(groupMasterKey) groupAuth, err := cli.GetAuthorizationForToday(ctx, masterKeyBytes) From fdb9a61601907d5391ab8a6716e886192ac55b58 Mon Sep 17 00:00:00 2001 From: Rowan <151715+rwky@users.noreply.github.com> Date: Mon, 13 Apr 2026 14:49:01 +0100 Subject: [PATCH 554/580] docker: add missing protobuf-dev package to non-ci dockerfile (#646) --- Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index 63e7542..1acc3d2 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,6 +1,6 @@ # -- Build libsignal (with Rust) -- FROM rust:1-alpine AS rust-builder -RUN apk add --no-cache git make cmake protoc musl-dev g++ clang-dev +RUN apk add --no-cache git make cmake protoc musl-dev g++ clang-dev protobuf-dev WORKDIR /build # Copy all files needed for Rust build, and no Go files From 952e7c473b28884eea56c0d60f107f0ef2ded296 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Mon, 13 Apr 2026 15:31:31 +0300 Subject: [PATCH 555/580] libsignal: update to v0.92.1 --- pkg/libsignalgo/libsignal | 2 +- pkg/libsignalgo/libsignal-ffi.h | 102 +++++++++++++++++++--------- pkg/libsignalgo/logging.go | 14 +++- pkg/libsignalgo/message.go | 3 +- pkg/libsignalgo/prekey.go | 3 +- pkg/libsignalgo/sealedsender.go | 13 +++- pkg/libsignalgo/session_test.go | 12 ++-- pkg/libsignalgo/setup_test.go | 2 + pkg/libsignalgo/version.go | 2 +- pkg/signalmeow/misc.go | 2 + pkg/signalmeow/receiving_decrypt.go | 5 ++ pkg/signalmeow/sending.go | 9 ++- 12 files changed, 120 insertions(+), 49 deletions(-) diff --git a/pkg/libsignalgo/libsignal b/pkg/libsignalgo/libsignal index a5e7667..b58bd7d 160000 --- a/pkg/libsignalgo/libsignal +++ b/pkg/libsignalgo/libsignal @@ -1 +1 @@ -Subproject commit a5e76674882a89bac1ed3f4a982120652966d21e +Subproject commit b58bd7d5dfa0a391486df4210fd83bab96b9b479 diff --git a/pkg/libsignalgo/libsignal-ffi.h b/pkg/libsignalgo/libsignal-ffi.h index 59409c8..fe3bf52 100644 --- a/pkg/libsignalgo/libsignal-ffi.h +++ b/pkg/libsignalgo/libsignal-ffi.h @@ -261,6 +261,7 @@ typedef enum { SignalErrorCodeRequestUnauthorized = 220, SignalErrorCodeMismatchedDevices = 221, SignalErrorCodeServiceIdNotFound = 222, + SignalErrorCodeUploadTooLarge = 223, } SignalErrorCode; enum SignalSvr2CredentialsResult { @@ -511,6 +512,46 @@ typedef struct { const SignalAuthenticatedChatConnection *raw; } SignalConstPointerAuthenticatedChatConnection; +/** + * A type alias to be used with [`OwnedBufferOf`], so that `OwnedBufferOf` and + * `OwnedBufferOf<*const c_char>` get distinct names. + */ +typedef const char *SignalCStringPtr; + +/** + * A representation of a array allocated on the Rust heap for use in C code. + */ +typedef struct { + SignalCStringPtr *base; + /** + * The number of elements in the buffer (not necessarily the number of bytes). + */ + size_t length; +} SignalOwnedBufferOfCStringPtr; + +typedef struct { + uint32_t cdn; + SignalCStringPtr key; + SignalOwnedBufferOfCStringPtr header_keys; + SignalOwnedBufferOfCStringPtr header_values; + SignalCStringPtr signed_upload_url; +} SignalFfiUploadForm; + +/** + * A C callback used to report the results of Rust futures. + * + * cbindgen will produce independent C types like `SignalCPromisei32` and + * `SignalCPromiseProtocolAddress`. + * + * This derives Copy because it behaves like a C type; nevertheless, a promise should still only be + * completed once. + */ +typedef struct { + void (*complete)(SignalFfiError *error, const SignalFfiUploadForm *result, const void *context); + const void *context; + SignalCancellationId cancellation_id; +} SignalCPromiseFfiUploadForm; + typedef SignalConnectionInfo SignalChatConnectionInfo; typedef struct { @@ -562,23 +603,6 @@ typedef struct { const SignalFfiChatListenerStruct *raw; } SignalConstPointerFfiChatListenerStruct; -/** - * A type alias to be used with [`OwnedBufferOf`], so that `OwnedBufferOf` and - * `OwnedBufferOf<*const c_char>` get distinct names. - */ -typedef const char *SignalCStringPtr; - -/** - * A representation of a array allocated on the Rust heap for use in C code. - */ -typedef struct { - SignalCStringPtr *base; - /** - * The number of elements in the buffer (not necessarily the number of bytes). - */ - size_t length; -} SignalOwnedBufferOfCStringPtr; - typedef struct { uint16_t status; const char *message; @@ -945,6 +969,11 @@ typedef struct { SignalOwnedBuffer second; } SignalPairOfc_charOwnedBufferOfc_uchar; +typedef struct { + SignalPairOfc_charOwnedBufferOfc_uchar first; + int64_t second; +} SignalPairOfPairOfc_charOwnedBufferOfc_uchari64; + typedef struct { const char *first; bool second; @@ -1075,15 +1104,18 @@ typedef struct { SignalIncrementalMac *raw; } SignalMutPointerIncrementalMac; -typedef void (*SignalLogCallback)(void *ctx, SignalLogLevel level, const char *file, uint32_t line, const char *message); +typedef int (*SignalFfiLoggerLog)(void *ctx, SignalLogLevel level, const char *file, uint32_t line, const char *message); -typedef void (*SignalLogFlushCallback)(void *ctx); +typedef int (*SignalFfiLoggerFlush)(void *ctx); + +typedef void (*SignalFfiLoggerDestroy)(void *ctx); typedef struct { void *ctx; - SignalLogCallback log; - SignalLogFlushCallback flush; -} SignalFfiLogger; + SignalFfiLoggerLog log; + SignalFfiLoggerFlush flush; + SignalFfiLoggerDestroy destroy; +} SignalFfiLoggerStruct; /** * A C callback used to report the results of Rust futures. @@ -1695,6 +1727,8 @@ SignalFfiError *signal_authenticated_chat_connection_destroy(SignalMutPointerAut SignalFfiError *signal_authenticated_chat_connection_disconnect(SignalCPromisebool *promise, SignalConstPointerTokioAsyncContext async_runtime, SignalConstPointerAuthenticatedChatConnection chat); +SignalFfiError *signal_authenticated_chat_connection_get_upload_form(SignalCPromiseFfiUploadForm *promise, SignalConstPointerTokioAsyncContext async_runtime, SignalConstPointerAuthenticatedChatConnection chat, uint64_t upload_length); + SignalFfiError *signal_authenticated_chat_connection_info(SignalMutPointerChatConnectionInfo *out, SignalConstPointerAuthenticatedChatConnection chat); SignalFfiError *signal_authenticated_chat_connection_init_listener(SignalConstPointerAuthenticatedChatConnection chat, SignalConstPointerFfiChatListenerStruct listener); @@ -1865,7 +1899,7 @@ SignalFfiError *signal_create_call_link_credential_response_check_valid_contents SignalFfiError *signal_decrypt_message(SignalOwnedBuffer *out, SignalConstPointerSignalMessage message, SignalConstPointerProtocolAddress protocol_address, SignalConstPointerFfiSessionStoreStruct session_store, SignalConstPointerFfiIdentityKeyStoreStruct identity_key_store); -SignalFfiError *signal_decrypt_pre_key_message(SignalOwnedBuffer *out, SignalConstPointerPreKeySignalMessage message, SignalConstPointerProtocolAddress protocol_address, SignalConstPointerFfiSessionStoreStruct session_store, SignalConstPointerFfiIdentityKeyStoreStruct identity_key_store, SignalConstPointerFfiPreKeyStoreStruct prekey_store, SignalConstPointerFfiSignedPreKeyStoreStruct signed_prekey_store, SignalConstPointerFfiKyberPreKeyStoreStruct kyber_prekey_store); +SignalFfiError *signal_decrypt_pre_key_message(SignalOwnedBuffer *out, SignalConstPointerPreKeySignalMessage message, SignalConstPointerProtocolAddress protocol_address, SignalConstPointerProtocolAddress local_address, SignalConstPointerFfiSessionStoreStruct session_store, SignalConstPointerFfiIdentityKeyStoreStruct identity_key_store, SignalConstPointerFfiPreKeyStoreStruct prekey_store, SignalConstPointerFfiSignedPreKeyStoreStruct signed_prekey_store, SignalConstPointerFfiKyberPreKeyStoreStruct kyber_prekey_store); SignalFfiError *signal_decryption_error_message_clone(SignalMutPointerDecryptionErrorMessage *new_obj, SignalConstPointerDecryptionErrorMessage obj); @@ -1891,7 +1925,7 @@ SignalFfiError *signal_device_transfer_generate_private_key(SignalOwnedBuffer *o SignalFfiError *signal_device_transfer_generate_private_key_with_format(SignalOwnedBuffer *out, uint8_t key_format); -SignalFfiError *signal_encrypt_message(SignalMutPointerCiphertextMessage *out, SignalBorrowedBuffer ptext, SignalConstPointerProtocolAddress protocol_address, SignalConstPointerFfiSessionStoreStruct session_store, SignalConstPointerFfiIdentityKeyStoreStruct identity_key_store, uint64_t now); +SignalFfiError *signal_encrypt_message(SignalMutPointerCiphertextMessage *out, SignalBorrowedBuffer ptext, SignalConstPointerProtocolAddress protocol_address, SignalConstPointerProtocolAddress local_address, SignalConstPointerFfiSessionStoreStruct session_store, SignalConstPointerFfiIdentityKeyStoreStruct identity_key_store, uint64_t now); void signal_error_free(SignalFfiError *err); @@ -1905,7 +1939,7 @@ SignalFfiError *signal_error_get_mismatched_device_errors(SignalOwnedBufferOfFfi SignalFfiError *signal_error_get_our_fingerprint_version(uint32_t *out, SignalUnwindSafeArgSignalFfiError err); -SignalFfiError *signal_error_get_rate_limit_challenge(SignalPairOfc_charOwnedBufferOfc_uchar *out, SignalUnwindSafeArgSignalFfiError err); +SignalFfiError *signal_error_get_rate_limit_challenge(SignalPairOfPairOfc_charOwnedBufferOfc_uchari64 *out, SignalUnwindSafeArgSignalFfiError err); SignalFfiError *signal_error_get_registration_error_not_deliverable(SignalPairOfc_charbool *out, SignalUnwindSafeArgSignalFfiError err); @@ -2080,18 +2114,16 @@ SignalFfiError *signal_incremental_mac_initialize(SignalMutPointerIncrementalMac SignalFfiError *signal_incremental_mac_update(SignalOwnedBuffer *out, SignalMutPointerIncrementalMac mac, SignalBorrowedBuffer bytes, uint32_t offset, uint32_t length); -bool signal_init_logger(SignalLogLevel max_level, SignalFfiLogger logger); +bool signal_init_logger(SignalLogLevel max_level, SignalFfiLoggerStruct logger); SignalFfiError *signal_key_transparency_aci_search_key(SignalOwnedBuffer *out, const SignalServiceIdFixedWidthBinaryBytes *aci); +SignalFfiError *signal_key_transparency_check(SignalCPromiseOwnedBufferOfc_uchar *promise, SignalConstPointerTokioAsyncContext async_runtime, uint8_t environment, SignalConstPointerUnauthenticatedChatConnection chat_connection, const SignalServiceIdFixedWidthBinaryBytes *aci, SignalConstPointerPublicKey aci_identity_key, const char *e164, SignalOptionalBorrowedSliceOfc_uchar unidentified_access_key, SignalOptionalBorrowedSliceOfc_uchar username_hash, SignalOptionalBorrowedSliceOfc_uchar account_data, SignalBorrowedBuffer last_distinguished_tree_head, bool is_self_check, bool is_e164_discoverable); + SignalFfiError *signal_key_transparency_distinguished(SignalCPromiseOwnedBufferOfc_uchar *promise, SignalConstPointerTokioAsyncContext async_runtime, uint8_t environment, SignalConstPointerUnauthenticatedChatConnection chat_connection, SignalOptionalBorrowedSliceOfc_uchar last_distinguished_tree_head); SignalFfiError *signal_key_transparency_e164_search_key(SignalOwnedBuffer *out, const char *e164); -SignalFfiError *signal_key_transparency_monitor(SignalCPromiseOwnedBufferOfc_uchar *promise, SignalConstPointerTokioAsyncContext async_runtime, uint8_t environment, SignalConstPointerUnauthenticatedChatConnection chat_connection, const SignalServiceIdFixedWidthBinaryBytes *aci, SignalConstPointerPublicKey aci_identity_key, const char *e164, SignalOptionalBorrowedSliceOfc_uchar unidentified_access_key, SignalOptionalBorrowedSliceOfc_uchar username_hash, SignalOptionalBorrowedSliceOfc_uchar account_data, SignalBorrowedBuffer last_distinguished_tree_head, bool is_self_monitor); - -SignalFfiError *signal_key_transparency_search(SignalCPromiseOwnedBufferOfc_uchar *promise, SignalConstPointerTokioAsyncContext async_runtime, uint8_t environment, SignalConstPointerUnauthenticatedChatConnection chat_connection, const SignalServiceIdFixedWidthBinaryBytes *aci, SignalConstPointerPublicKey aci_identity_key, const char *e164, SignalOptionalBorrowedSliceOfc_uchar unidentified_access_key, SignalOptionalBorrowedSliceOfc_uchar username_hash, SignalOptionalBorrowedSliceOfc_uchar account_data, SignalBorrowedBuffer last_distinguished_tree_head); - SignalFfiError *signal_key_transparency_username_hash_search_key(SignalOwnedBuffer *out, SignalBorrowedBuffer hash); SignalFfiError *signal_kyber_key_pair_clone(SignalMutPointerKyberKeyPair *new_obj, SignalConstPointerKyberKeyPair obj); @@ -2724,16 +2756,22 @@ SignalFfiError *signal_tokio_async_context_new(SignalMutPointerTokioAsyncContext SignalFfiError *signal_unauthenticated_chat_connection_account_exists(SignalCPromisebool *promise, SignalConstPointerTokioAsyncContext async_runtime, SignalConstPointerUnauthenticatedChatConnection chat, const SignalServiceIdFixedWidthBinaryBytes *account); +SignalFfiError *signal_unauthenticated_chat_connection_backup_get_media_upload_form(SignalCPromiseFfiUploadForm *promise, SignalConstPointerTokioAsyncContext async_runtime, SignalConstPointerUnauthenticatedChatConnection chat, SignalBorrowedBuffer credential, SignalBorrowedBuffer server_keys, SignalConstPointerPrivateKey signing_key, uint64_t upload_size, int64_t rng); + +SignalFfiError *signal_unauthenticated_chat_connection_backup_get_upload_form(SignalCPromiseFfiUploadForm *promise, SignalConstPointerTokioAsyncContext async_runtime, SignalConstPointerUnauthenticatedChatConnection chat, SignalBorrowedBuffer credential, SignalBorrowedBuffer server_keys, SignalConstPointerPrivateKey signing_key, uint64_t upload_size, int64_t rng); + SignalFfiError *signal_unauthenticated_chat_connection_connect(SignalCPromiseMutPointerUnauthenticatedChatConnection *promise, SignalConstPointerTokioAsyncContext async_runtime, SignalConstPointerConnectionManager connection_manager, SignalBorrowedBytestringArray languages); SignalFfiError *signal_unauthenticated_chat_connection_destroy(SignalMutPointerUnauthenticatedChatConnection p); SignalFfiError *signal_unauthenticated_chat_connection_disconnect(SignalCPromisebool *promise, SignalConstPointerTokioAsyncContext async_runtime, SignalConstPointerUnauthenticatedChatConnection chat); -SignalFfiError *signal_unauthenticated_chat_connection_get_pre_keys_access_group_auth(SignalCPromiseFfiPreKeysResponse *promise, SignalConstPointerTokioAsyncContext async_runtime, SignalConstPointerUnauthenticatedChatConnection chat, SignalBorrowedBuffer auth, const SignalServiceIdFixedWidthBinaryBytes *target, int32_t device); - SignalFfiError *signal_unauthenticated_chat_connection_get_pre_keys_access_key_auth(SignalCPromiseFfiPreKeysResponse *promise, SignalConstPointerTokioAsyncContext async_runtime, SignalConstPointerUnauthenticatedChatConnection chat, const uint8_t (*auth)[16], const SignalServiceIdFixedWidthBinaryBytes *target, int32_t device); +SignalFfiError *signal_unauthenticated_chat_connection_get_pre_keys_group_auth(SignalCPromiseFfiPreKeysResponse *promise, SignalConstPointerTokioAsyncContext async_runtime, SignalConstPointerUnauthenticatedChatConnection chat, SignalBorrowedBuffer auth, const SignalServiceIdFixedWidthBinaryBytes *target, int32_t device); + +SignalFfiError *signal_unauthenticated_chat_connection_get_pre_keys_unrestricted_auth(SignalCPromiseFfiPreKeysResponse *promise, SignalConstPointerTokioAsyncContext async_runtime, SignalConstPointerUnauthenticatedChatConnection chat, const SignalServiceIdFixedWidthBinaryBytes *target, int32_t device); + SignalFfiError *signal_unauthenticated_chat_connection_info(SignalMutPointerChatConnectionInfo *out, SignalConstPointerUnauthenticatedChatConnection chat); SignalFfiError *signal_unauthenticated_chat_connection_init_listener(SignalConstPointerUnauthenticatedChatConnection chat, SignalConstPointerFfiChatListenerStruct listener); diff --git a/pkg/libsignalgo/logging.go b/pkg/libsignalgo/logging.go index 9d21afa..1926c23 100644 --- a/pkg/libsignalgo/logging.go +++ b/pkg/libsignalgo/logging.go @@ -21,6 +21,7 @@ package libsignalgo extern void signal_log_callback(void *ctx, SignalLogLevel level, char *file, uint32_t line, char *message); extern void signal_log_flush_callback(void *ctx); +extern void signal_log_destroy_callback(void *ctx); */ import "C" import ( @@ -40,6 +41,11 @@ func signal_log_flush_callback(ctx unsafe.Pointer) { ffiLogger.Flush() } +//export signal_log_destroy_callback +func signal_log_destroy_callback(ctx unsafe.Pointer) { + ffiLogger.Destroy() +} + type LogLevel int const ( @@ -53,12 +59,14 @@ const ( type Logger interface { Log(level LogLevel, file string, line uint, message string) Flush() + Destroy() } func InitLogger(level LogLevel, logger Logger) { ffiLogger = logger - C.signal_init_logger(C.SignalLogLevel(level), C.SignalFfiLogger{ - log: C.SignalLogCallback(C.signal_log_callback), - flush: C.SignalLogFlushCallback(C.signal_log_flush_callback), + C.signal_init_logger(C.SignalLogLevel(level), C.SignalFfiLoggerStruct{ + log: C.SignalFfiLoggerLog(C.signal_log_callback), + flush: C.SignalFfiLoggerFlush(C.signal_log_flush_callback), + destroy: C.SignalFfiLoggerDestroy(C.signal_log_destroy_callback), }) } diff --git a/pkg/libsignalgo/message.go b/pkg/libsignalgo/message.go index f016daa..1b581c0 100644 --- a/pkg/libsignalgo/message.go +++ b/pkg/libsignalgo/message.go @@ -27,7 +27,7 @@ import ( "time" ) -func Encrypt(ctx context.Context, plaintext []byte, forAddress *Address, sessionStore SessionStore, identityKeyStore IdentityKeyStore) (*CiphertextMessage, error) { +func Encrypt(ctx context.Context, plaintext []byte, forAddress, localAddress *Address, sessionStore SessionStore, identityKeyStore IdentityKeyStore) (*CiphertextMessage, error) { var ciphertextMessage C.SignalMutPointerCiphertextMessage var now C.uint64_t = C.uint64_t(time.Now().Unix()) callbackCtx := NewCallbackContext(ctx) @@ -36,6 +36,7 @@ func Encrypt(ctx context.Context, plaintext []byte, forAddress *Address, session &ciphertextMessage, BytesToBuffer(plaintext), forAddress.constPtr(), + localAddress.constPtr(), callbackCtx.wrapSessionStore(sessionStore), callbackCtx.wrapIdentityKeyStore(identityKeyStore), now, diff --git a/pkg/libsignalgo/prekey.go b/pkg/libsignalgo/prekey.go index 4d01f89..29e640e 100644 --- a/pkg/libsignalgo/prekey.go +++ b/pkg/libsignalgo/prekey.go @@ -26,7 +26,7 @@ import ( "runtime" ) -func DecryptPreKey(ctx context.Context, preKeyMessage *PreKeyMessage, fromAddress *Address, sessionStore SessionStore, identityStore IdentityKeyStore, preKeyStore PreKeyStore, signedPreKeyStore SignedPreKeyStore, kyberPreKeyStore KyberPreKeyStore) ([]byte, error) { +func DecryptPreKey(ctx context.Context, preKeyMessage *PreKeyMessage, fromAddress, localAddress *Address, sessionStore SessionStore, identityStore IdentityKeyStore, preKeyStore PreKeyStore, signedPreKeyStore SignedPreKeyStore, kyberPreKeyStore KyberPreKeyStore) ([]byte, error) { callbackCtx := NewCallbackContext(ctx) defer callbackCtx.Unref() var decrypted C.SignalOwnedBuffer = C.SignalOwnedBuffer{} @@ -34,6 +34,7 @@ func DecryptPreKey(ctx context.Context, preKeyMessage *PreKeyMessage, fromAddres &decrypted, preKeyMessage.constPtr(), fromAddress.constPtr(), + localAddress.constPtr(), callbackCtx.wrapSessionStore(sessionStore), callbackCtx.wrapIdentityKeyStore(identityStore), callbackCtx.wrapPreKeyStore(preKeyStore), diff --git a/pkg/libsignalgo/sealedsender.go b/pkg/libsignalgo/sealedsender.go index 56ffe8b..84ff254 100644 --- a/pkg/libsignalgo/sealedsender.go +++ b/pkg/libsignalgo/sealedsender.go @@ -44,8 +44,17 @@ func NewSealedSenderAddress(e164 string, uuid uuid.UUID, deviceID uint32) *Seale } } -func SealedSenderEncryptPlaintext(ctx context.Context, message []byte, contentHint UnidentifiedSenderMessageContentHint, forAddress *Address, fromSenderCert *SenderCertificate, sessionStore SessionStore, identityStore IdentityKeyStore, groupID *GroupIdentifier) ([]byte, error) { - ciphertextMessage, err := Encrypt(ctx, message, forAddress, sessionStore, identityStore) +func SealedSenderEncryptPlaintext( + ctx context.Context, + message []byte, + contentHint UnidentifiedSenderMessageContentHint, + forAddress, localAddress *Address, + fromSenderCert *SenderCertificate, + sessionStore SessionStore, + identityStore IdentityKeyStore, + groupID *GroupIdentifier, +) ([]byte, error) { + ciphertextMessage, err := Encrypt(ctx, message, forAddress, localAddress, sessionStore, identityStore) if err != nil { return nil, err } diff --git a/pkg/libsignalgo/session_test.go b/pkg/libsignalgo/session_test.go index 6d0b720..4bde894 100644 --- a/pkg/libsignalgo/session_test.go +++ b/pkg/libsignalgo/session_test.go @@ -136,7 +136,7 @@ func TestSessionCipher(t *testing.T) { alicePlaintext := []byte{8, 6, 7, 5, 3, 0, 9} - aliceCiphertext, err := libsignalgo.Encrypt(ctx, alicePlaintext, bobAddress, aliceStore, aliceStore) + aliceCiphertext, err := libsignalgo.Encrypt(ctx, alicePlaintext, bobAddress, aliceAddress, aliceStore, aliceStore) assert.NoError(t, err) aliceCiphertextMessageType, err := aliceCiphertext.MessageType() assert.NoError(t, err) @@ -147,13 +147,13 @@ func TestSessionCipher(t *testing.T) { bobCiphertext, err := libsignalgo.DeserializePreKeyMessage(aliceCiphertextSerialized) assert.NoError(t, err) - bobPlaintext, err := libsignalgo.DecryptPreKey(ctx, bobCiphertext, aliceAddress, bobStore, bobStore, bobStore, bobStore, bobStore) + bobPlaintext, err := libsignalgo.DecryptPreKey(ctx, bobCiphertext, aliceAddress, bobAddress, bobStore, bobStore, bobStore, bobStore, bobStore) assert.NoError(t, err) assert.Equal(t, alicePlaintext, bobPlaintext) bobPlaintext2 := []byte{23} - bobCiphertext2, err := libsignalgo.Encrypt(ctx, bobPlaintext2, aliceAddress, bobStore, bobStore) + bobCiphertext2, err := libsignalgo.Encrypt(ctx, bobPlaintext2, aliceAddress, bobAddress, bobStore, bobStore) assert.NoError(t, err) bobCiphertext2MessageType, err := bobCiphertext2.MessageType() assert.NoError(t, err) @@ -187,7 +187,7 @@ func TestSessionCipherWithBadStore(t *testing.T) { alicePlaintext := []byte{8, 6, 7, 5, 3, 0, 9} - aliceCiphertext, err := libsignalgo.Encrypt(ctx, alicePlaintext, bobAddress, aliceStore, aliceStore) + aliceCiphertext, err := libsignalgo.Encrypt(ctx, alicePlaintext, bobAddress, aliceAddress, aliceStore, aliceStore) assert.NoError(t, err) aliceCiphertextMessageType, err := aliceCiphertext.MessageType() assert.NoError(t, err) @@ -198,7 +198,7 @@ func TestSessionCipherWithBadStore(t *testing.T) { bobCiphertext, err := libsignalgo.DeserializePreKeyMessage(aliceCiphertextSerialized) assert.NoError(t, err) t.Skip("This test is broken") // TODO fix - _, err = libsignalgo.DecryptPreKey(ctx, bobCiphertext, aliceAddress, bobStore, bobStore, bobStore, bobStore, bobStore) + _, err = libsignalgo.DecryptPreKey(ctx, bobCiphertext, aliceAddress, bobAddress, bobStore, bobStore, bobStore, bobStore, bobStore) require.Error(t, err) assert.Equal(t, "Test error", err.Error()) } @@ -241,7 +241,7 @@ func TestSealedSenderEncrypt_Repeated(t *testing.T) { }() for i := 0; i < 100; i++ { message := []byte(fmt.Sprintf("%04d vision", i)) - ciphertext, err := libsignalgo.SealedSenderEncryptPlaintext(ctx, message, libsignalgo.UnidentifiedSenderMessageContentHintDefault, bobAddress, senderCert, aliceStore, aliceStore, nil) + ciphertext, err := libsignalgo.SealedSenderEncryptPlaintext(ctx, message, libsignalgo.UnidentifiedSenderMessageContentHintDefault, bobAddress, aliceAddress, senderCert, aliceStore, aliceStore, nil) require.NoError(t, err) assert.NotNil(t, ciphertext) } diff --git a/pkg/libsignalgo/setup_test.go b/pkg/libsignalgo/setup_test.go index c22149d..47d7d77 100644 --- a/pkg/libsignalgo/setup_test.go +++ b/pkg/libsignalgo/setup_test.go @@ -54,6 +54,8 @@ func (FFILogger) Log(level libsignalgo.LogLevel, file string, line uint, message func (FFILogger) Flush() {} +func (FFILogger) Destroy() {} + var loggingSetup = false func setupLogging() { diff --git a/pkg/libsignalgo/version.go b/pkg/libsignalgo/version.go index ccd0d51..bd14084 100644 --- a/pkg/libsignalgo/version.go +++ b/pkg/libsignalgo/version.go @@ -2,4 +2,4 @@ package libsignalgo -const Version = "v0.89.1" +const Version = "v0.92.1" diff --git a/pkg/signalmeow/misc.go b/pkg/signalmeow/misc.go index 467f646..70d3ba5 100644 --- a/pkg/signalmeow/misc.go +++ b/pkg/signalmeow/misc.go @@ -69,6 +69,8 @@ func (l FFILogger) Log(level libsignalgo.LogLevel, file string, line uint, messa func (FFILogger) Flush() {} +func (FFILogger) Destroy() {} + // Ensure FFILogger implements the Logger interface var _ libsignalgo.Logger = FFILogger{} diff --git a/pkg/signalmeow/receiving_decrypt.go b/pkg/signalmeow/receiving_decrypt.go index 958f84f..24b76ff 100644 --- a/pkg/signalmeow/receiving_decrypt.go +++ b/pkg/signalmeow/receiving_decrypt.go @@ -188,12 +188,17 @@ func (cli *Client) prekeyDecrypt( if is == nil { return nil, fmt.Errorf("no identity store found for %s", destination) } + destinationAddress, err := destination.Address(uint(cli.Store.DeviceID)) + if err != nil { + return nil, fmt.Errorf("failed to get own/destination address: %w", err) + } plaintext, ciphertextHash, err := cli.bufferedDecryptTxn(ctx, encryptedContent, serverTimestamp, func(ctx context.Context) ([]byte, error) { return libsignalgo.DecryptPreKey( ctx, preKeyMessage, sender, + destinationAddress, ss, is, pks, diff --git a/pkg/signalmeow/sending.go b/pkg/signalmeow/sending.go index 568b4d4..94f1dcf 100644 --- a/pkg/signalmeow/sending.go +++ b/pkg/signalmeow/sending.go @@ -171,6 +171,10 @@ func (cli *Client) buildMessagesToSend( } else if len(sessions) == 0 { return nil, fmt.Errorf("no sessions found for recipient %s", recipient.String()) } + localAddress, err := cli.Store.ACIServiceID().Address(uint(cli.Store.DeviceID)) + if err != nil { + return nil, fmt.Errorf("failed to get own address: %w", err) + } messages := make([]MyMessage, 0, len(sessions)) for _, tuple := range sessions { @@ -193,7 +197,7 @@ func (cli *Client) buildMessagesToSend( includeE164 := groupID == nil && cli.Store.AccountRecord.GetPhoneNumberSharingMode() == signalpb.AccountRecord_EVERYBODY envelopeType, encryptedPayload, err := cli.buildMessageToSend( - ctx, tuple.Address, paddedMessage, getContentHint(content), ctmOverride, groupID, includeE164, unauthenticated, + ctx, tuple.Address, localAddress, paddedMessage, getContentHint(content), ctmOverride, groupID, includeE164, unauthenticated, ) if err != nil { return nil, err @@ -232,7 +236,7 @@ func ctmTypeToEnvelopeType(ctmType libsignalgo.CiphertextMessageType) signalpb.E func (cli *Client) buildMessageToSend( ctx context.Context, - recipientAddress *libsignalgo.Address, + recipientAddress, localAddress *libsignalgo.Address, paddedMessage []byte, contentHint libsignalgo.UnidentifiedSenderMessageContentHint, ciphertextMessage *libsignalgo.CiphertextMessage, @@ -244,6 +248,7 @@ func (cli *Client) buildMessageToSend( ctx, paddedMessage, recipientAddress, + localAddress, cli.Store.ACISessionStore, cli.Store.ACIIdentityStore, ) From 38f2ba9430c23bee7ded9a9a36f11e6eb540d4f3 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Mon, 13 Apr 2026 15:31:43 +0300 Subject: [PATCH 556/580] signalmeow/groups: use shared error type for unknown group master key --- pkg/signalmeow/groups.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/signalmeow/groups.go b/pkg/signalmeow/groups.go index 6dcd4ea..147d63d 100644 --- a/pkg/signalmeow/groups.go +++ b/pkg/signalmeow/groups.go @@ -619,7 +619,7 @@ func (cli *Client) fetchGroupByID(ctx context.Context, gid types.GroupIdentifier return nil, fmt.Errorf("failed to get group master key: %w", err) } if groupMasterKey == "" { - return nil, fmt.Errorf("No group master key found for group identifier %s", gid) + return nil, fmt.Errorf("%w for %s", ErrGroupMasterKeyNotFound, gid) } return cli.fetchGroupWithMasterKey(ctx, groupMasterKey) } From 2297e6b48bfe727aaaf49ceb4fdb9efe7a9d5fae Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Mon, 13 Apr 2026 16:32:10 +0300 Subject: [PATCH 557/580] signalmeow: update protobufs Content and SyncMessage switched to use oneofs, which is why a lot of code changed --- pkg/connector/handlematrix.go | 89 +- pkg/signalmeow/protobuf/Groups.pb.go | 271 +++- pkg/signalmeow/protobuf/Groups.proto | 14 +- pkg/signalmeow/protobuf/Provisioning.pb.go | 15 +- pkg/signalmeow/protobuf/Provisioning.proto | 2 +- pkg/signalmeow/protobuf/SignalService.pb.go | 1410 ++++++++++------ pkg/signalmeow/protobuf/SignalService.proto | 166 +- pkg/signalmeow/protobuf/StorageService.pb.go | 28 +- pkg/signalmeow/protobuf/StorageService.proto | 3 +- pkg/signalmeow/protobuf/backuppb/Backup.pb.go | 1418 ++++++++++------- pkg/signalmeow/protobuf/backuppb/Backup.proto | 25 +- pkg/signalmeow/protobuf/update-protos.sh | 15 +- pkg/signalmeow/provisioning.go | 12 +- pkg/signalmeow/receiving.go | 293 ++-- pkg/signalmeow/receiving_decrypt.go | 17 +- pkg/signalmeow/retry.go | 12 +- pkg/signalmeow/sending.go | 279 ++-- 17 files changed, 2475 insertions(+), 1594 deletions(-) diff --git a/pkg/connector/handlematrix.go b/pkg/connector/handlematrix.go index 0f63de2..7bcb214 100644 --- a/pkg/connector/handlematrix.go +++ b/pkg/connector/handlematrix.go @@ -137,7 +137,7 @@ func (s *SignalClient) doSendMessage( } msgID := signalid.MakeMessageID(s.Client.Store.ACI, ts) msg.AddPendingToIgnore(networkid.TransactionID(msgID)) - err := s.sendMessage(ctx, msg.Portal.ID, &signalpb.Content{DataMessage: converted}) + err := s.sendMessage(ctx, msg.Portal.ID, signalmeow.WrapDataMessage(converted)) if err != nil { return nil, bridgev2.WrapErrorInStatus(err).WithSendNotice(true) } @@ -173,10 +173,10 @@ func (s *SignalClient) HandleMatrixEdit(ctx context.Context, msg *bridgev2.Matri } ts := getTimestampForEvent(msg.InputTransactionID, msg.Event, msg.OrigSender) converted.Timestamp = &ts - err = s.sendMessage(ctx, msg.Portal.ID, &signalpb.Content{EditMessage: &signalpb.EditMessage{ + err = s.sendMessage(ctx, msg.Portal.ID, signalmeow.WrapEditMessage(&signalpb.EditMessage{ TargetSentTimestamp: proto.Uint64(targetSentTimestamp), DataMessage: converted, - }}) + })) if err != nil { return bridgev2.WrapErrorInStatus(err).WithSendNotice(true) } @@ -200,19 +200,16 @@ func (s *SignalClient) HandleMatrixReaction(ctx context.Context, msg *bridgev2.M return nil, fmt.Errorf("failed to parse target message ID: %w", err) } ts := getTimestampForEvent(msg.InputTransactionID, msg.Event, msg.OrigSender) - wrappedContent := &signalpb.Content{ - DataMessage: &signalpb.DataMessage{ - Timestamp: proto.Uint64(ts), - RequiredProtocolVersion: proto.Uint32(uint32(signalpb.DataMessage_REACTIONS)), - Reaction: &signalpb.DataMessage_Reaction{ - Emoji: proto.String(msg.PreHandleResp.Emoji), - Remove: proto.Bool(false), - TargetAuthorAciBinary: targetAuthorACI[:], - TargetSentTimestamp: proto.Uint64(targetSentTimestamp), - }, + err = s.sendMessage(ctx, msg.Portal.ID, signalmeow.WrapDataMessage(&signalpb.DataMessage{ + Timestamp: proto.Uint64(ts), + RequiredProtocolVersion: proto.Uint32(uint32(signalpb.DataMessage_REACTIONS)), + Reaction: &signalpb.DataMessage_Reaction{ + Emoji: proto.String(msg.PreHandleResp.Emoji), + Remove: proto.Bool(false), + TargetAuthorAciBinary: targetAuthorACI[:], + TargetSentTimestamp: proto.Uint64(targetSentTimestamp), }, - } - err = s.sendMessage(ctx, msg.Portal.ID, wrappedContent) + })) if err != nil { return nil, err } @@ -225,19 +222,16 @@ func (s *SignalClient) HandleMatrixReactionRemove(ctx context.Context, msg *brid return fmt.Errorf("failed to parse target message ID: %w", err) } ts := getTimestampForEvent(msg.InputTransactionID, msg.Event, msg.OrigSender) - wrappedContent := &signalpb.Content{ - DataMessage: &signalpb.DataMessage{ - Timestamp: proto.Uint64(ts), - RequiredProtocolVersion: proto.Uint32(uint32(signalpb.DataMessage_REACTIONS)), - Reaction: &signalpb.DataMessage_Reaction{ - Emoji: proto.String(msg.TargetReaction.Emoji), - Remove: proto.Bool(true), - TargetAuthorAciBinary: targetAuthorACI[:], - TargetSentTimestamp: proto.Uint64(targetSentTimestamp), - }, + err = s.sendMessage(ctx, msg.Portal.ID, signalmeow.WrapDataMessage(&signalpb.DataMessage{ + Timestamp: proto.Uint64(ts), + RequiredProtocolVersion: proto.Uint32(uint32(signalpb.DataMessage_REACTIONS)), + Reaction: &signalpb.DataMessage_Reaction{ + Emoji: proto.String(msg.TargetReaction.Emoji), + Remove: proto.Bool(true), + TargetAuthorAciBinary: targetAuthorACI[:], + TargetSentTimestamp: proto.Uint64(targetSentTimestamp), }, - } - err = s.sendMessage(ctx, msg.Portal.ID, wrappedContent) + })) if err != nil { return err } @@ -252,15 +246,12 @@ func (s *SignalClient) HandleMatrixMessageRemove(ctx context.Context, msg *bridg return fmt.Errorf("cannot delete other people's messages") } ts := getTimestampForEvent(msg.InputTransactionID, msg.Event, msg.OrigSender) - wrappedContent := &signalpb.Content{ - DataMessage: &signalpb.DataMessage{ - Timestamp: proto.Uint64(ts), - Delete: &signalpb.DataMessage_Delete{ - TargetSentTimestamp: proto.Uint64(targetSentTimestamp), - }, + err = s.sendMessage(ctx, msg.Portal.ID, signalmeow.WrapDataMessage(&signalpb.DataMessage{ + Timestamp: proto.Uint64(ts), + Delete: &signalpb.DataMessage_Delete{ + TargetSentTimestamp: proto.Uint64(targetSentTimestamp), }, - } - err = s.sendMessage(ctx, msg.Portal.ID, wrappedContent) + })) if err != nil { return err } @@ -688,13 +679,11 @@ func (s *SignalClient) HandleMatrixDisappearingTimer(ctx context.Context, msg *b }) } else { ts := getTimestampForEvent(msg.InputTransactionID, msg.Event, msg.OrigSender) - res := s.Client.SendMessage(ctx, userID, &signalpb.Content{ - DataMessage: &signalpb.DataMessage{ - Timestamp: ptr.Ptr(ts), - Flags: ptr.Ptr(uint32(signalpb.DataMessage_EXPIRATION_TIMER_UPDATE)), - ExpireTimer: ptr.Ptr(uint32(msg.Content.Timer.Seconds())), - }, - }) + res := s.Client.SendMessage(ctx, userID, signalmeow.WrapDataMessage(&signalpb.DataMessage{ + Timestamp: ptr.Ptr(ts), + Flags: ptr.Ptr(uint32(signalpb.DataMessage_EXPIRATION_TIMER_UPDATE)), + ExpireTimer: ptr.Ptr(uint32(msg.Content.Timer.Seconds())), + })) if !res.WasSuccessful { return false, res.Error } @@ -773,8 +762,8 @@ func (s *SignalClient) HandleMatrixDeleteChat(ctx context.Context, msg *bridgev2 recipientID := s.Client.Store.ACIServiceID() // Send DeleteForMe sync message to self - result := s.Client.SendMessage(ctx, recipientID, &signalpb.Content{ - SyncMessage: &signalpb.SyncMessage{ + result := s.Client.SendMessage(ctx, recipientID, signalmeow.WrapSyncMessage(&signalpb.SyncMessage{ + Content: &signalpb.SyncMessage_DeleteForMe_{ DeleteForMe: &signalpb.SyncMessage_DeleteForMe{ ConversationDeletes: []*signalpb.SyncMessage_DeleteForMe_ConversationDelete{{ Conversation: conversationID, @@ -783,7 +772,7 @@ func (s *SignalClient) HandleMatrixDeleteChat(ctx context.Context, msg *bridgev2 }}, }, }, - }) + })) zerolog.Ctx(ctx).Debug(). Str("portal_id", string(msg.Portal.ID)). @@ -868,11 +857,11 @@ func (s *SignalClient) syncMessageRequestResponse( } else { return fmt.Errorf("invalid portal ID for message request response: %s", portal.ID) } - res := s.Client.SendMessage(ctx, libsignalgo.NewACIServiceID(s.Client.Store.ACI), &signalpb.Content{ - SyncMessage: &signalpb.SyncMessage{ + res := s.Client.SendMessage(ctx, libsignalgo.NewACIServiceID(s.Client.Store.ACI), signalmeow.WrapSyncMessage(&signalpb.SyncMessage{ + Content: &signalpb.SyncMessage_MessageRequestResponse_{ MessageRequestResponse: accept, }, - }) + })) if !res.WasSuccessful { return res.Error } @@ -905,13 +894,13 @@ func (s *SignalClient) HandleMatrixAcceptMessageRequest(ctx context.Context, msg } } res := s.Client.SendMessage(ctx, userID, &signalpb.Content{ - DataMessage: &signalpb.DataMessage{ + Content: &signalpb.Content_DataMessage{DataMessage: &signalpb.DataMessage{ Flags: proto.Uint32(uint32(signalpb.DataMessage_PROFILE_KEY_UPDATE)), ProfileKey: profileKey.Slice(), Timestamp: proto.Uint64(getTimestampForEvent(msg.InputTransactionID, msg.Event, msg.OrigSender)), RequiredProtocolVersion: proto.Uint32(0), - }, + }}, PniSignatureMessage: pniSig, }) if !res.WasSuccessful { diff --git a/pkg/signalmeow/protobuf/Groups.pb.go b/pkg/signalmeow/protobuf/Groups.pb.go index c7717ff..0c2b81b 100644 --- a/pkg/signalmeow/protobuf/Groups.pb.go +++ b/pkg/signalmeow/protobuf/Groups.pb.go @@ -498,6 +498,7 @@ type AccessControl struct { Attributes AccessControl_AccessRequired `protobuf:"varint,1,opt,name=attributes,proto3,enum=signal.AccessControl_AccessRequired" json:"attributes,omitempty"` Members AccessControl_AccessRequired `protobuf:"varint,2,opt,name=members,proto3,enum=signal.AccessControl_AccessRequired" json:"members,omitempty"` AddFromInviteLink AccessControl_AccessRequired `protobuf:"varint,3,opt,name=addFromInviteLink,proto3,enum=signal.AccessControl_AccessRequired" json:"addFromInviteLink,omitempty"` + MemberLabel AccessControl_AccessRequired `protobuf:"varint,4,opt,name=memberLabel,proto3,enum=signal.AccessControl_AccessRequired" json:"memberLabel,omitempty"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } @@ -553,6 +554,13 @@ func (x *AccessControl) GetAddFromInviteLink() AccessControl_AccessRequired { return AccessControl_UNKNOWN } +func (x *AccessControl) GetMemberLabel() AccessControl_AccessRequired { + if x != nil { + return x.MemberLabel + } + return AccessControl_UNKNOWN +} + type Group struct { state protoimpl.MessageState `protogen:"open.v1"` PublicKey []byte `protobuf:"bytes,1,opt,name=publicKey,proto3" json:"publicKey,omitempty"` @@ -569,7 +577,8 @@ type Group struct { MembersPendingAdminApproval []*MemberPendingAdminApproval `protobuf:"bytes,9,rep,name=membersPendingAdminApproval,proto3" json:"membersPendingAdminApproval,omitempty"` InviteLinkPassword []byte `protobuf:"bytes,10,opt,name=inviteLinkPassword,proto3" json:"inviteLinkPassword,omitempty"` AnnouncementsOnly bool `protobuf:"varint,12,opt,name=announcements_only,json=announcementsOnly,proto3" json:"announcements_only,omitempty"` - MembersBanned []*MemberBanned `protobuf:"bytes,13,rep,name=members_banned,json=membersBanned,proto3" json:"members_banned,omitempty"` // next: 14 + MembersBanned []*MemberBanned `protobuf:"bytes,13,rep,name=members_banned,json=membersBanned,proto3" json:"members_banned,omitempty"` + Terminated bool `protobuf:"varint,14,opt,name=terminated,proto3" json:"terminated,omitempty"` // next: 15 unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } @@ -695,6 +704,13 @@ func (x *Group) GetMembersBanned() []*MemberBanned { return nil } +func (x *Group) GetTerminated() bool { + if x != nil { + return x.Terminated + } + return false +} + type GroupAttributeBlob struct { state protoimpl.MessageState `protogen:"open.v1"` // Types that are valid to be assigned to Content: @@ -1317,6 +1333,8 @@ type GroupChange_Actions struct { DeleteMembersBanned []*GroupChange_Actions_DeleteMemberBannedAction `protobuf:"bytes,23,rep,name=delete_members_banned,json=deleteMembersBanned,proto3" json:"delete_members_banned,omitempty"` // change epoch = 4 PromoteMembersPendingPniAciProfileKey []*GroupChange_Actions_PromoteMemberPendingPniAciProfileKeyAction `protobuf:"bytes,24,rep,name=promote_members_pending_pni_aci_profile_key,json=promoteMembersPendingPniAciProfileKey,proto3" json:"promote_members_pending_pni_aci_profile_key,omitempty"` // change epoch = 5 ModifyMemberLabels []*GroupChange_Actions_ModifyMemberLabelAction `protobuf:"bytes,26,rep,name=modifyMemberLabels,proto3" json:"modifyMemberLabels,omitempty"` // change epoch = 6; + ModifyMemberLabelAccess *GroupChange_Actions_ModifyMemberLabelAccessControlAction `protobuf:"bytes,27,opt,name=modifyMemberLabelAccess,proto3" json:"modifyMemberLabelAccess,omitempty"` // change epoch = 6 + TerminateGroup *GroupChange_Actions_TerminateGroupAction `protobuf:"bytes,28,opt,name=terminate_group,json=terminateGroup,proto3" json:"terminate_group,omitempty"` // change epoch = 7 unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } @@ -1533,6 +1551,20 @@ func (x *GroupChange_Actions) GetModifyMemberLabels() []*GroupChange_Actions_Mod return nil } +func (x *GroupChange_Actions) GetModifyMemberLabelAccess() *GroupChange_Actions_ModifyMemberLabelAccessControlAction { + if x != nil { + return x.ModifyMemberLabelAccess + } + return nil +} + +func (x *GroupChange_Actions) GetTerminateGroup() *GroupChange_Actions_TerminateGroupAction { + if x != nil { + return x.TerminateGroup + } + return nil +} + type GroupChange_Actions_AddMemberAction struct { state protoimpl.MessageState `protogen:"open.v1"` Added *Member `protobuf:"bytes,1,opt,name=added,proto3" json:"added,omitempty"` @@ -2553,6 +2585,50 @@ func (x *GroupChange_Actions_ModifyAddFromInviteLinkAccessControlAction) GetAddF return AccessControl_UNKNOWN } +type GroupChange_Actions_ModifyMemberLabelAccessControlAction struct { + state protoimpl.MessageState `protogen:"open.v1"` + MemberLabelAccess AccessControl_AccessRequired `protobuf:"varint,1,opt,name=memberLabelAccess,proto3,enum=signal.AccessControl_AccessRequired" json:"memberLabelAccess,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *GroupChange_Actions_ModifyMemberLabelAccessControlAction) Reset() { + *x = GroupChange_Actions_ModifyMemberLabelAccessControlAction{} + mi := &file_Groups_proto_msgTypes[38] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *GroupChange_Actions_ModifyMemberLabelAccessControlAction) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GroupChange_Actions_ModifyMemberLabelAccessControlAction) ProtoMessage() {} + +func (x *GroupChange_Actions_ModifyMemberLabelAccessControlAction) ProtoReflect() protoreflect.Message { + mi := &file_Groups_proto_msgTypes[38] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GroupChange_Actions_ModifyMemberLabelAccessControlAction.ProtoReflect.Descriptor instead. +func (*GroupChange_Actions_ModifyMemberLabelAccessControlAction) Descriptor() ([]byte, []int) { + return file_Groups_proto_rawDescGZIP(), []int{10, 0, 21} +} + +func (x *GroupChange_Actions_ModifyMemberLabelAccessControlAction) GetMemberLabelAccess() AccessControl_AccessRequired { + if x != nil { + return x.MemberLabelAccess + } + return AccessControl_UNKNOWN +} + type GroupChange_Actions_ModifyInviteLinkPasswordAction struct { state protoimpl.MessageState `protogen:"open.v1"` InviteLinkPassword []byte `protobuf:"bytes,1,opt,name=inviteLinkPassword,proto3" json:"inviteLinkPassword,omitempty"` @@ -2562,7 +2638,7 @@ type GroupChange_Actions_ModifyInviteLinkPasswordAction struct { func (x *GroupChange_Actions_ModifyInviteLinkPasswordAction) Reset() { *x = GroupChange_Actions_ModifyInviteLinkPasswordAction{} - mi := &file_Groups_proto_msgTypes[38] + mi := &file_Groups_proto_msgTypes[39] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2574,7 +2650,7 @@ func (x *GroupChange_Actions_ModifyInviteLinkPasswordAction) String() string { func (*GroupChange_Actions_ModifyInviteLinkPasswordAction) ProtoMessage() {} func (x *GroupChange_Actions_ModifyInviteLinkPasswordAction) ProtoReflect() protoreflect.Message { - mi := &file_Groups_proto_msgTypes[38] + mi := &file_Groups_proto_msgTypes[39] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2587,7 +2663,7 @@ func (x *GroupChange_Actions_ModifyInviteLinkPasswordAction) ProtoReflect() prot // Deprecated: Use GroupChange_Actions_ModifyInviteLinkPasswordAction.ProtoReflect.Descriptor instead. func (*GroupChange_Actions_ModifyInviteLinkPasswordAction) Descriptor() ([]byte, []int) { - return file_Groups_proto_rawDescGZIP(), []int{10, 0, 21} + return file_Groups_proto_rawDescGZIP(), []int{10, 0, 22} } func (x *GroupChange_Actions_ModifyInviteLinkPasswordAction) GetInviteLinkPassword() []byte { @@ -2606,7 +2682,7 @@ type GroupChange_Actions_ModifyAnnouncementsOnlyAction struct { func (x *GroupChange_Actions_ModifyAnnouncementsOnlyAction) Reset() { *x = GroupChange_Actions_ModifyAnnouncementsOnlyAction{} - mi := &file_Groups_proto_msgTypes[39] + mi := &file_Groups_proto_msgTypes[40] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2618,7 +2694,7 @@ func (x *GroupChange_Actions_ModifyAnnouncementsOnlyAction) String() string { func (*GroupChange_Actions_ModifyAnnouncementsOnlyAction) ProtoMessage() {} func (x *GroupChange_Actions_ModifyAnnouncementsOnlyAction) ProtoReflect() protoreflect.Message { - mi := &file_Groups_proto_msgTypes[39] + mi := &file_Groups_proto_msgTypes[40] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2631,7 +2707,7 @@ func (x *GroupChange_Actions_ModifyAnnouncementsOnlyAction) ProtoReflect() proto // Deprecated: Use GroupChange_Actions_ModifyAnnouncementsOnlyAction.ProtoReflect.Descriptor instead. func (*GroupChange_Actions_ModifyAnnouncementsOnlyAction) Descriptor() ([]byte, []int) { - return file_Groups_proto_rawDescGZIP(), []int{10, 0, 22} + return file_Groups_proto_rawDescGZIP(), []int{10, 0, 23} } func (x *GroupChange_Actions_ModifyAnnouncementsOnlyAction) GetAnnouncementsOnly() bool { @@ -2641,6 +2717,42 @@ func (x *GroupChange_Actions_ModifyAnnouncementsOnlyAction) GetAnnouncementsOnly return false } +type GroupChange_Actions_TerminateGroupAction struct { + state protoimpl.MessageState `protogen:"open.v1"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *GroupChange_Actions_TerminateGroupAction) Reset() { + *x = GroupChange_Actions_TerminateGroupAction{} + mi := &file_Groups_proto_msgTypes[41] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *GroupChange_Actions_TerminateGroupAction) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GroupChange_Actions_TerminateGroupAction) ProtoMessage() {} + +func (x *GroupChange_Actions_TerminateGroupAction) ProtoReflect() protoreflect.Message { + mi := &file_Groups_proto_msgTypes[41] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GroupChange_Actions_TerminateGroupAction.ProtoReflect.Descriptor instead. +func (*GroupChange_Actions_TerminateGroupAction) Descriptor() ([]byte, []int) { + return file_Groups_proto_rawDescGZIP(), []int{10, 0, 24} +} + type GroupChanges_GroupChangeState struct { state protoimpl.MessageState `protogen:"open.v1"` GroupChange *GroupChange `protobuf:"bytes,1,opt,name=groupChange,proto3" json:"groupChange,omitempty"` @@ -2651,7 +2763,7 @@ type GroupChanges_GroupChangeState struct { func (x *GroupChanges_GroupChangeState) Reset() { *x = GroupChanges_GroupChangeState{} - mi := &file_Groups_proto_msgTypes[40] + mi := &file_Groups_proto_msgTypes[42] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2663,7 +2775,7 @@ func (x *GroupChanges_GroupChangeState) String() string { func (*GroupChanges_GroupChangeState) ProtoMessage() {} func (x *GroupChanges_GroupChangeState) ProtoReflect() protoreflect.Message { - mi := &file_Groups_proto_msgTypes[40] + mi := &file_Groups_proto_msgTypes[42] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2737,20 +2849,21 @@ const file_Groups_proto_rawDesc = "" + "\ttimestamp\x18\x04 \x01(\x04R\ttimestamp\"D\n" + "\fMemberBanned\x12\x16\n" + "\x06userId\x18\x01 \x01(\fR\x06userId\x12\x1c\n" + - "\ttimestamp\x18\x02 \x01(\x04R\ttimestamp\"\xc3\x02\n" + + "\ttimestamp\x18\x02 \x01(\x04R\ttimestamp\"\x8b\x03\n" + "\rAccessControl\x12D\n" + "\n" + "attributes\x18\x01 \x01(\x0e2$.signal.AccessControl.AccessRequiredR\n" + "attributes\x12>\n" + "\amembers\x18\x02 \x01(\x0e2$.signal.AccessControl.AccessRequiredR\amembers\x12R\n" + - "\x11addFromInviteLink\x18\x03 \x01(\x0e2$.signal.AccessControl.AccessRequiredR\x11addFromInviteLink\"X\n" + + "\x11addFromInviteLink\x18\x03 \x01(\x0e2$.signal.AccessControl.AccessRequiredR\x11addFromInviteLink\x12F\n" + + "\vmemberLabel\x18\x04 \x01(\x0e2$.signal.AccessControl.AccessRequiredR\vmemberLabel\"X\n" + "\x0eAccessRequired\x12\v\n" + "\aUNKNOWN\x10\x00\x12\a\n" + "\x03ANY\x10\x01\x12\n" + "\n" + "\x06MEMBER\x10\x02\x12\x11\n" + "\rADMINISTRATOR\x10\x03\x12\x11\n" + - "\rUNSATISFIABLE\x10\x04\"\x99\x05\n" + + "\rUNSATISFIABLE\x10\x04\"\xb9\x05\n" + "\x05Group\x12\x1c\n" + "\tpublicKey\x18\x01 \x01(\fR\tpublicKey\x12\x14\n" + "\x05title\x18\x02 \x01(\fR\x05title\x12 \n" + @@ -2765,7 +2878,10 @@ const file_Groups_proto_rawDesc = "" + "\x12inviteLinkPassword\x18\n" + " \x01(\fR\x12inviteLinkPassword\x12-\n" + "\x12announcements_only\x18\f \x01(\bR\x11announcementsOnly\x12;\n" + - "\x0emembers_banned\x18\r \x03(\v2\x14.signal.MemberBannedR\rmembersBanned\"\xc3\x01\n" + + "\x0emembers_banned\x18\r \x03(\v2\x14.signal.MemberBannedR\rmembersBanned\x12\x1e\n" + + "\n" + + "terminated\x18\x0e \x01(\bR\n" + + "terminated\"\xc3\x01\n" + "\x12GroupAttributeBlob\x12\x16\n" + "\x05title\x18\x01 \x01(\tH\x00R\x05title\x12\x18\n" + "\x06avatar\x18\x02 \x01(\fH\x00R\x06avatar\x12D\n" + @@ -2789,11 +2905,11 @@ const file_Groups_proto_rawDesc = "" + "\vmemberCount\x18\x04 \x01(\rR\vmemberCount\x12R\n" + "\x11addFromInviteLink\x18\x05 \x01(\x0e2$.signal.AccessControl.AccessRequiredR\x11addFromInviteLink\x12\x18\n" + "\aversion\x18\x06 \x01(\rR\aversion\x122\n" + - "\x14pendingAdminApproval\x18\a \x01(\bR\x14pendingAdminApproval\"\xbb'\n" + + "\x14pendingAdminApproval\x18\a \x01(\bR\x14pendingAdminApproval\"\xa6*\n" + "\vGroupChange\x12\x18\n" + "\aactions\x18\x01 \x01(\fR\aactions\x12(\n" + "\x0fserverSignature\x18\x02 \x01(\fR\x0fserverSignature\x12 \n" + - "\vchangeEpoch\x18\x03 \x01(\rR\vchangeEpoch\x1a\xc5&\n" + + "\vchangeEpoch\x18\x03 \x01(\rR\vchangeEpoch\x1a\xb0)\n" + "\aActions\x12\"\n" + "\fsourceUserId\x18\x01 \x01(\fR\fsourceUserId\x12\x19\n" + "\bgroup_id\x18\x19 \x01(\fR\agroupId\x12\x18\n" + @@ -2823,7 +2939,9 @@ const file_Groups_proto_rawDesc = "" + "\x12add_members_banned\x18\x16 \x03(\v21.signal.GroupChange.Actions.AddMemberBannedActionR\x10addMembersBanned\x12h\n" + "\x15delete_members_banned\x18\x17 \x03(\v24.signal.GroupChange.Actions.DeleteMemberBannedActionR\x13deleteMembersBanned\x12\xa2\x01\n" + "+promote_members_pending_pni_aci_profile_key\x18\x18 \x03(\v2F.signal.GroupChange.Actions.PromoteMemberPendingPniAciProfileKeyActionR%promoteMembersPendingPniAciProfileKey\x12c\n" + - "\x12modifyMemberLabels\x18\x1a \x03(\v23.signal.GroupChange.Actions.ModifyMemberLabelActionR\x12modifyMemberLabels\x1ag\n" + + "\x12modifyMemberLabels\x18\x1a \x03(\v23.signal.GroupChange.Actions.ModifyMemberLabelActionR\x12modifyMemberLabels\x12z\n" + + "\x17modifyMemberLabelAccess\x18\x1b \x01(\v2@.signal.GroupChange.Actions.ModifyMemberLabelAccessControlActionR\x17modifyMemberLabelAccess\x12Y\n" + + "\x0fterminate_group\x18\x1c \x01(\v20.signal.GroupChange.Actions.TerminateGroupActionR\x0eterminateGroup\x1ag\n" + "\x0fAddMemberAction\x12$\n" + "\x05added\x18\x01 \x01(\v2\x0e.signal.MemberR\x05added\x12.\n" + "\x12joinFromInviteLink\x18\x02 \x01(\bR\x12joinFromInviteLink\x1a:\n" + @@ -2882,11 +3000,14 @@ const file_Groups_proto_rawDesc = "" + " ModifyMembersAccessControlAction\x12J\n" + "\rmembersAccess\x18\x01 \x01(\x0e2$.signal.AccessControl.AccessRequiredR\rmembersAccess\x1a\x8c\x01\n" + "*ModifyAddFromInviteLinkAccessControlAction\x12^\n" + - "\x17addFromInviteLinkAccess\x18\x01 \x01(\x0e2$.signal.AccessControl.AccessRequiredR\x17addFromInviteLinkAccess\x1aP\n" + + "\x17addFromInviteLinkAccess\x18\x01 \x01(\x0e2$.signal.AccessControl.AccessRequiredR\x17addFromInviteLinkAccess\x1az\n" + + "$ModifyMemberLabelAccessControlAction\x12R\n" + + "\x11memberLabelAccess\x18\x01 \x01(\x0e2$.signal.AccessControl.AccessRequiredR\x11memberLabelAccess\x1aP\n" + "\x1eModifyInviteLinkPasswordAction\x12.\n" + "\x12inviteLinkPassword\x18\x01 \x01(\fR\x12inviteLinkPassword\x1aN\n" + "\x1dModifyAnnouncementsOnlyAction\x12-\n" + - "\x12announcements_only\x18\x01 \x01(\bR\x11announcementsOnly\"/\n" + + "\x12announcements_only\x18\x01 \x01(\bR\x11announcementsOnly\x1a\x16\n" + + "\x14TerminateGroupAction\"/\n" + "\x17ExternalGroupCredential\x12\x14\n" + "\x05token\x18\x01 \x01(\tR\x05token\"}\n" + "\rGroupResponse\x12#\n" + @@ -2918,7 +3039,7 @@ func file_Groups_proto_rawDescGZIP() []byte { } var file_Groups_proto_enumTypes = make([]protoimpl.EnumInfo, 2) -var file_Groups_proto_msgTypes = make([]protoimpl.MessageInfo, 41) +var file_Groups_proto_msgTypes = make([]protoimpl.MessageInfo, 43) var file_Groups_proto_goTypes = []any{ (Member_Role)(0), // 0: signal.Member.Role (AccessControl_AccessRequired)(0), // 1: signal.AccessControl.AccessRequired @@ -2960,9 +3081,11 @@ var file_Groups_proto_goTypes = []any{ (*GroupChange_Actions_ModifyAttributesAccessControlAction)(nil), // 37: signal.GroupChange.Actions.ModifyAttributesAccessControlAction (*GroupChange_Actions_ModifyMembersAccessControlAction)(nil), // 38: signal.GroupChange.Actions.ModifyMembersAccessControlAction (*GroupChange_Actions_ModifyAddFromInviteLinkAccessControlAction)(nil), // 39: signal.GroupChange.Actions.ModifyAddFromInviteLinkAccessControlAction - (*GroupChange_Actions_ModifyInviteLinkPasswordAction)(nil), // 40: signal.GroupChange.Actions.ModifyInviteLinkPasswordAction - (*GroupChange_Actions_ModifyAnnouncementsOnlyAction)(nil), // 41: signal.GroupChange.Actions.ModifyAnnouncementsOnlyAction - (*GroupChanges_GroupChangeState)(nil), // 42: signal.GroupChanges.GroupChangeState + (*GroupChange_Actions_ModifyMemberLabelAccessControlAction)(nil), // 40: signal.GroupChange.Actions.ModifyMemberLabelAccessControlAction + (*GroupChange_Actions_ModifyInviteLinkPasswordAction)(nil), // 41: signal.GroupChange.Actions.ModifyInviteLinkPasswordAction + (*GroupChange_Actions_ModifyAnnouncementsOnlyAction)(nil), // 42: signal.GroupChange.Actions.ModifyAnnouncementsOnlyAction + (*GroupChange_Actions_TerminateGroupAction)(nil), // 43: signal.GroupChange.Actions.TerminateGroupAction + (*GroupChanges_GroupChangeState)(nil), // 44: signal.GroupChanges.GroupChangeState } var file_Groups_proto_depIdxs = []int32{ 0, // 0: signal.Member.role:type_name -> signal.Member.Role @@ -2970,55 +3093,59 @@ var file_Groups_proto_depIdxs = []int32{ 1, // 2: signal.AccessControl.attributes:type_name -> signal.AccessControl.AccessRequired 1, // 3: signal.AccessControl.members:type_name -> signal.AccessControl.AccessRequired 1, // 4: signal.AccessControl.addFromInviteLink:type_name -> signal.AccessControl.AccessRequired - 7, // 5: signal.Group.accessControl:type_name -> signal.AccessControl - 3, // 6: signal.Group.members:type_name -> signal.Member - 4, // 7: signal.Group.membersPendingProfileKey:type_name -> signal.MemberPendingProfileKey - 5, // 8: signal.Group.membersPendingAdminApproval:type_name -> signal.MemberPendingAdminApproval - 6, // 9: signal.Group.members_banned:type_name -> signal.MemberBanned - 17, // 10: signal.GroupInviteLink.contentsV1:type_name -> signal.GroupInviteLink.GroupInviteLinkContentsV1 - 1, // 11: signal.GroupJoinInfo.addFromInviteLink:type_name -> signal.AccessControl.AccessRequired - 8, // 12: signal.GroupResponse.group:type_name -> signal.Group - 42, // 13: signal.GroupChanges.groupChanges:type_name -> signal.GroupChanges.GroupChangeState - 12, // 14: signal.GroupChangeResponse.group_change:type_name -> signal.GroupChange - 19, // 15: signal.GroupChange.Actions.addMembers:type_name -> signal.GroupChange.Actions.AddMemberAction - 20, // 16: signal.GroupChange.Actions.deleteMembers:type_name -> signal.GroupChange.Actions.DeleteMemberAction - 21, // 17: signal.GroupChange.Actions.modifyMemberRoles:type_name -> signal.GroupChange.Actions.ModifyMemberRoleAction - 23, // 18: signal.GroupChange.Actions.modifyMemberProfileKeys:type_name -> signal.GroupChange.Actions.ModifyMemberProfileKeyAction - 24, // 19: signal.GroupChange.Actions.addMembersPendingProfileKey:type_name -> signal.GroupChange.Actions.AddMemberPendingProfileKeyAction - 25, // 20: signal.GroupChange.Actions.deleteMembersPendingProfileKey:type_name -> signal.GroupChange.Actions.DeleteMemberPendingProfileKeyAction - 26, // 21: signal.GroupChange.Actions.promoteMembersPendingProfileKey:type_name -> signal.GroupChange.Actions.PromoteMemberPendingProfileKeyAction - 33, // 22: signal.GroupChange.Actions.modifyTitle:type_name -> signal.GroupChange.Actions.ModifyTitleAction - 35, // 23: signal.GroupChange.Actions.modifyAvatar:type_name -> signal.GroupChange.Actions.ModifyAvatarAction - 36, // 24: signal.GroupChange.Actions.modifyDisappearingMessageTimer:type_name -> signal.GroupChange.Actions.ModifyDisappearingMessageTimerAction - 37, // 25: signal.GroupChange.Actions.modifyAttributesAccess:type_name -> signal.GroupChange.Actions.ModifyAttributesAccessControlAction - 38, // 26: signal.GroupChange.Actions.modifyMemberAccess:type_name -> signal.GroupChange.Actions.ModifyMembersAccessControlAction - 39, // 27: signal.GroupChange.Actions.modifyAddFromInviteLinkAccess:type_name -> signal.GroupChange.Actions.ModifyAddFromInviteLinkAccessControlAction - 28, // 28: signal.GroupChange.Actions.addMembersPendingAdminApproval:type_name -> signal.GroupChange.Actions.AddMemberPendingAdminApprovalAction - 29, // 29: signal.GroupChange.Actions.deleteMembersPendingAdminApproval:type_name -> signal.GroupChange.Actions.DeleteMemberPendingAdminApprovalAction - 30, // 30: signal.GroupChange.Actions.promoteMembersPendingAdminApproval:type_name -> signal.GroupChange.Actions.PromoteMemberPendingAdminApprovalAction - 40, // 31: signal.GroupChange.Actions.modifyInviteLinkPassword:type_name -> signal.GroupChange.Actions.ModifyInviteLinkPasswordAction - 34, // 32: signal.GroupChange.Actions.modifyDescription:type_name -> signal.GroupChange.Actions.ModifyDescriptionAction - 41, // 33: signal.GroupChange.Actions.modify_announcements_only:type_name -> signal.GroupChange.Actions.ModifyAnnouncementsOnlyAction - 31, // 34: signal.GroupChange.Actions.add_members_banned:type_name -> signal.GroupChange.Actions.AddMemberBannedAction - 32, // 35: signal.GroupChange.Actions.delete_members_banned:type_name -> signal.GroupChange.Actions.DeleteMemberBannedAction - 27, // 36: signal.GroupChange.Actions.promote_members_pending_pni_aci_profile_key:type_name -> signal.GroupChange.Actions.PromoteMemberPendingPniAciProfileKeyAction - 22, // 37: signal.GroupChange.Actions.modifyMemberLabels:type_name -> signal.GroupChange.Actions.ModifyMemberLabelAction - 3, // 38: signal.GroupChange.Actions.AddMemberAction.added:type_name -> signal.Member - 0, // 39: signal.GroupChange.Actions.ModifyMemberRoleAction.role:type_name -> signal.Member.Role - 4, // 40: signal.GroupChange.Actions.AddMemberPendingProfileKeyAction.added:type_name -> signal.MemberPendingProfileKey - 5, // 41: signal.GroupChange.Actions.AddMemberPendingAdminApprovalAction.added:type_name -> signal.MemberPendingAdminApproval - 0, // 42: signal.GroupChange.Actions.PromoteMemberPendingAdminApprovalAction.role:type_name -> signal.Member.Role - 6, // 43: signal.GroupChange.Actions.AddMemberBannedAction.added:type_name -> signal.MemberBanned - 1, // 44: signal.GroupChange.Actions.ModifyAttributesAccessControlAction.attributesAccess:type_name -> signal.AccessControl.AccessRequired - 1, // 45: signal.GroupChange.Actions.ModifyMembersAccessControlAction.membersAccess:type_name -> signal.AccessControl.AccessRequired - 1, // 46: signal.GroupChange.Actions.ModifyAddFromInviteLinkAccessControlAction.addFromInviteLinkAccess:type_name -> signal.AccessControl.AccessRequired - 12, // 47: signal.GroupChanges.GroupChangeState.groupChange:type_name -> signal.GroupChange - 8, // 48: signal.GroupChanges.GroupChangeState.groupState:type_name -> signal.Group - 49, // [49:49] is the sub-list for method output_type - 49, // [49:49] is the sub-list for method input_type - 49, // [49:49] is the sub-list for extension type_name - 49, // [49:49] is the sub-list for extension extendee - 0, // [0:49] is the sub-list for field type_name + 1, // 5: signal.AccessControl.memberLabel:type_name -> signal.AccessControl.AccessRequired + 7, // 6: signal.Group.accessControl:type_name -> signal.AccessControl + 3, // 7: signal.Group.members:type_name -> signal.Member + 4, // 8: signal.Group.membersPendingProfileKey:type_name -> signal.MemberPendingProfileKey + 5, // 9: signal.Group.membersPendingAdminApproval:type_name -> signal.MemberPendingAdminApproval + 6, // 10: signal.Group.members_banned:type_name -> signal.MemberBanned + 17, // 11: signal.GroupInviteLink.contentsV1:type_name -> signal.GroupInviteLink.GroupInviteLinkContentsV1 + 1, // 12: signal.GroupJoinInfo.addFromInviteLink:type_name -> signal.AccessControl.AccessRequired + 8, // 13: signal.GroupResponse.group:type_name -> signal.Group + 44, // 14: signal.GroupChanges.groupChanges:type_name -> signal.GroupChanges.GroupChangeState + 12, // 15: signal.GroupChangeResponse.group_change:type_name -> signal.GroupChange + 19, // 16: signal.GroupChange.Actions.addMembers:type_name -> signal.GroupChange.Actions.AddMemberAction + 20, // 17: signal.GroupChange.Actions.deleteMembers:type_name -> signal.GroupChange.Actions.DeleteMemberAction + 21, // 18: signal.GroupChange.Actions.modifyMemberRoles:type_name -> signal.GroupChange.Actions.ModifyMemberRoleAction + 23, // 19: signal.GroupChange.Actions.modifyMemberProfileKeys:type_name -> signal.GroupChange.Actions.ModifyMemberProfileKeyAction + 24, // 20: signal.GroupChange.Actions.addMembersPendingProfileKey:type_name -> signal.GroupChange.Actions.AddMemberPendingProfileKeyAction + 25, // 21: signal.GroupChange.Actions.deleteMembersPendingProfileKey:type_name -> signal.GroupChange.Actions.DeleteMemberPendingProfileKeyAction + 26, // 22: signal.GroupChange.Actions.promoteMembersPendingProfileKey:type_name -> signal.GroupChange.Actions.PromoteMemberPendingProfileKeyAction + 33, // 23: signal.GroupChange.Actions.modifyTitle:type_name -> signal.GroupChange.Actions.ModifyTitleAction + 35, // 24: signal.GroupChange.Actions.modifyAvatar:type_name -> signal.GroupChange.Actions.ModifyAvatarAction + 36, // 25: signal.GroupChange.Actions.modifyDisappearingMessageTimer:type_name -> signal.GroupChange.Actions.ModifyDisappearingMessageTimerAction + 37, // 26: signal.GroupChange.Actions.modifyAttributesAccess:type_name -> signal.GroupChange.Actions.ModifyAttributesAccessControlAction + 38, // 27: signal.GroupChange.Actions.modifyMemberAccess:type_name -> signal.GroupChange.Actions.ModifyMembersAccessControlAction + 39, // 28: signal.GroupChange.Actions.modifyAddFromInviteLinkAccess:type_name -> signal.GroupChange.Actions.ModifyAddFromInviteLinkAccessControlAction + 28, // 29: signal.GroupChange.Actions.addMembersPendingAdminApproval:type_name -> signal.GroupChange.Actions.AddMemberPendingAdminApprovalAction + 29, // 30: signal.GroupChange.Actions.deleteMembersPendingAdminApproval:type_name -> signal.GroupChange.Actions.DeleteMemberPendingAdminApprovalAction + 30, // 31: signal.GroupChange.Actions.promoteMembersPendingAdminApproval:type_name -> signal.GroupChange.Actions.PromoteMemberPendingAdminApprovalAction + 41, // 32: signal.GroupChange.Actions.modifyInviteLinkPassword:type_name -> signal.GroupChange.Actions.ModifyInviteLinkPasswordAction + 34, // 33: signal.GroupChange.Actions.modifyDescription:type_name -> signal.GroupChange.Actions.ModifyDescriptionAction + 42, // 34: signal.GroupChange.Actions.modify_announcements_only:type_name -> signal.GroupChange.Actions.ModifyAnnouncementsOnlyAction + 31, // 35: signal.GroupChange.Actions.add_members_banned:type_name -> signal.GroupChange.Actions.AddMemberBannedAction + 32, // 36: signal.GroupChange.Actions.delete_members_banned:type_name -> signal.GroupChange.Actions.DeleteMemberBannedAction + 27, // 37: signal.GroupChange.Actions.promote_members_pending_pni_aci_profile_key:type_name -> signal.GroupChange.Actions.PromoteMemberPendingPniAciProfileKeyAction + 22, // 38: signal.GroupChange.Actions.modifyMemberLabels:type_name -> signal.GroupChange.Actions.ModifyMemberLabelAction + 40, // 39: signal.GroupChange.Actions.modifyMemberLabelAccess:type_name -> signal.GroupChange.Actions.ModifyMemberLabelAccessControlAction + 43, // 40: signal.GroupChange.Actions.terminate_group:type_name -> signal.GroupChange.Actions.TerminateGroupAction + 3, // 41: signal.GroupChange.Actions.AddMemberAction.added:type_name -> signal.Member + 0, // 42: signal.GroupChange.Actions.ModifyMemberRoleAction.role:type_name -> signal.Member.Role + 4, // 43: signal.GroupChange.Actions.AddMemberPendingProfileKeyAction.added:type_name -> signal.MemberPendingProfileKey + 5, // 44: signal.GroupChange.Actions.AddMemberPendingAdminApprovalAction.added:type_name -> signal.MemberPendingAdminApproval + 0, // 45: signal.GroupChange.Actions.PromoteMemberPendingAdminApprovalAction.role:type_name -> signal.Member.Role + 6, // 46: signal.GroupChange.Actions.AddMemberBannedAction.added:type_name -> signal.MemberBanned + 1, // 47: signal.GroupChange.Actions.ModifyAttributesAccessControlAction.attributesAccess:type_name -> signal.AccessControl.AccessRequired + 1, // 48: signal.GroupChange.Actions.ModifyMembersAccessControlAction.membersAccess:type_name -> signal.AccessControl.AccessRequired + 1, // 49: signal.GroupChange.Actions.ModifyAddFromInviteLinkAccessControlAction.addFromInviteLinkAccess:type_name -> signal.AccessControl.AccessRequired + 1, // 50: signal.GroupChange.Actions.ModifyMemberLabelAccessControlAction.memberLabelAccess:type_name -> signal.AccessControl.AccessRequired + 12, // 51: signal.GroupChanges.GroupChangeState.groupChange:type_name -> signal.GroupChange + 8, // 52: signal.GroupChanges.GroupChangeState.groupState:type_name -> signal.Group + 53, // [53:53] is the sub-list for method output_type + 53, // [53:53] is the sub-list for method input_type + 53, // [53:53] is the sub-list for extension type_name + 53, // [53:53] is the sub-list for extension extendee + 0, // [0:53] is the sub-list for field type_name } func init() { file_Groups_proto_init() } @@ -3041,7 +3168,7 @@ func file_Groups_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: unsafe.Slice(unsafe.StringData(file_Groups_proto_rawDesc), len(file_Groups_proto_rawDesc)), NumEnums: 2, - NumMessages: 41, + NumMessages: 43, NumExtensions: 0, NumServices: 0, }, diff --git a/pkg/signalmeow/protobuf/Groups.proto b/pkg/signalmeow/protobuf/Groups.proto index 448846a..9843d1c 100644 --- a/pkg/signalmeow/protobuf/Groups.proto +++ b/pkg/signalmeow/protobuf/Groups.proto @@ -69,6 +69,7 @@ message AccessControl { AccessRequired attributes = 1; AccessRequired members = 2; AccessRequired addFromInviteLink = 3; + AccessRequired memberLabel = 4; } message Group { @@ -87,7 +88,8 @@ message Group { bytes inviteLinkPassword = 10; bool announcements_only = 12; repeated MemberBanned members_banned = 13; - // next: 14 + bool terminated = 14; + // next: 15 } message GroupAttributeBlob { @@ -225,6 +227,10 @@ message GroupChange { AccessControl.AccessRequired addFromInviteLinkAccess = 1; } + message ModifyMemberLabelAccessControlAction { + AccessControl.AccessRequired memberLabelAccess = 1; + } + message ModifyInviteLinkPasswordAction { bytes inviteLinkPassword = 1; } @@ -233,6 +239,8 @@ message GroupChange { bool announcements_only = 1; } + message TerminateGroupAction {} + bytes sourceUserId = 1; // clients should not provide this value; the server will provide it in the response buffer to ensure the signature is binding to a particular group // if clients set it during a request the server will respond with 400. @@ -262,7 +270,9 @@ message GroupChange { repeated DeleteMemberBannedAction delete_members_banned = 23; // change epoch = 4 repeated PromoteMemberPendingPniAciProfileKeyAction promote_members_pending_pni_aci_profile_key = 24; // change epoch = 5 repeated ModifyMemberLabelAction modifyMemberLabels = 26; // change epoch = 6; - // next: 27 + ModifyMemberLabelAccessControlAction modifyMemberLabelAccess = 27; // change epoch = 6 + TerminateGroupAction terminate_group = 28; // change epoch = 7 + // next: 29 } bytes actions = 1; diff --git a/pkg/signalmeow/protobuf/Provisioning.pb.go b/pkg/signalmeow/protobuf/Provisioning.pb.go index 0231512..c925fe6 100644 --- a/pkg/signalmeow/protobuf/Provisioning.pb.go +++ b/pkg/signalmeow/protobuf/Provisioning.pb.go @@ -199,7 +199,6 @@ type ProvisionMessage struct { ProfileKey []byte `protobuf:"bytes,6,opt,name=profileKey" json:"profileKey,omitempty"` ReadReceipts *bool `protobuf:"varint,7,opt,name=readReceipts" json:"readReceipts,omitempty"` ProvisioningVersion *uint32 `protobuf:"varint,9,opt,name=provisioningVersion" json:"provisioningVersion,omitempty"` - MasterKey []byte `protobuf:"bytes,13,opt,name=masterKey" json:"masterKey,omitempty"` // Deprecated, but required by linked devices EphemeralBackupKey []byte `protobuf:"bytes,14,opt,name=ephemeralBackupKey" json:"ephemeralBackupKey,omitempty"` // 32 bytes AccountEntropyPool *string `protobuf:"bytes,15,opt,name=accountEntropyPool" json:"accountEntropyPool,omitempty"` MediaRootBackupKey []byte `protobuf:"bytes,16,opt,name=mediaRootBackupKey" json:"mediaRootBackupKey,omitempty"` // 32-bytes @@ -323,13 +322,6 @@ func (x *ProvisionMessage) GetProvisioningVersion() uint32 { return 0 } -func (x *ProvisionMessage) GetMasterKey() []byte { - if x != nil { - return x.MasterKey - } - return nil -} - func (x *ProvisionMessage) GetEphemeralBackupKey() []byte { if x != nil { return x.EphemeralBackupKey @@ -374,7 +366,7 @@ const file_Provisioning_proto_rawDesc = "" + "\aaddress\x18\x01 \x01(\tR\aaddress\"E\n" + "\x11ProvisionEnvelope\x12\x1c\n" + "\tpublicKey\x18\x01 \x01(\fR\tpublicKey\x12\x12\n" + - "\x04body\x18\x02 \x01(\fR\x04body\"\xcc\x05\n" + + "\x04body\x18\x02 \x01(\fR\x04body\"\xb4\x05\n" + "\x10ProvisionMessage\x122\n" + "\x14aciIdentityKeyPublic\x18\x01 \x01(\fR\x14aciIdentityKeyPublic\x124\n" + "\x15aciIdentityKeyPrivate\x18\x02 \x01(\fR\x15aciIdentityKeyPrivate\x122\n" + @@ -390,13 +382,12 @@ const file_Provisioning_proto_rawDesc = "" + "profileKey\x18\x06 \x01(\fR\n" + "profileKey\x12\"\n" + "\freadReceipts\x18\a \x01(\bR\freadReceipts\x120\n" + - "\x13provisioningVersion\x18\t \x01(\rR\x13provisioningVersion\x12\x1c\n" + - "\tmasterKey\x18\r \x01(\fR\tmasterKey\x12.\n" + + "\x13provisioningVersion\x18\t \x01(\rR\x13provisioningVersion\x12.\n" + "\x12ephemeralBackupKey\x18\x0e \x01(\fR\x12ephemeralBackupKey\x12.\n" + "\x12accountEntropyPool\x18\x0f \x01(\tR\x12accountEntropyPool\x12.\n" + "\x12mediaRootBackupKey\x18\x10 \x01(\fR\x12mediaRootBackupKey\x12\x1c\n" + "\taciBinary\x18\x11 \x01(\fR\taciBinary\x12\x1c\n" + - "\tpniBinary\x18\x12 \x01(\fR\tpniBinary*G\n" + + "\tpniBinary\x18\x12 \x01(\fR\tpniBinaryJ\x04\b\r\x10\x0e*G\n" + "\x13ProvisioningVersion\x12\v\n" + "\aINITIAL\x10\x00\x12\x12\n" + "\x0eTABLET_SUPPORT\x10\x01\x12\v\n" + diff --git a/pkg/signalmeow/protobuf/Provisioning.proto b/pkg/signalmeow/protobuf/Provisioning.proto index 2fde938..b5eeaf6 100644 --- a/pkg/signalmeow/protobuf/Provisioning.proto +++ b/pkg/signalmeow/protobuf/Provisioning.proto @@ -38,7 +38,7 @@ message ProvisionMessage { optional bytes profileKey = 6; optional bool readReceipts = 7; optional uint32 provisioningVersion = 9; - optional bytes masterKey = 13; // Deprecated, but required by linked devices + reserved /*masterKey*/ 13; // Deprecated in favor of accountEntropyPool optional bytes ephemeralBackupKey = 14; // 32 bytes optional string accountEntropyPool = 15; optional bytes mediaRootBackupKey = 16; // 32-bytes diff --git a/pkg/signalmeow/protobuf/SignalService.pb.go b/pkg/signalmeow/protobuf/SignalService.pb.go index 5866dbb..32842bf 100644 --- a/pkg/signalmeow/protobuf/SignalService.pb.go +++ b/pkg/signalmeow/protobuf/SignalService.pb.go @@ -28,33 +28,71 @@ const ( type Envelope_Type int32 const ( - Envelope_UNKNOWN Envelope_Type = 0 - Envelope_CIPHERTEXT Envelope_Type = 1 // content => (version byte | SignalMessage{Content}) - Envelope_PREKEY_BUNDLE Envelope_Type = 3 // content => (version byte | PreKeySignalMessage{Content}) - Envelope_SERVER_DELIVERY_RECEIPT Envelope_Type = 5 // legacyMessage => [] AND content => [] - Envelope_UNIDENTIFIED_SENDER Envelope_Type = 6 // legacyMessage => [] AND content => ((version byte | UnidentifiedSenderMessage) OR (version byte | Multi-Recipient Sealed Sender Format)) - Envelope_SENDERKEY_MESSAGE Envelope_Type = 7 // legacyMessage => [] AND content => (version byte | SenderKeyMessage) - Envelope_PLAINTEXT_CONTENT Envelope_Type = 8 // legacyMessage => [] AND content => (marker byte | Content) + Envelope_UNKNOWN Envelope_Type = 0 + // * + // A double-ratchet message represents a "normal," "unsealed-sender" message + // encrypted using the Double Ratchet within an established Signal session. + // Double-ratchet messages include sender information in the plaintext + // portion of the `Envelope`. + Envelope_DOUBLE_RATCHET Envelope_Type = 1 // content => (version byte | SignalMessage{Content}) + // * + // A prekey message begins a new Signal session. The `content` of a prekey + // message is a superset of a double-ratchet message's `content` and + // contains the sender's identity public key and information identifying the + // pre-keys used in the message's ciphertext. Like double-ratchet messages, + // prekey messages contain sender information in the plaintext portion of + // the `Envelope`. + Envelope_PREKEY_MESSAGE Envelope_Type = 3 // content => (version byte | PreKeySignalMessage{Content}) + // * + // Server delivery receipts are generated by the server when + // "unsealed-sender" messages are delivered to and acknowledged by the + // destination device. Server delivery receipts identify the sender in the + // plaintext portion of the `Envelope` and have no `content`. Note that + // receipts for sealed-sender messages are generated by clients as + // `UNIDENTIFIED_SENDER` messages. + // + // Note that, with server delivery receipts, the "client timestamp" on + // the envelope refers to the timestamp of the original message (i.e. the + // message the server just delivered) and not to the time of delivery. The + // "server timestamp" refers to the time of delivery. + Envelope_SERVER_DELIVERY_RECEIPT Envelope_Type = 5 // content => [] + // * + // An unidentified sender message represents a message with no sender + // information in the plaintext portion of the `Envelope`. Unidentified + // sender messages always contain an additional `subtype` in their + // `content`. They may or may not be part of an existing Signal session + // (i.e. an unidentified sender message may have a "prekey message" + // subtype or may indicate an encryption error). + Envelope_UNIDENTIFIED_SENDER Envelope_Type = 6 // content => ((version byte | UnidentifiedSenderMessage) OR (version byte | Multi-Recipient Sealed Sender Format)) + // * + // A plaintext message is used solely to convey encryption error receipts + // and never contains encrypted message content. Encryption error receipts + // must be delivered in plaintext because, encryption/decryption of a prior + // message failed and there is no reason to believe that + // encryption/decryption of subsequent messages with the same key material + // would succeed. + // + // Critically, plaintext messages never have "real" message content + // generated by users. Plaintext messages include sender information. + Envelope_PLAINTEXT_CONTENT Envelope_Type = 8 // content => (marker byte | Content) ) // Enum value maps for Envelope_Type. var ( Envelope_Type_name = map[int32]string{ 0: "UNKNOWN", - 1: "CIPHERTEXT", - 3: "PREKEY_BUNDLE", + 1: "DOUBLE_RATCHET", + 3: "PREKEY_MESSAGE", 5: "SERVER_DELIVERY_RECEIPT", 6: "UNIDENTIFIED_SENDER", - 7: "SENDERKEY_MESSAGE", 8: "PLAINTEXT_CONTENT", } Envelope_Type_value = map[string]int32{ "UNKNOWN": 0, - "CIPHERTEXT": 1, - "PREKEY_BUNDLE": 3, + "DOUBLE_RATCHET": 1, + "PREKEY_MESSAGE": 3, "SERVER_DELIVERY_RECEIPT": 5, "UNIDENTIFIED_SENDER": 6, - "SENDERKEY_MESSAGE": 7, "PLAINTEXT_CONTENT": 8, } ) @@ -1753,9 +1791,9 @@ type Envelope struct { state protoimpl.MessageState `protogen:"open.v1"` Type *Envelope_Type `protobuf:"varint,1,opt,name=type,enum=signalservice.Envelope_Type" json:"type,omitempty"` SourceServiceId *string `protobuf:"bytes,11,opt,name=sourceServiceId" json:"sourceServiceId,omitempty"` - SourceDevice *uint32 `protobuf:"varint,7,opt,name=sourceDevice" json:"sourceDevice,omitempty"` + SourceDeviceId *uint32 `protobuf:"varint,7,opt,name=sourceDeviceId" json:"sourceDeviceId,omitempty"` DestinationServiceId *string `protobuf:"bytes,13,opt,name=destinationServiceId" json:"destinationServiceId,omitempty"` - Timestamp *uint64 `protobuf:"varint,5,opt,name=timestamp" json:"timestamp,omitempty"` + ClientTimestamp *uint64 `protobuf:"varint,5,opt,name=clientTimestamp" json:"clientTimestamp,omitempty"` Content []byte `protobuf:"bytes,8,opt,name=content" json:"content,omitempty"` // Contains an encrypted Content ServerGuid *string `protobuf:"bytes,9,opt,name=serverGuid" json:"serverGuid,omitempty"` ServerTimestamp *uint64 `protobuf:"varint,10,opt,name=serverTimestamp" json:"serverTimestamp,omitempty"` @@ -1821,9 +1859,9 @@ func (x *Envelope) GetSourceServiceId() string { return "" } -func (x *Envelope) GetSourceDevice() uint32 { - if x != nil && x.SourceDevice != nil { - return *x.SourceDevice +func (x *Envelope) GetSourceDeviceId() uint32 { + if x != nil && x.SourceDeviceId != nil { + return *x.SourceDeviceId } return 0 } @@ -1835,9 +1873,9 @@ func (x *Envelope) GetDestinationServiceId() string { return "" } -func (x *Envelope) GetTimestamp() uint64 { - if x != nil && x.Timestamp != nil { - return *x.Timestamp +func (x *Envelope) GetClientTimestamp() uint64 { + if x != nil && x.ClientTimestamp != nil { + return *x.ClientTimestamp } return 0 } @@ -1927,18 +1965,21 @@ func (x *Envelope) GetUpdatedPniBinary() []byte { } type Content struct { - state protoimpl.MessageState `protogen:"open.v1"` - DataMessage *DataMessage `protobuf:"bytes,1,opt,name=dataMessage" json:"dataMessage,omitempty"` - SyncMessage *SyncMessage `protobuf:"bytes,2,opt,name=syncMessage" json:"syncMessage,omitempty"` - CallMessage *CallMessage `protobuf:"bytes,3,opt,name=callMessage" json:"callMessage,omitempty"` - NullMessage *NullMessage `protobuf:"bytes,4,opt,name=nullMessage" json:"nullMessage,omitempty"` - ReceiptMessage *ReceiptMessage `protobuf:"bytes,5,opt,name=receiptMessage" json:"receiptMessage,omitempty"` - TypingMessage *TypingMessage `protobuf:"bytes,6,opt,name=typingMessage" json:"typingMessage,omitempty"` - SenderKeyDistributionMessage []byte `protobuf:"bytes,7,opt,name=senderKeyDistributionMessage" json:"senderKeyDistributionMessage,omitempty"` - DecryptionErrorMessage []byte `protobuf:"bytes,8,opt,name=decryptionErrorMessage" json:"decryptionErrorMessage,omitempty"` - StoryMessage *StoryMessage `protobuf:"bytes,9,opt,name=storyMessage" json:"storyMessage,omitempty"` - PniSignatureMessage *PniSignatureMessage `protobuf:"bytes,10,opt,name=pniSignatureMessage" json:"pniSignatureMessage,omitempty"` - EditMessage *EditMessage `protobuf:"bytes,11,opt,name=editMessage" json:"editMessage,omitempty"` + state protoimpl.MessageState `protogen:"open.v1"` + // Types that are valid to be assigned to Content: + // + // *Content_DataMessage + // *Content_SyncMessage + // *Content_CallMessage + // *Content_NullMessage + // *Content_ReceiptMessage + // *Content_TypingMessage + // *Content_DecryptionErrorMessage + // *Content_StoryMessage + // *Content_EditMessage + Content isContent_Content `protobuf_oneof:"content"` + SenderKeyDistributionMessage []byte `protobuf:"bytes,7,opt,name=senderKeyDistributionMessage" json:"senderKeyDistributionMessage,omitempty"` + PniSignatureMessage *PniSignatureMessage `protobuf:"bytes,10,opt,name=pniSignatureMessage" json:"pniSignatureMessage,omitempty"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } @@ -1973,44 +2014,90 @@ func (*Content) Descriptor() ([]byte, []int) { return file_SignalService_proto_rawDescGZIP(), []int{1} } +func (x *Content) GetContent() isContent_Content { + if x != nil { + return x.Content + } + return nil +} + func (x *Content) GetDataMessage() *DataMessage { if x != nil { - return x.DataMessage + if x, ok := x.Content.(*Content_DataMessage); ok { + return x.DataMessage + } } return nil } func (x *Content) GetSyncMessage() *SyncMessage { if x != nil { - return x.SyncMessage + if x, ok := x.Content.(*Content_SyncMessage); ok { + return x.SyncMessage + } } return nil } func (x *Content) GetCallMessage() *CallMessage { if x != nil { - return x.CallMessage + if x, ok := x.Content.(*Content_CallMessage); ok { + return x.CallMessage + } } return nil } func (x *Content) GetNullMessage() *NullMessage { if x != nil { - return x.NullMessage + if x, ok := x.Content.(*Content_NullMessage); ok { + return x.NullMessage + } } return nil } func (x *Content) GetReceiptMessage() *ReceiptMessage { if x != nil { - return x.ReceiptMessage + if x, ok := x.Content.(*Content_ReceiptMessage); ok { + return x.ReceiptMessage + } } return nil } func (x *Content) GetTypingMessage() *TypingMessage { if x != nil { - return x.TypingMessage + if x, ok := x.Content.(*Content_TypingMessage); ok { + return x.TypingMessage + } + } + return nil +} + +func (x *Content) GetDecryptionErrorMessage() []byte { + if x != nil { + if x, ok := x.Content.(*Content_DecryptionErrorMessage); ok { + return x.DecryptionErrorMessage + } + } + return nil +} + +func (x *Content) GetStoryMessage() *StoryMessage { + if x != nil { + if x, ok := x.Content.(*Content_StoryMessage); ok { + return x.StoryMessage + } + } + return nil +} + +func (x *Content) GetEditMessage() *EditMessage { + if x != nil { + if x, ok := x.Content.(*Content_EditMessage); ok { + return x.EditMessage + } } return nil } @@ -2022,20 +2109,6 @@ func (x *Content) GetSenderKeyDistributionMessage() []byte { return nil } -func (x *Content) GetDecryptionErrorMessage() []byte { - if x != nil { - return x.DecryptionErrorMessage - } - return nil -} - -func (x *Content) GetStoryMessage() *StoryMessage { - if x != nil { - return x.StoryMessage - } - return nil -} - func (x *Content) GetPniSignatureMessage() *PniSignatureMessage { if x != nil { return x.PniSignatureMessage @@ -2043,13 +2116,64 @@ func (x *Content) GetPniSignatureMessage() *PniSignatureMessage { return nil } -func (x *Content) GetEditMessage() *EditMessage { - if x != nil { - return x.EditMessage - } - return nil +type isContent_Content interface { + isContent_Content() } +type Content_DataMessage struct { + DataMessage *DataMessage `protobuf:"bytes,1,opt,name=dataMessage,oneof"` +} + +type Content_SyncMessage struct { + SyncMessage *SyncMessage `protobuf:"bytes,2,opt,name=syncMessage,oneof"` +} + +type Content_CallMessage struct { + CallMessage *CallMessage `protobuf:"bytes,3,opt,name=callMessage,oneof"` +} + +type Content_NullMessage struct { + NullMessage *NullMessage `protobuf:"bytes,4,opt,name=nullMessage,oneof"` +} + +type Content_ReceiptMessage struct { + ReceiptMessage *ReceiptMessage `protobuf:"bytes,5,opt,name=receiptMessage,oneof"` +} + +type Content_TypingMessage struct { + TypingMessage *TypingMessage `protobuf:"bytes,6,opt,name=typingMessage,oneof"` +} + +type Content_DecryptionErrorMessage struct { + DecryptionErrorMessage []byte `protobuf:"bytes,8,opt,name=decryptionErrorMessage,oneof"` +} + +type Content_StoryMessage struct { + StoryMessage *StoryMessage `protobuf:"bytes,9,opt,name=storyMessage,oneof"` +} + +type Content_EditMessage struct { + EditMessage *EditMessage `protobuf:"bytes,11,opt,name=editMessage,oneof"` +} + +func (*Content_DataMessage) isContent_Content() {} + +func (*Content_SyncMessage) isContent_Content() {} + +func (*Content_CallMessage) isContent_Content() {} + +func (*Content_NullMessage) isContent_Content() {} + +func (*Content_ReceiptMessage) isContent_Content() {} + +func (*Content_TypingMessage) isContent_Content() {} + +func (*Content_DecryptionErrorMessage) isContent_Content() {} + +func (*Content_StoryMessage) isContent_Content() {} + +func (*Content_EditMessage) isContent_Content() {} + type CallMessage struct { state protoimpl.MessageState `protogen:"open.v1"` Offer *CallMessage_Offer `protobuf:"bytes,1,opt,name=offer" json:"offer,omitempty"` @@ -2169,7 +2293,8 @@ type DataMessage struct { PollTerminate *DataMessage_PollTerminate `protobuf:"bytes,25,opt,name=pollTerminate" json:"pollTerminate,omitempty"` PollVote *DataMessage_PollVote `protobuf:"bytes,26,opt,name=pollVote" json:"pollVote,omitempty"` PinMessage *DataMessage_PinMessage `protobuf:"bytes,27,opt,name=pinMessage" json:"pinMessage,omitempty"` - UnpinMessage *DataMessage_UnpinMessage `protobuf:"bytes,28,opt,name=unpinMessage" json:"unpinMessage,omitempty"` // NEXT ID: 29 + UnpinMessage *DataMessage_UnpinMessage `protobuf:"bytes,28,opt,name=unpinMessage" json:"unpinMessage,omitempty"` + AdminDelete *DataMessage_AdminDelete `protobuf:"bytes,29,opt,name=adminDelete" json:"adminDelete,omitempty"` // NEXT ID: 30 unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } @@ -2386,6 +2511,13 @@ func (x *DataMessage) GetUnpinMessage() *DataMessage_UnpinMessage { return nil } +func (x *DataMessage) GetAdminDelete() *DataMessage_AdminDelete { + if x != nil { + return x.AdminDelete + } + return nil +} + type NullMessage struct { state protoimpl.MessageState `protogen:"open.v1"` Padding []byte `protobuf:"bytes,1,opt,name=padding" json:"padding,omitempty"` @@ -2931,32 +3063,38 @@ func (x *Verified) GetDestinationAciBinary() []byte { } type SyncMessage struct { - state protoimpl.MessageState `protogen:"open.v1"` - Sent *SyncMessage_Sent `protobuf:"bytes,1,opt,name=sent" json:"sent,omitempty"` - Contacts *SyncMessage_Contacts `protobuf:"bytes,2,opt,name=contacts" json:"contacts,omitempty"` - Request *SyncMessage_Request `protobuf:"bytes,4,opt,name=request" json:"request,omitempty"` - Read []*SyncMessage_Read `protobuf:"bytes,5,rep,name=read" json:"read,omitempty"` - Blocked *SyncMessage_Blocked `protobuf:"bytes,6,opt,name=blocked" json:"blocked,omitempty"` - Verified *Verified `protobuf:"bytes,7,opt,name=verified" json:"verified,omitempty"` - Configuration *SyncMessage_Configuration `protobuf:"bytes,9,opt,name=configuration" json:"configuration,omitempty"` - Padding []byte `protobuf:"bytes,8,opt,name=padding" json:"padding,omitempty"` - StickerPackOperation []*SyncMessage_StickerPackOperation `protobuf:"bytes,10,rep,name=stickerPackOperation" json:"stickerPackOperation,omitempty"` - ViewOnceOpen *SyncMessage_ViewOnceOpen `protobuf:"bytes,11,opt,name=viewOnceOpen" json:"viewOnceOpen,omitempty"` - FetchLatest *SyncMessage_FetchLatest `protobuf:"bytes,12,opt,name=fetchLatest" json:"fetchLatest,omitempty"` - Keys *SyncMessage_Keys `protobuf:"bytes,13,opt,name=keys" json:"keys,omitempty"` - MessageRequestResponse *SyncMessage_MessageRequestResponse `protobuf:"bytes,14,opt,name=messageRequestResponse" json:"messageRequestResponse,omitempty"` - OutgoingPayment *SyncMessage_OutgoingPayment `protobuf:"bytes,15,opt,name=outgoingPayment" json:"outgoingPayment,omitempty"` - Viewed []*SyncMessage_Viewed `protobuf:"bytes,16,rep,name=viewed" json:"viewed,omitempty"` - PniChangeNumber *SyncMessage_PniChangeNumber `protobuf:"bytes,18,opt,name=pniChangeNumber" json:"pniChangeNumber,omitempty"` - CallEvent *SyncMessage_CallEvent `protobuf:"bytes,19,opt,name=callEvent" json:"callEvent,omitempty"` - CallLinkUpdate *SyncMessage_CallLinkUpdate `protobuf:"bytes,20,opt,name=callLinkUpdate" json:"callLinkUpdate,omitempty"` - CallLogEvent *SyncMessage_CallLogEvent `protobuf:"bytes,21,opt,name=callLogEvent" json:"callLogEvent,omitempty"` - DeleteForMe *SyncMessage_DeleteForMe `protobuf:"bytes,22,opt,name=deleteForMe" json:"deleteForMe,omitempty"` - DeviceNameChange *SyncMessage_DeviceNameChange `protobuf:"bytes,23,opt,name=deviceNameChange" json:"deviceNameChange,omitempty"` - AttachmentBackfillRequest *SyncMessage_AttachmentBackfillRequest `protobuf:"bytes,24,opt,name=attachmentBackfillRequest" json:"attachmentBackfillRequest,omitempty"` - AttachmentBackfillResponse *SyncMessage_AttachmentBackfillResponse `protobuf:"bytes,25,opt,name=attachmentBackfillResponse" json:"attachmentBackfillResponse,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` + // Types that are valid to be assigned to Content: + // + // *SyncMessage_Sent_ + // *SyncMessage_Contacts_ + // *SyncMessage_Request_ + // *SyncMessage_Blocked_ + // *SyncMessage_Verified + // *SyncMessage_Configuration_ + // *SyncMessage_ViewOnceOpen_ + // *SyncMessage_FetchLatest_ + // *SyncMessage_Keys_ + // *SyncMessage_MessageRequestResponse_ + // *SyncMessage_OutgoingPayment_ + // *SyncMessage_PniChangeNumber_ + // *SyncMessage_CallEvent_ + // *SyncMessage_CallLinkUpdate_ + // *SyncMessage_CallLogEvent_ + // *SyncMessage_DeleteForMe_ + // *SyncMessage_DeviceNameChange_ + // *SyncMessage_AttachmentBackfillRequest_ + // *SyncMessage_AttachmentBackfillResponse_ + Content isSyncMessage_Content `protobuf_oneof:"content"` + // Protobufs don't allow `repeated` fields to be inside of `oneof` so while + // the fields below are mutually exclusive with the rest of the values above + // we have to place them outside of `oneof`. + Read []*SyncMessage_Read `protobuf:"bytes,5,rep,name=read" json:"read,omitempty"` + StickerPackOperation []*SyncMessage_StickerPackOperation `protobuf:"bytes,10,rep,name=stickerPackOperation" json:"stickerPackOperation,omitempty"` + Viewed []*SyncMessage_Viewed `protobuf:"bytes,16,rep,name=viewed" json:"viewed,omitempty"` + Padding []byte `protobuf:"bytes,8,opt,name=padding" json:"padding,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } func (x *SyncMessage) Reset() { @@ -2989,23 +3127,180 @@ func (*SyncMessage) Descriptor() ([]byte, []int) { return file_SignalService_proto_rawDescGZIP(), []int{11} } +func (x *SyncMessage) GetContent() isSyncMessage_Content { + if x != nil { + return x.Content + } + return nil +} + func (x *SyncMessage) GetSent() *SyncMessage_Sent { if x != nil { - return x.Sent + if x, ok := x.Content.(*SyncMessage_Sent_); ok { + return x.Sent + } } return nil } func (x *SyncMessage) GetContacts() *SyncMessage_Contacts { if x != nil { - return x.Contacts + if x, ok := x.Content.(*SyncMessage_Contacts_); ok { + return x.Contacts + } } return nil } func (x *SyncMessage) GetRequest() *SyncMessage_Request { if x != nil { - return x.Request + if x, ok := x.Content.(*SyncMessage_Request_); ok { + return x.Request + } + } + return nil +} + +func (x *SyncMessage) GetBlocked() *SyncMessage_Blocked { + if x != nil { + if x, ok := x.Content.(*SyncMessage_Blocked_); ok { + return x.Blocked + } + } + return nil +} + +func (x *SyncMessage) GetVerified() *Verified { + if x != nil { + if x, ok := x.Content.(*SyncMessage_Verified); ok { + return x.Verified + } + } + return nil +} + +func (x *SyncMessage) GetConfiguration() *SyncMessage_Configuration { + if x != nil { + if x, ok := x.Content.(*SyncMessage_Configuration_); ok { + return x.Configuration + } + } + return nil +} + +func (x *SyncMessage) GetViewOnceOpen() *SyncMessage_ViewOnceOpen { + if x != nil { + if x, ok := x.Content.(*SyncMessage_ViewOnceOpen_); ok { + return x.ViewOnceOpen + } + } + return nil +} + +func (x *SyncMessage) GetFetchLatest() *SyncMessage_FetchLatest { + if x != nil { + if x, ok := x.Content.(*SyncMessage_FetchLatest_); ok { + return x.FetchLatest + } + } + return nil +} + +func (x *SyncMessage) GetKeys() *SyncMessage_Keys { + if x != nil { + if x, ok := x.Content.(*SyncMessage_Keys_); ok { + return x.Keys + } + } + return nil +} + +func (x *SyncMessage) GetMessageRequestResponse() *SyncMessage_MessageRequestResponse { + if x != nil { + if x, ok := x.Content.(*SyncMessage_MessageRequestResponse_); ok { + return x.MessageRequestResponse + } + } + return nil +} + +func (x *SyncMessage) GetOutgoingPayment() *SyncMessage_OutgoingPayment { + if x != nil { + if x, ok := x.Content.(*SyncMessage_OutgoingPayment_); ok { + return x.OutgoingPayment + } + } + return nil +} + +func (x *SyncMessage) GetPniChangeNumber() *SyncMessage_PniChangeNumber { + if x != nil { + if x, ok := x.Content.(*SyncMessage_PniChangeNumber_); ok { + return x.PniChangeNumber + } + } + return nil +} + +func (x *SyncMessage) GetCallEvent() *SyncMessage_CallEvent { + if x != nil { + if x, ok := x.Content.(*SyncMessage_CallEvent_); ok { + return x.CallEvent + } + } + return nil +} + +func (x *SyncMessage) GetCallLinkUpdate() *SyncMessage_CallLinkUpdate { + if x != nil { + if x, ok := x.Content.(*SyncMessage_CallLinkUpdate_); ok { + return x.CallLinkUpdate + } + } + return nil +} + +func (x *SyncMessage) GetCallLogEvent() *SyncMessage_CallLogEvent { + if x != nil { + if x, ok := x.Content.(*SyncMessage_CallLogEvent_); ok { + return x.CallLogEvent + } + } + return nil +} + +func (x *SyncMessage) GetDeleteForMe() *SyncMessage_DeleteForMe { + if x != nil { + if x, ok := x.Content.(*SyncMessage_DeleteForMe_); ok { + return x.DeleteForMe + } + } + return nil +} + +func (x *SyncMessage) GetDeviceNameChange() *SyncMessage_DeviceNameChange { + if x != nil { + if x, ok := x.Content.(*SyncMessage_DeviceNameChange_); ok { + return x.DeviceNameChange + } + } + return nil +} + +func (x *SyncMessage) GetAttachmentBackfillRequest() *SyncMessage_AttachmentBackfillRequest { + if x != nil { + if x, ok := x.Content.(*SyncMessage_AttachmentBackfillRequest_); ok { + return x.AttachmentBackfillRequest + } + } + return nil +} + +func (x *SyncMessage) GetAttachmentBackfillResponse() *SyncMessage_AttachmentBackfillResponse { + if x != nil { + if x, ok := x.Content.(*SyncMessage_AttachmentBackfillResponse_); ok { + return x.AttachmentBackfillResponse + } } return nil } @@ -3017,34 +3312,6 @@ func (x *SyncMessage) GetRead() []*SyncMessage_Read { return nil } -func (x *SyncMessage) GetBlocked() *SyncMessage_Blocked { - if x != nil { - return x.Blocked - } - return nil -} - -func (x *SyncMessage) GetVerified() *Verified { - if x != nil { - return x.Verified - } - return nil -} - -func (x *SyncMessage) GetConfiguration() *SyncMessage_Configuration { - if x != nil { - return x.Configuration - } - return nil -} - -func (x *SyncMessage) GetPadding() []byte { - if x != nil { - return x.Padding - } - return nil -} - func (x *SyncMessage) GetStickerPackOperation() []*SyncMessage_StickerPackOperation { if x != nil { return x.StickerPackOperation @@ -3052,41 +3319,6 @@ func (x *SyncMessage) GetStickerPackOperation() []*SyncMessage_StickerPackOperat return nil } -func (x *SyncMessage) GetViewOnceOpen() *SyncMessage_ViewOnceOpen { - if x != nil { - return x.ViewOnceOpen - } - return nil -} - -func (x *SyncMessage) GetFetchLatest() *SyncMessage_FetchLatest { - if x != nil { - return x.FetchLatest - } - return nil -} - -func (x *SyncMessage) GetKeys() *SyncMessage_Keys { - if x != nil { - return x.Keys - } - return nil -} - -func (x *SyncMessage) GetMessageRequestResponse() *SyncMessage_MessageRequestResponse { - if x != nil { - return x.MessageRequestResponse - } - return nil -} - -func (x *SyncMessage) GetOutgoingPayment() *SyncMessage_OutgoingPayment { - if x != nil { - return x.OutgoingPayment - } - return nil -} - func (x *SyncMessage) GetViewed() []*SyncMessage_Viewed { if x != nil { return x.Viewed @@ -3094,62 +3326,131 @@ func (x *SyncMessage) GetViewed() []*SyncMessage_Viewed { return nil } -func (x *SyncMessage) GetPniChangeNumber() *SyncMessage_PniChangeNumber { +func (x *SyncMessage) GetPadding() []byte { if x != nil { - return x.PniChangeNumber + return x.Padding } return nil } -func (x *SyncMessage) GetCallEvent() *SyncMessage_CallEvent { - if x != nil { - return x.CallEvent - } - return nil +type isSyncMessage_Content interface { + isSyncMessage_Content() } -func (x *SyncMessage) GetCallLinkUpdate() *SyncMessage_CallLinkUpdate { - if x != nil { - return x.CallLinkUpdate - } - return nil +type SyncMessage_Sent_ struct { + Sent *SyncMessage_Sent `protobuf:"bytes,1,opt,name=sent,oneof"` } -func (x *SyncMessage) GetCallLogEvent() *SyncMessage_CallLogEvent { - if x != nil { - return x.CallLogEvent - } - return nil +type SyncMessage_Contacts_ struct { + Contacts *SyncMessage_Contacts `protobuf:"bytes,2,opt,name=contacts,oneof"` } -func (x *SyncMessage) GetDeleteForMe() *SyncMessage_DeleteForMe { - if x != nil { - return x.DeleteForMe - } - return nil +type SyncMessage_Request_ struct { + Request *SyncMessage_Request `protobuf:"bytes,4,opt,name=request,oneof"` } -func (x *SyncMessage) GetDeviceNameChange() *SyncMessage_DeviceNameChange { - if x != nil { - return x.DeviceNameChange - } - return nil +type SyncMessage_Blocked_ struct { + Blocked *SyncMessage_Blocked `protobuf:"bytes,6,opt,name=blocked,oneof"` } -func (x *SyncMessage) GetAttachmentBackfillRequest() *SyncMessage_AttachmentBackfillRequest { - if x != nil { - return x.AttachmentBackfillRequest - } - return nil +type SyncMessage_Verified struct { + Verified *Verified `protobuf:"bytes,7,opt,name=verified,oneof"` } -func (x *SyncMessage) GetAttachmentBackfillResponse() *SyncMessage_AttachmentBackfillResponse { - if x != nil { - return x.AttachmentBackfillResponse - } - return nil +type SyncMessage_Configuration_ struct { + Configuration *SyncMessage_Configuration `protobuf:"bytes,9,opt,name=configuration,oneof"` } +type SyncMessage_ViewOnceOpen_ struct { + ViewOnceOpen *SyncMessage_ViewOnceOpen `protobuf:"bytes,11,opt,name=viewOnceOpen,oneof"` +} + +type SyncMessage_FetchLatest_ struct { + FetchLatest *SyncMessage_FetchLatest `protobuf:"bytes,12,opt,name=fetchLatest,oneof"` +} + +type SyncMessage_Keys_ struct { + Keys *SyncMessage_Keys `protobuf:"bytes,13,opt,name=keys,oneof"` +} + +type SyncMessage_MessageRequestResponse_ struct { + MessageRequestResponse *SyncMessage_MessageRequestResponse `protobuf:"bytes,14,opt,name=messageRequestResponse,oneof"` +} + +type SyncMessage_OutgoingPayment_ struct { + OutgoingPayment *SyncMessage_OutgoingPayment `protobuf:"bytes,15,opt,name=outgoingPayment,oneof"` +} + +type SyncMessage_PniChangeNumber_ struct { + PniChangeNumber *SyncMessage_PniChangeNumber `protobuf:"bytes,18,opt,name=pniChangeNumber,oneof"` +} + +type SyncMessage_CallEvent_ struct { + CallEvent *SyncMessage_CallEvent `protobuf:"bytes,19,opt,name=callEvent,oneof"` +} + +type SyncMessage_CallLinkUpdate_ struct { + CallLinkUpdate *SyncMessage_CallLinkUpdate `protobuf:"bytes,20,opt,name=callLinkUpdate,oneof"` +} + +type SyncMessage_CallLogEvent_ struct { + CallLogEvent *SyncMessage_CallLogEvent `protobuf:"bytes,21,opt,name=callLogEvent,oneof"` +} + +type SyncMessage_DeleteForMe_ struct { + DeleteForMe *SyncMessage_DeleteForMe `protobuf:"bytes,22,opt,name=deleteForMe,oneof"` +} + +type SyncMessage_DeviceNameChange_ struct { + DeviceNameChange *SyncMessage_DeviceNameChange `protobuf:"bytes,23,opt,name=deviceNameChange,oneof"` +} + +type SyncMessage_AttachmentBackfillRequest_ struct { + AttachmentBackfillRequest *SyncMessage_AttachmentBackfillRequest `protobuf:"bytes,24,opt,name=attachmentBackfillRequest,oneof"` +} + +type SyncMessage_AttachmentBackfillResponse_ struct { + AttachmentBackfillResponse *SyncMessage_AttachmentBackfillResponse `protobuf:"bytes,25,opt,name=attachmentBackfillResponse,oneof"` +} + +func (*SyncMessage_Sent_) isSyncMessage_Content() {} + +func (*SyncMessage_Contacts_) isSyncMessage_Content() {} + +func (*SyncMessage_Request_) isSyncMessage_Content() {} + +func (*SyncMessage_Blocked_) isSyncMessage_Content() {} + +func (*SyncMessage_Verified) isSyncMessage_Content() {} + +func (*SyncMessage_Configuration_) isSyncMessage_Content() {} + +func (*SyncMessage_ViewOnceOpen_) isSyncMessage_Content() {} + +func (*SyncMessage_FetchLatest_) isSyncMessage_Content() {} + +func (*SyncMessage_Keys_) isSyncMessage_Content() {} + +func (*SyncMessage_MessageRequestResponse_) isSyncMessage_Content() {} + +func (*SyncMessage_OutgoingPayment_) isSyncMessage_Content() {} + +func (*SyncMessage_PniChangeNumber_) isSyncMessage_Content() {} + +func (*SyncMessage_CallEvent_) isSyncMessage_Content() {} + +func (*SyncMessage_CallLinkUpdate_) isSyncMessage_Content() {} + +func (*SyncMessage_CallLogEvent_) isSyncMessage_Content() {} + +func (*SyncMessage_DeleteForMe_) isSyncMessage_Content() {} + +func (*SyncMessage_DeviceNameChange_) isSyncMessage_Content() {} + +func (*SyncMessage_AttachmentBackfillRequest_) isSyncMessage_Content() {} + +func (*SyncMessage_AttachmentBackfillResponse_) isSyncMessage_Content() {} + type AttachmentPointer struct { state protoimpl.MessageState `protogen:"open.v1"` // Types that are valid to be assigned to AttachmentIdentifier: @@ -5117,8 +5418,8 @@ type DataMessage_PollVote struct { state protoimpl.MessageState `protogen:"open.v1"` TargetAuthorAciBinary []byte `protobuf:"bytes,1,opt,name=targetAuthorAciBinary" json:"targetAuthorAciBinary,omitempty"` TargetSentTimestamp *uint64 `protobuf:"varint,2,opt,name=targetSentTimestamp" json:"targetSentTimestamp,omitempty"` - OptionIndexes []uint32 `protobuf:"varint,3,rep,name=optionIndexes" json:"optionIndexes,omitempty"` // must be in the range [0, options.length) from the PollCreate - VoteCount *uint32 `protobuf:"varint,4,opt,name=voteCount" json:"voteCount,omitempty"` // increment this by 1 each time you vote on a given poll + OptionIndexes []uint32 `protobuf:"varint,3,rep,name=optionIndexes" json:"optionIndexes,omitempty"` + VoteCount *uint32 `protobuf:"varint,4,opt,name=voteCount" json:"voteCount,omitempty"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } @@ -5331,6 +5632,58 @@ func (x *DataMessage_UnpinMessage) GetTargetSentTimestamp() uint64 { return 0 } +type DataMessage_AdminDelete struct { + state protoimpl.MessageState `protogen:"open.v1"` + TargetAuthorAciBinary []byte `protobuf:"bytes,1,opt,name=targetAuthorAciBinary" json:"targetAuthorAciBinary,omitempty"` // 16-byte UUID + TargetSentTimestamp *uint64 `protobuf:"varint,2,opt,name=targetSentTimestamp" json:"targetSentTimestamp,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *DataMessage_AdminDelete) Reset() { + *x = DataMessage_AdminDelete{} + mi := &file_SignalService_proto_msgTypes[42] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *DataMessage_AdminDelete) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*DataMessage_AdminDelete) ProtoMessage() {} + +func (x *DataMessage_AdminDelete) ProtoReflect() protoreflect.Message { + mi := &file_SignalService_proto_msgTypes[42] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use DataMessage_AdminDelete.ProtoReflect.Descriptor instead. +func (*DataMessage_AdminDelete) Descriptor() ([]byte, []int) { + return file_SignalService_proto_rawDescGZIP(), []int{3, 14} +} + +func (x *DataMessage_AdminDelete) GetTargetAuthorAciBinary() []byte { + if x != nil { + return x.TargetAuthorAciBinary + } + return nil +} + +func (x *DataMessage_AdminDelete) GetTargetSentTimestamp() uint64 { + if x != nil && x.TargetSentTimestamp != nil { + return *x.TargetSentTimestamp + } + return 0 +} + type DataMessage_Payment_Amount struct { state protoimpl.MessageState `protogen:"open.v1"` // Types that are valid to be assigned to Amount: @@ -5343,7 +5696,7 @@ type DataMessage_Payment_Amount struct { func (x *DataMessage_Payment_Amount) Reset() { *x = DataMessage_Payment_Amount{} - mi := &file_SignalService_proto_msgTypes[42] + mi := &file_SignalService_proto_msgTypes[43] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5355,7 +5708,7 @@ func (x *DataMessage_Payment_Amount) String() string { func (*DataMessage_Payment_Amount) ProtoMessage() {} func (x *DataMessage_Payment_Amount) ProtoReflect() protoreflect.Message { - mi := &file_SignalService_proto_msgTypes[42] + mi := &file_SignalService_proto_msgTypes[43] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5411,7 +5764,7 @@ type DataMessage_Payment_Notification struct { func (x *DataMessage_Payment_Notification) Reset() { *x = DataMessage_Payment_Notification{} - mi := &file_SignalService_proto_msgTypes[43] + mi := &file_SignalService_proto_msgTypes[44] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5423,7 +5776,7 @@ func (x *DataMessage_Payment_Notification) String() string { func (*DataMessage_Payment_Notification) ProtoMessage() {} func (x *DataMessage_Payment_Notification) ProtoReflect() protoreflect.Message { - mi := &file_SignalService_proto_msgTypes[43] + mi := &file_SignalService_proto_msgTypes[44] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5482,7 +5835,7 @@ type DataMessage_Payment_Activation struct { func (x *DataMessage_Payment_Activation) Reset() { *x = DataMessage_Payment_Activation{} - mi := &file_SignalService_proto_msgTypes[44] + mi := &file_SignalService_proto_msgTypes[45] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5494,7 +5847,7 @@ func (x *DataMessage_Payment_Activation) String() string { func (*DataMessage_Payment_Activation) ProtoMessage() {} func (x *DataMessage_Payment_Activation) ProtoReflect() protoreflect.Message { - mi := &file_SignalService_proto_msgTypes[44] + mi := &file_SignalService_proto_msgTypes[45] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5526,7 +5879,7 @@ type DataMessage_Payment_Amount_MobileCoin struct { func (x *DataMessage_Payment_Amount_MobileCoin) Reset() { *x = DataMessage_Payment_Amount_MobileCoin{} - mi := &file_SignalService_proto_msgTypes[45] + mi := &file_SignalService_proto_msgTypes[46] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5538,7 +5891,7 @@ func (x *DataMessage_Payment_Amount_MobileCoin) String() string { func (*DataMessage_Payment_Amount_MobileCoin) ProtoMessage() {} func (x *DataMessage_Payment_Amount_MobileCoin) ProtoReflect() protoreflect.Message { - mi := &file_SignalService_proto_msgTypes[45] + mi := &file_SignalService_proto_msgTypes[46] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5570,7 +5923,7 @@ type DataMessage_Payment_Notification_MobileCoin struct { func (x *DataMessage_Payment_Notification_MobileCoin) Reset() { *x = DataMessage_Payment_Notification_MobileCoin{} - mi := &file_SignalService_proto_msgTypes[46] + mi := &file_SignalService_proto_msgTypes[47] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5582,7 +5935,7 @@ func (x *DataMessage_Payment_Notification_MobileCoin) String() string { func (*DataMessage_Payment_Notification_MobileCoin) ProtoMessage() {} func (x *DataMessage_Payment_Notification_MobileCoin) ProtoReflect() protoreflect.Message { - mi := &file_SignalService_proto_msgTypes[46] + mi := &file_SignalService_proto_msgTypes[47] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5616,7 +5969,7 @@ type DataMessage_Quote_QuotedAttachment struct { func (x *DataMessage_Quote_QuotedAttachment) Reset() { *x = DataMessage_Quote_QuotedAttachment{} - mi := &file_SignalService_proto_msgTypes[47] + mi := &file_SignalService_proto_msgTypes[48] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5628,7 +5981,7 @@ func (x *DataMessage_Quote_QuotedAttachment) String() string { func (*DataMessage_Quote_QuotedAttachment) ProtoMessage() {} func (x *DataMessage_Quote_QuotedAttachment) ProtoReflect() protoreflect.Message { - mi := &file_SignalService_proto_msgTypes[47] + mi := &file_SignalService_proto_msgTypes[48] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5679,7 +6032,7 @@ type DataMessage_Contact_Name struct { func (x *DataMessage_Contact_Name) Reset() { *x = DataMessage_Contact_Name{} - mi := &file_SignalService_proto_msgTypes[48] + mi := &file_SignalService_proto_msgTypes[49] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5691,7 +6044,7 @@ func (x *DataMessage_Contact_Name) String() string { func (*DataMessage_Contact_Name) ProtoMessage() {} func (x *DataMessage_Contact_Name) ProtoReflect() protoreflect.Message { - mi := &file_SignalService_proto_msgTypes[48] + mi := &file_SignalService_proto_msgTypes[49] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5760,7 +6113,7 @@ type DataMessage_Contact_Phone struct { func (x *DataMessage_Contact_Phone) Reset() { *x = DataMessage_Contact_Phone{} - mi := &file_SignalService_proto_msgTypes[49] + mi := &file_SignalService_proto_msgTypes[50] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5772,7 +6125,7 @@ func (x *DataMessage_Contact_Phone) String() string { func (*DataMessage_Contact_Phone) ProtoMessage() {} func (x *DataMessage_Contact_Phone) ProtoReflect() protoreflect.Message { - mi := &file_SignalService_proto_msgTypes[49] + mi := &file_SignalService_proto_msgTypes[50] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5820,7 +6173,7 @@ type DataMessage_Contact_Email struct { func (x *DataMessage_Contact_Email) Reset() { *x = DataMessage_Contact_Email{} - mi := &file_SignalService_proto_msgTypes[50] + mi := &file_SignalService_proto_msgTypes[51] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5832,7 +6185,7 @@ func (x *DataMessage_Contact_Email) String() string { func (*DataMessage_Contact_Email) ProtoMessage() {} func (x *DataMessage_Contact_Email) ProtoReflect() protoreflect.Message { - mi := &file_SignalService_proto_msgTypes[50] + mi := &file_SignalService_proto_msgTypes[51] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5886,7 +6239,7 @@ type DataMessage_Contact_PostalAddress struct { func (x *DataMessage_Contact_PostalAddress) Reset() { *x = DataMessage_Contact_PostalAddress{} - mi := &file_SignalService_proto_msgTypes[51] + mi := &file_SignalService_proto_msgTypes[52] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5898,7 +6251,7 @@ func (x *DataMessage_Contact_PostalAddress) String() string { func (*DataMessage_Contact_PostalAddress) ProtoMessage() {} func (x *DataMessage_Contact_PostalAddress) ProtoReflect() protoreflect.Message { - mi := &file_SignalService_proto_msgTypes[51] + mi := &file_SignalService_proto_msgTypes[52] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5987,7 +6340,7 @@ type DataMessage_Contact_Avatar struct { func (x *DataMessage_Contact_Avatar) Reset() { *x = DataMessage_Contact_Avatar{} - mi := &file_SignalService_proto_msgTypes[52] + mi := &file_SignalService_proto_msgTypes[53] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5999,7 +6352,7 @@ func (x *DataMessage_Contact_Avatar) String() string { func (*DataMessage_Contact_Avatar) ProtoMessage() {} func (x *DataMessage_Contact_Avatar) ProtoReflect() protoreflect.Message { - mi := &file_SignalService_proto_msgTypes[52] + mi := &file_SignalService_proto_msgTypes[53] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6042,7 +6395,7 @@ type TextAttachment_Gradient struct { func (x *TextAttachment_Gradient) Reset() { *x = TextAttachment_Gradient{} - mi := &file_SignalService_proto_msgTypes[53] + mi := &file_SignalService_proto_msgTypes[54] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6054,7 +6407,7 @@ func (x *TextAttachment_Gradient) String() string { func (*TextAttachment_Gradient) ProtoMessage() {} func (x *TextAttachment_Gradient) ProtoReflect() protoreflect.Message { - mi := &file_SignalService_proto_msgTypes[53] + mi := &file_SignalService_proto_msgTypes[54] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6129,7 +6482,7 @@ const ( func (x *SyncMessage_Sent) Reset() { *x = SyncMessage_Sent{} - mi := &file_SignalService_proto_msgTypes[54] + mi := &file_SignalService_proto_msgTypes[55] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6141,7 +6494,7 @@ func (x *SyncMessage_Sent) String() string { func (*SyncMessage_Sent) ProtoMessage() {} func (x *SyncMessage_Sent) ProtoReflect() protoreflect.Message { - mi := &file_SignalService_proto_msgTypes[54] + mi := &file_SignalService_proto_msgTypes[55] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6249,7 +6602,7 @@ const ( func (x *SyncMessage_Contacts) Reset() { *x = SyncMessage_Contacts{} - mi := &file_SignalService_proto_msgTypes[55] + mi := &file_SignalService_proto_msgTypes[56] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6261,7 +6614,7 @@ func (x *SyncMessage_Contacts) String() string { func (*SyncMessage_Contacts) ProtoMessage() {} func (x *SyncMessage_Contacts) ProtoReflect() protoreflect.Message { - mi := &file_SignalService_proto_msgTypes[55] + mi := &file_SignalService_proto_msgTypes[56] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6303,7 +6656,7 @@ type SyncMessage_Blocked struct { func (x *SyncMessage_Blocked) Reset() { *x = SyncMessage_Blocked{} - mi := &file_SignalService_proto_msgTypes[56] + mi := &file_SignalService_proto_msgTypes[57] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6315,7 +6668,7 @@ func (x *SyncMessage_Blocked) String() string { func (*SyncMessage_Blocked) ProtoMessage() {} func (x *SyncMessage_Blocked) ProtoReflect() protoreflect.Message { - mi := &file_SignalService_proto_msgTypes[56] + mi := &file_SignalService_proto_msgTypes[57] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6368,7 +6721,7 @@ type SyncMessage_Request struct { func (x *SyncMessage_Request) Reset() { *x = SyncMessage_Request{} - mi := &file_SignalService_proto_msgTypes[57] + mi := &file_SignalService_proto_msgTypes[58] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6380,7 +6733,7 @@ func (x *SyncMessage_Request) String() string { func (*SyncMessage_Request) ProtoMessage() {} func (x *SyncMessage_Request) ProtoReflect() protoreflect.Message { - mi := &file_SignalService_proto_msgTypes[57] + mi := &file_SignalService_proto_msgTypes[58] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6414,7 +6767,7 @@ type SyncMessage_Read struct { func (x *SyncMessage_Read) Reset() { *x = SyncMessage_Read{} - mi := &file_SignalService_proto_msgTypes[58] + mi := &file_SignalService_proto_msgTypes[59] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6426,7 +6779,7 @@ func (x *SyncMessage_Read) String() string { func (*SyncMessage_Read) ProtoMessage() {} func (x *SyncMessage_Read) ProtoReflect() protoreflect.Message { - mi := &file_SignalService_proto_msgTypes[58] + mi := &file_SignalService_proto_msgTypes[59] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6474,7 +6827,7 @@ type SyncMessage_Viewed struct { func (x *SyncMessage_Viewed) Reset() { *x = SyncMessage_Viewed{} - mi := &file_SignalService_proto_msgTypes[59] + mi := &file_SignalService_proto_msgTypes[60] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6486,7 +6839,7 @@ func (x *SyncMessage_Viewed) String() string { func (*SyncMessage_Viewed) ProtoMessage() {} func (x *SyncMessage_Viewed) ProtoReflect() protoreflect.Message { - mi := &file_SignalService_proto_msgTypes[59] + mi := &file_SignalService_proto_msgTypes[60] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6528,7 +6881,6 @@ type SyncMessage_Configuration struct { ReadReceipts *bool `protobuf:"varint,1,opt,name=readReceipts" json:"readReceipts,omitempty"` UnidentifiedDeliveryIndicators *bool `protobuf:"varint,2,opt,name=unidentifiedDeliveryIndicators" json:"unidentifiedDeliveryIndicators,omitempty"` TypingIndicators *bool `protobuf:"varint,3,opt,name=typingIndicators" json:"typingIndicators,omitempty"` - ProvisioningVersion *uint32 `protobuf:"varint,5,opt,name=provisioningVersion" json:"provisioningVersion,omitempty"` LinkPreviews *bool `protobuf:"varint,6,opt,name=linkPreviews" json:"linkPreviews,omitempty"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache @@ -6536,7 +6888,7 @@ type SyncMessage_Configuration struct { func (x *SyncMessage_Configuration) Reset() { *x = SyncMessage_Configuration{} - mi := &file_SignalService_proto_msgTypes[60] + mi := &file_SignalService_proto_msgTypes[61] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6548,7 +6900,7 @@ func (x *SyncMessage_Configuration) String() string { func (*SyncMessage_Configuration) ProtoMessage() {} func (x *SyncMessage_Configuration) ProtoReflect() protoreflect.Message { - mi := &file_SignalService_proto_msgTypes[60] + mi := &file_SignalService_proto_msgTypes[61] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6585,13 +6937,6 @@ func (x *SyncMessage_Configuration) GetTypingIndicators() bool { return false } -func (x *SyncMessage_Configuration) GetProvisioningVersion() uint32 { - if x != nil && x.ProvisioningVersion != nil { - return *x.ProvisioningVersion - } - return 0 -} - func (x *SyncMessage_Configuration) GetLinkPreviews() bool { if x != nil && x.LinkPreviews != nil { return *x.LinkPreviews @@ -6610,7 +6955,7 @@ type SyncMessage_StickerPackOperation struct { func (x *SyncMessage_StickerPackOperation) Reset() { *x = SyncMessage_StickerPackOperation{} - mi := &file_SignalService_proto_msgTypes[61] + mi := &file_SignalService_proto_msgTypes[62] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6622,7 +6967,7 @@ func (x *SyncMessage_StickerPackOperation) String() string { func (*SyncMessage_StickerPackOperation) ProtoMessage() {} func (x *SyncMessage_StickerPackOperation) ProtoReflect() protoreflect.Message { - mi := &file_SignalService_proto_msgTypes[61] + mi := &file_SignalService_proto_msgTypes[62] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6670,7 +7015,7 @@ type SyncMessage_ViewOnceOpen struct { func (x *SyncMessage_ViewOnceOpen) Reset() { *x = SyncMessage_ViewOnceOpen{} - mi := &file_SignalService_proto_msgTypes[62] + mi := &file_SignalService_proto_msgTypes[63] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6682,7 +7027,7 @@ func (x *SyncMessage_ViewOnceOpen) String() string { func (*SyncMessage_ViewOnceOpen) ProtoMessage() {} func (x *SyncMessage_ViewOnceOpen) ProtoReflect() protoreflect.Message { - mi := &file_SignalService_proto_msgTypes[62] + mi := &file_SignalService_proto_msgTypes[63] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6728,7 +7073,7 @@ type SyncMessage_FetchLatest struct { func (x *SyncMessage_FetchLatest) Reset() { *x = SyncMessage_FetchLatest{} - mi := &file_SignalService_proto_msgTypes[63] + mi := &file_SignalService_proto_msgTypes[64] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6740,7 +7085,7 @@ func (x *SyncMessage_FetchLatest) String() string { func (*SyncMessage_FetchLatest) ProtoMessage() {} func (x *SyncMessage_FetchLatest) ProtoReflect() protoreflect.Message { - mi := &file_SignalService_proto_msgTypes[63] + mi := &file_SignalService_proto_msgTypes[64] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6765,7 +7110,6 @@ func (x *SyncMessage_FetchLatest) GetType() SyncMessage_FetchLatest_Type { type SyncMessage_Keys struct { state protoimpl.MessageState `protogen:"open.v1"` - Master []byte `protobuf:"bytes,2,opt,name=master" json:"master,omitempty"` // deprecated: this field will be removed in a future release. AccountEntropyPool *string `protobuf:"bytes,3,opt,name=accountEntropyPool" json:"accountEntropyPool,omitempty"` MediaRootBackupKey []byte `protobuf:"bytes,4,opt,name=mediaRootBackupKey" json:"mediaRootBackupKey,omitempty"` unknownFields protoimpl.UnknownFields @@ -6774,7 +7118,7 @@ type SyncMessage_Keys struct { func (x *SyncMessage_Keys) Reset() { *x = SyncMessage_Keys{} - mi := &file_SignalService_proto_msgTypes[64] + mi := &file_SignalService_proto_msgTypes[65] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6786,7 +7130,7 @@ func (x *SyncMessage_Keys) String() string { func (*SyncMessage_Keys) ProtoMessage() {} func (x *SyncMessage_Keys) ProtoReflect() protoreflect.Message { - mi := &file_SignalService_proto_msgTypes[64] + mi := &file_SignalService_proto_msgTypes[65] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6802,13 +7146,6 @@ func (*SyncMessage_Keys) Descriptor() ([]byte, []int) { return file_SignalService_proto_rawDescGZIP(), []int{11, 10} } -func (x *SyncMessage_Keys) GetMaster() []byte { - if x != nil { - return x.Master - } - return nil -} - func (x *SyncMessage_Keys) GetAccountEntropyPool() string { if x != nil && x.AccountEntropyPool != nil { return *x.AccountEntropyPool @@ -6833,7 +7170,7 @@ type SyncMessage_PniIdentity struct { func (x *SyncMessage_PniIdentity) Reset() { *x = SyncMessage_PniIdentity{} - mi := &file_SignalService_proto_msgTypes[65] + mi := &file_SignalService_proto_msgTypes[66] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6845,7 +7182,7 @@ func (x *SyncMessage_PniIdentity) String() string { func (*SyncMessage_PniIdentity) ProtoMessage() {} func (x *SyncMessage_PniIdentity) ProtoReflect() protoreflect.Message { - mi := &file_SignalService_proto_msgTypes[65] + mi := &file_SignalService_proto_msgTypes[66] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6887,7 +7224,7 @@ type SyncMessage_MessageRequestResponse struct { func (x *SyncMessage_MessageRequestResponse) Reset() { *x = SyncMessage_MessageRequestResponse{} - mi := &file_SignalService_proto_msgTypes[66] + mi := &file_SignalService_proto_msgTypes[67] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6899,7 +7236,7 @@ func (x *SyncMessage_MessageRequestResponse) String() string { func (*SyncMessage_MessageRequestResponse) ProtoMessage() {} func (x *SyncMessage_MessageRequestResponse) ProtoReflect() protoreflect.Message { - mi := &file_SignalService_proto_msgTypes[66] + mi := &file_SignalService_proto_msgTypes[67] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6957,7 +7294,7 @@ type SyncMessage_OutgoingPayment struct { func (x *SyncMessage_OutgoingPayment) Reset() { *x = SyncMessage_OutgoingPayment{} - mi := &file_SignalService_proto_msgTypes[67] + mi := &file_SignalService_proto_msgTypes[68] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6969,7 +7306,7 @@ func (x *SyncMessage_OutgoingPayment) String() string { func (*SyncMessage_OutgoingPayment) ProtoMessage() {} func (x *SyncMessage_OutgoingPayment) ProtoReflect() protoreflect.Message { - mi := &file_SignalService_proto_msgTypes[67] + mi := &file_SignalService_proto_msgTypes[68] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7039,7 +7376,7 @@ type SyncMessage_PniChangeNumber struct { func (x *SyncMessage_PniChangeNumber) Reset() { *x = SyncMessage_PniChangeNumber{} - mi := &file_SignalService_proto_msgTypes[68] + mi := &file_SignalService_proto_msgTypes[69] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7051,7 +7388,7 @@ func (x *SyncMessage_PniChangeNumber) String() string { func (*SyncMessage_PniChangeNumber) ProtoMessage() {} func (x *SyncMessage_PniChangeNumber) ProtoReflect() protoreflect.Message { - mi := &file_SignalService_proto_msgTypes[68] + mi := &file_SignalService_proto_msgTypes[69] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7121,7 +7458,7 @@ type SyncMessage_CallEvent struct { func (x *SyncMessage_CallEvent) Reset() { *x = SyncMessage_CallEvent{} - mi := &file_SignalService_proto_msgTypes[69] + mi := &file_SignalService_proto_msgTypes[70] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7133,7 +7470,7 @@ func (x *SyncMessage_CallEvent) String() string { func (*SyncMessage_CallEvent) ProtoMessage() {} func (x *SyncMessage_CallEvent) ProtoReflect() protoreflect.Message { - mi := &file_SignalService_proto_msgTypes[69] + mi := &file_SignalService_proto_msgTypes[70] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7196,14 +7533,13 @@ type SyncMessage_CallLinkUpdate struct { RootKey []byte `protobuf:"bytes,1,opt,name=rootKey" json:"rootKey,omitempty"` AdminPasskey []byte `protobuf:"bytes,2,opt,name=adminPasskey" json:"adminPasskey,omitempty"` Type *SyncMessage_CallLinkUpdate_Type `protobuf:"varint,3,opt,name=type,enum=signalservice.SyncMessage_CallLinkUpdate_Type" json:"type,omitempty"` // defaults to UPDATE - Epoch []byte `protobuf:"bytes,4,opt,name=epoch" json:"epoch,omitempty"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } func (x *SyncMessage_CallLinkUpdate) Reset() { *x = SyncMessage_CallLinkUpdate{} - mi := &file_SignalService_proto_msgTypes[70] + mi := &file_SignalService_proto_msgTypes[71] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7215,7 +7551,7 @@ func (x *SyncMessage_CallLinkUpdate) String() string { func (*SyncMessage_CallLinkUpdate) ProtoMessage() {} func (x *SyncMessage_CallLinkUpdate) ProtoReflect() protoreflect.Message { - mi := &file_SignalService_proto_msgTypes[70] + mi := &file_SignalService_proto_msgTypes[71] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7252,13 +7588,6 @@ func (x *SyncMessage_CallLinkUpdate) GetType() SyncMessage_CallLinkUpdate_Type { return SyncMessage_CallLinkUpdate_UPDATE } -func (x *SyncMessage_CallLinkUpdate) GetEpoch() []byte { - if x != nil { - return x.Epoch - } - return nil -} - type SyncMessage_CallLogEvent struct { state protoimpl.MessageState `protogen:"open.v1"` Type *SyncMessage_CallLogEvent_Type `protobuf:"varint,1,opt,name=type,enum=signalservice.SyncMessage_CallLogEvent_Type" json:"type,omitempty"` @@ -7276,7 +7605,7 @@ type SyncMessage_CallLogEvent struct { func (x *SyncMessage_CallLogEvent) Reset() { *x = SyncMessage_CallLogEvent{} - mi := &file_SignalService_proto_msgTypes[71] + mi := &file_SignalService_proto_msgTypes[72] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7288,7 +7617,7 @@ func (x *SyncMessage_CallLogEvent) String() string { func (*SyncMessage_CallLogEvent) ProtoMessage() {} func (x *SyncMessage_CallLogEvent) ProtoReflect() protoreflect.Message { - mi := &file_SignalService_proto_msgTypes[71] + mi := &file_SignalService_proto_msgTypes[72] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7344,7 +7673,7 @@ type SyncMessage_DeleteForMe struct { func (x *SyncMessage_DeleteForMe) Reset() { *x = SyncMessage_DeleteForMe{} - mi := &file_SignalService_proto_msgTypes[72] + mi := &file_SignalService_proto_msgTypes[73] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7356,7 +7685,7 @@ func (x *SyncMessage_DeleteForMe) String() string { func (*SyncMessage_DeleteForMe) ProtoMessage() {} func (x *SyncMessage_DeleteForMe) ProtoReflect() protoreflect.Message { - mi := &file_SignalService_proto_msgTypes[72] + mi := &file_SignalService_proto_msgTypes[73] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7409,7 +7738,7 @@ type SyncMessage_DeviceNameChange struct { func (x *SyncMessage_DeviceNameChange) Reset() { *x = SyncMessage_DeviceNameChange{} - mi := &file_SignalService_proto_msgTypes[73] + mi := &file_SignalService_proto_msgTypes[74] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7421,7 +7750,7 @@ func (x *SyncMessage_DeviceNameChange) String() string { func (*SyncMessage_DeviceNameChange) ProtoMessage() {} func (x *SyncMessage_DeviceNameChange) ProtoReflect() protoreflect.Message { - mi := &file_SignalService_proto_msgTypes[73] + mi := &file_SignalService_proto_msgTypes[74] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7454,7 +7783,7 @@ type SyncMessage_AttachmentBackfillRequest struct { func (x *SyncMessage_AttachmentBackfillRequest) Reset() { *x = SyncMessage_AttachmentBackfillRequest{} - mi := &file_SignalService_proto_msgTypes[74] + mi := &file_SignalService_proto_msgTypes[75] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7466,7 +7795,7 @@ func (x *SyncMessage_AttachmentBackfillRequest) String() string { func (*SyncMessage_AttachmentBackfillRequest) ProtoMessage() {} func (x *SyncMessage_AttachmentBackfillRequest) ProtoReflect() protoreflect.Message { - mi := &file_SignalService_proto_msgTypes[74] + mi := &file_SignalService_proto_msgTypes[75] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7511,7 +7840,7 @@ type SyncMessage_AttachmentBackfillResponse struct { func (x *SyncMessage_AttachmentBackfillResponse) Reset() { *x = SyncMessage_AttachmentBackfillResponse{} - mi := &file_SignalService_proto_msgTypes[75] + mi := &file_SignalService_proto_msgTypes[76] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7523,7 +7852,7 @@ func (x *SyncMessage_AttachmentBackfillResponse) String() string { func (*SyncMessage_AttachmentBackfillResponse) ProtoMessage() {} func (x *SyncMessage_AttachmentBackfillResponse) ProtoReflect() protoreflect.Message { - mi := &file_SignalService_proto_msgTypes[75] + mi := &file_SignalService_proto_msgTypes[76] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7608,7 +7937,7 @@ type SyncMessage_Sent_UnidentifiedDeliveryStatus struct { func (x *SyncMessage_Sent_UnidentifiedDeliveryStatus) Reset() { *x = SyncMessage_Sent_UnidentifiedDeliveryStatus{} - mi := &file_SignalService_proto_msgTypes[76] + mi := &file_SignalService_proto_msgTypes[77] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7620,7 +7949,7 @@ func (x *SyncMessage_Sent_UnidentifiedDeliveryStatus) String() string { func (*SyncMessage_Sent_UnidentifiedDeliveryStatus) ProtoMessage() {} func (x *SyncMessage_Sent_UnidentifiedDeliveryStatus) ProtoReflect() protoreflect.Message { - mi := &file_SignalService_proto_msgTypes[76] + mi := &file_SignalService_proto_msgTypes[77] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7676,7 +8005,7 @@ type SyncMessage_Sent_StoryMessageRecipient struct { func (x *SyncMessage_Sent_StoryMessageRecipient) Reset() { *x = SyncMessage_Sent_StoryMessageRecipient{} - mi := &file_SignalService_proto_msgTypes[77] + mi := &file_SignalService_proto_msgTypes[78] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7688,7 +8017,7 @@ func (x *SyncMessage_Sent_StoryMessageRecipient) String() string { func (*SyncMessage_Sent_StoryMessageRecipient) ProtoMessage() {} func (x *SyncMessage_Sent_StoryMessageRecipient) ProtoReflect() protoreflect.Message { - mi := &file_SignalService_proto_msgTypes[77] + mi := &file_SignalService_proto_msgTypes[78] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7748,7 +8077,7 @@ type SyncMessage_OutgoingPayment_MobileCoin struct { func (x *SyncMessage_OutgoingPayment_MobileCoin) Reset() { *x = SyncMessage_OutgoingPayment_MobileCoin{} - mi := &file_SignalService_proto_msgTypes[78] + mi := &file_SignalService_proto_msgTypes[79] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7760,7 +8089,7 @@ func (x *SyncMessage_OutgoingPayment_MobileCoin) String() string { func (*SyncMessage_OutgoingPayment_MobileCoin) ProtoMessage() {} func (x *SyncMessage_OutgoingPayment_MobileCoin) ProtoReflect() protoreflect.Message { - mi := &file_SignalService_proto_msgTypes[78] + mi := &file_SignalService_proto_msgTypes[79] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7842,7 +8171,7 @@ type SyncMessage_DeleteForMe_MessageDeletes struct { func (x *SyncMessage_DeleteForMe_MessageDeletes) Reset() { *x = SyncMessage_DeleteForMe_MessageDeletes{} - mi := &file_SignalService_proto_msgTypes[79] + mi := &file_SignalService_proto_msgTypes[80] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7854,7 +8183,7 @@ func (x *SyncMessage_DeleteForMe_MessageDeletes) String() string { func (*SyncMessage_DeleteForMe_MessageDeletes) ProtoMessage() {} func (x *SyncMessage_DeleteForMe_MessageDeletes) ProtoReflect() protoreflect.Message { - mi := &file_SignalService_proto_msgTypes[79] + mi := &file_SignalService_proto_msgTypes[80] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7900,7 +8229,7 @@ type SyncMessage_DeleteForMe_AttachmentDelete struct { func (x *SyncMessage_DeleteForMe_AttachmentDelete) Reset() { *x = SyncMessage_DeleteForMe_AttachmentDelete{} - mi := &file_SignalService_proto_msgTypes[80] + mi := &file_SignalService_proto_msgTypes[81] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7912,7 +8241,7 @@ func (x *SyncMessage_DeleteForMe_AttachmentDelete) String() string { func (*SyncMessage_DeleteForMe_AttachmentDelete) ProtoMessage() {} func (x *SyncMessage_DeleteForMe_AttachmentDelete) ProtoReflect() protoreflect.Message { - mi := &file_SignalService_proto_msgTypes[80] + mi := &file_SignalService_proto_msgTypes[81] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7975,7 +8304,7 @@ type SyncMessage_DeleteForMe_ConversationDelete struct { func (x *SyncMessage_DeleteForMe_ConversationDelete) Reset() { *x = SyncMessage_DeleteForMe_ConversationDelete{} - mi := &file_SignalService_proto_msgTypes[81] + mi := &file_SignalService_proto_msgTypes[82] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7987,7 +8316,7 @@ func (x *SyncMessage_DeleteForMe_ConversationDelete) String() string { func (*SyncMessage_DeleteForMe_ConversationDelete) ProtoMessage() {} func (x *SyncMessage_DeleteForMe_ConversationDelete) ProtoReflect() protoreflect.Message { - mi := &file_SignalService_proto_msgTypes[81] + mi := &file_SignalService_proto_msgTypes[82] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8040,7 +8369,7 @@ type SyncMessage_DeleteForMe_LocalOnlyConversationDelete struct { func (x *SyncMessage_DeleteForMe_LocalOnlyConversationDelete) Reset() { *x = SyncMessage_DeleteForMe_LocalOnlyConversationDelete{} - mi := &file_SignalService_proto_msgTypes[82] + mi := &file_SignalService_proto_msgTypes[83] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8052,7 +8381,7 @@ func (x *SyncMessage_DeleteForMe_LocalOnlyConversationDelete) String() string { func (*SyncMessage_DeleteForMe_LocalOnlyConversationDelete) ProtoMessage() {} func (x *SyncMessage_DeleteForMe_LocalOnlyConversationDelete) ProtoReflect() protoreflect.Message { - mi := &file_SignalService_proto_msgTypes[82] + mi := &file_SignalService_proto_msgTypes[83] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8088,7 +8417,7 @@ type SyncMessage_AttachmentBackfillResponse_AttachmentData struct { func (x *SyncMessage_AttachmentBackfillResponse_AttachmentData) Reset() { *x = SyncMessage_AttachmentBackfillResponse_AttachmentData{} - mi := &file_SignalService_proto_msgTypes[83] + mi := &file_SignalService_proto_msgTypes[84] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8100,7 +8429,7 @@ func (x *SyncMessage_AttachmentBackfillResponse_AttachmentData) String() string func (*SyncMessage_AttachmentBackfillResponse_AttachmentData) ProtoMessage() {} func (x *SyncMessage_AttachmentBackfillResponse_AttachmentData) ProtoReflect() protoreflect.Message { - mi := &file_SignalService_proto_msgTypes[83] + mi := &file_SignalService_proto_msgTypes[84] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8169,7 +8498,7 @@ type SyncMessage_AttachmentBackfillResponse_AttachmentDataList struct { func (x *SyncMessage_AttachmentBackfillResponse_AttachmentDataList) Reset() { *x = SyncMessage_AttachmentBackfillResponse_AttachmentDataList{} - mi := &file_SignalService_proto_msgTypes[84] + mi := &file_SignalService_proto_msgTypes[85] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8181,7 +8510,7 @@ func (x *SyncMessage_AttachmentBackfillResponse_AttachmentDataList) String() str func (*SyncMessage_AttachmentBackfillResponse_AttachmentDataList) ProtoMessage() {} func (x *SyncMessage_AttachmentBackfillResponse_AttachmentDataList) ProtoReflect() protoreflect.Message { - mi := &file_SignalService_proto_msgTypes[84] + mi := &file_SignalService_proto_msgTypes[85] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8221,7 +8550,7 @@ type ContactDetails_Avatar struct { func (x *ContactDetails_Avatar) Reset() { *x = ContactDetails_Avatar{} - mi := &file_SignalService_proto_msgTypes[85] + mi := &file_SignalService_proto_msgTypes[86] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8233,7 +8562,7 @@ func (x *ContactDetails_Avatar) String() string { func (*ContactDetails_Avatar) ProtoMessage() {} func (x *ContactDetails_Avatar) ProtoReflect() protoreflect.Message { - mi := &file_SignalService_proto_msgTypes[85] + mi := &file_SignalService_proto_msgTypes[86] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8273,7 +8602,7 @@ type PaymentAddress_MobileCoin struct { func (x *PaymentAddress_MobileCoin) Reset() { *x = PaymentAddress_MobileCoin{} - mi := &file_SignalService_proto_msgTypes[86] + mi := &file_SignalService_proto_msgTypes[87] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8285,7 +8614,7 @@ func (x *PaymentAddress_MobileCoin) String() string { func (*PaymentAddress_MobileCoin) ProtoMessage() {} func (x *PaymentAddress_MobileCoin) ProtoReflect() protoreflect.Message { - mi := &file_SignalService_proto_msgTypes[86] + mi := &file_SignalService_proto_msgTypes[87] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8319,13 +8648,13 @@ var File_SignalService_proto protoreflect.FileDescriptor const file_SignalService_proto_rawDesc = "" + "\n" + - "\x13SignalService.proto\x12\rsignalservice\"\xf5\x06\n" + + "\x13SignalService.proto\x12\rsignalservice\"\x8c\a\n" + "\bEnvelope\x120\n" + "\x04type\x18\x01 \x01(\x0e2\x1c.signalservice.Envelope.TypeR\x04type\x12(\n" + - "\x0fsourceServiceId\x18\v \x01(\tR\x0fsourceServiceId\x12\"\n" + - "\fsourceDevice\x18\a \x01(\rR\fsourceDevice\x122\n" + - "\x14destinationServiceId\x18\r \x01(\tR\x14destinationServiceId\x12\x1c\n" + - "\ttimestamp\x18\x05 \x01(\x04R\ttimestamp\x12\x18\n" + + "\x0fsourceServiceId\x18\v \x01(\tR\x0fsourceServiceId\x12&\n" + + "\x0esourceDeviceId\x18\a \x01(\rR\x0esourceDeviceId\x122\n" + + "\x14destinationServiceId\x18\r \x01(\tR\x14destinationServiceId\x12(\n" + + "\x0fclientTimestamp\x18\x05 \x01(\x04R\x0fclientTimestamp\x12\x18\n" + "\acontent\x18\b \x01(\fR\acontent\x12\x1e\n" + "\n" + "serverGuid\x18\t \x01(\tR\n" + @@ -8342,29 +8671,28 @@ const file_SignalService_proto_rawDesc = "" + "\x15sourceServiceIdBinary\x18\x13 \x01(\fR\x15sourceServiceIdBinary\x12>\n" + "\x1adestinationServiceIdBinary\x18\x14 \x01(\fR\x1adestinationServiceIdBinary\x12*\n" + "\x10serverGuidBinary\x18\x15 \x01(\fR\x10serverGuidBinary\x12*\n" + - "\x10updatedPniBinary\x18\x16 \x01(\fR\x10updatedPniBinary\"\xae\x01\n" + + "\x10updatedPniBinary\x18\x16 \x01(\fR\x10updatedPniBinary\"\xb5\x01\n" + "\x04Type\x12\v\n" + - "\aUNKNOWN\x10\x00\x12\x0e\n" + - "\n" + - "CIPHERTEXT\x10\x01\x12\x11\n" + - "\rPREKEY_BUNDLE\x10\x03\x12\x1b\n" + + "\aUNKNOWN\x10\x00\x12\x12\n" + + "\x0eDOUBLE_RATCHET\x10\x01\x12\x12\n" + + "\x0ePREKEY_MESSAGE\x10\x03\x12\x1b\n" + "\x17SERVER_DELIVERY_RECEIPT\x10\x05\x12\x17\n" + "\x13UNIDENTIFIED_SENDER\x10\x06\x12\x15\n" + - "\x11SENDERKEY_MESSAGE\x10\a\x12\x15\n" + - "\x11PLAINTEXT_CONTENT\x10\b\"\x04\b\x02\x10\x02*\fKEY_EXCHANGEJ\x04\b\x02\x10\x03J\x04\b\x03\x10\x04J\x04\b\x06\x10\aJ\x04\b\x12\x10\x13\"\xdd\x05\n" + - "\aContent\x12<\n" + - "\vdataMessage\x18\x01 \x01(\v2\x1a.signalservice.DataMessageR\vdataMessage\x12<\n" + - "\vsyncMessage\x18\x02 \x01(\v2\x1a.signalservice.SyncMessageR\vsyncMessage\x12<\n" + - "\vcallMessage\x18\x03 \x01(\v2\x1a.signalservice.CallMessageR\vcallMessage\x12<\n" + - "\vnullMessage\x18\x04 \x01(\v2\x1a.signalservice.NullMessageR\vnullMessage\x12E\n" + - "\x0ereceiptMessage\x18\x05 \x01(\v2\x1d.signalservice.ReceiptMessageR\x0ereceiptMessage\x12B\n" + - "\rtypingMessage\x18\x06 \x01(\v2\x1c.signalservice.TypingMessageR\rtypingMessage\x12B\n" + - "\x1csenderKeyDistributionMessage\x18\a \x01(\fR\x1csenderKeyDistributionMessage\x126\n" + - "\x16decryptionErrorMessage\x18\b \x01(\fR\x16decryptionErrorMessage\x12?\n" + - "\fstoryMessage\x18\t \x01(\v2\x1b.signalservice.StoryMessageR\fstoryMessage\x12T\n" + + "\x11PLAINTEXT_CONTENT\x10\b\"\x04\b\x02\x10\x02\"\x04\b\a\x10\a*\fKEY_EXCHANGE*\x11SENDERKEY_MESSAGEJ\x04\b\x02\x10\x03J\x04\b\x03\x10\x04J\x04\b\x06\x10\aJ\x04\b\x12\x10\x13\"\xfa\x05\n" + + "\aContent\x12>\n" + + "\vdataMessage\x18\x01 \x01(\v2\x1a.signalservice.DataMessageH\x00R\vdataMessage\x12>\n" + + "\vsyncMessage\x18\x02 \x01(\v2\x1a.signalservice.SyncMessageH\x00R\vsyncMessage\x12>\n" + + "\vcallMessage\x18\x03 \x01(\v2\x1a.signalservice.CallMessageH\x00R\vcallMessage\x12>\n" + + "\vnullMessage\x18\x04 \x01(\v2\x1a.signalservice.NullMessageH\x00R\vnullMessage\x12G\n" + + "\x0ereceiptMessage\x18\x05 \x01(\v2\x1d.signalservice.ReceiptMessageH\x00R\x0ereceiptMessage\x12D\n" + + "\rtypingMessage\x18\x06 \x01(\v2\x1c.signalservice.TypingMessageH\x00R\rtypingMessage\x128\n" + + "\x16decryptionErrorMessage\x18\b \x01(\fH\x00R\x16decryptionErrorMessage\x12A\n" + + "\fstoryMessage\x18\t \x01(\v2\x1b.signalservice.StoryMessageH\x00R\fstoryMessage\x12>\n" + + "\veditMessage\x18\v \x01(\v2\x1a.signalservice.EditMessageH\x00R\veditMessage\x12B\n" + + "\x1csenderKeyDistributionMessage\x18\a \x01(\fR\x1csenderKeyDistributionMessage\x12T\n" + "\x13pniSignatureMessage\x18\n" + - " \x01(\v2\".signalservice.PniSignatureMessageR\x13pniSignatureMessage\x12<\n" + - "\veditMessage\x18\v \x01(\v2\x1a.signalservice.EditMessageR\veditMessage\"\xf2\b\n" + + " \x01(\v2\".signalservice.PniSignatureMessageR\x13pniSignatureMessageB\t\n" + + "\acontent\"\xf2\b\n" + "\vCallMessage\x126\n" + "\x05offer\x18\x01 \x01(\v2 .signalservice.CallMessage.OfferR\x05offer\x129\n" + "\x06answer\x18\x02 \x01(\v2!.signalservice.CallMessage.AnswerR\x06answer\x12B\n" + @@ -8404,7 +8732,7 @@ const file_SignalService_proto_rawDesc = "" + "\aurgency\x18\x02 \x01(\x0e2).signalservice.CallMessage.Opaque.UrgencyR\aurgency\"0\n" + "\aUrgency\x12\r\n" + "\tDROPPABLE\x10\x00\x12\x16\n" + - "\x12HANDLE_IMMEDIATELY\x10\x01J\x04\b\x04\x10\x05J\x04\b\x06\x10\aJ\x04\b\b\x10\t\"\xca,\n" + + "\x12HANDLE_IMMEDIATELY\x10\x01J\x04\b\x04\x10\x05J\x04\b\x06\x10\aJ\x04\b\b\x10\t\"\x8b.\n" + "\vDataMessage\x12\x12\n" + "\x04body\x18\x01 \x01(\tR\x04body\x12B\n" + "\vattachments\x18\x02 \x03(\v2 .signalservice.AttachmentPointerR\vattachments\x127\n" + @@ -8442,7 +8770,8 @@ const file_SignalService_proto_rawDesc = "" + "\n" + "pinMessage\x18\x1b \x01(\v2%.signalservice.DataMessage.PinMessageR\n" + "pinMessage\x12K\n" + - "\funpinMessage\x18\x1c \x01(\v2'.signalservice.DataMessage.UnpinMessageR\funpinMessage\x1a\x9a\x05\n" + + "\funpinMessage\x18\x1c \x01(\v2'.signalservice.DataMessage.UnpinMessageR\funpinMessage\x12H\n" + + "\vadminDelete\x18\x1d \x01(\v2&.signalservice.DataMessage.AdminDeleteR\vadminDelete\x1a\x9a\x05\n" + "\aPayment\x12U\n" + "\fnotification\x18\x01 \x01(\v2/.signalservice.DataMessage.Payment.NotificationH\x00R\fnotification\x12O\n" + "\n" + @@ -8594,6 +8923,9 @@ const file_SignalService_proto_rawDesc = "" + "\vpinDuration\x1av\n" + "\fUnpinMessage\x124\n" + "\x15targetAuthorAciBinary\x18\x01 \x01(\fR\x15targetAuthorAciBinary\x120\n" + + "\x13targetSentTimestamp\x18\x02 \x01(\x04R\x13targetSentTimestamp\x1au\n" + + "\vAdminDelete\x124\n" + + "\x15targetAuthorAciBinary\x18\x01 \x01(\fR\x15targetAuthorAciBinary\x120\n" + "\x13targetSentTimestamp\x18\x02 \x01(\x04R\x13targetSentTimestamp\"Z\n" + "\x05Flags\x12\x0f\n" + "\vEND_SESSION\x10\x01\x12\x1b\n" + @@ -8683,32 +9015,32 @@ const file_SignalService_proto_rawDesc = "" + "\aDEFAULT\x10\x00\x12\f\n" + "\bVERIFIED\x10\x01\x12\x0e\n" + "\n" + - "UNVERIFIED\x10\x02J\x04\b\x01\x10\x02\"\x8fG\n" + - "\vSyncMessage\x123\n" + - "\x04sent\x18\x01 \x01(\v2\x1f.signalservice.SyncMessage.SentR\x04sent\x12?\n" + - "\bcontacts\x18\x02 \x01(\v2#.signalservice.SyncMessage.ContactsR\bcontacts\x12<\n" + - "\arequest\x18\x04 \x01(\v2\".signalservice.SyncMessage.RequestR\arequest\x123\n" + - "\x04read\x18\x05 \x03(\v2\x1f.signalservice.SyncMessage.ReadR\x04read\x12<\n" + - "\ablocked\x18\x06 \x01(\v2\".signalservice.SyncMessage.BlockedR\ablocked\x123\n" + - "\bverified\x18\a \x01(\v2\x17.signalservice.VerifiedR\bverified\x12N\n" + - "\rconfiguration\x18\t \x01(\v2(.signalservice.SyncMessage.ConfigurationR\rconfiguration\x12\x18\n" + - "\apadding\x18\b \x01(\fR\apadding\x12c\n" + + "UNVERIFIED\x10\x02J\x04\b\x01\x10\x02\"\xf1F\n" + + "\vSyncMessage\x125\n" + + "\x04sent\x18\x01 \x01(\v2\x1f.signalservice.SyncMessage.SentH\x00R\x04sent\x12A\n" + + "\bcontacts\x18\x02 \x01(\v2#.signalservice.SyncMessage.ContactsH\x00R\bcontacts\x12>\n" + + "\arequest\x18\x04 \x01(\v2\".signalservice.SyncMessage.RequestH\x00R\arequest\x12>\n" + + "\ablocked\x18\x06 \x01(\v2\".signalservice.SyncMessage.BlockedH\x00R\ablocked\x125\n" + + "\bverified\x18\a \x01(\v2\x17.signalservice.VerifiedH\x00R\bverified\x12P\n" + + "\rconfiguration\x18\t \x01(\v2(.signalservice.SyncMessage.ConfigurationH\x00R\rconfiguration\x12M\n" + + "\fviewOnceOpen\x18\v \x01(\v2'.signalservice.SyncMessage.ViewOnceOpenH\x00R\fviewOnceOpen\x12J\n" + + "\vfetchLatest\x18\f \x01(\v2&.signalservice.SyncMessage.FetchLatestH\x00R\vfetchLatest\x125\n" + + "\x04keys\x18\r \x01(\v2\x1f.signalservice.SyncMessage.KeysH\x00R\x04keys\x12k\n" + + "\x16messageRequestResponse\x18\x0e \x01(\v21.signalservice.SyncMessage.MessageRequestResponseH\x00R\x16messageRequestResponse\x12V\n" + + "\x0foutgoingPayment\x18\x0f \x01(\v2*.signalservice.SyncMessage.OutgoingPaymentH\x00R\x0foutgoingPayment\x12V\n" + + "\x0fpniChangeNumber\x18\x12 \x01(\v2*.signalservice.SyncMessage.PniChangeNumberH\x00R\x0fpniChangeNumber\x12D\n" + + "\tcallEvent\x18\x13 \x01(\v2$.signalservice.SyncMessage.CallEventH\x00R\tcallEvent\x12S\n" + + "\x0ecallLinkUpdate\x18\x14 \x01(\v2).signalservice.SyncMessage.CallLinkUpdateH\x00R\x0ecallLinkUpdate\x12M\n" + + "\fcallLogEvent\x18\x15 \x01(\v2'.signalservice.SyncMessage.CallLogEventH\x00R\fcallLogEvent\x12J\n" + + "\vdeleteForMe\x18\x16 \x01(\v2&.signalservice.SyncMessage.DeleteForMeH\x00R\vdeleteForMe\x12Y\n" + + "\x10deviceNameChange\x18\x17 \x01(\v2+.signalservice.SyncMessage.DeviceNameChangeH\x00R\x10deviceNameChange\x12t\n" + + "\x19attachmentBackfillRequest\x18\x18 \x01(\v24.signalservice.SyncMessage.AttachmentBackfillRequestH\x00R\x19attachmentBackfillRequest\x12w\n" + + "\x1aattachmentBackfillResponse\x18\x19 \x01(\v25.signalservice.SyncMessage.AttachmentBackfillResponseH\x00R\x1aattachmentBackfillResponse\x123\n" + + "\x04read\x18\x05 \x03(\v2\x1f.signalservice.SyncMessage.ReadR\x04read\x12c\n" + "\x14stickerPackOperation\x18\n" + - " \x03(\v2/.signalservice.SyncMessage.StickerPackOperationR\x14stickerPackOperation\x12K\n" + - "\fviewOnceOpen\x18\v \x01(\v2'.signalservice.SyncMessage.ViewOnceOpenR\fviewOnceOpen\x12H\n" + - "\vfetchLatest\x18\f \x01(\v2&.signalservice.SyncMessage.FetchLatestR\vfetchLatest\x123\n" + - "\x04keys\x18\r \x01(\v2\x1f.signalservice.SyncMessage.KeysR\x04keys\x12i\n" + - "\x16messageRequestResponse\x18\x0e \x01(\v21.signalservice.SyncMessage.MessageRequestResponseR\x16messageRequestResponse\x12T\n" + - "\x0foutgoingPayment\x18\x0f \x01(\v2*.signalservice.SyncMessage.OutgoingPaymentR\x0foutgoingPayment\x129\n" + - "\x06viewed\x18\x10 \x03(\v2!.signalservice.SyncMessage.ViewedR\x06viewed\x12T\n" + - "\x0fpniChangeNumber\x18\x12 \x01(\v2*.signalservice.SyncMessage.PniChangeNumberR\x0fpniChangeNumber\x12B\n" + - "\tcallEvent\x18\x13 \x01(\v2$.signalservice.SyncMessage.CallEventR\tcallEvent\x12Q\n" + - "\x0ecallLinkUpdate\x18\x14 \x01(\v2).signalservice.SyncMessage.CallLinkUpdateR\x0ecallLinkUpdate\x12K\n" + - "\fcallLogEvent\x18\x15 \x01(\v2'.signalservice.SyncMessage.CallLogEventR\fcallLogEvent\x12H\n" + - "\vdeleteForMe\x18\x16 \x01(\v2&.signalservice.SyncMessage.DeleteForMeR\vdeleteForMe\x12W\n" + - "\x10deviceNameChange\x18\x17 \x01(\v2+.signalservice.SyncMessage.DeviceNameChangeR\x10deviceNameChange\x12r\n" + - "\x19attachmentBackfillRequest\x18\x18 \x01(\v24.signalservice.SyncMessage.AttachmentBackfillRequestR\x19attachmentBackfillRequest\x12u\n" + - "\x1aattachmentBackfillResponse\x18\x19 \x01(\v25.signalservice.SyncMessage.AttachmentBackfillResponseR\x1aattachmentBackfillResponse\x1a\xbc\t\n" + + " \x03(\v2/.signalservice.SyncMessage.StickerPackOperationR\x14stickerPackOperation\x129\n" + + "\x06viewed\x18\x10 \x03(\v2!.signalservice.SyncMessage.ViewedR\x06viewed\x12\x18\n" + + "\apadding\x18\b \x01(\fR\apadding\x1a\xbc\t\n" + "\x04Sent\x12(\n" + "\x0fdestinationE164\x18\x01 \x01(\tR\x0fdestinationE164\x122\n" + "\x14destinationServiceId\x18\a \x01(\tR\x14destinationServiceId\x12\x1c\n" + @@ -8757,13 +9089,12 @@ const file_SignalService_proto_rawDesc = "" + "\x06Viewed\x12\x1c\n" + "\tsenderAci\x18\x03 \x01(\tR\tsenderAci\x12\x1c\n" + "\ttimestamp\x18\x02 \x01(\x04R\ttimestamp\x12(\n" + - "\x0fsenderAciBinary\x18\x04 \x01(\fR\x0fsenderAciBinaryJ\x04\b\x01\x10\x02\x1a\x83\x02\n" + + "\x0fsenderAciBinary\x18\x04 \x01(\fR\x0fsenderAciBinaryJ\x04\b\x01\x10\x02\x1a\xd7\x01\n" + "\rConfiguration\x12\"\n" + "\freadReceipts\x18\x01 \x01(\bR\freadReceipts\x12F\n" + "\x1eunidentifiedDeliveryIndicators\x18\x02 \x01(\bR\x1eunidentifiedDeliveryIndicators\x12*\n" + - "\x10typingIndicators\x18\x03 \x01(\bR\x10typingIndicators\x120\n" + - "\x13provisioningVersion\x18\x05 \x01(\rR\x13provisioningVersion\x12\"\n" + - "\flinkPreviews\x18\x06 \x01(\bR\flinkPreviewsJ\x04\b\x04\x10\x05\x1a\xb3\x01\n" + + "\x10typingIndicators\x18\x03 \x01(\bR\x10typingIndicators\x12\"\n" + + "\flinkPreviews\x18\x06 \x01(\bR\flinkPreviewsJ\x04\b\x04\x10\x05J\x04\b\x05\x10\x06\x1a\xb3\x01\n" + "\x14StickerPackOperation\x12\x16\n" + "\x06packId\x18\x01 \x01(\fR\x06packId\x12\x18\n" + "\apackKey\x18\x02 \x01(\fR\apackKey\x12H\n" + @@ -8782,11 +9113,10 @@ const file_SignalService_proto_rawDesc = "" + "\aUNKNOWN\x10\x00\x12\x11\n" + "\rLOCAL_PROFILE\x10\x01\x12\x14\n" + "\x10STORAGE_MANIFEST\x10\x02\x12\x17\n" + - "\x13SUBSCRIPTION_STATUS\x10\x03\x1a\x84\x01\n" + - "\x04Keys\x12\x16\n" + - "\x06master\x18\x02 \x01(\fR\x06master\x12.\n" + + "\x13SUBSCRIPTION_STATUS\x10\x03\x1ar\n" + + "\x04Keys\x12.\n" + "\x12accountEntropyPool\x18\x03 \x01(\tR\x12accountEntropyPool\x12.\n" + - "\x12mediaRootBackupKey\x18\x04 \x01(\fR\x12mediaRootBackupKeyJ\x04\b\x01\x10\x02\x1aK\n" + + "\x12mediaRootBackupKey\x18\x04 \x01(\fR\x12mediaRootBackupKeyJ\x04\b\x01\x10\x02J\x04\b\x02\x10\x03\x1aK\n" + "\vPniIdentity\x12\x1c\n" + "\tpublicKey\x18\x01 \x01(\fR\tpublicKey\x12\x1e\n" + "\n" + @@ -8858,15 +9188,14 @@ const file_SignalService_proto_rawDesc = "" + "\fNOT_ACCEPTED\x10\x02\x12\n" + "\n" + "\x06DELETE\x10\x03\x12\f\n" + - "\bOBSERVED\x10\x04\x1a\xc2\x01\n" + + "\bOBSERVED\x10\x04\x1a\xb2\x01\n" + "\x0eCallLinkUpdate\x12\x18\n" + "\arootKey\x18\x01 \x01(\fR\arootKey\x12\"\n" + "\fadminPasskey\x18\x02 \x01(\fR\fadminPasskey\x12B\n" + - "\x04type\x18\x03 \x01(\x0e2..signalservice.SyncMessage.CallLinkUpdate.TypeR\x04type\x12\x14\n" + - "\x05epoch\x18\x04 \x01(\fR\x05epoch\"\x18\n" + + "\x04type\x18\x03 \x01(\x0e2..signalservice.SyncMessage.CallLinkUpdate.TypeR\x04type\"\x18\n" + "\x04Type\x12\n" + "\n" + - "\x06UPDATE\x10\x00\"\x04\b\x01\x10\x01\x1a\x94\x02\n" + + "\x06UPDATE\x10\x00\"\x04\b\x01\x10\x01J\x04\b\x04\x10\x05\x1a\x94\x02\n" + "\fCallLogEvent\x12@\n" + "\x04type\x18\x01 \x01(\x0e2,.signalservice.SyncMessage.CallLogEvent.TypeR\x04type\x12\x1c\n" + "\ttimestamp\x18\x02 \x01(\x04R\ttimestamp\x12&\n" + @@ -8925,7 +9254,8 @@ const file_SignalService_proto_rawDesc = "" + "\blongText\x18\x02 \x01(\v2D.signalservice.SyncMessage.AttachmentBackfillResponse.AttachmentDataR\blongText\"\x1e\n" + "\x05Error\x12\x15\n" + "\x11MESSAGE_NOT_FOUND\x10\x00B\x06\n" + - "\x04dataJ\x04\b\x03\x10\x04J\x04\b\x11\x10\x12\"\xe7\x04\n" + + "\x04dataB\t\n" + + "\acontentJ\x04\b\x03\x10\x04J\x04\b\x11\x10\x12\"\xe7\x04\n" + "\x11AttachmentPointer\x12\x16\n" + "\x05cdnId\x18\x01 \x01(\x06H\x00R\x05cdnId\x12\x18\n" + "\x06cdnKey\x18\x0f \x01(\tH\x00R\x06cdnKey\x12\x1e\n" + @@ -9041,7 +9371,7 @@ func file_SignalService_proto_rawDescGZIP() []byte { } var file_SignalService_proto_enumTypes = make([]protoimpl.EnumInfo, 28) -var file_SignalService_proto_msgTypes = make([]protoimpl.MessageInfo, 87) +var file_SignalService_proto_msgTypes = make([]protoimpl.MessageInfo, 88) var file_SignalService_proto_goTypes = []any{ (Envelope_Type)(0), // 0: signalservice.Envelope.Type (CallMessage_Offer_Type)(0), // 1: signalservice.CallMessage.Offer.Type @@ -9113,51 +9443,52 @@ var file_SignalService_proto_goTypes = []any{ (*DataMessage_PollVote)(nil), // 67: signalservice.DataMessage.PollVote (*DataMessage_PinMessage)(nil), // 68: signalservice.DataMessage.PinMessage (*DataMessage_UnpinMessage)(nil), // 69: signalservice.DataMessage.UnpinMessage - (*DataMessage_Payment_Amount)(nil), // 70: signalservice.DataMessage.Payment.Amount - (*DataMessage_Payment_Notification)(nil), // 71: signalservice.DataMessage.Payment.Notification - (*DataMessage_Payment_Activation)(nil), // 72: signalservice.DataMessage.Payment.Activation - (*DataMessage_Payment_Amount_MobileCoin)(nil), // 73: signalservice.DataMessage.Payment.Amount.MobileCoin - (*DataMessage_Payment_Notification_MobileCoin)(nil), // 74: signalservice.DataMessage.Payment.Notification.MobileCoin - (*DataMessage_Quote_QuotedAttachment)(nil), // 75: signalservice.DataMessage.Quote.QuotedAttachment - (*DataMessage_Contact_Name)(nil), // 76: signalservice.DataMessage.Contact.Name - (*DataMessage_Contact_Phone)(nil), // 77: signalservice.DataMessage.Contact.Phone - (*DataMessage_Contact_Email)(nil), // 78: signalservice.DataMessage.Contact.Email - (*DataMessage_Contact_PostalAddress)(nil), // 79: signalservice.DataMessage.Contact.PostalAddress - (*DataMessage_Contact_Avatar)(nil), // 80: signalservice.DataMessage.Contact.Avatar - (*TextAttachment_Gradient)(nil), // 81: signalservice.TextAttachment.Gradient - (*SyncMessage_Sent)(nil), // 82: signalservice.SyncMessage.Sent - (*SyncMessage_Contacts)(nil), // 83: signalservice.SyncMessage.Contacts - (*SyncMessage_Blocked)(nil), // 84: signalservice.SyncMessage.Blocked - (*SyncMessage_Request)(nil), // 85: signalservice.SyncMessage.Request - (*SyncMessage_Read)(nil), // 86: signalservice.SyncMessage.Read - (*SyncMessage_Viewed)(nil), // 87: signalservice.SyncMessage.Viewed - (*SyncMessage_Configuration)(nil), // 88: signalservice.SyncMessage.Configuration - (*SyncMessage_StickerPackOperation)(nil), // 89: signalservice.SyncMessage.StickerPackOperation - (*SyncMessage_ViewOnceOpen)(nil), // 90: signalservice.SyncMessage.ViewOnceOpen - (*SyncMessage_FetchLatest)(nil), // 91: signalservice.SyncMessage.FetchLatest - (*SyncMessage_Keys)(nil), // 92: signalservice.SyncMessage.Keys - (*SyncMessage_PniIdentity)(nil), // 93: signalservice.SyncMessage.PniIdentity - (*SyncMessage_MessageRequestResponse)(nil), // 94: signalservice.SyncMessage.MessageRequestResponse - (*SyncMessage_OutgoingPayment)(nil), // 95: signalservice.SyncMessage.OutgoingPayment - (*SyncMessage_PniChangeNumber)(nil), // 96: signalservice.SyncMessage.PniChangeNumber - (*SyncMessage_CallEvent)(nil), // 97: signalservice.SyncMessage.CallEvent - (*SyncMessage_CallLinkUpdate)(nil), // 98: signalservice.SyncMessage.CallLinkUpdate - (*SyncMessage_CallLogEvent)(nil), // 99: signalservice.SyncMessage.CallLogEvent - (*SyncMessage_DeleteForMe)(nil), // 100: signalservice.SyncMessage.DeleteForMe - (*SyncMessage_DeviceNameChange)(nil), // 101: signalservice.SyncMessage.DeviceNameChange - (*SyncMessage_AttachmentBackfillRequest)(nil), // 102: signalservice.SyncMessage.AttachmentBackfillRequest - (*SyncMessage_AttachmentBackfillResponse)(nil), // 103: signalservice.SyncMessage.AttachmentBackfillResponse - (*SyncMessage_Sent_UnidentifiedDeliveryStatus)(nil), // 104: signalservice.SyncMessage.Sent.UnidentifiedDeliveryStatus - (*SyncMessage_Sent_StoryMessageRecipient)(nil), // 105: signalservice.SyncMessage.Sent.StoryMessageRecipient - (*SyncMessage_OutgoingPayment_MobileCoin)(nil), // 106: signalservice.SyncMessage.OutgoingPayment.MobileCoin - (*SyncMessage_DeleteForMe_MessageDeletes)(nil), // 107: signalservice.SyncMessage.DeleteForMe.MessageDeletes - (*SyncMessage_DeleteForMe_AttachmentDelete)(nil), // 108: signalservice.SyncMessage.DeleteForMe.AttachmentDelete - (*SyncMessage_DeleteForMe_ConversationDelete)(nil), // 109: signalservice.SyncMessage.DeleteForMe.ConversationDelete - (*SyncMessage_DeleteForMe_LocalOnlyConversationDelete)(nil), // 110: signalservice.SyncMessage.DeleteForMe.LocalOnlyConversationDelete - (*SyncMessage_AttachmentBackfillResponse_AttachmentData)(nil), // 111: signalservice.SyncMessage.AttachmentBackfillResponse.AttachmentData - (*SyncMessage_AttachmentBackfillResponse_AttachmentDataList)(nil), // 112: signalservice.SyncMessage.AttachmentBackfillResponse.AttachmentDataList - (*ContactDetails_Avatar)(nil), // 113: signalservice.ContactDetails.Avatar - (*PaymentAddress_MobileCoin)(nil), // 114: signalservice.PaymentAddress.MobileCoin + (*DataMessage_AdminDelete)(nil), // 70: signalservice.DataMessage.AdminDelete + (*DataMessage_Payment_Amount)(nil), // 71: signalservice.DataMessage.Payment.Amount + (*DataMessage_Payment_Notification)(nil), // 72: signalservice.DataMessage.Payment.Notification + (*DataMessage_Payment_Activation)(nil), // 73: signalservice.DataMessage.Payment.Activation + (*DataMessage_Payment_Amount_MobileCoin)(nil), // 74: signalservice.DataMessage.Payment.Amount.MobileCoin + (*DataMessage_Payment_Notification_MobileCoin)(nil), // 75: signalservice.DataMessage.Payment.Notification.MobileCoin + (*DataMessage_Quote_QuotedAttachment)(nil), // 76: signalservice.DataMessage.Quote.QuotedAttachment + (*DataMessage_Contact_Name)(nil), // 77: signalservice.DataMessage.Contact.Name + (*DataMessage_Contact_Phone)(nil), // 78: signalservice.DataMessage.Contact.Phone + (*DataMessage_Contact_Email)(nil), // 79: signalservice.DataMessage.Contact.Email + (*DataMessage_Contact_PostalAddress)(nil), // 80: signalservice.DataMessage.Contact.PostalAddress + (*DataMessage_Contact_Avatar)(nil), // 81: signalservice.DataMessage.Contact.Avatar + (*TextAttachment_Gradient)(nil), // 82: signalservice.TextAttachment.Gradient + (*SyncMessage_Sent)(nil), // 83: signalservice.SyncMessage.Sent + (*SyncMessage_Contacts)(nil), // 84: signalservice.SyncMessage.Contacts + (*SyncMessage_Blocked)(nil), // 85: signalservice.SyncMessage.Blocked + (*SyncMessage_Request)(nil), // 86: signalservice.SyncMessage.Request + (*SyncMessage_Read)(nil), // 87: signalservice.SyncMessage.Read + (*SyncMessage_Viewed)(nil), // 88: signalservice.SyncMessage.Viewed + (*SyncMessage_Configuration)(nil), // 89: signalservice.SyncMessage.Configuration + (*SyncMessage_StickerPackOperation)(nil), // 90: signalservice.SyncMessage.StickerPackOperation + (*SyncMessage_ViewOnceOpen)(nil), // 91: signalservice.SyncMessage.ViewOnceOpen + (*SyncMessage_FetchLatest)(nil), // 92: signalservice.SyncMessage.FetchLatest + (*SyncMessage_Keys)(nil), // 93: signalservice.SyncMessage.Keys + (*SyncMessage_PniIdentity)(nil), // 94: signalservice.SyncMessage.PniIdentity + (*SyncMessage_MessageRequestResponse)(nil), // 95: signalservice.SyncMessage.MessageRequestResponse + (*SyncMessage_OutgoingPayment)(nil), // 96: signalservice.SyncMessage.OutgoingPayment + (*SyncMessage_PniChangeNumber)(nil), // 97: signalservice.SyncMessage.PniChangeNumber + (*SyncMessage_CallEvent)(nil), // 98: signalservice.SyncMessage.CallEvent + (*SyncMessage_CallLinkUpdate)(nil), // 99: signalservice.SyncMessage.CallLinkUpdate + (*SyncMessage_CallLogEvent)(nil), // 100: signalservice.SyncMessage.CallLogEvent + (*SyncMessage_DeleteForMe)(nil), // 101: signalservice.SyncMessage.DeleteForMe + (*SyncMessage_DeviceNameChange)(nil), // 102: signalservice.SyncMessage.DeviceNameChange + (*SyncMessage_AttachmentBackfillRequest)(nil), // 103: signalservice.SyncMessage.AttachmentBackfillRequest + (*SyncMessage_AttachmentBackfillResponse)(nil), // 104: signalservice.SyncMessage.AttachmentBackfillResponse + (*SyncMessage_Sent_UnidentifiedDeliveryStatus)(nil), // 105: signalservice.SyncMessage.Sent.UnidentifiedDeliveryStatus + (*SyncMessage_Sent_StoryMessageRecipient)(nil), // 106: signalservice.SyncMessage.Sent.StoryMessageRecipient + (*SyncMessage_OutgoingPayment_MobileCoin)(nil), // 107: signalservice.SyncMessage.OutgoingPayment.MobileCoin + (*SyncMessage_DeleteForMe_MessageDeletes)(nil), // 108: signalservice.SyncMessage.DeleteForMe.MessageDeletes + (*SyncMessage_DeleteForMe_AttachmentDelete)(nil), // 109: signalservice.SyncMessage.DeleteForMe.AttachmentDelete + (*SyncMessage_DeleteForMe_ConversationDelete)(nil), // 110: signalservice.SyncMessage.DeleteForMe.ConversationDelete + (*SyncMessage_DeleteForMe_LocalOnlyConversationDelete)(nil), // 111: signalservice.SyncMessage.DeleteForMe.LocalOnlyConversationDelete + (*SyncMessage_AttachmentBackfillResponse_AttachmentData)(nil), // 112: signalservice.SyncMessage.AttachmentBackfillResponse.AttachmentData + (*SyncMessage_AttachmentBackfillResponse_AttachmentDataList)(nil), // 113: signalservice.SyncMessage.AttachmentBackfillResponse.AttachmentDataList + (*ContactDetails_Avatar)(nil), // 114: signalservice.ContactDetails.Avatar + (*PaymentAddress_MobileCoin)(nil), // 115: signalservice.PaymentAddress.MobileCoin } var file_SignalService_proto_depIdxs = []int32{ 0, // 0: signalservice.Envelope.type:type_name -> signalservice.Envelope.Type @@ -9168,8 +9499,8 @@ var file_SignalService_proto_depIdxs = []int32{ 33, // 5: signalservice.Content.receiptMessage:type_name -> signalservice.ReceiptMessage 34, // 6: signalservice.Content.typingMessage:type_name -> signalservice.TypingMessage 35, // 7: signalservice.Content.storyMessage:type_name -> signalservice.StoryMessage - 45, // 8: signalservice.Content.pniSignatureMessage:type_name -> signalservice.PniSignatureMessage - 46, // 9: signalservice.Content.editMessage:type_name -> signalservice.EditMessage + 46, // 8: signalservice.Content.editMessage:type_name -> signalservice.EditMessage + 45, // 9: signalservice.Content.pniSignatureMessage:type_name -> signalservice.PniSignatureMessage 50, // 10: signalservice.CallMessage.offer:type_name -> signalservice.CallMessage.Offer 51, // 11: signalservice.CallMessage.answer:type_name -> signalservice.CallMessage.Answer 52, // 12: signalservice.CallMessage.iceUpdate:type_name -> signalservice.CallMessage.IceUpdate @@ -9194,108 +9525,109 @@ var file_SignalService_proto_depIdxs = []int32{ 67, // 31: signalservice.DataMessage.pollVote:type_name -> signalservice.DataMessage.PollVote 68, // 32: signalservice.DataMessage.pinMessage:type_name -> signalservice.DataMessage.PinMessage 69, // 33: signalservice.DataMessage.unpinMessage:type_name -> signalservice.DataMessage.UnpinMessage - 11, // 34: signalservice.ReceiptMessage.type:type_name -> signalservice.ReceiptMessage.Type - 12, // 35: signalservice.TypingMessage.action:type_name -> signalservice.TypingMessage.Action - 41, // 36: signalservice.StoryMessage.group:type_name -> signalservice.GroupContextV2 - 40, // 37: signalservice.StoryMessage.fileAttachment:type_name -> signalservice.AttachmentPointer - 37, // 38: signalservice.StoryMessage.textAttachment:type_name -> signalservice.TextAttachment - 47, // 39: signalservice.StoryMessage.bodyRanges:type_name -> signalservice.BodyRange - 40, // 40: signalservice.Preview.image:type_name -> signalservice.AttachmentPointer - 13, // 41: signalservice.TextAttachment.textStyle:type_name -> signalservice.TextAttachment.Style - 36, // 42: signalservice.TextAttachment.preview:type_name -> signalservice.Preview - 81, // 43: signalservice.TextAttachment.gradient:type_name -> signalservice.TextAttachment.Gradient - 14, // 44: signalservice.Verified.state:type_name -> signalservice.Verified.State - 82, // 45: signalservice.SyncMessage.sent:type_name -> signalservice.SyncMessage.Sent - 83, // 46: signalservice.SyncMessage.contacts:type_name -> signalservice.SyncMessage.Contacts - 85, // 47: signalservice.SyncMessage.request:type_name -> signalservice.SyncMessage.Request - 86, // 48: signalservice.SyncMessage.read:type_name -> signalservice.SyncMessage.Read - 84, // 49: signalservice.SyncMessage.blocked:type_name -> signalservice.SyncMessage.Blocked + 70, // 34: signalservice.DataMessage.adminDelete:type_name -> signalservice.DataMessage.AdminDelete + 11, // 35: signalservice.ReceiptMessage.type:type_name -> signalservice.ReceiptMessage.Type + 12, // 36: signalservice.TypingMessage.action:type_name -> signalservice.TypingMessage.Action + 41, // 37: signalservice.StoryMessage.group:type_name -> signalservice.GroupContextV2 + 40, // 38: signalservice.StoryMessage.fileAttachment:type_name -> signalservice.AttachmentPointer + 37, // 39: signalservice.StoryMessage.textAttachment:type_name -> signalservice.TextAttachment + 47, // 40: signalservice.StoryMessage.bodyRanges:type_name -> signalservice.BodyRange + 40, // 41: signalservice.Preview.image:type_name -> signalservice.AttachmentPointer + 13, // 42: signalservice.TextAttachment.textStyle:type_name -> signalservice.TextAttachment.Style + 36, // 43: signalservice.TextAttachment.preview:type_name -> signalservice.Preview + 82, // 44: signalservice.TextAttachment.gradient:type_name -> signalservice.TextAttachment.Gradient + 14, // 45: signalservice.Verified.state:type_name -> signalservice.Verified.State + 83, // 46: signalservice.SyncMessage.sent:type_name -> signalservice.SyncMessage.Sent + 84, // 47: signalservice.SyncMessage.contacts:type_name -> signalservice.SyncMessage.Contacts + 86, // 48: signalservice.SyncMessage.request:type_name -> signalservice.SyncMessage.Request + 85, // 49: signalservice.SyncMessage.blocked:type_name -> signalservice.SyncMessage.Blocked 38, // 50: signalservice.SyncMessage.verified:type_name -> signalservice.Verified - 88, // 51: signalservice.SyncMessage.configuration:type_name -> signalservice.SyncMessage.Configuration - 89, // 52: signalservice.SyncMessage.stickerPackOperation:type_name -> signalservice.SyncMessage.StickerPackOperation - 90, // 53: signalservice.SyncMessage.viewOnceOpen:type_name -> signalservice.SyncMessage.ViewOnceOpen - 91, // 54: signalservice.SyncMessage.fetchLatest:type_name -> signalservice.SyncMessage.FetchLatest - 92, // 55: signalservice.SyncMessage.keys:type_name -> signalservice.SyncMessage.Keys - 94, // 56: signalservice.SyncMessage.messageRequestResponse:type_name -> signalservice.SyncMessage.MessageRequestResponse - 95, // 57: signalservice.SyncMessage.outgoingPayment:type_name -> signalservice.SyncMessage.OutgoingPayment - 87, // 58: signalservice.SyncMessage.viewed:type_name -> signalservice.SyncMessage.Viewed - 96, // 59: signalservice.SyncMessage.pniChangeNumber:type_name -> signalservice.SyncMessage.PniChangeNumber - 97, // 60: signalservice.SyncMessage.callEvent:type_name -> signalservice.SyncMessage.CallEvent - 98, // 61: signalservice.SyncMessage.callLinkUpdate:type_name -> signalservice.SyncMessage.CallLinkUpdate - 99, // 62: signalservice.SyncMessage.callLogEvent:type_name -> signalservice.SyncMessage.CallLogEvent - 100, // 63: signalservice.SyncMessage.deleteForMe:type_name -> signalservice.SyncMessage.DeleteForMe - 101, // 64: signalservice.SyncMessage.deviceNameChange:type_name -> signalservice.SyncMessage.DeviceNameChange - 102, // 65: signalservice.SyncMessage.attachmentBackfillRequest:type_name -> signalservice.SyncMessage.AttachmentBackfillRequest - 103, // 66: signalservice.SyncMessage.attachmentBackfillResponse:type_name -> signalservice.SyncMessage.AttachmentBackfillResponse - 113, // 67: signalservice.ContactDetails.avatar:type_name -> signalservice.ContactDetails.Avatar - 114, // 68: signalservice.PaymentAddress.mobileCoin:type_name -> signalservice.PaymentAddress.MobileCoin - 31, // 69: signalservice.EditMessage.dataMessage:type_name -> signalservice.DataMessage - 27, // 70: signalservice.BodyRange.style:type_name -> signalservice.BodyRange.Style - 1, // 71: signalservice.CallMessage.Offer.type:type_name -> signalservice.CallMessage.Offer.Type - 2, // 72: signalservice.CallMessage.Hangup.type:type_name -> signalservice.CallMessage.Hangup.Type - 3, // 73: signalservice.CallMessage.Opaque.urgency:type_name -> signalservice.CallMessage.Opaque.Urgency - 71, // 74: signalservice.DataMessage.Payment.notification:type_name -> signalservice.DataMessage.Payment.Notification - 72, // 75: signalservice.DataMessage.Payment.activation:type_name -> signalservice.DataMessage.Payment.Activation - 75, // 76: signalservice.DataMessage.Quote.attachments:type_name -> signalservice.DataMessage.Quote.QuotedAttachment - 47, // 77: signalservice.DataMessage.Quote.bodyRanges:type_name -> signalservice.BodyRange - 7, // 78: signalservice.DataMessage.Quote.type:type_name -> signalservice.DataMessage.Quote.Type - 76, // 79: signalservice.DataMessage.Contact.name:type_name -> signalservice.DataMessage.Contact.Name - 77, // 80: signalservice.DataMessage.Contact.number:type_name -> signalservice.DataMessage.Contact.Phone - 78, // 81: signalservice.DataMessage.Contact.email:type_name -> signalservice.DataMessage.Contact.Email - 79, // 82: signalservice.DataMessage.Contact.address:type_name -> signalservice.DataMessage.Contact.PostalAddress - 80, // 83: signalservice.DataMessage.Contact.avatar:type_name -> signalservice.DataMessage.Contact.Avatar - 40, // 84: signalservice.DataMessage.Sticker.data:type_name -> signalservice.AttachmentPointer - 73, // 85: signalservice.DataMessage.Payment.Amount.mobileCoin:type_name -> signalservice.DataMessage.Payment.Amount.MobileCoin - 74, // 86: signalservice.DataMessage.Payment.Notification.mobileCoin:type_name -> signalservice.DataMessage.Payment.Notification.MobileCoin - 6, // 87: signalservice.DataMessage.Payment.Activation.type:type_name -> signalservice.DataMessage.Payment.Activation.Type - 40, // 88: signalservice.DataMessage.Quote.QuotedAttachment.thumbnail:type_name -> signalservice.AttachmentPointer - 8, // 89: signalservice.DataMessage.Contact.Phone.type:type_name -> signalservice.DataMessage.Contact.Phone.Type - 9, // 90: signalservice.DataMessage.Contact.Email.type:type_name -> signalservice.DataMessage.Contact.Email.Type - 10, // 91: signalservice.DataMessage.Contact.PostalAddress.type:type_name -> signalservice.DataMessage.Contact.PostalAddress.Type - 40, // 92: signalservice.DataMessage.Contact.Avatar.avatar:type_name -> signalservice.AttachmentPointer - 31, // 93: signalservice.SyncMessage.Sent.message:type_name -> signalservice.DataMessage - 104, // 94: signalservice.SyncMessage.Sent.unidentifiedStatus:type_name -> signalservice.SyncMessage.Sent.UnidentifiedDeliveryStatus - 35, // 95: signalservice.SyncMessage.Sent.storyMessage:type_name -> signalservice.StoryMessage - 105, // 96: signalservice.SyncMessage.Sent.storyMessageRecipients:type_name -> signalservice.SyncMessage.Sent.StoryMessageRecipient - 46, // 97: signalservice.SyncMessage.Sent.editMessage:type_name -> signalservice.EditMessage - 40, // 98: signalservice.SyncMessage.Contacts.blob:type_name -> signalservice.AttachmentPointer - 15, // 99: signalservice.SyncMessage.Request.type:type_name -> signalservice.SyncMessage.Request.Type - 16, // 100: signalservice.SyncMessage.StickerPackOperation.type:type_name -> signalservice.SyncMessage.StickerPackOperation.Type - 17, // 101: signalservice.SyncMessage.FetchLatest.type:type_name -> signalservice.SyncMessage.FetchLatest.Type - 18, // 102: signalservice.SyncMessage.MessageRequestResponse.type:type_name -> signalservice.SyncMessage.MessageRequestResponse.Type - 106, // 103: signalservice.SyncMessage.OutgoingPayment.mobileCoin:type_name -> signalservice.SyncMessage.OutgoingPayment.MobileCoin - 19, // 104: signalservice.SyncMessage.CallEvent.type:type_name -> signalservice.SyncMessage.CallEvent.Type - 20, // 105: signalservice.SyncMessage.CallEvent.direction:type_name -> signalservice.SyncMessage.CallEvent.Direction - 21, // 106: signalservice.SyncMessage.CallEvent.event:type_name -> signalservice.SyncMessage.CallEvent.Event - 22, // 107: signalservice.SyncMessage.CallLinkUpdate.type:type_name -> signalservice.SyncMessage.CallLinkUpdate.Type - 23, // 108: signalservice.SyncMessage.CallLogEvent.type:type_name -> signalservice.SyncMessage.CallLogEvent.Type - 107, // 109: signalservice.SyncMessage.DeleteForMe.messageDeletes:type_name -> signalservice.SyncMessage.DeleteForMe.MessageDeletes - 109, // 110: signalservice.SyncMessage.DeleteForMe.conversationDeletes:type_name -> signalservice.SyncMessage.DeleteForMe.ConversationDelete - 110, // 111: signalservice.SyncMessage.DeleteForMe.localOnlyConversationDeletes:type_name -> signalservice.SyncMessage.DeleteForMe.LocalOnlyConversationDelete - 108, // 112: signalservice.SyncMessage.DeleteForMe.attachmentDeletes:type_name -> signalservice.SyncMessage.DeleteForMe.AttachmentDelete - 48, // 113: signalservice.SyncMessage.AttachmentBackfillRequest.targetMessage:type_name -> signalservice.AddressableMessage - 49, // 114: signalservice.SyncMessage.AttachmentBackfillRequest.targetConversation:type_name -> signalservice.ConversationIdentifier - 48, // 115: signalservice.SyncMessage.AttachmentBackfillResponse.targetMessage:type_name -> signalservice.AddressableMessage - 49, // 116: signalservice.SyncMessage.AttachmentBackfillResponse.targetConversation:type_name -> signalservice.ConversationIdentifier - 112, // 117: signalservice.SyncMessage.AttachmentBackfillResponse.attachments:type_name -> signalservice.SyncMessage.AttachmentBackfillResponse.AttachmentDataList - 24, // 118: signalservice.SyncMessage.AttachmentBackfillResponse.error:type_name -> signalservice.SyncMessage.AttachmentBackfillResponse.Error - 49, // 119: signalservice.SyncMessage.DeleteForMe.MessageDeletes.conversation:type_name -> signalservice.ConversationIdentifier - 48, // 120: signalservice.SyncMessage.DeleteForMe.MessageDeletes.messages:type_name -> signalservice.AddressableMessage - 49, // 121: signalservice.SyncMessage.DeleteForMe.AttachmentDelete.conversation:type_name -> signalservice.ConversationIdentifier - 48, // 122: signalservice.SyncMessage.DeleteForMe.AttachmentDelete.targetMessage:type_name -> signalservice.AddressableMessage - 49, // 123: signalservice.SyncMessage.DeleteForMe.ConversationDelete.conversation:type_name -> signalservice.ConversationIdentifier - 48, // 124: signalservice.SyncMessage.DeleteForMe.ConversationDelete.mostRecentMessages:type_name -> signalservice.AddressableMessage - 48, // 125: signalservice.SyncMessage.DeleteForMe.ConversationDelete.mostRecentNonExpiringMessages:type_name -> signalservice.AddressableMessage - 49, // 126: signalservice.SyncMessage.DeleteForMe.LocalOnlyConversationDelete.conversation:type_name -> signalservice.ConversationIdentifier - 40, // 127: signalservice.SyncMessage.AttachmentBackfillResponse.AttachmentData.attachment:type_name -> signalservice.AttachmentPointer - 25, // 128: signalservice.SyncMessage.AttachmentBackfillResponse.AttachmentData.status:type_name -> signalservice.SyncMessage.AttachmentBackfillResponse.AttachmentData.Status - 111, // 129: signalservice.SyncMessage.AttachmentBackfillResponse.AttachmentDataList.attachments:type_name -> signalservice.SyncMessage.AttachmentBackfillResponse.AttachmentData - 111, // 130: signalservice.SyncMessage.AttachmentBackfillResponse.AttachmentDataList.longText:type_name -> signalservice.SyncMessage.AttachmentBackfillResponse.AttachmentData - 131, // [131:131] is the sub-list for method output_type - 131, // [131:131] is the sub-list for method input_type - 131, // [131:131] is the sub-list for extension type_name - 131, // [131:131] is the sub-list for extension extendee - 0, // [0:131] is the sub-list for field type_name + 89, // 51: signalservice.SyncMessage.configuration:type_name -> signalservice.SyncMessage.Configuration + 91, // 52: signalservice.SyncMessage.viewOnceOpen:type_name -> signalservice.SyncMessage.ViewOnceOpen + 92, // 53: signalservice.SyncMessage.fetchLatest:type_name -> signalservice.SyncMessage.FetchLatest + 93, // 54: signalservice.SyncMessage.keys:type_name -> signalservice.SyncMessage.Keys + 95, // 55: signalservice.SyncMessage.messageRequestResponse:type_name -> signalservice.SyncMessage.MessageRequestResponse + 96, // 56: signalservice.SyncMessage.outgoingPayment:type_name -> signalservice.SyncMessage.OutgoingPayment + 97, // 57: signalservice.SyncMessage.pniChangeNumber:type_name -> signalservice.SyncMessage.PniChangeNumber + 98, // 58: signalservice.SyncMessage.callEvent:type_name -> signalservice.SyncMessage.CallEvent + 99, // 59: signalservice.SyncMessage.callLinkUpdate:type_name -> signalservice.SyncMessage.CallLinkUpdate + 100, // 60: signalservice.SyncMessage.callLogEvent:type_name -> signalservice.SyncMessage.CallLogEvent + 101, // 61: signalservice.SyncMessage.deleteForMe:type_name -> signalservice.SyncMessage.DeleteForMe + 102, // 62: signalservice.SyncMessage.deviceNameChange:type_name -> signalservice.SyncMessage.DeviceNameChange + 103, // 63: signalservice.SyncMessage.attachmentBackfillRequest:type_name -> signalservice.SyncMessage.AttachmentBackfillRequest + 104, // 64: signalservice.SyncMessage.attachmentBackfillResponse:type_name -> signalservice.SyncMessage.AttachmentBackfillResponse + 87, // 65: signalservice.SyncMessage.read:type_name -> signalservice.SyncMessage.Read + 90, // 66: signalservice.SyncMessage.stickerPackOperation:type_name -> signalservice.SyncMessage.StickerPackOperation + 88, // 67: signalservice.SyncMessage.viewed:type_name -> signalservice.SyncMessage.Viewed + 114, // 68: signalservice.ContactDetails.avatar:type_name -> signalservice.ContactDetails.Avatar + 115, // 69: signalservice.PaymentAddress.mobileCoin:type_name -> signalservice.PaymentAddress.MobileCoin + 31, // 70: signalservice.EditMessage.dataMessage:type_name -> signalservice.DataMessage + 27, // 71: signalservice.BodyRange.style:type_name -> signalservice.BodyRange.Style + 1, // 72: signalservice.CallMessage.Offer.type:type_name -> signalservice.CallMessage.Offer.Type + 2, // 73: signalservice.CallMessage.Hangup.type:type_name -> signalservice.CallMessage.Hangup.Type + 3, // 74: signalservice.CallMessage.Opaque.urgency:type_name -> signalservice.CallMessage.Opaque.Urgency + 72, // 75: signalservice.DataMessage.Payment.notification:type_name -> signalservice.DataMessage.Payment.Notification + 73, // 76: signalservice.DataMessage.Payment.activation:type_name -> signalservice.DataMessage.Payment.Activation + 76, // 77: signalservice.DataMessage.Quote.attachments:type_name -> signalservice.DataMessage.Quote.QuotedAttachment + 47, // 78: signalservice.DataMessage.Quote.bodyRanges:type_name -> signalservice.BodyRange + 7, // 79: signalservice.DataMessage.Quote.type:type_name -> signalservice.DataMessage.Quote.Type + 77, // 80: signalservice.DataMessage.Contact.name:type_name -> signalservice.DataMessage.Contact.Name + 78, // 81: signalservice.DataMessage.Contact.number:type_name -> signalservice.DataMessage.Contact.Phone + 79, // 82: signalservice.DataMessage.Contact.email:type_name -> signalservice.DataMessage.Contact.Email + 80, // 83: signalservice.DataMessage.Contact.address:type_name -> signalservice.DataMessage.Contact.PostalAddress + 81, // 84: signalservice.DataMessage.Contact.avatar:type_name -> signalservice.DataMessage.Contact.Avatar + 40, // 85: signalservice.DataMessage.Sticker.data:type_name -> signalservice.AttachmentPointer + 74, // 86: signalservice.DataMessage.Payment.Amount.mobileCoin:type_name -> signalservice.DataMessage.Payment.Amount.MobileCoin + 75, // 87: signalservice.DataMessage.Payment.Notification.mobileCoin:type_name -> signalservice.DataMessage.Payment.Notification.MobileCoin + 6, // 88: signalservice.DataMessage.Payment.Activation.type:type_name -> signalservice.DataMessage.Payment.Activation.Type + 40, // 89: signalservice.DataMessage.Quote.QuotedAttachment.thumbnail:type_name -> signalservice.AttachmentPointer + 8, // 90: signalservice.DataMessage.Contact.Phone.type:type_name -> signalservice.DataMessage.Contact.Phone.Type + 9, // 91: signalservice.DataMessage.Contact.Email.type:type_name -> signalservice.DataMessage.Contact.Email.Type + 10, // 92: signalservice.DataMessage.Contact.PostalAddress.type:type_name -> signalservice.DataMessage.Contact.PostalAddress.Type + 40, // 93: signalservice.DataMessage.Contact.Avatar.avatar:type_name -> signalservice.AttachmentPointer + 31, // 94: signalservice.SyncMessage.Sent.message:type_name -> signalservice.DataMessage + 105, // 95: signalservice.SyncMessage.Sent.unidentifiedStatus:type_name -> signalservice.SyncMessage.Sent.UnidentifiedDeliveryStatus + 35, // 96: signalservice.SyncMessage.Sent.storyMessage:type_name -> signalservice.StoryMessage + 106, // 97: signalservice.SyncMessage.Sent.storyMessageRecipients:type_name -> signalservice.SyncMessage.Sent.StoryMessageRecipient + 46, // 98: signalservice.SyncMessage.Sent.editMessage:type_name -> signalservice.EditMessage + 40, // 99: signalservice.SyncMessage.Contacts.blob:type_name -> signalservice.AttachmentPointer + 15, // 100: signalservice.SyncMessage.Request.type:type_name -> signalservice.SyncMessage.Request.Type + 16, // 101: signalservice.SyncMessage.StickerPackOperation.type:type_name -> signalservice.SyncMessage.StickerPackOperation.Type + 17, // 102: signalservice.SyncMessage.FetchLatest.type:type_name -> signalservice.SyncMessage.FetchLatest.Type + 18, // 103: signalservice.SyncMessage.MessageRequestResponse.type:type_name -> signalservice.SyncMessage.MessageRequestResponse.Type + 107, // 104: signalservice.SyncMessage.OutgoingPayment.mobileCoin:type_name -> signalservice.SyncMessage.OutgoingPayment.MobileCoin + 19, // 105: signalservice.SyncMessage.CallEvent.type:type_name -> signalservice.SyncMessage.CallEvent.Type + 20, // 106: signalservice.SyncMessage.CallEvent.direction:type_name -> signalservice.SyncMessage.CallEvent.Direction + 21, // 107: signalservice.SyncMessage.CallEvent.event:type_name -> signalservice.SyncMessage.CallEvent.Event + 22, // 108: signalservice.SyncMessage.CallLinkUpdate.type:type_name -> signalservice.SyncMessage.CallLinkUpdate.Type + 23, // 109: signalservice.SyncMessage.CallLogEvent.type:type_name -> signalservice.SyncMessage.CallLogEvent.Type + 108, // 110: signalservice.SyncMessage.DeleteForMe.messageDeletes:type_name -> signalservice.SyncMessage.DeleteForMe.MessageDeletes + 110, // 111: signalservice.SyncMessage.DeleteForMe.conversationDeletes:type_name -> signalservice.SyncMessage.DeleteForMe.ConversationDelete + 111, // 112: signalservice.SyncMessage.DeleteForMe.localOnlyConversationDeletes:type_name -> signalservice.SyncMessage.DeleteForMe.LocalOnlyConversationDelete + 109, // 113: signalservice.SyncMessage.DeleteForMe.attachmentDeletes:type_name -> signalservice.SyncMessage.DeleteForMe.AttachmentDelete + 48, // 114: signalservice.SyncMessage.AttachmentBackfillRequest.targetMessage:type_name -> signalservice.AddressableMessage + 49, // 115: signalservice.SyncMessage.AttachmentBackfillRequest.targetConversation:type_name -> signalservice.ConversationIdentifier + 48, // 116: signalservice.SyncMessage.AttachmentBackfillResponse.targetMessage:type_name -> signalservice.AddressableMessage + 49, // 117: signalservice.SyncMessage.AttachmentBackfillResponse.targetConversation:type_name -> signalservice.ConversationIdentifier + 113, // 118: signalservice.SyncMessage.AttachmentBackfillResponse.attachments:type_name -> signalservice.SyncMessage.AttachmentBackfillResponse.AttachmentDataList + 24, // 119: signalservice.SyncMessage.AttachmentBackfillResponse.error:type_name -> signalservice.SyncMessage.AttachmentBackfillResponse.Error + 49, // 120: signalservice.SyncMessage.DeleteForMe.MessageDeletes.conversation:type_name -> signalservice.ConversationIdentifier + 48, // 121: signalservice.SyncMessage.DeleteForMe.MessageDeletes.messages:type_name -> signalservice.AddressableMessage + 49, // 122: signalservice.SyncMessage.DeleteForMe.AttachmentDelete.conversation:type_name -> signalservice.ConversationIdentifier + 48, // 123: signalservice.SyncMessage.DeleteForMe.AttachmentDelete.targetMessage:type_name -> signalservice.AddressableMessage + 49, // 124: signalservice.SyncMessage.DeleteForMe.ConversationDelete.conversation:type_name -> signalservice.ConversationIdentifier + 48, // 125: signalservice.SyncMessage.DeleteForMe.ConversationDelete.mostRecentMessages:type_name -> signalservice.AddressableMessage + 48, // 126: signalservice.SyncMessage.DeleteForMe.ConversationDelete.mostRecentNonExpiringMessages:type_name -> signalservice.AddressableMessage + 49, // 127: signalservice.SyncMessage.DeleteForMe.LocalOnlyConversationDelete.conversation:type_name -> signalservice.ConversationIdentifier + 40, // 128: signalservice.SyncMessage.AttachmentBackfillResponse.AttachmentData.attachment:type_name -> signalservice.AttachmentPointer + 25, // 129: signalservice.SyncMessage.AttachmentBackfillResponse.AttachmentData.status:type_name -> signalservice.SyncMessage.AttachmentBackfillResponse.AttachmentData.Status + 112, // 130: signalservice.SyncMessage.AttachmentBackfillResponse.AttachmentDataList.attachments:type_name -> signalservice.SyncMessage.AttachmentBackfillResponse.AttachmentData + 112, // 131: signalservice.SyncMessage.AttachmentBackfillResponse.AttachmentDataList.longText:type_name -> signalservice.SyncMessage.AttachmentBackfillResponse.AttachmentData + 132, // [132:132] is the sub-list for method output_type + 132, // [132:132] is the sub-list for method input_type + 132, // [132:132] is the sub-list for extension type_name + 132, // [132:132] is the sub-list for extension extendee + 0, // [0:132] is the sub-list for field type_name } func init() { file_SignalService_proto_init() } @@ -9303,6 +9635,17 @@ func file_SignalService_proto_init() { if File_SignalService_proto != nil { return } + file_SignalService_proto_msgTypes[1].OneofWrappers = []any{ + (*Content_DataMessage)(nil), + (*Content_SyncMessage)(nil), + (*Content_CallMessage)(nil), + (*Content_NullMessage)(nil), + (*Content_ReceiptMessage)(nil), + (*Content_TypingMessage)(nil), + (*Content_DecryptionErrorMessage)(nil), + (*Content_StoryMessage)(nil), + (*Content_EditMessage)(nil), + } file_SignalService_proto_msgTypes[7].OneofWrappers = []any{ (*StoryMessage_FileAttachment)(nil), (*StoryMessage_TextAttachment)(nil), @@ -9311,6 +9654,27 @@ func file_SignalService_proto_init() { (*TextAttachment_Gradient_)(nil), (*TextAttachment_Color)(nil), } + file_SignalService_proto_msgTypes[11].OneofWrappers = []any{ + (*SyncMessage_Sent_)(nil), + (*SyncMessage_Contacts_)(nil), + (*SyncMessage_Request_)(nil), + (*SyncMessage_Blocked_)(nil), + (*SyncMessage_Verified)(nil), + (*SyncMessage_Configuration_)(nil), + (*SyncMessage_ViewOnceOpen_)(nil), + (*SyncMessage_FetchLatest_)(nil), + (*SyncMessage_Keys_)(nil), + (*SyncMessage_MessageRequestResponse_)(nil), + (*SyncMessage_OutgoingPayment_)(nil), + (*SyncMessage_PniChangeNumber_)(nil), + (*SyncMessage_CallEvent_)(nil), + (*SyncMessage_CallLinkUpdate_)(nil), + (*SyncMessage_CallLogEvent_)(nil), + (*SyncMessage_DeleteForMe_)(nil), + (*SyncMessage_DeviceNameChange_)(nil), + (*SyncMessage_AttachmentBackfillRequest_)(nil), + (*SyncMessage_AttachmentBackfillResponse_)(nil), + } file_SignalService_proto_msgTypes[12].OneofWrappers = []any{ (*AttachmentPointer_CdnId)(nil), (*AttachmentPointer_CdnKey)(nil), @@ -9342,20 +9706,20 @@ func file_SignalService_proto_init() { (*DataMessage_PinMessage_PinDurationSeconds)(nil), (*DataMessage_PinMessage_PinDurationForever)(nil), } - file_SignalService_proto_msgTypes[42].OneofWrappers = []any{ + file_SignalService_proto_msgTypes[43].OneofWrappers = []any{ (*DataMessage_Payment_Amount_MobileCoin_)(nil), } - file_SignalService_proto_msgTypes[43].OneofWrappers = []any{ + file_SignalService_proto_msgTypes[44].OneofWrappers = []any{ (*DataMessage_Payment_Notification_MobileCoin_)(nil), } - file_SignalService_proto_msgTypes[67].OneofWrappers = []any{ + file_SignalService_proto_msgTypes[68].OneofWrappers = []any{ (*SyncMessage_OutgoingPayment_MobileCoin_)(nil), } - file_SignalService_proto_msgTypes[75].OneofWrappers = []any{ + file_SignalService_proto_msgTypes[76].OneofWrappers = []any{ (*SyncMessage_AttachmentBackfillResponse_Attachments)(nil), (*SyncMessage_AttachmentBackfillResponse_Error_)(nil), } - file_SignalService_proto_msgTypes[83].OneofWrappers = []any{ + file_SignalService_proto_msgTypes[84].OneofWrappers = []any{ (*SyncMessage_AttachmentBackfillResponse_AttachmentData_Attachment)(nil), (*SyncMessage_AttachmentBackfillResponse_AttachmentData_Status_)(nil), } @@ -9365,7 +9729,7 @@ func file_SignalService_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: unsafe.Slice(unsafe.StringData(file_SignalService_proto_rawDesc), len(file_SignalService_proto_rawDesc)), NumEnums: 28, - NumMessages: 87, + NumMessages: 88, NumExtensions: 0, NumServices: 0, }, diff --git a/pkg/signalmeow/protobuf/SignalService.proto b/pkg/signalmeow/protobuf/SignalService.proto index da4d44f..0089a16 100644 --- a/pkg/signalmeow/protobuf/SignalService.proto +++ b/pkg/signalmeow/protobuf/SignalService.proto @@ -13,23 +13,79 @@ option java_outer_classname = "SignalServiceProtos"; message Envelope { enum Type { UNKNOWN = 0; - CIPHERTEXT = 1; // content => (version byte | SignalMessage{Content}) + + /** + * A double-ratchet message represents a "normal," "unsealed-sender" message + * encrypted using the Double Ratchet within an established Signal session. + * Double-ratchet messages include sender information in the plaintext + * portion of the `Envelope`. + */ + DOUBLE_RATCHET = 1; // content => (version byte | SignalMessage{Content}) + reserved 2; reserved "KEY_EXCHANGE"; - PREKEY_BUNDLE = 3; // content => (version byte | PreKeySignalMessage{Content}) - SERVER_DELIVERY_RECEIPT = 5; // legacyMessage => [] AND content => [] - UNIDENTIFIED_SENDER = 6; // legacyMessage => [] AND content => ((version byte | UnidentifiedSenderMessage) OR (version byte | Multi-Recipient Sealed Sender Format)) - SENDERKEY_MESSAGE = 7; // legacyMessage => [] AND content => (version byte | SenderKeyMessage) - PLAINTEXT_CONTENT = 8; // legacyMessage => [] AND content => (marker byte | Content) + + /** + * A prekey message begins a new Signal session. The `content` of a prekey + * message is a superset of a double-ratchet message's `content` and + * contains the sender's identity public key and information identifying the + * pre-keys used in the message's ciphertext. Like double-ratchet messages, + * prekey messages contain sender information in the plaintext portion of + * the `Envelope`. + */ + PREKEY_MESSAGE = 3; // content => (version byte | PreKeySignalMessage{Content}) + + /** + * Server delivery receipts are generated by the server when + * "unsealed-sender" messages are delivered to and acknowledged by the + * destination device. Server delivery receipts identify the sender in the + * plaintext portion of the `Envelope` and have no `content`. Note that + * receipts for sealed-sender messages are generated by clients as + * `UNIDENTIFIED_SENDER` messages. + * + * Note that, with server delivery receipts, the "client timestamp" on + * the envelope refers to the timestamp of the original message (i.e. the + * message the server just delivered) and not to the time of delivery. The + * "server timestamp" refers to the time of delivery. + */ + SERVER_DELIVERY_RECEIPT = 5; // content => [] + + /** + * An unidentified sender message represents a message with no sender + * information in the plaintext portion of the `Envelope`. Unidentified + * sender messages always contain an additional `subtype` in their + * `content`. They may or may not be part of an existing Signal session + * (i.e. an unidentified sender message may have a "prekey message" + * subtype or may indicate an encryption error). + */ + UNIDENTIFIED_SENDER = 6; // content => ((version byte | UnidentifiedSenderMessage) OR (version byte | Multi-Recipient Sealed Sender Format)) + + reserved 7; + reserved "SENDERKEY_MESSAGE"; + + /** + * A plaintext message is used solely to convey encryption error receipts + * and never contains encrypted message content. Encryption error receipts + * must be delivered in plaintext because, encryption/decryption of a prior + * message failed and there is no reason to believe that + * encryption/decryption of subsequent messages with the same key material + * would succeed. + * + * Critically, plaintext messages never have "real" message content + * generated by users. Plaintext messages include sender information. + */ + PLAINTEXT_CONTENT = 8; // content => (marker byte | Content) + + // next: 9 } optional Type type = 1; reserved 2; // formerly optional string sourceE164 = 2; optional string sourceServiceId = 11; - optional uint32 sourceDevice = 7; + optional uint32 sourceDeviceId = 7; optional string destinationServiceId = 13; reserved 3; // formerly optional string relay = 3; - optional uint64 timestamp = 5; + optional uint64 clientTimestamp = 5; reserved 6; // formerly optional bytes legacyMessage = 6; // Contains an encrypted DataMessage; this field could have been set historically for type 1 or 3 messages; no longer in use optional bytes content = 8; // Contains an encrypted Content optional string serverGuid = 9; @@ -48,17 +104,20 @@ message Envelope { } message Content { - optional DataMessage dataMessage = 1; - optional SyncMessage syncMessage = 2; - optional CallMessage callMessage = 3; - optional NullMessage nullMessage = 4; - optional ReceiptMessage receiptMessage = 5; - optional TypingMessage typingMessage = 6; + oneof content { + DataMessage dataMessage = 1; + SyncMessage syncMessage = 2; + CallMessage callMessage = 3; + NullMessage nullMessage = 4; + ReceiptMessage receiptMessage = 5; + TypingMessage typingMessage = 6; + bytes /* DecryptionErrorMessage */ decryptionErrorMessage = 8; + StoryMessage storyMessage = 9; + EditMessage editMessage = 11; + } + optional bytes /* SenderKeyDistributionMessage */ senderKeyDistributionMessage = 7; - optional bytes /* DecryptionErrorMessage */ decryptionErrorMessage = 8; - optional StoryMessage storyMessage = 9; optional PniSignatureMessage pniSignatureMessage = 10; - optional EditMessage editMessage = 11; } message CallMessage { @@ -331,8 +390,8 @@ message DataMessage { message PollVote { optional bytes targetAuthorAciBinary = 1; optional uint64 targetSentTimestamp = 2; - repeated uint32 optionIndexes = 3; // must be in the range [0, options.length) from the PollCreate - optional uint32 voteCount = 4; // increment this by 1 each time you vote on a given poll + repeated uint32 optionIndexes = 3; + optional uint32 voteCount = 4; } message PinMessage { @@ -349,6 +408,11 @@ message DataMessage { optional uint64 targetSentTimestamp = 2; } + message AdminDelete { + optional bytes targetAuthorAciBinary = 1; // 16-byte UUID + optional uint64 targetSentTimestamp = 2; + } + optional string body = 1; repeated AttachmentPointer attachments = 2; reserved /*groupV1*/ 3; @@ -376,7 +440,8 @@ message DataMessage { optional PollVote pollVote = 26; optional PinMessage pinMessage = 27; optional UnpinMessage unpinMessage = 28; - // NEXT ID: 29 + optional AdminDelete adminDelete = 29; + // NEXT ID: 30 } message NullMessage { @@ -435,6 +500,12 @@ message TextAttachment { } message Gradient { + // Color ordering: + // 0 degrees: bottom-to-top + // 90 degrees: left-to-right + // 180 degrees: top-to-bottom + // 270 degrees: right-to-left + optional uint32 startColor = 1; // deprecated: this field will be removed in a future release. optional uint32 endColor = 2; // deprecated: this field will be removed in a future release. optional uint32 angle = 3; // degrees @@ -547,7 +618,7 @@ message SyncMessage { optional bool unidentifiedDeliveryIndicators = 2; optional bool typingIndicators = 3; reserved /* linkPreviews */ 4; - optional uint32 provisioningVersion = 5; + reserved /* provisioningVersion */ 5; optional bool linkPreviews = 6; } @@ -582,7 +653,7 @@ message SyncMessage { message Keys { reserved /* storageService */ 1; - optional bytes master = 2; // deprecated: this field will be removed in a future release. + reserved /* master */ 2; optional string accountEntropyPool = 3; optional bytes mediaRootBackupKey = 4; } @@ -682,7 +753,7 @@ message SyncMessage { optional bytes rootKey = 1; optional bytes adminPasskey = 2; optional Type type = 3; // defaults to UPDATE - optional bytes epoch = 4; + reserved /*epoch*/ 4; } message CallLogEvent { @@ -779,31 +850,40 @@ message SyncMessage { } } - optional Sent sent = 1; - optional Contacts contacts = 2; + oneof content { + Sent sent = 1; + Contacts contacts = 2; + Request request = 4; + Blocked blocked = 6; + Verified verified = 7; + Configuration configuration = 9; + ViewOnceOpen viewOnceOpen = 11; + FetchLatest fetchLatest = 12; + Keys keys = 13; + MessageRequestResponse messageRequestResponse = 14; + OutgoingPayment outgoingPayment = 15; + PniChangeNumber pniChangeNumber = 18; + CallEvent callEvent = 19; + CallLinkUpdate callLinkUpdate = 20; + CallLogEvent callLogEvent = 21; + DeleteForMe deleteForMe = 22; + DeviceNameChange deviceNameChange = 23; + AttachmentBackfillRequest attachmentBackfillRequest = 24; + AttachmentBackfillResponse attachmentBackfillResponse = 25; + } + reserved /*groups*/ 3; - optional Request request = 4; + + // Protobufs don't allow `repeated` fields to be inside of `oneof` so while + // the fields below are mutually exclusive with the rest of the values above + // we have to place them outside of `oneof`. repeated Read read = 5; - optional Blocked blocked = 6; - optional Verified verified = 7; - optional Configuration configuration = 9; - optional bytes padding = 8; repeated StickerPackOperation stickerPackOperation = 10; - optional ViewOnceOpen viewOnceOpen = 11; - optional FetchLatest fetchLatest = 12; - optional Keys keys = 13; - optional MessageRequestResponse messageRequestResponse = 14; - optional OutgoingPayment outgoingPayment = 15; repeated Viewed viewed = 16; + reserved /*pniIdentity*/ 17; - optional PniChangeNumber pniChangeNumber = 18; - optional CallEvent callEvent = 19; - optional CallLinkUpdate callLinkUpdate = 20; - optional CallLogEvent callLogEvent = 21; - optional DeleteForMe deleteForMe = 22; - optional DeviceNameChange deviceNameChange = 23; - optional AttachmentBackfillRequest attachmentBackfillRequest = 24; - optional AttachmentBackfillResponse attachmentBackfillResponse = 25; + + optional bytes padding = 8; } message AttachmentPointer { diff --git a/pkg/signalmeow/protobuf/StorageService.pb.go b/pkg/signalmeow/protobuf/StorageService.pb.go index 9a27146..619221f 100644 --- a/pkg/signalmeow/protobuf/StorageService.pb.go +++ b/pkg/signalmeow/protobuf/StorageService.pb.go @@ -1598,6 +1598,7 @@ type AccountRecord struct { NotificationProfileManualOverride *AccountRecord_NotificationProfileManualOverride `protobuf:"bytes,44,opt,name=notificationProfileManualOverride,proto3" json:"notificationProfileManualOverride,omitempty"` NotificationProfileSyncDisabled bool `protobuf:"varint,45,opt,name=notificationProfileSyncDisabled,proto3" json:"notificationProfileSyncDisabled,omitempty"` AutomaticKeyVerificationDisabled bool `protobuf:"varint,46,opt,name=automaticKeyVerificationDisabled,proto3" json:"automaticKeyVerificationDisabled,omitempty"` + HasSeenAdminDeleteEducationDialog bool `protobuf:"varint,47,opt,name=hasSeenAdminDeleteEducationDialog,proto3" json:"hasSeenAdminDeleteEducationDialog,omitempty"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } @@ -1905,6 +1906,13 @@ func (x *AccountRecord) GetAutomaticKeyVerificationDisabled() bool { return false } +func (x *AccountRecord) GetHasSeenAdminDeleteEducationDialog() bool { + if x != nil { + return x.HasSeenAdminDeleteEducationDialog + } + return false +} + type StoryDistributionListRecord struct { state protoimpl.MessageState `protogen:"open.v1"` Identifier []byte `protobuf:"bytes,1,opt,name=identifier,proto3" json:"identifier,omitempty"` @@ -2002,7 +2010,6 @@ type CallLinkRecord struct { RootKey []byte `protobuf:"bytes,1,opt,name=rootKey,proto3" json:"rootKey,omitempty"` AdminPasskey []byte `protobuf:"bytes,2,opt,name=adminPasskey,proto3" json:"adminPasskey,omitempty"` DeletedAtTimestampMs uint64 `protobuf:"varint,3,opt,name=deletedAtTimestampMs,proto3" json:"deletedAtTimestampMs,omitempty"` - Epoch []byte `protobuf:"bytes,4,opt,name=epoch,proto3,oneof" json:"epoch,omitempty"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } @@ -2058,13 +2065,6 @@ func (x *CallLinkRecord) GetDeletedAtTimestampMs() uint64 { return 0 } -func (x *CallLinkRecord) GetEpoch() []byte { - if x != nil { - return x.Epoch - } - return nil -} - type Recipient struct { state protoimpl.MessageState `protogen:"open.v1"` // Types that are valid to be assigned to Identifier: @@ -3216,7 +3216,7 @@ const file_StorageService_proto_rawDesc = "" + "\">\n" + "\bPayments\x12\x18\n" + "\aenabled\x18\x01 \x01(\bR\aenabled\x12\x18\n" + - "\aentropy\x18\x02 \x01(\fR\aentropy\"\xcb\x1c\n" + + "\aentropy\x18\x02 \x01(\fR\aentropy\"\x99\x1d\n" + "\rAccountRecord\x12\x1e\n" + "\n" + "profileKey\x18\x01 \x01(\fR\n" + @@ -3263,7 +3263,8 @@ const file_StorageService_proto_rawDesc = "" + "\x11backupTierHistory\x18+ \x01(\v2..signalservice.AccountRecord.BackupTierHistoryR\x11backupTierHistory\x12\x8c\x01\n" + "!notificationProfileManualOverride\x18, \x01(\v2>.signalservice.AccountRecord.NotificationProfileManualOverrideR!notificationProfileManualOverride\x12H\n" + "\x1fnotificationProfileSyncDisabled\x18- \x01(\bR\x1fnotificationProfileSyncDisabled\x12J\n" + - " automaticKeyVerificationDisabled\x18. \x01(\bR automaticKeyVerificationDisabled\x1a\xb0\x02\n" + + " automaticKeyVerificationDisabled\x18. \x01(\bR automaticKeyVerificationDisabled\x12L\n" + + "!hasSeenAdminDeleteEducationDialog\x18/ \x01(\bR!hasSeenAdminDeleteEducationDialog\x1a\xb0\x02\n" + "\x12PinnedConversation\x12S\n" + "\acontact\x18\x01 \x01(\v27.signalservice.AccountRecord.PinnedConversation.ContactH\x00R\acontact\x12&\n" + "\rlegacyGroupId\x18\x03 \x01(\fH\x00R\rlegacyGroupId\x12(\n" + @@ -3329,13 +3330,11 @@ const file_StorageService_proto_rawDesc = "" + "\x12deletedAtTimestamp\x18\x04 \x01(\x04R\x12deletedAtTimestamp\x12$\n" + "\rallowsReplies\x18\x05 \x01(\bR\rallowsReplies\x12 \n" + "\visBlockList\x18\x06 \x01(\bR\visBlockList\x12<\n" + - "\x19recipientServiceIdsBinary\x18\a \x03(\fR\x19recipientServiceIdsBinary\"\xa7\x01\n" + + "\x19recipientServiceIdsBinary\x18\a \x03(\fR\x19recipientServiceIdsBinary\"\x88\x01\n" + "\x0eCallLinkRecord\x12\x18\n" + "\arootKey\x18\x01 \x01(\fR\arootKey\x12\"\n" + "\fadminPasskey\x18\x02 \x01(\fR\fadminPasskey\x122\n" + - "\x14deletedAtTimestampMs\x18\x03 \x01(\x04R\x14deletedAtTimestampMs\x12\x19\n" + - "\x05epoch\x18\x04 \x01(\fH\x00R\x05epoch\x88\x01\x01B\b\n" + - "\x06_epoch\"\x90\x02\n" + + "\x14deletedAtTimestampMs\x18\x03 \x01(\x04R\x14deletedAtTimestampMsJ\x04\b\x04\x10\x05\"\x90\x02\n" + "\tRecipient\x12<\n" + "\acontact\x18\x01 \x01(\v2 .signalservice.Recipient.ContactH\x00R\acontact\x12&\n" + "\rlegacyGroupId\x18\x02 \x01(\fH\x00R\rlegacyGroupId\x12(\n" + @@ -3531,7 +3530,6 @@ func file_StorageService_proto_init() { file_StorageService_proto_msgTypes[7].OneofWrappers = []any{} file_StorageService_proto_msgTypes[9].OneofWrappers = []any{} file_StorageService_proto_msgTypes[11].OneofWrappers = []any{} - file_StorageService_proto_msgTypes[13].OneofWrappers = []any{} file_StorageService_proto_msgTypes[14].OneofWrappers = []any{ (*Recipient_Contact_)(nil), (*Recipient_LegacyGroupId)(nil), diff --git a/pkg/signalmeow/protobuf/StorageService.proto b/pkg/signalmeow/protobuf/StorageService.proto index 95ec845..d22babc 100644 --- a/pkg/signalmeow/protobuf/StorageService.proto +++ b/pkg/signalmeow/protobuf/StorageService.proto @@ -296,6 +296,7 @@ message AccountRecord { NotificationProfileManualOverride notificationProfileManualOverride = 44; bool notificationProfileSyncDisabled = 45; bool automaticKeyVerificationDisabled = 46; + bool hasSeenAdminDeleteEducationDialog = 47; } message StoryDistributionListRecord { @@ -312,7 +313,7 @@ message CallLinkRecord { bytes rootKey = 1; bytes adminPasskey = 2; uint64 deletedAtTimestampMs = 3; - optional bytes epoch = 4; + reserved 4; // was epoch field, never used } message Recipient { diff --git a/pkg/signalmeow/protobuf/backuppb/Backup.pb.go b/pkg/signalmeow/protobuf/backuppb/Backup.pb.go index 73930ae..326c170 100644 --- a/pkg/signalmeow/protobuf/backuppb/Backup.pb.go +++ b/pkg/signalmeow/protobuf/backuppb/Backup.pb.go @@ -1504,7 +1504,7 @@ func (x IndividualCall_Type) Number() protoreflect.EnumNumber { // Deprecated: Use IndividualCall_Type.Descriptor instead. func (IndividualCall_Type) EnumDescriptor() ([]byte, []int) { - return file_backuppb_Backup_proto_rawDescGZIP(), []int{34, 0} + return file_backuppb_Backup_proto_rawDescGZIP(), []int{35, 0} } type IndividualCall_Direction int32 @@ -1553,7 +1553,7 @@ func (x IndividualCall_Direction) Number() protoreflect.EnumNumber { // Deprecated: Use IndividualCall_Direction.Descriptor instead. func (IndividualCall_Direction) EnumDescriptor() ([]byte, []int) { - return file_backuppb_Backup_proto_rawDescGZIP(), []int{34, 1} + return file_backuppb_Backup_proto_rawDescGZIP(), []int{35, 1} } type IndividualCall_State int32 @@ -1612,7 +1612,7 @@ func (x IndividualCall_State) Number() protoreflect.EnumNumber { // Deprecated: Use IndividualCall_State.Descriptor instead. func (IndividualCall_State) EnumDescriptor() ([]byte, []int) { - return file_backuppb_Backup_proto_rawDescGZIP(), []int{34, 2} + return file_backuppb_Backup_proto_rawDescGZIP(), []int{35, 2} } type GroupCall_State int32 @@ -1688,7 +1688,7 @@ func (x GroupCall_State) Number() protoreflect.EnumNumber { // Deprecated: Use GroupCall_State.Descriptor instead. func (GroupCall_State) EnumDescriptor() ([]byte, []int) { - return file_backuppb_Backup_proto_rawDescGZIP(), []int{35, 0} + return file_backuppb_Backup_proto_rawDescGZIP(), []int{36, 0} } type SimpleChatUpdate_Type int32 @@ -1779,7 +1779,7 @@ func (x SimpleChatUpdate_Type) Number() protoreflect.EnumNumber { // Deprecated: Use SimpleChatUpdate_Type.Descriptor instead. func (SimpleChatUpdate_Type) EnumDescriptor() ([]byte, []int) { - return file_backuppb_Backup_proto_rawDescGZIP(), []int{36, 0} + return file_backuppb_Backup_proto_rawDescGZIP(), []int{37, 0} } type ChatStyle_WallpaperPreset int32 @@ -1885,7 +1885,7 @@ func (x ChatStyle_WallpaperPreset) Number() protoreflect.EnumNumber { // Deprecated: Use ChatStyle_WallpaperPreset.Descriptor instead. func (ChatStyle_WallpaperPreset) EnumDescriptor() ([]byte, []int) { - return file_backuppb_Backup_proto_rawDescGZIP(), []int{80, 0} + return file_backuppb_Backup_proto_rawDescGZIP(), []int{83, 0} } type ChatStyle_BubbleColorPreset int32 @@ -1994,7 +1994,7 @@ func (x ChatStyle_BubbleColorPreset) Number() protoreflect.EnumNumber { // Deprecated: Use ChatStyle_BubbleColorPreset.Descriptor instead. func (ChatStyle_BubbleColorPreset) EnumDescriptor() ([]byte, []int) { - return file_backuppb_Backup_proto_rawDescGZIP(), []int{80, 1} + return file_backuppb_Backup_proto_rawDescGZIP(), []int{83, 1} } type NotificationProfile_DayOfWeek int32 @@ -2058,7 +2058,7 @@ func (x NotificationProfile_DayOfWeek) Number() protoreflect.EnumNumber { // Deprecated: Use NotificationProfile_DayOfWeek.Descriptor instead. func (NotificationProfile_DayOfWeek) EnumDescriptor() ([]byte, []int) { - return file_backuppb_Backup_proto_rawDescGZIP(), []int{81, 0} + return file_backuppb_Backup_proto_rawDescGZIP(), []int{84, 0} } // Represents the default "All chats" folder record vs all other custom folders @@ -2108,7 +2108,7 @@ func (x ChatFolder_FolderType) Number() protoreflect.EnumNumber { // Deprecated: Use ChatFolder_FolderType.Descriptor instead. func (ChatFolder_FolderType) EnumDescriptor() ([]byte, []int) { - return file_backuppb_Backup_proto_rawDescGZIP(), []int{82, 0} + return file_backuppb_Backup_proto_rawDescGZIP(), []int{85, 0} } type BackupInfo struct { @@ -3241,7 +3241,6 @@ type CallLink struct { Name string `protobuf:"bytes,3,opt,name=name,proto3" json:"name,omitempty"` Restrictions CallLink_Restrictions `protobuf:"varint,4,opt,name=restrictions,proto3,enum=signal.backup.CallLink_Restrictions" json:"restrictions,omitempty"` ExpirationMs uint64 `protobuf:"varint,5,opt,name=expirationMs,proto3" json:"expirationMs,omitempty"` - Epoch []byte `protobuf:"bytes,6,opt,name=epoch,proto3,oneof" json:"epoch,omitempty"` // May be absent/empty for older links unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } @@ -3311,13 +3310,6 @@ func (x *CallLink) GetExpirationMs() uint64 { return 0 } -func (x *CallLink) GetEpoch() []byte { - if x != nil { - return x.Epoch - } - return nil -} - type AdHocCall struct { state protoimpl.MessageState `protogen:"open.v1"` CallId uint64 `protobuf:"varint,1,opt,name=callId,proto3" json:"callId,omitempty"` @@ -3580,6 +3572,7 @@ type ChatItem struct { // *ChatItem_ViewOnceMessage // *ChatItem_DirectStoryReplyMessage // *ChatItem_Poll + // *ChatItem_AdminDeletedMessage Item isChatItem_Item `protobuf_oneof:"item"` PinDetails *ChatItem_PinDetails `protobuf:"bytes,21,opt,name=pinDetails,proto3" json:"pinDetails,omitempty"` // only set if message is pinned unknownFields protoimpl.UnknownFields @@ -3796,6 +3789,15 @@ func (x *ChatItem) GetPoll() *Poll { return nil } +func (x *ChatItem) GetAdminDeletedMessage() *AdminDeletedMessage { + if x != nil { + if x, ok := x.Item.(*ChatItem_AdminDeletedMessage); ok { + return x.AdminDeletedMessage + } + } + return nil +} + func (x *ChatItem) GetPinDetails() *ChatItem_PinDetails { if x != nil { return x.PinDetails @@ -3869,6 +3871,10 @@ type ChatItem_Poll struct { Poll *Poll `protobuf:"bytes,20,opt,name=poll,proto3,oneof"` } +type ChatItem_AdminDeletedMessage struct { + AdminDeletedMessage *AdminDeletedMessage `protobuf:"bytes,22,opt,name=adminDeletedMessage,proto3,oneof"` +} + func (*ChatItem_StandardMessage) isChatItem_Item() {} func (*ChatItem_ContactMessage) isChatItem_Item() {} @@ -3889,6 +3895,8 @@ func (*ChatItem_DirectStoryReplyMessage) isChatItem_Item() {} func (*ChatItem_Poll) isChatItem_Item() {} +func (*ChatItem_AdminDeletedMessage) isChatItem_Item() {} + type SendStatus struct { state protoimpl.MessageState `protogen:"open.v1"` RecipientId uint64 `protobuf:"varint,1,opt,name=recipientId,proto3" json:"recipientId,omitempty"` @@ -5355,6 +5363,50 @@ func (x *Poll) GetReactions() []*Reaction { return nil } +type AdminDeletedMessage struct { + state protoimpl.MessageState `protogen:"open.v1"` + AdminId uint64 `protobuf:"varint,1,opt,name=adminId,proto3" json:"adminId,omitempty"` // id of the admin that deleted the message + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *AdminDeletedMessage) Reset() { + *x = AdminDeletedMessage{} + mi := &file_backuppb_Backup_proto_msgTypes[33] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *AdminDeletedMessage) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*AdminDeletedMessage) ProtoMessage() {} + +func (x *AdminDeletedMessage) ProtoReflect() protoreflect.Message { + mi := &file_backuppb_Backup_proto_msgTypes[33] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use AdminDeletedMessage.ProtoReflect.Descriptor instead. +func (*AdminDeletedMessage) Descriptor() ([]byte, []int) { + return file_backuppb_Backup_proto_rawDescGZIP(), []int{33} +} + +func (x *AdminDeletedMessage) GetAdminId() uint64 { + if x != nil { + return x.AdminId + } + return 0 +} + type ChatUpdateMessage struct { state protoimpl.MessageState `protogen:"open.v1"` // If unset, importers should ignore the update message without throwing an error. @@ -5379,7 +5431,7 @@ type ChatUpdateMessage struct { func (x *ChatUpdateMessage) Reset() { *x = ChatUpdateMessage{} - mi := &file_backuppb_Backup_proto_msgTypes[33] + mi := &file_backuppb_Backup_proto_msgTypes[34] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5391,7 +5443,7 @@ func (x *ChatUpdateMessage) String() string { func (*ChatUpdateMessage) ProtoMessage() {} func (x *ChatUpdateMessage) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[33] + mi := &file_backuppb_Backup_proto_msgTypes[34] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5404,7 +5456,7 @@ func (x *ChatUpdateMessage) ProtoReflect() protoreflect.Message { // Deprecated: Use ChatUpdateMessage.ProtoReflect.Descriptor instead. func (*ChatUpdateMessage) Descriptor() ([]byte, []int) { - return file_backuppb_Backup_proto_rawDescGZIP(), []int{33} + return file_backuppb_Backup_proto_rawDescGZIP(), []int{34} } func (x *ChatUpdateMessage) GetUpdate() isChatUpdateMessage_Update { @@ -5597,7 +5649,7 @@ type IndividualCall struct { func (x *IndividualCall) Reset() { *x = IndividualCall{} - mi := &file_backuppb_Backup_proto_msgTypes[34] + mi := &file_backuppb_Backup_proto_msgTypes[35] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5609,7 +5661,7 @@ func (x *IndividualCall) String() string { func (*IndividualCall) ProtoMessage() {} func (x *IndividualCall) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[34] + mi := &file_backuppb_Backup_proto_msgTypes[35] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5622,7 +5674,7 @@ func (x *IndividualCall) ProtoReflect() protoreflect.Message { // Deprecated: Use IndividualCall.ProtoReflect.Descriptor instead. func (*IndividualCall) Descriptor() ([]byte, []int) { - return file_backuppb_Backup_proto_rawDescGZIP(), []int{34} + return file_backuppb_Backup_proto_rawDescGZIP(), []int{35} } func (x *IndividualCall) GetCallId() uint64 { @@ -5682,7 +5734,7 @@ type GroupCall struct { func (x *GroupCall) Reset() { *x = GroupCall{} - mi := &file_backuppb_Backup_proto_msgTypes[35] + mi := &file_backuppb_Backup_proto_msgTypes[36] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5694,7 +5746,7 @@ func (x *GroupCall) String() string { func (*GroupCall) ProtoMessage() {} func (x *GroupCall) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[35] + mi := &file_backuppb_Backup_proto_msgTypes[36] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5707,7 +5759,7 @@ func (x *GroupCall) ProtoReflect() protoreflect.Message { // Deprecated: Use GroupCall.ProtoReflect.Descriptor instead. func (*GroupCall) Descriptor() ([]byte, []int) { - return file_backuppb_Backup_proto_rawDescGZIP(), []int{35} + return file_backuppb_Backup_proto_rawDescGZIP(), []int{36} } func (x *GroupCall) GetCallId() uint64 { @@ -5768,7 +5820,7 @@ type SimpleChatUpdate struct { func (x *SimpleChatUpdate) Reset() { *x = SimpleChatUpdate{} - mi := &file_backuppb_Backup_proto_msgTypes[36] + mi := &file_backuppb_Backup_proto_msgTypes[37] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5780,7 +5832,7 @@ func (x *SimpleChatUpdate) String() string { func (*SimpleChatUpdate) ProtoMessage() {} func (x *SimpleChatUpdate) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[36] + mi := &file_backuppb_Backup_proto_msgTypes[37] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5793,7 +5845,7 @@ func (x *SimpleChatUpdate) ProtoReflect() protoreflect.Message { // Deprecated: Use SimpleChatUpdate.ProtoReflect.Descriptor instead. func (*SimpleChatUpdate) Descriptor() ([]byte, []int) { - return file_backuppb_Backup_proto_rawDescGZIP(), []int{36} + return file_backuppb_Backup_proto_rawDescGZIP(), []int{37} } func (x *SimpleChatUpdate) GetType() SimpleChatUpdate_Type { @@ -5814,7 +5866,7 @@ type ExpirationTimerChatUpdate struct { func (x *ExpirationTimerChatUpdate) Reset() { *x = ExpirationTimerChatUpdate{} - mi := &file_backuppb_Backup_proto_msgTypes[37] + mi := &file_backuppb_Backup_proto_msgTypes[38] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5826,7 +5878,7 @@ func (x *ExpirationTimerChatUpdate) String() string { func (*ExpirationTimerChatUpdate) ProtoMessage() {} func (x *ExpirationTimerChatUpdate) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[37] + mi := &file_backuppb_Backup_proto_msgTypes[38] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5839,7 +5891,7 @@ func (x *ExpirationTimerChatUpdate) ProtoReflect() protoreflect.Message { // Deprecated: Use ExpirationTimerChatUpdate.ProtoReflect.Descriptor instead. func (*ExpirationTimerChatUpdate) Descriptor() ([]byte, []int) { - return file_backuppb_Backup_proto_rawDescGZIP(), []int{37} + return file_backuppb_Backup_proto_rawDescGZIP(), []int{38} } func (x *ExpirationTimerChatUpdate) GetExpiresInMs() uint64 { @@ -5859,7 +5911,7 @@ type ProfileChangeChatUpdate struct { func (x *ProfileChangeChatUpdate) Reset() { *x = ProfileChangeChatUpdate{} - mi := &file_backuppb_Backup_proto_msgTypes[38] + mi := &file_backuppb_Backup_proto_msgTypes[39] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5871,7 +5923,7 @@ func (x *ProfileChangeChatUpdate) String() string { func (*ProfileChangeChatUpdate) ProtoMessage() {} func (x *ProfileChangeChatUpdate) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[38] + mi := &file_backuppb_Backup_proto_msgTypes[39] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5884,7 +5936,7 @@ func (x *ProfileChangeChatUpdate) ProtoReflect() protoreflect.Message { // Deprecated: Use ProfileChangeChatUpdate.ProtoReflect.Descriptor instead. func (*ProfileChangeChatUpdate) Descriptor() ([]byte, []int) { - return file_backuppb_Backup_proto_rawDescGZIP(), []int{38} + return file_backuppb_Backup_proto_rawDescGZIP(), []int{39} } func (x *ProfileChangeChatUpdate) GetPreviousName() string { @@ -5916,7 +5968,7 @@ type LearnedProfileChatUpdate struct { func (x *LearnedProfileChatUpdate) Reset() { *x = LearnedProfileChatUpdate{} - mi := &file_backuppb_Backup_proto_msgTypes[39] + mi := &file_backuppb_Backup_proto_msgTypes[40] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5928,7 +5980,7 @@ func (x *LearnedProfileChatUpdate) String() string { func (*LearnedProfileChatUpdate) ProtoMessage() {} func (x *LearnedProfileChatUpdate) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[39] + mi := &file_backuppb_Backup_proto_msgTypes[40] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5941,7 +5993,7 @@ func (x *LearnedProfileChatUpdate) ProtoReflect() protoreflect.Message { // Deprecated: Use LearnedProfileChatUpdate.ProtoReflect.Descriptor instead. func (*LearnedProfileChatUpdate) Descriptor() ([]byte, []int) { - return file_backuppb_Backup_proto_rawDescGZIP(), []int{39} + return file_backuppb_Backup_proto_rawDescGZIP(), []int{40} } func (x *LearnedProfileChatUpdate) GetPreviousName() isLearnedProfileChatUpdate_PreviousName { @@ -5994,7 +6046,7 @@ type ThreadMergeChatUpdate struct { func (x *ThreadMergeChatUpdate) Reset() { *x = ThreadMergeChatUpdate{} - mi := &file_backuppb_Backup_proto_msgTypes[40] + mi := &file_backuppb_Backup_proto_msgTypes[41] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6006,7 +6058,7 @@ func (x *ThreadMergeChatUpdate) String() string { func (*ThreadMergeChatUpdate) ProtoMessage() {} func (x *ThreadMergeChatUpdate) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[40] + mi := &file_backuppb_Backup_proto_msgTypes[41] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6019,7 +6071,7 @@ func (x *ThreadMergeChatUpdate) ProtoReflect() protoreflect.Message { // Deprecated: Use ThreadMergeChatUpdate.ProtoReflect.Descriptor instead. func (*ThreadMergeChatUpdate) Descriptor() ([]byte, []int) { - return file_backuppb_Backup_proto_rawDescGZIP(), []int{40} + return file_backuppb_Backup_proto_rawDescGZIP(), []int{41} } func (x *ThreadMergeChatUpdate) GetPreviousE164() uint64 { @@ -6038,7 +6090,7 @@ type SessionSwitchoverChatUpdate struct { func (x *SessionSwitchoverChatUpdate) Reset() { *x = SessionSwitchoverChatUpdate{} - mi := &file_backuppb_Backup_proto_msgTypes[41] + mi := &file_backuppb_Backup_proto_msgTypes[42] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6050,7 +6102,7 @@ func (x *SessionSwitchoverChatUpdate) String() string { func (*SessionSwitchoverChatUpdate) ProtoMessage() {} func (x *SessionSwitchoverChatUpdate) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[41] + mi := &file_backuppb_Backup_proto_msgTypes[42] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6063,7 +6115,7 @@ func (x *SessionSwitchoverChatUpdate) ProtoReflect() protoreflect.Message { // Deprecated: Use SessionSwitchoverChatUpdate.ProtoReflect.Descriptor instead. func (*SessionSwitchoverChatUpdate) Descriptor() ([]byte, []int) { - return file_backuppb_Backup_proto_rawDescGZIP(), []int{41} + return file_backuppb_Backup_proto_rawDescGZIP(), []int{42} } func (x *SessionSwitchoverChatUpdate) GetE164() uint64 { @@ -6084,7 +6136,7 @@ type GroupChangeChatUpdate struct { func (x *GroupChangeChatUpdate) Reset() { *x = GroupChangeChatUpdate{} - mi := &file_backuppb_Backup_proto_msgTypes[42] + mi := &file_backuppb_Backup_proto_msgTypes[43] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6096,7 +6148,7 @@ func (x *GroupChangeChatUpdate) String() string { func (*GroupChangeChatUpdate) ProtoMessage() {} func (x *GroupChangeChatUpdate) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[42] + mi := &file_backuppb_Backup_proto_msgTypes[43] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6109,7 +6161,7 @@ func (x *GroupChangeChatUpdate) ProtoReflect() protoreflect.Message { // Deprecated: Use GroupChangeChatUpdate.ProtoReflect.Descriptor instead. func (*GroupChangeChatUpdate) Descriptor() ([]byte, []int) { - return file_backuppb_Backup_proto_rawDescGZIP(), []int{42} + return file_backuppb_Backup_proto_rawDescGZIP(), []int{43} } func (x *GroupChangeChatUpdate) GetUpdates() []*GroupChangeChatUpdate_Update { @@ -6128,7 +6180,7 @@ type GenericGroupUpdate struct { func (x *GenericGroupUpdate) Reset() { *x = GenericGroupUpdate{} - mi := &file_backuppb_Backup_proto_msgTypes[43] + mi := &file_backuppb_Backup_proto_msgTypes[44] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6140,7 +6192,7 @@ func (x *GenericGroupUpdate) String() string { func (*GenericGroupUpdate) ProtoMessage() {} func (x *GenericGroupUpdate) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[43] + mi := &file_backuppb_Backup_proto_msgTypes[44] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6153,7 +6205,7 @@ func (x *GenericGroupUpdate) ProtoReflect() protoreflect.Message { // Deprecated: Use GenericGroupUpdate.ProtoReflect.Descriptor instead. func (*GenericGroupUpdate) Descriptor() ([]byte, []int) { - return file_backuppb_Backup_proto_rawDescGZIP(), []int{43} + return file_backuppb_Backup_proto_rawDescGZIP(), []int{44} } func (x *GenericGroupUpdate) GetUpdaterAci() []byte { @@ -6172,7 +6224,7 @@ type GroupCreationUpdate struct { func (x *GroupCreationUpdate) Reset() { *x = GroupCreationUpdate{} - mi := &file_backuppb_Backup_proto_msgTypes[44] + mi := &file_backuppb_Backup_proto_msgTypes[45] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6184,7 +6236,7 @@ func (x *GroupCreationUpdate) String() string { func (*GroupCreationUpdate) ProtoMessage() {} func (x *GroupCreationUpdate) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[44] + mi := &file_backuppb_Backup_proto_msgTypes[45] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6197,7 +6249,7 @@ func (x *GroupCreationUpdate) ProtoReflect() protoreflect.Message { // Deprecated: Use GroupCreationUpdate.ProtoReflect.Descriptor instead. func (*GroupCreationUpdate) Descriptor() ([]byte, []int) { - return file_backuppb_Backup_proto_rawDescGZIP(), []int{44} + return file_backuppb_Backup_proto_rawDescGZIP(), []int{45} } func (x *GroupCreationUpdate) GetUpdaterAci() []byte { @@ -6218,7 +6270,7 @@ type GroupNameUpdate struct { func (x *GroupNameUpdate) Reset() { *x = GroupNameUpdate{} - mi := &file_backuppb_Backup_proto_msgTypes[45] + mi := &file_backuppb_Backup_proto_msgTypes[46] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6230,7 +6282,7 @@ func (x *GroupNameUpdate) String() string { func (*GroupNameUpdate) ProtoMessage() {} func (x *GroupNameUpdate) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[45] + mi := &file_backuppb_Backup_proto_msgTypes[46] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6243,7 +6295,7 @@ func (x *GroupNameUpdate) ProtoReflect() protoreflect.Message { // Deprecated: Use GroupNameUpdate.ProtoReflect.Descriptor instead. func (*GroupNameUpdate) Descriptor() ([]byte, []int) { - return file_backuppb_Backup_proto_rawDescGZIP(), []int{45} + return file_backuppb_Backup_proto_rawDescGZIP(), []int{46} } func (x *GroupNameUpdate) GetUpdaterAci() []byte { @@ -6270,7 +6322,7 @@ type GroupAvatarUpdate struct { func (x *GroupAvatarUpdate) Reset() { *x = GroupAvatarUpdate{} - mi := &file_backuppb_Backup_proto_msgTypes[46] + mi := &file_backuppb_Backup_proto_msgTypes[47] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6282,7 +6334,7 @@ func (x *GroupAvatarUpdate) String() string { func (*GroupAvatarUpdate) ProtoMessage() {} func (x *GroupAvatarUpdate) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[46] + mi := &file_backuppb_Backup_proto_msgTypes[47] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6295,7 +6347,7 @@ func (x *GroupAvatarUpdate) ProtoReflect() protoreflect.Message { // Deprecated: Use GroupAvatarUpdate.ProtoReflect.Descriptor instead. func (*GroupAvatarUpdate) Descriptor() ([]byte, []int) { - return file_backuppb_Backup_proto_rawDescGZIP(), []int{46} + return file_backuppb_Backup_proto_rawDescGZIP(), []int{47} } func (x *GroupAvatarUpdate) GetUpdaterAci() []byte { @@ -6323,7 +6375,7 @@ type GroupDescriptionUpdate struct { func (x *GroupDescriptionUpdate) Reset() { *x = GroupDescriptionUpdate{} - mi := &file_backuppb_Backup_proto_msgTypes[47] + mi := &file_backuppb_Backup_proto_msgTypes[48] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6335,7 +6387,7 @@ func (x *GroupDescriptionUpdate) String() string { func (*GroupDescriptionUpdate) ProtoMessage() {} func (x *GroupDescriptionUpdate) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[47] + mi := &file_backuppb_Backup_proto_msgTypes[48] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6348,7 +6400,7 @@ func (x *GroupDescriptionUpdate) ProtoReflect() protoreflect.Message { // Deprecated: Use GroupDescriptionUpdate.ProtoReflect.Descriptor instead. func (*GroupDescriptionUpdate) Descriptor() ([]byte, []int) { - return file_backuppb_Backup_proto_rawDescGZIP(), []int{47} + return file_backuppb_Backup_proto_rawDescGZIP(), []int{48} } func (x *GroupDescriptionUpdate) GetUpdaterAci() []byte { @@ -6375,7 +6427,7 @@ type GroupMembershipAccessLevelChangeUpdate struct { func (x *GroupMembershipAccessLevelChangeUpdate) Reset() { *x = GroupMembershipAccessLevelChangeUpdate{} - mi := &file_backuppb_Backup_proto_msgTypes[48] + mi := &file_backuppb_Backup_proto_msgTypes[49] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6387,7 +6439,7 @@ func (x *GroupMembershipAccessLevelChangeUpdate) String() string { func (*GroupMembershipAccessLevelChangeUpdate) ProtoMessage() {} func (x *GroupMembershipAccessLevelChangeUpdate) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[48] + mi := &file_backuppb_Backup_proto_msgTypes[49] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6400,7 +6452,7 @@ func (x *GroupMembershipAccessLevelChangeUpdate) ProtoReflect() protoreflect.Mes // Deprecated: Use GroupMembershipAccessLevelChangeUpdate.ProtoReflect.Descriptor instead. func (*GroupMembershipAccessLevelChangeUpdate) Descriptor() ([]byte, []int) { - return file_backuppb_Backup_proto_rawDescGZIP(), []int{48} + return file_backuppb_Backup_proto_rawDescGZIP(), []int{49} } func (x *GroupMembershipAccessLevelChangeUpdate) GetUpdaterAci() []byte { @@ -6427,7 +6479,7 @@ type GroupAttributesAccessLevelChangeUpdate struct { func (x *GroupAttributesAccessLevelChangeUpdate) Reset() { *x = GroupAttributesAccessLevelChangeUpdate{} - mi := &file_backuppb_Backup_proto_msgTypes[49] + mi := &file_backuppb_Backup_proto_msgTypes[50] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6439,7 +6491,7 @@ func (x *GroupAttributesAccessLevelChangeUpdate) String() string { func (*GroupAttributesAccessLevelChangeUpdate) ProtoMessage() {} func (x *GroupAttributesAccessLevelChangeUpdate) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[49] + mi := &file_backuppb_Backup_proto_msgTypes[50] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6452,7 +6504,7 @@ func (x *GroupAttributesAccessLevelChangeUpdate) ProtoReflect() protoreflect.Mes // Deprecated: Use GroupAttributesAccessLevelChangeUpdate.ProtoReflect.Descriptor instead. func (*GroupAttributesAccessLevelChangeUpdate) Descriptor() ([]byte, []int) { - return file_backuppb_Backup_proto_rawDescGZIP(), []int{49} + return file_backuppb_Backup_proto_rawDescGZIP(), []int{50} } func (x *GroupAttributesAccessLevelChangeUpdate) GetUpdaterAci() []byte { @@ -6469,6 +6521,102 @@ func (x *GroupAttributesAccessLevelChangeUpdate) GetAccessLevel() GroupV2AccessL return GroupV2AccessLevel_UNKNOWN } +type GroupMemberLabelAccessLevelChangeUpdate struct { + state protoimpl.MessageState `protogen:"open.v1"` + UpdaterAci []byte `protobuf:"bytes,1,opt,name=updaterAci,proto3,oneof" json:"updaterAci,omitempty"` + AccessLevel GroupV2AccessLevel `protobuf:"varint,2,opt,name=accessLevel,proto3,enum=signal.backup.GroupV2AccessLevel" json:"accessLevel,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *GroupMemberLabelAccessLevelChangeUpdate) Reset() { + *x = GroupMemberLabelAccessLevelChangeUpdate{} + mi := &file_backuppb_Backup_proto_msgTypes[51] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *GroupMemberLabelAccessLevelChangeUpdate) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GroupMemberLabelAccessLevelChangeUpdate) ProtoMessage() {} + +func (x *GroupMemberLabelAccessLevelChangeUpdate) ProtoReflect() protoreflect.Message { + mi := &file_backuppb_Backup_proto_msgTypes[51] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GroupMemberLabelAccessLevelChangeUpdate.ProtoReflect.Descriptor instead. +func (*GroupMemberLabelAccessLevelChangeUpdate) Descriptor() ([]byte, []int) { + return file_backuppb_Backup_proto_rawDescGZIP(), []int{51} +} + +func (x *GroupMemberLabelAccessLevelChangeUpdate) GetUpdaterAci() []byte { + if x != nil { + return x.UpdaterAci + } + return nil +} + +func (x *GroupMemberLabelAccessLevelChangeUpdate) GetAccessLevel() GroupV2AccessLevel { + if x != nil { + return x.AccessLevel + } + return GroupV2AccessLevel_UNKNOWN +} + +type GroupTerminateChangeUpdate struct { + state protoimpl.MessageState `protogen:"open.v1"` + UpdaterAci []byte `protobuf:"bytes,1,opt,name=updaterAci,proto3,oneof" json:"updaterAci,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *GroupTerminateChangeUpdate) Reset() { + *x = GroupTerminateChangeUpdate{} + mi := &file_backuppb_Backup_proto_msgTypes[52] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *GroupTerminateChangeUpdate) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GroupTerminateChangeUpdate) ProtoMessage() {} + +func (x *GroupTerminateChangeUpdate) ProtoReflect() protoreflect.Message { + mi := &file_backuppb_Backup_proto_msgTypes[52] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GroupTerminateChangeUpdate.ProtoReflect.Descriptor instead. +func (*GroupTerminateChangeUpdate) Descriptor() ([]byte, []int) { + return file_backuppb_Backup_proto_rawDescGZIP(), []int{52} +} + +func (x *GroupTerminateChangeUpdate) GetUpdaterAci() []byte { + if x != nil { + return x.UpdaterAci + } + return nil +} + type GroupAnnouncementOnlyChangeUpdate struct { state protoimpl.MessageState `protogen:"open.v1"` UpdaterAci []byte `protobuf:"bytes,1,opt,name=updaterAci,proto3,oneof" json:"updaterAci,omitempty"` @@ -6479,7 +6627,7 @@ type GroupAnnouncementOnlyChangeUpdate struct { func (x *GroupAnnouncementOnlyChangeUpdate) Reset() { *x = GroupAnnouncementOnlyChangeUpdate{} - mi := &file_backuppb_Backup_proto_msgTypes[50] + mi := &file_backuppb_Backup_proto_msgTypes[53] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6491,7 +6639,7 @@ func (x *GroupAnnouncementOnlyChangeUpdate) String() string { func (*GroupAnnouncementOnlyChangeUpdate) ProtoMessage() {} func (x *GroupAnnouncementOnlyChangeUpdate) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[50] + mi := &file_backuppb_Backup_proto_msgTypes[53] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6504,7 +6652,7 @@ func (x *GroupAnnouncementOnlyChangeUpdate) ProtoReflect() protoreflect.Message // Deprecated: Use GroupAnnouncementOnlyChangeUpdate.ProtoReflect.Descriptor instead. func (*GroupAnnouncementOnlyChangeUpdate) Descriptor() ([]byte, []int) { - return file_backuppb_Backup_proto_rawDescGZIP(), []int{50} + return file_backuppb_Backup_proto_rawDescGZIP(), []int{53} } func (x *GroupAnnouncementOnlyChangeUpdate) GetUpdaterAci() []byte { @@ -6533,7 +6681,7 @@ type GroupAdminStatusUpdate struct { func (x *GroupAdminStatusUpdate) Reset() { *x = GroupAdminStatusUpdate{} - mi := &file_backuppb_Backup_proto_msgTypes[51] + mi := &file_backuppb_Backup_proto_msgTypes[54] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6545,7 +6693,7 @@ func (x *GroupAdminStatusUpdate) String() string { func (*GroupAdminStatusUpdate) ProtoMessage() {} func (x *GroupAdminStatusUpdate) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[51] + mi := &file_backuppb_Backup_proto_msgTypes[54] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6558,7 +6706,7 @@ func (x *GroupAdminStatusUpdate) ProtoReflect() protoreflect.Message { // Deprecated: Use GroupAdminStatusUpdate.ProtoReflect.Descriptor instead. func (*GroupAdminStatusUpdate) Descriptor() ([]byte, []int) { - return file_backuppb_Backup_proto_rawDescGZIP(), []int{51} + return file_backuppb_Backup_proto_rawDescGZIP(), []int{54} } func (x *GroupAdminStatusUpdate) GetUpdaterAci() []byte { @@ -6591,7 +6739,7 @@ type GroupMemberLeftUpdate struct { func (x *GroupMemberLeftUpdate) Reset() { *x = GroupMemberLeftUpdate{} - mi := &file_backuppb_Backup_proto_msgTypes[52] + mi := &file_backuppb_Backup_proto_msgTypes[55] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6603,7 +6751,7 @@ func (x *GroupMemberLeftUpdate) String() string { func (*GroupMemberLeftUpdate) ProtoMessage() {} func (x *GroupMemberLeftUpdate) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[52] + mi := &file_backuppb_Backup_proto_msgTypes[55] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6616,7 +6764,7 @@ func (x *GroupMemberLeftUpdate) ProtoReflect() protoreflect.Message { // Deprecated: Use GroupMemberLeftUpdate.ProtoReflect.Descriptor instead. func (*GroupMemberLeftUpdate) Descriptor() ([]byte, []int) { - return file_backuppb_Backup_proto_rawDescGZIP(), []int{52} + return file_backuppb_Backup_proto_rawDescGZIP(), []int{55} } func (x *GroupMemberLeftUpdate) GetAci() []byte { @@ -6636,7 +6784,7 @@ type GroupMemberRemovedUpdate struct { func (x *GroupMemberRemovedUpdate) Reset() { *x = GroupMemberRemovedUpdate{} - mi := &file_backuppb_Backup_proto_msgTypes[53] + mi := &file_backuppb_Backup_proto_msgTypes[56] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6648,7 +6796,7 @@ func (x *GroupMemberRemovedUpdate) String() string { func (*GroupMemberRemovedUpdate) ProtoMessage() {} func (x *GroupMemberRemovedUpdate) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[53] + mi := &file_backuppb_Backup_proto_msgTypes[56] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6661,7 +6809,7 @@ func (x *GroupMemberRemovedUpdate) ProtoReflect() protoreflect.Message { // Deprecated: Use GroupMemberRemovedUpdate.ProtoReflect.Descriptor instead. func (*GroupMemberRemovedUpdate) Descriptor() ([]byte, []int) { - return file_backuppb_Backup_proto_rawDescGZIP(), []int{53} + return file_backuppb_Backup_proto_rawDescGZIP(), []int{56} } func (x *GroupMemberRemovedUpdate) GetRemoverAci() []byte { @@ -6687,7 +6835,7 @@ type SelfInvitedToGroupUpdate struct { func (x *SelfInvitedToGroupUpdate) Reset() { *x = SelfInvitedToGroupUpdate{} - mi := &file_backuppb_Backup_proto_msgTypes[54] + mi := &file_backuppb_Backup_proto_msgTypes[57] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6699,7 +6847,7 @@ func (x *SelfInvitedToGroupUpdate) String() string { func (*SelfInvitedToGroupUpdate) ProtoMessage() {} func (x *SelfInvitedToGroupUpdate) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[54] + mi := &file_backuppb_Backup_proto_msgTypes[57] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6712,7 +6860,7 @@ func (x *SelfInvitedToGroupUpdate) ProtoReflect() protoreflect.Message { // Deprecated: Use SelfInvitedToGroupUpdate.ProtoReflect.Descriptor instead. func (*SelfInvitedToGroupUpdate) Descriptor() ([]byte, []int) { - return file_backuppb_Backup_proto_rawDescGZIP(), []int{54} + return file_backuppb_Backup_proto_rawDescGZIP(), []int{57} } func (x *SelfInvitedToGroupUpdate) GetInviterAci() []byte { @@ -6732,7 +6880,7 @@ type SelfInvitedOtherUserToGroupUpdate struct { func (x *SelfInvitedOtherUserToGroupUpdate) Reset() { *x = SelfInvitedOtherUserToGroupUpdate{} - mi := &file_backuppb_Backup_proto_msgTypes[55] + mi := &file_backuppb_Backup_proto_msgTypes[58] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6744,7 +6892,7 @@ func (x *SelfInvitedOtherUserToGroupUpdate) String() string { func (*SelfInvitedOtherUserToGroupUpdate) ProtoMessage() {} func (x *SelfInvitedOtherUserToGroupUpdate) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[55] + mi := &file_backuppb_Backup_proto_msgTypes[58] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6757,7 +6905,7 @@ func (x *SelfInvitedOtherUserToGroupUpdate) ProtoReflect() protoreflect.Message // Deprecated: Use SelfInvitedOtherUserToGroupUpdate.ProtoReflect.Descriptor instead. func (*SelfInvitedOtherUserToGroupUpdate) Descriptor() ([]byte, []int) { - return file_backuppb_Backup_proto_rawDescGZIP(), []int{55} + return file_backuppb_Backup_proto_rawDescGZIP(), []int{58} } func (x *SelfInvitedOtherUserToGroupUpdate) GetInviteeServiceId() []byte { @@ -6778,7 +6926,7 @@ type GroupUnknownInviteeUpdate struct { func (x *GroupUnknownInviteeUpdate) Reset() { *x = GroupUnknownInviteeUpdate{} - mi := &file_backuppb_Backup_proto_msgTypes[56] + mi := &file_backuppb_Backup_proto_msgTypes[59] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6790,7 +6938,7 @@ func (x *GroupUnknownInviteeUpdate) String() string { func (*GroupUnknownInviteeUpdate) ProtoMessage() {} func (x *GroupUnknownInviteeUpdate) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[56] + mi := &file_backuppb_Backup_proto_msgTypes[59] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6803,7 +6951,7 @@ func (x *GroupUnknownInviteeUpdate) ProtoReflect() protoreflect.Message { // Deprecated: Use GroupUnknownInviteeUpdate.ProtoReflect.Descriptor instead. func (*GroupUnknownInviteeUpdate) Descriptor() ([]byte, []int) { - return file_backuppb_Backup_proto_rawDescGZIP(), []int{56} + return file_backuppb_Backup_proto_rawDescGZIP(), []int{59} } func (x *GroupUnknownInviteeUpdate) GetInviterAci() []byte { @@ -6830,7 +6978,7 @@ type GroupInvitationAcceptedUpdate struct { func (x *GroupInvitationAcceptedUpdate) Reset() { *x = GroupInvitationAcceptedUpdate{} - mi := &file_backuppb_Backup_proto_msgTypes[57] + mi := &file_backuppb_Backup_proto_msgTypes[60] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6842,7 +6990,7 @@ func (x *GroupInvitationAcceptedUpdate) String() string { func (*GroupInvitationAcceptedUpdate) ProtoMessage() {} func (x *GroupInvitationAcceptedUpdate) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[57] + mi := &file_backuppb_Backup_proto_msgTypes[60] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6855,7 +7003,7 @@ func (x *GroupInvitationAcceptedUpdate) ProtoReflect() protoreflect.Message { // Deprecated: Use GroupInvitationAcceptedUpdate.ProtoReflect.Descriptor instead. func (*GroupInvitationAcceptedUpdate) Descriptor() ([]byte, []int) { - return file_backuppb_Backup_proto_rawDescGZIP(), []int{57} + return file_backuppb_Backup_proto_rawDescGZIP(), []int{60} } func (x *GroupInvitationAcceptedUpdate) GetInviterAci() []byte { @@ -6883,7 +7031,7 @@ type GroupInvitationDeclinedUpdate struct { func (x *GroupInvitationDeclinedUpdate) Reset() { *x = GroupInvitationDeclinedUpdate{} - mi := &file_backuppb_Backup_proto_msgTypes[58] + mi := &file_backuppb_Backup_proto_msgTypes[61] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6895,7 +7043,7 @@ func (x *GroupInvitationDeclinedUpdate) String() string { func (*GroupInvitationDeclinedUpdate) ProtoMessage() {} func (x *GroupInvitationDeclinedUpdate) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[58] + mi := &file_backuppb_Backup_proto_msgTypes[61] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6908,7 +7056,7 @@ func (x *GroupInvitationDeclinedUpdate) ProtoReflect() protoreflect.Message { // Deprecated: Use GroupInvitationDeclinedUpdate.ProtoReflect.Descriptor instead. func (*GroupInvitationDeclinedUpdate) Descriptor() ([]byte, []int) { - return file_backuppb_Backup_proto_rawDescGZIP(), []int{58} + return file_backuppb_Backup_proto_rawDescGZIP(), []int{61} } func (x *GroupInvitationDeclinedUpdate) GetInviterAci() []byte { @@ -6934,7 +7082,7 @@ type GroupMemberJoinedUpdate struct { func (x *GroupMemberJoinedUpdate) Reset() { *x = GroupMemberJoinedUpdate{} - mi := &file_backuppb_Backup_proto_msgTypes[59] + mi := &file_backuppb_Backup_proto_msgTypes[62] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6946,7 +7094,7 @@ func (x *GroupMemberJoinedUpdate) String() string { func (*GroupMemberJoinedUpdate) ProtoMessage() {} func (x *GroupMemberJoinedUpdate) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[59] + mi := &file_backuppb_Backup_proto_msgTypes[62] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6959,7 +7107,7 @@ func (x *GroupMemberJoinedUpdate) ProtoReflect() protoreflect.Message { // Deprecated: Use GroupMemberJoinedUpdate.ProtoReflect.Descriptor instead. func (*GroupMemberJoinedUpdate) Descriptor() ([]byte, []int) { - return file_backuppb_Backup_proto_rawDescGZIP(), []int{59} + return file_backuppb_Backup_proto_rawDescGZIP(), []int{62} } func (x *GroupMemberJoinedUpdate) GetNewMemberAci() []byte { @@ -6982,7 +7130,7 @@ type GroupMemberAddedUpdate struct { func (x *GroupMemberAddedUpdate) Reset() { *x = GroupMemberAddedUpdate{} - mi := &file_backuppb_Backup_proto_msgTypes[60] + mi := &file_backuppb_Backup_proto_msgTypes[63] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6994,7 +7142,7 @@ func (x *GroupMemberAddedUpdate) String() string { func (*GroupMemberAddedUpdate) ProtoMessage() {} func (x *GroupMemberAddedUpdate) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[60] + mi := &file_backuppb_Backup_proto_msgTypes[63] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7007,7 +7155,7 @@ func (x *GroupMemberAddedUpdate) ProtoReflect() protoreflect.Message { // Deprecated: Use GroupMemberAddedUpdate.ProtoReflect.Descriptor instead. func (*GroupMemberAddedUpdate) Descriptor() ([]byte, []int) { - return file_backuppb_Backup_proto_rawDescGZIP(), []int{60} + return file_backuppb_Backup_proto_rawDescGZIP(), []int{63} } func (x *GroupMemberAddedUpdate) GetUpdaterAci() []byte { @@ -7048,7 +7196,7 @@ type GroupSelfInvitationRevokedUpdate struct { func (x *GroupSelfInvitationRevokedUpdate) Reset() { *x = GroupSelfInvitationRevokedUpdate{} - mi := &file_backuppb_Backup_proto_msgTypes[61] + mi := &file_backuppb_Backup_proto_msgTypes[64] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7060,7 +7208,7 @@ func (x *GroupSelfInvitationRevokedUpdate) String() string { func (*GroupSelfInvitationRevokedUpdate) ProtoMessage() {} func (x *GroupSelfInvitationRevokedUpdate) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[61] + mi := &file_backuppb_Backup_proto_msgTypes[64] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7073,7 +7221,7 @@ func (x *GroupSelfInvitationRevokedUpdate) ProtoReflect() protoreflect.Message { // Deprecated: Use GroupSelfInvitationRevokedUpdate.ProtoReflect.Descriptor instead. func (*GroupSelfInvitationRevokedUpdate) Descriptor() ([]byte, []int) { - return file_backuppb_Backup_proto_rawDescGZIP(), []int{61} + return file_backuppb_Backup_proto_rawDescGZIP(), []int{64} } func (x *GroupSelfInvitationRevokedUpdate) GetRevokerAci() []byte { @@ -7099,7 +7247,7 @@ type GroupInvitationRevokedUpdate struct { func (x *GroupInvitationRevokedUpdate) Reset() { *x = GroupInvitationRevokedUpdate{} - mi := &file_backuppb_Backup_proto_msgTypes[62] + mi := &file_backuppb_Backup_proto_msgTypes[65] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7111,7 +7259,7 @@ func (x *GroupInvitationRevokedUpdate) String() string { func (*GroupInvitationRevokedUpdate) ProtoMessage() {} func (x *GroupInvitationRevokedUpdate) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[62] + mi := &file_backuppb_Backup_proto_msgTypes[65] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7124,7 +7272,7 @@ func (x *GroupInvitationRevokedUpdate) ProtoReflect() protoreflect.Message { // Deprecated: Use GroupInvitationRevokedUpdate.ProtoReflect.Descriptor instead. func (*GroupInvitationRevokedUpdate) Descriptor() ([]byte, []int) { - return file_backuppb_Backup_proto_rawDescGZIP(), []int{62} + return file_backuppb_Backup_proto_rawDescGZIP(), []int{65} } func (x *GroupInvitationRevokedUpdate) GetUpdaterAci() []byte { @@ -7150,7 +7298,7 @@ type GroupJoinRequestUpdate struct { func (x *GroupJoinRequestUpdate) Reset() { *x = GroupJoinRequestUpdate{} - mi := &file_backuppb_Backup_proto_msgTypes[63] + mi := &file_backuppb_Backup_proto_msgTypes[66] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7162,7 +7310,7 @@ func (x *GroupJoinRequestUpdate) String() string { func (*GroupJoinRequestUpdate) ProtoMessage() {} func (x *GroupJoinRequestUpdate) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[63] + mi := &file_backuppb_Backup_proto_msgTypes[66] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7175,7 +7323,7 @@ func (x *GroupJoinRequestUpdate) ProtoReflect() protoreflect.Message { // Deprecated: Use GroupJoinRequestUpdate.ProtoReflect.Descriptor instead. func (*GroupJoinRequestUpdate) Descriptor() ([]byte, []int) { - return file_backuppb_Backup_proto_rawDescGZIP(), []int{63} + return file_backuppb_Backup_proto_rawDescGZIP(), []int{66} } func (x *GroupJoinRequestUpdate) GetRequestorAci() []byte { @@ -7197,7 +7345,7 @@ type GroupJoinRequestApprovalUpdate struct { func (x *GroupJoinRequestApprovalUpdate) Reset() { *x = GroupJoinRequestApprovalUpdate{} - mi := &file_backuppb_Backup_proto_msgTypes[64] + mi := &file_backuppb_Backup_proto_msgTypes[67] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7209,7 +7357,7 @@ func (x *GroupJoinRequestApprovalUpdate) String() string { func (*GroupJoinRequestApprovalUpdate) ProtoMessage() {} func (x *GroupJoinRequestApprovalUpdate) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[64] + mi := &file_backuppb_Backup_proto_msgTypes[67] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7222,7 +7370,7 @@ func (x *GroupJoinRequestApprovalUpdate) ProtoReflect() protoreflect.Message { // Deprecated: Use GroupJoinRequestApprovalUpdate.ProtoReflect.Descriptor instead. func (*GroupJoinRequestApprovalUpdate) Descriptor() ([]byte, []int) { - return file_backuppb_Backup_proto_rawDescGZIP(), []int{64} + return file_backuppb_Backup_proto_rawDescGZIP(), []int{67} } func (x *GroupJoinRequestApprovalUpdate) GetRequestorAci() []byte { @@ -7255,7 +7403,7 @@ type GroupJoinRequestCanceledUpdate struct { func (x *GroupJoinRequestCanceledUpdate) Reset() { *x = GroupJoinRequestCanceledUpdate{} - mi := &file_backuppb_Backup_proto_msgTypes[65] + mi := &file_backuppb_Backup_proto_msgTypes[68] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7267,7 +7415,7 @@ func (x *GroupJoinRequestCanceledUpdate) String() string { func (*GroupJoinRequestCanceledUpdate) ProtoMessage() {} func (x *GroupJoinRequestCanceledUpdate) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[65] + mi := &file_backuppb_Backup_proto_msgTypes[68] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7280,7 +7428,7 @@ func (x *GroupJoinRequestCanceledUpdate) ProtoReflect() protoreflect.Message { // Deprecated: Use GroupJoinRequestCanceledUpdate.ProtoReflect.Descriptor instead. func (*GroupJoinRequestCanceledUpdate) Descriptor() ([]byte, []int) { - return file_backuppb_Backup_proto_rawDescGZIP(), []int{65} + return file_backuppb_Backup_proto_rawDescGZIP(), []int{68} } func (x *GroupJoinRequestCanceledUpdate) GetRequestorAci() []byte { @@ -7306,7 +7454,7 @@ type GroupSequenceOfRequestsAndCancelsUpdate struct { func (x *GroupSequenceOfRequestsAndCancelsUpdate) Reset() { *x = GroupSequenceOfRequestsAndCancelsUpdate{} - mi := &file_backuppb_Backup_proto_msgTypes[66] + mi := &file_backuppb_Backup_proto_msgTypes[69] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7318,7 +7466,7 @@ func (x *GroupSequenceOfRequestsAndCancelsUpdate) String() string { func (*GroupSequenceOfRequestsAndCancelsUpdate) ProtoMessage() {} func (x *GroupSequenceOfRequestsAndCancelsUpdate) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[66] + mi := &file_backuppb_Backup_proto_msgTypes[69] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7331,7 +7479,7 @@ func (x *GroupSequenceOfRequestsAndCancelsUpdate) ProtoReflect() protoreflect.Me // Deprecated: Use GroupSequenceOfRequestsAndCancelsUpdate.ProtoReflect.Descriptor instead. func (*GroupSequenceOfRequestsAndCancelsUpdate) Descriptor() ([]byte, []int) { - return file_backuppb_Backup_proto_rawDescGZIP(), []int{66} + return file_backuppb_Backup_proto_rawDescGZIP(), []int{69} } func (x *GroupSequenceOfRequestsAndCancelsUpdate) GetRequestorAci() []byte { @@ -7357,7 +7505,7 @@ type GroupInviteLinkResetUpdate struct { func (x *GroupInviteLinkResetUpdate) Reset() { *x = GroupInviteLinkResetUpdate{} - mi := &file_backuppb_Backup_proto_msgTypes[67] + mi := &file_backuppb_Backup_proto_msgTypes[70] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7369,7 +7517,7 @@ func (x *GroupInviteLinkResetUpdate) String() string { func (*GroupInviteLinkResetUpdate) ProtoMessage() {} func (x *GroupInviteLinkResetUpdate) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[67] + mi := &file_backuppb_Backup_proto_msgTypes[70] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7382,7 +7530,7 @@ func (x *GroupInviteLinkResetUpdate) ProtoReflect() protoreflect.Message { // Deprecated: Use GroupInviteLinkResetUpdate.ProtoReflect.Descriptor instead. func (*GroupInviteLinkResetUpdate) Descriptor() ([]byte, []int) { - return file_backuppb_Backup_proto_rawDescGZIP(), []int{67} + return file_backuppb_Backup_proto_rawDescGZIP(), []int{70} } func (x *GroupInviteLinkResetUpdate) GetUpdaterAci() []byte { @@ -7402,7 +7550,7 @@ type GroupInviteLinkEnabledUpdate struct { func (x *GroupInviteLinkEnabledUpdate) Reset() { *x = GroupInviteLinkEnabledUpdate{} - mi := &file_backuppb_Backup_proto_msgTypes[68] + mi := &file_backuppb_Backup_proto_msgTypes[71] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7414,7 +7562,7 @@ func (x *GroupInviteLinkEnabledUpdate) String() string { func (*GroupInviteLinkEnabledUpdate) ProtoMessage() {} func (x *GroupInviteLinkEnabledUpdate) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[68] + mi := &file_backuppb_Backup_proto_msgTypes[71] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7427,7 +7575,7 @@ func (x *GroupInviteLinkEnabledUpdate) ProtoReflect() protoreflect.Message { // Deprecated: Use GroupInviteLinkEnabledUpdate.ProtoReflect.Descriptor instead. func (*GroupInviteLinkEnabledUpdate) Descriptor() ([]byte, []int) { - return file_backuppb_Backup_proto_rawDescGZIP(), []int{68} + return file_backuppb_Backup_proto_rawDescGZIP(), []int{71} } func (x *GroupInviteLinkEnabledUpdate) GetUpdaterAci() []byte { @@ -7454,7 +7602,7 @@ type GroupInviteLinkAdminApprovalUpdate struct { func (x *GroupInviteLinkAdminApprovalUpdate) Reset() { *x = GroupInviteLinkAdminApprovalUpdate{} - mi := &file_backuppb_Backup_proto_msgTypes[69] + mi := &file_backuppb_Backup_proto_msgTypes[72] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7466,7 +7614,7 @@ func (x *GroupInviteLinkAdminApprovalUpdate) String() string { func (*GroupInviteLinkAdminApprovalUpdate) ProtoMessage() {} func (x *GroupInviteLinkAdminApprovalUpdate) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[69] + mi := &file_backuppb_Backup_proto_msgTypes[72] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7479,7 +7627,7 @@ func (x *GroupInviteLinkAdminApprovalUpdate) ProtoReflect() protoreflect.Message // Deprecated: Use GroupInviteLinkAdminApprovalUpdate.ProtoReflect.Descriptor instead. func (*GroupInviteLinkAdminApprovalUpdate) Descriptor() ([]byte, []int) { - return file_backuppb_Backup_proto_rawDescGZIP(), []int{69} + return file_backuppb_Backup_proto_rawDescGZIP(), []int{72} } func (x *GroupInviteLinkAdminApprovalUpdate) GetUpdaterAci() []byte { @@ -7505,7 +7653,7 @@ type GroupInviteLinkDisabledUpdate struct { func (x *GroupInviteLinkDisabledUpdate) Reset() { *x = GroupInviteLinkDisabledUpdate{} - mi := &file_backuppb_Backup_proto_msgTypes[70] + mi := &file_backuppb_Backup_proto_msgTypes[73] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7517,7 +7665,7 @@ func (x *GroupInviteLinkDisabledUpdate) String() string { func (*GroupInviteLinkDisabledUpdate) ProtoMessage() {} func (x *GroupInviteLinkDisabledUpdate) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[70] + mi := &file_backuppb_Backup_proto_msgTypes[73] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7530,7 +7678,7 @@ func (x *GroupInviteLinkDisabledUpdate) ProtoReflect() protoreflect.Message { // Deprecated: Use GroupInviteLinkDisabledUpdate.ProtoReflect.Descriptor instead. func (*GroupInviteLinkDisabledUpdate) Descriptor() ([]byte, []int) { - return file_backuppb_Backup_proto_rawDescGZIP(), []int{70} + return file_backuppb_Backup_proto_rawDescGZIP(), []int{73} } func (x *GroupInviteLinkDisabledUpdate) GetUpdaterAci() []byte { @@ -7549,7 +7697,7 @@ type GroupMemberJoinedByLinkUpdate struct { func (x *GroupMemberJoinedByLinkUpdate) Reset() { *x = GroupMemberJoinedByLinkUpdate{} - mi := &file_backuppb_Backup_proto_msgTypes[71] + mi := &file_backuppb_Backup_proto_msgTypes[74] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7561,7 +7709,7 @@ func (x *GroupMemberJoinedByLinkUpdate) String() string { func (*GroupMemberJoinedByLinkUpdate) ProtoMessage() {} func (x *GroupMemberJoinedByLinkUpdate) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[71] + mi := &file_backuppb_Backup_proto_msgTypes[74] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7574,7 +7722,7 @@ func (x *GroupMemberJoinedByLinkUpdate) ProtoReflect() protoreflect.Message { // Deprecated: Use GroupMemberJoinedByLinkUpdate.ProtoReflect.Descriptor instead. func (*GroupMemberJoinedByLinkUpdate) Descriptor() ([]byte, []int) { - return file_backuppb_Backup_proto_rawDescGZIP(), []int{71} + return file_backuppb_Backup_proto_rawDescGZIP(), []int{74} } func (x *GroupMemberJoinedByLinkUpdate) GetNewMemberAci() []byte { @@ -7593,7 +7741,7 @@ type GroupV2MigrationUpdate struct { func (x *GroupV2MigrationUpdate) Reset() { *x = GroupV2MigrationUpdate{} - mi := &file_backuppb_Backup_proto_msgTypes[72] + mi := &file_backuppb_Backup_proto_msgTypes[75] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7605,7 +7753,7 @@ func (x *GroupV2MigrationUpdate) String() string { func (*GroupV2MigrationUpdate) ProtoMessage() {} func (x *GroupV2MigrationUpdate) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[72] + mi := &file_backuppb_Backup_proto_msgTypes[75] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7618,7 +7766,7 @@ func (x *GroupV2MigrationUpdate) ProtoReflect() protoreflect.Message { // Deprecated: Use GroupV2MigrationUpdate.ProtoReflect.Descriptor instead. func (*GroupV2MigrationUpdate) Descriptor() ([]byte, []int) { - return file_backuppb_Backup_proto_rawDescGZIP(), []int{72} + return file_backuppb_Backup_proto_rawDescGZIP(), []int{75} } // Another user migrated gv1->gv2 but was unable to add @@ -7631,7 +7779,7 @@ type GroupV2MigrationSelfInvitedUpdate struct { func (x *GroupV2MigrationSelfInvitedUpdate) Reset() { *x = GroupV2MigrationSelfInvitedUpdate{} - mi := &file_backuppb_Backup_proto_msgTypes[73] + mi := &file_backuppb_Backup_proto_msgTypes[76] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7643,7 +7791,7 @@ func (x *GroupV2MigrationSelfInvitedUpdate) String() string { func (*GroupV2MigrationSelfInvitedUpdate) ProtoMessage() {} func (x *GroupV2MigrationSelfInvitedUpdate) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[73] + mi := &file_backuppb_Backup_proto_msgTypes[76] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7656,7 +7804,7 @@ func (x *GroupV2MigrationSelfInvitedUpdate) ProtoReflect() protoreflect.Message // Deprecated: Use GroupV2MigrationSelfInvitedUpdate.ProtoReflect.Descriptor instead. func (*GroupV2MigrationSelfInvitedUpdate) Descriptor() ([]byte, []int) { - return file_backuppb_Backup_proto_rawDescGZIP(), []int{73} + return file_backuppb_Backup_proto_rawDescGZIP(), []int{76} } // The local user migrated gv1->gv2 but was unable to @@ -7671,7 +7819,7 @@ type GroupV2MigrationInvitedMembersUpdate struct { func (x *GroupV2MigrationInvitedMembersUpdate) Reset() { *x = GroupV2MigrationInvitedMembersUpdate{} - mi := &file_backuppb_Backup_proto_msgTypes[74] + mi := &file_backuppb_Backup_proto_msgTypes[77] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7683,7 +7831,7 @@ func (x *GroupV2MigrationInvitedMembersUpdate) String() string { func (*GroupV2MigrationInvitedMembersUpdate) ProtoMessage() {} func (x *GroupV2MigrationInvitedMembersUpdate) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[74] + mi := &file_backuppb_Backup_proto_msgTypes[77] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7696,7 +7844,7 @@ func (x *GroupV2MigrationInvitedMembersUpdate) ProtoReflect() protoreflect.Messa // Deprecated: Use GroupV2MigrationInvitedMembersUpdate.ProtoReflect.Descriptor instead. func (*GroupV2MigrationInvitedMembersUpdate) Descriptor() ([]byte, []int) { - return file_backuppb_Backup_proto_rawDescGZIP(), []int{74} + return file_backuppb_Backup_proto_rawDescGZIP(), []int{77} } func (x *GroupV2MigrationInvitedMembersUpdate) GetInvitedMembersCount() uint32 { @@ -7718,7 +7866,7 @@ type GroupV2MigrationDroppedMembersUpdate struct { func (x *GroupV2MigrationDroppedMembersUpdate) Reset() { *x = GroupV2MigrationDroppedMembersUpdate{} - mi := &file_backuppb_Backup_proto_msgTypes[75] + mi := &file_backuppb_Backup_proto_msgTypes[78] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7730,7 +7878,7 @@ func (x *GroupV2MigrationDroppedMembersUpdate) String() string { func (*GroupV2MigrationDroppedMembersUpdate) ProtoMessage() {} func (x *GroupV2MigrationDroppedMembersUpdate) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[75] + mi := &file_backuppb_Backup_proto_msgTypes[78] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7743,7 +7891,7 @@ func (x *GroupV2MigrationDroppedMembersUpdate) ProtoReflect() protoreflect.Messa // Deprecated: Use GroupV2MigrationDroppedMembersUpdate.ProtoReflect.Descriptor instead. func (*GroupV2MigrationDroppedMembersUpdate) Descriptor() ([]byte, []int) { - return file_backuppb_Backup_proto_rawDescGZIP(), []int{75} + return file_backuppb_Backup_proto_rawDescGZIP(), []int{78} } func (x *GroupV2MigrationDroppedMembersUpdate) GetDroppedMembersCount() uint32 { @@ -7764,7 +7912,7 @@ type GroupExpirationTimerUpdate struct { func (x *GroupExpirationTimerUpdate) Reset() { *x = GroupExpirationTimerUpdate{} - mi := &file_backuppb_Backup_proto_msgTypes[76] + mi := &file_backuppb_Backup_proto_msgTypes[79] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7776,7 +7924,7 @@ func (x *GroupExpirationTimerUpdate) String() string { func (*GroupExpirationTimerUpdate) ProtoMessage() {} func (x *GroupExpirationTimerUpdate) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[76] + mi := &file_backuppb_Backup_proto_msgTypes[79] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7789,7 +7937,7 @@ func (x *GroupExpirationTimerUpdate) ProtoReflect() protoreflect.Message { // Deprecated: Use GroupExpirationTimerUpdate.ProtoReflect.Descriptor instead. func (*GroupExpirationTimerUpdate) Descriptor() ([]byte, []int) { - return file_backuppb_Backup_proto_rawDescGZIP(), []int{76} + return file_backuppb_Backup_proto_rawDescGZIP(), []int{79} } func (x *GroupExpirationTimerUpdate) GetExpiresInMs() uint64 { @@ -7816,7 +7964,7 @@ type PollTerminateUpdate struct { func (x *PollTerminateUpdate) Reset() { *x = PollTerminateUpdate{} - mi := &file_backuppb_Backup_proto_msgTypes[77] + mi := &file_backuppb_Backup_proto_msgTypes[80] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7828,7 +7976,7 @@ func (x *PollTerminateUpdate) String() string { func (*PollTerminateUpdate) ProtoMessage() {} func (x *PollTerminateUpdate) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[77] + mi := &file_backuppb_Backup_proto_msgTypes[80] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7841,7 +7989,7 @@ func (x *PollTerminateUpdate) ProtoReflect() protoreflect.Message { // Deprecated: Use PollTerminateUpdate.ProtoReflect.Descriptor instead. func (*PollTerminateUpdate) Descriptor() ([]byte, []int) { - return file_backuppb_Backup_proto_rawDescGZIP(), []int{77} + return file_backuppb_Backup_proto_rawDescGZIP(), []int{80} } func (x *PollTerminateUpdate) GetTargetSentTimestamp() uint64 { @@ -7868,7 +8016,7 @@ type PinMessageUpdate struct { func (x *PinMessageUpdate) Reset() { *x = PinMessageUpdate{} - mi := &file_backuppb_Backup_proto_msgTypes[78] + mi := &file_backuppb_Backup_proto_msgTypes[81] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7880,7 +8028,7 @@ func (x *PinMessageUpdate) String() string { func (*PinMessageUpdate) ProtoMessage() {} func (x *PinMessageUpdate) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[78] + mi := &file_backuppb_Backup_proto_msgTypes[81] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7893,7 +8041,7 @@ func (x *PinMessageUpdate) ProtoReflect() protoreflect.Message { // Deprecated: Use PinMessageUpdate.ProtoReflect.Descriptor instead. func (*PinMessageUpdate) Descriptor() ([]byte, []int) { - return file_backuppb_Backup_proto_rawDescGZIP(), []int{78} + return file_backuppb_Backup_proto_rawDescGZIP(), []int{81} } func (x *PinMessageUpdate) GetTargetSentTimestamp() uint64 { @@ -7920,7 +8068,7 @@ type StickerPack struct { func (x *StickerPack) Reset() { *x = StickerPack{} - mi := &file_backuppb_Backup_proto_msgTypes[79] + mi := &file_backuppb_Backup_proto_msgTypes[82] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7932,7 +8080,7 @@ func (x *StickerPack) String() string { func (*StickerPack) ProtoMessage() {} func (x *StickerPack) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[79] + mi := &file_backuppb_Backup_proto_msgTypes[82] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7945,7 +8093,7 @@ func (x *StickerPack) ProtoReflect() protoreflect.Message { // Deprecated: Use StickerPack.ProtoReflect.Descriptor instead. func (*StickerPack) Descriptor() ([]byte, []int) { - return file_backuppb_Backup_proto_rawDescGZIP(), []int{79} + return file_backuppb_Backup_proto_rawDescGZIP(), []int{82} } func (x *StickerPack) GetPackId() []byte { @@ -7986,7 +8134,7 @@ type ChatStyle struct { func (x *ChatStyle) Reset() { *x = ChatStyle{} - mi := &file_backuppb_Backup_proto_msgTypes[80] + mi := &file_backuppb_Backup_proto_msgTypes[83] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7998,7 +8146,7 @@ func (x *ChatStyle) String() string { func (*ChatStyle) ProtoMessage() {} func (x *ChatStyle) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[80] + mi := &file_backuppb_Backup_proto_msgTypes[83] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8011,7 +8159,7 @@ func (x *ChatStyle) ProtoReflect() protoreflect.Message { // Deprecated: Use ChatStyle.ProtoReflect.Descriptor instead. func (*ChatStyle) Descriptor() ([]byte, []int) { - return file_backuppb_Backup_proto_rawDescGZIP(), []int{80} + return file_backuppb_Backup_proto_rawDescGZIP(), []int{83} } func (x *ChatStyle) GetWallpaper() isChatStyle_Wallpaper { @@ -8143,7 +8291,7 @@ type NotificationProfile struct { func (x *NotificationProfile) Reset() { *x = NotificationProfile{} - mi := &file_backuppb_Backup_proto_msgTypes[81] + mi := &file_backuppb_Backup_proto_msgTypes[84] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8155,7 +8303,7 @@ func (x *NotificationProfile) String() string { func (*NotificationProfile) ProtoMessage() {} func (x *NotificationProfile) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[81] + mi := &file_backuppb_Backup_proto_msgTypes[84] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8168,7 +8316,7 @@ func (x *NotificationProfile) ProtoReflect() protoreflect.Message { // Deprecated: Use NotificationProfile.ProtoReflect.Descriptor instead. func (*NotificationProfile) Descriptor() ([]byte, []int) { - return file_backuppb_Backup_proto_rawDescGZIP(), []int{81} + return file_backuppb_Backup_proto_rawDescGZIP(), []int{84} } func (x *NotificationProfile) GetName() string { @@ -8274,7 +8422,7 @@ type ChatFolder struct { func (x *ChatFolder) Reset() { *x = ChatFolder{} - mi := &file_backuppb_Backup_proto_msgTypes[82] + mi := &file_backuppb_Backup_proto_msgTypes[85] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8286,7 +8434,7 @@ func (x *ChatFolder) String() string { func (*ChatFolder) ProtoMessage() {} func (x *ChatFolder) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[82] + mi := &file_backuppb_Backup_proto_msgTypes[85] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8299,7 +8447,7 @@ func (x *ChatFolder) ProtoReflect() protoreflect.Message { // Deprecated: Use ChatFolder.ProtoReflect.Descriptor instead. func (*ChatFolder) Descriptor() ([]byte, []int) { - return file_backuppb_Backup_proto_rawDescGZIP(), []int{82} + return file_backuppb_Backup_proto_rawDescGZIP(), []int{85} } func (x *ChatFolder) GetName() string { @@ -8376,7 +8524,7 @@ type AccountData_UsernameLink struct { func (x *AccountData_UsernameLink) Reset() { *x = AccountData_UsernameLink{} - mi := &file_backuppb_Backup_proto_msgTypes[83] + mi := &file_backuppb_Backup_proto_msgTypes[86] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8388,7 +8536,7 @@ func (x *AccountData_UsernameLink) String() string { func (*AccountData_UsernameLink) ProtoMessage() {} func (x *AccountData_UsernameLink) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[83] + mi := &file_backuppb_Backup_proto_msgTypes[86] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8437,7 +8585,7 @@ type AccountData_AutoDownloadSettings struct { func (x *AccountData_AutoDownloadSettings) Reset() { *x = AccountData_AutoDownloadSettings{} - mi := &file_backuppb_Backup_proto_msgTypes[84] + mi := &file_backuppb_Backup_proto_msgTypes[87] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8449,7 +8597,7 @@ func (x *AccountData_AutoDownloadSettings) String() string { func (*AccountData_AutoDownloadSettings) ProtoMessage() {} func (x *AccountData_AutoDownloadSettings) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[84] + mi := &file_backuppb_Backup_proto_msgTypes[87] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8516,22 +8664,23 @@ type AccountData_AccountSettings struct { CustomChatColors []*ChatStyle_CustomChatColor `protobuf:"bytes,19,rep,name=customChatColors,proto3" json:"customChatColors,omitempty"` OptimizeOnDeviceStorage bool `protobuf:"varint,20,opt,name=optimizeOnDeviceStorage,proto3" json:"optimizeOnDeviceStorage,omitempty"` // See zkgroup for integer particular values. Unset if backups are not enabled. - BackupTier *uint64 `protobuf:"varint,21,opt,name=backupTier,proto3,oneof" json:"backupTier,omitempty"` - DefaultSentMediaQuality AccountData_SentMediaQuality `protobuf:"varint,23,opt,name=defaultSentMediaQuality,proto3,enum=signal.backup.AccountData_SentMediaQuality" json:"defaultSentMediaQuality,omitempty"` - AutoDownloadSettings *AccountData_AutoDownloadSettings `protobuf:"bytes,24,opt,name=autoDownloadSettings,proto3" json:"autoDownloadSettings,omitempty"` - ScreenLockTimeoutMinutes *uint32 `protobuf:"varint,26,opt,name=screenLockTimeoutMinutes,proto3,oneof" json:"screenLockTimeoutMinutes,omitempty"` // If unset, consider screen lock to be disabled. - PinReminders *bool `protobuf:"varint,27,opt,name=pinReminders,proto3,oneof" json:"pinReminders,omitempty"` // If unset, consider pin reminders to be enabled. - AppTheme AccountData_AppTheme `protobuf:"varint,28,opt,name=appTheme,proto3,enum=signal.backup.AccountData_AppTheme" json:"appTheme,omitempty"` // If unset, treat the same as "Unknown" case - CallsUseLessDataSetting AccountData_CallsUseLessDataSetting `protobuf:"varint,29,opt,name=callsUseLessDataSetting,proto3,enum=signal.backup.AccountData_CallsUseLessDataSetting" json:"callsUseLessDataSetting,omitempty"` // If unset, treat the same as "Unknown" case - AllowSealedSenderFromAnyone bool `protobuf:"varint,30,opt,name=allowSealedSenderFromAnyone,proto3" json:"allowSealedSenderFromAnyone,omitempty"` - AllowAutomaticKeyVerification bool `protobuf:"varint,31,opt,name=allowAutomaticKeyVerification,proto3" json:"allowAutomaticKeyVerification,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache + BackupTier *uint64 `protobuf:"varint,21,opt,name=backupTier,proto3,oneof" json:"backupTier,omitempty"` + DefaultSentMediaQuality AccountData_SentMediaQuality `protobuf:"varint,23,opt,name=defaultSentMediaQuality,proto3,enum=signal.backup.AccountData_SentMediaQuality" json:"defaultSentMediaQuality,omitempty"` + AutoDownloadSettings *AccountData_AutoDownloadSettings `protobuf:"bytes,24,opt,name=autoDownloadSettings,proto3" json:"autoDownloadSettings,omitempty"` + ScreenLockTimeoutMinutes *uint32 `protobuf:"varint,26,opt,name=screenLockTimeoutMinutes,proto3,oneof" json:"screenLockTimeoutMinutes,omitempty"` // If unset, consider screen lock to be disabled. + PinReminders *bool `protobuf:"varint,27,opt,name=pinReminders,proto3,oneof" json:"pinReminders,omitempty"` // If unset, consider pin reminders to be enabled. + AppTheme AccountData_AppTheme `protobuf:"varint,28,opt,name=appTheme,proto3,enum=signal.backup.AccountData_AppTheme" json:"appTheme,omitempty"` // If unset, treat the same as "Unknown" case + CallsUseLessDataSetting AccountData_CallsUseLessDataSetting `protobuf:"varint,29,opt,name=callsUseLessDataSetting,proto3,enum=signal.backup.AccountData_CallsUseLessDataSetting" json:"callsUseLessDataSetting,omitempty"` // If unset, treat the same as "Unknown" case + AllowSealedSenderFromAnyone bool `protobuf:"varint,30,opt,name=allowSealedSenderFromAnyone,proto3" json:"allowSealedSenderFromAnyone,omitempty"` + AllowAutomaticKeyVerification bool `protobuf:"varint,31,opt,name=allowAutomaticKeyVerification,proto3" json:"allowAutomaticKeyVerification,omitempty"` + HasSeenAdminDeleteEducationDialog bool `protobuf:"varint,32,opt,name=hasSeenAdminDeleteEducationDialog,proto3" json:"hasSeenAdminDeleteEducationDialog,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } func (x *AccountData_AccountSettings) Reset() { *x = AccountData_AccountSettings{} - mi := &file_backuppb_Backup_proto_msgTypes[85] + mi := &file_backuppb_Backup_proto_msgTypes[88] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8543,7 +8692,7 @@ func (x *AccountData_AccountSettings) String() string { func (*AccountData_AccountSettings) ProtoMessage() {} func (x *AccountData_AccountSettings) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[85] + mi := &file_backuppb_Backup_proto_msgTypes[88] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8762,6 +8911,13 @@ func (x *AccountData_AccountSettings) GetAllowAutomaticKeyVerification() bool { return false } +func (x *AccountData_AccountSettings) GetHasSeenAdminDeleteEducationDialog() bool { + if x != nil { + return x.HasSeenAdminDeleteEducationDialog + } + return false +} + type AccountData_SubscriberData struct { state protoimpl.MessageState `protogen:"open.v1"` SubscriberId []byte `protobuf:"bytes,1,opt,name=subscriberId,proto3" json:"subscriberId,omitempty"` @@ -8773,7 +8929,7 @@ type AccountData_SubscriberData struct { func (x *AccountData_SubscriberData) Reset() { *x = AccountData_SubscriberData{} - mi := &file_backuppb_Backup_proto_msgTypes[86] + mi := &file_backuppb_Backup_proto_msgTypes[89] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8785,7 +8941,7 @@ func (x *AccountData_SubscriberData) String() string { func (*AccountData_SubscriberData) ProtoMessage() {} func (x *AccountData_SubscriberData) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[86] + mi := &file_backuppb_Backup_proto_msgTypes[89] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8838,7 +8994,7 @@ type AccountData_IAPSubscriberData struct { func (x *AccountData_IAPSubscriberData) Reset() { *x = AccountData_IAPSubscriberData{} - mi := &file_backuppb_Backup_proto_msgTypes[87] + mi := &file_backuppb_Backup_proto_msgTypes[90] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8850,7 +9006,7 @@ func (x *AccountData_IAPSubscriberData) String() string { func (*AccountData_IAPSubscriberData) ProtoMessage() {} func (x *AccountData_IAPSubscriberData) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[87] + mi := &file_backuppb_Backup_proto_msgTypes[90] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8929,7 +9085,7 @@ type AccountData_AndroidSpecificSettings struct { func (x *AccountData_AndroidSpecificSettings) Reset() { *x = AccountData_AndroidSpecificSettings{} - mi := &file_backuppb_Backup_proto_msgTypes[88] + mi := &file_backuppb_Backup_proto_msgTypes[91] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8941,7 +9097,7 @@ func (x *AccountData_AndroidSpecificSettings) String() string { func (*AccountData_AndroidSpecificSettings) ProtoMessage() {} func (x *AccountData_AndroidSpecificSettings) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[88] + mi := &file_backuppb_Backup_proto_msgTypes[91] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8986,7 +9142,7 @@ type Contact_Registered struct { func (x *Contact_Registered) Reset() { *x = Contact_Registered{} - mi := &file_backuppb_Backup_proto_msgTypes[89] + mi := &file_backuppb_Backup_proto_msgTypes[92] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8998,7 +9154,7 @@ func (x *Contact_Registered) String() string { func (*Contact_Registered) ProtoMessage() {} func (x *Contact_Registered) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[89] + mi := &file_backuppb_Backup_proto_msgTypes[92] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9023,7 +9179,7 @@ type Contact_NotRegistered struct { func (x *Contact_NotRegistered) Reset() { *x = Contact_NotRegistered{} - mi := &file_backuppb_Backup_proto_msgTypes[90] + mi := &file_backuppb_Backup_proto_msgTypes[93] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9035,7 +9191,7 @@ func (x *Contact_NotRegistered) String() string { func (*Contact_NotRegistered) ProtoMessage() {} func (x *Contact_NotRegistered) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[90] + mi := &file_backuppb_Backup_proto_msgTypes[93] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9068,7 +9224,7 @@ type Contact_Name struct { func (x *Contact_Name) Reset() { *x = Contact_Name{} - mi := &file_backuppb_Backup_proto_msgTypes[91] + mi := &file_backuppb_Backup_proto_msgTypes[94] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9080,7 +9236,7 @@ func (x *Contact_Name) String() string { func (*Contact_Name) ProtoMessage() {} func (x *Contact_Name) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[91] + mi := &file_backuppb_Backup_proto_msgTypes[94] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9129,13 +9285,14 @@ type Group_GroupSnapshot struct { InviteLinkPassword []byte `protobuf:"bytes,10,opt,name=inviteLinkPassword,proto3" json:"inviteLinkPassword,omitempty"` AnnouncementsOnly bool `protobuf:"varint,12,opt,name=announcements_only,json=announcementsOnly,proto3" json:"announcements_only,omitempty"` MembersBanned []*Group_MemberBanned `protobuf:"bytes,13,rep,name=members_banned,json=membersBanned,proto3" json:"members_banned,omitempty"` + Terminated bool `protobuf:"varint,14,opt,name=terminated,proto3" json:"terminated,omitempty"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } func (x *Group_GroupSnapshot) Reset() { *x = Group_GroupSnapshot{} - mi := &file_backuppb_Backup_proto_msgTypes[92] + mi := &file_backuppb_Backup_proto_msgTypes[95] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9147,7 +9304,7 @@ func (x *Group_GroupSnapshot) String() string { func (*Group_GroupSnapshot) ProtoMessage() {} func (x *Group_GroupSnapshot) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[92] + mi := &file_backuppb_Backup_proto_msgTypes[95] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9247,6 +9404,13 @@ func (x *Group_GroupSnapshot) GetMembersBanned() []*Group_MemberBanned { return nil } +func (x *Group_GroupSnapshot) GetTerminated() bool { + if x != nil { + return x.Terminated + } + return false +} + type Group_GroupAttributeBlob struct { state protoimpl.MessageState `protogen:"open.v1"` // If unset, consider the field it represents to not be present @@ -9264,7 +9428,7 @@ type Group_GroupAttributeBlob struct { func (x *Group_GroupAttributeBlob) Reset() { *x = Group_GroupAttributeBlob{} - mi := &file_backuppb_Backup_proto_msgTypes[93] + mi := &file_backuppb_Backup_proto_msgTypes[96] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9276,7 +9440,7 @@ func (x *Group_GroupAttributeBlob) String() string { func (*Group_GroupAttributeBlob) ProtoMessage() {} func (x *Group_GroupAttributeBlob) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[93] + mi := &file_backuppb_Backup_proto_msgTypes[96] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9368,13 +9532,15 @@ type Group_Member struct { UserId []byte `protobuf:"bytes,1,opt,name=userId,proto3" json:"userId,omitempty"` Role Group_Member_Role `protobuf:"varint,2,opt,name=role,proto3,enum=signal.backup.Group_Member_Role" json:"role,omitempty"` JoinedAtVersion uint32 `protobuf:"varint,5,opt,name=joinedAtVersion,proto3" json:"joinedAtVersion,omitempty"` + LabelEmoji string `protobuf:"bytes,6,opt,name=labelEmoji,proto3" json:"labelEmoji,omitempty"` + LabelString string `protobuf:"bytes,7,opt,name=labelString,proto3" json:"labelString,omitempty"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } func (x *Group_Member) Reset() { *x = Group_Member{} - mi := &file_backuppb_Backup_proto_msgTypes[94] + mi := &file_backuppb_Backup_proto_msgTypes[97] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9386,7 +9552,7 @@ func (x *Group_Member) String() string { func (*Group_Member) ProtoMessage() {} func (x *Group_Member) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[94] + mi := &file_backuppb_Backup_proto_msgTypes[97] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9423,6 +9589,20 @@ func (x *Group_Member) GetJoinedAtVersion() uint32 { return 0 } +func (x *Group_Member) GetLabelEmoji() string { + if x != nil { + return x.LabelEmoji + } + return "" +} + +func (x *Group_Member) GetLabelString() string { + if x != nil { + return x.LabelString + } + return "" +} + type Group_MemberPendingProfileKey struct { state protoimpl.MessageState `protogen:"open.v1"` Member *Group_Member `protobuf:"bytes,1,opt,name=member,proto3" json:"member,omitempty"` @@ -9434,7 +9614,7 @@ type Group_MemberPendingProfileKey struct { func (x *Group_MemberPendingProfileKey) Reset() { *x = Group_MemberPendingProfileKey{} - mi := &file_backuppb_Backup_proto_msgTypes[95] + mi := &file_backuppb_Backup_proto_msgTypes[98] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9446,7 +9626,7 @@ func (x *Group_MemberPendingProfileKey) String() string { func (*Group_MemberPendingProfileKey) ProtoMessage() {} func (x *Group_MemberPendingProfileKey) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[95] + mi := &file_backuppb_Backup_proto_msgTypes[98] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9493,7 +9673,7 @@ type Group_MemberPendingAdminApproval struct { func (x *Group_MemberPendingAdminApproval) Reset() { *x = Group_MemberPendingAdminApproval{} - mi := &file_backuppb_Backup_proto_msgTypes[96] + mi := &file_backuppb_Backup_proto_msgTypes[99] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9505,7 +9685,7 @@ func (x *Group_MemberPendingAdminApproval) String() string { func (*Group_MemberPendingAdminApproval) ProtoMessage() {} func (x *Group_MemberPendingAdminApproval) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[96] + mi := &file_backuppb_Backup_proto_msgTypes[99] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9545,7 +9725,7 @@ type Group_MemberBanned struct { func (x *Group_MemberBanned) Reset() { *x = Group_MemberBanned{} - mi := &file_backuppb_Backup_proto_msgTypes[97] + mi := &file_backuppb_Backup_proto_msgTypes[100] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9557,7 +9737,7 @@ func (x *Group_MemberBanned) String() string { func (*Group_MemberBanned) ProtoMessage() {} func (x *Group_MemberBanned) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[97] + mi := &file_backuppb_Backup_proto_msgTypes[100] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9592,13 +9772,14 @@ type Group_AccessControl struct { Attributes Group_AccessControl_AccessRequired `protobuf:"varint,1,opt,name=attributes,proto3,enum=signal.backup.Group_AccessControl_AccessRequired" json:"attributes,omitempty"` Members Group_AccessControl_AccessRequired `protobuf:"varint,2,opt,name=members,proto3,enum=signal.backup.Group_AccessControl_AccessRequired" json:"members,omitempty"` AddFromInviteLink Group_AccessControl_AccessRequired `protobuf:"varint,3,opt,name=addFromInviteLink,proto3,enum=signal.backup.Group_AccessControl_AccessRequired" json:"addFromInviteLink,omitempty"` + MemberLabel Group_AccessControl_AccessRequired `protobuf:"varint,4,opt,name=memberLabel,proto3,enum=signal.backup.Group_AccessControl_AccessRequired" json:"memberLabel,omitempty"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } func (x *Group_AccessControl) Reset() { *x = Group_AccessControl{} - mi := &file_backuppb_Backup_proto_msgTypes[98] + mi := &file_backuppb_Backup_proto_msgTypes[101] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9610,7 +9791,7 @@ func (x *Group_AccessControl) String() string { func (*Group_AccessControl) ProtoMessage() {} func (x *Group_AccessControl) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[98] + mi := &file_backuppb_Backup_proto_msgTypes[101] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9647,6 +9828,13 @@ func (x *Group_AccessControl) GetAddFromInviteLink() Group_AccessControl_AccessR return Group_AccessControl_UNKNOWN } +func (x *Group_AccessControl) GetMemberLabel() Group_AccessControl_AccessRequired { + if x != nil { + return x.MemberLabel + } + return Group_AccessControl_UNKNOWN +} + type ChatItem_IncomingMessageDetails struct { state protoimpl.MessageState `protogen:"open.v1"` DateReceived uint64 `protobuf:"varint,1,opt,name=dateReceived,proto3" json:"dateReceived,omitempty"` @@ -9659,7 +9847,7 @@ type ChatItem_IncomingMessageDetails struct { func (x *ChatItem_IncomingMessageDetails) Reset() { *x = ChatItem_IncomingMessageDetails{} - mi := &file_backuppb_Backup_proto_msgTypes[99] + mi := &file_backuppb_Backup_proto_msgTypes[102] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9671,7 +9859,7 @@ func (x *ChatItem_IncomingMessageDetails) String() string { func (*ChatItem_IncomingMessageDetails) ProtoMessage() {} func (x *ChatItem_IncomingMessageDetails) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[99] + mi := &file_backuppb_Backup_proto_msgTypes[102] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9725,7 +9913,7 @@ type ChatItem_OutgoingMessageDetails struct { func (x *ChatItem_OutgoingMessageDetails) Reset() { *x = ChatItem_OutgoingMessageDetails{} - mi := &file_backuppb_Backup_proto_msgTypes[100] + mi := &file_backuppb_Backup_proto_msgTypes[103] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9737,7 +9925,7 @@ func (x *ChatItem_OutgoingMessageDetails) String() string { func (*ChatItem_OutgoingMessageDetails) ProtoMessage() {} func (x *ChatItem_OutgoingMessageDetails) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[100] + mi := &file_backuppb_Backup_proto_msgTypes[103] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9775,7 +9963,7 @@ type ChatItem_DirectionlessMessageDetails struct { func (x *ChatItem_DirectionlessMessageDetails) Reset() { *x = ChatItem_DirectionlessMessageDetails{} - mi := &file_backuppb_Backup_proto_msgTypes[101] + mi := &file_backuppb_Backup_proto_msgTypes[104] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9787,7 +9975,7 @@ func (x *ChatItem_DirectionlessMessageDetails) String() string { func (*ChatItem_DirectionlessMessageDetails) ProtoMessage() {} func (x *ChatItem_DirectionlessMessageDetails) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[101] + mi := &file_backuppb_Backup_proto_msgTypes[104] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9817,7 +10005,7 @@ type ChatItem_PinDetails struct { func (x *ChatItem_PinDetails) Reset() { *x = ChatItem_PinDetails{} - mi := &file_backuppb_Backup_proto_msgTypes[102] + mi := &file_backuppb_Backup_proto_msgTypes[105] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9829,7 +10017,7 @@ func (x *ChatItem_PinDetails) String() string { func (*ChatItem_PinDetails) ProtoMessage() {} func (x *ChatItem_PinDetails) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[102] + mi := &file_backuppb_Backup_proto_msgTypes[105] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9901,7 +10089,7 @@ type SendStatus_Pending struct { func (x *SendStatus_Pending) Reset() { *x = SendStatus_Pending{} - mi := &file_backuppb_Backup_proto_msgTypes[103] + mi := &file_backuppb_Backup_proto_msgTypes[106] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9913,7 +10101,7 @@ func (x *SendStatus_Pending) String() string { func (*SendStatus_Pending) ProtoMessage() {} func (x *SendStatus_Pending) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[103] + mi := &file_backuppb_Backup_proto_msgTypes[106] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9938,7 +10126,7 @@ type SendStatus_Sent struct { func (x *SendStatus_Sent) Reset() { *x = SendStatus_Sent{} - mi := &file_backuppb_Backup_proto_msgTypes[104] + mi := &file_backuppb_Backup_proto_msgTypes[107] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9950,7 +10138,7 @@ func (x *SendStatus_Sent) String() string { func (*SendStatus_Sent) ProtoMessage() {} func (x *SendStatus_Sent) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[104] + mi := &file_backuppb_Backup_proto_msgTypes[107] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9982,7 +10170,7 @@ type SendStatus_Delivered struct { func (x *SendStatus_Delivered) Reset() { *x = SendStatus_Delivered{} - mi := &file_backuppb_Backup_proto_msgTypes[105] + mi := &file_backuppb_Backup_proto_msgTypes[108] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9994,7 +10182,7 @@ func (x *SendStatus_Delivered) String() string { func (*SendStatus_Delivered) ProtoMessage() {} func (x *SendStatus_Delivered) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[105] + mi := &file_backuppb_Backup_proto_msgTypes[108] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -10026,7 +10214,7 @@ type SendStatus_Read struct { func (x *SendStatus_Read) Reset() { *x = SendStatus_Read{} - mi := &file_backuppb_Backup_proto_msgTypes[106] + mi := &file_backuppb_Backup_proto_msgTypes[109] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -10038,7 +10226,7 @@ func (x *SendStatus_Read) String() string { func (*SendStatus_Read) ProtoMessage() {} func (x *SendStatus_Read) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[106] + mi := &file_backuppb_Backup_proto_msgTypes[109] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -10070,7 +10258,7 @@ type SendStatus_Viewed struct { func (x *SendStatus_Viewed) Reset() { *x = SendStatus_Viewed{} - mi := &file_backuppb_Backup_proto_msgTypes[107] + mi := &file_backuppb_Backup_proto_msgTypes[110] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -10082,7 +10270,7 @@ func (x *SendStatus_Viewed) String() string { func (*SendStatus_Viewed) ProtoMessage() {} func (x *SendStatus_Viewed) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[107] + mi := &file_backuppb_Backup_proto_msgTypes[110] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -10114,7 +10302,7 @@ type SendStatus_Skipped struct { func (x *SendStatus_Skipped) Reset() { *x = SendStatus_Skipped{} - mi := &file_backuppb_Backup_proto_msgTypes[108] + mi := &file_backuppb_Backup_proto_msgTypes[111] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -10126,7 +10314,7 @@ func (x *SendStatus_Skipped) String() string { func (*SendStatus_Skipped) ProtoMessage() {} func (x *SendStatus_Skipped) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[108] + mi := &file_backuppb_Backup_proto_msgTypes[111] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -10151,7 +10339,7 @@ type SendStatus_Failed struct { func (x *SendStatus_Failed) Reset() { *x = SendStatus_Failed{} - mi := &file_backuppb_Backup_proto_msgTypes[109] + mi := &file_backuppb_Backup_proto_msgTypes[112] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -10163,7 +10351,7 @@ func (x *SendStatus_Failed) String() string { func (*SendStatus_Failed) ProtoMessage() {} func (x *SendStatus_Failed) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[109] + mi := &file_backuppb_Backup_proto_msgTypes[112] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -10196,7 +10384,7 @@ type DirectStoryReplyMessage_TextReply struct { func (x *DirectStoryReplyMessage_TextReply) Reset() { *x = DirectStoryReplyMessage_TextReply{} - mi := &file_backuppb_Backup_proto_msgTypes[110] + mi := &file_backuppb_Backup_proto_msgTypes[113] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -10208,7 +10396,7 @@ func (x *DirectStoryReplyMessage_TextReply) String() string { func (*DirectStoryReplyMessage_TextReply) ProtoMessage() {} func (x *DirectStoryReplyMessage_TextReply) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[110] + mi := &file_backuppb_Backup_proto_msgTypes[113] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -10253,7 +10441,7 @@ type PaymentNotification_TransactionDetails struct { func (x *PaymentNotification_TransactionDetails) Reset() { *x = PaymentNotification_TransactionDetails{} - mi := &file_backuppb_Backup_proto_msgTypes[111] + mi := &file_backuppb_Backup_proto_msgTypes[114] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -10265,7 +10453,7 @@ func (x *PaymentNotification_TransactionDetails) String() string { func (*PaymentNotification_TransactionDetails) ProtoMessage() {} func (x *PaymentNotification_TransactionDetails) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[111] + mi := &file_backuppb_Backup_proto_msgTypes[114] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -10334,7 +10522,7 @@ type PaymentNotification_TransactionDetails_MobileCoinTxoIdentification struct { func (x *PaymentNotification_TransactionDetails_MobileCoinTxoIdentification) Reset() { *x = PaymentNotification_TransactionDetails_MobileCoinTxoIdentification{} - mi := &file_backuppb_Backup_proto_msgTypes[112] + mi := &file_backuppb_Backup_proto_msgTypes[115] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -10346,7 +10534,7 @@ func (x *PaymentNotification_TransactionDetails_MobileCoinTxoIdentification) Str func (*PaymentNotification_TransactionDetails_MobileCoinTxoIdentification) ProtoMessage() {} func (x *PaymentNotification_TransactionDetails_MobileCoinTxoIdentification) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[112] + mi := &file_backuppb_Backup_proto_msgTypes[115] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -10385,7 +10573,7 @@ type PaymentNotification_TransactionDetails_FailedTransaction struct { func (x *PaymentNotification_TransactionDetails_FailedTransaction) Reset() { *x = PaymentNotification_TransactionDetails_FailedTransaction{} - mi := &file_backuppb_Backup_proto_msgTypes[113] + mi := &file_backuppb_Backup_proto_msgTypes[116] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -10397,7 +10585,7 @@ func (x *PaymentNotification_TransactionDetails_FailedTransaction) String() stri func (*PaymentNotification_TransactionDetails_FailedTransaction) ProtoMessage() {} func (x *PaymentNotification_TransactionDetails_FailedTransaction) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[113] + mi := &file_backuppb_Backup_proto_msgTypes[116] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -10438,7 +10626,7 @@ type PaymentNotification_TransactionDetails_Transaction struct { func (x *PaymentNotification_TransactionDetails_Transaction) Reset() { *x = PaymentNotification_TransactionDetails_Transaction{} - mi := &file_backuppb_Backup_proto_msgTypes[114] + mi := &file_backuppb_Backup_proto_msgTypes[117] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -10450,7 +10638,7 @@ func (x *PaymentNotification_TransactionDetails_Transaction) String() string { func (*PaymentNotification_TransactionDetails_Transaction) ProtoMessage() {} func (x *PaymentNotification_TransactionDetails_Transaction) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[114] + mi := &file_backuppb_Backup_proto_msgTypes[117] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -10529,7 +10717,7 @@ type ContactAttachment_Name struct { func (x *ContactAttachment_Name) Reset() { *x = ContactAttachment_Name{} - mi := &file_backuppb_Backup_proto_msgTypes[115] + mi := &file_backuppb_Backup_proto_msgTypes[118] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -10541,7 +10729,7 @@ func (x *ContactAttachment_Name) String() string { func (*ContactAttachment_Name) ProtoMessage() {} func (x *ContactAttachment_Name) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[115] + mi := &file_backuppb_Backup_proto_msgTypes[118] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -10610,7 +10798,7 @@ type ContactAttachment_Phone struct { func (x *ContactAttachment_Phone) Reset() { *x = ContactAttachment_Phone{} - mi := &file_backuppb_Backup_proto_msgTypes[116] + mi := &file_backuppb_Backup_proto_msgTypes[119] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -10622,7 +10810,7 @@ func (x *ContactAttachment_Phone) String() string { func (*ContactAttachment_Phone) ProtoMessage() {} func (x *ContactAttachment_Phone) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[116] + mi := &file_backuppb_Backup_proto_msgTypes[119] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -10670,7 +10858,7 @@ type ContactAttachment_Email struct { func (x *ContactAttachment_Email) Reset() { *x = ContactAttachment_Email{} - mi := &file_backuppb_Backup_proto_msgTypes[117] + mi := &file_backuppb_Backup_proto_msgTypes[120] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -10682,7 +10870,7 @@ func (x *ContactAttachment_Email) String() string { func (*ContactAttachment_Email) ProtoMessage() {} func (x *ContactAttachment_Email) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[117] + mi := &file_backuppb_Backup_proto_msgTypes[120] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -10736,7 +10924,7 @@ type ContactAttachment_PostalAddress struct { func (x *ContactAttachment_PostalAddress) Reset() { *x = ContactAttachment_PostalAddress{} - mi := &file_backuppb_Backup_proto_msgTypes[118] + mi := &file_backuppb_Backup_proto_msgTypes[121] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -10748,7 +10936,7 @@ func (x *ContactAttachment_PostalAddress) String() string { func (*ContactAttachment_PostalAddress) ProtoMessage() {} func (x *ContactAttachment_PostalAddress) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[118] + mi := &file_backuppb_Backup_proto_msgTypes[121] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -10863,7 +11051,7 @@ type FilePointer_LocatorInfo struct { func (x *FilePointer_LocatorInfo) Reset() { *x = FilePointer_LocatorInfo{} - mi := &file_backuppb_Backup_proto_msgTypes[119] + mi := &file_backuppb_Backup_proto_msgTypes[122] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -10875,7 +11063,7 @@ func (x *FilePointer_LocatorInfo) String() string { func (*FilePointer_LocatorInfo) ProtoMessage() {} func (x *FilePointer_LocatorInfo) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[119] + mi := &file_backuppb_Backup_proto_msgTypes[122] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -10995,7 +11183,7 @@ type Quote_QuotedAttachment struct { func (x *Quote_QuotedAttachment) Reset() { *x = Quote_QuotedAttachment{} - mi := &file_backuppb_Backup_proto_msgTypes[120] + mi := &file_backuppb_Backup_proto_msgTypes[123] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -11007,7 +11195,7 @@ func (x *Quote_QuotedAttachment) String() string { func (*Quote_QuotedAttachment) ProtoMessage() {} func (x *Quote_QuotedAttachment) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[120] + mi := &file_backuppb_Backup_proto_msgTypes[123] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -11054,7 +11242,7 @@ type Poll_PollOption struct { func (x *Poll_PollOption) Reset() { *x = Poll_PollOption{} - mi := &file_backuppb_Backup_proto_msgTypes[121] + mi := &file_backuppb_Backup_proto_msgTypes[124] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -11066,7 +11254,7 @@ func (x *Poll_PollOption) String() string { func (*Poll_PollOption) ProtoMessage() {} func (x *Poll_PollOption) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[121] + mi := &file_backuppb_Backup_proto_msgTypes[124] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -11106,7 +11294,7 @@ type Poll_PollOption_PollVote struct { func (x *Poll_PollOption_PollVote) Reset() { *x = Poll_PollOption_PollVote{} - mi := &file_backuppb_Backup_proto_msgTypes[122] + mi := &file_backuppb_Backup_proto_msgTypes[125] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -11118,7 +11306,7 @@ func (x *Poll_PollOption_PollVote) String() string { func (*Poll_PollOption_PollVote) ProtoMessage() {} func (x *Poll_PollOption_PollVote) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[122] + mi := &file_backuppb_Backup_proto_msgTypes[125] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -11188,6 +11376,8 @@ type GroupChangeChatUpdate_Update struct { // *GroupChangeChatUpdate_Update_GroupV2MigrationDroppedMembersUpdate // *GroupChangeChatUpdate_Update_GroupSequenceOfRequestsAndCancelsUpdate // *GroupChangeChatUpdate_Update_GroupExpirationTimerUpdate + // *GroupChangeChatUpdate_Update_GroupMemberLabelAccessLevelChangeUpdate + // *GroupChangeChatUpdate_Update_GroupTerminateChangeUpdate Update isGroupChangeChatUpdate_Update_Update `protobuf_oneof:"update"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache @@ -11195,7 +11385,7 @@ type GroupChangeChatUpdate_Update struct { func (x *GroupChangeChatUpdate_Update) Reset() { *x = GroupChangeChatUpdate_Update{} - mi := &file_backuppb_Backup_proto_msgTypes[123] + mi := &file_backuppb_Backup_proto_msgTypes[126] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -11207,7 +11397,7 @@ func (x *GroupChangeChatUpdate_Update) String() string { func (*GroupChangeChatUpdate_Update) ProtoMessage() {} func (x *GroupChangeChatUpdate_Update) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[123] + mi := &file_backuppb_Backup_proto_msgTypes[126] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -11220,7 +11410,7 @@ func (x *GroupChangeChatUpdate_Update) ProtoReflect() protoreflect.Message { // Deprecated: Use GroupChangeChatUpdate_Update.ProtoReflect.Descriptor instead. func (*GroupChangeChatUpdate_Update) Descriptor() ([]byte, []int) { - return file_backuppb_Backup_proto_rawDescGZIP(), []int{42, 0} + return file_backuppb_Backup_proto_rawDescGZIP(), []int{43, 0} } func (x *GroupChangeChatUpdate_Update) GetUpdate() isGroupChangeChatUpdate_Update_Update { @@ -11536,6 +11726,24 @@ func (x *GroupChangeChatUpdate_Update) GetGroupExpirationTimerUpdate() *GroupExp return nil } +func (x *GroupChangeChatUpdate_Update) GetGroupMemberLabelAccessLevelChangeUpdate() *GroupMemberLabelAccessLevelChangeUpdate { + if x != nil { + if x, ok := x.Update.(*GroupChangeChatUpdate_Update_GroupMemberLabelAccessLevelChangeUpdate); ok { + return x.GroupMemberLabelAccessLevelChangeUpdate + } + } + return nil +} + +func (x *GroupChangeChatUpdate_Update) GetGroupTerminateChangeUpdate() *GroupTerminateChangeUpdate { + if x != nil { + if x, ok := x.Update.(*GroupChangeChatUpdate_Update_GroupTerminateChangeUpdate); ok { + return x.GroupTerminateChangeUpdate + } + } + return nil +} + type isGroupChangeChatUpdate_Update_Update interface { isGroupChangeChatUpdate_Update_Update() } @@ -11676,6 +11884,14 @@ type GroupChangeChatUpdate_Update_GroupExpirationTimerUpdate struct { GroupExpirationTimerUpdate *GroupExpirationTimerUpdate `protobuf:"bytes,34,opt,name=groupExpirationTimerUpdate,proto3,oneof"` } +type GroupChangeChatUpdate_Update_GroupMemberLabelAccessLevelChangeUpdate struct { + GroupMemberLabelAccessLevelChangeUpdate *GroupMemberLabelAccessLevelChangeUpdate `protobuf:"bytes,35,opt,name=groupMemberLabelAccessLevelChangeUpdate,proto3,oneof"` +} + +type GroupChangeChatUpdate_Update_GroupTerminateChangeUpdate struct { + GroupTerminateChangeUpdate *GroupTerminateChangeUpdate `protobuf:"bytes,36,opt,name=groupTerminateChangeUpdate,proto3,oneof"` +} + func (*GroupChangeChatUpdate_Update_GenericGroupUpdate) isGroupChangeChatUpdate_Update_Update() {} func (*GroupChangeChatUpdate_Update_GroupCreationUpdate) isGroupChangeChatUpdate_Update_Update() {} @@ -11768,6 +11984,12 @@ func (*GroupChangeChatUpdate_Update_GroupSequenceOfRequestsAndCancelsUpdate) isG func (*GroupChangeChatUpdate_Update_GroupExpirationTimerUpdate) isGroupChangeChatUpdate_Update_Update() { } +func (*GroupChangeChatUpdate_Update_GroupMemberLabelAccessLevelChangeUpdate) isGroupChangeChatUpdate_Update_Update() { +} + +func (*GroupChangeChatUpdate_Update_GroupTerminateChangeUpdate) isGroupChangeChatUpdate_Update_Update() { +} + type GroupInvitationRevokedUpdate_Invitee struct { state protoimpl.MessageState `protogen:"open.v1"` InviterAci []byte `protobuf:"bytes,1,opt,name=inviterAci,proto3,oneof" json:"inviterAci,omitempty"` @@ -11781,7 +12003,7 @@ type GroupInvitationRevokedUpdate_Invitee struct { func (x *GroupInvitationRevokedUpdate_Invitee) Reset() { *x = GroupInvitationRevokedUpdate_Invitee{} - mi := &file_backuppb_Backup_proto_msgTypes[124] + mi := &file_backuppb_Backup_proto_msgTypes[127] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -11793,7 +12015,7 @@ func (x *GroupInvitationRevokedUpdate_Invitee) String() string { func (*GroupInvitationRevokedUpdate_Invitee) ProtoMessage() {} func (x *GroupInvitationRevokedUpdate_Invitee) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[124] + mi := &file_backuppb_Backup_proto_msgTypes[127] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -11806,7 +12028,7 @@ func (x *GroupInvitationRevokedUpdate_Invitee) ProtoReflect() protoreflect.Messa // Deprecated: Use GroupInvitationRevokedUpdate_Invitee.ProtoReflect.Descriptor instead. func (*GroupInvitationRevokedUpdate_Invitee) Descriptor() ([]byte, []int) { - return file_backuppb_Backup_proto_rawDescGZIP(), []int{62, 0} + return file_backuppb_Backup_proto_rawDescGZIP(), []int{65, 0} } func (x *GroupInvitationRevokedUpdate_Invitee) GetInviterAci() []byte { @@ -11841,7 +12063,7 @@ type ChatStyle_Gradient struct { func (x *ChatStyle_Gradient) Reset() { *x = ChatStyle_Gradient{} - mi := &file_backuppb_Backup_proto_msgTypes[125] + mi := &file_backuppb_Backup_proto_msgTypes[128] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -11853,7 +12075,7 @@ func (x *ChatStyle_Gradient) String() string { func (*ChatStyle_Gradient) ProtoMessage() {} func (x *ChatStyle_Gradient) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[125] + mi := &file_backuppb_Backup_proto_msgTypes[128] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -11866,7 +12088,7 @@ func (x *ChatStyle_Gradient) ProtoReflect() protoreflect.Message { // Deprecated: Use ChatStyle_Gradient.ProtoReflect.Descriptor instead. func (*ChatStyle_Gradient) Descriptor() ([]byte, []int) { - return file_backuppb_Backup_proto_rawDescGZIP(), []int{80, 0} + return file_backuppb_Backup_proto_rawDescGZIP(), []int{83, 0} } func (x *ChatStyle_Gradient) GetAngle() uint32 { @@ -11906,7 +12128,7 @@ type ChatStyle_CustomChatColor struct { func (x *ChatStyle_CustomChatColor) Reset() { *x = ChatStyle_CustomChatColor{} - mi := &file_backuppb_Backup_proto_msgTypes[126] + mi := &file_backuppb_Backup_proto_msgTypes[129] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -11918,7 +12140,7 @@ func (x *ChatStyle_CustomChatColor) String() string { func (*ChatStyle_CustomChatColor) ProtoMessage() {} func (x *ChatStyle_CustomChatColor) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[126] + mi := &file_backuppb_Backup_proto_msgTypes[129] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -11931,7 +12153,7 @@ func (x *ChatStyle_CustomChatColor) ProtoReflect() protoreflect.Message { // Deprecated: Use ChatStyle_CustomChatColor.ProtoReflect.Descriptor instead. func (*ChatStyle_CustomChatColor) Descriptor() ([]byte, []int) { - return file_backuppb_Backup_proto_rawDescGZIP(), []int{80, 1} + return file_backuppb_Backup_proto_rawDescGZIP(), []int{83, 1} } func (x *ChatStyle_CustomChatColor) GetId() uint64 { @@ -11990,7 +12212,7 @@ type ChatStyle_AutomaticBubbleColor struct { func (x *ChatStyle_AutomaticBubbleColor) Reset() { *x = ChatStyle_AutomaticBubbleColor{} - mi := &file_backuppb_Backup_proto_msgTypes[127] + mi := &file_backuppb_Backup_proto_msgTypes[130] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -12002,7 +12224,7 @@ func (x *ChatStyle_AutomaticBubbleColor) String() string { func (*ChatStyle_AutomaticBubbleColor) ProtoMessage() {} func (x *ChatStyle_AutomaticBubbleColor) ProtoReflect() protoreflect.Message { - mi := &file_backuppb_Backup_proto_msgTypes[127] + mi := &file_backuppb_Backup_proto_msgTypes[130] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -12015,7 +12237,7 @@ func (x *ChatStyle_AutomaticBubbleColor) ProtoReflect() protoreflect.Message { // Deprecated: Use ChatStyle_AutomaticBubbleColor.ProtoReflect.Descriptor instead. func (*ChatStyle_AutomaticBubbleColor) Descriptor() ([]byte, []int) { - return file_backuppb_Backup_proto_rawDescGZIP(), []int{80, 2} + return file_backuppb_Backup_proto_rawDescGZIP(), []int{83, 2} } var File_backuppb_Backup_proto protoreflect.FileDescriptor @@ -12042,7 +12264,7 @@ const file_backuppb_Backup_proto_rawDesc = "" + "\n" + "chatFolder\x18\b \x01(\v2\x19.signal.backup.ChatFolderH\x00R\n" + "chatFolderB\x06\n" + - "\x04item\"\xf9\"\n" + + "\x04item\"\xc7#\n" + "\vAccountData\x12\x1e\n" + "\n" + "profileKey\x18\x01 \x01(\fR\n" + @@ -12088,7 +12310,7 @@ const file_backuppb_Backup_proto_rawDesc = "" + "\aUNKNOWN\x10\x00\x12\t\n" + "\x05NEVER\x10\x01\x12\b\n" + "\x04WIFI\x10\x02\x12\x15\n" + - "\x11WIFI_AND_CELLULAR\x10\x03\x1a\xc9\x0f\n" + + "\x11WIFI_AND_CELLULAR\x10\x03\x1a\x97\x10\n" + "\x0fAccountSettings\x12\"\n" + "\freadReceipts\x18\x01 \x01(\bR\freadReceipts\x126\n" + "\x16sealedSenderIndicators\x18\x02 \x01(\bR\x16sealedSenderIndicators\x12*\n" + @@ -12121,7 +12343,8 @@ const file_backuppb_Backup_proto_rawDesc = "" + "\bappTheme\x18\x1c \x01(\x0e2#.signal.backup.AccountData.AppThemeR\bappTheme\x12l\n" + "\x17callsUseLessDataSetting\x18\x1d \x01(\x0e22.signal.backup.AccountData.CallsUseLessDataSettingR\x17callsUseLessDataSetting\x12@\n" + "\x1ballowSealedSenderFromAnyone\x18\x1e \x01(\bR\x1ballowSealedSenderFromAnyone\x12D\n" + - "\x1dallowAutomaticKeyVerification\x18\x1f \x01(\bR\x1dallowAutomaticKeyVerificationB\x1b\n" + + "\x1dallowAutomaticKeyVerification\x18\x1f \x01(\bR\x1dallowAutomaticKeyVerification\x12L\n" + + "!hasSeenAdminDeleteEducationDialog\x18 \x01(\bR!hasSeenAdminDeleteEducationDialogB\x1b\n" + "\x19_storyViewReceiptsEnabledB\r\n" + "\v_backupTierB\x1b\n" + "\x19_screenLockTimeoutMinutesB\x0f\n" + @@ -12234,7 +12457,7 @@ const file_backuppb_Backup_proto_rawDesc = "" + "\x12_profileFamilyNameB\x0e\n" + "\f_identityKeyB\x0e\n" + "\f_avatarColorB\x16\n" + - "\x14_keyTransparencyData\"\x8f\x12\n" + + "\x14_keyTransparencyData\"\xc6\x13\n" + "\x05Group\x12\x1c\n" + "\tmasterKey\x18\x01 \x01(\fR\tmasterKey\x12 \n" + "\vwhitelisted\x18\x02 \x01(\bR\vwhitelisted\x12\x1c\n" + @@ -12242,7 +12465,7 @@ const file_backuppb_Backup_proto_rawDesc = "" + "\rstorySendMode\x18\x04 \x01(\x0e2\".signal.backup.Group.StorySendModeR\rstorySendMode\x12>\n" + "\bsnapshot\x18\x05 \x01(\v2\".signal.backup.Group.GroupSnapshotR\bsnapshot\x12\x18\n" + "\ablocked\x18\x06 \x01(\bR\ablocked\x12A\n" + - "\vavatarColor\x18\a \x01(\x0e2\x1a.signal.backup.AvatarColorH\x00R\vavatarColor\x88\x01\x01\x1a\xc5\x06\n" + + "\vavatarColor\x18\a \x01(\x0e2\x1a.signal.backup.AvatarColorH\x00R\vavatarColor\x88\x01\x01\x1a\xe5\x06\n" + "\rGroupSnapshot\x12=\n" + "\x05title\x18\x02 \x01(\v2'.signal.backup.Group.GroupAttributeBlobR\x05title\x12I\n" + "\vdescription\x18\v \x01(\v2'.signal.backup.Group.GroupAttributeBlobR\vdescription\x12\x1c\n" + @@ -12256,17 +12479,24 @@ const file_backuppb_Backup_proto_rawDesc = "" + "\x12inviteLinkPassword\x18\n" + " \x01(\fR\x12inviteLinkPassword\x12-\n" + "\x12announcements_only\x18\f \x01(\bR\x11announcementsOnly\x12H\n" + - "\x0emembers_banned\x18\r \x03(\v2!.signal.backup.Group.MemberBannedR\rmembersBannedJ\x04\b\x01\x10\x02\x1a\xc3\x01\n" + + "\x0emembers_banned\x18\r \x03(\v2!.signal.backup.Group.MemberBannedR\rmembersBanned\x12\x1e\n" + + "\n" + + "terminated\x18\x0e \x01(\bR\n" + + "terminatedJ\x04\b\x01\x10\x02\x1a\xc3\x01\n" + "\x12GroupAttributeBlob\x12\x16\n" + "\x05title\x18\x01 \x01(\tH\x00R\x05title\x12\x18\n" + "\x06avatar\x18\x02 \x01(\fH\x00R\x06avatar\x12D\n" + "\x1cdisappearingMessagesDuration\x18\x03 \x01(\rH\x00R\x1cdisappearingMessagesDuration\x12*\n" + "\x0fdescriptionText\x18\x04 \x01(\tH\x00R\x0fdescriptionTextB\t\n" + - "\acontent\x1a\xc1\x01\n" + + "\acontent\x1a\x83\x02\n" + "\x06Member\x12\x16\n" + "\x06userId\x18\x01 \x01(\fR\x06userId\x124\n" + "\x04role\x18\x02 \x01(\x0e2 .signal.backup.Group.Member.RoleR\x04role\x12(\n" + - "\x0fjoinedAtVersion\x18\x05 \x01(\rR\x0fjoinedAtVersion\"3\n" + + "\x0fjoinedAtVersion\x18\x05 \x01(\rR\x0fjoinedAtVersion\x12\x1e\n" + + "\n" + + "labelEmoji\x18\x06 \x01(\tR\n" + + "labelEmoji\x12 \n" + + "\vlabelString\x18\a \x01(\tR\vlabelString\"3\n" + "\x04Role\x12\v\n" + "\aUNKNOWN\x10\x00\x12\v\n" + "\aDEFAULT\x10\x01\x12\x11\n" + @@ -12280,13 +12510,14 @@ const file_backuppb_Backup_proto_rawDesc = "" + "\ttimestamp\x18\x04 \x01(\x04R\ttimestampJ\x04\b\x02\x10\x03J\x04\b\x03\x10\x04\x1aD\n" + "\fMemberBanned\x12\x16\n" + "\x06userId\x18\x01 \x01(\fR\x06userId\x12\x1c\n" + - "\ttimestamp\x18\x02 \x01(\x04R\ttimestamp\x1a\xea\x02\n" + + "\ttimestamp\x18\x02 \x01(\x04R\ttimestamp\x1a\xbf\x03\n" + "\rAccessControl\x12Q\n" + "\n" + "attributes\x18\x01 \x01(\x0e21.signal.backup.Group.AccessControl.AccessRequiredR\n" + "attributes\x12K\n" + "\amembers\x18\x02 \x01(\x0e21.signal.backup.Group.AccessControl.AccessRequiredR\amembers\x12_\n" + - "\x11addFromInviteLink\x18\x03 \x01(\x0e21.signal.backup.Group.AccessControl.AccessRequiredR\x11addFromInviteLink\"X\n" + + "\x11addFromInviteLink\x18\x03 \x01(\x0e21.signal.backup.Group.AccessControl.AccessRequiredR\x11addFromInviteLink\x12S\n" + + "\vmemberLabel\x18\x04 \x01(\x0e21.signal.backup.Group.AccessControl.AccessRequiredR\vmemberLabel\"X\n" + "\x0eAccessRequired\x12\v\n" + "\aUNKNOWN\x10\x00\x12\a\n" + "\x03ANY\x10\x01\x12\n" + @@ -12317,20 +12548,18 @@ const file_backuppb_Backup_proto_rawDesc = "" + " \x01(\rR\x12expireTimerVersionB\x0e\n" + "\f_pinnedOrderB\x14\n" + "\x12_expirationTimerMsB\x0e\n" + - "\f_muteUntilMs\"\xb4\x02\n" + + "\f_muteUntilMs\"\x95\x02\n" + "\bCallLink\x12\x18\n" + "\arootKey\x18\x01 \x01(\fR\arootKey\x12\x1f\n" + "\badminKey\x18\x02 \x01(\fH\x00R\badminKey\x88\x01\x01\x12\x12\n" + "\x04name\x18\x03 \x01(\tR\x04name\x12H\n" + "\frestrictions\x18\x04 \x01(\x0e2$.signal.backup.CallLink.RestrictionsR\frestrictions\x12\"\n" + - "\fexpirationMs\x18\x05 \x01(\x04R\fexpirationMs\x12\x19\n" + - "\x05epoch\x18\x06 \x01(\fH\x01R\x05epoch\x88\x01\x01\"9\n" + + "\fexpirationMs\x18\x05 \x01(\x04R\fexpirationMs\"9\n" + "\fRestrictions\x12\v\n" + "\aUNKNOWN\x10\x00\x12\b\n" + "\x04NONE\x10\x01\x12\x12\n" + "\x0eADMIN_APPROVAL\x10\x02B\v\n" + - "\t_adminKeyB\b\n" + - "\x06_epoch\"\xca\x01\n" + + "\t_adminKeyJ\x04\b\x06\x10\a\"\xca\x01\n" + "\tAdHocCall\x12\x16\n" + "\x06callId\x18\x01 \x01(\x04R\x06callId\x12 \n" + "\vrecipientId\x18\x02 \x01(\x04R\vrecipientId\x124\n" + @@ -12354,7 +12583,7 @@ const file_backuppb_Backup_proto_rawDesc = "" + "\tONLY_WITH\x10\x01\x12\x0e\n" + "\n" + "ALL_EXCEPT\x10\x02\x12\a\n" + - "\x03ALL\x10\x03\"\xe5\x0e\n" + + "\x03ALL\x10\x03\"\xbd\x0f\n" + "\bChatItem\x12\x16\n" + "\x06chatId\x18\x01 \x01(\x04R\x06chatId\x12\x1a\n" + "\bauthorId\x18\x02 \x01(\x04R\bauthorId\x12\x1a\n" + @@ -12376,7 +12605,8 @@ const file_backuppb_Backup_proto_rawDesc = "" + "\tgiftBadge\x18\x11 \x01(\v2\x18.signal.backup.GiftBadgeH\x01R\tgiftBadge\x12J\n" + "\x0fviewOnceMessage\x18\x12 \x01(\v2\x1e.signal.backup.ViewOnceMessageH\x01R\x0fviewOnceMessage\x12b\n" + "\x17directStoryReplyMessage\x18\x13 \x01(\v2&.signal.backup.DirectStoryReplyMessageH\x01R\x17directStoryReplyMessage\x12)\n" + - "\x04poll\x18\x14 \x01(\v2\x13.signal.backup.PollH\x01R\x04poll\x12B\n" + + "\x04poll\x18\x14 \x01(\v2\x13.signal.backup.PollH\x01R\x04poll\x12V\n" + + "\x13adminDeletedMessage\x18\x16 \x01(\v2\".signal.backup.AdminDeletedMessageH\x01R\x13adminDeletedMessage\x12B\n" + "\n" + "pinDetails\x18\x15 \x01(\v2\".signal.backup.ChatItem.PinDetailsR\n" + "pinDetails\x1a\xb4\x01\n" + @@ -12706,7 +12936,9 @@ const file_backuppb_Backup_proto_rawDesc = "" + "\x05votes\x18\x02 \x03(\v2'.signal.backup.Poll.PollOption.PollVoteR\x05votes\x1aB\n" + "\bPollVote\x12\x18\n" + "\avoterId\x18\x01 \x01(\x04R\avoterId\x12\x1c\n" + - "\tvoteCount\x18\x02 \x01(\rR\tvoteCount\"\xf7\x06\n" + + "\tvoteCount\x18\x02 \x01(\rR\tvoteCount\"/\n" + + "\x13AdminDeletedMessage\x12\x18\n" + + "\aadminId\x18\x01 \x01(\x04R\aadminId\"\xf7\x06\n" + "\x11ChatUpdateMessage\x12E\n" + "\fsimpleUpdate\x18\x01 \x01(\v2\x1f.signal.backup.SimpleChatUpdateH\x00R\fsimpleUpdate\x12H\n" + "\vgroupChange\x18\x02 \x01(\v2$.signal.backup.GroupChangeChatUpdateH\x00R\vgroupChange\x12`\n" + @@ -12805,9 +13037,9 @@ const file_backuppb_Backup_proto_rawDesc = "" + "\x15ThreadMergeChatUpdate\x12\"\n" + "\fpreviousE164\x18\x01 \x01(\x04R\fpreviousE164\"1\n" + "\x1bSessionSwitchoverChatUpdate\x12\x12\n" + - "\x04e164\x18\x01 \x01(\x04R\x04e164\"\x86\x1f\n" + + "\x04e164\x18\x01 \x01(\x04R\x04e164\"\x88!\n" + "\x15GroupChangeChatUpdate\x12E\n" + - "\aupdates\x18\x01 \x03(\v2+.signal.backup.GroupChangeChatUpdate.UpdateR\aupdates\x1a\xa5\x1e\n" + + "\aupdates\x18\x01 \x03(\v2+.signal.backup.GroupChangeChatUpdate.UpdateR\aupdates\x1a\xa7 \n" + "\x06Update\x12S\n" + "\x12genericGroupUpdate\x18\x01 \x01(\v2!.signal.backup.GenericGroupUpdateH\x00R\x12genericGroupUpdate\x12V\n" + "\x13groupCreationUpdate\x18\x02 \x01(\v2\".signal.backup.GroupCreationUpdateH\x00R\x13groupCreationUpdate\x12J\n" + @@ -12843,7 +13075,9 @@ const file_backuppb_Backup_proto_rawDesc = "" + "$groupV2MigrationInvitedMembersUpdate\x18\x1f \x01(\v23.signal.backup.GroupV2MigrationInvitedMembersUpdateH\x00R$groupV2MigrationInvitedMembersUpdate\x12\x89\x01\n" + "$groupV2MigrationDroppedMembersUpdate\x18 \x01(\v23.signal.backup.GroupV2MigrationDroppedMembersUpdateH\x00R$groupV2MigrationDroppedMembersUpdate\x12\x92\x01\n" + "'groupSequenceOfRequestsAndCancelsUpdate\x18! \x01(\v26.signal.backup.GroupSequenceOfRequestsAndCancelsUpdateH\x00R'groupSequenceOfRequestsAndCancelsUpdate\x12k\n" + - "\x1agroupExpirationTimerUpdate\x18\" \x01(\v2).signal.backup.GroupExpirationTimerUpdateH\x00R\x1agroupExpirationTimerUpdateB\b\n" + + "\x1agroupExpirationTimerUpdate\x18\" \x01(\v2).signal.backup.GroupExpirationTimerUpdateH\x00R\x1agroupExpirationTimerUpdate\x12\x92\x01\n" + + "'groupMemberLabelAccessLevelChangeUpdate\x18# \x01(\v26.signal.backup.GroupMemberLabelAccessLevelChangeUpdateH\x00R'groupMemberLabelAccessLevelChangeUpdate\x12k\n" + + "\x1agroupTerminateChangeUpdate\x18$ \x01(\v2).signal.backup.GroupTerminateChangeUpdateH\x00R\x1agroupTerminateChangeUpdateB\b\n" + "\x06update\"H\n" + "\x12GenericGroupUpdate\x12#\n" + "\n" + @@ -12888,6 +13122,17 @@ const file_backuppb_Backup_proto_rawDesc = "" + "updaterAci\x18\x01 \x01(\fH\x00R\n" + "updaterAci\x88\x01\x01\x12C\n" + "\vaccessLevel\x18\x02 \x01(\x0e2!.signal.backup.GroupV2AccessLevelR\vaccessLevelB\r\n" + + "\v_updaterAci\"\xa2\x01\n" + + "'GroupMemberLabelAccessLevelChangeUpdate\x12#\n" + + "\n" + + "updaterAci\x18\x01 \x01(\fH\x00R\n" + + "updaterAci\x88\x01\x01\x12C\n" + + "\vaccessLevel\x18\x02 \x01(\x0e2!.signal.backup.GroupV2AccessLevelR\vaccessLevelB\r\n" + + "\v_updaterAci\"P\n" + + "\x1aGroupTerminateChangeUpdate\x12#\n" + + "\n" + + "updaterAci\x18\x01 \x01(\fH\x00R\n" + + "updaterAci\x88\x01\x01B\r\n" + "\v_updaterAci\"\x87\x01\n" + "!GroupAnnouncementOnlyChangeUpdate\x12#\n" + "\n" + @@ -13176,8 +13421,8 @@ const file_backuppb_Backup_proto_rawDesc = "" + "\n" + "\x06MEMBER\x10\x02\x12\x11\n" + "\rADMINISTRATOR\x10\x03\x12\x11\n" + - "\rUNSATISFIABLE\x10\x04B;\n" + - "*org.thoughtcrime.securesms.backup.v2.proto\xba\x02\fBackupProto_b\x06proto3" + "\rUNSATISFIABLE\x10\x04B)\n" + + "\x18org.signal.archive.proto\xba\x02\fBackupProto_b\x06proto3" var ( file_backuppb_Backup_proto_rawDescOnce sync.Once @@ -13192,7 +13437,7 @@ func file_backuppb_Backup_proto_rawDescGZIP() []byte { } var file_backuppb_Backup_proto_enumTypes = make([]protoimpl.EnumInfo, 36) -var file_backuppb_Backup_proto_msgTypes = make([]protoimpl.MessageInfo, 128) +var file_backuppb_Backup_proto_msgTypes = make([]protoimpl.MessageInfo, 131) var file_backuppb_Backup_proto_goTypes = []any{ (AvatarColor)(0), // 0: signal.backup.AvatarColor (GroupV2AccessLevel)(0), // 1: signal.backup.GroupV2AccessLevel @@ -13263,116 +13508,119 @@ var file_backuppb_Backup_proto_goTypes = []any{ (*BodyRange)(nil), // 66: signal.backup.BodyRange (*Reaction)(nil), // 67: signal.backup.Reaction (*Poll)(nil), // 68: signal.backup.Poll - (*ChatUpdateMessage)(nil), // 69: signal.backup.ChatUpdateMessage - (*IndividualCall)(nil), // 70: signal.backup.IndividualCall - (*GroupCall)(nil), // 71: signal.backup.GroupCall - (*SimpleChatUpdate)(nil), // 72: signal.backup.SimpleChatUpdate - (*ExpirationTimerChatUpdate)(nil), // 73: signal.backup.ExpirationTimerChatUpdate - (*ProfileChangeChatUpdate)(nil), // 74: signal.backup.ProfileChangeChatUpdate - (*LearnedProfileChatUpdate)(nil), // 75: signal.backup.LearnedProfileChatUpdate - (*ThreadMergeChatUpdate)(nil), // 76: signal.backup.ThreadMergeChatUpdate - (*SessionSwitchoverChatUpdate)(nil), // 77: signal.backup.SessionSwitchoverChatUpdate - (*GroupChangeChatUpdate)(nil), // 78: signal.backup.GroupChangeChatUpdate - (*GenericGroupUpdate)(nil), // 79: signal.backup.GenericGroupUpdate - (*GroupCreationUpdate)(nil), // 80: signal.backup.GroupCreationUpdate - (*GroupNameUpdate)(nil), // 81: signal.backup.GroupNameUpdate - (*GroupAvatarUpdate)(nil), // 82: signal.backup.GroupAvatarUpdate - (*GroupDescriptionUpdate)(nil), // 83: signal.backup.GroupDescriptionUpdate - (*GroupMembershipAccessLevelChangeUpdate)(nil), // 84: signal.backup.GroupMembershipAccessLevelChangeUpdate - (*GroupAttributesAccessLevelChangeUpdate)(nil), // 85: signal.backup.GroupAttributesAccessLevelChangeUpdate - (*GroupAnnouncementOnlyChangeUpdate)(nil), // 86: signal.backup.GroupAnnouncementOnlyChangeUpdate - (*GroupAdminStatusUpdate)(nil), // 87: signal.backup.GroupAdminStatusUpdate - (*GroupMemberLeftUpdate)(nil), // 88: signal.backup.GroupMemberLeftUpdate - (*GroupMemberRemovedUpdate)(nil), // 89: signal.backup.GroupMemberRemovedUpdate - (*SelfInvitedToGroupUpdate)(nil), // 90: signal.backup.SelfInvitedToGroupUpdate - (*SelfInvitedOtherUserToGroupUpdate)(nil), // 91: signal.backup.SelfInvitedOtherUserToGroupUpdate - (*GroupUnknownInviteeUpdate)(nil), // 92: signal.backup.GroupUnknownInviteeUpdate - (*GroupInvitationAcceptedUpdate)(nil), // 93: signal.backup.GroupInvitationAcceptedUpdate - (*GroupInvitationDeclinedUpdate)(nil), // 94: signal.backup.GroupInvitationDeclinedUpdate - (*GroupMemberJoinedUpdate)(nil), // 95: signal.backup.GroupMemberJoinedUpdate - (*GroupMemberAddedUpdate)(nil), // 96: signal.backup.GroupMemberAddedUpdate - (*GroupSelfInvitationRevokedUpdate)(nil), // 97: signal.backup.GroupSelfInvitationRevokedUpdate - (*GroupInvitationRevokedUpdate)(nil), // 98: signal.backup.GroupInvitationRevokedUpdate - (*GroupJoinRequestUpdate)(nil), // 99: signal.backup.GroupJoinRequestUpdate - (*GroupJoinRequestApprovalUpdate)(nil), // 100: signal.backup.GroupJoinRequestApprovalUpdate - (*GroupJoinRequestCanceledUpdate)(nil), // 101: signal.backup.GroupJoinRequestCanceledUpdate - (*GroupSequenceOfRequestsAndCancelsUpdate)(nil), // 102: signal.backup.GroupSequenceOfRequestsAndCancelsUpdate - (*GroupInviteLinkResetUpdate)(nil), // 103: signal.backup.GroupInviteLinkResetUpdate - (*GroupInviteLinkEnabledUpdate)(nil), // 104: signal.backup.GroupInviteLinkEnabledUpdate - (*GroupInviteLinkAdminApprovalUpdate)(nil), // 105: signal.backup.GroupInviteLinkAdminApprovalUpdate - (*GroupInviteLinkDisabledUpdate)(nil), // 106: signal.backup.GroupInviteLinkDisabledUpdate - (*GroupMemberJoinedByLinkUpdate)(nil), // 107: signal.backup.GroupMemberJoinedByLinkUpdate - (*GroupV2MigrationUpdate)(nil), // 108: signal.backup.GroupV2MigrationUpdate - (*GroupV2MigrationSelfInvitedUpdate)(nil), // 109: signal.backup.GroupV2MigrationSelfInvitedUpdate - (*GroupV2MigrationInvitedMembersUpdate)(nil), // 110: signal.backup.GroupV2MigrationInvitedMembersUpdate - (*GroupV2MigrationDroppedMembersUpdate)(nil), // 111: signal.backup.GroupV2MigrationDroppedMembersUpdate - (*GroupExpirationTimerUpdate)(nil), // 112: signal.backup.GroupExpirationTimerUpdate - (*PollTerminateUpdate)(nil), // 113: signal.backup.PollTerminateUpdate - (*PinMessageUpdate)(nil), // 114: signal.backup.PinMessageUpdate - (*StickerPack)(nil), // 115: signal.backup.StickerPack - (*ChatStyle)(nil), // 116: signal.backup.ChatStyle - (*NotificationProfile)(nil), // 117: signal.backup.NotificationProfile - (*ChatFolder)(nil), // 118: signal.backup.ChatFolder - (*AccountData_UsernameLink)(nil), // 119: signal.backup.AccountData.UsernameLink - (*AccountData_AutoDownloadSettings)(nil), // 120: signal.backup.AccountData.AutoDownloadSettings - (*AccountData_AccountSettings)(nil), // 121: signal.backup.AccountData.AccountSettings - (*AccountData_SubscriberData)(nil), // 122: signal.backup.AccountData.SubscriberData - (*AccountData_IAPSubscriberData)(nil), // 123: signal.backup.AccountData.IAPSubscriberData - (*AccountData_AndroidSpecificSettings)(nil), // 124: signal.backup.AccountData.AndroidSpecificSettings - (*Contact_Registered)(nil), // 125: signal.backup.Contact.Registered - (*Contact_NotRegistered)(nil), // 126: signal.backup.Contact.NotRegistered - (*Contact_Name)(nil), // 127: signal.backup.Contact.Name - (*Group_GroupSnapshot)(nil), // 128: signal.backup.Group.GroupSnapshot - (*Group_GroupAttributeBlob)(nil), // 129: signal.backup.Group.GroupAttributeBlob - (*Group_Member)(nil), // 130: signal.backup.Group.Member - (*Group_MemberPendingProfileKey)(nil), // 131: signal.backup.Group.MemberPendingProfileKey - (*Group_MemberPendingAdminApproval)(nil), // 132: signal.backup.Group.MemberPendingAdminApproval - (*Group_MemberBanned)(nil), // 133: signal.backup.Group.MemberBanned - (*Group_AccessControl)(nil), // 134: signal.backup.Group.AccessControl - (*ChatItem_IncomingMessageDetails)(nil), // 135: signal.backup.ChatItem.IncomingMessageDetails - (*ChatItem_OutgoingMessageDetails)(nil), // 136: signal.backup.ChatItem.OutgoingMessageDetails - (*ChatItem_DirectionlessMessageDetails)(nil), // 137: signal.backup.ChatItem.DirectionlessMessageDetails - (*ChatItem_PinDetails)(nil), // 138: signal.backup.ChatItem.PinDetails - (*SendStatus_Pending)(nil), // 139: signal.backup.SendStatus.Pending - (*SendStatus_Sent)(nil), // 140: signal.backup.SendStatus.Sent - (*SendStatus_Delivered)(nil), // 141: signal.backup.SendStatus.Delivered - (*SendStatus_Read)(nil), // 142: signal.backup.SendStatus.Read - (*SendStatus_Viewed)(nil), // 143: signal.backup.SendStatus.Viewed - (*SendStatus_Skipped)(nil), // 144: signal.backup.SendStatus.Skipped - (*SendStatus_Failed)(nil), // 145: signal.backup.SendStatus.Failed - (*DirectStoryReplyMessage_TextReply)(nil), // 146: signal.backup.DirectStoryReplyMessage.TextReply - (*PaymentNotification_TransactionDetails)(nil), // 147: signal.backup.PaymentNotification.TransactionDetails - (*PaymentNotification_TransactionDetails_MobileCoinTxoIdentification)(nil), // 148: signal.backup.PaymentNotification.TransactionDetails.MobileCoinTxoIdentification - (*PaymentNotification_TransactionDetails_FailedTransaction)(nil), // 149: signal.backup.PaymentNotification.TransactionDetails.FailedTransaction - (*PaymentNotification_TransactionDetails_Transaction)(nil), // 150: signal.backup.PaymentNotification.TransactionDetails.Transaction - (*ContactAttachment_Name)(nil), // 151: signal.backup.ContactAttachment.Name - (*ContactAttachment_Phone)(nil), // 152: signal.backup.ContactAttachment.Phone - (*ContactAttachment_Email)(nil), // 153: signal.backup.ContactAttachment.Email - (*ContactAttachment_PostalAddress)(nil), // 154: signal.backup.ContactAttachment.PostalAddress - (*FilePointer_LocatorInfo)(nil), // 155: signal.backup.FilePointer.LocatorInfo - (*Quote_QuotedAttachment)(nil), // 156: signal.backup.Quote.QuotedAttachment - (*Poll_PollOption)(nil), // 157: signal.backup.Poll.PollOption - (*Poll_PollOption_PollVote)(nil), // 158: signal.backup.Poll.PollOption.PollVote - (*GroupChangeChatUpdate_Update)(nil), // 159: signal.backup.GroupChangeChatUpdate.Update - (*GroupInvitationRevokedUpdate_Invitee)(nil), // 160: signal.backup.GroupInvitationRevokedUpdate.Invitee - (*ChatStyle_Gradient)(nil), // 161: signal.backup.ChatStyle.Gradient - (*ChatStyle_CustomChatColor)(nil), // 162: signal.backup.ChatStyle.CustomChatColor - (*ChatStyle_AutomaticBubbleColor)(nil), // 163: signal.backup.ChatStyle.AutomaticBubbleColor + (*AdminDeletedMessage)(nil), // 69: signal.backup.AdminDeletedMessage + (*ChatUpdateMessage)(nil), // 70: signal.backup.ChatUpdateMessage + (*IndividualCall)(nil), // 71: signal.backup.IndividualCall + (*GroupCall)(nil), // 72: signal.backup.GroupCall + (*SimpleChatUpdate)(nil), // 73: signal.backup.SimpleChatUpdate + (*ExpirationTimerChatUpdate)(nil), // 74: signal.backup.ExpirationTimerChatUpdate + (*ProfileChangeChatUpdate)(nil), // 75: signal.backup.ProfileChangeChatUpdate + (*LearnedProfileChatUpdate)(nil), // 76: signal.backup.LearnedProfileChatUpdate + (*ThreadMergeChatUpdate)(nil), // 77: signal.backup.ThreadMergeChatUpdate + (*SessionSwitchoverChatUpdate)(nil), // 78: signal.backup.SessionSwitchoverChatUpdate + (*GroupChangeChatUpdate)(nil), // 79: signal.backup.GroupChangeChatUpdate + (*GenericGroupUpdate)(nil), // 80: signal.backup.GenericGroupUpdate + (*GroupCreationUpdate)(nil), // 81: signal.backup.GroupCreationUpdate + (*GroupNameUpdate)(nil), // 82: signal.backup.GroupNameUpdate + (*GroupAvatarUpdate)(nil), // 83: signal.backup.GroupAvatarUpdate + (*GroupDescriptionUpdate)(nil), // 84: signal.backup.GroupDescriptionUpdate + (*GroupMembershipAccessLevelChangeUpdate)(nil), // 85: signal.backup.GroupMembershipAccessLevelChangeUpdate + (*GroupAttributesAccessLevelChangeUpdate)(nil), // 86: signal.backup.GroupAttributesAccessLevelChangeUpdate + (*GroupMemberLabelAccessLevelChangeUpdate)(nil), // 87: signal.backup.GroupMemberLabelAccessLevelChangeUpdate + (*GroupTerminateChangeUpdate)(nil), // 88: signal.backup.GroupTerminateChangeUpdate + (*GroupAnnouncementOnlyChangeUpdate)(nil), // 89: signal.backup.GroupAnnouncementOnlyChangeUpdate + (*GroupAdminStatusUpdate)(nil), // 90: signal.backup.GroupAdminStatusUpdate + (*GroupMemberLeftUpdate)(nil), // 91: signal.backup.GroupMemberLeftUpdate + (*GroupMemberRemovedUpdate)(nil), // 92: signal.backup.GroupMemberRemovedUpdate + (*SelfInvitedToGroupUpdate)(nil), // 93: signal.backup.SelfInvitedToGroupUpdate + (*SelfInvitedOtherUserToGroupUpdate)(nil), // 94: signal.backup.SelfInvitedOtherUserToGroupUpdate + (*GroupUnknownInviteeUpdate)(nil), // 95: signal.backup.GroupUnknownInviteeUpdate + (*GroupInvitationAcceptedUpdate)(nil), // 96: signal.backup.GroupInvitationAcceptedUpdate + (*GroupInvitationDeclinedUpdate)(nil), // 97: signal.backup.GroupInvitationDeclinedUpdate + (*GroupMemberJoinedUpdate)(nil), // 98: signal.backup.GroupMemberJoinedUpdate + (*GroupMemberAddedUpdate)(nil), // 99: signal.backup.GroupMemberAddedUpdate + (*GroupSelfInvitationRevokedUpdate)(nil), // 100: signal.backup.GroupSelfInvitationRevokedUpdate + (*GroupInvitationRevokedUpdate)(nil), // 101: signal.backup.GroupInvitationRevokedUpdate + (*GroupJoinRequestUpdate)(nil), // 102: signal.backup.GroupJoinRequestUpdate + (*GroupJoinRequestApprovalUpdate)(nil), // 103: signal.backup.GroupJoinRequestApprovalUpdate + (*GroupJoinRequestCanceledUpdate)(nil), // 104: signal.backup.GroupJoinRequestCanceledUpdate + (*GroupSequenceOfRequestsAndCancelsUpdate)(nil), // 105: signal.backup.GroupSequenceOfRequestsAndCancelsUpdate + (*GroupInviteLinkResetUpdate)(nil), // 106: signal.backup.GroupInviteLinkResetUpdate + (*GroupInviteLinkEnabledUpdate)(nil), // 107: signal.backup.GroupInviteLinkEnabledUpdate + (*GroupInviteLinkAdminApprovalUpdate)(nil), // 108: signal.backup.GroupInviteLinkAdminApprovalUpdate + (*GroupInviteLinkDisabledUpdate)(nil), // 109: signal.backup.GroupInviteLinkDisabledUpdate + (*GroupMemberJoinedByLinkUpdate)(nil), // 110: signal.backup.GroupMemberJoinedByLinkUpdate + (*GroupV2MigrationUpdate)(nil), // 111: signal.backup.GroupV2MigrationUpdate + (*GroupV2MigrationSelfInvitedUpdate)(nil), // 112: signal.backup.GroupV2MigrationSelfInvitedUpdate + (*GroupV2MigrationInvitedMembersUpdate)(nil), // 113: signal.backup.GroupV2MigrationInvitedMembersUpdate + (*GroupV2MigrationDroppedMembersUpdate)(nil), // 114: signal.backup.GroupV2MigrationDroppedMembersUpdate + (*GroupExpirationTimerUpdate)(nil), // 115: signal.backup.GroupExpirationTimerUpdate + (*PollTerminateUpdate)(nil), // 116: signal.backup.PollTerminateUpdate + (*PinMessageUpdate)(nil), // 117: signal.backup.PinMessageUpdate + (*StickerPack)(nil), // 118: signal.backup.StickerPack + (*ChatStyle)(nil), // 119: signal.backup.ChatStyle + (*NotificationProfile)(nil), // 120: signal.backup.NotificationProfile + (*ChatFolder)(nil), // 121: signal.backup.ChatFolder + (*AccountData_UsernameLink)(nil), // 122: signal.backup.AccountData.UsernameLink + (*AccountData_AutoDownloadSettings)(nil), // 123: signal.backup.AccountData.AutoDownloadSettings + (*AccountData_AccountSettings)(nil), // 124: signal.backup.AccountData.AccountSettings + (*AccountData_SubscriberData)(nil), // 125: signal.backup.AccountData.SubscriberData + (*AccountData_IAPSubscriberData)(nil), // 126: signal.backup.AccountData.IAPSubscriberData + (*AccountData_AndroidSpecificSettings)(nil), // 127: signal.backup.AccountData.AndroidSpecificSettings + (*Contact_Registered)(nil), // 128: signal.backup.Contact.Registered + (*Contact_NotRegistered)(nil), // 129: signal.backup.Contact.NotRegistered + (*Contact_Name)(nil), // 130: signal.backup.Contact.Name + (*Group_GroupSnapshot)(nil), // 131: signal.backup.Group.GroupSnapshot + (*Group_GroupAttributeBlob)(nil), // 132: signal.backup.Group.GroupAttributeBlob + (*Group_Member)(nil), // 133: signal.backup.Group.Member + (*Group_MemberPendingProfileKey)(nil), // 134: signal.backup.Group.MemberPendingProfileKey + (*Group_MemberPendingAdminApproval)(nil), // 135: signal.backup.Group.MemberPendingAdminApproval + (*Group_MemberBanned)(nil), // 136: signal.backup.Group.MemberBanned + (*Group_AccessControl)(nil), // 137: signal.backup.Group.AccessControl + (*ChatItem_IncomingMessageDetails)(nil), // 138: signal.backup.ChatItem.IncomingMessageDetails + (*ChatItem_OutgoingMessageDetails)(nil), // 139: signal.backup.ChatItem.OutgoingMessageDetails + (*ChatItem_DirectionlessMessageDetails)(nil), // 140: signal.backup.ChatItem.DirectionlessMessageDetails + (*ChatItem_PinDetails)(nil), // 141: signal.backup.ChatItem.PinDetails + (*SendStatus_Pending)(nil), // 142: signal.backup.SendStatus.Pending + (*SendStatus_Sent)(nil), // 143: signal.backup.SendStatus.Sent + (*SendStatus_Delivered)(nil), // 144: signal.backup.SendStatus.Delivered + (*SendStatus_Read)(nil), // 145: signal.backup.SendStatus.Read + (*SendStatus_Viewed)(nil), // 146: signal.backup.SendStatus.Viewed + (*SendStatus_Skipped)(nil), // 147: signal.backup.SendStatus.Skipped + (*SendStatus_Failed)(nil), // 148: signal.backup.SendStatus.Failed + (*DirectStoryReplyMessage_TextReply)(nil), // 149: signal.backup.DirectStoryReplyMessage.TextReply + (*PaymentNotification_TransactionDetails)(nil), // 150: signal.backup.PaymentNotification.TransactionDetails + (*PaymentNotification_TransactionDetails_MobileCoinTxoIdentification)(nil), // 151: signal.backup.PaymentNotification.TransactionDetails.MobileCoinTxoIdentification + (*PaymentNotification_TransactionDetails_FailedTransaction)(nil), // 152: signal.backup.PaymentNotification.TransactionDetails.FailedTransaction + (*PaymentNotification_TransactionDetails_Transaction)(nil), // 153: signal.backup.PaymentNotification.TransactionDetails.Transaction + (*ContactAttachment_Name)(nil), // 154: signal.backup.ContactAttachment.Name + (*ContactAttachment_Phone)(nil), // 155: signal.backup.ContactAttachment.Phone + (*ContactAttachment_Email)(nil), // 156: signal.backup.ContactAttachment.Email + (*ContactAttachment_PostalAddress)(nil), // 157: signal.backup.ContactAttachment.PostalAddress + (*FilePointer_LocatorInfo)(nil), // 158: signal.backup.FilePointer.LocatorInfo + (*Quote_QuotedAttachment)(nil), // 159: signal.backup.Quote.QuotedAttachment + (*Poll_PollOption)(nil), // 160: signal.backup.Poll.PollOption + (*Poll_PollOption_PollVote)(nil), // 161: signal.backup.Poll.PollOption.PollVote + (*GroupChangeChatUpdate_Update)(nil), // 162: signal.backup.GroupChangeChatUpdate.Update + (*GroupInvitationRevokedUpdate_Invitee)(nil), // 163: signal.backup.GroupInvitationRevokedUpdate.Invitee + (*ChatStyle_Gradient)(nil), // 164: signal.backup.ChatStyle.Gradient + (*ChatStyle_CustomChatColor)(nil), // 165: signal.backup.ChatStyle.CustomChatColor + (*ChatStyle_AutomaticBubbleColor)(nil), // 166: signal.backup.ChatStyle.AutomaticBubbleColor } var file_backuppb_Backup_proto_depIdxs = []int32{ 38, // 0: signal.backup.Frame.account:type_name -> signal.backup.AccountData 39, // 1: signal.backup.Frame.recipient:type_name -> signal.backup.Recipient 44, // 2: signal.backup.Frame.chat:type_name -> signal.backup.Chat 49, // 3: signal.backup.Frame.chatItem:type_name -> signal.backup.ChatItem - 115, // 4: signal.backup.Frame.stickerPack:type_name -> signal.backup.StickerPack + 118, // 4: signal.backup.Frame.stickerPack:type_name -> signal.backup.StickerPack 46, // 5: signal.backup.Frame.adHocCall:type_name -> signal.backup.AdHocCall - 117, // 6: signal.backup.Frame.notificationProfile:type_name -> signal.backup.NotificationProfile - 118, // 7: signal.backup.Frame.chatFolder:type_name -> signal.backup.ChatFolder - 119, // 8: signal.backup.AccountData.usernameLink:type_name -> signal.backup.AccountData.UsernameLink - 122, // 9: signal.backup.AccountData.donationSubscriberData:type_name -> signal.backup.AccountData.SubscriberData - 121, // 10: signal.backup.AccountData.accountSettings:type_name -> signal.backup.AccountData.AccountSettings - 123, // 11: signal.backup.AccountData.backupsSubscriberData:type_name -> signal.backup.AccountData.IAPSubscriberData - 124, // 12: signal.backup.AccountData.androidSpecificSettings:type_name -> signal.backup.AccountData.AndroidSpecificSettings + 120, // 6: signal.backup.Frame.notificationProfile:type_name -> signal.backup.NotificationProfile + 121, // 7: signal.backup.Frame.chatFolder:type_name -> signal.backup.ChatFolder + 122, // 8: signal.backup.AccountData.usernameLink:type_name -> signal.backup.AccountData.UsernameLink + 125, // 9: signal.backup.AccountData.donationSubscriberData:type_name -> signal.backup.AccountData.SubscriberData + 124, // 10: signal.backup.AccountData.accountSettings:type_name -> signal.backup.AccountData.AccountSettings + 126, // 11: signal.backup.AccountData.backupsSubscriberData:type_name -> signal.backup.AccountData.IAPSubscriberData + 127, // 12: signal.backup.AccountData.androidSpecificSettings:type_name -> signal.backup.AccountData.AndroidSpecificSettings 40, // 13: signal.backup.Recipient.contact:type_name -> signal.backup.Contact 41, // 14: signal.backup.Recipient.group:type_name -> signal.backup.Group 47, // 15: signal.backup.Recipient.distributionList:type_name -> signal.backup.DistributionListItem @@ -13380,181 +13628,186 @@ var file_backuppb_Backup_proto_depIdxs = []int32{ 43, // 17: signal.backup.Recipient.releaseNotes:type_name -> signal.backup.ReleaseNotes 45, // 18: signal.backup.Recipient.callLink:type_name -> signal.backup.CallLink 10, // 19: signal.backup.Contact.visibility:type_name -> signal.backup.Contact.Visibility - 125, // 20: signal.backup.Contact.registered:type_name -> signal.backup.Contact.Registered - 126, // 21: signal.backup.Contact.notRegistered:type_name -> signal.backup.Contact.NotRegistered + 128, // 20: signal.backup.Contact.registered:type_name -> signal.backup.Contact.Registered + 129, // 21: signal.backup.Contact.notRegistered:type_name -> signal.backup.Contact.NotRegistered 9, // 22: signal.backup.Contact.identityState:type_name -> signal.backup.Contact.IdentityState - 127, // 23: signal.backup.Contact.nickname:type_name -> signal.backup.Contact.Name + 130, // 23: signal.backup.Contact.nickname:type_name -> signal.backup.Contact.Name 0, // 24: signal.backup.Contact.avatarColor:type_name -> signal.backup.AvatarColor 11, // 25: signal.backup.Group.storySendMode:type_name -> signal.backup.Group.StorySendMode - 128, // 26: signal.backup.Group.snapshot:type_name -> signal.backup.Group.GroupSnapshot + 131, // 26: signal.backup.Group.snapshot:type_name -> signal.backup.Group.GroupSnapshot 0, // 27: signal.backup.Group.avatarColor:type_name -> signal.backup.AvatarColor 0, // 28: signal.backup.Self.avatarColor:type_name -> signal.backup.AvatarColor - 116, // 29: signal.backup.Chat.style:type_name -> signal.backup.ChatStyle + 119, // 29: signal.backup.Chat.style:type_name -> signal.backup.ChatStyle 14, // 30: signal.backup.CallLink.restrictions:type_name -> signal.backup.CallLink.Restrictions 15, // 31: signal.backup.AdHocCall.state:type_name -> signal.backup.AdHocCall.State 48, // 32: signal.backup.DistributionListItem.distributionList:type_name -> signal.backup.DistributionList 16, // 33: signal.backup.DistributionList.privacyMode:type_name -> signal.backup.DistributionList.PrivacyMode 49, // 34: signal.backup.ChatItem.revisions:type_name -> signal.backup.ChatItem - 135, // 35: signal.backup.ChatItem.incoming:type_name -> signal.backup.ChatItem.IncomingMessageDetails - 136, // 36: signal.backup.ChatItem.outgoing:type_name -> signal.backup.ChatItem.OutgoingMessageDetails - 137, // 37: signal.backup.ChatItem.directionless:type_name -> signal.backup.ChatItem.DirectionlessMessageDetails + 138, // 35: signal.backup.ChatItem.incoming:type_name -> signal.backup.ChatItem.IncomingMessageDetails + 139, // 36: signal.backup.ChatItem.outgoing:type_name -> signal.backup.ChatItem.OutgoingMessageDetails + 140, // 37: signal.backup.ChatItem.directionless:type_name -> signal.backup.ChatItem.DirectionlessMessageDetails 52, // 38: signal.backup.ChatItem.standardMessage:type_name -> signal.backup.StandardMessage 53, // 39: signal.backup.ChatItem.contactMessage:type_name -> signal.backup.ContactMessage 59, // 40: signal.backup.ChatItem.stickerMessage:type_name -> signal.backup.StickerMessage 60, // 41: signal.backup.ChatItem.remoteDeletedMessage:type_name -> signal.backup.RemoteDeletedMessage - 69, // 42: signal.backup.ChatItem.updateMessage:type_name -> signal.backup.ChatUpdateMessage + 70, // 42: signal.backup.ChatItem.updateMessage:type_name -> signal.backup.ChatUpdateMessage 55, // 43: signal.backup.ChatItem.paymentNotification:type_name -> signal.backup.PaymentNotification 56, // 44: signal.backup.ChatItem.giftBadge:type_name -> signal.backup.GiftBadge 57, // 45: signal.backup.ChatItem.viewOnceMessage:type_name -> signal.backup.ViewOnceMessage 54, // 46: signal.backup.ChatItem.directStoryReplyMessage:type_name -> signal.backup.DirectStoryReplyMessage 68, // 47: signal.backup.ChatItem.poll:type_name -> signal.backup.Poll - 138, // 48: signal.backup.ChatItem.pinDetails:type_name -> signal.backup.ChatItem.PinDetails - 139, // 49: signal.backup.SendStatus.pending:type_name -> signal.backup.SendStatus.Pending - 140, // 50: signal.backup.SendStatus.sent:type_name -> signal.backup.SendStatus.Sent - 141, // 51: signal.backup.SendStatus.delivered:type_name -> signal.backup.SendStatus.Delivered - 142, // 52: signal.backup.SendStatus.read:type_name -> signal.backup.SendStatus.Read - 143, // 53: signal.backup.SendStatus.viewed:type_name -> signal.backup.SendStatus.Viewed - 144, // 54: signal.backup.SendStatus.skipped:type_name -> signal.backup.SendStatus.Skipped - 145, // 55: signal.backup.SendStatus.failed:type_name -> signal.backup.SendStatus.Failed - 66, // 56: signal.backup.Text.bodyRanges:type_name -> signal.backup.BodyRange - 65, // 57: signal.backup.StandardMessage.quote:type_name -> signal.backup.Quote - 51, // 58: signal.backup.StandardMessage.text:type_name -> signal.backup.Text - 63, // 59: signal.backup.StandardMessage.attachments:type_name -> signal.backup.MessageAttachment - 62, // 60: signal.backup.StandardMessage.linkPreview:type_name -> signal.backup.LinkPreview - 64, // 61: signal.backup.StandardMessage.longText:type_name -> signal.backup.FilePointer - 67, // 62: signal.backup.StandardMessage.reactions:type_name -> signal.backup.Reaction - 58, // 63: signal.backup.ContactMessage.contact:type_name -> signal.backup.ContactAttachment - 67, // 64: signal.backup.ContactMessage.reactions:type_name -> signal.backup.Reaction - 146, // 65: signal.backup.DirectStoryReplyMessage.textReply:type_name -> signal.backup.DirectStoryReplyMessage.TextReply - 67, // 66: signal.backup.DirectStoryReplyMessage.reactions:type_name -> signal.backup.Reaction - 147, // 67: signal.backup.PaymentNotification.transactionDetails:type_name -> signal.backup.PaymentNotification.TransactionDetails - 20, // 68: signal.backup.GiftBadge.state:type_name -> signal.backup.GiftBadge.State - 63, // 69: signal.backup.ViewOnceMessage.attachment:type_name -> signal.backup.MessageAttachment - 67, // 70: signal.backup.ViewOnceMessage.reactions:type_name -> signal.backup.Reaction - 151, // 71: signal.backup.ContactAttachment.name:type_name -> signal.backup.ContactAttachment.Name - 152, // 72: signal.backup.ContactAttachment.number:type_name -> signal.backup.ContactAttachment.Phone - 153, // 73: signal.backup.ContactAttachment.email:type_name -> signal.backup.ContactAttachment.Email - 154, // 74: signal.backup.ContactAttachment.address:type_name -> signal.backup.ContactAttachment.PostalAddress - 64, // 75: signal.backup.ContactAttachment.avatar:type_name -> signal.backup.FilePointer - 61, // 76: signal.backup.StickerMessage.sticker:type_name -> signal.backup.Sticker - 67, // 77: signal.backup.StickerMessage.reactions:type_name -> signal.backup.Reaction - 64, // 78: signal.backup.Sticker.data:type_name -> signal.backup.FilePointer - 64, // 79: signal.backup.LinkPreview.image:type_name -> signal.backup.FilePointer - 64, // 80: signal.backup.MessageAttachment.pointer:type_name -> signal.backup.FilePointer - 24, // 81: signal.backup.MessageAttachment.flag:type_name -> signal.backup.MessageAttachment.Flag - 155, // 82: signal.backup.FilePointer.locatorInfo:type_name -> signal.backup.FilePointer.LocatorInfo - 51, // 83: signal.backup.Quote.text:type_name -> signal.backup.Text - 156, // 84: signal.backup.Quote.attachments:type_name -> signal.backup.Quote.QuotedAttachment - 25, // 85: signal.backup.Quote.type:type_name -> signal.backup.Quote.Type - 26, // 86: signal.backup.BodyRange.style:type_name -> signal.backup.BodyRange.Style - 157, // 87: signal.backup.Poll.options:type_name -> signal.backup.Poll.PollOption - 67, // 88: signal.backup.Poll.reactions:type_name -> signal.backup.Reaction - 72, // 89: signal.backup.ChatUpdateMessage.simpleUpdate:type_name -> signal.backup.SimpleChatUpdate - 78, // 90: signal.backup.ChatUpdateMessage.groupChange:type_name -> signal.backup.GroupChangeChatUpdate - 73, // 91: signal.backup.ChatUpdateMessage.expirationTimerChange:type_name -> signal.backup.ExpirationTimerChatUpdate - 74, // 92: signal.backup.ChatUpdateMessage.profileChange:type_name -> signal.backup.ProfileChangeChatUpdate - 76, // 93: signal.backup.ChatUpdateMessage.threadMerge:type_name -> signal.backup.ThreadMergeChatUpdate - 77, // 94: signal.backup.ChatUpdateMessage.sessionSwitchover:type_name -> signal.backup.SessionSwitchoverChatUpdate - 70, // 95: signal.backup.ChatUpdateMessage.individualCall:type_name -> signal.backup.IndividualCall - 71, // 96: signal.backup.ChatUpdateMessage.groupCall:type_name -> signal.backup.GroupCall - 75, // 97: signal.backup.ChatUpdateMessage.learnedProfileChange:type_name -> signal.backup.LearnedProfileChatUpdate - 113, // 98: signal.backup.ChatUpdateMessage.pollTerminate:type_name -> signal.backup.PollTerminateUpdate - 114, // 99: signal.backup.ChatUpdateMessage.pinMessage:type_name -> signal.backup.PinMessageUpdate - 27, // 100: signal.backup.IndividualCall.type:type_name -> signal.backup.IndividualCall.Type - 28, // 101: signal.backup.IndividualCall.direction:type_name -> signal.backup.IndividualCall.Direction - 29, // 102: signal.backup.IndividualCall.state:type_name -> signal.backup.IndividualCall.State - 30, // 103: signal.backup.GroupCall.state:type_name -> signal.backup.GroupCall.State - 31, // 104: signal.backup.SimpleChatUpdate.type:type_name -> signal.backup.SimpleChatUpdate.Type - 159, // 105: signal.backup.GroupChangeChatUpdate.updates:type_name -> signal.backup.GroupChangeChatUpdate.Update - 1, // 106: signal.backup.GroupMembershipAccessLevelChangeUpdate.accessLevel:type_name -> signal.backup.GroupV2AccessLevel - 1, // 107: signal.backup.GroupAttributesAccessLevelChangeUpdate.accessLevel:type_name -> signal.backup.GroupV2AccessLevel - 160, // 108: signal.backup.GroupInvitationRevokedUpdate.invitees:type_name -> signal.backup.GroupInvitationRevokedUpdate.Invitee - 32, // 109: signal.backup.ChatStyle.wallpaperPreset:type_name -> signal.backup.ChatStyle.WallpaperPreset - 64, // 110: signal.backup.ChatStyle.wallpaperPhoto:type_name -> signal.backup.FilePointer - 163, // 111: signal.backup.ChatStyle.autoBubbleColor:type_name -> signal.backup.ChatStyle.AutomaticBubbleColor - 33, // 112: signal.backup.ChatStyle.bubbleColorPreset:type_name -> signal.backup.ChatStyle.BubbleColorPreset - 34, // 113: signal.backup.NotificationProfile.scheduleDaysEnabled:type_name -> signal.backup.NotificationProfile.DayOfWeek - 35, // 114: signal.backup.ChatFolder.folderType:type_name -> signal.backup.ChatFolder.FolderType - 6, // 115: signal.backup.AccountData.UsernameLink.color:type_name -> signal.backup.AccountData.UsernameLink.Color - 7, // 116: signal.backup.AccountData.AutoDownloadSettings.images:type_name -> signal.backup.AccountData.AutoDownloadSettings.AutoDownloadOption - 7, // 117: signal.backup.AccountData.AutoDownloadSettings.audio:type_name -> signal.backup.AccountData.AutoDownloadSettings.AutoDownloadOption - 7, // 118: signal.backup.AccountData.AutoDownloadSettings.video:type_name -> signal.backup.AccountData.AutoDownloadSettings.AutoDownloadOption - 7, // 119: signal.backup.AccountData.AutoDownloadSettings.documents:type_name -> signal.backup.AccountData.AutoDownloadSettings.AutoDownloadOption - 2, // 120: signal.backup.AccountData.AccountSettings.phoneNumberSharingMode:type_name -> signal.backup.AccountData.PhoneNumberSharingMode - 116, // 121: signal.backup.AccountData.AccountSettings.defaultChatStyle:type_name -> signal.backup.ChatStyle - 162, // 122: signal.backup.AccountData.AccountSettings.customChatColors:type_name -> signal.backup.ChatStyle.CustomChatColor - 3, // 123: signal.backup.AccountData.AccountSettings.defaultSentMediaQuality:type_name -> signal.backup.AccountData.SentMediaQuality - 120, // 124: signal.backup.AccountData.AccountSettings.autoDownloadSettings:type_name -> signal.backup.AccountData.AutoDownloadSettings - 4, // 125: signal.backup.AccountData.AccountSettings.appTheme:type_name -> signal.backup.AccountData.AppTheme - 5, // 126: signal.backup.AccountData.AccountSettings.callsUseLessDataSetting:type_name -> signal.backup.AccountData.CallsUseLessDataSetting - 8, // 127: signal.backup.AccountData.AndroidSpecificSettings.navigationBarSize:type_name -> signal.backup.AccountData.AndroidSpecificSettings.NavigationBarSize - 129, // 128: signal.backup.Group.GroupSnapshot.title:type_name -> signal.backup.Group.GroupAttributeBlob - 129, // 129: signal.backup.Group.GroupSnapshot.description:type_name -> signal.backup.Group.GroupAttributeBlob - 129, // 130: signal.backup.Group.GroupSnapshot.disappearingMessagesTimer:type_name -> signal.backup.Group.GroupAttributeBlob - 134, // 131: signal.backup.Group.GroupSnapshot.accessControl:type_name -> signal.backup.Group.AccessControl - 130, // 132: signal.backup.Group.GroupSnapshot.members:type_name -> signal.backup.Group.Member - 131, // 133: signal.backup.Group.GroupSnapshot.membersPendingProfileKey:type_name -> signal.backup.Group.MemberPendingProfileKey - 132, // 134: signal.backup.Group.GroupSnapshot.membersPendingAdminApproval:type_name -> signal.backup.Group.MemberPendingAdminApproval - 133, // 135: signal.backup.Group.GroupSnapshot.members_banned:type_name -> signal.backup.Group.MemberBanned - 12, // 136: signal.backup.Group.Member.role:type_name -> signal.backup.Group.Member.Role - 130, // 137: signal.backup.Group.MemberPendingProfileKey.member:type_name -> signal.backup.Group.Member - 13, // 138: signal.backup.Group.AccessControl.attributes:type_name -> signal.backup.Group.AccessControl.AccessRequired - 13, // 139: signal.backup.Group.AccessControl.members:type_name -> signal.backup.Group.AccessControl.AccessRequired - 13, // 140: signal.backup.Group.AccessControl.addFromInviteLink:type_name -> signal.backup.Group.AccessControl.AccessRequired - 50, // 141: signal.backup.ChatItem.OutgoingMessageDetails.sendStatus:type_name -> signal.backup.SendStatus - 17, // 142: signal.backup.SendStatus.Failed.reason:type_name -> signal.backup.SendStatus.Failed.FailureReason - 51, // 143: signal.backup.DirectStoryReplyMessage.TextReply.text:type_name -> signal.backup.Text - 64, // 144: signal.backup.DirectStoryReplyMessage.TextReply.longText:type_name -> signal.backup.FilePointer - 150, // 145: signal.backup.PaymentNotification.TransactionDetails.transaction:type_name -> signal.backup.PaymentNotification.TransactionDetails.Transaction - 149, // 146: signal.backup.PaymentNotification.TransactionDetails.failedTransaction:type_name -> signal.backup.PaymentNotification.TransactionDetails.FailedTransaction - 18, // 147: signal.backup.PaymentNotification.TransactionDetails.FailedTransaction.reason:type_name -> signal.backup.PaymentNotification.TransactionDetails.FailedTransaction.FailureReason - 19, // 148: signal.backup.PaymentNotification.TransactionDetails.Transaction.status:type_name -> signal.backup.PaymentNotification.TransactionDetails.Transaction.Status - 148, // 149: signal.backup.PaymentNotification.TransactionDetails.Transaction.mobileCoinIdentification:type_name -> signal.backup.PaymentNotification.TransactionDetails.MobileCoinTxoIdentification - 21, // 150: signal.backup.ContactAttachment.Phone.type:type_name -> signal.backup.ContactAttachment.Phone.Type - 22, // 151: signal.backup.ContactAttachment.Email.type:type_name -> signal.backup.ContactAttachment.Email.Type - 23, // 152: signal.backup.ContactAttachment.PostalAddress.type:type_name -> signal.backup.ContactAttachment.PostalAddress.Type - 63, // 153: signal.backup.Quote.QuotedAttachment.thumbnail:type_name -> signal.backup.MessageAttachment - 158, // 154: signal.backup.Poll.PollOption.votes:type_name -> signal.backup.Poll.PollOption.PollVote - 79, // 155: signal.backup.GroupChangeChatUpdate.Update.genericGroupUpdate:type_name -> signal.backup.GenericGroupUpdate - 80, // 156: signal.backup.GroupChangeChatUpdate.Update.groupCreationUpdate:type_name -> signal.backup.GroupCreationUpdate - 81, // 157: signal.backup.GroupChangeChatUpdate.Update.groupNameUpdate:type_name -> signal.backup.GroupNameUpdate - 82, // 158: signal.backup.GroupChangeChatUpdate.Update.groupAvatarUpdate:type_name -> signal.backup.GroupAvatarUpdate - 83, // 159: signal.backup.GroupChangeChatUpdate.Update.groupDescriptionUpdate:type_name -> signal.backup.GroupDescriptionUpdate - 84, // 160: signal.backup.GroupChangeChatUpdate.Update.groupMembershipAccessLevelChangeUpdate:type_name -> signal.backup.GroupMembershipAccessLevelChangeUpdate - 85, // 161: signal.backup.GroupChangeChatUpdate.Update.groupAttributesAccessLevelChangeUpdate:type_name -> signal.backup.GroupAttributesAccessLevelChangeUpdate - 86, // 162: signal.backup.GroupChangeChatUpdate.Update.groupAnnouncementOnlyChangeUpdate:type_name -> signal.backup.GroupAnnouncementOnlyChangeUpdate - 87, // 163: signal.backup.GroupChangeChatUpdate.Update.groupAdminStatusUpdate:type_name -> signal.backup.GroupAdminStatusUpdate - 88, // 164: signal.backup.GroupChangeChatUpdate.Update.groupMemberLeftUpdate:type_name -> signal.backup.GroupMemberLeftUpdate - 89, // 165: signal.backup.GroupChangeChatUpdate.Update.groupMemberRemovedUpdate:type_name -> signal.backup.GroupMemberRemovedUpdate - 90, // 166: signal.backup.GroupChangeChatUpdate.Update.selfInvitedToGroupUpdate:type_name -> signal.backup.SelfInvitedToGroupUpdate - 91, // 167: signal.backup.GroupChangeChatUpdate.Update.selfInvitedOtherUserToGroupUpdate:type_name -> signal.backup.SelfInvitedOtherUserToGroupUpdate - 92, // 168: signal.backup.GroupChangeChatUpdate.Update.groupUnknownInviteeUpdate:type_name -> signal.backup.GroupUnknownInviteeUpdate - 93, // 169: signal.backup.GroupChangeChatUpdate.Update.groupInvitationAcceptedUpdate:type_name -> signal.backup.GroupInvitationAcceptedUpdate - 94, // 170: signal.backup.GroupChangeChatUpdate.Update.groupInvitationDeclinedUpdate:type_name -> signal.backup.GroupInvitationDeclinedUpdate - 95, // 171: signal.backup.GroupChangeChatUpdate.Update.groupMemberJoinedUpdate:type_name -> signal.backup.GroupMemberJoinedUpdate - 96, // 172: signal.backup.GroupChangeChatUpdate.Update.groupMemberAddedUpdate:type_name -> signal.backup.GroupMemberAddedUpdate - 97, // 173: signal.backup.GroupChangeChatUpdate.Update.groupSelfInvitationRevokedUpdate:type_name -> signal.backup.GroupSelfInvitationRevokedUpdate - 98, // 174: signal.backup.GroupChangeChatUpdate.Update.groupInvitationRevokedUpdate:type_name -> signal.backup.GroupInvitationRevokedUpdate - 99, // 175: signal.backup.GroupChangeChatUpdate.Update.groupJoinRequestUpdate:type_name -> signal.backup.GroupJoinRequestUpdate - 100, // 176: signal.backup.GroupChangeChatUpdate.Update.groupJoinRequestApprovalUpdate:type_name -> signal.backup.GroupJoinRequestApprovalUpdate - 101, // 177: signal.backup.GroupChangeChatUpdate.Update.groupJoinRequestCanceledUpdate:type_name -> signal.backup.GroupJoinRequestCanceledUpdate - 103, // 178: signal.backup.GroupChangeChatUpdate.Update.groupInviteLinkResetUpdate:type_name -> signal.backup.GroupInviteLinkResetUpdate - 104, // 179: signal.backup.GroupChangeChatUpdate.Update.groupInviteLinkEnabledUpdate:type_name -> signal.backup.GroupInviteLinkEnabledUpdate - 105, // 180: signal.backup.GroupChangeChatUpdate.Update.groupInviteLinkAdminApprovalUpdate:type_name -> signal.backup.GroupInviteLinkAdminApprovalUpdate - 106, // 181: signal.backup.GroupChangeChatUpdate.Update.groupInviteLinkDisabledUpdate:type_name -> signal.backup.GroupInviteLinkDisabledUpdate - 107, // 182: signal.backup.GroupChangeChatUpdate.Update.groupMemberJoinedByLinkUpdate:type_name -> signal.backup.GroupMemberJoinedByLinkUpdate - 108, // 183: signal.backup.GroupChangeChatUpdate.Update.groupV2MigrationUpdate:type_name -> signal.backup.GroupV2MigrationUpdate - 109, // 184: signal.backup.GroupChangeChatUpdate.Update.groupV2MigrationSelfInvitedUpdate:type_name -> signal.backup.GroupV2MigrationSelfInvitedUpdate - 110, // 185: signal.backup.GroupChangeChatUpdate.Update.groupV2MigrationInvitedMembersUpdate:type_name -> signal.backup.GroupV2MigrationInvitedMembersUpdate - 111, // 186: signal.backup.GroupChangeChatUpdate.Update.groupV2MigrationDroppedMembersUpdate:type_name -> signal.backup.GroupV2MigrationDroppedMembersUpdate - 102, // 187: signal.backup.GroupChangeChatUpdate.Update.groupSequenceOfRequestsAndCancelsUpdate:type_name -> signal.backup.GroupSequenceOfRequestsAndCancelsUpdate - 112, // 188: signal.backup.GroupChangeChatUpdate.Update.groupExpirationTimerUpdate:type_name -> signal.backup.GroupExpirationTimerUpdate - 161, // 189: signal.backup.ChatStyle.CustomChatColor.gradient:type_name -> signal.backup.ChatStyle.Gradient - 190, // [190:190] is the sub-list for method output_type - 190, // [190:190] is the sub-list for method input_type - 190, // [190:190] is the sub-list for extension type_name - 190, // [190:190] is the sub-list for extension extendee - 0, // [0:190] is the sub-list for field type_name + 69, // 48: signal.backup.ChatItem.adminDeletedMessage:type_name -> signal.backup.AdminDeletedMessage + 141, // 49: signal.backup.ChatItem.pinDetails:type_name -> signal.backup.ChatItem.PinDetails + 142, // 50: signal.backup.SendStatus.pending:type_name -> signal.backup.SendStatus.Pending + 143, // 51: signal.backup.SendStatus.sent:type_name -> signal.backup.SendStatus.Sent + 144, // 52: signal.backup.SendStatus.delivered:type_name -> signal.backup.SendStatus.Delivered + 145, // 53: signal.backup.SendStatus.read:type_name -> signal.backup.SendStatus.Read + 146, // 54: signal.backup.SendStatus.viewed:type_name -> signal.backup.SendStatus.Viewed + 147, // 55: signal.backup.SendStatus.skipped:type_name -> signal.backup.SendStatus.Skipped + 148, // 56: signal.backup.SendStatus.failed:type_name -> signal.backup.SendStatus.Failed + 66, // 57: signal.backup.Text.bodyRanges:type_name -> signal.backup.BodyRange + 65, // 58: signal.backup.StandardMessage.quote:type_name -> signal.backup.Quote + 51, // 59: signal.backup.StandardMessage.text:type_name -> signal.backup.Text + 63, // 60: signal.backup.StandardMessage.attachments:type_name -> signal.backup.MessageAttachment + 62, // 61: signal.backup.StandardMessage.linkPreview:type_name -> signal.backup.LinkPreview + 64, // 62: signal.backup.StandardMessage.longText:type_name -> signal.backup.FilePointer + 67, // 63: signal.backup.StandardMessage.reactions:type_name -> signal.backup.Reaction + 58, // 64: signal.backup.ContactMessage.contact:type_name -> signal.backup.ContactAttachment + 67, // 65: signal.backup.ContactMessage.reactions:type_name -> signal.backup.Reaction + 149, // 66: signal.backup.DirectStoryReplyMessage.textReply:type_name -> signal.backup.DirectStoryReplyMessage.TextReply + 67, // 67: signal.backup.DirectStoryReplyMessage.reactions:type_name -> signal.backup.Reaction + 150, // 68: signal.backup.PaymentNotification.transactionDetails:type_name -> signal.backup.PaymentNotification.TransactionDetails + 20, // 69: signal.backup.GiftBadge.state:type_name -> signal.backup.GiftBadge.State + 63, // 70: signal.backup.ViewOnceMessage.attachment:type_name -> signal.backup.MessageAttachment + 67, // 71: signal.backup.ViewOnceMessage.reactions:type_name -> signal.backup.Reaction + 154, // 72: signal.backup.ContactAttachment.name:type_name -> signal.backup.ContactAttachment.Name + 155, // 73: signal.backup.ContactAttachment.number:type_name -> signal.backup.ContactAttachment.Phone + 156, // 74: signal.backup.ContactAttachment.email:type_name -> signal.backup.ContactAttachment.Email + 157, // 75: signal.backup.ContactAttachment.address:type_name -> signal.backup.ContactAttachment.PostalAddress + 64, // 76: signal.backup.ContactAttachment.avatar:type_name -> signal.backup.FilePointer + 61, // 77: signal.backup.StickerMessage.sticker:type_name -> signal.backup.Sticker + 67, // 78: signal.backup.StickerMessage.reactions:type_name -> signal.backup.Reaction + 64, // 79: signal.backup.Sticker.data:type_name -> signal.backup.FilePointer + 64, // 80: signal.backup.LinkPreview.image:type_name -> signal.backup.FilePointer + 64, // 81: signal.backup.MessageAttachment.pointer:type_name -> signal.backup.FilePointer + 24, // 82: signal.backup.MessageAttachment.flag:type_name -> signal.backup.MessageAttachment.Flag + 158, // 83: signal.backup.FilePointer.locatorInfo:type_name -> signal.backup.FilePointer.LocatorInfo + 51, // 84: signal.backup.Quote.text:type_name -> signal.backup.Text + 159, // 85: signal.backup.Quote.attachments:type_name -> signal.backup.Quote.QuotedAttachment + 25, // 86: signal.backup.Quote.type:type_name -> signal.backup.Quote.Type + 26, // 87: signal.backup.BodyRange.style:type_name -> signal.backup.BodyRange.Style + 160, // 88: signal.backup.Poll.options:type_name -> signal.backup.Poll.PollOption + 67, // 89: signal.backup.Poll.reactions:type_name -> signal.backup.Reaction + 73, // 90: signal.backup.ChatUpdateMessage.simpleUpdate:type_name -> signal.backup.SimpleChatUpdate + 79, // 91: signal.backup.ChatUpdateMessage.groupChange:type_name -> signal.backup.GroupChangeChatUpdate + 74, // 92: signal.backup.ChatUpdateMessage.expirationTimerChange:type_name -> signal.backup.ExpirationTimerChatUpdate + 75, // 93: signal.backup.ChatUpdateMessage.profileChange:type_name -> signal.backup.ProfileChangeChatUpdate + 77, // 94: signal.backup.ChatUpdateMessage.threadMerge:type_name -> signal.backup.ThreadMergeChatUpdate + 78, // 95: signal.backup.ChatUpdateMessage.sessionSwitchover:type_name -> signal.backup.SessionSwitchoverChatUpdate + 71, // 96: signal.backup.ChatUpdateMessage.individualCall:type_name -> signal.backup.IndividualCall + 72, // 97: signal.backup.ChatUpdateMessage.groupCall:type_name -> signal.backup.GroupCall + 76, // 98: signal.backup.ChatUpdateMessage.learnedProfileChange:type_name -> signal.backup.LearnedProfileChatUpdate + 116, // 99: signal.backup.ChatUpdateMessage.pollTerminate:type_name -> signal.backup.PollTerminateUpdate + 117, // 100: signal.backup.ChatUpdateMessage.pinMessage:type_name -> signal.backup.PinMessageUpdate + 27, // 101: signal.backup.IndividualCall.type:type_name -> signal.backup.IndividualCall.Type + 28, // 102: signal.backup.IndividualCall.direction:type_name -> signal.backup.IndividualCall.Direction + 29, // 103: signal.backup.IndividualCall.state:type_name -> signal.backup.IndividualCall.State + 30, // 104: signal.backup.GroupCall.state:type_name -> signal.backup.GroupCall.State + 31, // 105: signal.backup.SimpleChatUpdate.type:type_name -> signal.backup.SimpleChatUpdate.Type + 162, // 106: signal.backup.GroupChangeChatUpdate.updates:type_name -> signal.backup.GroupChangeChatUpdate.Update + 1, // 107: signal.backup.GroupMembershipAccessLevelChangeUpdate.accessLevel:type_name -> signal.backup.GroupV2AccessLevel + 1, // 108: signal.backup.GroupAttributesAccessLevelChangeUpdate.accessLevel:type_name -> signal.backup.GroupV2AccessLevel + 1, // 109: signal.backup.GroupMemberLabelAccessLevelChangeUpdate.accessLevel:type_name -> signal.backup.GroupV2AccessLevel + 163, // 110: signal.backup.GroupInvitationRevokedUpdate.invitees:type_name -> signal.backup.GroupInvitationRevokedUpdate.Invitee + 32, // 111: signal.backup.ChatStyle.wallpaperPreset:type_name -> signal.backup.ChatStyle.WallpaperPreset + 64, // 112: signal.backup.ChatStyle.wallpaperPhoto:type_name -> signal.backup.FilePointer + 166, // 113: signal.backup.ChatStyle.autoBubbleColor:type_name -> signal.backup.ChatStyle.AutomaticBubbleColor + 33, // 114: signal.backup.ChatStyle.bubbleColorPreset:type_name -> signal.backup.ChatStyle.BubbleColorPreset + 34, // 115: signal.backup.NotificationProfile.scheduleDaysEnabled:type_name -> signal.backup.NotificationProfile.DayOfWeek + 35, // 116: signal.backup.ChatFolder.folderType:type_name -> signal.backup.ChatFolder.FolderType + 6, // 117: signal.backup.AccountData.UsernameLink.color:type_name -> signal.backup.AccountData.UsernameLink.Color + 7, // 118: signal.backup.AccountData.AutoDownloadSettings.images:type_name -> signal.backup.AccountData.AutoDownloadSettings.AutoDownloadOption + 7, // 119: signal.backup.AccountData.AutoDownloadSettings.audio:type_name -> signal.backup.AccountData.AutoDownloadSettings.AutoDownloadOption + 7, // 120: signal.backup.AccountData.AutoDownloadSettings.video:type_name -> signal.backup.AccountData.AutoDownloadSettings.AutoDownloadOption + 7, // 121: signal.backup.AccountData.AutoDownloadSettings.documents:type_name -> signal.backup.AccountData.AutoDownloadSettings.AutoDownloadOption + 2, // 122: signal.backup.AccountData.AccountSettings.phoneNumberSharingMode:type_name -> signal.backup.AccountData.PhoneNumberSharingMode + 119, // 123: signal.backup.AccountData.AccountSettings.defaultChatStyle:type_name -> signal.backup.ChatStyle + 165, // 124: signal.backup.AccountData.AccountSettings.customChatColors:type_name -> signal.backup.ChatStyle.CustomChatColor + 3, // 125: signal.backup.AccountData.AccountSettings.defaultSentMediaQuality:type_name -> signal.backup.AccountData.SentMediaQuality + 123, // 126: signal.backup.AccountData.AccountSettings.autoDownloadSettings:type_name -> signal.backup.AccountData.AutoDownloadSettings + 4, // 127: signal.backup.AccountData.AccountSettings.appTheme:type_name -> signal.backup.AccountData.AppTheme + 5, // 128: signal.backup.AccountData.AccountSettings.callsUseLessDataSetting:type_name -> signal.backup.AccountData.CallsUseLessDataSetting + 8, // 129: signal.backup.AccountData.AndroidSpecificSettings.navigationBarSize:type_name -> signal.backup.AccountData.AndroidSpecificSettings.NavigationBarSize + 132, // 130: signal.backup.Group.GroupSnapshot.title:type_name -> signal.backup.Group.GroupAttributeBlob + 132, // 131: signal.backup.Group.GroupSnapshot.description:type_name -> signal.backup.Group.GroupAttributeBlob + 132, // 132: signal.backup.Group.GroupSnapshot.disappearingMessagesTimer:type_name -> signal.backup.Group.GroupAttributeBlob + 137, // 133: signal.backup.Group.GroupSnapshot.accessControl:type_name -> signal.backup.Group.AccessControl + 133, // 134: signal.backup.Group.GroupSnapshot.members:type_name -> signal.backup.Group.Member + 134, // 135: signal.backup.Group.GroupSnapshot.membersPendingProfileKey:type_name -> signal.backup.Group.MemberPendingProfileKey + 135, // 136: signal.backup.Group.GroupSnapshot.membersPendingAdminApproval:type_name -> signal.backup.Group.MemberPendingAdminApproval + 136, // 137: signal.backup.Group.GroupSnapshot.members_banned:type_name -> signal.backup.Group.MemberBanned + 12, // 138: signal.backup.Group.Member.role:type_name -> signal.backup.Group.Member.Role + 133, // 139: signal.backup.Group.MemberPendingProfileKey.member:type_name -> signal.backup.Group.Member + 13, // 140: signal.backup.Group.AccessControl.attributes:type_name -> signal.backup.Group.AccessControl.AccessRequired + 13, // 141: signal.backup.Group.AccessControl.members:type_name -> signal.backup.Group.AccessControl.AccessRequired + 13, // 142: signal.backup.Group.AccessControl.addFromInviteLink:type_name -> signal.backup.Group.AccessControl.AccessRequired + 13, // 143: signal.backup.Group.AccessControl.memberLabel:type_name -> signal.backup.Group.AccessControl.AccessRequired + 50, // 144: signal.backup.ChatItem.OutgoingMessageDetails.sendStatus:type_name -> signal.backup.SendStatus + 17, // 145: signal.backup.SendStatus.Failed.reason:type_name -> signal.backup.SendStatus.Failed.FailureReason + 51, // 146: signal.backup.DirectStoryReplyMessage.TextReply.text:type_name -> signal.backup.Text + 64, // 147: signal.backup.DirectStoryReplyMessage.TextReply.longText:type_name -> signal.backup.FilePointer + 153, // 148: signal.backup.PaymentNotification.TransactionDetails.transaction:type_name -> signal.backup.PaymentNotification.TransactionDetails.Transaction + 152, // 149: signal.backup.PaymentNotification.TransactionDetails.failedTransaction:type_name -> signal.backup.PaymentNotification.TransactionDetails.FailedTransaction + 18, // 150: signal.backup.PaymentNotification.TransactionDetails.FailedTransaction.reason:type_name -> signal.backup.PaymentNotification.TransactionDetails.FailedTransaction.FailureReason + 19, // 151: signal.backup.PaymentNotification.TransactionDetails.Transaction.status:type_name -> signal.backup.PaymentNotification.TransactionDetails.Transaction.Status + 151, // 152: signal.backup.PaymentNotification.TransactionDetails.Transaction.mobileCoinIdentification:type_name -> signal.backup.PaymentNotification.TransactionDetails.MobileCoinTxoIdentification + 21, // 153: signal.backup.ContactAttachment.Phone.type:type_name -> signal.backup.ContactAttachment.Phone.Type + 22, // 154: signal.backup.ContactAttachment.Email.type:type_name -> signal.backup.ContactAttachment.Email.Type + 23, // 155: signal.backup.ContactAttachment.PostalAddress.type:type_name -> signal.backup.ContactAttachment.PostalAddress.Type + 63, // 156: signal.backup.Quote.QuotedAttachment.thumbnail:type_name -> signal.backup.MessageAttachment + 161, // 157: signal.backup.Poll.PollOption.votes:type_name -> signal.backup.Poll.PollOption.PollVote + 80, // 158: signal.backup.GroupChangeChatUpdate.Update.genericGroupUpdate:type_name -> signal.backup.GenericGroupUpdate + 81, // 159: signal.backup.GroupChangeChatUpdate.Update.groupCreationUpdate:type_name -> signal.backup.GroupCreationUpdate + 82, // 160: signal.backup.GroupChangeChatUpdate.Update.groupNameUpdate:type_name -> signal.backup.GroupNameUpdate + 83, // 161: signal.backup.GroupChangeChatUpdate.Update.groupAvatarUpdate:type_name -> signal.backup.GroupAvatarUpdate + 84, // 162: signal.backup.GroupChangeChatUpdate.Update.groupDescriptionUpdate:type_name -> signal.backup.GroupDescriptionUpdate + 85, // 163: signal.backup.GroupChangeChatUpdate.Update.groupMembershipAccessLevelChangeUpdate:type_name -> signal.backup.GroupMembershipAccessLevelChangeUpdate + 86, // 164: signal.backup.GroupChangeChatUpdate.Update.groupAttributesAccessLevelChangeUpdate:type_name -> signal.backup.GroupAttributesAccessLevelChangeUpdate + 89, // 165: signal.backup.GroupChangeChatUpdate.Update.groupAnnouncementOnlyChangeUpdate:type_name -> signal.backup.GroupAnnouncementOnlyChangeUpdate + 90, // 166: signal.backup.GroupChangeChatUpdate.Update.groupAdminStatusUpdate:type_name -> signal.backup.GroupAdminStatusUpdate + 91, // 167: signal.backup.GroupChangeChatUpdate.Update.groupMemberLeftUpdate:type_name -> signal.backup.GroupMemberLeftUpdate + 92, // 168: signal.backup.GroupChangeChatUpdate.Update.groupMemberRemovedUpdate:type_name -> signal.backup.GroupMemberRemovedUpdate + 93, // 169: signal.backup.GroupChangeChatUpdate.Update.selfInvitedToGroupUpdate:type_name -> signal.backup.SelfInvitedToGroupUpdate + 94, // 170: signal.backup.GroupChangeChatUpdate.Update.selfInvitedOtherUserToGroupUpdate:type_name -> signal.backup.SelfInvitedOtherUserToGroupUpdate + 95, // 171: signal.backup.GroupChangeChatUpdate.Update.groupUnknownInviteeUpdate:type_name -> signal.backup.GroupUnknownInviteeUpdate + 96, // 172: signal.backup.GroupChangeChatUpdate.Update.groupInvitationAcceptedUpdate:type_name -> signal.backup.GroupInvitationAcceptedUpdate + 97, // 173: signal.backup.GroupChangeChatUpdate.Update.groupInvitationDeclinedUpdate:type_name -> signal.backup.GroupInvitationDeclinedUpdate + 98, // 174: signal.backup.GroupChangeChatUpdate.Update.groupMemberJoinedUpdate:type_name -> signal.backup.GroupMemberJoinedUpdate + 99, // 175: signal.backup.GroupChangeChatUpdate.Update.groupMemberAddedUpdate:type_name -> signal.backup.GroupMemberAddedUpdate + 100, // 176: signal.backup.GroupChangeChatUpdate.Update.groupSelfInvitationRevokedUpdate:type_name -> signal.backup.GroupSelfInvitationRevokedUpdate + 101, // 177: signal.backup.GroupChangeChatUpdate.Update.groupInvitationRevokedUpdate:type_name -> signal.backup.GroupInvitationRevokedUpdate + 102, // 178: signal.backup.GroupChangeChatUpdate.Update.groupJoinRequestUpdate:type_name -> signal.backup.GroupJoinRequestUpdate + 103, // 179: signal.backup.GroupChangeChatUpdate.Update.groupJoinRequestApprovalUpdate:type_name -> signal.backup.GroupJoinRequestApprovalUpdate + 104, // 180: signal.backup.GroupChangeChatUpdate.Update.groupJoinRequestCanceledUpdate:type_name -> signal.backup.GroupJoinRequestCanceledUpdate + 106, // 181: signal.backup.GroupChangeChatUpdate.Update.groupInviteLinkResetUpdate:type_name -> signal.backup.GroupInviteLinkResetUpdate + 107, // 182: signal.backup.GroupChangeChatUpdate.Update.groupInviteLinkEnabledUpdate:type_name -> signal.backup.GroupInviteLinkEnabledUpdate + 108, // 183: signal.backup.GroupChangeChatUpdate.Update.groupInviteLinkAdminApprovalUpdate:type_name -> signal.backup.GroupInviteLinkAdminApprovalUpdate + 109, // 184: signal.backup.GroupChangeChatUpdate.Update.groupInviteLinkDisabledUpdate:type_name -> signal.backup.GroupInviteLinkDisabledUpdate + 110, // 185: signal.backup.GroupChangeChatUpdate.Update.groupMemberJoinedByLinkUpdate:type_name -> signal.backup.GroupMemberJoinedByLinkUpdate + 111, // 186: signal.backup.GroupChangeChatUpdate.Update.groupV2MigrationUpdate:type_name -> signal.backup.GroupV2MigrationUpdate + 112, // 187: signal.backup.GroupChangeChatUpdate.Update.groupV2MigrationSelfInvitedUpdate:type_name -> signal.backup.GroupV2MigrationSelfInvitedUpdate + 113, // 188: signal.backup.GroupChangeChatUpdate.Update.groupV2MigrationInvitedMembersUpdate:type_name -> signal.backup.GroupV2MigrationInvitedMembersUpdate + 114, // 189: signal.backup.GroupChangeChatUpdate.Update.groupV2MigrationDroppedMembersUpdate:type_name -> signal.backup.GroupV2MigrationDroppedMembersUpdate + 105, // 190: signal.backup.GroupChangeChatUpdate.Update.groupSequenceOfRequestsAndCancelsUpdate:type_name -> signal.backup.GroupSequenceOfRequestsAndCancelsUpdate + 115, // 191: signal.backup.GroupChangeChatUpdate.Update.groupExpirationTimerUpdate:type_name -> signal.backup.GroupExpirationTimerUpdate + 87, // 192: signal.backup.GroupChangeChatUpdate.Update.groupMemberLabelAccessLevelChangeUpdate:type_name -> signal.backup.GroupMemberLabelAccessLevelChangeUpdate + 88, // 193: signal.backup.GroupChangeChatUpdate.Update.groupTerminateChangeUpdate:type_name -> signal.backup.GroupTerminateChangeUpdate + 164, // 194: signal.backup.ChatStyle.CustomChatColor.gradient:type_name -> signal.backup.ChatStyle.Gradient + 195, // [195:195] is the sub-list for method output_type + 195, // [195:195] is the sub-list for method input_type + 195, // [195:195] is the sub-list for extension type_name + 195, // [195:195] is the sub-list for extension extendee + 0, // [0:195] is the sub-list for field type_name } func init() { file_backuppb_Backup_proto_init() } @@ -13607,6 +13860,7 @@ func file_backuppb_Backup_proto_init() { (*ChatItem_ViewOnceMessage)(nil), (*ChatItem_DirectStoryReplyMessage)(nil), (*ChatItem_Poll)(nil), + (*ChatItem_AdminDeletedMessage)(nil), } file_backuppb_Backup_proto_msgTypes[14].OneofWrappers = []any{ (*SendStatus_Pending_)(nil), @@ -13633,7 +13887,7 @@ func file_backuppb_Backup_proto_init() { (*BodyRange_MentionAci)(nil), (*BodyRange_Style_)(nil), } - file_backuppb_Backup_proto_msgTypes[33].OneofWrappers = []any{ + file_backuppb_Backup_proto_msgTypes[34].OneofWrappers = []any{ (*ChatUpdateMessage_SimpleUpdate)(nil), (*ChatUpdateMessage_GroupChange)(nil), (*ChatUpdateMessage_ExpirationTimerChange)(nil), @@ -13646,13 +13900,12 @@ func file_backuppb_Backup_proto_init() { (*ChatUpdateMessage_PollTerminate)(nil), (*ChatUpdateMessage_PinMessage)(nil), } - file_backuppb_Backup_proto_msgTypes[34].OneofWrappers = []any{} file_backuppb_Backup_proto_msgTypes[35].OneofWrappers = []any{} - file_backuppb_Backup_proto_msgTypes[39].OneofWrappers = []any{ + file_backuppb_Backup_proto_msgTypes[36].OneofWrappers = []any{} + file_backuppb_Backup_proto_msgTypes[40].OneofWrappers = []any{ (*LearnedProfileChatUpdate_E164)(nil), (*LearnedProfileChatUpdate_Username)(nil), } - file_backuppb_Backup_proto_msgTypes[43].OneofWrappers = []any{} file_backuppb_Backup_proto_msgTypes[44].OneofWrappers = []any{} file_backuppb_Backup_proto_msgTypes[45].OneofWrappers = []any{} file_backuppb_Backup_proto_msgTypes[46].OneofWrappers = []any{} @@ -13661,55 +13914,58 @@ func file_backuppb_Backup_proto_init() { file_backuppb_Backup_proto_msgTypes[49].OneofWrappers = []any{} file_backuppb_Backup_proto_msgTypes[50].OneofWrappers = []any{} file_backuppb_Backup_proto_msgTypes[51].OneofWrappers = []any{} + file_backuppb_Backup_proto_msgTypes[52].OneofWrappers = []any{} file_backuppb_Backup_proto_msgTypes[53].OneofWrappers = []any{} file_backuppb_Backup_proto_msgTypes[54].OneofWrappers = []any{} file_backuppb_Backup_proto_msgTypes[56].OneofWrappers = []any{} file_backuppb_Backup_proto_msgTypes[57].OneofWrappers = []any{} - file_backuppb_Backup_proto_msgTypes[58].OneofWrappers = []any{} + file_backuppb_Backup_proto_msgTypes[59].OneofWrappers = []any{} file_backuppb_Backup_proto_msgTypes[60].OneofWrappers = []any{} file_backuppb_Backup_proto_msgTypes[61].OneofWrappers = []any{} - file_backuppb_Backup_proto_msgTypes[62].OneofWrappers = []any{} + file_backuppb_Backup_proto_msgTypes[63].OneofWrappers = []any{} file_backuppb_Backup_proto_msgTypes[64].OneofWrappers = []any{} + file_backuppb_Backup_proto_msgTypes[65].OneofWrappers = []any{} file_backuppb_Backup_proto_msgTypes[67].OneofWrappers = []any{} - file_backuppb_Backup_proto_msgTypes[68].OneofWrappers = []any{} - file_backuppb_Backup_proto_msgTypes[69].OneofWrappers = []any{} file_backuppb_Backup_proto_msgTypes[70].OneofWrappers = []any{} - file_backuppb_Backup_proto_msgTypes[76].OneofWrappers = []any{} - file_backuppb_Backup_proto_msgTypes[80].OneofWrappers = []any{ + file_backuppb_Backup_proto_msgTypes[71].OneofWrappers = []any{} + file_backuppb_Backup_proto_msgTypes[72].OneofWrappers = []any{} + file_backuppb_Backup_proto_msgTypes[73].OneofWrappers = []any{} + file_backuppb_Backup_proto_msgTypes[79].OneofWrappers = []any{} + file_backuppb_Backup_proto_msgTypes[83].OneofWrappers = []any{ (*ChatStyle_WallpaperPreset_)(nil), (*ChatStyle_WallpaperPhoto)(nil), (*ChatStyle_AutoBubbleColor)(nil), (*ChatStyle_BubbleColorPreset_)(nil), (*ChatStyle_CustomColorId)(nil), } - file_backuppb_Backup_proto_msgTypes[81].OneofWrappers = []any{} - file_backuppb_Backup_proto_msgTypes[85].OneofWrappers = []any{} - file_backuppb_Backup_proto_msgTypes[87].OneofWrappers = []any{ + file_backuppb_Backup_proto_msgTypes[84].OneofWrappers = []any{} + file_backuppb_Backup_proto_msgTypes[88].OneofWrappers = []any{} + file_backuppb_Backup_proto_msgTypes[90].OneofWrappers = []any{ (*AccountData_IAPSubscriberData_PurchaseToken)(nil), (*AccountData_IAPSubscriberData_OriginalTransactionId)(nil), } - file_backuppb_Backup_proto_msgTypes[93].OneofWrappers = []any{ + file_backuppb_Backup_proto_msgTypes[96].OneofWrappers = []any{ (*Group_GroupAttributeBlob_Title)(nil), (*Group_GroupAttributeBlob_Avatar)(nil), (*Group_GroupAttributeBlob_DisappearingMessagesDuration)(nil), (*Group_GroupAttributeBlob_DescriptionText)(nil), } - file_backuppb_Backup_proto_msgTypes[99].OneofWrappers = []any{} - file_backuppb_Backup_proto_msgTypes[102].OneofWrappers = []any{ + file_backuppb_Backup_proto_msgTypes[102].OneofWrappers = []any{} + file_backuppb_Backup_proto_msgTypes[105].OneofWrappers = []any{ (*ChatItem_PinDetails_PinExpiresAtTimestamp)(nil), (*ChatItem_PinDetails_PinNeverExpires)(nil), } - file_backuppb_Backup_proto_msgTypes[111].OneofWrappers = []any{ + file_backuppb_Backup_proto_msgTypes[114].OneofWrappers = []any{ (*PaymentNotification_TransactionDetails_Transaction_)(nil), (*PaymentNotification_TransactionDetails_FailedTransaction_)(nil), } - file_backuppb_Backup_proto_msgTypes[114].OneofWrappers = []any{} - file_backuppb_Backup_proto_msgTypes[119].OneofWrappers = []any{ + file_backuppb_Backup_proto_msgTypes[117].OneofWrappers = []any{} + file_backuppb_Backup_proto_msgTypes[122].OneofWrappers = []any{ (*FilePointer_LocatorInfo_PlaintextHash)(nil), (*FilePointer_LocatorInfo_EncryptedDigest)(nil), } - file_backuppb_Backup_proto_msgTypes[120].OneofWrappers = []any{} - file_backuppb_Backup_proto_msgTypes[123].OneofWrappers = []any{ + file_backuppb_Backup_proto_msgTypes[123].OneofWrappers = []any{} + file_backuppb_Backup_proto_msgTypes[126].OneofWrappers = []any{ (*GroupChangeChatUpdate_Update_GenericGroupUpdate)(nil), (*GroupChangeChatUpdate_Update_GroupCreationUpdate)(nil), (*GroupChangeChatUpdate_Update_GroupNameUpdate)(nil), @@ -13744,9 +14000,11 @@ func file_backuppb_Backup_proto_init() { (*GroupChangeChatUpdate_Update_GroupV2MigrationDroppedMembersUpdate)(nil), (*GroupChangeChatUpdate_Update_GroupSequenceOfRequestsAndCancelsUpdate)(nil), (*GroupChangeChatUpdate_Update_GroupExpirationTimerUpdate)(nil), + (*GroupChangeChatUpdate_Update_GroupMemberLabelAccessLevelChangeUpdate)(nil), + (*GroupChangeChatUpdate_Update_GroupTerminateChangeUpdate)(nil), } - file_backuppb_Backup_proto_msgTypes[124].OneofWrappers = []any{} - file_backuppb_Backup_proto_msgTypes[126].OneofWrappers = []any{ + file_backuppb_Backup_proto_msgTypes[127].OneofWrappers = []any{} + file_backuppb_Backup_proto_msgTypes[129].OneofWrappers = []any{ (*ChatStyle_CustomChatColor_Solid)(nil), (*ChatStyle_CustomChatColor_Gradient)(nil), } @@ -13756,7 +14014,7 @@ func file_backuppb_Backup_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: unsafe.Slice(unsafe.StringData(file_backuppb_Backup_proto_rawDesc), len(file_backuppb_Backup_proto_rawDesc)), NumEnums: 36, - NumMessages: 128, + NumMessages: 131, NumExtensions: 0, NumServices: 0, }, diff --git a/pkg/signalmeow/protobuf/backuppb/Backup.proto b/pkg/signalmeow/protobuf/backuppb/Backup.proto index 1b70167..d7407cb 100644 --- a/pkg/signalmeow/protobuf/backuppb/Backup.proto +++ b/pkg/signalmeow/protobuf/backuppb/Backup.proto @@ -2,7 +2,7 @@ syntax = "proto3"; package signal.backup; -option java_package = "org.thoughtcrime.securesms.backup.v2.proto"; +option java_package = "org.signal.archive.proto"; option swift_prefix = "BackupProto_"; message BackupInfo { @@ -135,6 +135,7 @@ message AccountData { CallsUseLessDataSetting callsUseLessDataSetting = 29; // If unset, treat the same as "Unknown" case bool allowSealedSenderFromAnyone = 30; bool allowAutomaticKeyVerification = 31; + bool hasSeenAdminDeleteEducationDialog = 32; } message SubscriberData { @@ -307,6 +308,7 @@ message Group { bytes inviteLinkPassword = 10; bool announcements_only = 12; repeated MemberBanned members_banned = 13; + bool terminated = 14; } message GroupAttributeBlob { @@ -331,6 +333,8 @@ message Group { reserved /*profileKey*/ 3; // This field is ignored in Backups, in favor of Contact frames for members reserved /*presentation*/ 4; // This field is deprecated in the context of static group state uint32 joinedAtVersion = 5; + string labelEmoji = 6; + string labelString = 7; } message MemberPendingProfileKey { @@ -363,6 +367,7 @@ message Group { AccessRequired attributes = 1; AccessRequired members = 2; AccessRequired addFromInviteLink = 3; + AccessRequired memberLabel = 4; } } @@ -405,7 +410,7 @@ message CallLink { string name = 3; Restrictions restrictions = 4; uint64 expirationMs = 5; - optional bytes epoch = 6; // May be absent/empty for older links + reserved /*epoch*/ 6; } message AdHocCall { @@ -498,6 +503,7 @@ message ChatItem { ViewOnceMessage viewOnceMessage = 18; DirectStoryReplyMessage directStoryReplyMessage = 19; // group story reply messages are not backed up Poll poll = 20; + AdminDeletedMessage adminDeletedMessage = 22; } PinDetails pinDetails = 21; // only set if message is pinned @@ -898,6 +904,10 @@ message Poll { repeated Reaction reactions = 5; } +message AdminDeletedMessage { + uint64 adminId = 1; // id of the admin that deleted the message +} + message ChatUpdateMessage { // If unset, importers should ignore the update message without throwing an error. oneof update { @@ -1068,6 +1078,8 @@ message GroupChangeChatUpdate { GroupV2MigrationDroppedMembersUpdate groupV2MigrationDroppedMembersUpdate = 32; GroupSequenceOfRequestsAndCancelsUpdate groupSequenceOfRequestsAndCancelsUpdate = 33; GroupExpirationTimerUpdate groupExpirationTimerUpdate = 34; + GroupMemberLabelAccessLevelChangeUpdate groupMemberLabelAccessLevelChangeUpdate = 35; + GroupTerminateChangeUpdate groupTerminateChangeUpdate = 36; } } @@ -1119,6 +1131,15 @@ message GroupAttributesAccessLevelChangeUpdate { GroupV2AccessLevel accessLevel = 2; } +message GroupMemberLabelAccessLevelChangeUpdate { + optional bytes updaterAci = 1; + GroupV2AccessLevel accessLevel = 2; +} + +message GroupTerminateChangeUpdate { + optional bytes updaterAci = 1; +} + message GroupAnnouncementOnlyChangeUpdate { optional bytes updaterAci = 1; bool isAnnouncementOnly = 2; diff --git a/pkg/signalmeow/protobuf/update-protos.sh b/pkg/signalmeow/protobuf/update-protos.sh index d65567c..ffaa697 100755 --- a/pkg/signalmeow/protobuf/update-protos.sh +++ b/pkg/signalmeow/protobuf/update-protos.sh @@ -1,8 +1,8 @@ #!/bin/bash set -euo pipefail -ANDROID_GIT_REVISION=${1:-bc6114f6e0d3a4b1dcdc472331505f2644185264} -DESKTOP_GIT_REVISION=${1:-a9063ec0c3c1079072c1e30e0749c1ae8be5500a} +ANDROID_GIT_REVISION=${1:-dfd2f7baf96825834f784900ce644e9ead8a9a89} +DESKTOP_GIT_REVISION=${1:-60a1e125452ee672d8747564d0055d5bfec9f679} update_proto() { case "$1" in @@ -11,9 +11,9 @@ update_proto() { prefix="lib/libsignal-service/src/main/protowire/" GIT_REVISION=$ANDROID_GIT_REVISION ;; - Signal-Android-App) + Signal-Android-Archive) REPO="Signal-Android" - prefix="app/src/main/protowire/" + prefix="lib/archive/src/main/protowire/" GIT_REVISION=$ANDROID_GIT_REVISION ;; Signal-Desktop) @@ -34,11 +34,10 @@ update_proto Signal-Android StickerResources.proto update_proto Signal-Android WebSocketResources.proto update_proto Signal-Android StorageService.proto -update_proto Signal-Android-App Backup.proto +update_proto Signal-Android-Archive Backup.proto mv Backup.proto backuppb/Backup.proto update_proto Signal-Desktop DeviceName.proto -# TODO this was moved to libsignal only +# TODO these were moved to libsignal only #update_proto Signal-Desktop UnidentifiedDelivery.proto -# Android has CDSI.proto too, but the types have more generic names (since android uses a different package name) -update_proto Signal-Desktop ContactDiscovery.proto +#update_proto Signal-Desktop ContactDiscovery.proto diff --git a/pkg/signalmeow/provisioning.go b/pkg/signalmeow/provisioning.go index 48a8042..8e0fa96 100644 --- a/pkg/signalmeow/provisioning.go +++ b/pkg/signalmeow/provisioning.go @@ -18,7 +18,6 @@ package signalmeow import ( "context" - "crypto/hmac" "encoding/base64" "encoding/json" "fmt" @@ -166,24 +165,19 @@ func PerformProvisioning(ctx context.Context, deviceStore store.DeviceStore, dev DeviceID: deviceId, Number: *provisioningMessage.Number, Password: password, - MasterKey: provisioningMessage.GetMasterKey(), AccountEntropyPool: libsignalgo.AccountEntropyPool(provisioningMessage.GetAccountEntropyPool()), EphemeralBackupKey: libsignalgo.BytesToBackupKey(provisioningMessage.GetEphemeralBackupKey()), MediaRootBackupKey: libsignalgo.BytesToBackupKey(provisioningMessage.GetMediaRootBackupKey()), } if provisioningMessage.GetAccountEntropyPool() != "" { - var masterKey []byte - masterKey, err = libsignalgo.AccountEntropyPool(provisioningMessage.GetAccountEntropyPool()).DeriveSVRKey() + data.MasterKey, err = libsignalgo.AccountEntropyPool(provisioningMessage.GetAccountEntropyPool()).DeriveSVRKey() if err != nil { log.Err(err).Msg("Failed to derive master key from account entropy pool") } else { log.Debug().Msg("Derived master key from account entropy pool") } - if data.MasterKey == nil { - data.MasterKey = masterKey - } else if !hmac.Equal(data.MasterKey, masterKey) { - log.Warn().Msg("Master key mismatch") - } + } else { + log.Warn().Msg("No account entropy pool in provisioning message") } // Store the provisioning data diff --git a/pkg/signalmeow/receiving.go b/pkg/signalmeow/receiving.go index 9fa4b84..6b92d04 100644 --- a/pkg/signalmeow/receiving.go +++ b/pkg/signalmeow/receiving.go @@ -357,7 +357,7 @@ func (cli *Client) incomingAPIMessageHandler(ctx context.Context, req *signalpb. return nil, err } log = log.With(). - Uint64("envelope_timestamp", envelope.GetTimestamp()). + Uint64("envelope_timestamp", envelope.GetClientTimestamp()). Uint64("server_timestamp", envelope.GetServerTimestamp()). Logger() ctx = log.WithContext(ctx) @@ -368,7 +368,7 @@ func (cli *Client) incomingAPIMessageHandler(ctx context.Context, req *signalpb. Str("source_service_id", envelope.GetSourceServiceId()). Hex("destination_service_id_bytes", envelope.GetDestinationServiceIdBinary()). Hex("source_service_id_bytes", envelope.GetSourceServiceIdBinary()). - Uint32("source_device_id", envelope.GetSourceDevice()). + Uint32("source_device_id", envelope.GetSourceDeviceId()). Object("parsed_destination_service_id", destinationServiceID). Object("parsed_source_service_id", sourceServiceID). Int32("envelope_type_id", int32(envelope.GetType())). @@ -436,20 +436,20 @@ func (cli *Client) handleDecryptedResult( Bool("urgent", envelope.GetUrgent()). Stringer("content_hint", result.ContentHint). Uint64("server_ts", envelope.GetServerTimestamp()). - Uint64("client_ts", envelope.GetTimestamp()). + Uint64("client_ts", envelope.GetClientTimestamp()). Msg("No sender address received") return nil } else if theirServiceID, err = result.SenderAddress.NameServiceID(); err != nil { log.Warn(). Uint64("server_ts", envelope.GetServerTimestamp()). - Uint64("client_ts", envelope.GetTimestamp()). + Uint64("client_ts", envelope.GetClientTimestamp()). Msg("Failed to get sender name as service ID") return fmt.Errorf("failed to get sender name as service ID: %w", err) } else if theirServiceID.Type != libsignalgo.ServiceIDTypeACI { log.Warn(). Any("their_service_id", theirServiceID). Uint64("server_ts", envelope.GetServerTimestamp()). - Uint64("client_ts", envelope.GetTimestamp()). + Uint64("client_ts", envelope.GetClientTimestamp()). Msg("Dropping message from non-ACI sender") return nil } @@ -469,7 +469,7 @@ func (cli *Client) handleDecryptedResult( Bool("urgent", envelope.GetUrgent()). Stringer("content_hint", result.ContentHint). Uint64("server_ts", envelope.GetServerTimestamp()). - Uint64("client_ts", envelope.GetTimestamp()). + Uint64("client_ts", envelope.GetClientTimestamp()). Stringer("sender", theirServiceID). Msg("Ignoring already processed event") return nil @@ -478,7 +478,7 @@ func (cli *Client) handleDecryptedResult( Bool("urgent", envelope.GetUrgent()). Stringer("content_hint", result.ContentHint). Uint64("server_ts", envelope.GetServerTimestamp()). - Uint64("client_ts", envelope.GetTimestamp()). + Uint64("client_ts", envelope.GetClientTimestamp()). Stringer("sender", theirServiceID). Msg("Decryption error with known sender") // Only send decryption error event if the message was urgent, @@ -489,12 +489,12 @@ func (cli *Client) handleDecryptedResult( handlerSuccess = cli.handleEvent(&events.DecryptionError{ Sender: theirServiceID.UUID, Err: result.Err, - Timestamp: envelope.GetTimestamp(), + Timestamp: envelope.GetClientTimestamp(), }) } if result.Retriable { go func() { - err := cli.sendRetryRequest(ctx, result, envelope.GetTimestamp()) + err := cli.sendRetryRequest(ctx, result, envelope.GetClientTimestamp()) if err != nil { log.Err(err).Msg("Failed to send retry request in background") } @@ -506,15 +506,15 @@ func (cli *Client) handleDecryptedResult( return nil } - content := result.Content - if content == nil { + rawContent := result.Content + if rawContent == nil { log.Warn().Msg("Decrypted content is nil") return nil } deviceID, _ := result.SenderAddress.DeviceID() log.Trace(). - Any("raw_data", content). + Any("raw_data", rawContent). Stringer("sender", theirServiceID). Uint("sender_device", deviceID). Msg("Raw event data") @@ -531,9 +531,10 @@ func (cli *Client) handleDecryptedResult( } logEvt.Bool("unencrypted", result.Unencrypted).Msg("Decrypted message") - if content.DecryptionErrorMessage != nil { + // Handle unencrypted types early and refuse any other unencrypted message + if rawContent.GetDecryptionErrorMessage() != nil { handlerSuccess = true - dem, err := libsignalgo.DeserializeDecryptionErrorMessage(content.DecryptionErrorMessage) + dem, err := libsignalgo.DeserializeDecryptionErrorMessage(rawContent.GetDecryptionErrorMessage()) if err != nil { log.Warn().Err(err).Msg("Failed to unmarshal decryption error message") } else { @@ -551,9 +552,9 @@ func (cli *Client) handleDecryptedResult( } // If there's a sender key distribution message, process it - if content.GetSenderKeyDistributionMessage() != nil { + if rawContent.SenderKeyDistributionMessage != nil { log.Debug().Msg("content includes sender key distribution message") - skdm, err := libsignalgo.DeserializeSenderKeyDistributionMessage(content.GetSenderKeyDistributionMessage()) + skdm, err := libsignalgo.DeserializeSenderKeyDistributionMessage(rawContent.SenderKeyDistributionMessage) if err != nil { log.Err(err).Msg("DeserializeSenderKeyDistributionMessage error") return err @@ -570,6 +571,7 @@ func (cli *Client) handleDecryptedResult( } } + // If we're getting a message to our PNI, mark it as needing a PNI signature message on the next send if destinationServiceID == cli.Store.PNIServiceID() { _, err = cli.Store.RecipientStore.LoadAndUpdateRecipient(ctx, theirServiceID.UUID, uuid.Nil, func(recipient *types.Recipient) (changed bool, err error) { if recipient.Whitelisted == nil { @@ -589,86 +591,100 @@ func (cli *Client) handleDecryptedResult( } } - if content.PniSignatureMessage != nil { + // If we receive a PNI signature message (because we sent to a PNI earlier), process it + if rawContent.PniSignatureMessage != nil { log.Debug().Msg("Content includes PNI signature message") - err = cli.handlePNISignatureMessage(ctx, theirServiceID, content.PniSignatureMessage) + err = cli.handlePNISignatureMessage(ctx, theirServiceID, rawContent.PniSignatureMessage) if err != nil { log.Err(err). - Hex("pni_raw", content.PniSignatureMessage.GetPni()). + Hex("pni_raw", rawContent.PniSignatureMessage.GetPni()). Stringer("aci", theirServiceID.UUID). Msg("Failed to verify ACI-PNI mapping") } } - if content.SyncMessage != nil && theirServiceID == cli.Store.ACIServiceID() { - handlerSuccess = cli.handleSyncMessage(ctx, content.SyncMessage, envelope) - return nil - } - isBlocked, err := cli.Store.RecipientStore.IsBlocked(ctx, theirServiceID.UUID) if err != nil { log.Err(err).Stringer("sender", theirServiceID).Msg("Failed to check if sender is blocked") } var sendDeliveryReceipt bool - if content.DataMessage != nil { + var deliveryReceiptTS uint64 + switch content := rawContent.Content.(type) { + case *signalpb.Content_SyncMessage: + if theirServiceID == cli.Store.ACIServiceID() { + handlerSuccess = cli.handleSyncMessage(ctx, content.SyncMessage, envelope) + } + return nil + case *signalpb.Content_DataMessage: handlerSuccess, sendDeliveryReceipt = cli.incomingDataMessage( ctx, content.DataMessage, theirServiceID.UUID, theirServiceID, envelope.GetServerTimestamp(), isBlocked, ) - } else if content.EditMessage != nil { + deliveryReceiptTS = content.DataMessage.GetTimestamp() + case *signalpb.Content_EditMessage: handlerSuccess, sendDeliveryReceipt = cli.incomingEditMessage( ctx, content.EditMessage, theirServiceID.UUID, theirServiceID, envelope.GetServerTimestamp(), isBlocked, ) - } - if sendDeliveryReceipt && handlerSuccess { - err = cli.sendDeliveryReceipts(ctx, []uint64{content.DataMessage.GetTimestamp()}, theirServiceID.UUID) - if err != nil { - log.Err(err).Msg("sendDeliveryReceipts error") - } - } - - if content.TypingMessage != nil && (!isBlocked || content.TypingMessage.GetGroupId() != nil) { - var groupID types.GroupIdentifier - if content.TypingMessage.GetGroupId() != nil { - gidBytes := content.TypingMessage.GetGroupId() - groupID = types.GroupIdentifier(base64.StdEncoding.EncodeToString(gidBytes)) - } - // No handler success check here, nobody cares if typing notifications are dropped - cli.handleEvent(&events.ChatEvent{ - Info: events.MessageInfo{ - Sender: theirServiceID.UUID, - ChatID: groupOrUserID(groupID, theirServiceID), - ServerTimestamp: envelope.GetServerTimestamp(), - }, - Event: content.TypingMessage, - }) - } - - // DM call message (group call is an opaque callMessage and a groupCallUpdate in a dataMessage) - if content.CallMessage != nil && (content.CallMessage.Offer != nil || content.CallMessage.Hangup != nil) && !isBlocked { - handlerSuccess = cli.handleEvent(&events.Call{ - Info: events.MessageInfo{ - Sender: theirServiceID.UUID, - ChatID: theirServiceID.String(), - ServerTimestamp: envelope.GetServerTimestamp(), - }, - // CallMessage doesn't have its own timestamp, use one from the envelope - Timestamp: envelope.GetTimestamp(), - IsRinging: content.CallMessage.Offer != nil, - }) && handlerSuccess - } - - // Read and delivery receipts - if content.ReceiptMessage != nil { - if content.GetReceiptMessage().GetType() == signalpb.ReceiptMessage_DELIVERY && theirServiceID == cli.Store.ACIServiceID() { + deliveryReceiptTS = content.EditMessage.GetDataMessage().GetTimestamp() + case *signalpb.Content_ReceiptMessage: + if content.ReceiptMessage.GetType() == signalpb.ReceiptMessage_DELIVERY && theirServiceID == cli.Store.ACIServiceID() { // Ignore delivery receipts from other own devices return nil } handlerSuccess = cli.handleEvent(&events.Receipt{ Sender: theirServiceID.UUID, Content: content.ReceiptMessage, - }) && handlerSuccess + }) + case *signalpb.Content_TypingMessage: + var groupID types.GroupIdentifier + if content.TypingMessage.GetGroupId() != nil { + gidBytes := content.TypingMessage.GetGroupId() + groupID = types.GroupIdentifier(base64.StdEncoding.EncodeToString(gidBytes)) + } + if !isBlocked || groupID != "" { + // No handler success check here, nobody cares if typing notifications are dropped + cli.handleEvent(&events.ChatEvent{ + Info: events.MessageInfo{ + Sender: theirServiceID.UUID, + ChatID: groupOrUserID(groupID, theirServiceID), + ServerTimestamp: envelope.GetServerTimestamp(), + }, + Event: content.TypingMessage, + }) + } + case *signalpb.Content_CallMessage: + if !isBlocked && (content.CallMessage.Offer != nil || content.CallMessage.Hangup != nil) { + handlerSuccess = cli.handleEvent(&events.Call{ + Info: events.MessageInfo{ + Sender: theirServiceID.UUID, + ChatID: theirServiceID.String(), + ServerTimestamp: envelope.GetServerTimestamp(), + }, + // CallMessage doesn't have its own timestamp, use one from the envelope + Timestamp: envelope.GetClientTimestamp(), + IsRinging: content.CallMessage.Offer != nil, + }) + } + case *signalpb.Content_DecryptionErrorMessage: + // These should've been handled earlier + log.Warn().Msg("Unexpected decryption error message content in decrypted message") + case *signalpb.Content_NullMessage: + // This is intentionally ignored + case *signalpb.Content_StoryMessage: + // This is also ignored for now + default: + if rawContent.PniSignatureMessage == nil && rawContent.SenderKeyDistributionMessage == nil { + log.Warn().Type("content_type", content).Msg("Unrecognized message content type") + } } + + if sendDeliveryReceipt && handlerSuccess { + err = cli.sendDeliveryReceipts(ctx, []uint64{deliveryReceiptTS}, theirServiceID.UUID) + if err != nil { + log.Err(err).Msg("sendDeliveryReceipts error") + } + } + return nil } @@ -683,9 +699,9 @@ func (cli *Client) handleSyncMessage(ctx context.Context, msg *signalpb.SyncMess // TODO: handle more sync messages handlerSuccess = true log := zerolog.Ctx(ctx) - if msg.Keys != nil { - aep := libsignalgo.AccountEntropyPool(msg.Keys.GetAccountEntropyPool()) - cli.Store.MasterKey = msg.Keys.GetMaster() + switch content := msg.Content.(type) { + case *signalpb.SyncMessage_Keys_: + aep := libsignalgo.AccountEntropyPool(content.Keys.GetAccountEntropyPool()) if aep != "" { aepMasterKey, err := aep.DeriveSVRKey() if err != nil { @@ -708,59 +724,65 @@ func (cli *Client) handleSyncMessage(ctx context.Context, msg *signalpb.SyncMess log.Info().Msg("Received master key") go cli.SyncStorage(ctx) } - } else if msg.GetFetchLatest().GetType() == signalpb.SyncMessage_FetchLatest_STORAGE_MANIFEST { - log.Debug().Msg("Received storage manifest fetch latest notice") - go cli.SyncStorage(ctx) - } - syncSent := msg.GetSent() - if syncSent.GetMessage() != nil || syncSent.GetEditMessage() != nil { - syncDestinationServiceID, err := ParseStringOrBinaryServiceID(syncSent.GetDestinationServiceId(), syncSent.GetDestinationServiceIdBinary()) - if err != nil && !errors.Is(err, ErrEmptyUUIDInput) { - log.Err(err).Msg("Sync message destination parse error") + case *signalpb.SyncMessage_FetchLatest_: + switch content.FetchLatest.GetType() { + case signalpb.SyncMessage_FetchLatest_STORAGE_MANIFEST: + log.Debug().Msg("Received storage manifest fetch latest notice") + go cli.SyncStorage(ctx) + default: + log.Debug(). + Stringer("fetch_latest_type", content.FetchLatest.GetType()). + Msg("Received unknown fetch latest notice") } - if syncSent.GetDestinationE164() != "" && !syncDestinationServiceID.IsEmpty() { - aci, pni := syncDestinationServiceID.ToACIAndPNI() - _, err = cli.Store.RecipientStore.UpdateRecipientE164(ctx, aci, pni, syncSent.GetDestinationE164()) - if err != nil { - log.Err(err).Msg("Failed to update recipient E164 after receiving sync message") + case *signalpb.SyncMessage_Sent_: + syncSent := content.Sent + if syncSent.GetMessage() != nil || syncSent.GetEditMessage() != nil { + syncDestinationServiceID, err := ParseStringOrBinaryServiceID(syncSent.GetDestinationServiceId(), syncSent.GetDestinationServiceIdBinary()) + if err != nil && !errors.Is(err, ErrEmptyUUIDInput) { + log.Err(err).Msg("Sync message destination parse error") } - } - for _, unident := range syncSent.GetUnidentifiedStatus() { - serviceID, err := ParseStringOrBinaryServiceID(unident.GetDestinationServiceId(), unident.GetDestinationServiceIdBinary()) - if err != nil { - log.Err(err). - Str("destination_service_id", unident.GetDestinationServiceId()). - Hex("destination_service_id_bytes", unident.GetDestinationServiceIdBinary()). - Msg("Failed to parse destination service ID of unidentified send") - continue + if syncSent.GetDestinationE164() != "" && !syncDestinationServiceID.IsEmpty() { + aci, pni := syncDestinationServiceID.ToACIAndPNI() + _, err = cli.Store.RecipientStore.UpdateRecipientE164(ctx, aci, pni, syncSent.GetDestinationE164()) + if err != nil { + log.Err(err).Msg("Failed to update recipient E164 after receiving sync message") + } } - changed, err := cli.saveSyncPNIIdentityKey(ctx, serviceID, unident.GetDestinationPniIdentityKey()) - if err != nil { - log.Err(err). - Stringer("destination_service_id", serviceID). - Msg("Failed to save PNI identity key from sync message") - } else if changed { - log.Debug(). - Stringer("destination_service_id", serviceID). - Msg("Saved new PNI identity key from sync message") + for _, unident := range syncSent.GetUnidentifiedStatus() { + serviceID, err := ParseStringOrBinaryServiceID(unident.GetDestinationServiceId(), unident.GetDestinationServiceIdBinary()) + if err != nil { + log.Err(err). + Str("destination_service_id", unident.GetDestinationServiceId()). + Hex("destination_service_id_bytes", unident.GetDestinationServiceIdBinary()). + Msg("Failed to parse destination service ID of unidentified send") + continue + } + changed, err := cli.saveSyncPNIIdentityKey(ctx, serviceID, unident.GetDestinationPniIdentityKey()) + if err != nil { + log.Err(err). + Stringer("destination_service_id", serviceID). + Msg("Failed to save PNI identity key from sync message") + } else if changed { + log.Debug(). + Stringer("destination_service_id", serviceID). + Msg("Saved new PNI identity key from sync message") + } } - } - if syncDestinationServiceID.IsEmpty() && syncSent.GetMessage().GetGroupV2() == nil && syncSent.GetEditMessage().GetDataMessage().GetGroupV2() == nil { - log.Warn().Msg("sync message sent destination is nil") - } else if msg.Sent.Message != nil { - // TODO handle expiration start ts, and maybe the sync message ts? - cli.incomingDataMessage(ctx, msg.Sent.Message, cli.Store.ACI, syncDestinationServiceID, envelope.GetServerTimestamp(), false) - } else if msg.Sent.EditMessage != nil { - cli.incomingEditMessage(ctx, msg.Sent.EditMessage, cli.Store.ACI, syncDestinationServiceID, envelope.GetServerTimestamp(), false) + if syncDestinationServiceID.IsEmpty() && syncSent.GetMessage().GetGroupV2() == nil && syncSent.GetEditMessage().GetDataMessage().GetGroupV2() == nil { + log.Warn().Msg("sync message sent destination is nil") + } else if syncSent.Message != nil { + // TODO handle expiration start ts, and maybe the sync message ts? + cli.incomingDataMessage(ctx, syncSent.Message, cli.Store.ACI, syncDestinationServiceID, envelope.GetServerTimestamp(), false) + } else if syncSent.EditMessage != nil { + cli.incomingEditMessage(ctx, syncSent.EditMessage, cli.Store.ACI, syncDestinationServiceID, envelope.GetServerTimestamp(), false) + } } - } - if msg.Contacts != nil { + case *signalpb.SyncMessage_Contacts_: log.Debug().Msg("Recieved sync message contacts") - blob := msg.Contacts.Blob - if blob != nil { + if content.Contacts.Blob != nil { // TODO roundtrip via disk to save memory - contactsBytes, err := DownloadAttachmentWithPointer(ctx, blob, nil, nil) + contactsBytes, err := DownloadAttachmentWithPointer(ctx, content.Contacts.Blob, nil, nil) if err != nil { log.Err(err).Msg("Contacts Sync DownloadAttachment error") } @@ -796,22 +818,14 @@ func (cli *Client) handleSyncMessage(ctx context.Context, msg *signalpb.SyncMess }) } } - } - if msg.Read != nil { - handlerSuccess = cli.handleEvent(&events.ReadSelf{ - Timestamp: envelope.GetTimestamp(), - Messages: msg.GetRead(), - }) - } - if msg.DeleteForMe != nil { + case *signalpb.SyncMessage_DeleteForMe_: handlerSuccess = cli.handleEvent(&events.DeleteForMe{ - Timestamp: envelope.GetTimestamp(), - SyncMessage_DeleteForMe: msg.DeleteForMe, + Timestamp: envelope.GetClientTimestamp(), + SyncMessage_DeleteForMe: content.DeleteForMe, }) - } - if msg.MessageRequestResponse != nil { - aciUUID, _ := ParseStringOrBinaryUUID(msg.MessageRequestResponse.GetThreadAci(), msg.MessageRequestResponse.GetThreadAciBinary()) - if aciUUID != uuid.Nil && msg.MessageRequestResponse.GetType() == signalpb.SyncMessage_MessageRequestResponse_ACCEPT { + case *signalpb.SyncMessage_MessageRequestResponse_: + aciUUID, _ := ParseStringOrBinaryUUID(content.MessageRequestResponse.GetThreadAci(), content.MessageRequestResponse.GetThreadAciBinary()) + if aciUUID != uuid.Nil && content.MessageRequestResponse.GetType() == signalpb.SyncMessage_MessageRequestResponse_ACCEPT { _, err := cli.Store.RecipientStore.LoadAndUpdateRecipient(ctx, aciUUID, uuid.Nil, func(recipient *types.Recipient) (changed bool, err error) { changed = !ptr.Val(recipient.Whitelisted) || recipient.NeedsPNISignature recipient.Whitelisted = ptr.Ptr(true) @@ -823,16 +837,23 @@ func (cli *Client) handleSyncMessage(ctx context.Context, msg *signalpb.SyncMess } } var groupID *libsignalgo.GroupIdentifier - if len(msg.MessageRequestResponse.GroupId) == libsignalgo.GroupIdentifierLength { - groupID = (*libsignalgo.GroupIdentifier)(msg.MessageRequestResponse.GroupId) + if len(content.MessageRequestResponse.GroupId) == libsignalgo.GroupIdentifierLength { + groupID = (*libsignalgo.GroupIdentifier)(content.MessageRequestResponse.GroupId) } handlerSuccess = cli.handleEvent(&events.MessageRequestResponse{ - Timestamp: envelope.GetTimestamp(), + Timestamp: envelope.GetClientTimestamp(), ThreadACI: aciUUID, GroupID: groupID, - Type: msg.MessageRequestResponse.GetType(), - Raw: msg.MessageRequestResponse, + Type: content.MessageRequestResponse.GetType(), + Raw: content.MessageRequestResponse, }) + default: + if msg.Read != nil { + handlerSuccess = cli.handleEvent(&events.ReadSelf{ + Timestamp: envelope.GetClientTimestamp(), + Messages: msg.Read, + }) + } } return } diff --git a/pkg/signalmeow/receiving_decrypt.go b/pkg/signalmeow/receiving_decrypt.go index 24b76ff..6296f00 100644 --- a/pkg/signalmeow/receiving_decrypt.go +++ b/pkg/signalmeow/receiving_decrypt.go @@ -64,14 +64,14 @@ func (cli *Client) decryptEnvelope( } return result - case signalpb.Envelope_PREKEY_BUNDLE, signalpb.Envelope_CIPHERTEXT: - sender, err := sourceServiceID.Address(uint(envelope.GetSourceDevice())) + case signalpb.Envelope_PREKEY_MESSAGE, signalpb.Envelope_DOUBLE_RATCHET: + sender, err := sourceServiceID.Address(uint(envelope.GetSourceDeviceId())) if err != nil { return DecryptionResult{Err: fmt.Errorf("failed to wrap address: %v", err)} } var result *DecryptionResult var bundleType string - if *envelope.Type == signalpb.Envelope_PREKEY_BUNDLE { + if *envelope.Type == signalpb.Envelope_PREKEY_MESSAGE { result, err = cli.prekeyDecrypt(ctx, destinationServiceID, sender, envelope.Content, envelope.GetServerTimestamp()) bundleType = "prekey bundle" } else { @@ -90,7 +90,7 @@ func (cli *Client) decryptEnvelope( return *result case signalpb.Envelope_PLAINTEXT_CONTENT: - addr, err := sourceServiceID.Address(uint(envelope.GetSourceDevice())) + addr, err := sourceServiceID.Address(uint(envelope.GetSourceDeviceId())) if err != nil { return DecryptionResult{Err: fmt.Errorf("failed to wrap address: %v", err)} } @@ -100,16 +100,13 @@ func (cli *Client) decryptEnvelope( } return DecryptionResult{ SenderAddress: addr, - Content: &signalpb.Content{DecryptionErrorMessage: content}, + Content: &signalpb.Content{Content: &signalpb.Content_DecryptionErrorMessage{DecryptionErrorMessage: content}}, Unencrypted: true, } case signalpb.Envelope_SERVER_DELIVERY_RECEIPT: return DecryptionResult{Err: fmt.Errorf("server delivery receipt envelopes are not yet supported")} - case signalpb.Envelope_SENDERKEY_MESSAGE: - return DecryptionResult{Err: fmt.Errorf("senderkey message envelopes are not yet supported")} - case signalpb.Envelope_UNKNOWN: return DecryptionResult{Err: fmt.Errorf("unknown envelope type")} @@ -399,7 +396,9 @@ func (cli *Client) decryptUnidentifiedSenderEnvelope(ctx context.Context, destin } result.Unencrypted = true result.Content = &signalpb.Content{ - DecryptionErrorMessage: usmcContents, + Content: &signalpb.Content_DecryptionErrorMessage{ + DecryptionErrorMessage: usmcContents, + }, } return result, err default: diff --git a/pkg/signalmeow/retry.go b/pkg/signalmeow/retry.go index 2c89ecc..a581075 100644 --- a/pkg/signalmeow/retry.go +++ b/pkg/signalmeow/retry.go @@ -19,10 +19,12 @@ package signalmeow import ( "context" "fmt" + "math/rand/v2" "slices" "time" "github.com/rs/zerolog" + "go.mau.fi/util/random" "go.mau.fi/mautrix-signal/pkg/libsignalgo" signalpb "go.mau.fi/mautrix-signal/pkg/signalmeow/protobuf" @@ -63,7 +65,9 @@ func (cli *Client) sendRetryRequest(ctx context.Context, result DecryptionResult return fmt.Errorf("failed to create ciphertext message from plaintext content: %w", err) } _, err = cli.sendContent(ctx, serviceID, uint64(time.Now().UnixMilli()), &signalpb.Content{ - DecryptionErrorMessage: demBytes, + Content: &signalpb.Content_DecryptionErrorMessage{ + DecryptionErrorMessage: demBytes, + }, }, 0, true, result.GroupID, ctm) if err != nil { return fmt.Errorf("failed to send decryption error message: %w", err) @@ -182,7 +186,11 @@ func (cli *Client) handleRetryRequest( Msg("Not responding to decryption error message") return nil } - retryContent.NullMessage = &signalpb.NullMessage{} + retryContent.Content = &signalpb.Content_NullMessage{ + NullMessage: &signalpb.NullMessage{ + Padding: random.Bytes(rand.IntN(511) + 1), + }, + } } responseTimestamp := uint64(time.Now().UnixMilli()) if cacheHit { diff --git a/pkg/signalmeow/sending.go b/pkg/signalmeow/sending.go index 94f1dcf..769798a 100644 --- a/pkg/signalmeow/sending.go +++ b/pkg/signalmeow/sending.go @@ -22,6 +22,7 @@ import ( "encoding/json" "errors" "fmt" + "math/rand/v2" "net/http" "strconv" "strings" @@ -31,6 +32,7 @@ import ( "github.com/rs/zerolog" "go.mau.fi/util/exfmt" "go.mau.fi/util/ptr" + "go.mau.fi/util/random" "google.golang.org/protobuf/proto" "go.mau.fi/mautrix-signal/pkg/libsignalgo" @@ -222,11 +224,9 @@ func (cli *Client) buildMessagesToSend( func ctmTypeToEnvelopeType(ctmType libsignalgo.CiphertextMessageType) signalpb.Envelope_Type { switch ctmType { case libsignalgo.CiphertextMessageTypeWhisper: - return signalpb.Envelope_CIPHERTEXT // 2 -> 1 + return signalpb.Envelope_DOUBLE_RATCHET // 2 -> 1 case libsignalgo.CiphertextMessageTypePreKey: - return signalpb.Envelope_PREKEY_BUNDLE // 3 -> 3 - case libsignalgo.CiphertextMessageTypeSenderKey: - return signalpb.Envelope_SENDERKEY_MESSAGE // 7 -> 7 + return signalpb.Envelope_PREKEY_MESSAGE // 3 -> 3 case libsignalgo.CiphertextMessageTypePlaintext: return signalpb.Envelope_PLAINTEXT_CONTENT // 8 -> 8 default: @@ -302,11 +302,21 @@ type SendResult interface { func (gmsr *GroupMessageSendResult) isSendResult() {} func (smsr *SendMessageResult) isSendResult() {} -func contentFromDataMessage(dataMessage *signalpb.DataMessage) *signalpb.Content { +func WrapSyncMessage(content *signalpb.SyncMessage) *signalpb.Content { + content.Padding = random.Bytes(rand.IntN(511) + 1) return &signalpb.Content{ - DataMessage: dataMessage, + Content: &signalpb.Content_SyncMessage{SyncMessage: content}, } } + +func syncSentMessage(sent *signalpb.SyncMessage_Sent) *signalpb.Content { + return WrapSyncMessage(&signalpb.SyncMessage{ + Content: &signalpb.SyncMessage_Sent_{ + Sent: sent, + }, + }) +} + func syncMessageFromGroupDataMessage(dataMessage *signalpb.DataMessage, results []SuccessfulSendResult) *signalpb.Content { unidentifiedStatuses := []*signalpb.SyncMessage_Sent_UnidentifiedDeliveryStatus{} for _, result := range results { @@ -315,17 +325,14 @@ func syncMessageFromGroupDataMessage(dataMessage *signalpb.DataMessage, results Unidentified: &result.Unidentified, }) } - return &signalpb.Content{ - SyncMessage: &signalpb.SyncMessage{ - Sent: &signalpb.SyncMessage_Sent{ - Message: dataMessage, - Timestamp: dataMessage.Timestamp, - UnidentifiedStatus: unidentifiedStatuses, - ExpirationStartTimestamp: ptr.Ptr(uint64(time.Now().UnixMilli())), - }, - }, - } + return syncSentMessage(&signalpb.SyncMessage_Sent{ + Message: dataMessage, + Timestamp: dataMessage.Timestamp, + UnidentifiedStatus: unidentifiedStatuses, + ExpirationStartTimestamp: ptr.Ptr(uint64(time.Now().UnixMilli())), + }) } + func syncMessageFromGroupEditMessage(editMessage *signalpb.EditMessage, results []SuccessfulSendResult) *signalpb.Content { unidentifiedStatuses := []*signalpb.SyncMessage_Sent_UnidentifiedDeliveryStatus{} for _, result := range results { @@ -334,58 +341,46 @@ func syncMessageFromGroupEditMessage(editMessage *signalpb.EditMessage, results Unidentified: &result.Unidentified, }) } - return &signalpb.Content{ - SyncMessage: &signalpb.SyncMessage{ - Sent: &signalpb.SyncMessage_Sent{ - EditMessage: editMessage, - Timestamp: editMessage.GetDataMessage().Timestamp, - UnidentifiedStatus: unidentifiedStatuses, - ExpirationStartTimestamp: ptr.Ptr(uint64(time.Now().UnixMilli())), - }, - }, - } + return syncSentMessage(&signalpb.SyncMessage_Sent{ + EditMessage: editMessage, + Timestamp: editMessage.GetDataMessage().Timestamp, + UnidentifiedStatus: unidentifiedStatuses, + ExpirationStartTimestamp: ptr.Ptr(uint64(time.Now().UnixMilli())), + }) } func syncMessageFromSoloDataMessage(dataMessage *signalpb.DataMessage, result SuccessfulSendResult) *signalpb.Content { - return &signalpb.Content{ - SyncMessage: &signalpb.SyncMessage{ - Sent: &signalpb.SyncMessage_Sent{ - Message: dataMessage, - DestinationE164: result.RecipientE164, + return syncSentMessage(&signalpb.SyncMessage_Sent{ + Message: dataMessage, + DestinationE164: result.RecipientE164, + DestinationServiceIdBinary: result.Recipient.Bytes(), + Timestamp: dataMessage.Timestamp, + ExpirationStartTimestamp: ptr.Ptr(uint64(time.Now().UnixMilli())), + UnidentifiedStatus: []*signalpb.SyncMessage_Sent_UnidentifiedDeliveryStatus{ + { DestinationServiceIdBinary: result.Recipient.Bytes(), - Timestamp: dataMessage.Timestamp, - ExpirationStartTimestamp: ptr.Ptr(uint64(time.Now().UnixMilli())), - UnidentifiedStatus: []*signalpb.SyncMessage_Sent_UnidentifiedDeliveryStatus{ - { - DestinationServiceIdBinary: result.Recipient.Bytes(), - Unidentified: &result.Unidentified, - DestinationPniIdentityKey: result.DestinationPNIIdentityKey.TrySerialize(), - }, - }, + Unidentified: &result.Unidentified, + DestinationPniIdentityKey: result.DestinationPNIIdentityKey.TrySerialize(), }, }, - } + }) } func syncMessageFromSoloEditMessage(editMessage *signalpb.EditMessage, result SuccessfulSendResult) *signalpb.Content { - return &signalpb.Content{ - SyncMessage: &signalpb.SyncMessage{ - Sent: &signalpb.SyncMessage_Sent{ - EditMessage: editMessage, - DestinationE164: result.RecipientE164, + return syncSentMessage(&signalpb.SyncMessage_Sent{ + EditMessage: editMessage, + DestinationE164: result.RecipientE164, + DestinationServiceIdBinary: result.Recipient.Bytes(), + Timestamp: editMessage.DataMessage.Timestamp, + ExpirationStartTimestamp: ptr.Ptr(uint64(time.Now().UnixMilli())), + UnidentifiedStatus: []*signalpb.SyncMessage_Sent_UnidentifiedDeliveryStatus{ + { DestinationServiceIdBinary: result.Recipient.Bytes(), - Timestamp: editMessage.DataMessage.Timestamp, - ExpirationStartTimestamp: ptr.Ptr(uint64(time.Now().UnixMilli())), - UnidentifiedStatus: []*signalpb.SyncMessage_Sent_UnidentifiedDeliveryStatus{ - { - DestinationServiceIdBinary: result.Recipient.Bytes(), - Unidentified: &result.Unidentified, - DestinationPniIdentityKey: result.DestinationPNIIdentityKey.TrySerialize(), - }, - }, + Unidentified: &result.Unidentified, + DestinationPniIdentityKey: result.DestinationPNIIdentityKey.TrySerialize(), }, }, - } + }) } func syncMessageFromReadReceiptMessage(ctx context.Context, receiptMessage *signalpb.ReceiptMessage, messageSender libsignalgo.ServiceID) *signalpb.Content { @@ -407,11 +402,9 @@ func syncMessageFromReadReceiptMessage(ctx context.Context, receiptMessage *sign SenderAci: proto.String(messageSender.UUID.String()), }) } - return &signalpb.Content{ - SyncMessage: &signalpb.SyncMessage{ - Read: read, - }, - } + return WrapSyncMessage(&signalpb.SyncMessage{ + Read: read, + }) } func (cli *Client) SendContactSyncRequest(ctx context.Context) error { @@ -427,13 +420,13 @@ func (cli *Client) SendContactSyncRequest(ctx context.Context) error { } cli.LastContactRequestTime = time.Now() - _, err := cli.sendContent(ctx, cli.Store.ACIServiceID(), uint64(time.Now().UnixMilli()), &signalpb.Content{ - SyncMessage: &signalpb.SyncMessage{ + _, err := cli.sendContent(ctx, cli.Store.ACIServiceID(), uint64(time.Now().UnixMilli()), WrapSyncMessage(&signalpb.SyncMessage{ + Content: &signalpb.SyncMessage_Request_{ Request: &signalpb.SyncMessage_Request{ Type: signalpb.SyncMessage_Request_CONTACTS.Enum(), }, }, - }, 0, false, nil, nil) + }), 0, false, nil, nil) if err != nil { log.Err(err).Msg("Failed to send contact sync request message to myself") return err @@ -447,13 +440,13 @@ func (cli *Client) SendStorageMasterKeyRequest(ctx context.Context) error { Logger() ctx = log.WithContext(ctx) - _, err := cli.sendContent(ctx, cli.Store.ACIServiceID(), uint64(time.Now().UnixMilli()), &signalpb.Content{ - SyncMessage: &signalpb.SyncMessage{ + _, err := cli.sendContent(ctx, cli.Store.ACIServiceID(), uint64(time.Now().UnixMilli()), WrapSyncMessage(&signalpb.SyncMessage{ + Content: &signalpb.SyncMessage_Request_{ Request: &signalpb.SyncMessage_Request{ Type: signalpb.SyncMessage_Request_KEYS.Enum(), }, }, - }, 0, false, nil, nil) + }), 0, false, nil, nil) if err != nil { log.Err(err).Msg("Failed to send key sync request message to myself") return err @@ -473,38 +466,47 @@ func TypingMessage(isTyping bool) *signalpb.Content { } else { action = signalpb.TypingMessage_STOPPED } - tm := &signalpb.TypingMessage{ - Timestamp: ×tamp, - Action: &action, - } return &signalpb.Content{ - TypingMessage: tm, + Content: &signalpb.Content_TypingMessage{ + TypingMessage: &signalpb.TypingMessage{ + Timestamp: ×tamp, + Action: &action, + }, + }, } } func DeliveredReceiptMessageForTimestamps(timestamps []uint64) *signalpb.Content { - rm := &signalpb.ReceiptMessage{ - Timestamp: timestamps, - Type: signalpb.ReceiptMessage_DELIVERY.Enum(), - } return &signalpb.Content{ - ReceiptMessage: rm, + Content: &signalpb.Content_ReceiptMessage{ + ReceiptMessage: &signalpb.ReceiptMessage{ + Timestamp: timestamps, + Type: signalpb.ReceiptMessage_DELIVERY.Enum(), + }, + }, } } func ReadReceptMessageForTimestamps(timestamps []uint64) *signalpb.Content { - rm := &signalpb.ReceiptMessage{ - Timestamp: timestamps, - Type: signalpb.ReceiptMessage_READ.Enum(), - } return &signalpb.Content{ - ReceiptMessage: rm, + Content: &signalpb.Content_ReceiptMessage{ + ReceiptMessage: &signalpb.ReceiptMessage{ + Timestamp: timestamps, + Type: signalpb.ReceiptMessage_READ.Enum(), + }, + }, } } -func wrapDataMessageInContent(dm *signalpb.DataMessage) *signalpb.Content { +func WrapDataMessage(dm *signalpb.DataMessage) *signalpb.Content { return &signalpb.Content{ - DataMessage: dm, + Content: &signalpb.Content_DataMessage{DataMessage: dm}, + } +} + +func WrapEditMessage(dm *signalpb.EditMessage) *signalpb.Content { + return &signalpb.Content{ + Content: &signalpb.Content_EditMessage{EditMessage: dm}, } } @@ -531,7 +533,7 @@ func (cli *Client) SendGroupUpdate(ctx context.Context, group *Group, groupConte Timestamp: ×tamp, GroupV2: groupContext, } - content := wrapDataMessageInContent(dm) + content := WrapDataMessage(dm) var recipients []libsignalgo.ServiceID for _, member := range group.Members { serviceID := member.UserServiceID() @@ -569,13 +571,14 @@ func (cli *Client) SendGroupMessage(ctx context.Context, gid types.GroupIdentifi return nil, err } var messageTimestamp uint64 - if content.GetDataMessage() != nil { + switch content := content.Content.(type) { + case *signalpb.Content_DataMessage: messageTimestamp = content.DataMessage.GetTimestamp() content.DataMessage.GroupV2 = groupMetadataForDataMessage(*group) - } else if content.GetEditMessage().GetDataMessage() != nil { + case *signalpb.Content_EditMessage: messageTimestamp = content.EditMessage.DataMessage.GetTimestamp() content.EditMessage.DataMessage.GroupV2 = groupMetadataForDataMessage(*group) - } else if content.GetTypingMessage() != nil { + case *signalpb.Content_TypingMessage: messageTimestamp = content.TypingMessage.GetTimestamp() groupIDBytes, err := group.GroupIdentifier.Bytes() if err != nil { @@ -611,7 +614,7 @@ func (cli *Client) sendToGroup( FailedToSendTo: []FailedSendResult{}, } } - if content.TypingMessage != nil { + if content.GetTypingMessage() != nil { // Never send typing messages via fallback path return result, nil } @@ -653,15 +656,16 @@ func (cli *Client) sendToGroup( func (cli *Client) sendGroupSyncCopy( ctx context.Context, - content *signalpb.Content, + rawContent *signalpb.Content, messageTimestamp uint64, result *GroupMessageSendResult, groupID *libsignalgo.GroupIdentifier, ) { var syncContent *signalpb.Content - if content.GetDataMessage() != nil { + switch content := rawContent.Content.(type) { + case *signalpb.Content_DataMessage: syncContent = syncMessageFromGroupDataMessage(content.DataMessage, result.SuccessfullySentTo) - } else if content.GetEditMessage() != nil { + case *signalpb.Content_EditMessage: syncContent = syncMessageFromGroupEditMessage(content.EditMessage, result.SuccessfullySentTo) } if syncContent != nil { @@ -672,16 +676,17 @@ func (cli *Client) sendGroupSyncCopy( } } -func (cli *Client) sendSyncCopy(ctx context.Context, content *signalpb.Content, messageTS uint64, result *SuccessfulSendResult) bool { +func (cli *Client) sendSyncCopy(ctx context.Context, rawContent *signalpb.Content, messageTS uint64, result *SuccessfulSendResult) bool { var syncContent *signalpb.Content - if content.GetDataMessage() != nil { + switch content := rawContent.Content.(type) { + case *signalpb.Content_DataMessage: syncContent = syncMessageFromSoloDataMessage(content.DataMessage, *result) - } else if content.GetEditMessage() != nil { + case *signalpb.Content_EditMessage: syncContent = syncMessageFromSoloEditMessage(content.EditMessage, *result) - } else if content.GetReceiptMessage().GetType() == signalpb.ReceiptMessage_READ { + case *signalpb.Content_ReceiptMessage: syncContent = syncMessageFromReadReceiptMessage(ctx, content.ReceiptMessage, result.Recipient) - } else if content.GetSyncMessage() != nil { - syncContent = content + case *signalpb.Content_SyncMessage: + syncContent = rawContent } if syncContent != nil { _, selfSendErr := cli.sendContent(ctx, cli.Store.ACIServiceID(), messageTS, syncContent, 0, true, nil, nil) @@ -697,22 +702,25 @@ func (cli *Client) sendSyncCopy(ctx context.Context, content *signalpb.Content, func (cli *Client) SendMessage(ctx context.Context, recipientID libsignalgo.ServiceID, content *signalpb.Content) SendMessageResult { // Assemble the content to send var messageTimestamp uint64 - switch { - case content.DataMessage != nil: - messageTimestamp = *content.DataMessage.Timestamp - case content.EditMessage != nil: - messageTimestamp = *content.EditMessage.DataMessage.Timestamp - case content.TypingMessage != nil: - messageTimestamp = *content.TypingMessage.Timestamp - case content.SyncMessage != nil, - content.NullMessage != nil, - content.ReceiptMessage != nil, - content.PniSignatureMessage != nil, - content.SenderKeyDistributionMessage != nil, - content.DecryptionErrorMessage != nil: + switch realContent := content.Content.(type) { + case *signalpb.Content_DataMessage: + messageTimestamp = *realContent.DataMessage.Timestamp + case *signalpb.Content_EditMessage: + messageTimestamp = *realContent.EditMessage.DataMessage.Timestamp + case *signalpb.Content_TypingMessage: + messageTimestamp = *realContent.TypingMessage.Timestamp + case *signalpb.Content_SyncMessage, + *signalpb.Content_NullMessage, + *signalpb.Content_ReceiptMessage, + *signalpb.Content_DecryptionErrorMessage: messageTimestamp = currentMessageTimestamp() + case *signalpb.Content_StoryMessage: + // not yet supported default: - panic(fmt.Errorf("unsupported payload in SendMessage")) + if content.SenderKeyDistributionMessage == nil && content.PniSignatureMessage == nil { + panic(fmt.Errorf("unsupported payload in SendMessage")) + } + messageTimestamp = currentMessageTimestamp() } var aci, pni uuid.UUID if recipientID.Type == libsignalgo.ServiceIDTypeACI { @@ -720,7 +728,7 @@ func (cli *Client) SendMessage(ctx context.Context, recipientID libsignalgo.Serv } else if recipientID.Type == libsignalgo.ServiceIDTypePNI { pni = recipientID.UUID } - isTypingOrReceipt := content.TypingMessage != nil || content.ReceiptMessage != nil + isTypingOrReceipt := content.GetTypingMessage() != nil || content.GetReceiptMessage() != nil recipientData, err := cli.Store.RecipientStore.LoadAndUpdateRecipient(ctx, aci, pni, func(recipientData *types.Recipient) (changed bool, err error) { if content.GetDataMessage().GetFlags() == uint32(signalpb.DataMessage_PROFILE_KEY_UPDATE) { recipientData.Whitelisted = ptr.Ptr(true) @@ -758,7 +766,7 @@ func (cli *Client) SendMessage(ctx context.Context, recipientID libsignalgo.Serv cli.sendSyncCopy(ctx, content, messageTimestamp, &res) } return SendMessageResult{WasSuccessful: true, SuccessfulSendResult: res} - } else if content.TypingMessage != nil && cli.Store.DeviceData.AccountRecord != nil && !cli.Store.DeviceData.AccountRecord.GetTypingIndicators() { + } else if content.GetTypingMessage() != nil && cli.Store.DeviceData.AccountRecord != nil && !cli.Store.DeviceData.AccountRecord.GetTypingIndicators() { zerolog.Ctx(ctx).Debug().Msg("Not sending typing message as typing indicators are disabled") res := SuccessfulSendResult{Recipient: recipientID} return SendMessageResult{WasSuccessful: true, SuccessfulSendResult: res} @@ -770,7 +778,7 @@ func (cli *Client) SendMessage(ctx context.Context, recipientID libsignalgo.Serv return SendMessageResult{WasSuccessful: true, SuccessfulSendResult: res} } - isDeliveryReceipt := content.ReceiptMessage != nil && content.GetReceiptMessage().GetType() == signalpb.ReceiptMessage_DELIVERY + isDeliveryReceipt := content.GetReceiptMessage() != nil && content.GetReceiptMessage().GetType() == signalpb.ReceiptMessage_DELIVERY if recipientID == cli.Store.ACIServiceID() && !isDeliveryReceipt { res := SuccessfulSendResult{ Recipient: recipientID, @@ -824,25 +832,38 @@ func currentMessageTimestamp() uint64 { } func isSyncMessageUrgent(content *signalpb.SyncMessage) bool { - return content.Sent != nil || content.Request != nil + switch content.Content.(type) { + case *signalpb.SyncMessage_Request_, + *signalpb.SyncMessage_Sent_: + return true + default: + return false + } } -func isUrgent(content *signalpb.Content) bool { - return content.DataMessage != nil || - content.CallMessage != nil || - content.StoryMessage != nil || - content.EditMessage != nil || - (content.SyncMessage != nil && isSyncMessageUrgent(content.SyncMessage)) +func isUrgent(rawContent *signalpb.Content) bool { + switch content := rawContent.Content.(type) { + case *signalpb.Content_SyncMessage: + return isSyncMessageUrgent(content.SyncMessage) + case *signalpb.Content_DataMessage, + *signalpb.Content_EditMessage, + *signalpb.Content_CallMessage, + *signalpb.Content_StoryMessage: + return true + default: + return false + } } -func getContentHint(content *signalpb.Content) libsignalgo.UnidentifiedSenderMessageContentHint { - if content.DataMessage != nil || content.EditMessage != nil { +func getContentHint(rawContent *signalpb.Content) libsignalgo.UnidentifiedSenderMessageContentHint { + switch rawContent.Content.(type) { + case *signalpb.Content_DataMessage, *signalpb.Content_EditMessage: return libsignalgo.UnidentifiedSenderMessageContentHintResendable - } - if content.TypingMessage != nil || content.ReceiptMessage != nil { + case *signalpb.Content_TypingMessage, *signalpb.Content_ReceiptMessage: return libsignalgo.UnidentifiedSenderMessageContentHintImplicit + default: + return libsignalgo.UnidentifiedSenderMessageContentHintDefault } - return libsignalgo.UnidentifiedSenderMessageContentHintDefault } func (cli *Client) sendContent( @@ -863,12 +884,12 @@ func (cli *Client) sendContent( ctx = log.WithContext(ctx) // If it's a data message, add our profile key - if content.DataMessage != nil && content.DataMessage.ProfileKey == nil { + if content.GetDataMessage() != nil && content.GetDataMessage().ProfileKey == nil { profileKey, err := cli.ProfileKeyForSignalID(ctx, cli.Store.ACI) if err != nil { log.Err(err).Msg("Error getting profile key, not adding to outgoing message") } else { - content.DataMessage.ProfileKey = profileKey.Slice() + content.GetDataMessage().ProfileKey = profileKey.Slice() } } From e0901b648fbd6504da03ff3c2eb88754232309eb Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Mon, 13 Apr 2026 16:58:43 +0300 Subject: [PATCH 558/580] handlesignal: add support for admin deletes --- pkg/connector/handlesignal.go | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/pkg/connector/handlesignal.go b/pkg/connector/handlesignal.go index 4438cb0..329b2cf 100644 --- a/pkg/connector/handlesignal.go +++ b/pkg/connector/handlesignal.go @@ -184,7 +184,7 @@ func (evt *Bv2ChatEvent) GetType() bridgev2.RemoteEventType { return bridgev2.RemoteEventReactionRemove } return bridgev2.RemoteEventReaction - case innerEvt.Delete != nil: + case innerEvt.Delete != nil, innerEvt.AdminDelete != nil: return bridgev2.RemoteEventMessageRemove case innerEvt.GetGroupV2().GetGroupChange() != nil: return bridgev2.RemoteEventChatInfoChange @@ -303,6 +303,11 @@ func (evt *Bv2ChatEvent) GetTargetMessage() networkid.MessageID { targetSentTS = innerEvt.Reaction.GetTargetSentTimestamp() case innerEvt.Delete != nil: targetSentTS = innerEvt.Delete.GetTargetSentTimestamp() + case innerEvt.AdminDelete != nil: + if len(innerEvt.AdminDelete.GetTargetAuthorAciBinary()) == 16 { + targetAuthorACI = uuid.UUID(innerEvt.AdminDelete.GetTargetAuthorAciBinary()) + } + targetSentTS = innerEvt.AdminDelete.GetTargetSentTimestamp() default: return "" } @@ -421,7 +426,7 @@ func (b *Bv2Receipt) GetReadUpTo() time.Time { return time.Time{} } -var _ bridgev2.RemoteReceipt = (*Bv2Receipt)(nil) +var _ bridgev2.RemoteReadReceipt = (*Bv2Receipt)(nil) func convertReceipts[T any](ctx context.Context, input []T, getMessageFunc func(ctx context.Context, msgID T) (*database.Message, error)) map[networkid.PortalKey]*Bv2Receipt { log := zerolog.Ctx(ctx) From fd61f51ed9e3220d70710433a501275de7963529 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Wed, 15 Apr 2026 14:28:57 +0300 Subject: [PATCH 559/580] signalmeow/storageservice: handle binary uuids in contact records --- pkg/signalmeow/storageservice.go | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/pkg/signalmeow/storageservice.go b/pkg/signalmeow/storageservice.go index fcf6848..899c54b 100644 --- a/pkg/signalmeow/storageservice.go +++ b/pkg/signalmeow/storageservice.go @@ -66,12 +66,14 @@ func (cli *Client) processStorageInTxn(ctx context.Context, update *StorageUpdat switch data := record.StorageRecord.GetRecord().(type) { case *signalpb.StorageRecord_Contact: log.Trace().Any("contact_record", data.Contact).Msg("Handling contact record") - aci, _ := uuid.Parse(data.Contact.Aci) - pni, _ := uuid.Parse(data.Contact.Pni) + aci, _ := ParseStringOrBinaryUUID(data.Contact.Aci, data.Contact.AciBinary) + pni, _ := ParseStringOrBinaryUUID(data.Contact.Pni, data.Contact.PniBinary) if aci == uuid.Nil && pni == uuid.Nil { log.Warn(). Str("raw_aci", data.Contact.Aci). Str("raw_pni", data.Contact.Pni). + Hex("raw_aci_binary", data.Contact.AciBinary). + Hex("raw_pni_binary", data.Contact.PniBinary). Str("raw_e164", data.Contact.E164). Msg("Storage service has contact record with no ACI or PNI") continue From 1f45d1af1a64a96265647ee74a80aa454b0b7296 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Thu, 16 Apr 2026 16:44:51 +0300 Subject: [PATCH 560/580] Bump version to v26.04 --- CHANGELOG.md | 9 ++++++++ cmd/mautrix-signal/main.go | 2 +- go.mod | 24 ++++++++++----------- go.sum | 44 +++++++++++++++++++------------------- 4 files changed, 44 insertions(+), 35 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d992cab..1bf9682 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,12 @@ +# v26.04 + +* Updated libsignal to v0.92.1 +* Added support for admin message deletes from Signal. +* Added support for binary service IDs in storage service. +* Fixed `private_chat_portal_meta` option not setting DM room names correctly. +* Fixed panic if user is logged out during initial chat sync. +* Fixed avatar upload failing when creating new Signal group. + # v26.03 * Switched to sending binary service ID fields in outgoing messages. diff --git a/cmd/mautrix-signal/main.go b/cmd/mautrix-signal/main.go index cc1ec10..6440669 100644 --- a/cmd/mautrix-signal/main.go +++ b/cmd/mautrix-signal/main.go @@ -37,7 +37,7 @@ var m = mxmain.BridgeMain{ Name: "mautrix-signal", URL: "https://github.com/mautrix/signal", Description: "A Matrix-Signal puppeting bridge.", - Version: "26.03", + Version: "26.04", SemCalVer: true, Connector: &connector.SignalConnector{}, diff --git a/go.mod b/go.mod index 78ca5a0..1106eb6 100644 --- a/go.mod +++ b/go.mod @@ -2,7 +2,7 @@ module go.mau.fi/mautrix-signal go 1.25.0 -toolchain go1.26.1 +toolchain go1.26.2 tool go.mau.fi/util/cmd/maubuild @@ -14,13 +14,13 @@ require ( github.com/rs/zerolog v1.35.0 github.com/stretchr/testify v1.11.1 github.com/tidwall/gjson v1.18.0 - go.mau.fi/util v0.9.8-0.20260406161447-0300c476893a - golang.org/x/crypto v0.49.0 - golang.org/x/exp v0.0.0-20260312153236-7ab1446f8b90 - golang.org/x/net v0.52.0 + go.mau.fi/util v0.9.8 + golang.org/x/crypto v0.50.0 + golang.org/x/exp v0.0.0-20260410095643-746e56fc9e2f + golang.org/x/net v0.53.0 google.golang.org/protobuf v1.36.11 gopkg.in/yaml.v3 v3.0.1 - maunium.net/go/mautrix v0.26.5-0.20260410220226-744570e6f1f5 + maunium.net/go/mautrix v0.27.0 ) require ( @@ -28,11 +28,11 @@ require ( github.com/coreos/go-systemd/v22 v22.7.0 // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/kr/pretty v0.3.1 // indirect - github.com/lib/pq v1.12.0 // indirect + github.com/lib/pq v1.12.3 // indirect github.com/mattn/go-colorable v0.1.14 // indirect github.com/mattn/go-isatty v0.0.20 // indirect - github.com/mattn/go-sqlite3 v1.14.37 // indirect - github.com/petermattis/goid v0.0.0-20260226131333-17d1149c6ac6 // indirect + github.com/mattn/go-sqlite3 v1.14.42 // indirect + github.com/petermattis/goid v0.0.0-20260330135022-df67b199bc81 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/rogpeppe/go-internal v1.10.0 // indirect github.com/rs/xid v1.6.0 // indirect @@ -42,10 +42,10 @@ require ( github.com/tidwall/sjson v1.2.5 // indirect github.com/yuin/goldmark v1.8.2 // indirect go.mau.fi/zeroconfig v0.2.0 // indirect - golang.org/x/mod v0.34.0 // indirect + golang.org/x/mod v0.35.0 // indirect golang.org/x/sync v0.20.0 // indirect - golang.org/x/sys v0.42.0 // indirect - golang.org/x/text v0.35.0 // indirect + golang.org/x/sys v0.43.0 // indirect + golang.org/x/text v0.36.0 // indirect gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect gopkg.in/natefinch/lumberjack.v2 v2.2.1 // indirect maunium.net/go/mauflag v1.0.0 // indirect diff --git a/go.sum b/go.sum index 57a3b8d..0f27daa 100644 --- a/go.sum +++ b/go.sum @@ -22,18 +22,18 @@ github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= -github.com/lib/pq v1.12.0 h1:mC1zeiNamwKBecjHarAr26c/+d8V5w/u4J0I/yASbJo= -github.com/lib/pq v1.12.0/go.mod h1:/p+8NSbOcwzAEI7wiMXFlgydTwcgTr3OSKMsD2BitpA= +github.com/lib/pq v1.12.3 h1:tTWxr2YLKwIvK90ZXEw8GP7UFHtcbTtty8zsI+YjrfQ= +github.com/lib/pq v1.12.3/go.mod h1:/p+8NSbOcwzAEI7wiMXFlgydTwcgTr3OSKMsD2BitpA= github.com/mattn/go-colorable v0.1.14 h1:9A9LHSqF/7dyVVX6g0U9cwm9pG3kP9gSzcuIPHPsaIE= github.com/mattn/go-colorable v0.1.14/go.mod h1:6LmQG8QLFO4G5z1gPvYEzlUgJ2wF+stgPZH1UqBm1s8= github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mattn/go-pointer v0.0.1 h1:n+XhsuGeVO6MEAp7xyEukFINEa+Quek5psIR/ylA6o0= github.com/mattn/go-pointer v0.0.1/go.mod h1:2zXcozF6qYGgmsG+SeTZz3oAbFLdD3OWqnUbNvJZAlc= -github.com/mattn/go-sqlite3 v1.14.37 h1:3DOZp4cXis1cUIpCfXLtmlGolNLp2VEqhiB/PARNBIg= -github.com/mattn/go-sqlite3 v1.14.37/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y= -github.com/petermattis/goid v0.0.0-20260226131333-17d1149c6ac6 h1:rh2lKw/P/EqHa724vYH2+VVQ1YnW4u6EOXl0PMAovZE= -github.com/petermattis/goid v0.0.0-20260226131333-17d1149c6ac6/go.mod h1:pxMtw7cyUw6B2bRH0ZBANSPg+AoSud1I1iyJHI69jH4= +github.com/mattn/go-sqlite3 v1.14.42 h1:MigqEP4ZmHw3aIdIT7T+9TLa90Z6smwcthx+Azv4Cgo= +github.com/mattn/go-sqlite3 v1.14.42/go.mod h1:pjEuOr8IwzLJP2MfGeTb0A35jauH+C2kbHKBr7yXKVQ= +github.com/petermattis/goid v0.0.0-20260330135022-df67b199bc81 h1:WDsQxOJDy0N1VRAjXLpi8sCEZRSGarLWQevDxpTBRrM= +github.com/petermattis/goid v0.0.0-20260330135022-df67b199bc81/go.mod h1:pxMtw7cyUw6B2bRH0ZBANSPg+AoSud1I1iyJHI69jH4= github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= @@ -61,25 +61,25 @@ github.com/tidwall/sjson v1.2.5 h1:kLy8mja+1c9jlljvWTlSazM7cKDRfJuR/bOJhcY5NcY= github.com/tidwall/sjson v1.2.5/go.mod h1:Fvgq9kS/6ociJEDnK0Fk1cpYF4FIW6ZF7LAe+6jwd28= github.com/yuin/goldmark v1.8.2 h1:kEGpgqJXdgbkhcOgBxkC0X0PmoPG1ZyoZ117rDVp4zE= github.com/yuin/goldmark v1.8.2/go.mod h1:ip/1k0VRfGynBgxOz0yCqHrbZXhcjxyuS66Brc7iBKg= -go.mau.fi/util v0.9.8-0.20260406161447-0300c476893a h1:OQQF3rTJH10l6+dcP0OKnYbNDMBTGoIZZINNJm8QBG8= -go.mau.fi/util v0.9.8-0.20260406161447-0300c476893a/go.mod h1:5T2f3ZWZFAGgmFwg3dGw7YK6kIsb9lryDzvynoR98pE= +go.mau.fi/util v0.9.8 h1:+/jf8eM2dAT2wx9UidmaneH28r/CSCKCniCyby1qWz8= +go.mau.fi/util v0.9.8/go.mod h1:up/5mbzH2M1pSBNXqRxODn8dg/hEKbLJu92W4/SNAX0= go.mau.fi/zeroconfig v0.2.0 h1:e/OGEERqVRRKlgaro7E6bh8xXiKFSXB3eNNIud7FUjU= go.mau.fi/zeroconfig v0.2.0/go.mod h1:J0Vn0prHNOm493oZoQ84kq83ZaNCYZnq+noI1b1eN8w= -golang.org/x/crypto v0.49.0 h1:+Ng2ULVvLHnJ/ZFEq4KdcDd/cfjrrjjNSXNzxg0Y4U4= -golang.org/x/crypto v0.49.0/go.mod h1:ErX4dUh2UM+CFYiXZRTcMpEcN8b/1gxEuv3nODoYtCA= -golang.org/x/exp v0.0.0-20260312153236-7ab1446f8b90 h1:jiDhWWeC7jfWqR9c/uplMOqJ0sbNlNWv0UkzE0vX1MA= -golang.org/x/exp v0.0.0-20260312153236-7ab1446f8b90/go.mod h1:xE1HEv6b+1SCZ5/uscMRjUBKtIxworgEcEi+/n9NQDQ= -golang.org/x/mod v0.34.0 h1:xIHgNUUnW6sYkcM5Jleh05DvLOtwc6RitGHbDk4akRI= -golang.org/x/mod v0.34.0/go.mod h1:ykgH52iCZe79kzLLMhyCUzhMci+nQj+0XkbXpNYtVjY= -golang.org/x/net v0.52.0 h1:He/TN1l0e4mmR3QqHMT2Xab3Aj3L9qjbhRm78/6jrW0= -golang.org/x/net v0.52.0/go.mod h1:R1MAz7uMZxVMualyPXb+VaqGSa3LIaUqk0eEt3w36Sw= +golang.org/x/crypto v0.50.0 h1:zO47/JPrL6vsNkINmLoo/PH1gcxpls50DNogFvB5ZGI= +golang.org/x/crypto v0.50.0/go.mod h1:3muZ7vA7PBCE6xgPX7nkzzjiUq87kRItoJQM1Yo8S+Q= +golang.org/x/exp v0.0.0-20260410095643-746e56fc9e2f h1:W3F4c+6OLc6H2lb//N1q4WpJkhzJCK5J6kUi1NTVXfM= +golang.org/x/exp v0.0.0-20260410095643-746e56fc9e2f/go.mod h1:J1xhfL/vlindoeF/aINzNzt2Bket5bjo9sdOYzOsU80= +golang.org/x/mod v0.35.0 h1:Ww1D637e6Pg+Zb2KrWfHQUnH2dQRLBQyAtpr/haaJeM= +golang.org/x/mod v0.35.0/go.mod h1:+GwiRhIInF8wPm+4AoT6L0FA1QWAad3OMdTRx4tFYlU= +golang.org/x/net v0.53.0 h1:d+qAbo5L0orcWAr0a9JweQpjXF19LMXJE8Ey7hwOdUA= +golang.org/x/net v0.53.0/go.mod h1:JvMuJH7rrdiCfbeHoo3fCQU24Lf5JJwT9W3sJFulfgs= golang.org/x/sync v0.20.0 h1:e0PTpb7pjO8GAtTs2dQ6jYa5BWYlMuX047Dco/pItO4= golang.org/x/sync v0.20.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.42.0 h1:omrd2nAlyT5ESRdCLYdm3+fMfNFE/+Rf4bDIQImRJeo= -golang.org/x/sys v0.42.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= -golang.org/x/text v0.35.0 h1:JOVx6vVDFokkpaq1AEptVzLTpDe9KGpj5tR4/X+ybL8= -golang.org/x/text v0.35.0/go.mod h1:khi/HExzZJ2pGnjenulevKNX1W67CUy0AsXcNubPGCA= +golang.org/x/sys v0.43.0 h1:Rlag2XtaFTxp19wS8MXlJwTvoh8ArU6ezoyFsMyCTNI= +golang.org/x/sys v0.43.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= +golang.org/x/text v0.36.0 h1:JfKh3XmcRPqZPKevfXVpI1wXPTqbkE5f7JA92a55Yxg= +golang.org/x/text v0.36.0/go.mod h1:NIdBknypM8iqVmPiuco0Dh6P5Jcdk8lJL0CUebqK164= google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE= google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= @@ -91,5 +91,5 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= maunium.net/go/mauflag v1.0.0 h1:YiaRc0tEI3toYtJMRIfjP+jklH45uDHtT80nUamyD4M= maunium.net/go/mauflag v1.0.0/go.mod h1:nLivPOpTpHnpzEh8jEdSL9UqO9+/KBJFmNRlwKfkPeA= -maunium.net/go/mautrix v0.26.5-0.20260410220226-744570e6f1f5 h1:icMEYdJZfRKWXf5AyPk/2jncA84DmfxzrjhCZ4Mm/PE= -maunium.net/go/mautrix v0.26.5-0.20260410220226-744570e6f1f5/go.mod h1:MX4DQLiBe0c7sI/wizruqdxHinSOWs42/DYsP9GH7Q4= +maunium.net/go/mautrix v0.27.0 h1:yfEYwoIluVWkofUgbZl9gP4i5nQTF+QNsxtb+r5bKlM= +maunium.net/go/mautrix v0.27.0/go.mod h1:7QpEQiTy6p4LHkXXaZI+N46tGYy8HMhD0JjzZAFoFWs= From d4b2659f96d1b5fbabc7fc8794ebf57b0a71a1d7 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Thu, 23 Apr 2026 20:39:33 +0300 Subject: [PATCH 561/580] signalmeow/sending: remove unnecessary warnings for receipt sync messages --- pkg/signalmeow/sending.go | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/pkg/signalmeow/sending.go b/pkg/signalmeow/sending.go index 769798a..a485b54 100644 --- a/pkg/signalmeow/sending.go +++ b/pkg/signalmeow/sending.go @@ -384,15 +384,7 @@ func syncMessageFromSoloEditMessage(editMessage *signalpb.EditMessage, result Su } func syncMessageFromReadReceiptMessage(ctx context.Context, receiptMessage *signalpb.ReceiptMessage, messageSender libsignalgo.ServiceID) *signalpb.Content { - if *receiptMessage.Type != signalpb.ReceiptMessage_READ { - zerolog.Ctx(ctx).Warn(). - Any("receipt_message_type", receiptMessage.Type). - Msg("syncMessageFromReadReceiptMessage called with non-read receipt message") - return nil - } else if messageSender.Type != libsignalgo.ServiceIDTypeACI { - zerolog.Ctx(ctx).Warn(). - Stringer("message_sender", messageSender). - Msg("syncMessageFromReadReceiptMessage called with non-ACI message sender") + if *receiptMessage.Type != signalpb.ReceiptMessage_READ || messageSender.Type != libsignalgo.ServiceIDTypeACI { return nil } read := []*signalpb.SyncMessage_Read{} From 2b2a3b036f5d8095d9603e414055f770c1a2a0b9 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Mon, 27 Apr 2026 12:19:52 +0300 Subject: [PATCH 562/580] signalmeow/attachments: use go-util for pkcs7 padding --- go.mod | 2 +- go.sum | 4 ++-- pkg/signalmeow/attachments.go | 44 ++++++++++++++++++++--------------- 3 files changed, 28 insertions(+), 22 deletions(-) diff --git a/go.mod b/go.mod index 1106eb6..8df1d19 100644 --- a/go.mod +++ b/go.mod @@ -14,7 +14,7 @@ require ( github.com/rs/zerolog v1.35.0 github.com/stretchr/testify v1.11.1 github.com/tidwall/gjson v1.18.0 - go.mau.fi/util v0.9.8 + go.mau.fi/util v0.9.9-0.20260424160448-fd0d9737ad38 golang.org/x/crypto v0.50.0 golang.org/x/exp v0.0.0-20260410095643-746e56fc9e2f golang.org/x/net v0.53.0 diff --git a/go.sum b/go.sum index 0f27daa..af95348 100644 --- a/go.sum +++ b/go.sum @@ -61,8 +61,8 @@ github.com/tidwall/sjson v1.2.5 h1:kLy8mja+1c9jlljvWTlSazM7cKDRfJuR/bOJhcY5NcY= github.com/tidwall/sjson v1.2.5/go.mod h1:Fvgq9kS/6ociJEDnK0Fk1cpYF4FIW6ZF7LAe+6jwd28= github.com/yuin/goldmark v1.8.2 h1:kEGpgqJXdgbkhcOgBxkC0X0PmoPG1ZyoZ117rDVp4zE= github.com/yuin/goldmark v1.8.2/go.mod h1:ip/1k0VRfGynBgxOz0yCqHrbZXhcjxyuS66Brc7iBKg= -go.mau.fi/util v0.9.8 h1:+/jf8eM2dAT2wx9UidmaneH28r/CSCKCniCyby1qWz8= -go.mau.fi/util v0.9.8/go.mod h1:up/5mbzH2M1pSBNXqRxODn8dg/hEKbLJu92W4/SNAX0= +go.mau.fi/util v0.9.9-0.20260424160448-fd0d9737ad38 h1:D4OKITjyvlud39Q10oMnfhdeNkzEIVkXrEeCW6nvgLk= +go.mau.fi/util v0.9.9-0.20260424160448-fd0d9737ad38/go.mod h1:up/5mbzH2M1pSBNXqRxODn8dg/hEKbLJu92W4/SNAX0= go.mau.fi/zeroconfig v0.2.0 h1:e/OGEERqVRRKlgaro7E6bh8xXiKFSXB3eNNIud7FUjU= go.mau.fi/zeroconfig v0.2.0/go.mod h1:J0Vn0prHNOm493oZoQ84kq83ZaNCYZnq+noI1b1eN8w= golang.org/x/crypto v0.50.0 h1:zO47/JPrL6vsNkINmLoo/PH1gcxpls50DNogFvB5ZGI= diff --git a/pkg/signalmeow/attachments.go b/pkg/signalmeow/attachments.go index a48414e..c091827 100644 --- a/pkg/signalmeow/attachments.go +++ b/pkg/signalmeow/attachments.go @@ -35,6 +35,7 @@ import ( "github.com/rs/zerolog" "go.mau.fi/util/fallocate" + "go.mau.fi/util/pkcs7" "go.mau.fi/util/random" "google.golang.org/protobuf/proto" @@ -136,6 +137,15 @@ func DownloadAttachment( const MACLength = 32 const IVLength = 16 +func macAndAESDecrypt(body, key []byte) ([]byte, error) { + l := len(body) - MACLength + if !verifyMAC(key[MACLength:], body[:l], body[l:]) { + return nil, ErrInvalidMACForAttachment + } + + return aesDecrypt(key[:MACLength], body[:l]) +} + func decryptAttachment(body, key, digest []byte, plaintextDigest bool, size uint32) ([]byte, error) { if !plaintextDigest { hash := sha256.Sum256(body) @@ -143,12 +153,7 @@ func decryptAttachment(body, key, digest []byte, plaintextDigest bool, size uint return nil, ErrInvalidDigestForAttachment } } - l := len(body) - MACLength - if !verifyMAC(key[MACLength:], body[:l], body[l:]) { - return nil, ErrInvalidMACForAttachment - } - - decrypted, err := aesDecrypt(key[:MACLength], body[:l]) + decrypted, err := macAndAESDecrypt(body, key) if err != nil { return nil, err } @@ -240,6 +245,14 @@ func extend(data []byte, paddedLen int) []byte { } } +func macAndAESEncrypt(keys, plaintext []byte) ([]byte, error) { + encrypted, err := aesEncrypt(keys[:32], plaintext) + if err != nil { + return nil, err + } + return appendMAC(keys[32:], encrypted), nil +} + func (cli *Client) UploadAttachment(ctx context.Context, body []byte) (*signalpb.AttachmentPointer, error) { log := zerolog.Ctx(ctx).With().Str("func", "upload attachment").Logger() keys := random.Bytes(64) // combined AES and MAC keys @@ -255,11 +268,10 @@ func (cli *Client) UploadAttachment(ctx context.Context, body []byte) (*signalpb } body = extend(body, paddedLen) - encrypted, err := aesEncrypt(keys[:32], body) + encryptedWithMAC, err := macAndAESEncrypt(keys, body) if err != nil { return nil, err } - encryptedWithMAC := appendMAC(keys[32:], encrypted) // Get upload attributes from Signal server attributesPath := "/v4/attachments/form/upload" @@ -467,13 +479,10 @@ func aesDecrypt(key, ciphertext []byte) ([]byte, error) { } iv := ciphertext[:IVLength] + ciphertext = ciphertext[IVLength:] mode := cipher.NewCBCDecrypter(block, iv) mode.CryptBlocks(ciphertext, ciphertext) - pad := ciphertext[len(ciphertext)-1] - if pad > aes.BlockSize { - return nil, fmt.Errorf("pad value (%d) larger than AES blocksize (%d)", pad, aes.BlockSize) - } - return ciphertext[aes.BlockSize : len(ciphertext)-int(pad)], nil + return pkcs7.Unpad(ciphertext) } func aesDecryptFile(key []byte, file *os.File, downloadedSize int64) (int64, error) { @@ -533,14 +542,11 @@ func aesEncrypt(key, plaintext []byte) ([]byte, error) { return nil, err } - pad := aes.BlockSize - len(plaintext)%aes.BlockSize - plaintext = append(plaintext, bytes.Repeat([]byte{byte(pad)}, pad)...) - - ciphertext := make([]byte, len(plaintext)) + plaintext = pkcs7.Pad(plaintext, aes.BlockSize) iv := random.Bytes(16) mode := cipher.NewCBCEncrypter(block, iv) - mode.CryptBlocks(ciphertext, plaintext) + mode.CryptBlocks(plaintext, plaintext) - return append(iv, ciphertext...), nil + return append(iv, plaintext...), nil } From 6beb2faa9fa2ee2dda264f813766bd6517db5d84 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Thu, 23 Apr 2026 20:39:21 +0300 Subject: [PATCH 563/580] msgconv/from-matrix: preserve sticker pack metadata when sending to signal --- go.mod | 2 +- go.sum | 4 +-- pkg/msgconv/from-matrix.go | 29 ++++++++++--------- pkg/msgconv/from-signal.go | 20 ++++++------- pkg/msgconv/imagepack.go | 57 ++++++++++++++++++++++++++++++++++++++ 5 files changed, 84 insertions(+), 28 deletions(-) create mode 100644 pkg/msgconv/imagepack.go diff --git a/go.mod b/go.mod index 8df1d19..a4718d6 100644 --- a/go.mod +++ b/go.mod @@ -20,7 +20,7 @@ require ( golang.org/x/net v0.53.0 google.golang.org/protobuf v1.36.11 gopkg.in/yaml.v3 v3.0.1 - maunium.net/go/mautrix v0.27.0 + maunium.net/go/mautrix v0.27.1-0.20260428110059-49a05bf06436 ) require ( diff --git a/go.sum b/go.sum index af95348..ddff313 100644 --- a/go.sum +++ b/go.sum @@ -91,5 +91,5 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= maunium.net/go/mauflag v1.0.0 h1:YiaRc0tEI3toYtJMRIfjP+jklH45uDHtT80nUamyD4M= maunium.net/go/mauflag v1.0.0/go.mod h1:nLivPOpTpHnpzEh8jEdSL9UqO9+/KBJFmNRlwKfkPeA= -maunium.net/go/mautrix v0.27.0 h1:yfEYwoIluVWkofUgbZl9gP4i5nQTF+QNsxtb+r5bKlM= -maunium.net/go/mautrix v0.27.0/go.mod h1:7QpEQiTy6p4LHkXXaZI+N46tGYy8HMhD0JjzZAFoFWs= +maunium.net/go/mautrix v0.27.1-0.20260428110059-49a05bf06436 h1:vga9ypiOLJmGguxq4D1aquDPFihOuD99EGPEwva12UI= +maunium.net/go/mautrix v0.27.1-0.20260428110059-49a05bf06436/go.mod h1:4fZ0M0xB5ZtueQI65RilX28J/3794BeK+LaCg4U61Jk= diff --git a/pkg/msgconv/from-matrix.go b/pkg/msgconv/from-matrix.go index 89b0181..a334afd 100644 --- a/pkg/msgconv/from-matrix.go +++ b/pkg/msgconv/from-matrix.go @@ -110,21 +110,24 @@ func (mc *MessageConverter) ToSignal( return nil, fmt.Errorf("failed to convert sticker: %w", err) } att.Flags = proto.Uint32(uint32(signalpb.AttachmentPointer_BORDERLESS)) - var emoji *string - // TODO check for single grapheme cluster? - if len([]rune(content.Body)) == 1 { - emoji = proto.String(variationselector.Remove(content.Body)) - } - dm.Sticker = &signalpb.DataMessage_Sticker{ - // Signal iOS validates that pack id/key are of the correct length. - // Android is fine with any non-nil values (like a zero-length byte string). - PackId: make([]byte, 16), - PackKey: make([]byte, 32), - StickerId: proto.Uint32(0), - Data: att, - Emoji: emoji, + dm.Sticker = ParseStickerMeta(content.Info.BridgedSticker) + if dm.Sticker == nil { + var emoji *string + // TODO check for single grapheme cluster? + if len([]rune(content.Body)) == 1 { + emoji = proto.String(variationselector.Remove(content.Body)) + } + dm.Sticker = &signalpb.DataMessage_Sticker{ + // Signal iOS validates that pack id/key are of the correct length. + // Android is fine with any non-nil values (like a zero-length byte string). + PackId: make([]byte, 16), + PackKey: make([]byte, 32), + StickerId: proto.Uint32(0), + Emoji: emoji, + } } + dm.Sticker.Data = att case event.MsgLocation: lat, lon, err := parseGeoURI(content.GeoURI) if err != nil { diff --git a/pkg/msgconv/from-signal.go b/pkg/msgconv/from-signal.go index 96b4f10..defbe44 100644 --- a/pkg/msgconv/from-signal.go +++ b/pkg/msgconv/from-signal.go @@ -468,20 +468,16 @@ func (mc *MessageConverter) convertStickerToMatrix(ctx context.Context, sticker converted.Content.Info.Height = 200 } converted.Content.Body = sticker.GetEmoji() + if len(sticker.GetPackId()) == PackIDLength && len(sticker.GetPackKey()) == PackKeyLength && !bytes.Equal(sticker.GetPackId(), zeroPackID) { + converted.Content.Info.BridgedSticker = &event.BridgedSticker{ + Network: StickerSourceID, + ID: strconv.FormatUint(uint64(sticker.GetStickerId()), 10), + Emoji: sticker.GetEmoji(), + PackURL: fmt.Sprintf(PackURLFormat, sticker.GetPackId(), sticker.GetPackKey()), + } + } converted.Type = event.EventSticker converted.Content.MsgType = "" - if converted.Extra == nil { - converted.Extra = map[string]any{} - } - // TODO fetch full pack metadata like the old bridge did? - converted.Extra["fi.mau.signal.sticker"] = map[string]any{ - "id": sticker.GetStickerId(), - "emoji": sticker.GetEmoji(), - "pack": map[string]any{ - "id": sticker.GetPackId(), - "key": sticker.GetPackKey(), - }, - } return converted } diff --git a/pkg/msgconv/imagepack.go b/pkg/msgconv/imagepack.go new file mode 100644 index 0000000..910b5bc --- /dev/null +++ b/pkg/msgconv/imagepack.go @@ -0,0 +1,57 @@ +// mautrix-signal - A Matrix-Signal puppeting bridge. +// Copyright (C) 2026 Tulir Asokan +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +package msgconv + +import ( + "fmt" + "strconv" + + "google.golang.org/protobuf/proto" + "maunium.net/go/mautrix/event" + + signalpb "go.mau.fi/mautrix-signal/pkg/signalmeow/protobuf" +) + +const StickerSourceID = "signal" +const PackURLFormat = "https://signal.art/addstickers/#pack_id=%x&pack_key=%x" + +const PackIDLength = 16 +const PackKeyLength = 32 +const PackURLLength = len(PackURLFormat) - len("%x")*2 + PackIDLength*2 + PackKeyLength*2 + +var zeroPackID = make([]byte, PackIDLength) + +func ParseStickerMeta(info *event.BridgedSticker) *signalpb.DataMessage_Sticker { + if info.Network != StickerSourceID || len(info.PackURL) != PackURLLength { + return nil + } + stickerID, err := strconv.ParseUint(info.ID, 10, 32) + if err != nil { + return nil + } + var packID, packKey []byte + _, err = fmt.Sscanf(info.PackURL, PackURLFormat, &packID, &packKey) + if err != nil || len(packID) != PackIDLength || len(packKey) != PackKeyLength { + return nil + } + return &signalpb.DataMessage_Sticker{ + PackId: packID, + PackKey: packKey, + StickerId: proto.Uint32(uint32(stickerID)), + Emoji: &info.Emoji, + } +} From c2afb9f1135e125f6baa3252b4faf8a4ea960eba Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Mon, 27 Apr 2026 12:22:20 +0300 Subject: [PATCH 564/580] signalmeow/web: sent ContentLength field in request --- pkg/signalmeow/web/web.go | 1 + 1 file changed, 1 insertion(+) diff --git a/pkg/signalmeow/web/web.go b/pkg/signalmeow/web/web.go index d0fcd01..e617b40 100644 --- a/pkg/signalmeow/web/web.go +++ b/pkg/signalmeow/web/web.go @@ -129,6 +129,7 @@ func SendHTTPRequest(ctx context.Context, host, method, path string, opt *HTTPRe } else { req.Header.Set("Content-Type", string(ContentTypeJSON)) } + req.ContentLength = int64(len(opt.Body)) req.Header.Set("Content-Length", fmt.Sprintf("%d", len(opt.Body))) req.Header.Set("User-Agent", UserAgent) req.Header.Set("X-Signal-Agent", SignalAgent) From 9e9dc8b548b35a8a964358d835ae12b161d020fc Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Mon, 27 Apr 2026 12:30:54 +0300 Subject: [PATCH 565/580] signalmeow/sticker: add methods for creating and fetching sticker packs --- go.mod | 2 +- pkg/signalmeow/sticker.go | 251 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 252 insertions(+), 1 deletion(-) create mode 100644 pkg/signalmeow/sticker.go diff --git a/go.mod b/go.mod index a4718d6..030ad61 100644 --- a/go.mod +++ b/go.mod @@ -18,6 +18,7 @@ require ( golang.org/x/crypto v0.50.0 golang.org/x/exp v0.0.0-20260410095643-746e56fc9e2f golang.org/x/net v0.53.0 + golang.org/x/sync v0.20.0 google.golang.org/protobuf v1.36.11 gopkg.in/yaml.v3 v3.0.1 maunium.net/go/mautrix v0.27.1-0.20260428110059-49a05bf06436 @@ -43,7 +44,6 @@ require ( github.com/yuin/goldmark v1.8.2 // indirect go.mau.fi/zeroconfig v0.2.0 // indirect golang.org/x/mod v0.35.0 // indirect - golang.org/x/sync v0.20.0 // indirect golang.org/x/sys v0.43.0 // indirect golang.org/x/text v0.36.0 // indirect gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect diff --git a/pkg/signalmeow/sticker.go b/pkg/signalmeow/sticker.go new file mode 100644 index 0000000..2759d18 --- /dev/null +++ b/pkg/signalmeow/sticker.go @@ -0,0 +1,251 @@ +// mautrix-signal - A Matrix-signal puppeting bridge. +// Copyright (C) 2026 Tulir Asokan +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +package signalmeow + +import ( + "bytes" + "context" + "crypto/hkdf" + "crypto/sha256" + "encoding/hex" + "errors" + "fmt" + "io" + "mime/multipart" + "net/http" + "net/textproto" + "sync" + + "go.mau.fi/util/exerrors" + "go.mau.fi/util/random" + "golang.org/x/sync/semaphore" + "google.golang.org/protobuf/proto" + + signalpb "go.mau.fi/mautrix-signal/pkg/signalmeow/protobuf" + "go.mau.fi/mautrix-signal/pkg/signalmeow/web" +) + +func DownloadStickerPackManifest(ctx context.Context, packID, packKey []byte) (*signalpb.Pack, error) { + if len(packID) != 16 { + return nil, fmt.Errorf("invalid pack ID length: %d", len(packID)) + } + resp, err := downloadStickerData(ctx, fmt.Sprintf("/stickers/%x/manifest.proto", packID), packKey) + if err != nil { + return nil, err + } + var pack signalpb.Pack + err = proto.Unmarshal(resp, &pack) + if err != nil { + return nil, fmt.Errorf("failed to unmarshal decrypted manifest: %w", err) + } + return &pack, nil +} + +func DownloadStickerPackItem(ctx context.Context, packID, packKey []byte, stickerID uint32) ([]byte, error) { + if len(packID) != 16 { + return nil, fmt.Errorf("invalid pack ID length: %d", len(packID)) + } + return downloadStickerData(ctx, fmt.Sprintf("/stickers/%x/full/%d", packID, stickerID), packKey) +} + +func downloadStickerData(ctx context.Context, path string, packKey []byte) ([]byte, error) { + if len(packKey) != 32 { + return nil, fmt.Errorf("invalid pack key length: %d", len(packKey)) + } + var body, decrypted []byte + resp, err := web.SendHTTPRequest(ctx, web.CDN1Hostname, http.MethodGet, path, nil) + defer web.CloseBody(resp) + if err != nil { + return nil, fmt.Errorf("failed to make request: %w", err) + } else if resp.StatusCode != http.StatusOK { + return nil, fmt.Errorf("unexpected status code %d", resp.StatusCode) + } else if body, err = io.ReadAll(resp.Body); err != nil { + return nil, fmt.Errorf("failed to read response: %w", err) + } else if decrypted, err = decryptSticker(packKey, body); err != nil { + return nil, fmt.Errorf("failed to decrypt response: %w", err) + } else { + return decrypted, nil + } +} + +type stickerUploadAttributes struct { + ACL string `json:"acl"` + Algorithm string `json:"algorithm"` + Credential string `json:"credential"` + Date string `json:"date"` + ID int `json:"id"` + Key string `json:"key"` + Policy string `json:"policy"` + Signature string `json:"signature"` +} + +func (sua *stickerUploadAttributes) makeFormBody(encryptedData []byte) (*web.HTTPReqOpt, error) { + var buf bytes.Buffer + writer := multipart.NewWriter(&buf) + var closed bool + // This isn't necessary in practice, just do it to avoid linter warnings + defer func() { + if !closed { + _ = writer.Close() + } + }() + fields := map[string]string{ + "key": sua.Key, + "acl": sua.ACL, + "policy": sua.Policy, + "x-amz-algorithm": sua.Algorithm, + "x-amz-credential": sua.Credential, + "x-amz-date": sua.Date, + "Content-Type": "application/octet-stream", + } + for key, value := range fields { + err := writer.WriteField(key, value) + if err != nil { + return nil, fmt.Errorf("failed to write multipart field %s: %w", key, err) + } + } + filePart, err := writer.CreatePart(textproto.MIMEHeader{ + "Content-Type": []string{"application/octet-stream"}, + "Content-Disposition": []string{`form-data; name="file"`}, + }) + if err != nil { + return nil, fmt.Errorf("failed to create multipart file part: %w", err) + } + _, err = filePart.Write(encryptedData) + if err != nil { + return nil, fmt.Errorf("failed to write file data to multipart body: %w", err) + } + err = writer.Close() + if err != nil { + return nil, fmt.Errorf("failed to close multipart writer: %w", err) + } + closed = true + return &web.HTTPReqOpt{ + Body: buf.Bytes(), + ContentType: web.ContentType(writer.FormDataContentType()), + }, nil +} + +func (sua *stickerUploadAttributes) upload(ctx context.Context, packKey, fileData []byte) error { + encryptedData, err := macAndAESEncrypt(fileData, deriveStickerPackKey(packKey)) + if err != nil { + return fmt.Errorf("failed to encrypt sticker data: %w", err) + } + req, err := sua.makeFormBody(encryptedData) + if err != nil { + return fmt.Errorf("failed to prepare request: %w", err) + } + resp, err := web.SendHTTPRequest(ctx, web.CDN1Hostname, http.MethodPost, "/", req) + if err != nil { + return err + } + _ = resp.Body.Close() + if resp.StatusCode < 200 || resp.StatusCode >= 300 { + return fmt.Errorf("unexpected status code %d", resp.StatusCode) + } + return nil +} + +func (sua *stickerUploadAttributes) uploadAsync( + ctx context.Context, + packKey []byte, + getFileData func(context.Context) ([]byte, error), + sema *semaphore.Weighted, + done func(), + onError func(error), +) { + defer done() + err := sema.Acquire(ctx, 1) + if err != nil { + return + } + defer sema.Release(1) + fileData, err := getFileData(ctx) + if err == nil { + err = sua.upload(ctx, packKey, fileData) + } + if err != nil { + onError(err) + } +} + +type stickerPackUploadAttributes struct { + PackID string `json:"packId"` + Manifest *stickerUploadAttributes `json:"manifest"` + Stickers []*stickerUploadAttributes `json:"stickers"` +} + +var StickerUploadParallelism = 4 + +func (cli *Client) UploadStickerPack(ctx context.Context, pack *signalpb.Pack, stickerData []func(context.Context) ([]byte, error)) (packID, packKey []byte, err error) { + for i, sticker := range pack.Stickers { + if sticker.GetId() >= uint32(len(stickerData)) { + return nil, nil, fmt.Errorf("sticker ID %d at index %d is out of bounds, only %d sticker blobs provided", sticker.GetId(), i, len(stickerData)) + } + } + marshaledPack, err := proto.Marshal(pack) + if err != nil { + return nil, nil, fmt.Errorf("failed to marshal pack: %w", err) + } + packKey = random.Bytes(32) + resp, err := cli.AuthedWS.SendRequest(ctx, http.MethodGet, fmt.Sprintf("/v1/sticker/pack/form/%d", len(stickerData)), nil, nil) + if err != nil { + return nil, nil, fmt.Errorf("failed to get upload form: %w", err) + } + var packAttributes stickerPackUploadAttributes + err = web.DecodeWSResponseBody(ctx, &packAttributes, resp) + if err != nil { + return nil, nil, fmt.Errorf("failed to decode pack attributes: %w", err) + } + if len(packAttributes.Stickers) != len(stickerData) { + return nil, nil, fmt.Errorf("expected %d sticker upload attribute sets, got %d", len(stickerData), len(packAttributes.Stickers)) + } + packID, err = hex.DecodeString(packAttributes.PackID) + if err != nil { + return nil, nil, fmt.Errorf("invalid pack ID in response: %w", err) + } + err = packAttributes.Manifest.upload(ctx, packKey, marshaledPack) + if err != nil { + return nil, nil, fmt.Errorf("failed to upload manifest: %w", err) + } + var wg sync.WaitGroup + wg.Add(len(packAttributes.Stickers)) + sema := semaphore.NewWeighted(int64(StickerUploadParallelism)) + var errorList []error + var errorLock sync.Mutex + for i, attrs := range packAttributes.Stickers { + go attrs.uploadAsync(ctx, packKey, stickerData[i], sema, wg.Done, func(err error) { + errorLock.Lock() + errorList = append(errorList, fmt.Errorf("failed to upload sticker #%d: %w", i+1, err)) + errorLock.Unlock() + }) + } + wg.Wait() + err = ctx.Err() + if err == nil { + err = errors.Join(errorList...) + } + return +} + +func decryptSticker(packKey, ciphertext []byte) ([]byte, error) { + return macAndAESDecrypt(ciphertext, deriveStickerPackKey(packKey)) +} + +func deriveStickerPackKey(key []byte) []byte { + return exerrors.Must(hkdf.Key(sha256.New, key, make([]byte, 32), "Sticker Pack", 2*32)) +} From a27b6745b2eeb7720ad74a1c890a1b58e969848c Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Wed, 29 Apr 2026 09:10:31 +0300 Subject: [PATCH 566/580] dependencies: update mautrix-go --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 030ad61..0a53f3b 100644 --- a/go.mod +++ b/go.mod @@ -21,7 +21,7 @@ require ( golang.org/x/sync v0.20.0 google.golang.org/protobuf v1.36.11 gopkg.in/yaml.v3 v3.0.1 - maunium.net/go/mautrix v0.27.1-0.20260428110059-49a05bf06436 + maunium.net/go/mautrix v0.27.1-0.20260429060852-d7aad0e862c7 ) require ( diff --git a/go.sum b/go.sum index ddff313..f291411 100644 --- a/go.sum +++ b/go.sum @@ -91,5 +91,5 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= maunium.net/go/mauflag v1.0.0 h1:YiaRc0tEI3toYtJMRIfjP+jklH45uDHtT80nUamyD4M= maunium.net/go/mauflag v1.0.0/go.mod h1:nLivPOpTpHnpzEh8jEdSL9UqO9+/KBJFmNRlwKfkPeA= -maunium.net/go/mautrix v0.27.1-0.20260428110059-49a05bf06436 h1:vga9ypiOLJmGguxq4D1aquDPFihOuD99EGPEwva12UI= -maunium.net/go/mautrix v0.27.1-0.20260428110059-49a05bf06436/go.mod h1:4fZ0M0xB5ZtueQI65RilX28J/3794BeK+LaCg4U61Jk= +maunium.net/go/mautrix v0.27.1-0.20260429060852-d7aad0e862c7 h1:ZL/dTgBuj7ZzH543brFUvxZo2lJGsCMBvnfKIvjdHC4= +maunium.net/go/mautrix v0.27.1-0.20260429060852-d7aad0e862c7/go.mod h1:4fZ0M0xB5ZtueQI65RilX28J/3794BeK+LaCg4U61Jk= From 14559977fc5d1d796a39170c7c1b39b4ab3303c5 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Thu, 30 Apr 2026 12:05:00 +0300 Subject: [PATCH 567/580] directmedia: fix response metadata for avatars --- go.mod | 2 +- go.sum | 4 ++-- pkg/connector/directmedia.go | 40 ++++++++++++++---------------------- 3 files changed, 18 insertions(+), 28 deletions(-) diff --git a/go.mod b/go.mod index 0a53f3b..9ef0f7b 100644 --- a/go.mod +++ b/go.mod @@ -21,7 +21,7 @@ require ( golang.org/x/sync v0.20.0 google.golang.org/protobuf v1.36.11 gopkg.in/yaml.v3 v3.0.1 - maunium.net/go/mautrix v0.27.1-0.20260429060852-d7aad0e862c7 + maunium.net/go/mautrix v0.27.1-0.20260430090139-beddfdeef6c9 ) require ( diff --git a/go.sum b/go.sum index f291411..1ae8e5f 100644 --- a/go.sum +++ b/go.sum @@ -91,5 +91,5 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= maunium.net/go/mauflag v1.0.0 h1:YiaRc0tEI3toYtJMRIfjP+jklH45uDHtT80nUamyD4M= maunium.net/go/mauflag v1.0.0/go.mod h1:nLivPOpTpHnpzEh8jEdSL9UqO9+/KBJFmNRlwKfkPeA= -maunium.net/go/mautrix v0.27.1-0.20260429060852-d7aad0e862c7 h1:ZL/dTgBuj7ZzH543brFUvxZo2lJGsCMBvnfKIvjdHC4= -maunium.net/go/mautrix v0.27.1-0.20260429060852-d7aad0e862c7/go.mod h1:4fZ0M0xB5ZtueQI65RilX28J/3794BeK+LaCg4U61Jk= +maunium.net/go/mautrix v0.27.1-0.20260430090139-beddfdeef6c9 h1:ffaVxcARQCkNq4Vw+AaXMUH4HcU5StEWOrfphM/jEfw= +maunium.net/go/mautrix v0.27.1-0.20260430090139-beddfdeef6c9/go.mod h1:4fZ0M0xB5ZtueQI65RilX28J/3794BeK+LaCg4U61Jk= diff --git a/pkg/connector/directmedia.go b/pkg/connector/directmedia.go index 0877d66..4f010f6 100644 --- a/pkg/connector/directmedia.go +++ b/pkg/connector/directmedia.go @@ -4,7 +4,6 @@ import ( "context" "encoding/base64" "fmt" - "io" "os" "maunium.net/go/mautrix/bridgev2" @@ -30,6 +29,7 @@ func (s *SignalConnector) Download(ctx context.Context, mediaID networkid.MediaI return nil, fmt.Errorf("failed to parse direct media id: %w", err) } + var rawDataResp []byte switch info := info.(type) { case *signalid.DirectMediaAttachment: log.Info(). @@ -76,18 +76,11 @@ func (s *SignalConnector) Download(ctx context.Context, mediaID networkid.MediaI return nil, fmt.Errorf("failed to to get group master key: %w", err) } - return &mediaproxy.GetMediaResponseCallback{ - Callback: func(w io.Writer) (int64, error) { - data, err := client.Client.DownloadGroupAvatar(ctx, info.GroupAvatarPath, groupMasterKey) - if err != nil { - log.Err(err).Msg("Direct download failed") - return 0, err - } - - _, err = w.Write(data) - return int64(len(data)), err - }, - }, nil + rawDataResp, err = client.Client.DownloadGroupAvatar(ctx, info.GroupAvatarPath, groupMasterKey) + if err != nil { + log.Err(err).Msg("Direct download failed") + return nil, err + } case *signalid.DirectMediaProfileAvatar: log.Info(). Stringer("user_id", info.UserID). @@ -111,19 +104,16 @@ func (s *SignalConnector) Download(ctx context.Context, mediaID networkid.MediaI return nil, fmt.Errorf("profile key not found") } - return &mediaproxy.GetMediaResponseCallback{ - Callback: func(w io.Writer) (int64, error) { - data, err := client.Client.DownloadUserAvatar(ctx, info.ProfileAvatarPath, *profileKey) - if err != nil { - log.Err(err).Msg("Direct download failed") - return 0, err - } - - _, err = w.Write(data) - return int64(len(data)), err - }, - }, nil + rawDataResp, err = client.Client.DownloadUserAvatar(ctx, info.ProfileAvatarPath, *profileKey) + if err != nil { + log.Err(err).Msg("Direct download failed") + return nil, err + } default: return nil, fmt.Errorf("no downloader for direct media type: %T", info) } + if rawDataResp == nil { + return nil, fmt.Errorf("unexpected fallthrough with no data") + } + return mediaproxy.GetMediaResponseRawData(rawDataResp), nil } From 1f1b645213c02b7142338ae7d6aaf2e803410f70 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Thu, 30 Apr 2026 12:26:24 +0300 Subject: [PATCH 568/580] client: add support for importing Signal sticker packs --- go.mod | 2 +- go.sum | 4 +- pkg/connector/client.go | 5 ++ pkg/connector/directmedia.go | 11 +++ pkg/msgconv/imagepack.go | 147 ++++++++++++++++++++++++++++++++++- pkg/signalid/media.go | 35 +++++++++ 6 files changed, 198 insertions(+), 6 deletions(-) diff --git a/go.mod b/go.mod index 9ef0f7b..f409215 100644 --- a/go.mod +++ b/go.mod @@ -14,7 +14,7 @@ require ( github.com/rs/zerolog v1.35.0 github.com/stretchr/testify v1.11.1 github.com/tidwall/gjson v1.18.0 - go.mau.fi/util v0.9.9-0.20260424160448-fd0d9737ad38 + go.mau.fi/util v0.9.9-0.20260430092340-8772e7714ea5 golang.org/x/crypto v0.50.0 golang.org/x/exp v0.0.0-20260410095643-746e56fc9e2f golang.org/x/net v0.53.0 diff --git a/go.sum b/go.sum index 1ae8e5f..abe70ca 100644 --- a/go.sum +++ b/go.sum @@ -61,8 +61,8 @@ github.com/tidwall/sjson v1.2.5 h1:kLy8mja+1c9jlljvWTlSazM7cKDRfJuR/bOJhcY5NcY= github.com/tidwall/sjson v1.2.5/go.mod h1:Fvgq9kS/6ociJEDnK0Fk1cpYF4FIW6ZF7LAe+6jwd28= github.com/yuin/goldmark v1.8.2 h1:kEGpgqJXdgbkhcOgBxkC0X0PmoPG1ZyoZ117rDVp4zE= github.com/yuin/goldmark v1.8.2/go.mod h1:ip/1k0VRfGynBgxOz0yCqHrbZXhcjxyuS66Brc7iBKg= -go.mau.fi/util v0.9.9-0.20260424160448-fd0d9737ad38 h1:D4OKITjyvlud39Q10oMnfhdeNkzEIVkXrEeCW6nvgLk= -go.mau.fi/util v0.9.9-0.20260424160448-fd0d9737ad38/go.mod h1:up/5mbzH2M1pSBNXqRxODn8dg/hEKbLJu92W4/SNAX0= +go.mau.fi/util v0.9.9-0.20260430092340-8772e7714ea5 h1:cNm4gkt7j907g1Q4XvyNKW8tTM8BaU91Kbfa5GGyiCs= +go.mau.fi/util v0.9.9-0.20260430092340-8772e7714ea5/go.mod h1:up/5mbzH2M1pSBNXqRxODn8dg/hEKbLJu92W4/SNAX0= go.mau.fi/zeroconfig v0.2.0 h1:e/OGEERqVRRKlgaro7E6bh8xXiKFSXB3eNNIud7FUjU= go.mau.fi/zeroconfig v0.2.0/go.mod h1:J0Vn0prHNOm493oZoQ84kq83ZaNCYZnq+noI1b1eN8w= golang.org/x/crypto v0.50.0 h1:zO47/JPrL6vsNkINmLoo/PH1gcxpls50DNogFvB5ZGI= diff --git a/pkg/connector/client.go b/pkg/connector/client.go index 17ee216..1f69191 100644 --- a/pkg/connector/client.go +++ b/pkg/connector/client.go @@ -46,6 +46,7 @@ type SignalClient struct { var ( _ bridgev2.NetworkAPI = (*SignalClient)(nil) _ bridgev2.BackgroundSyncingNetworkAPI = (*SignalClient)(nil) + _ bridgev2.StickerImportingNetworkAPI = (*SignalClient)(nil) ) var pushCfg = &bridgev2.PushConfig{ @@ -76,6 +77,10 @@ func (s *SignalClient) RegisterPushNotifications(ctx context.Context, pushType b } } +func (s *SignalClient) DownloadImagePack(ctx context.Context, url string) (*bridgev2.ImportedImagePack, error) { + return s.Main.MsgConv.DownloadImagePack(ctx, url) +} + func (s *SignalClient) LogoutRemote(ctx context.Context) { if s.Client == nil { return diff --git a/pkg/connector/directmedia.go b/pkg/connector/directmedia.go index 4f010f6..05e2a07 100644 --- a/pkg/connector/directmedia.go +++ b/pkg/connector/directmedia.go @@ -109,6 +109,17 @@ func (s *SignalConnector) Download(ctx context.Context, mediaID networkid.MediaI log.Err(err).Msg("Direct download failed") return nil, err } + case *signalid.DirectMediaSticker: + log.Info(). + Hex("pack_id", info.PackID). + Uint32("sticker_id", info.StickerID). + Msg("Direct downloading sticker") + + rawDataResp, err = signalmeow.DownloadStickerPackItem(ctx, info.PackID, info.PackKey, info.StickerID) + if err != nil { + log.Err(err).Msg("Direct download failed") + return nil, err + } default: return nil, fmt.Errorf("no downloader for direct media type: %T", info) } diff --git a/pkg/msgconv/imagepack.go b/pkg/msgconv/imagepack.go index 910b5bc..8d538bf 100644 --- a/pkg/msgconv/imagepack.go +++ b/pkg/msgconv/imagepack.go @@ -17,12 +17,23 @@ package msgconv import ( + "bytes" + "context" + "encoding/hex" "fmt" + "net/url" "strconv" + "strings" + "go.mau.fi/util/emojishortcodes" "google.golang.org/protobuf/proto" + "maunium.net/go/mautrix/bridgev2" + "maunium.net/go/mautrix/bridgev2/database" "maunium.net/go/mautrix/event" + "maunium.net/go/mautrix/id" + "go.mau.fi/mautrix-signal/pkg/signalid" + "go.mau.fi/mautrix-signal/pkg/signalmeow" signalpb "go.mau.fi/mautrix-signal/pkg/signalmeow/protobuf" ) @@ -43,9 +54,8 @@ func ParseStickerMeta(info *event.BridgedSticker) *signalpb.DataMessage_Sticker if err != nil { return nil } - var packID, packKey []byte - _, err = fmt.Sscanf(info.PackURL, PackURLFormat, &packID, &packKey) - if err != nil || len(packID) != PackIDLength || len(packKey) != PackKeyLength { + packID, packKey, err := parsePackURL(info.PackURL) + if err != nil || len(packID) != PackIDLength || len(packKey) != PackKeyLength || bytes.Equal(packID, zeroPackID) { return nil } return &signalpb.DataMessage_Sticker{ @@ -55,3 +65,134 @@ func ParseStickerMeta(info *event.BridgedSticker) *signalpb.DataMessage_Sticker Emoji: &info.Emoji, } } + +func parsePackURL(rawURL string) (packID, packKey []byte, err error) { + parsed, err := url.Parse(rawURL) + if err != nil { + return nil, nil, fmt.Errorf("invalid URL: %w", err) + } else if parsed.Host != "signal.art" || !strings.HasPrefix(parsed.Path, "/addstickers") { + return nil, nil, fmt.Errorf("invalid host or path in URL") + } + q, err := url.ParseQuery(parsed.Fragment) + if err != nil { + return nil, nil, fmt.Errorf("invalid URL fragment: %w", err) + } + packID, err = hex.DecodeString(q.Get("pack_id")) + if err != nil { + return nil, nil, fmt.Errorf("invalid pack ID in URL: %w", err) + } + packKey, err = hex.DecodeString(q.Get("pack_key")) + if err != nil { + return nil, nil, fmt.Errorf("invalid pack key in URL: %w", err) + } + return +} + +func (mc *MessageConverter) DownloadImagePack(ctx context.Context, url string) (*bridgev2.ImportedImagePack, error) { + packID, packKey, err := parsePackURL(url) + if err != nil { + return nil, err + } + manifest, err := signalmeow.DownloadStickerPackManifest(ctx, packID, packKey) + if err != nil { + return nil, fmt.Errorf("failed to download sticker pack manifest: %w", err) + } + topLevelExtra := map[string]any{ + "fi.mau.signal.stickerpack": map[string]any{ + "pack_id": hex.EncodeToString(packID), + "pack_key": hex.EncodeToString(packKey), + }, + } + content := &event.ImagePackEventContent{ + Images: make(map[string]*event.ImagePackImage, len(manifest.Stickers)), + Metadata: event.ImagePackMetadata{ + DisplayName: manifest.GetTitle(), + AvatarURL: "", + Usage: []event.ImagePackUsage{event.ImagePackUsageSticker}, + Attribution: manifest.GetAuthor(), + BridgedPack: &event.BridgedStickerPack{ + Network: StickerSourceID, + URL: fmt.Sprintf(PackURLFormat, packID, packKey), + }, + }, + } + imagesByID := make(map[uint32]id.ContentURIString, len(manifest.Stickers)) + uploadImage := func(sticker *signalpb.Pack_Sticker) (id.ContentURIString, error) { + stickerID := sticker.GetId() + existing, ok := imagesByID[stickerID] + if ok { + return existing, nil + } + var mxc id.ContentURIString + if mc.DirectMedia { + mediaID, err := signalid.DirectMediaSticker{ + PackID: packID, + PackKey: packKey, + StickerID: stickerID, + }.AsMediaID() + if err != nil { + return "", fmt.Errorf("failed to create media ID for sticker %d: %w", stickerID, err) + } + mxc, err = mc.Bridge.Matrix.GenerateContentURI(ctx, mediaID) + if err != nil { + return "", fmt.Errorf("failed to generate content URI for sticker %d: %w", stickerID, err) + } + } else { + dbKey := database.Key(fmt.Sprintf("stickercache:%x:%d", packID, stickerID)) + if cached := mc.Bridge.DB.KV.Get(ctx, dbKey); cached != "" { + mxc = id.ContentURIString(cached) + imagesByID[stickerID] = mxc + return mxc, nil + } + data, err := signalmeow.DownloadStickerPackItem(ctx, packID, packKey, stickerID) + if err != nil { + return "", fmt.Errorf("failed to download sticker %d: %w", stickerID, err) + } + mxc, _, err = mc.Bridge.Bot.UploadMedia(ctx, "", data, "", sticker.GetContentType()) + if err != nil { + return "", fmt.Errorf("failed to upload sticker %d: %w", stickerID, err) + } + mc.Bridge.DB.KV.Set(ctx, dbKey, string(mxc)) + } + imagesByID[stickerID] = mxc + return mxc, nil + } + for _, sticker := range manifest.Stickers { + mxc, err := uploadImage(sticker) + if err != nil { + return nil, err + } + shortcode := emojishortcodes.Get(sticker.GetEmoji()) + realShortcode := shortcode + i := 2 + for _, alreadyExists := content.Images[realShortcode]; alreadyExists; i++ { + realShortcode = fmt.Sprintf("%s_%d", shortcode, i) + } + content.Images[realShortcode] = &event.ImagePackImage{ + URL: mxc, + Body: sticker.GetEmoji(), + Info: &event.FileInfo{ + MimeType: sticker.GetContentType(), + Width: 200, + Height: 200, + BridgedSticker: &event.BridgedSticker{ + Network: StickerSourceID, + ID: strconv.FormatUint(uint64(sticker.GetId()), 10), + Emoji: sticker.GetEmoji(), + PackURL: content.Metadata.BridgedPack.URL, + }, + }, + } + } + if manifest.Cover != nil { + content.Metadata.AvatarURL, err = uploadImage(manifest.Cover) + if err != nil { + return nil, fmt.Errorf("failed to upload sticker pack cover: %w", err) + } + } + return &bridgev2.ImportedImagePack{ + Content: content, + Extra: topLevelExtra, + Shortcode: hex.EncodeToString(packID), + }, nil +} diff --git a/pkg/signalid/media.go b/pkg/signalid/media.go index 8c91b6a..a530c22 100644 --- a/pkg/signalid/media.go +++ b/pkg/signalid/media.go @@ -34,6 +34,7 @@ const ( directMediaTypeGroupAvatar directMediaType = 1 directMediaTypeProfileAvatar directMediaType = 2 directMediaTypePlaintextDigestAttachment directMediaType = 3 + directMediaTypeSticker directMediaType = 4 ) type DirectMediaInfo interface { @@ -44,6 +45,7 @@ var ( _ DirectMediaInfo = (*DirectMediaAttachment)(nil) _ DirectMediaInfo = (*DirectMediaGroupAvatar)(nil) _ DirectMediaInfo = (*DirectMediaProfileAvatar)(nil) + _ DirectMediaInfo = (*DirectMediaSticker)(nil) ) type DirectMediaAttachment struct { @@ -127,6 +129,30 @@ func (m DirectMediaProfileAvatar) AsMediaID() (mediaID networkid.MediaID, err er return networkid.MediaID(buf.Bytes()), nil } +type DirectMediaSticker struct { + PackID []byte + PackKey []byte + StickerID uint32 +} + +const packIDLen = 16 +const packKeyLen = 32 +const directMediaStickerLen = 1 + packIDLen + packKeyLen + 4 + +func (m DirectMediaSticker) AsMediaID() (mediaID networkid.MediaID, err error) { + if len(m.PackID) != packIDLen { + return nil, fmt.Errorf("invalid pack ID length: %d", len(m.PackID)) + } else if len(m.PackKey) != packKeyLen { + return nil, fmt.Errorf("invalid pack key length: %d", len(m.PackKey)) + } + mediaID = make(networkid.MediaID, directMediaStickerLen) + mediaID[0] = byte(directMediaTypeSticker) + copy(mediaID[1:], m.PackID) + copy(mediaID[1+packIDLen:], m.PackKey) + binary.BigEndian.PutUint32(mediaID[1+packIDLen+packKeyLen:], m.StickerID) + return mediaID, nil +} + func ParseDirectMediaInfo(mediaID networkid.MediaID) (_ DirectMediaInfo, err error) { mediaIDLen := len(mediaID) if mediaIDLen == 0 { @@ -200,6 +226,15 @@ func ParseDirectMediaInfo(mediaID networkid.MediaID) (_ DirectMediaInfo, err err info.ProfileAvatarPath = string(profileAvatarPath) } return &info, nil + case directMediaTypeSticker: + var info DirectMediaSticker + if len(mediaID) != directMediaStickerLen { + return info, fmt.Errorf("invalid media ID length for sticker: %d", len(mediaID)) + } + info.PackID = mediaID[1 : 1+packIDLen] + info.PackKey = mediaID[1+packIDLen : 1+packIDLen+packKeyLen] + info.StickerID = binary.BigEndian.Uint32(mediaID[1+packIDLen+packKeyLen:]) + return &info, nil } return nil, fmt.Errorf("invalid direct media type %d", mediaType) From 9ebd8d4dd09fbbbf3b39deaf673e01d9c611fe2d Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Thu, 30 Apr 2026 13:23:08 +0300 Subject: [PATCH 569/580] .github: add another item to bug report template --- .github/ISSUE_TEMPLATE/bug.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/ISSUE_TEMPLATE/bug.md b/.github/ISSUE_TEMPLATE/bug.md index c10630f..06ba9e8 100644 --- a/.github/ISSUE_TEMPLATE/bug.md +++ b/.github/ISSUE_TEMPLATE/bug.md @@ -11,7 +11,8 @@ type: Bug ### Checklist - + * [ ] This is an actual bug, not just a setup issue (see the [troubleshooting docs](https://docs.mau.fi/bridges/general/troubleshooting.html) or ask in the Matrix room for setup help). * [ ] I am certain that sufficient information is included. Ask in the Matrix room first if not. +* [ ] The bug is still present on the main branch. From 694858478c710b08a7a61e18a57b402d5d35eafc Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Thu, 30 Apr 2026 15:15:08 +0300 Subject: [PATCH 570/580] client: add stub ListImagePacks method --- go.mod | 2 +- go.sum | 4 ++-- pkg/connector/capabilities.go | 1 + pkg/connector/client.go | 5 +++++ 4 files changed, 9 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index f409215..a936973 100644 --- a/go.mod +++ b/go.mod @@ -21,7 +21,7 @@ require ( golang.org/x/sync v0.20.0 google.golang.org/protobuf v1.36.11 gopkg.in/yaml.v3 v3.0.1 - maunium.net/go/mautrix v0.27.1-0.20260430090139-beddfdeef6c9 + maunium.net/go/mautrix v0.27.1-0.20260430124810-125ac2c48014 ) require ( diff --git a/go.sum b/go.sum index abe70ca..f817e1d 100644 --- a/go.sum +++ b/go.sum @@ -91,5 +91,5 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= maunium.net/go/mauflag v1.0.0 h1:YiaRc0tEI3toYtJMRIfjP+jklH45uDHtT80nUamyD4M= maunium.net/go/mauflag v1.0.0/go.mod h1:nLivPOpTpHnpzEh8jEdSL9UqO9+/KBJFmNRlwKfkPeA= -maunium.net/go/mautrix v0.27.1-0.20260430090139-beddfdeef6c9 h1:ffaVxcARQCkNq4Vw+AaXMUH4HcU5StEWOrfphM/jEfw= -maunium.net/go/mautrix v0.27.1-0.20260430090139-beddfdeef6c9/go.mod h1:4fZ0M0xB5ZtueQI65RilX28J/3794BeK+LaCg4U61Jk= +maunium.net/go/mautrix v0.27.1-0.20260430124810-125ac2c48014 h1:KwXGBWwUHYJKVTYWgbZEFcaM6uYLMvfjzHJg/TLwvKc= +maunium.net/go/mautrix v0.27.1-0.20260430124810-125ac2c48014/go.mod h1:4fZ0M0xB5ZtueQI65RilX28J/3794BeK+LaCg4U61Jk= diff --git a/pkg/connector/capabilities.go b/pkg/connector/capabilities.go index e791324..d23285c 100644 --- a/pkg/connector/capabilities.go +++ b/pkg/connector/capabilities.go @@ -211,6 +211,7 @@ var signalGeneralCaps = &bridgev2.NetworkGeneralCapabilities{ AggressiveUpdateInfo: true, ImplicitReadReceipts: true, Provisioning: bridgev2.ProvisioningCapabilities{ + ImagePackImport: true, ResolveIdentifier: bridgev2.ResolveIdentifierCapabilities{ CreateDM: true, LookupPhone: true, diff --git a/pkg/connector/client.go b/pkg/connector/client.go index 1f69191..4fcf188 100644 --- a/pkg/connector/client.go +++ b/pkg/connector/client.go @@ -27,6 +27,7 @@ import ( "maunium.net/go/mautrix/bridgev2" "maunium.net/go/mautrix/bridgev2/networkid" "maunium.net/go/mautrix/bridgev2/status" + "maunium.net/go/mautrix/event" "go.mau.fi/mautrix-signal/pkg/signalid" "go.mau.fi/mautrix-signal/pkg/signalmeow" @@ -81,6 +82,10 @@ func (s *SignalClient) DownloadImagePack(ctx context.Context, url string) (*brid return s.Main.MsgConv.DownloadImagePack(ctx, url) } +func (s *SignalClient) ListImagePacks(ctx context.Context) ([]*event.ImagePackMetadata, error) { + return []*event.ImagePackMetadata{}, nil +} + func (s *SignalClient) LogoutRemote(ctx context.Context) { if s.Client == nil { return From 0214ecc6005359dcb41bacd56cd07de5bc4521a3 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Mon, 4 May 2026 17:32:04 +0300 Subject: [PATCH 571/580] msgconv/imagepack: fix stickers with no bridged metadata --- pkg/msgconv/imagepack.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/msgconv/imagepack.go b/pkg/msgconv/imagepack.go index 8d538bf..e8f91cb 100644 --- a/pkg/msgconv/imagepack.go +++ b/pkg/msgconv/imagepack.go @@ -47,7 +47,7 @@ const PackURLLength = len(PackURLFormat) - len("%x")*2 + PackIDLength*2 + PackKe var zeroPackID = make([]byte, PackIDLength) func ParseStickerMeta(info *event.BridgedSticker) *signalpb.DataMessage_Sticker { - if info.Network != StickerSourceID || len(info.PackURL) != PackURLLength { + if info == nil || info.Network != StickerSourceID || len(info.PackURL) != PackURLLength { return nil } stickerID, err := strconv.ParseUint(info.ID, 10, 32) From 0813d3909524ec4db44284cc180a75685557c847 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Wed, 6 May 2026 13:23:56 +0300 Subject: [PATCH 572/580] .github: add version command to bug report template --- .github/ISSUE_TEMPLATE/bug.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/ISSUE_TEMPLATE/bug.md b/.github/ISSUE_TEMPLATE/bug.md index 06ba9e8..cba1054 100644 --- a/.github/ISSUE_TEMPLATE/bug.md +++ b/.github/ISSUE_TEMPLATE/bug.md @@ -15,4 +15,4 @@ type: Bug * [ ] This is an actual bug, not just a setup issue (see the [troubleshooting docs](https://docs.mau.fi/bridges/general/troubleshooting.html) or ask in the Matrix room for setup help). * [ ] I am certain that sufficient information is included. Ask in the Matrix room first if not. -* [ ] The bug is still present on the main branch. +* [ ] The bug is still present on the main branch. The `!signal version` command output is: `` From 90487a25e048d9677e059291d44d8f80a6a5a391 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Wed, 6 May 2026 13:47:09 +0300 Subject: [PATCH 573/580] imagepack: return 404 on incorrectly formatted link --- pkg/msgconv/imagepack.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pkg/msgconv/imagepack.go b/pkg/msgconv/imagepack.go index e8f91cb..a2529af 100644 --- a/pkg/msgconv/imagepack.go +++ b/pkg/msgconv/imagepack.go @@ -27,6 +27,7 @@ import ( "go.mau.fi/util/emojishortcodes" "google.golang.org/protobuf/proto" + "maunium.net/go/mautrix" "maunium.net/go/mautrix/bridgev2" "maunium.net/go/mautrix/bridgev2/database" "maunium.net/go/mautrix/event" @@ -91,7 +92,7 @@ func parsePackURL(rawURL string) (packID, packKey []byte, err error) { func (mc *MessageConverter) DownloadImagePack(ctx context.Context, url string) (*bridgev2.ImportedImagePack, error) { packID, packKey, err := parsePackURL(url) if err != nil { - return nil, err + return nil, bridgev2.WrapRespErr(err, mautrix.MNotFound) } manifest, err := signalmeow.DownloadStickerPackManifest(ctx, packID, packKey) if err != nil { From 06bdbfc2cab281e91af2dc97f2cdc15512d00b7e Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Fri, 8 May 2026 16:55:42 +0300 Subject: [PATCH 574/580] libsignal: update to v0.93.2 --- pkg/libsignalgo/identitykeystore.go | 12 +- pkg/libsignalgo/kyberprekeystore.go | 8 +- pkg/libsignalgo/libsignal | 2 +- pkg/libsignalgo/libsignal-ffi.h | 191 ++++++++++++++------------- pkg/libsignalgo/message.go | 3 +- pkg/libsignalgo/prekeybundle.go | 3 +- pkg/libsignalgo/prekeystore.go | 8 +- pkg/libsignalgo/senderkeystore.go | 6 +- pkg/libsignalgo/session_test.go | 19 +-- pkg/libsignalgo/sessionstore.go | 6 +- pkg/libsignalgo/signedprekeystore.go | 6 +- pkg/libsignalgo/version.go | 2 +- pkg/signalmeow/keys.go | 5 + pkg/signalmeow/receiving_decrypt.go | 5 + 14 files changed, 147 insertions(+), 129 deletions(-) diff --git a/pkg/libsignalgo/identitykeystore.go b/pkg/libsignalgo/identitykeystore.go index 43941da..ba26f06 100644 --- a/pkg/libsignalgo/identitykeystore.go +++ b/pkg/libsignalgo/identitykeystore.go @@ -159,11 +159,11 @@ func signal_destroy_identity_key_store_callback(storeCtx unsafe.Pointer) { func (ctx *CallbackContext) wrapIdentityKeyStore(store IdentityKeyStore) C.SignalConstPointerFfiIdentityKeyStoreStruct { return C.SignalConstPointerFfiIdentityKeyStoreStruct{&C.SignalIdentityKeyStore{ ctx: wrapStore(ctx, store), - get_local_identity_key_pair: C.SignalFfiBridgeIdentityKeyStoreGetLocalIdentityKeyPair(C.signal_get_identity_key_pair_callback), - get_local_registration_id: C.SignalFfiBridgeIdentityKeyStoreGetLocalRegistrationId(C.signal_get_local_registration_id_callback), - get_identity_key: C.SignalFfiBridgeIdentityKeyStoreGetIdentityKey(C.signal_get_identity_key_callback), - save_identity_key: C.SignalFfiBridgeIdentityKeyStoreSaveIdentityKey(C.signal_save_identity_key_callback), - is_trusted_identity: C.SignalFfiBridgeIdentityKeyStoreIsTrustedIdentity(C.signal_is_trusted_identity_callback), - destroy: C.SignalFfiBridgeIdentityKeyStoreDestroy(C.signal_destroy_identity_key_store_callback), + get_local_identity_key_pair: C.SignalFfiIdentityKeyStoreGetLocalIdentityKeyPair(C.signal_get_identity_key_pair_callback), + get_local_registration_id: C.SignalFfiIdentityKeyStoreGetLocalRegistrationId(C.signal_get_local_registration_id_callback), + get_identity_key: C.SignalFfiIdentityKeyStoreGetIdentityKey(C.signal_get_identity_key_callback), + save_identity_key: C.SignalFfiIdentityKeyStoreSaveIdentityKey(C.signal_save_identity_key_callback), + is_trusted_identity: C.SignalFfiIdentityKeyStoreIsTrustedIdentity(C.signal_is_trusted_identity_callback), + destroy: C.SignalFfiIdentityKeyStoreDestroy(C.signal_destroy_identity_key_store_callback), }} } diff --git a/pkg/libsignalgo/kyberprekeystore.go b/pkg/libsignalgo/kyberprekeystore.go index ebb5a9f..9deea17 100644 --- a/pkg/libsignalgo/kyberprekeystore.go +++ b/pkg/libsignalgo/kyberprekeystore.go @@ -77,9 +77,9 @@ func signal_destroy_kyber_pre_key_store_callback(storeCtx unsafe.Pointer) { func (ctx *CallbackContext) wrapKyberPreKeyStore(store KyberPreKeyStore) C.SignalConstPointerFfiKyberPreKeyStoreStruct { return C.SignalConstPointerFfiKyberPreKeyStoreStruct{&C.SignalKyberPreKeyStore{ ctx: wrapStore(ctx, store), - load_kyber_pre_key: C.SignalFfiBridgeKyberPreKeyStoreLoadKyberPreKey(C.signal_load_kyber_pre_key_callback), - store_kyber_pre_key: C.SignalFfiBridgeKyberPreKeyStoreStoreKyberPreKey(C.signal_store_kyber_pre_key_callback), - mark_kyber_pre_key_used: C.SignalFfiBridgeKyberPreKeyStoreMarkKyberPreKeyUsed(C.signal_mark_kyber_pre_key_used_callback), - destroy: C.SignalFfiBridgeKyberPreKeyStoreDestroy(C.signal_destroy_kyber_pre_key_store_callback), + load_kyber_pre_key: C.SignalFfiKyberPreKeyStoreLoadKyberPreKey(C.signal_load_kyber_pre_key_callback), + store_kyber_pre_key: C.SignalFfiKyberPreKeyStoreStoreKyberPreKey(C.signal_store_kyber_pre_key_callback), + mark_kyber_pre_key_used: C.SignalFfiKyberPreKeyStoreMarkKyberPreKeyUsed(C.signal_mark_kyber_pre_key_used_callback), + destroy: C.SignalFfiKyberPreKeyStoreDestroy(C.signal_destroy_kyber_pre_key_store_callback), }} } diff --git a/pkg/libsignalgo/libsignal b/pkg/libsignalgo/libsignal index b58bd7d..bbc1688 160000 --- a/pkg/libsignalgo/libsignal +++ b/pkg/libsignalgo/libsignal @@ -1 +1 @@ -Subproject commit b58bd7d5dfa0a391486df4210fd83bab96b9b479 +Subproject commit bbc16886cae2feab1cd1fe271ccc651e8860ce96 diff --git a/pkg/libsignalgo/libsignal-ffi.h b/pkg/libsignalgo/libsignal-ffi.h index fe3bf52..b75462a 100644 --- a/pkg/libsignalgo/libsignal-ffi.h +++ b/pkg/libsignalgo/libsignal-ffi.h @@ -629,13 +629,6 @@ typedef struct { const SignalHttpRequest *raw; } SignalConstPointerHttpRequest; -/** - * A wrapper type for raw UUIDs, because C treats arrays specially in argument position. - */ -typedef struct { - uint8_t bytes[16]; -} SignalUuid; - /** * The fixed-width binary representation of a ServiceId. * @@ -643,6 +636,27 @@ typedef struct { */ typedef uint8_t SignalServiceIdFixedWidthBinaryBytes[17]; +typedef struct { + const uint32_t *base; + size_t length; +} SignalBorrowedSliceOfu32; + +typedef struct { + const SignalCiphertextMessage *raw; +} SignalConstPointerCiphertextMessage; + +typedef struct { + const SignalConstPointerCiphertextMessage *base; + size_t length; +} SignalBorrowedSliceOfConstPointerCiphertextMessage; + +/** + * A wrapper type for raw UUIDs, because C treats arrays specially in argument position. + */ +typedef struct { + uint8_t bytes[16]; +} SignalUuid; + typedef struct { SignalPrivateKey *raw; } SignalMutPointerPrivateKey; @@ -754,10 +768,6 @@ typedef struct { const SignalPlaintextContent *raw; } SignalConstPointerPlaintextContent; -typedef struct { - const SignalCiphertextMessage *raw; -} SignalConstPointerCiphertextMessage; - typedef struct { SignalConnectionInfo *raw; } SignalMutPointerConnectionInfo; @@ -782,20 +792,18 @@ typedef struct { SignalSessionRecord *raw; } SignalMutPointerSessionRecord; -typedef int (*SignalFfiBridgeSessionStoreLoadSession)(void *ctx, SignalMutPointerSessionRecord *out, SignalMutPointerProtocolAddress address); +typedef int (*SignalFfiSessionStoreLoadSession)(void *ctx, SignalMutPointerSessionRecord *out, SignalMutPointerProtocolAddress address); -typedef int (*SignalFfiBridgeSessionStoreStoreSession)(void *ctx, SignalMutPointerProtocolAddress address, SignalMutPointerSessionRecord record); +typedef int (*SignalFfiSessionStoreStoreSession)(void *ctx, SignalMutPointerProtocolAddress address, SignalMutPointerSessionRecord record); -typedef void (*SignalFfiBridgeSessionStoreDestroy)(void *ctx); +typedef void (*SignalFfiSessionStoreDestroy)(void *ctx); typedef struct { void *ctx; - SignalFfiBridgeSessionStoreLoadSession load_session; - SignalFfiBridgeSessionStoreStoreSession store_session; - SignalFfiBridgeSessionStoreDestroy destroy; -} SignalFfiBridgeSessionStoreStruct; - -typedef SignalFfiBridgeSessionStoreStruct SignalSessionStore; + SignalFfiSessionStoreLoadSession load_session; + SignalFfiSessionStoreStoreSession store_session; + SignalFfiSessionStoreDestroy destroy; +} SignalSessionStore; typedef struct { const SignalSessionStore *raw; @@ -810,29 +818,27 @@ typedef struct { SignalMutPointerPublicKey second; } SignalPairOfMutPointerPrivateKeyMutPointerPublicKey; -typedef int (*SignalFfiBridgeIdentityKeyStoreGetLocalIdentityKeyPair)(void *ctx, SignalPairOfMutPointerPrivateKeyMutPointerPublicKey *out); +typedef int (*SignalFfiIdentityKeyStoreGetLocalIdentityKeyPair)(void *ctx, SignalPairOfMutPointerPrivateKeyMutPointerPublicKey *out); -typedef int (*SignalFfiBridgeIdentityKeyStoreGetLocalRegistrationId)(void *ctx, uint32_t *out); +typedef int (*SignalFfiIdentityKeyStoreGetLocalRegistrationId)(void *ctx, uint32_t *out); -typedef int (*SignalFfiBridgeIdentityKeyStoreGetIdentityKey)(void *ctx, SignalMutPointerPublicKey *out, SignalMutPointerProtocolAddress address); +typedef int (*SignalFfiIdentityKeyStoreGetIdentityKey)(void *ctx, SignalMutPointerPublicKey *out, SignalMutPointerProtocolAddress address); -typedef int (*SignalFfiBridgeIdentityKeyStoreSaveIdentityKey)(void *ctx, uint8_t *out, SignalMutPointerProtocolAddress address, SignalMutPointerPublicKey public_key); +typedef int (*SignalFfiIdentityKeyStoreSaveIdentityKey)(void *ctx, uint8_t *out, SignalMutPointerProtocolAddress address, SignalMutPointerPublicKey public_key); -typedef int (*SignalFfiBridgeIdentityKeyStoreIsTrustedIdentity)(void *ctx, bool *out, SignalMutPointerProtocolAddress address, SignalMutPointerPublicKey public_key, uint32_t direction); +typedef int (*SignalFfiIdentityKeyStoreIsTrustedIdentity)(void *ctx, bool *out, SignalMutPointerProtocolAddress address, SignalMutPointerPublicKey public_key, uint32_t direction); -typedef void (*SignalFfiBridgeIdentityKeyStoreDestroy)(void *ctx); +typedef void (*SignalFfiIdentityKeyStoreDestroy)(void *ctx); typedef struct { void *ctx; - SignalFfiBridgeIdentityKeyStoreGetLocalIdentityKeyPair get_local_identity_key_pair; - SignalFfiBridgeIdentityKeyStoreGetLocalRegistrationId get_local_registration_id; - SignalFfiBridgeIdentityKeyStoreGetIdentityKey get_identity_key; - SignalFfiBridgeIdentityKeyStoreSaveIdentityKey save_identity_key; - SignalFfiBridgeIdentityKeyStoreIsTrustedIdentity is_trusted_identity; - SignalFfiBridgeIdentityKeyStoreDestroy destroy; -} SignalFfiBridgeIdentityKeyStoreStruct; - -typedef SignalFfiBridgeIdentityKeyStoreStruct SignalIdentityKeyStore; + SignalFfiIdentityKeyStoreGetLocalIdentityKeyPair get_local_identity_key_pair; + SignalFfiIdentityKeyStoreGetLocalRegistrationId get_local_registration_id; + SignalFfiIdentityKeyStoreGetIdentityKey get_identity_key; + SignalFfiIdentityKeyStoreSaveIdentityKey save_identity_key; + SignalFfiIdentityKeyStoreIsTrustedIdentity is_trusted_identity; + SignalFfiIdentityKeyStoreDestroy destroy; +} SignalIdentityKeyStore; typedef struct { const SignalIdentityKeyStore *raw; @@ -846,23 +852,21 @@ typedef struct { SignalPreKeyRecord *raw; } SignalMutPointerPreKeyRecord; -typedef int (*SignalFfiBridgePreKeyStoreLoadPreKey)(void *ctx, SignalMutPointerPreKeyRecord *out, uint32_t id); +typedef int (*SignalFfiPreKeyStoreLoadPreKey)(void *ctx, SignalMutPointerPreKeyRecord *out, uint32_t id); -typedef int (*SignalFfiBridgePreKeyStoreStorePreKey)(void *ctx, uint32_t id, SignalMutPointerPreKeyRecord record); +typedef int (*SignalFfiPreKeyStoreStorePreKey)(void *ctx, uint32_t id, SignalMutPointerPreKeyRecord record); -typedef int (*SignalFfiBridgePreKeyStoreRemovePreKey)(void *ctx, uint32_t id); +typedef int (*SignalFfiPreKeyStoreRemovePreKey)(void *ctx, uint32_t id); -typedef void (*SignalFfiBridgePreKeyStoreDestroy)(void *ctx); +typedef void (*SignalFfiPreKeyStoreDestroy)(void *ctx); typedef struct { void *ctx; - SignalFfiBridgePreKeyStoreLoadPreKey load_pre_key; - SignalFfiBridgePreKeyStoreStorePreKey store_pre_key; - SignalFfiBridgePreKeyStoreRemovePreKey remove_pre_key; - SignalFfiBridgePreKeyStoreDestroy destroy; -} SignalFfiBridgePreKeyStoreStruct; - -typedef SignalFfiBridgePreKeyStoreStruct SignalPreKeyStore; + SignalFfiPreKeyStoreLoadPreKey load_pre_key; + SignalFfiPreKeyStoreStorePreKey store_pre_key; + SignalFfiPreKeyStoreRemovePreKey remove_pre_key; + SignalFfiPreKeyStoreDestroy destroy; +} SignalPreKeyStore; typedef struct { const SignalPreKeyStore *raw; @@ -872,20 +876,18 @@ typedef struct { SignalSignedPreKeyRecord *raw; } SignalMutPointerSignedPreKeyRecord; -typedef int (*SignalFfiBridgeSignedPreKeyStoreLoadSignedPreKey)(void *ctx, SignalMutPointerSignedPreKeyRecord *out, uint32_t id); +typedef int (*SignalFfiSignedPreKeyStoreLoadSignedPreKey)(void *ctx, SignalMutPointerSignedPreKeyRecord *out, uint32_t id); -typedef int (*SignalFfiBridgeSignedPreKeyStoreStoreSignedPreKey)(void *ctx, uint32_t id, SignalMutPointerSignedPreKeyRecord record); +typedef int (*SignalFfiSignedPreKeyStoreStoreSignedPreKey)(void *ctx, uint32_t id, SignalMutPointerSignedPreKeyRecord record); -typedef void (*SignalFfiBridgeSignedPreKeyStoreDestroy)(void *ctx); +typedef void (*SignalFfiSignedPreKeyStoreDestroy)(void *ctx); typedef struct { void *ctx; - SignalFfiBridgeSignedPreKeyStoreLoadSignedPreKey load_signed_pre_key; - SignalFfiBridgeSignedPreKeyStoreStoreSignedPreKey store_signed_pre_key; - SignalFfiBridgeSignedPreKeyStoreDestroy destroy; -} SignalFfiBridgeSignedPreKeyStoreStruct; - -typedef SignalFfiBridgeSignedPreKeyStoreStruct SignalSignedPreKeyStore; + SignalFfiSignedPreKeyStoreLoadSignedPreKey load_signed_pre_key; + SignalFfiSignedPreKeyStoreStoreSignedPreKey store_signed_pre_key; + SignalFfiSignedPreKeyStoreDestroy destroy; +} SignalSignedPreKeyStore; typedef struct { const SignalSignedPreKeyStore *raw; @@ -895,23 +897,21 @@ typedef struct { SignalKyberPreKeyRecord *raw; } SignalMutPointerKyberPreKeyRecord; -typedef int (*SignalFfiBridgeKyberPreKeyStoreLoadKyberPreKey)(void *ctx, SignalMutPointerKyberPreKeyRecord *out, uint32_t id); +typedef int (*SignalFfiKyberPreKeyStoreLoadKyberPreKey)(void *ctx, SignalMutPointerKyberPreKeyRecord *out, uint32_t id); -typedef int (*SignalFfiBridgeKyberPreKeyStoreStoreKyberPreKey)(void *ctx, uint32_t id, SignalMutPointerKyberPreKeyRecord record); +typedef int (*SignalFfiKyberPreKeyStoreStoreKyberPreKey)(void *ctx, uint32_t id, SignalMutPointerKyberPreKeyRecord record); -typedef int (*SignalFfiBridgeKyberPreKeyStoreMarkKyberPreKeyUsed)(void *ctx, uint32_t id, uint32_t ec_prekey_id, SignalMutPointerPublicKey base_key); +typedef int (*SignalFfiKyberPreKeyStoreMarkKyberPreKeyUsed)(void *ctx, uint32_t id, uint32_t ec_prekey_id, SignalMutPointerPublicKey base_key); -typedef void (*SignalFfiBridgeKyberPreKeyStoreDestroy)(void *ctx); +typedef void (*SignalFfiKyberPreKeyStoreDestroy)(void *ctx); typedef struct { void *ctx; - SignalFfiBridgeKyberPreKeyStoreLoadKyberPreKey load_kyber_pre_key; - SignalFfiBridgeKyberPreKeyStoreStoreKyberPreKey store_kyber_pre_key; - SignalFfiBridgeKyberPreKeyStoreMarkKyberPreKeyUsed mark_kyber_pre_key_used; - SignalFfiBridgeKyberPreKeyStoreDestroy destroy; -} SignalFfiBridgeKyberPreKeyStoreStruct; - -typedef SignalFfiBridgeKyberPreKeyStoreStruct SignalKyberPreKeyStore; + SignalFfiKyberPreKeyStoreLoadKyberPreKey load_kyber_pre_key; + SignalFfiKyberPreKeyStoreStoreKyberPreKey store_kyber_pre_key; + SignalFfiKyberPreKeyStoreMarkKyberPreKeyUsed mark_kyber_pre_key_used; + SignalFfiKyberPreKeyStoreDestroy destroy; +} SignalKyberPreKeyStore; typedef struct { const SignalKyberPreKeyStore *raw; @@ -1047,20 +1047,18 @@ typedef struct { SignalSenderKeyRecord *raw; } SignalMutPointerSenderKeyRecord; -typedef int (*SignalFfiBridgeSenderKeyStoreLoadSenderKey)(void *ctx, SignalMutPointerSenderKeyRecord *out, SignalMutPointerProtocolAddress sender, SignalUuid distribution_id); +typedef int (*SignalFfiSenderKeyStoreLoadSenderKey)(void *ctx, SignalMutPointerSenderKeyRecord *out, SignalMutPointerProtocolAddress sender, SignalUuid distribution_id); -typedef int (*SignalFfiBridgeSenderKeyStoreStoreSenderKey)(void *ctx, SignalMutPointerProtocolAddress sender, SignalUuid distribution_id, SignalMutPointerSenderKeyRecord record); +typedef int (*SignalFfiSenderKeyStoreStoreSenderKey)(void *ctx, SignalMutPointerProtocolAddress sender, SignalUuid distribution_id, SignalMutPointerSenderKeyRecord record); -typedef void (*SignalFfiBridgeSenderKeyStoreDestroy)(void *ctx); +typedef void (*SignalFfiSenderKeyStoreDestroy)(void *ctx); typedef struct { void *ctx; - SignalFfiBridgeSenderKeyStoreLoadSenderKey load_sender_key; - SignalFfiBridgeSenderKeyStoreStoreSenderKey store_sender_key; - SignalFfiBridgeSenderKeyStoreDestroy destroy; -} SignalFfiBridgeSenderKeyStoreStruct; - -typedef SignalFfiBridgeSenderKeyStoreStruct SignalSenderKeyStore; + SignalFfiSenderKeyStoreLoadSenderKey load_sender_key; + SignalFfiSenderKeyStoreStoreSenderKey store_sender_key; + SignalFfiSenderKeyStoreDestroy destroy; +} SignalSenderKeyStore; typedef struct { const SignalSenderKeyStore *raw; @@ -1117,6 +1115,11 @@ typedef struct { SignalFfiLoggerDestroy destroy; } SignalFfiLoggerStruct; +typedef struct { + SignalOwnedBuffer first; + SignalOwnedBuffer second; +} SignalPairOfOwnedBufferOfc_ucharOwnedBufferOfc_uchar; + /** * A C callback used to report the results of Rust futures. * @@ -1127,10 +1130,10 @@ typedef struct { * completed once. */ typedef struct { - void (*complete)(SignalFfiError *error, const SignalOwnedBuffer *result, const void *context); + void (*complete)(SignalFfiError *error, const SignalPairOfOwnedBufferOfc_ucharOwnedBufferOfc_uchar *result, const void *context); const void *context; SignalCancellationId cancellation_id; -} SignalCPromiseOwnedBufferOfc_uchar; +} SignalCPromisePairOfOwnedBufferOfc_ucharOwnedBufferOfc_uchar; typedef struct { const SignalUnauthenticatedChatConnection *raw; @@ -1200,20 +1203,18 @@ typedef struct { const SignalMessageBackupValidationOutcome *raw; } SignalConstPointerMessageBackupValidationOutcome; -typedef int (*SignalFfiBridgeInputStreamRead)(void *ctx, size_t *out, SignalBorrowedMutableBuffer buf); +typedef int (*SignalFfiInputStreamRead)(void *ctx, size_t *out, SignalBorrowedMutableBuffer buf); -typedef int (*SignalFfiBridgeInputStreamSkip)(void *ctx, uint64_t amount); +typedef int (*SignalFfiInputStreamSkip)(void *ctx, uint64_t amount); -typedef void (*SignalFfiBridgeInputStreamDestroy)(void *ctx); +typedef void (*SignalFfiInputStreamDestroy)(void *ctx); typedef struct { void *ctx; - SignalFfiBridgeInputStreamRead read; - SignalFfiBridgeInputStreamSkip skip; - SignalFfiBridgeInputStreamDestroy destroy; -} SignalFfiBridgeInputStreamStruct; - -typedef SignalFfiBridgeInputStreamStruct SignalInputStream; + SignalFfiInputStreamRead read; + SignalFfiInputStreamSkip skip; + SignalFfiInputStreamDestroy destroy; +} SignalInputStream; typedef struct { const SignalInputStream *raw; @@ -1647,9 +1648,7 @@ typedef struct { SignalValidatingMac *raw; } SignalMutPointerValidatingMac; -typedef SignalFfiBridgeInputStreamStruct SignalFfiBridgeSyncInputStreamStruct; - -typedef SignalFfiBridgeSyncInputStreamStruct SignalSyncInputStream; +typedef SignalInputStream SignalSyncInputStream; typedef struct { const SignalSyncInputStream *raw; @@ -1737,6 +1736,10 @@ SignalFfiError *signal_authenticated_chat_connection_preconnect(SignalCPromisebo SignalFfiError *signal_authenticated_chat_connection_send(SignalCPromiseFfiChatResponse *promise, SignalConstPointerTokioAsyncContext async_runtime, SignalConstPointerAuthenticatedChatConnection chat, SignalConstPointerHttpRequest http_request, uint32_t timeout_millis); +SignalFfiError *signal_authenticated_chat_connection_send_message(SignalCPromisebool *promise, SignalConstPointerTokioAsyncContext async_runtime, SignalConstPointerAuthenticatedChatConnection chat, const SignalServiceIdFixedWidthBinaryBytes *destination, uint64_t timestamp, SignalBorrowedSliceOfu32 device_ids, SignalBorrowedSliceOfu32 registration_ids, SignalBorrowedSliceOfConstPointerCiphertextMessage contents, bool online_only, bool is_urgent); + +SignalFfiError *signal_authenticated_chat_connection_send_sync_message(SignalCPromisebool *promise, SignalConstPointerTokioAsyncContext async_runtime, SignalConstPointerAuthenticatedChatConnection chat, uint64_t timestamp, SignalBorrowedSliceOfu32 device_ids, SignalBorrowedSliceOfu32 registration_ids, SignalBorrowedSliceOfConstPointerCiphertextMessage contents, bool is_urgent); + SignalFfiError *signal_backup_auth_credential_check_valid_contents(SignalBorrowedBuffer params_bytes); SignalFfiError *signal_backup_auth_credential_get_backup_id(uint8_t (*out)[16], SignalBorrowedBuffer credential_bytes); @@ -1897,7 +1900,7 @@ SignalFfiError *signal_create_call_link_credential_request_issue_deterministic(S SignalFfiError *signal_create_call_link_credential_response_check_valid_contents(SignalBorrowedBuffer response_bytes); -SignalFfiError *signal_decrypt_message(SignalOwnedBuffer *out, SignalConstPointerSignalMessage message, SignalConstPointerProtocolAddress protocol_address, SignalConstPointerFfiSessionStoreStruct session_store, SignalConstPointerFfiIdentityKeyStoreStruct identity_key_store); +SignalFfiError *signal_decrypt_message(SignalOwnedBuffer *out, SignalConstPointerSignalMessage message, SignalConstPointerProtocolAddress protocol_address, SignalConstPointerProtocolAddress local_address, SignalConstPointerFfiSessionStoreStruct session_store, SignalConstPointerFfiIdentityKeyStoreStruct identity_key_store); SignalFfiError *signal_decrypt_pre_key_message(SignalOwnedBuffer *out, SignalConstPointerPreKeySignalMessage message, SignalConstPointerProtocolAddress protocol_address, SignalConstPointerProtocolAddress local_address, SignalConstPointerFfiSessionStoreStruct session_store, SignalConstPointerFfiIdentityKeyStoreStruct identity_key_store, SignalConstPointerFfiPreKeyStoreStruct prekey_store, SignalConstPointerFfiSignedPreKeyStoreStruct signed_prekey_store, SignalConstPointerFfiKyberPreKeyStoreStruct kyber_prekey_store); @@ -2118,9 +2121,7 @@ bool signal_init_logger(SignalLogLevel max_level, SignalFfiLoggerStruct logger); SignalFfiError *signal_key_transparency_aci_search_key(SignalOwnedBuffer *out, const SignalServiceIdFixedWidthBinaryBytes *aci); -SignalFfiError *signal_key_transparency_check(SignalCPromiseOwnedBufferOfc_uchar *promise, SignalConstPointerTokioAsyncContext async_runtime, uint8_t environment, SignalConstPointerUnauthenticatedChatConnection chat_connection, const SignalServiceIdFixedWidthBinaryBytes *aci, SignalConstPointerPublicKey aci_identity_key, const char *e164, SignalOptionalBorrowedSliceOfc_uchar unidentified_access_key, SignalOptionalBorrowedSliceOfc_uchar username_hash, SignalOptionalBorrowedSliceOfc_uchar account_data, SignalBorrowedBuffer last_distinguished_tree_head, bool is_self_check, bool is_e164_discoverable); - -SignalFfiError *signal_key_transparency_distinguished(SignalCPromiseOwnedBufferOfc_uchar *promise, SignalConstPointerTokioAsyncContext async_runtime, uint8_t environment, SignalConstPointerUnauthenticatedChatConnection chat_connection, SignalOptionalBorrowedSliceOfc_uchar last_distinguished_tree_head); +SignalFfiError *signal_key_transparency_check(SignalCPromisePairOfOwnedBufferOfc_ucharOwnedBufferOfc_uchar *promise, SignalConstPointerTokioAsyncContext async_runtime, uint8_t environment, SignalConstPointerUnauthenticatedChatConnection chat_connection, const SignalServiceIdFixedWidthBinaryBytes *aci, SignalConstPointerPublicKey aci_identity_key, const char *e164, SignalOptionalBorrowedSliceOfc_uchar unidentified_access_key, SignalOptionalBorrowedSliceOfc_uchar username_hash, SignalOptionalBorrowedSliceOfc_uchar account_data, SignalOptionalBorrowedSliceOfc_uchar last_distinguished_tree_head, bool is_self_check, bool is_e164_discoverable); SignalFfiError *signal_key_transparency_e164_search_key(SignalOwnedBuffer *out, const char *e164); @@ -2354,7 +2355,7 @@ SignalFfiError *signal_privatekey_serialize(SignalOwnedBuffer *out, SignalConstP SignalFfiError *signal_privatekey_sign(SignalOwnedBuffer *out, SignalConstPointerPrivateKey key, SignalBorrowedBuffer message); -SignalFfiError *signal_process_prekey_bundle(SignalConstPointerPreKeyBundle bundle, SignalConstPointerProtocolAddress protocol_address, SignalConstPointerFfiSessionStoreStruct session_store, SignalConstPointerFfiIdentityKeyStoreStruct identity_key_store, uint64_t now); +SignalFfiError *signal_process_prekey_bundle(SignalConstPointerPreKeyBundle bundle, SignalConstPointerProtocolAddress protocol_address, SignalConstPointerProtocolAddress local_address, SignalConstPointerFfiSessionStoreStruct session_store, SignalConstPointerFfiIdentityKeyStoreStruct identity_key_store, uint64_t now); SignalFfiError *signal_process_sender_key_distribution_message(SignalConstPointerProtocolAddress sender, SignalConstPointerSenderKeyDistributionMessage sender_key_distribution_message, SignalConstPointerFfiSenderKeyStoreStruct store); @@ -2782,6 +2783,8 @@ SignalFfiError *signal_unauthenticated_chat_connection_look_up_username_link(Sig SignalFfiError *signal_unauthenticated_chat_connection_send(SignalCPromiseFfiChatResponse *promise, SignalConstPointerTokioAsyncContext async_runtime, SignalConstPointerUnauthenticatedChatConnection chat, SignalConstPointerHttpRequest http_request, uint32_t timeout_millis); +SignalFfiError *signal_unauthenticated_chat_connection_send_message(SignalCPromisebool *promise, SignalConstPointerTokioAsyncContext async_runtime, SignalConstPointerUnauthenticatedChatConnection chat, const SignalServiceIdFixedWidthBinaryBytes *destination, uint64_t timestamp, SignalBorrowedSliceOfu32 device_ids, SignalBorrowedSliceOfu32 registration_ids, SignalBorrowedSliceOfBuffers contents, uint8_t auth_kind, SignalOptionalBorrowedSliceOfc_uchar auth_buffer, bool online_only, bool is_urgent); + SignalFfiError *signal_unauthenticated_chat_connection_send_multi_recipient_message(SignalCPromiseOwnedBufferOfServiceIdFixedWidthBinaryBytes *promise, SignalConstPointerTokioAsyncContext async_runtime, SignalConstPointerUnauthenticatedChatConnection chat, SignalBorrowedBuffer payload, uint64_t timestamp, SignalBorrowedBuffer auth, bool online_only, bool is_urgent); SignalFfiError *signal_unidentified_sender_message_content_deserialize(SignalMutPointerUnidentifiedSenderMessageContent *out, SignalBorrowedBuffer data); diff --git a/pkg/libsignalgo/message.go b/pkg/libsignalgo/message.go index 1b581c0..6cba873 100644 --- a/pkg/libsignalgo/message.go +++ b/pkg/libsignalgo/message.go @@ -49,7 +49,7 @@ func Encrypt(ctx context.Context, plaintext []byte, forAddress, localAddress *Ad return wrapCiphertextMessage(ciphertextMessage.raw), nil } -func Decrypt(ctx context.Context, message *Message, fromAddress *Address, sessionStore SessionStore, identityStore IdentityKeyStore) ([]byte, error) { +func Decrypt(ctx context.Context, message *Message, fromAddress, localAddress *Address, sessionStore SessionStore, identityStore IdentityKeyStore) ([]byte, error) { callbackCtx := NewCallbackContext(ctx) defer callbackCtx.Unref() var decrypted C.SignalOwnedBuffer = C.SignalOwnedBuffer{} @@ -57,6 +57,7 @@ func Decrypt(ctx context.Context, message *Message, fromAddress *Address, sessio &decrypted, message.constPtr(), fromAddress.constPtr(), + localAddress.constPtr(), callbackCtx.wrapSessionStore(sessionStore), callbackCtx.wrapIdentityKeyStore(identityStore), ) diff --git a/pkg/libsignalgo/prekeybundle.go b/pkg/libsignalgo/prekeybundle.go index 4cd5547..8a6fcaa 100644 --- a/pkg/libsignalgo/prekeybundle.go +++ b/pkg/libsignalgo/prekeybundle.go @@ -27,13 +27,14 @@ import ( "time" ) -func ProcessPreKeyBundle(ctx context.Context, bundle *PreKeyBundle, forAddress *Address, sessionStore SessionStore, identityStore IdentityKeyStore) error { +func ProcessPreKeyBundle(ctx context.Context, bundle *PreKeyBundle, forAddress, localAddress *Address, sessionStore SessionStore, identityStore IdentityKeyStore) error { callbackCtx := NewCallbackContext(ctx) defer callbackCtx.Unref() var now C.uint64_t = C.uint64_t(time.Now().Unix()) signalFfiError := C.signal_process_prekey_bundle( bundle.constPtr(), forAddress.constPtr(), + localAddress.constPtr(), callbackCtx.wrapSessionStore(sessionStore), callbackCtx.wrapIdentityKeyStore(identityStore), now, diff --git a/pkg/libsignalgo/prekeystore.go b/pkg/libsignalgo/prekeystore.go index ed8ea21..8c3c36f 100644 --- a/pkg/libsignalgo/prekeystore.go +++ b/pkg/libsignalgo/prekeystore.go @@ -76,9 +76,9 @@ func signal_destroy_pre_key_store_callback(storeCtx unsafe.Pointer) { func (ctx *CallbackContext) wrapPreKeyStore(store PreKeyStore) C.SignalConstPointerFfiPreKeyStoreStruct { return C.SignalConstPointerFfiPreKeyStoreStruct{&C.SignalPreKeyStore{ ctx: wrapStore(ctx, store), - load_pre_key: C.SignalFfiBridgePreKeyStoreLoadPreKey(C.signal_load_pre_key_callback), - store_pre_key: C.SignalFfiBridgePreKeyStoreStorePreKey(C.signal_store_pre_key_callback), - remove_pre_key: C.SignalFfiBridgePreKeyStoreRemovePreKey(C.signal_remove_pre_key_callback), - destroy: C.SignalFfiBridgePreKeyStoreDestroy(C.signal_destroy_pre_key_store_callback), + load_pre_key: C.SignalFfiPreKeyStoreLoadPreKey(C.signal_load_pre_key_callback), + store_pre_key: C.SignalFfiPreKeyStoreStorePreKey(C.signal_store_pre_key_callback), + remove_pre_key: C.SignalFfiPreKeyStoreRemovePreKey(C.signal_remove_pre_key_callback), + destroy: C.SignalFfiPreKeyStoreDestroy(C.signal_destroy_pre_key_store_callback), }} } diff --git a/pkg/libsignalgo/senderkeystore.go b/pkg/libsignalgo/senderkeystore.go index a07a287..1649216 100644 --- a/pkg/libsignalgo/senderkeystore.go +++ b/pkg/libsignalgo/senderkeystore.go @@ -70,8 +70,8 @@ func signal_destroy_sender_key_store_callback(storeCtx unsafe.Pointer) { func (ctx *CallbackContext) wrapSenderKeyStore(store SenderKeyStore) C.SignalConstPointerFfiSenderKeyStoreStruct { return C.SignalConstPointerFfiSenderKeyStoreStruct{&C.SignalSenderKeyStore{ ctx: wrapStore(ctx, store), - load_sender_key: C.SignalFfiBridgeSenderKeyStoreLoadSenderKey(C.signal_load_sender_key_callback), - store_sender_key: C.SignalFfiBridgeSenderKeyStoreStoreSenderKey(C.signal_store_sender_key_callback), - destroy: C.SignalFfiBridgeSenderKeyStoreDestroy(C.signal_destroy_sender_key_store_callback), + load_sender_key: C.SignalFfiSenderKeyStoreLoadSenderKey(C.signal_load_sender_key_callback), + store_sender_key: C.SignalFfiSenderKeyStoreStoreSenderKey(C.signal_store_sender_key_callback), + destroy: C.SignalFfiSenderKeyStoreDestroy(C.signal_destroy_sender_key_store_callback), }} } diff --git a/pkg/libsignalgo/session_test.go b/pkg/libsignalgo/session_test.go index 4bde894..dd05718 100644 --- a/pkg/libsignalgo/session_test.go +++ b/pkg/libsignalgo/session_test.go @@ -30,7 +30,7 @@ import ( "go.mau.fi/mautrix-signal/pkg/libsignalgo" ) -func initializeSessions(t *testing.T, aliceStore, bobStore *InMemorySignalProtocolStore, bobAddress *libsignalgo.Address) { +func initializeSessions(t *testing.T, aliceStore, bobStore *InMemorySignalProtocolStore, bobAddress, aliceAddress *libsignalgo.Address) { ctx := context.TODO() bobPreKey, err := libsignalgo.GeneratePrivateKey() @@ -86,7 +86,7 @@ func initializeSessions(t *testing.T, aliceStore, bobStore *InMemorySignalProtoc assert.NoError(t, err) // Alice processes the bundle - err = libsignalgo.ProcessPreKeyBundle(ctx, bobBundle, bobAddress, aliceStore, aliceStore) + err = libsignalgo.ProcessPreKeyBundle(ctx, bobBundle, bobAddress, aliceAddress, aliceStore, aliceStore) assert.NoError(t, err) record, err := aliceStore.LoadSession(ctx, bobAddress) @@ -132,7 +132,7 @@ func TestSessionCipher(t *testing.T) { aliceStore := NewInMemorySignalProtocolStore() bobStore := NewInMemorySignalProtocolStore() - initializeSessions(t, aliceStore, bobStore, bobAddress) + initializeSessions(t, aliceStore, bobStore, bobAddress, aliceAddress) alicePlaintext := []byte{8, 6, 7, 5, 3, 0, 9} @@ -163,7 +163,7 @@ func TestSessionCipher(t *testing.T) { assert.NoError(t, err) aliceCiphertext2, err := libsignalgo.DeserializeMessage(bobCiphertext2Serialized) assert.NoError(t, err) - alicePlaintext2, err := libsignalgo.Decrypt(ctx, aliceCiphertext2, bobAddress, aliceStore, aliceStore) + alicePlaintext2, err := libsignalgo.Decrypt(ctx, aliceCiphertext2, bobAddress, aliceAddress, aliceStore, aliceStore) assert.NoError(t, err) assert.Equal(t, bobPlaintext2, alicePlaintext2) } @@ -183,7 +183,7 @@ func TestSessionCipherWithBadStore(t *testing.T) { aliceStore := NewInMemorySignalProtocolStore() bobStore := &BadInMemorySignalProtocolStore{NewInMemorySignalProtocolStore()} - initializeSessions(t, aliceStore, bobStore.InMemorySignalProtocolStore, bobAddress) + initializeSessions(t, aliceStore, bobStore.InMemorySignalProtocolStore, bobAddress, aliceAddress) alicePlaintext := []byte{8, 6, 7, 5, 3, 0, 9} @@ -216,7 +216,7 @@ func TestSealedSenderEncrypt_Repeated(t *testing.T) { aliceStore := NewInMemorySignalProtocolStore() bobStore := NewInMemorySignalProtocolStore() - initializeSessions(t, aliceStore, bobStore, bobAddress) + initializeSessions(t, aliceStore, bobStore, bobAddress, aliceAddress) trustRoot, err := libsignalgo.GenerateIdentityKeyPair() assert.NoError(t, err) @@ -252,15 +252,18 @@ func TestArchiveSession(t *testing.T) { ctx := context.TODO() setupLogging() + aliceACI := uuid.New() bobACI := uuid.New() + aliceAddress, err := libsignalgo.NewACIServiceID(aliceACI).Address(1) + assert.NoError(t, err) bobAddress, err := libsignalgo.NewACIServiceID(bobACI).Address(1) assert.NoError(t, err) aliceStore := NewInMemorySignalProtocolStore() bobStore := NewInMemorySignalProtocolStore() - initializeSessions(t, aliceStore, bobStore, bobAddress) + initializeSessions(t, aliceStore, bobStore, bobAddress, aliceAddress) session, err := aliceStore.LoadSession(ctx, bobAddress) assert.NoError(t, err) @@ -315,7 +318,7 @@ func TestSealedSenderGroupCipher(t *testing.T) { bobStore := NewInMemorySignalProtocolStore() - initializeSessions(t, aliceStore, bobStore, bobAddress) + initializeSessions(t, aliceStore, bobStore, bobAddress, aliceAddress) trustRoot, err := libsignalgo.GenerateIdentityKeyPair() assert.NoError(t, err) diff --git a/pkg/libsignalgo/sessionstore.go b/pkg/libsignalgo/sessionstore.go index 2515232..99000e5 100644 --- a/pkg/libsignalgo/sessionstore.go +++ b/pkg/libsignalgo/sessionstore.go @@ -67,8 +67,8 @@ func signal_destroy_session_store_callback(storeCtx unsafe.Pointer) { func (ctx *CallbackContext) wrapSessionStore(store SessionStore) C.SignalConstPointerFfiSessionStoreStruct { return C.SignalConstPointerFfiSessionStoreStruct{&C.SignalSessionStore{ ctx: wrapStore(ctx, store), - load_session: C.SignalFfiBridgeSessionStoreLoadSession(C.signal_load_session_callback), - store_session: C.SignalFfiBridgeSessionStoreStoreSession(C.signal_store_session_callback), - destroy: C.SignalFfiBridgeSessionStoreDestroy(C.signal_destroy_session_store_callback), + load_session: C.SignalFfiSessionStoreLoadSession(C.signal_load_session_callback), + store_session: C.SignalFfiSessionStoreStoreSession(C.signal_store_session_callback), + destroy: C.SignalFfiSessionStoreDestroy(C.signal_destroy_session_store_callback), }} } diff --git a/pkg/libsignalgo/signedprekeystore.go b/pkg/libsignalgo/signedprekeystore.go index cfb3015..b1306e2 100644 --- a/pkg/libsignalgo/signedprekeystore.go +++ b/pkg/libsignalgo/signedprekeystore.go @@ -67,8 +67,8 @@ func signal_destroy_signed_pre_key_store_callback(storeCtx unsafe.Pointer) { func (ctx *CallbackContext) wrapSignedPreKeyStore(store SignedPreKeyStore) C.SignalConstPointerFfiSignedPreKeyStoreStruct { return C.SignalConstPointerFfiSignedPreKeyStoreStruct{&C.SignalSignedPreKeyStore{ ctx: wrapStore(ctx, store), - load_signed_pre_key: C.SignalFfiBridgeSignedPreKeyStoreLoadSignedPreKey(C.signal_load_signed_pre_key_callback), - store_signed_pre_key: C.SignalFfiBridgeSignedPreKeyStoreStoreSignedPreKey(C.signal_store_signed_pre_key_callback), - destroy: C.SignalFfiBridgeSignedPreKeyStoreDestroy(C.signal_destroy_signed_pre_key_store_callback), + load_signed_pre_key: C.SignalFfiSignedPreKeyStoreLoadSignedPreKey(C.signal_load_signed_pre_key_callback), + store_signed_pre_key: C.SignalFfiSignedPreKeyStoreStoreSignedPreKey(C.signal_store_signed_pre_key_callback), + destroy: C.SignalFfiSignedPreKeyStoreDestroy(C.signal_destroy_signed_pre_key_store_callback), }} } diff --git a/pkg/libsignalgo/version.go b/pkg/libsignalgo/version.go index bd14084..1f7e94d 100644 --- a/pkg/libsignalgo/version.go +++ b/pkg/libsignalgo/version.go @@ -2,4 +2,4 @@ package libsignalgo -const Version = "v0.92.1" +const Version = "v0.93.2" diff --git a/pkg/signalmeow/keys.go b/pkg/signalmeow/keys.go index f1801e5..5439755 100644 --- a/pkg/signalmeow/keys.go +++ b/pkg/signalmeow/keys.go @@ -413,6 +413,10 @@ func (cli *Client) FetchAndProcessPreKey(ctx context.Context, theirServiceID lib if cli.Store.RecipientStore.IsUnregistered(ctx, theirServiceID) { return fmt.Errorf("%w (cached)", ErrUnregisteredUser) } + localAddress, err := cli.Store.ACIServiceID().Address(uint(cli.Store.DeviceID)) + if err != nil { + return fmt.Errorf("failed to get own address: %w", err) + } // Fetch prekey deviceIDPath := "/*" if specificDeviceID >= 0 { @@ -518,6 +522,7 @@ func (cli *Client) FetchAndProcessPreKey(ctx context.Context, theirServiceID lib ctx, preKeyBundle, address, + localAddress, cli.Store.ACISessionStore, cli.Store.ACIIdentityStore, ) diff --git a/pkg/signalmeow/receiving_decrypt.go b/pkg/signalmeow/receiving_decrypt.go index 6296f00..1d2c8cc 100644 --- a/pkg/signalmeow/receiving_decrypt.go +++ b/pkg/signalmeow/receiving_decrypt.go @@ -243,11 +243,16 @@ func (cli *Client) decryptCiphertextEnvelope( if identityStore == nil { return nil, fmt.Errorf("no identity store for destination service ID %s", destinationServiceID) } + destinationAddress, err := destinationServiceID.Address(uint(cli.Store.DeviceID)) + if err != nil { + return nil, fmt.Errorf("failed to get own address: %w", err) + } plaintext, ciphertextHash, err := cli.bufferedDecryptTxn(ctx, ciphertext, serverTimestamp, func(ctx context.Context) ([]byte, error) { return libsignalgo.Decrypt( ctx, message, senderAddress, + destinationAddress, sessionStore, identityStore, ) From 4f1ebf7aa2708374c0e71d3f76913e07485aad96 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Fri, 8 May 2026 16:56:40 +0300 Subject: [PATCH 575/580] dependencies: update mautrix-go --- go.mod | 8 ++++---- go.sum | 16 ++++++++-------- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/go.mod b/go.mod index a936973..c9cf551 100644 --- a/go.mod +++ b/go.mod @@ -11,17 +11,17 @@ require ( github.com/emersion/go-vcard v0.0.0-20241024213814-c9703dde27ff github.com/google/uuid v1.6.0 github.com/mattn/go-pointer v0.0.1 - github.com/rs/zerolog v1.35.0 + github.com/rs/zerolog v1.35.1 github.com/stretchr/testify v1.11.1 github.com/tidwall/gjson v1.18.0 - go.mau.fi/util v0.9.9-0.20260430092340-8772e7714ea5 + go.mau.fi/util v0.9.9-0.20260508133822-4207002539ff golang.org/x/crypto v0.50.0 golang.org/x/exp v0.0.0-20260410095643-746e56fc9e2f golang.org/x/net v0.53.0 golang.org/x/sync v0.20.0 google.golang.org/protobuf v1.36.11 gopkg.in/yaml.v3 v3.0.1 - maunium.net/go/mautrix v0.27.1-0.20260430124810-125ac2c48014 + maunium.net/go/mautrix v0.27.1-0.20260507230413-b25744aa7730 ) require ( @@ -32,7 +32,7 @@ require ( github.com/lib/pq v1.12.3 // indirect github.com/mattn/go-colorable v0.1.14 // indirect github.com/mattn/go-isatty v0.0.20 // indirect - github.com/mattn/go-sqlite3 v1.14.42 // indirect + github.com/mattn/go-sqlite3 v1.14.44 // indirect github.com/petermattis/goid v0.0.0-20260330135022-df67b199bc81 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/rogpeppe/go-internal v1.10.0 // indirect diff --git a/go.sum b/go.sum index f817e1d..69eb732 100644 --- a/go.sum +++ b/go.sum @@ -30,8 +30,8 @@ github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWE github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mattn/go-pointer v0.0.1 h1:n+XhsuGeVO6MEAp7xyEukFINEa+Quek5psIR/ylA6o0= github.com/mattn/go-pointer v0.0.1/go.mod h1:2zXcozF6qYGgmsG+SeTZz3oAbFLdD3OWqnUbNvJZAlc= -github.com/mattn/go-sqlite3 v1.14.42 h1:MigqEP4ZmHw3aIdIT7T+9TLa90Z6smwcthx+Azv4Cgo= -github.com/mattn/go-sqlite3 v1.14.42/go.mod h1:pjEuOr8IwzLJP2MfGeTb0A35jauH+C2kbHKBr7yXKVQ= +github.com/mattn/go-sqlite3 v1.14.44 h1:3VSe+xafpbzsLbdr2AWlAZk9yRHiBhTBakioXaCKTF8= +github.com/mattn/go-sqlite3 v1.14.44/go.mod h1:pjEuOr8IwzLJP2MfGeTb0A35jauH+C2kbHKBr7yXKVQ= github.com/petermattis/goid v0.0.0-20260330135022-df67b199bc81 h1:WDsQxOJDy0N1VRAjXLpi8sCEZRSGarLWQevDxpTBRrM= github.com/petermattis/goid v0.0.0-20260330135022-df67b199bc81/go.mod h1:pxMtw7cyUw6B2bRH0ZBANSPg+AoSud1I1iyJHI69jH4= github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= @@ -42,8 +42,8 @@ github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjR github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog= github.com/rs/xid v1.6.0 h1:fV591PaemRlL6JfRxGDEPl69wICngIQ3shQtzfy2gxU= github.com/rs/xid v1.6.0/go.mod h1:7XoLgs4eV+QndskICGsho+ADou8ySMSjJKDIan90Nz0= -github.com/rs/zerolog v1.35.0 h1:VD0ykx7HMiMJytqINBsKcbLS+BJ4WYjz+05us+LRTdI= -github.com/rs/zerolog v1.35.0/go.mod h1:EjML9kdfa/RMA7h/6z6pYmq1ykOuA8/mjWaEvGI+jcw= +github.com/rs/zerolog v1.35.1 h1:m7xQeoiLIiV0BCEY4Hs+j2NG4Gp2o2KPKmhnnLiazKI= +github.com/rs/zerolog v1.35.1/go.mod h1:EjML9kdfa/RMA7h/6z6pYmq1ykOuA8/mjWaEvGI+jcw= github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e h1:MRM5ITcdelLK2j1vwZ3Je0FKVCfqOLp5zO6trqMLYs0= github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e/go.mod h1:XV66xRDqSt+GTGFMVlhk3ULuV0y9ZmzeVGR4mloJI3M= github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= @@ -61,8 +61,8 @@ github.com/tidwall/sjson v1.2.5 h1:kLy8mja+1c9jlljvWTlSazM7cKDRfJuR/bOJhcY5NcY= github.com/tidwall/sjson v1.2.5/go.mod h1:Fvgq9kS/6ociJEDnK0Fk1cpYF4FIW6ZF7LAe+6jwd28= github.com/yuin/goldmark v1.8.2 h1:kEGpgqJXdgbkhcOgBxkC0X0PmoPG1ZyoZ117rDVp4zE= github.com/yuin/goldmark v1.8.2/go.mod h1:ip/1k0VRfGynBgxOz0yCqHrbZXhcjxyuS66Brc7iBKg= -go.mau.fi/util v0.9.9-0.20260430092340-8772e7714ea5 h1:cNm4gkt7j907g1Q4XvyNKW8tTM8BaU91Kbfa5GGyiCs= -go.mau.fi/util v0.9.9-0.20260430092340-8772e7714ea5/go.mod h1:up/5mbzH2M1pSBNXqRxODn8dg/hEKbLJu92W4/SNAX0= +go.mau.fi/util v0.9.9-0.20260508133822-4207002539ff h1:nH8zuwSw5uu2pal7p9x5BSAvavuiJqRFN558XvcTtKg= +go.mau.fi/util v0.9.9-0.20260508133822-4207002539ff/go.mod h1:jE9FfhbgEgAwxei6lomO9v8zdCIATcquONUu4vjRwSs= go.mau.fi/zeroconfig v0.2.0 h1:e/OGEERqVRRKlgaro7E6bh8xXiKFSXB3eNNIud7FUjU= go.mau.fi/zeroconfig v0.2.0/go.mod h1:J0Vn0prHNOm493oZoQ84kq83ZaNCYZnq+noI1b1eN8w= golang.org/x/crypto v0.50.0 h1:zO47/JPrL6vsNkINmLoo/PH1gcxpls50DNogFvB5ZGI= @@ -91,5 +91,5 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= maunium.net/go/mauflag v1.0.0 h1:YiaRc0tEI3toYtJMRIfjP+jklH45uDHtT80nUamyD4M= maunium.net/go/mauflag v1.0.0/go.mod h1:nLivPOpTpHnpzEh8jEdSL9UqO9+/KBJFmNRlwKfkPeA= -maunium.net/go/mautrix v0.27.1-0.20260430124810-125ac2c48014 h1:KwXGBWwUHYJKVTYWgbZEFcaM6uYLMvfjzHJg/TLwvKc= -maunium.net/go/mautrix v0.27.1-0.20260430124810-125ac2c48014/go.mod h1:4fZ0M0xB5ZtueQI65RilX28J/3794BeK+LaCg4U61Jk= +maunium.net/go/mautrix v0.27.1-0.20260507230413-b25744aa7730 h1:GcBSD72Ez7D3LoFVprsFFQx3mKcaRh983KpLIiifw68= +maunium.net/go/mautrix v0.27.1-0.20260507230413-b25744aa7730/go.mod h1:2ANjihDB+wv2UAqJapkRekmNXw7khSisccAkE5Jg3P0= From 9cdd4c9963726af2d1f2eaaeec41f18adf3284c9 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Fri, 8 May 2026 16:57:56 +0300 Subject: [PATCH 576/580] signalmeow: update protobufs --- pkg/signalmeow/protobuf/ContactDiscovery.pb.go | 2 +- pkg/signalmeow/protobuf/DeviceName.pb.go | 2 +- pkg/signalmeow/protobuf/Groups.pb.go | 2 +- pkg/signalmeow/protobuf/Provisioning.pb.go | 2 +- pkg/signalmeow/protobuf/SignalService.pb.go | 2 +- pkg/signalmeow/protobuf/StickerResources.pb.go | 2 +- pkg/signalmeow/protobuf/StorageService.pb.go | 15 ++++++++++++--- pkg/signalmeow/protobuf/StorageService.proto | 1 + .../protobuf/UnidentifiedDelivery.pb.go | 2 +- pkg/signalmeow/protobuf/WebSocketResources.pb.go | 2 +- pkg/signalmeow/protobuf/backuppb/Backup.pb.go | 2 +- pkg/signalmeow/protobuf/update-protos.sh | 4 ++-- 12 files changed, 24 insertions(+), 14 deletions(-) diff --git a/pkg/signalmeow/protobuf/ContactDiscovery.pb.go b/pkg/signalmeow/protobuf/ContactDiscovery.pb.go index 637a2d2..5cb232c 100644 --- a/pkg/signalmeow/protobuf/ContactDiscovery.pb.go +++ b/pkg/signalmeow/protobuf/ContactDiscovery.pb.go @@ -1,7 +1,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: // protoc-gen-go v1.36.11 -// protoc v6.33.5 +// protoc v7.34.1 // source: ContactDiscovery.proto // Copyright 2021 Signal Messenger, LLC diff --git a/pkg/signalmeow/protobuf/DeviceName.pb.go b/pkg/signalmeow/protobuf/DeviceName.pb.go index 5666b7e..31b5704 100644 --- a/pkg/signalmeow/protobuf/DeviceName.pb.go +++ b/pkg/signalmeow/protobuf/DeviceName.pb.go @@ -1,7 +1,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: // protoc-gen-go v1.36.11 -// protoc v6.33.5 +// protoc v7.34.1 // source: DeviceName.proto // Copyright 2018 Signal Messenger, LLC diff --git a/pkg/signalmeow/protobuf/Groups.pb.go b/pkg/signalmeow/protobuf/Groups.pb.go index 0c2b81b..8d4e2e3 100644 --- a/pkg/signalmeow/protobuf/Groups.pb.go +++ b/pkg/signalmeow/protobuf/Groups.pb.go @@ -5,7 +5,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: // protoc-gen-go v1.36.11 -// protoc v6.33.5 +// protoc v7.34.1 // source: Groups.proto package signalpb diff --git a/pkg/signalmeow/protobuf/Provisioning.pb.go b/pkg/signalmeow/protobuf/Provisioning.pb.go index c925fe6..88ebe90 100644 --- a/pkg/signalmeow/protobuf/Provisioning.pb.go +++ b/pkg/signalmeow/protobuf/Provisioning.pb.go @@ -5,7 +5,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: // protoc-gen-go v1.36.11 -// protoc v6.33.5 +// protoc v7.34.1 // source: Provisioning.proto package signalpb diff --git a/pkg/signalmeow/protobuf/SignalService.pb.go b/pkg/signalmeow/protobuf/SignalService.pb.go index 32842bf..c4268dd 100644 --- a/pkg/signalmeow/protobuf/SignalService.pb.go +++ b/pkg/signalmeow/protobuf/SignalService.pb.go @@ -5,7 +5,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: // protoc-gen-go v1.36.11 -// protoc v6.33.5 +// protoc v7.34.1 // source: SignalService.proto package signalpb diff --git a/pkg/signalmeow/protobuf/StickerResources.pb.go b/pkg/signalmeow/protobuf/StickerResources.pb.go index e83cda1..f8194aa 100644 --- a/pkg/signalmeow/protobuf/StickerResources.pb.go +++ b/pkg/signalmeow/protobuf/StickerResources.pb.go @@ -6,7 +6,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: // protoc-gen-go v1.36.11 -// protoc v6.33.5 +// protoc v7.34.1 // source: StickerResources.proto package signalpb diff --git a/pkg/signalmeow/protobuf/StorageService.pb.go b/pkg/signalmeow/protobuf/StorageService.pb.go index 619221f..bbe88ef 100644 --- a/pkg/signalmeow/protobuf/StorageService.pb.go +++ b/pkg/signalmeow/protobuf/StorageService.pb.go @@ -6,7 +6,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: // protoc-gen-go v1.36.11 -// protoc v6.33.5 +// protoc v7.34.1 // source: StorageService.proto package signalpb @@ -1401,6 +1401,7 @@ type GroupV2Record struct { HideStory bool `protobuf:"varint,8,opt,name=hideStory,proto3" json:"hideStory,omitempty"` StorySendMode GroupV2Record_StorySendMode `protobuf:"varint,10,opt,name=storySendMode,proto3,enum=signalservice.GroupV2Record_StorySendMode" json:"storySendMode,omitempty"` AvatarColor *AvatarColor `protobuf:"varint,11,opt,name=avatarColor,proto3,enum=signalservice.AvatarColor,oneof" json:"avatarColor,omitempty"` + VerifiedNameHash []byte `protobuf:"bytes,12,opt,name=verifiedNameHash,proto3" json:"verifiedNameHash,omitempty"` // SHA-256 of UTF-8 encoded decrypted group title that was last verified unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } @@ -1505,6 +1506,13 @@ func (x *GroupV2Record) GetAvatarColor() AvatarColor { return AvatarColor_A100 } +func (x *GroupV2Record) GetVerifiedNameHash() []byte { + if x != nil { + return x.VerifiedNameHash + } + return nil +} + type Payments struct { state protoimpl.MessageState `protogen:"open.v1"` Enabled bool `protobuf:"varint,1,opt,name=enabled,proto3" json:"enabled,omitempty"` @@ -3195,7 +3203,7 @@ const file_StorageService_proto_rawDesc = "" + "\vwhitelisted\x18\x03 \x01(\bR\vwhitelisted\x12\x1a\n" + "\barchived\x18\x04 \x01(\bR\barchived\x12\"\n" + "\fmarkedUnread\x18\x05 \x01(\bR\fmarkedUnread\x120\n" + - "\x13mutedUntilTimestamp\x18\x06 \x01(\x04R\x13mutedUntilTimestamp\"\xa1\x04\n" + + "\x13mutedUntilTimestamp\x18\x06 \x01(\x04R\x13mutedUntilTimestamp\"\xcd\x04\n" + "\rGroupV2Record\x12\x1c\n" + "\tmasterKey\x18\x01 \x01(\fR\tmasterKey\x12\x18\n" + "\ablocked\x18\x02 \x01(\bR\ablocked\x12 \n" + @@ -3207,7 +3215,8 @@ const file_StorageService_proto_rawDesc = "" + "\thideStory\x18\b \x01(\bR\thideStory\x12P\n" + "\rstorySendMode\x18\n" + " \x01(\x0e2*.signalservice.GroupV2Record.StorySendModeR\rstorySendMode\x12A\n" + - "\vavatarColor\x18\v \x01(\x0e2\x1a.signalservice.AvatarColorH\x00R\vavatarColor\x88\x01\x01\"7\n" + + "\vavatarColor\x18\v \x01(\x0e2\x1a.signalservice.AvatarColorH\x00R\vavatarColor\x88\x01\x01\x12*\n" + + "\x10verifiedNameHash\x18\f \x01(\fR\x10verifiedNameHash\"7\n" + "\rStorySendMode\x12\v\n" + "\aDEFAULT\x10\x00\x12\f\n" + "\bDISABLED\x10\x01\x12\v\n" + diff --git a/pkg/signalmeow/protobuf/StorageService.proto b/pkg/signalmeow/protobuf/StorageService.proto index d22babc..dd232ca 100644 --- a/pkg/signalmeow/protobuf/StorageService.proto +++ b/pkg/signalmeow/protobuf/StorageService.proto @@ -172,6 +172,7 @@ message GroupV2Record { reserved /* storySendEnabled */ 9; StorySendMode storySendMode = 10; optional AvatarColor avatarColor = 11; + bytes verifiedNameHash = 12; // SHA-256 of UTF-8 encoded decrypted group title that was last verified } message Payments { diff --git a/pkg/signalmeow/protobuf/UnidentifiedDelivery.pb.go b/pkg/signalmeow/protobuf/UnidentifiedDelivery.pb.go index e30f6d6..5979a4c 100644 --- a/pkg/signalmeow/protobuf/UnidentifiedDelivery.pb.go +++ b/pkg/signalmeow/protobuf/UnidentifiedDelivery.pb.go @@ -1,7 +1,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: // protoc-gen-go v1.36.11 -// protoc v6.33.5 +// protoc v7.34.1 // source: UnidentifiedDelivery.proto // Copyright 2018 Signal Messenger, LLC diff --git a/pkg/signalmeow/protobuf/WebSocketResources.pb.go b/pkg/signalmeow/protobuf/WebSocketResources.pb.go index f35110d..66520eb 100644 --- a/pkg/signalmeow/protobuf/WebSocketResources.pb.go +++ b/pkg/signalmeow/protobuf/WebSocketResources.pb.go @@ -6,7 +6,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: // protoc-gen-go v1.36.11 -// protoc v6.33.5 +// protoc v7.34.1 // source: WebSocketResources.proto package signalpb diff --git a/pkg/signalmeow/protobuf/backuppb/Backup.pb.go b/pkg/signalmeow/protobuf/backuppb/Backup.pb.go index 326c170..bc488e7 100644 --- a/pkg/signalmeow/protobuf/backuppb/Backup.pb.go +++ b/pkg/signalmeow/protobuf/backuppb/Backup.pb.go @@ -1,7 +1,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: // protoc-gen-go v1.36.11 -// protoc v6.33.5 +// protoc v7.34.1 // source: backuppb/Backup.proto package backuppb diff --git a/pkg/signalmeow/protobuf/update-protos.sh b/pkg/signalmeow/protobuf/update-protos.sh index ffaa697..f9c86fc 100755 --- a/pkg/signalmeow/protobuf/update-protos.sh +++ b/pkg/signalmeow/protobuf/update-protos.sh @@ -1,8 +1,8 @@ #!/bin/bash set -euo pipefail -ANDROID_GIT_REVISION=${1:-dfd2f7baf96825834f784900ce644e9ead8a9a89} -DESKTOP_GIT_REVISION=${1:-60a1e125452ee672d8747564d0055d5bfec9f679} +ANDROID_GIT_REVISION=${1:-439760e7732585bfd078d92d93732c04cc31e29e} +DESKTOP_GIT_REVISION=${1:-1b2a3e7b283c32c5654a39da12fc04139fd26dbd} update_proto() { case "$1" in From 4545def01787e39cf9c86b5fa7e726330de17b28 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Mon, 11 May 2026 16:16:36 +0300 Subject: [PATCH 577/580] signalmeow/web: log request durations --- pkg/signalmeow/web/web.go | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/pkg/signalmeow/web/web.go b/pkg/signalmeow/web/web.go index e617b40..f211b77 100644 --- a/pkg/signalmeow/web/web.go +++ b/pkg/signalmeow/web/web.go @@ -28,6 +28,7 @@ import ( "net/http" "runtime" "strings" + "time" "github.com/rs/zerolog" @@ -140,12 +141,14 @@ func SendHTTPRequest(ctx context.Context, host, method, path string, opt *HTTPRe httpReqCounter++ log = log.With().Int("request_number", httpReqCounter).Logger() log.Trace().Msg("Sending HTTP request") + start := time.Now() resp, err := SignalHTTPClient.Do(req) + dur := time.Since(start) if err != nil { - log.Err(err).Msg("Error sending request") + log.Err(err).Dur("duration", dur).Msg("Error sending request") return nil, err } - log.Debug().Int("status_code", resp.StatusCode).Msg("received HTTP response") + log.Debug().Int("status_code", resp.StatusCode).Dur("duration", dur).Msg("Received HTTP response") return resp, nil } From 41a37cd1844c63737b1ccca80d54118cf5c02819 Mon Sep 17 00:00:00 2001 From: SpiritCroc Date: Tue, 12 May 2026 11:43:06 +0200 Subject: [PATCH 578/580] capabilities: drop webp to only partial support (#649) Co-authored-by: Tulir Asokan --- pkg/connector/capabilities.go | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/pkg/connector/capabilities.go b/pkg/connector/capabilities.go index d23285c..5eab6a8 100644 --- a/pkg/connector/capabilities.go +++ b/pkg/connector/capabilities.go @@ -38,7 +38,7 @@ func supportedIfFFmpeg() event.CapabilitySupportLevel { } func capID() string { - base := "fi.mau.signal.capabilities.2025_12_09" + base := "fi.mau.signal.capabilities.2026_05_12" if ffmpeg.Supported() { return base + "+ffmpeg" } @@ -111,7 +111,8 @@ var signalCaps = &event.RoomFeatures{ }, event.CapMsgSticker: { MimeTypes: map[string]event.CapabilitySupportLevel{ - "image/webp": event.CapLevelFullySupported, + // Signal clients will only render static webp, so apng is preferred + "image/webp": event.CapLevelPartialSupport, "image/png": event.CapLevelFullySupported, "image/apng": event.CapLevelFullySupported, "image/gif": supportedIfFFmpeg(), @@ -236,5 +237,5 @@ func (s *SignalConnector) GetCapabilities() *bridgev2.NetworkGeneralCapabilities } func (s *SignalConnector) GetBridgeInfoVersion() (info, capabilities int) { - return 1, 7 + return 1, 8 } From 14592ffdccac3ea222a2ac787c7405133d227cfa Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Tue, 12 May 2026 16:00:56 +0300 Subject: [PATCH 579/580] dependencies: update mautrix-go --- go.mod | 4 ++-- go.sum | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/go.mod b/go.mod index c9cf551..db72345 100644 --- a/go.mod +++ b/go.mod @@ -14,14 +14,14 @@ require ( github.com/rs/zerolog v1.35.1 github.com/stretchr/testify v1.11.1 github.com/tidwall/gjson v1.18.0 - go.mau.fi/util v0.9.9-0.20260508133822-4207002539ff + go.mau.fi/util v0.9.9-0.20260511124621-9241e81bdf25 golang.org/x/crypto v0.50.0 golang.org/x/exp v0.0.0-20260410095643-746e56fc9e2f golang.org/x/net v0.53.0 golang.org/x/sync v0.20.0 google.golang.org/protobuf v1.36.11 gopkg.in/yaml.v3 v3.0.1 - maunium.net/go/mautrix v0.27.1-0.20260507230413-b25744aa7730 + maunium.net/go/mautrix v0.27.1-0.20260512144923-7c0986318ff8 ) require ( diff --git a/go.sum b/go.sum index 69eb732..753b96d 100644 --- a/go.sum +++ b/go.sum @@ -61,8 +61,8 @@ github.com/tidwall/sjson v1.2.5 h1:kLy8mja+1c9jlljvWTlSazM7cKDRfJuR/bOJhcY5NcY= github.com/tidwall/sjson v1.2.5/go.mod h1:Fvgq9kS/6ociJEDnK0Fk1cpYF4FIW6ZF7LAe+6jwd28= github.com/yuin/goldmark v1.8.2 h1:kEGpgqJXdgbkhcOgBxkC0X0PmoPG1ZyoZ117rDVp4zE= github.com/yuin/goldmark v1.8.2/go.mod h1:ip/1k0VRfGynBgxOz0yCqHrbZXhcjxyuS66Brc7iBKg= -go.mau.fi/util v0.9.9-0.20260508133822-4207002539ff h1:nH8zuwSw5uu2pal7p9x5BSAvavuiJqRFN558XvcTtKg= -go.mau.fi/util v0.9.9-0.20260508133822-4207002539ff/go.mod h1:jE9FfhbgEgAwxei6lomO9v8zdCIATcquONUu4vjRwSs= +go.mau.fi/util v0.9.9-0.20260511124621-9241e81bdf25 h1:YPEmc+li7TF6C9AdRTcSLMb6yCHdF27/wNT7kFLIVNg= +go.mau.fi/util v0.9.9-0.20260511124621-9241e81bdf25/go.mod h1:jE9FfhbgEgAwxei6lomO9v8zdCIATcquONUu4vjRwSs= go.mau.fi/zeroconfig v0.2.0 h1:e/OGEERqVRRKlgaro7E6bh8xXiKFSXB3eNNIud7FUjU= go.mau.fi/zeroconfig v0.2.0/go.mod h1:J0Vn0prHNOm493oZoQ84kq83ZaNCYZnq+noI1b1eN8w= golang.org/x/crypto v0.50.0 h1:zO47/JPrL6vsNkINmLoo/PH1gcxpls50DNogFvB5ZGI= @@ -91,5 +91,5 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= maunium.net/go/mauflag v1.0.0 h1:YiaRc0tEI3toYtJMRIfjP+jklH45uDHtT80nUamyD4M= maunium.net/go/mauflag v1.0.0/go.mod h1:nLivPOpTpHnpzEh8jEdSL9UqO9+/KBJFmNRlwKfkPeA= -maunium.net/go/mautrix v0.27.1-0.20260507230413-b25744aa7730 h1:GcBSD72Ez7D3LoFVprsFFQx3mKcaRh983KpLIiifw68= -maunium.net/go/mautrix v0.27.1-0.20260507230413-b25744aa7730/go.mod h1:2ANjihDB+wv2UAqJapkRekmNXw7khSisccAkE5Jg3P0= +maunium.net/go/mautrix v0.27.1-0.20260512144923-7c0986318ff8 h1:8eHwxv8J9b8ebVwL4H98mlKE4SSAeqhqwD251oSiEkc= +maunium.net/go/mautrix v0.27.1-0.20260512144923-7c0986318ff8/go.mod h1:3sOGhXi3P1V6/NruTA0gujkvTypXVUraWktCuTGyDuM= From 0df937749bfc3dfa5c06d657b29f49c7548ef4d4 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Wed, 13 May 2026 15:05:37 +0300 Subject: [PATCH 580/580] dependencies: update mautrix-go --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index db72345..931af45 100644 --- a/go.mod +++ b/go.mod @@ -21,7 +21,7 @@ require ( golang.org/x/sync v0.20.0 google.golang.org/protobuf v1.36.11 gopkg.in/yaml.v3 v3.0.1 - maunium.net/go/mautrix v0.27.1-0.20260512144923-7c0986318ff8 + maunium.net/go/mautrix v0.27.1-0.20260513120123-5fba7e3afae4 ) require ( diff --git a/go.sum b/go.sum index 753b96d..2f02866 100644 --- a/go.sum +++ b/go.sum @@ -91,5 +91,5 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= maunium.net/go/mauflag v1.0.0 h1:YiaRc0tEI3toYtJMRIfjP+jklH45uDHtT80nUamyD4M= maunium.net/go/mauflag v1.0.0/go.mod h1:nLivPOpTpHnpzEh8jEdSL9UqO9+/KBJFmNRlwKfkPeA= -maunium.net/go/mautrix v0.27.1-0.20260512144923-7c0986318ff8 h1:8eHwxv8J9b8ebVwL4H98mlKE4SSAeqhqwD251oSiEkc= -maunium.net/go/mautrix v0.27.1-0.20260512144923-7c0986318ff8/go.mod h1:3sOGhXi3P1V6/NruTA0gujkvTypXVUraWktCuTGyDuM= +maunium.net/go/mautrix v0.27.1-0.20260513120123-5fba7e3afae4 h1:zNC9eVAhw8FhKpM3AxNAh/iy75UEYX91uJUvqqAYlvo= +maunium.net/go/mautrix v0.27.1-0.20260513120123-5fba7e3afae4/go.mod h1:3sOGhXi3P1V6/NruTA0gujkvTypXVUraWktCuTGyDuM=